void FlagStatus::updateStatusMessage(void) { #ifndef FLAGSTATUS_TEST Flags f = FlagStatus::getLockedFlags(); if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_general_show_sticky_modifier_status)) { f.add(FlagStatus::getStickyFlags()); } if (f != statusMessageFlags_) { int index = BRIDGE_USERCLIENT_STATUS_MESSAGE_MODIFIER; CommonData::clear_statusmessage(index); if (f.isOn(ModifierFlag::FN)) { CommonData::append_statusmessage(index, "FN "); } if (f.isOn(ModifierFlag::COMMAND_L) || f.isOn(ModifierFlag::COMMAND_R)) { CommonData::append_statusmessage(index, "Cmd "); } if (f.isOn(ModifierFlag::CONTROL_L) || f.isOn(ModifierFlag::CONTROL_R)) { CommonData::append_statusmessage(index, "Ctrl "); } if (f.isOn(ModifierFlag::OPTION_L) || f.isOn(ModifierFlag::OPTION_R)) { CommonData::append_statusmessage(index, "Opt "); } if (f.isOn(ModifierFlag::SHIFT_L) || f.isOn(ModifierFlag::SHIFT_R)) { CommonData::append_statusmessage(index, "Shift "); } if (f.isOn(ModifierFlag::EXTRA1)) { CommonData::append_statusmessage(index, "Ex1 "); } if (f.isOn(ModifierFlag::EXTRA2)) { CommonData::append_statusmessage(index, "Ex2 "); } if (f.isOn(ModifierFlag::EXTRA3)) { CommonData::append_statusmessage(index, "Ex3 "); } if (f.isOn(ModifierFlag::EXTRA4)) { CommonData::append_statusmessage(index, "Ex4 "); } if (f.isOn(ModifierFlag::EXTRA5)) { CommonData::append_statusmessage(index, "Ex5 "); } CommonData::send_notification_statusmessage(index); } statusMessageFlags_ = f; #endif }
// ------------------------------------------------------------ bool EventType::isKeyDownOrModifierDown(KeyCode key, Flags flags) const { if (*this == EventType::DOWN) return true; if (*this == EventType::MODIFY) { return flags.isOn(key.getModifierFlag()); } return false; }
Flags& Flags::remove(ModifierFlag flag) { // We consider the following case. // (ModifierFlag::SHIFT_L | ModifierFlag::SHIFT_R).remove(ModifierFlag::SHIFT_L). // // The value of SHIFT_L and SHIFT_R is below. // // ModifierFlag::SHIFT_L : 0x20002 // ModifierFlag::SHIFT_R : 0x20004 // // So, the correct value of above case is 0x20004 (SHIFT_R). // // If we remove bits simple way (value_ &= ~flags), // the result value becomes 0x00004. It's not right. // // Therefore, we save the old value, and restore the necessary bits from it. // Flags old = *this; // keep ModifierFlag::NUMPAD. value_ &= ~(flag.getRawBits()); auto& pairs = KeyCodeModifierFlagPairs::getPairs(); for (size_t i = 0; i < pairs.size(); ++i) { ModifierFlag f = pairs[i].getModifierFlag(); if (f == flag) continue; if (!old.isOn(f)) continue; value_ |= f.getRawBits(); } return *this; }
ScopedTemporaryFlagsChanger(Flags toFlags) { count_ = new int[MAXNUM]; if (! count_) return; for (int i = 0;; ++i) { count_[i] = 0; ModifierFlag flag = getFlag(i); if (flag == ModifierFlag::NONE) break; // ---------------------------------------- // reset flag while (! makeFlags().isOn(flag)) { temporary_increase(flag); ++count_[i]; } while (makeFlags().isOn(flag)) { temporary_decrease(flag); --count_[i]; } // ---------------------------------------- // set a flag if (toFlags.isOn(flag)) { temporary_increase(flag); ++count_[i]; } } }
bool isOn(Flags flags) const { if (flags.isOn(ModifierFlag::NONE)) { return (value_ | ModifierFlag::NONE.get()) == flags.get(); } else { return (value_ & flags.get()) == flags.get(); } }
void ListHookedKeyboard::setcapslock_timer_callback(OSObject* owner, IOTimerEventSource* sender) { ListHookedKeyboard& self = ListHookedKeyboard::instance(); if (Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_general_passthrough_capslock_led_status)) return; Flags flags = FlagStatus::globalFlagStatus().makeFlags(); for (Item* p = static_cast<Item*>(self.list_.safe_front()); p; p = static_cast<Item*>(p->getnext())) { if (!p->isReplaced()) continue; // Don't call setAlphaLock on devices which have non-Apple driver. if (p->getDeviceType() != DeviceType::APPLE_INTERNAL && p->getDeviceType() != DeviceType::APPLE_EXTERNAL) { continue; } IOHIKeyboard* kbd = OSDynamicCast(IOHIKeyboard, p->get()); if (!kbd) continue; { GlobalLock::ScopedUnlock lk; // We call setAlphaLock to match a state of CapsLock of the hardware with remapped CapsLock. if (flags.isOn(ModifierFlag::CAPSLOCK)) { if (!kbd->alphaLock()) { kbd->setAlphaLock(true); } } else { if (kbd->alphaLock()) { kbd->setAlphaLock(false); } } } } }
FlagStatus::FlagStatus(Flags flags) { initialize(); for (size_t i = 0; i < item_.size(); ++i) { if (flags.isOn(item_[i].flag_)) { item_[i].increase(); } } }
void FlagStatus::Item::set(KeyCode key, Flags flags) { temporary_count_ = 0; // ------------------------------------------------------------ if (key != flag_.getKeyCode()) return; // ------------------------------------------------------------ if (flag_ == ModifierFlag::CAPSLOCK) { if (flags.isOn(flag_)) { lock_count_ = 1; } else { lock_count_ = 0; } } else { if (flags.isOn(flag_)) { increase(); } else { decrease(); } } }
bool KeyCode::FNKeyHack::remap(KeyCode& key, Flags flags, EventType eventType, bool& active, KeyCode fromKeyCode, KeyCode toKeyCode) { if (key != fromKeyCode) return false; bool isKeyDown = eventType.isKeyDownOrModifierDown(key, flags); if (isKeyDown) { if (!flags.isOn(ModifierFlag::FN)) return false; active = true; } else { if (!active) return false; active = false; } key = toKeyCode; return true; }
bool FromEvent::changePressingState(const ParamsUnion& paramsUnion, Flags currentFlags, Flags fromFlags) { bool isDown = false; if (! isTargetEvent(isDown, paramsUnion)) return false; if (isDown) { if (currentFlags.isOn(fromFlags)) { isPressing_ = true; return true; } } else { if (isPressing_) { isPressing_ = false; return true; } } return false; }
ScopedTemporaryFlagsChanger(FlagStatus& flagStatus, Flags toFlags) : flagStatus_(flagStatus) { for (size_t i = 0; i < flagStatus_.item_.size(); ++i) { count_.push_back(0); // ---------------------------------------- // reset flag while (flagStatus_.item_[i].sum() < 0) { flagStatus_.item_[i].temporary_increase(); ++(count_.back()); } while (flagStatus_.item_[i].sum() > 0) { flagStatus_.item_[i].temporary_decrease(); --(count_.back()); } // ---------------------------------------- // set a flag ModifierFlag flag = flagStatus_.getFlag(i); if (toFlags.isOn(flag)) { flagStatus_.item_[i].temporary_increase(); ++(count_.back()); } } }
TEST(Flags, isOn) { Flags mask = ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_R | ModifierFlag::COMMAND_R; Flags flags = mask; EXPECT_TRUE(flags.isOn(Flags(0))); EXPECT_TRUE(flags.isOn(ModifierFlag::SHIFT_L)); EXPECT_FALSE(flags.isOn(ModifierFlag::SHIFT_R)); flags = ModifierFlag::NONE; EXPECT_TRUE(flags.isOn(ModifierFlag::NONE)); flags = 0; EXPECT_FALSE(flags.isOn(ModifierFlag::NONE)); EXPECT_TRUE(flags.isOn(Flags(ModifierFlag::NONE))); EXPECT_TRUE(flags.isOn(Flags(0))); flags = ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_R | ModifierFlag::COMMAND_R; EXPECT_TRUE(flags.isOn(ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_R)); EXPECT_TRUE(flags.isOn(Flags(0))); EXPECT_TRUE(flags.isOn(ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_R | ModifierFlag::COMMAND_R | ModifierFlag::NONE)); EXPECT_FALSE(flags.isOn(ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_R | ModifierFlag::NONE)); }
void EventOutputQueue::FireModifiers::fire(Flags toFlags, KeyboardType keyboardType) { toFlags.stripNONE(); toFlags.stripEXTRA(); if (lastFlags_ == toFlags) return; // ------------------------------------------------------------ // At first we handle KeyUp events and handle KeyDown events next. // We need to end KeyDown at Command+Space to Option_L+Shift_L. // // When Option_L+Shift_L has a meaning (switch input language at Windows), // it does not works well when the last is KeyUp of Command. // ------------------------------------------------------------ // About ModifierFlag::CURSOR (UpdateEventFlags) handling: // // We need to treat ModifierFlag::CURSOR specially. // // When we activated "Control+Right to Option+Right" and pressed Control+Right, // the following events are happened. // // ----------------------+---------------------------------------------------------------------- // (1) Press Control_L | eventType:keyMod code:0x3b name:Control_L flags: misc: // (2) Press Right | eventType:keyMod code:0x3a name:Option_L flags:Opt misc: // | eventType:keyDown code:0x7c name:Right flags:Opt NumPad Fn misc: // (3) Release Right | eventType:keyUp code:0x7c name:Right flags:Opt NumPad Fn misc: // (4) Release Control_L | eventType:keyMod code:0x3a name:Option_L flags: misc: // ----------------------+---------------------------------------------------------------------- // // We need to treat "ModifierFlag::CURSOR Down" event after other modifiers. // We need to treat "ModifierFlag::CURSOR Up" event before other modifiers. // If not, unnecessary ModifierFlag::CURSOR is added on keyMod events. // ModifierFlag::CURSOR (Up) if (lastFlags_.isOn(ModifierFlag::CURSOR) && ! toFlags.isOn(ModifierFlag::CURSOR)) { lastFlags_.remove(ModifierFlag::CURSOR); Params_UpdateEventFlagsCallback::auto_ptr ptr(Params_UpdateEventFlagsCallback::alloc(lastFlags_)); if (ptr) { EventOutputQueue::push(*ptr); } } // ------------------------------------------------------------ // KeyUp for (int i = 0;; ++i) { ModifierFlag flag = FlagStatus::getFlag(i); if (flag == ModifierFlag::NONE) break; if (flag == ModifierFlag::CURSOR) continue; if (Flags(flag).isVirtualModifiersOn()) continue; if (! lastFlags_.isOn(flag)) continue; if (toFlags.isOn(flag)) continue; lastFlags_.remove(flag); Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false)); if (! ptr) continue; EventOutputQueue::push(*ptr); } // KeyDown for (int i = 0;; ++i) { ModifierFlag flag = FlagStatus::getFlag(i); if (flag == ModifierFlag::NONE) break; if (flag == ModifierFlag::CURSOR) continue; if (Flags(flag).isVirtualModifiersOn()) continue; if (! toFlags.isOn(flag)) continue; if (lastFlags_.isOn(flag)) continue; lastFlags_.add(flag); Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false)); if (! ptr) continue; EventOutputQueue::push(*ptr); } // ------------------------------------------------------------ // ModifierFlag::CURSOR (Down) if (! lastFlags_.isOn(ModifierFlag::CURSOR) && toFlags.isOn(ModifierFlag::CURSOR)) { lastFlags_.add(ModifierFlag::CURSOR); Params_UpdateEventFlagsCallback::auto_ptr ptr(Params_UpdateEventFlagsCallback::alloc(lastFlags_)); if (ptr) { EventOutputQueue::push(*ptr); } } lastFlags_ = toFlags; }
void EventOutputQueue::FireModifiers::fire(AutogenId autogenId, PhysicalEventType physicalEventType, Flags toFlags, KeyboardType keyboardType) { if (lastFlags_ == toFlags) return; if (physicalEventType == PhysicalEventType::DOWN) { isIgnorePhysicalUpEvent_ = false; } else if (physicalEventType == PhysicalEventType::UP) { if (isIgnorePhysicalUpEvent_) { return; } } // ------------------------------------------------------------ // At first we handle KeyUp events and handle KeyDown events next. // We need to end KeyDown at Command+Space to Option_L+Shift_L. // // When Option_L+Shift_L has a meaning (switch input language at Windows), // it does not works well when the last is KeyUp of Command. // ModifierFlag::NUMPAD handling. // (We need to remove ModifierFlag::NUMPAD at first in order to strip NUMPAD flag from normal modifier key events.) if (!toFlags.isOn(ModifierFlag::NUMPAD)) { lastFlags_.remove(ModifierFlag::NUMPAD); } // ------------------------------------------------------------ // KeyUp for (size_t i = 0; i < FlagStatus::globalFlagStatus().itemSize(); ++i) { ModifierFlag flag = FlagStatus::globalFlagStatus().getFlag(i); // Skipping invalid flags if (flag.getKeyCode() == KeyCode::VK_NONE) continue; // Skipping virtual modifiers. if (flag.getRawBits() == 0) continue; // ---------------------------------------- if (!lastFlags_.isOn(flag)) continue; if (toFlags.isOn(flag)) continue; lastFlags_.remove(flag); Params_KeyboardEventCallBack params(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false); EventOutputQueue::push(params, autogenId); } // KeyDown for (size_t i = 0; i < FlagStatus::globalFlagStatus().itemSize(); ++i) { ModifierFlag flag = FlagStatus::globalFlagStatus().getFlag(i); // Skipping invalid flags if (flag.getKeyCode() == KeyCode::VK_NONE) continue; // Skipping virtual modifiers. if (flag.getRawBits() == 0) continue; // ---------------------------------------- if (!toFlags.isOn(flag)) continue; if (lastFlags_.isOn(flag)) continue; lastFlags_.add(flag); Params_KeyboardEventCallBack params(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false); EventOutputQueue::push(params, autogenId); } // ModifierFlag::NUMPAD handling. // (We need to add ModifierFlag::NUMPAD at last in order to strip NUMPAD flag from normal modifier key events.) if (toFlags.isOn(ModifierFlag::NUMPAD)) { lastFlags_.add(ModifierFlag::NUMPAD); } }