bool set_config(const int32_t* const config_vector, mach_vm_size_t config_size) { // ------------------------------------------------------------ // check if (! remapclasses_) { IOLOG_ERROR("%s remapclasses_ == NULL.\n", __FUNCTION__); return false; } if (config_size != (BRIDGE_ESSENTIAL_CONFIG_INDEX__END__ + remapclasses_->size()) * sizeof(int32_t)) { IOLOG_ERROR("%s config_size mismatch.\n", __FUNCTION__); return false; } // ------------------------------------------------------------ // essential config const int32_t* p = config_vector; Config::set_essential_config(p, BRIDGE_ESSENTIAL_CONFIG_INDEX__END__); // remapclasses config p += BRIDGE_ESSENTIAL_CONFIG_INDEX__END__; for (size_t i = 0; i < remapclasses_->size(); ++i) { RemapClass* rc = (*remapclasses_)[i]; if (! rc) { IOLOG_ERROR("%s RemapClass == NULL.\n", __FUNCTION__); } else { rc->setEnabled(p[i]); } } refresh(); return true; }
// ====================================================================== static void refresh_timer_callback(OSObject* owner, IOTimerEventSource* sender) { if (! remapclasses_) { IOLOG_ERROR("RemapClassManager::refresh_core remapclasses_ == NULL.\n"); return; } // ---------------------------------------- if (enabled_remapclasses_) { delete enabled_remapclasses_; } enabled_remapclasses_ = new Vector_RemapClassPointer(); if (! enabled_remapclasses_) return; // ---------------------------------------- KeyboardRepeat::cancel(); statusmessage_[0] = '\0'; isEventInputQueueDelayEnabled_ = false; for (size_t i = 0; i < remapclasses_->size(); ++i) { RemapClass* p = (*remapclasses_)[i]; if (! p) continue; if (p->enabled()) { enabled_remapclasses_->push_back(p); const char* msg = p->get_statusmessage(); if (msg) { strlcat(statusmessage_, msg, sizeof(statusmessage_)); strlcat(statusmessage_, " ", sizeof(statusmessage_)); } if (p->is_simultaneouskeypresses()) { isEventInputQueueDelayEnabled_ = true; } } } if (strcmp(statusmessage_, lastmessage_) != 0) { strlcpy(lastmessage_, statusmessage_, sizeof(lastmessage_)); int index = BRIDGE_USERCLIENT_STATUS_MESSAGE_EXTRA; CommonData::clear_statusmessage(index); CommonData::append_statusmessage(index, statusmessage_); CommonData::send_notification_statusmessage(index); } }
bool isEnabled(size_t configindex) { if (! remapclasses_) return false; if (configindex >= remapclasses_->size()) { IOLOG_ERROR("RemapClass::isEnabled invalid configindex.\n"); return false; } RemapClass* p = (*remapclasses_)[configindex]; if (! p) return false; return p->enabled(); }
bool remap_dropkeyafterremap(const Params_KeyboardEventCallBack& params) { bool dropped = false; if (enabled_remapclasses_) { for (size_t i = 0; i < enabled_remapclasses_->size(); ++i) { RemapClass* p = (*enabled_remapclasses_)[i]; if (p) { if (p->remap_dropkeyafterremap(params)) dropped = true; } } } return dropped; }
// ====================================================================== static void refresh_core(OSObject* owner, IOTimerEventSource* sender) { IOLockWrapper::ScopedLock lk(lock_); if (! remapclasses_) return; // ---------------------------------------- if (enabled_remapclasses_) { delete enabled_remapclasses_; } enabled_remapclasses_ = new Vector_RemapClassPointer(); if (! enabled_remapclasses_) return; // ---------------------------------------- KeyboardRepeat::cancel(); statusmessage_[0] = '\0'; isEventInputQueueDelayEnabled_ = false; for (size_t i = 0; i < remapclasses_->size(); ++i) { RemapClass* p = (*remapclasses_)[i]; if (! p) continue; if (p->enabled()) { enabled_remapclasses_->push_back(p); const char* msg = p->get_statusmessage(); if (msg) { strlcat(statusmessage_, msg, sizeof(statusmessage_)); strlcat(statusmessage_, " ", sizeof(statusmessage_)); } if (p->is_simultaneouskeypresses()) { isEventInputQueueDelayEnabled_ = true; } } } if (strcmp(statusmessage_, lastmessage_) != 0) { KeyRemap4MacBook_bridge::StatusMessage::Request request(KeyRemap4MacBook_bridge::StatusMessage::MESSAGETYPE_EXTRA, statusmessage_); KeyRemap4MacBook_client::sendmsg(KeyRemap4MacBook_bridge::REQUEST_STATUS_MESSAGE, &request, sizeof(request), NULL, 0); strlcpy(lastmessage_, statusmessage_, sizeof(lastmessage_)); } }
bool remap_simultaneouskeypresses(void) { bool queue_changed = false; if (enabled_remapclasses_) { for (size_t i = 0; i < enabled_remapclasses_->size(); ++i) { RemapClass* p = (*enabled_remapclasses_)[i]; if (p) { if (p->remap_simultaneouskeypresses()) { queue_changed = true; } } } } return queue_changed; }
bool isEnabled(size_t configindex) { // isEnabled called in remap_key, remap_consumer, ... // So, don't make ScopedLock(lock_). if (! remapclasses_) return false; if (configindex >= remapclasses_->size()) { IOLOG_ERROR("RemapClass::isEnabled invalid configindex.\n"); return false; } RemapClass* p = (*remapclasses_)[configindex]; if (! p) return false; return p->enabled(); }
bool VirtualKey::VK_CONFIG::handle(const Params_KeyboardEventCallBack& params, AutogenId autogenId) { RemapClass* remapclass = nullptr; bool value_old = false; for (size_t i = 0; i < items_.size(); ++i) { remapclass = items_[i].remapclass; KeyCode keycode_toggle(items_[i].keycode_toggle); KeyCode keycode_force_on(items_[i].keycode_force_on); KeyCode keycode_force_off(items_[i].keycode_force_off); KeyCode keycode_sync_keydownup(items_[i].keycode_sync_keydownup); if (!remapclass) return false; value_old = remapclass->enabled(); if (params.key == keycode_toggle) { if (params.repeat) goto finish; if (params.ex_iskeydown) { remapclass->toggleEnabled(); goto refresh; } goto finish; } else if (params.key == keycode_force_on) { if (params.repeat) goto finish; if (params.ex_iskeydown) { remapclass->setEnabled(true); goto refresh; } goto finish; } else if (params.key == keycode_force_off) { if (params.repeat) goto finish; if (params.ex_iskeydown) { remapclass->setEnabled(false); goto refresh; } goto finish; } else if (params.key == keycode_sync_keydownup) { if (params.repeat) goto finish; if (params.ex_iskeydown) { remapclass->setEnabled(true); } else { remapclass->setEnabled(false); } goto refresh; } } return false; refresh: if (remapclass) { bool value_new = remapclass->enabled(); // * send_notification_to_userspace takes a time. // * VK_CONFIG_FORCE_OFF_* might not change remapclass state. // Therefore, we call send_notification_to_userspace only if needed. if (value_old != value_new) { RemapClassManager::refresh(); // Tell remapclass status is changed to userspace. org_pqrs_driver_Karabiner_UserClient_kext::send_notification_to_userspace(BRIDGE_USERCLIENT_NOTIFICATION_TYPE_CONFIG_ENABLED_UPDATED, remapclass->get_configindex()); } } finish: EventOutputQueue::FireModifiers::fire(); return true; }
bool VirtualKey::VK_CONFIG::handle(const Params_KeyboardEventCallBack& params) { if (! items_) return false; RemapClass* remapclass = NULL; for (size_t i = 0; i < items_->size(); ++i) { remapclass = (*items_)[i].remapclass; unsigned int keycode_toggle = (*items_)[i].keycode_toggle; unsigned int keycode_force_on = (*items_)[i].keycode_force_on; unsigned int keycode_force_off = (*items_)[i].keycode_force_off; unsigned int keycode_sync_keydownup = (*items_)[i].keycode_sync_keydownup; if (! remapclass) return false; if (params.ex_iskeydown && params.repeat == false) { /* */ if (params.key == keycode_toggle) { remapclass->toggleEnabled(); goto refresh; } else if (params.key == keycode_force_on) { remapclass->setEnabled(true); goto refresh; } else if (params.key == keycode_force_off) { remapclass->setEnabled(false); goto refresh; } else if (params.key == keycode_sync_keydownup) { remapclass->setEnabled(true); goto refresh; } } else if (params.eventType == EventType::UP) { if (params.key == keycode_toggle || params.key == keycode_force_on || params.key == keycode_force_off) { goto finish; } if (params.key == keycode_sync_keydownup) { remapclass->setEnabled(false); goto refresh; } } } return false; refresh: RemapClassManager::refresh(); // Tell remapclass status is changed to userspace. if (remapclass) { org_pqrs_driver_KeyRemap4MacBook_UserClient_kext::send_notification_to_userspace(BRIDGE_USERCLIENT_NOTIFICATION_TYPE_CONFIG_ENABLED_UPDATED, remapclass->get_configindex()); } finish: EventOutputQueue::FireModifiers::fire(); return true; }