Skip to content

Commit

Permalink
Add vendor_id and product_id into virtual_hid_keyboard_parameters (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
tekezo authored Aug 29, 2024
1 parent 904eb90 commit f1d35c6
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 34 deletions.
6 changes: 4 additions & 2 deletions examples/virtual-hid-device-service-client/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ int main(void) {
client1->connected.connect([&client1] {
std::cout << "connected" << std::endl;

client1->async_virtual_hid_keyboard_initialize(pqrs::hid::country_code::us);
pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters parameters;
client1->async_virtual_hid_keyboard_initialize(parameters);
client1->async_virtual_hid_pointing_initialize();
});
client1->connect_failed.connect([](auto&& error_code) {
Expand Down Expand Up @@ -164,7 +165,8 @@ int main(void) {
//

client2->connected.connect([&client2] {
client2->async_virtual_hid_keyboard_initialize(pqrs::hid::country_code::us);
pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters parameters;
client2->async_virtual_hid_keyboard_initialize(parameters);
});
client2->virtual_hid_keyboard_ready.connect([&client2, &client_mutex, &keyboard_thread2, &keyboard_thread_mutex](auto&& ready) {
if (ready) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ inline std::ostream& operator<<(std::ostream& stream, const value_t& value) {
}

// clang-format off
constexpr value_t embedded_client_protocol_version(4);
constexpr value_t embedded_client_protocol_version(5);
// clang-format on
} // namespace client_protocol_version
} // namespace driverkit
Expand Down
2 changes: 1 addition & 1 deletion include/pqrs/karabiner/driverkit/driver_version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ inline std::ostream& operator<<(std::ostream& stream, const value_t& value) {
}

// clang-format off
constexpr value_t embedded_driver_version(10700);
constexpr value_t embedded_driver_version(10800);
// clang-format on
} // namespace driver_version
} // namespace driverkit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "driver_version.hpp"
#include "virtual_hid_device_service/client.hpp"
#include "virtual_hid_device_service/constants.hpp"
#include "virtual_hid_device_service/parameters.hpp"
#include "virtual_hid_device_service/request.hpp"
#include "virtual_hid_device_service/response.hpp"
#include "virtual_hid_device_service/utility.hpp"
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// (See https://www.boost.org/LICENSE_1_0.txt)

#include "constants.hpp"
#include "parameters.hpp"
#include "request.hpp"
#include "response.hpp"
#include <glob/glob.hpp>
Expand Down Expand Up @@ -66,19 +67,19 @@ class client final : public dispatcher::extra::dispatcher_client {
});
}

void async_virtual_hid_keyboard_initialize(hid::country_code::value_t country_code,
void async_virtual_hid_keyboard_initialize(const pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters& parameters,
bool force = false) {
if (!force) {
if (last_virtual_hid_keyboard_ready_ == true &&
last_virtual_hid_keyboard_initialize_country_code_ == country_code) {
last_virtual_hid_keyboard_parameters_ == parameters) {
return;
}
}

last_virtual_hid_keyboard_initialize_country_code_ = country_code;
last_virtual_hid_keyboard_parameters_ = parameters;

async_send(request::virtual_hid_keyboard_initialize,
country_code);
parameters);
}

void async_virtual_hid_keyboard_terminate(void) {
Expand Down Expand Up @@ -171,7 +172,7 @@ class client final : public dispatcher::extra::dispatcher_client {
last_virtual_hid_pointing_ready_ = std::nullopt;
virtual_hid_pointing_ready(false);

last_virtual_hid_keyboard_initialize_country_code_ = std::nullopt;
last_virtual_hid_keyboard_parameters_ = std::nullopt;
}

void create_client(void) {
Expand Down Expand Up @@ -319,7 +320,7 @@ class client final : public dispatcher::extra::dispatcher_client {
std::optional<bool> last_virtual_hid_keyboard_ready_;
std::optional<bool> last_virtual_hid_pointing_ready_;

std::optional<hid::country_code::value_t> last_virtual_hid_keyboard_initialize_country_code_;
std::optional<pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters> last_virtual_hid_keyboard_parameters_;
};
} // namespace virtual_hid_device_service
} // namespace driverkit
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#pragma once

// (C) Copyright Takayama Fumihiko 2024.
// Distributed under the Boost Software License, Version 1.0.
// (See https://www.boost.org/LICENSE_1_0.txt)

#include <pqrs/hid.hpp>
#include <string_view>

namespace pqrs {
namespace karabiner {
namespace driverkit {
namespace virtual_hid_device_service {
class virtual_hid_keyboard_parameters final {
public:
virtual_hid_keyboard_parameters(void)
: virtual_hid_keyboard_parameters(pqrs::hid::vendor_id::value_t(0x16c0),
pqrs::hid::product_id::value_t(0x27db),
pqrs::hid::country_code::not_supported) {
}

virtual_hid_keyboard_parameters(pqrs::hid::vendor_id::value_t vendor_id,
pqrs::hid::product_id::value_t product_id,
pqrs::hid::country_code::value_t country_code)
: vendor_id_(vendor_id),
product_id_(product_id),
country_code_(country_code) {
}

pqrs::hid::vendor_id::value_t get_vendor_id(void) const {
return vendor_id_;
}

void set_vendor_id(pqrs::hid::vendor_id::value_t value) {
vendor_id_ = value;
}

pqrs::hid::product_id::value_t get_product_id(void) const {
return product_id_;
}

void set_product_id(pqrs::hid::product_id::value_t value) {
product_id_ = value;
}

pqrs::hid::country_code::value_t get_country_code(void) const {
return country_code_;
}

void set_country_code(pqrs::hid::country_code::value_t value) {
country_code_ = value;
}

bool operator==(const virtual_hid_keyboard_parameters&) const = default;

private:
pqrs::hid::vendor_id::value_t vendor_id_;
pqrs::hid::product_id::value_t product_id_;
pqrs::hid::country_code::value_t country_code_;
};
} // namespace virtual_hid_device_service
} // namespace driverkit
} // namespace karabiner
} // namespace pqrs
11 changes: 8 additions & 3 deletions src/Daemon/include/io_service_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <pqrs/karabiner/driverkit/client_protocol_version.hpp>
#include <pqrs/karabiner/driverkit/driver_version.hpp>
#include <pqrs/karabiner/driverkit/virtual_hid_device_driver.hpp>
#include <pqrs/karabiner/driverkit/virtual_hid_device_service.hpp>
#include <pqrs/osx/iokit_return.hpp>
#include <pqrs/osx/iokit_service_monitor.hpp>

Expand Down Expand Up @@ -149,11 +150,15 @@ class io_service_client final : public pqrs::dispatcher::extra::dispatcher_clien
});
}

void async_virtual_hid_keyboard_initialize(pqrs::hid::country_code::value_t country_code) const {
void async_virtual_hid_keyboard_initialize(const pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters& parameters) const {
logger::get_logger()->info("io_service_client::{0}", __func__);

enqueue_to_dispatcher([this, country_code] {
std::array<uint64_t, 1> input = {type_safe::get(country_code)};
enqueue_to_dispatcher([this, parameters] {
std::array<uint64_t, 3> input = {
type_safe::get(parameters.get_vendor_id()),
type_safe::get(parameters.get_product_id()),
type_safe::get(parameters.get_country_code()),
};

auto r = call_scalar_method(pqrs::karabiner::driverkit::virtual_hid_device_driver::user_client_method::virtual_hid_keyboard_initialize,
input.data(),
Expand Down
21 changes: 10 additions & 11 deletions src/Daemon/include/virtual_hid_device_service_clients_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ class virtual_hid_device_service_clients_manager final : public pqrs::dispatcher
}

void initialize_keyboard(const std::string& endpoint_path,
pqrs::hid::country_code::value_t country_code) {
const pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters& parameters) {
if (!dispatcher_thread()) {
throw std::logic_error(fmt::format("{0} is called in wrong thread", __func__));
}

auto it = entries_.find(endpoint_path);
if (it != std::end(entries_)) {
it->second->initialize_keyboard(country_code);
it->second->initialize_keyboard(parameters);
}
}

Expand Down Expand Up @@ -231,7 +231,6 @@ class virtual_hid_device_service_clients_manager final : public pqrs::dispatcher
initialize_timer_(*this),
ready_timer_(*this),
virtual_hid_keyboard_enabled_(false),
virtual_hid_keyboard_country_code_(pqrs::hid::country_code::not_supported),
virtual_hid_pointing_enabled_(false) {
io_service_client_nop_ = std::make_shared<io_service_client>(run_loop_thread_);
io_service_client_nop_->async_start();
Expand All @@ -247,7 +246,7 @@ class virtual_hid_device_service_clients_manager final : public pqrs::dispatcher
io_service_client_keyboard_ = std::make_shared<io_service_client>(run_loop_thread_);

io_service_client_keyboard_->opened.connect([this] {
io_service_client_keyboard_->async_virtual_hid_keyboard_initialize(virtual_hid_keyboard_country_code_);
io_service_client_keyboard_->async_virtual_hid_keyboard_initialize(virtual_hid_keyboard_parameters_);
});

io_service_client_keyboard_->async_start();
Expand Down Expand Up @@ -325,18 +324,18 @@ class virtual_hid_device_service_clients_manager final : public pqrs::dispatcher
// io_service_client_keyboard_
//

void initialize_keyboard(pqrs::hid::country_code::value_t country_code) {
enqueue_to_dispatcher([this, country_code] {
// Destroy io_service_client_keyboard_ if country_code is changed.
void initialize_keyboard(const pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters& parameters) {
enqueue_to_dispatcher([this, parameters] {
// Destroy io_service_client_keyboard_ if parameters is changed.
if (io_service_client_keyboard_ &&
virtual_hid_keyboard_country_code_ != country_code) {
logger::get_logger()->info("destroy io_service_client_keyboard_ due to country_code changes");
virtual_hid_keyboard_parameters_ != parameters) {
logger::get_logger()->info("destroy io_service_client_keyboard_ due to parameter changes");

io_service_client_keyboard_ = nullptr;
}

virtual_hid_keyboard_enabled_ = true;
virtual_hid_keyboard_country_code_ = country_code;
virtual_hid_keyboard_parameters_ = parameters;
});
}

Expand Down Expand Up @@ -443,7 +442,7 @@ class virtual_hid_device_service_clients_manager final : public pqrs::dispatcher

// virtual_hid_keyboard
bool virtual_hid_keyboard_enabled_;
pqrs::hid::country_code::value_t virtual_hid_keyboard_country_code_;
pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters virtual_hid_keyboard_parameters_;

// virtual_hid_pointing
bool virtual_hid_pointing_enabled_;
Expand Down
6 changes: 3 additions & 3 deletions src/Daemon/include/virtual_hid_device_service_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,16 @@ class virtual_hid_device_service_server final : public pqrs::dispatcher::extra::
logger::get_logger()->info("received request::virtual_hid_keyboard_initialize: {0}",
sender_endpoint_filename.c_str());

if (sizeof(pqrs::hid::country_code::value_t) != size) {
if (sizeof(pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters) != size) {
logger::get_logger()->warn("virtual_hid_device_service_server: received: virtual_hid_keyboard_initialize buffer size error");
return;
}

auto country_code = *(reinterpret_cast<pqrs::hid::country_code::value_t*>(p));
auto parameters = reinterpret_cast<pqrs::karabiner::driverkit::virtual_hid_device_service::virtual_hid_keyboard_parameters*>(p);

virtual_hid_device_service_clients_manager_->create_client(sender_endpoint->path());
virtual_hid_device_service_clients_manager_->initialize_keyboard(sender_endpoint->path(),
country_code);
*parameters);
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ kern_return_t createIOMemoryDescriptor(IOUserClientMethodArguments* arguments, I
} // namespace

struct org_pqrs_Karabiner_DriverKit_VirtualHIDDeviceUserClient_IVars {
uint32_t keyboardVendorId;
uint32_t keyboardProductId;
uint32_t keyboardCountryCode;
org_pqrs_Karabiner_DriverKit_VirtualHIDKeyboard* keyboard;
org_pqrs_Karabiner_DriverKit_VirtualHIDPointing* pointing;
Expand Down Expand Up @@ -99,8 +101,10 @@ kern_return_t org_pqrs_Karabiner_DriverKit_VirtualHIDDeviceUserClient::ExternalM

case pqrs::karabiner::driverkit::virtual_hid_device_driver::user_client_method::virtual_hid_keyboard_initialize:
if (!ivars->keyboard) {
if (arguments->scalarInputCount > 0) {
ivars->keyboardCountryCode = static_cast<uint32_t>(arguments->scalarInput[0]);
if (arguments->scalarInputCount > 2) {
ivars->keyboardVendorId = static_cast<uint32_t>(arguments->scalarInput[0]);
ivars->keyboardProductId = static_cast<uint32_t>(arguments->scalarInput[1]);
ivars->keyboardCountryCode = static_cast<uint32_t>(arguments->scalarInput[2]);
}

IOService* client;
Expand Down Expand Up @@ -200,6 +204,14 @@ kern_return_t org_pqrs_Karabiner_DriverKit_VirtualHIDDeviceUserClient::ExternalM
return kIOReturnBadArgument;
}

uint32_t IMPL(org_pqrs_Karabiner_DriverKit_VirtualHIDDeviceUserClient, getKeyboardVendorId) {
return ivars->keyboardVendorId;
}

uint32_t IMPL(org_pqrs_Karabiner_DriverKit_VirtualHIDDeviceUserClient, getKeyboardProductId) {
return ivars->keyboardProductId;
}

uint32_t IMPL(org_pqrs_Karabiner_DriverKit_VirtualHIDDeviceUserClient, getKeyboardCountryCode) {
return ivars->keyboardCountryCode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public:
OSObject* target,
void* reference) override;

virtual uint32_t getKeyboardVendorId(void);
virtual uint32_t getKeyboardProductId(void);
virtual uint32_t getKeyboardCountryCode(void);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,20 @@ OSDictionary* org_pqrs_Karabiner_DriverKit_VirtualHIDKeyboard::newDeviceDescript
serialNumber->release();
}

if (auto vendorId = OSNumber::withNumber(static_cast<uint32_t>(0x16c0), 32)) {
uint32_t keyboardVendorId = 0x16c0;
if (ivars->provider) {
keyboardVendorId = ivars->provider->getKeyboardVendorId();
}
if (auto vendorId = OSNumber::withNumber(keyboardVendorId, 32)) {
OSDictionarySetValue(dictionary, kIOHIDVendorIDKey, vendorId);
vendorId->release();
}

if (auto productId = OSNumber::withNumber(static_cast<uint32_t>(0x27db), 32)) {
uint32_t keyboardProductId = 0x27db;
if (ivars->provider) {
keyboardProductId = ivars->provider->getKeyboardProductId();
}
if (auto productId = OSNumber::withNumber(keyboardProductId, 32)) {
OSDictionarySetValue(dictionary, kIOHIDProductIDKey, productId);
productId->release();
}
Expand Down
6 changes: 3 additions & 3 deletions version.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"package_version": "4.3.0",
"driver_version": "1.7.0",
"client_protocol_version": 4
"package_version": "4.3.1",
"driver_version": "1.8.0",
"client_protocol_version": 5
}

0 comments on commit f1d35c6

Please sign in to comment.