// ====================================================================== static void refresh_timer_callback(OSObject* owner, IOTimerEventSource* sender) { if (! remapclasses_) { IOLOG_ERROR("RemapClassManager::refresh_core remapclasses_ == NULL.\n"); return; } // ---------------------------------------- if (enabled_remapclasses_) { // call disabled_callback for (size_t i = 0; i < enabled_remapclasses_->size(); ++i) { RemapClass* p = (*enabled_remapclasses_)[i]; if (p && ! p->enabled()) { p->call_disabled_callback(); } } 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) { pqrs::strlcpy_utf8::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(); }
// ====================================================================== 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 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; }