TEST(Flags, stripEXTRA) { Flags mask = ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_R | ModifierFlag::COMMAND_R; Flags flags = mask; EXPECT_EQ(mask, flags.stripEXTRA()); flags.add(ModifierFlag::EXTRA1); EXPECT_EQ(mask, flags.stripEXTRA()); flags.add(ModifierFlag::EXTRA2); EXPECT_EQ(mask, flags.stripEXTRA()); flags.add(ModifierFlag::EXTRA3 | ModifierFlag::EXTRA5); EXPECT_EQ(mask, flags.stripEXTRA()); }
// ====================================================================== void EventOutputQueue::FireKey::fire(const Params_KeyboardEventCallBack& params) { if (VirtualKey::handle(params)) return; // ---------------------------------------- if (params.key == KeyCode::VK_MODIFIER_EXTRA1 || params.key == KeyCode::VK_MODIFIER_EXTRA2 || params.key == KeyCode::VK_MODIFIER_EXTRA3 || params.key == KeyCode::VK_MODIFIER_EXTRA4 || params.key == KeyCode::VK_MODIFIER_EXTRA5) return; // ------------------------------------------------------------ KeyCode newkeycode = params.key; Flags newflags = params.flags; KeyCode::reverseNormalizeKey(newkeycode, newflags, params.eventType, params.keyboardType); newflags.stripEXTRA(); // skip no-outputable keycodes. // Note: check before FireModifiers to avoid meaningless modifier event. if (newkeycode == KeyCode::VK_NONE || newkeycode == KeyCode::VK_PSEUDO_KEY) { return; } FireModifiers::fire(newflags, params.keyboardType); if (params.eventType == EventType::DOWN || params.eventType == EventType::UP) { Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(params.eventType, newflags, newkeycode, params.charCode, params.charSet, params.origCharCode, params.origCharSet, params.keyboardType, params.repeat)); if (ptr) { EventOutputQueue::push(*ptr); } if (! params.repeat) { if (params.eventType == EventType::DOWN) { PressDownKeys::add(newkeycode, params.keyboardType); } else { PressDownKeys::remove(newkeycode, params.keyboardType); } } } }
// ====================================================================== void EventOutputQueue::FireConsumer::fire(const Params_KeyboardSpecialEventCallback& params) { Flags newflags = params.flags; newflags.stripEXTRA(); // skip no-outputable keycodes. // Note: check before FireModifiers to avoid meaningless modifier event. if (params.key == ConsumerKeyCode::VK_NONE || params.key == ConsumerKeyCode::VK_PSEUDO_KEY) { return; } FireModifiers::fire(); Params_KeyboardSpecialEventCallback::auto_ptr ptr(Params_KeyboardSpecialEventCallback::alloc(params.eventType, newflags, params.key, params.repeat)); if (ptr) { EventOutputQueue::push(*ptr); } }
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; }