Chromium Code Reviews| Index: chrome/browser/ui/ash/event_rewriter.cc |
| diff --git a/chrome/browser/ui/ash/event_rewriter.cc b/chrome/browser/ui/ash/event_rewriter.cc |
| index 42b1b8e6d928b410dc41ab1c72bb1c6bf1488542..b6364dd2ae631061e7e97959c38dba158856dc22 100644 |
| --- a/chrome/browser/ui/ash/event_rewriter.cc |
| +++ b/chrome/browser/ui/ash/event_rewriter.cc |
| @@ -121,12 +121,6 @@ bool HasChromeOSKeyboard() { |
| switches::kHasChromeOSKeyboard); |
| } |
| -bool EventSourceIsChromebookKeyboard(ui::KeyEvent* /* event */) { |
| - // TODO(danakj): Determine if the event came from a Chromebook internal |
| - // keyboard. |
| - return true; |
| -} |
| - |
| bool IsMod3UsedByCurrentInputMethod() { |
| // Since both German Neo2 XKB layout and Caps Lock depend on Mod3Mask, |
| // it's not possible to make both features work. For now, we don't remap |
| @@ -149,6 +143,7 @@ const PrefService* GetPrefService() { |
| EventRewriter::EventRewriter() |
| : last_device_id_(kBadDeviceId), |
| #if defined(OS_CHROMEOS) |
| + force_chromeos_keyboard_for_testing_(false), |
| xkeyboard_(NULL), |
| #endif |
| pref_service_(NULL) { |
| @@ -200,6 +195,15 @@ EventRewriter::DeviceType EventRewriter::GetDeviceType( |
| return kDeviceAppleKeyboard; |
| } |
| + if (HasChromeOSKeyboard()) { |
| + // The chromebook internal keyboard's name. |
| + if (LowerCaseEqualsASCII(device_name, "at translated set 2 keyboard")) |
| + return kDeviceChromeOSKeyboard; |
| + // The chromebox chrome-specific keyboard's name. |
| + if (LowerCaseEqualsASCII(device_name, "samsung usb keyboard")) |
| + return kDeviceChromeOSKeyboard; |
| + } |
| + |
| return kDeviceUnknown; |
| } |
| @@ -275,90 +279,97 @@ void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { |
| } |
| void EventRewriter::RefreshKeycodes() { |
| - Display* display = ui::GetXDisplay(); |
| - control_l_xkeycode_ = XKeysymToKeycode(display, XK_Control_L); |
| - control_r_xkeycode_ = XKeysymToKeycode(display, XK_Control_R); |
| - alt_l_xkeycode_ = XKeysymToKeycode(display, XK_Alt_L); |
| - alt_r_xkeycode_ = XKeysymToKeycode(display, XK_Alt_R); |
| - meta_l_xkeycode_ = XKeysymToKeycode(display, XK_Meta_L); |
| - meta_r_xkeycode_ = XKeysymToKeycode(display, XK_Meta_R); |
| - windows_l_xkeycode_ = XKeysymToKeycode(display, XK_Super_L); |
| - caps_lock_xkeycode_ = XKeysymToKeycode(display, XK_Caps_Lock); |
| - void_symbol_xkeycode_ = XKeysymToKeycode(display, XK_VoidSymbol); |
| - delete_xkeycode_ = XKeysymToKeycode(display, XK_Delete); |
| - home_xkeycode_ = XKeysymToKeycode(display, XK_Home); |
| - end_xkeycode_ = XKeysymToKeycode(display, XK_End); |
| - prior_xkeycode_ = XKeysymToKeycode(display, XK_Prior); |
| - next_xkeycode_ = XKeysymToKeycode(display, XK_Next); |
| - kp_0_xkeycode_ = XKeysymToKeycode(display, XK_KP_0); |
| - kp_1_xkeycode_ = XKeysymToKeycode(display, XK_KP_1); |
| - kp_2_xkeycode_ = XKeysymToKeycode(display, XK_KP_2); |
| - kp_3_xkeycode_ = XKeysymToKeycode(display, XK_KP_3); |
| - kp_4_xkeycode_ = XKeysymToKeycode(display, XK_KP_4); |
| - kp_5_xkeycode_ = XKeysymToKeycode(display, XK_KP_5); |
| - kp_6_xkeycode_ = XKeysymToKeycode(display, XK_KP_6); |
| - kp_7_xkeycode_ = XKeysymToKeycode(display, XK_KP_7); |
| - kp_8_xkeycode_ = XKeysymToKeycode(display, XK_KP_8); |
| - kp_9_xkeycode_ = XKeysymToKeycode(display, XK_KP_9); |
| - kp_decimal_xkeycode_ = XKeysymToKeycode(display, XK_KP_Decimal); |
| + keysym_to_keycode_map_.clear(); |
| } |
| KeyCode EventRewriter::NativeKeySymToNativeKeycode(KeySym keysym) { |
| - switch (keysym) { |
| - case XK_Control_L: |
| - return control_l_xkeycode_; |
| - case XK_Control_R: |
| - return control_r_xkeycode_; |
| - case XK_Alt_L: |
| - return alt_l_xkeycode_; |
| - case XK_Alt_R: |
| - return alt_r_xkeycode_; |
| - case XK_Meta_L: |
| - return meta_l_xkeycode_; |
| - case XK_Meta_R: |
| - return meta_r_xkeycode_; |
| - case XK_Super_L: |
| - return windows_l_xkeycode_; |
| - case XK_Caps_Lock: |
| - return caps_lock_xkeycode_; |
| - case XK_VoidSymbol: |
| - return void_symbol_xkeycode_; |
| - case XK_Delete: |
| - return delete_xkeycode_; |
| - case XK_Home: |
| - return home_xkeycode_; |
| - case XK_End: |
| - return end_xkeycode_; |
| - case XK_Prior: |
| - return prior_xkeycode_; |
| - case XK_Next: |
| - return next_xkeycode_; |
| - case XK_KP_0: |
| - return kp_0_xkeycode_; |
| - case XK_KP_1: |
| - return kp_1_xkeycode_; |
| - case XK_KP_2: |
| - return kp_2_xkeycode_; |
| - case XK_KP_3: |
| - return kp_3_xkeycode_; |
| - case XK_KP_4: |
| - return kp_4_xkeycode_; |
| - case XK_KP_5: |
| - return kp_5_xkeycode_; |
| - case XK_KP_6: |
| - return kp_6_xkeycode_; |
| - case XK_KP_7: |
| - return kp_7_xkeycode_; |
| - case XK_KP_8: |
| - return kp_8_xkeycode_; |
| - case XK_KP_9: |
| - return kp_9_xkeycode_; |
| - case XK_KP_Decimal: |
| - return kp_decimal_xkeycode_; |
| - default: |
| - break; |
| + base::hash_map<KeySym, KeyCode>::iterator it; |
|
Daniel Erat
2012/11/29 04:54:23
nit: delete this; it doesn't look like you're usin
danakj
2012/11/30 03:07:40
Done.
|
| + |
| + if (keysym_to_keycode_map_.count(keysym)) |
| + return keysym_to_keycode_map_[keysym]; |
| + |
| + Display* display = ui::GetXDisplay(); |
| + KeyCode keycode = XKeysymToKeycode(display, keysym); |
| + keysym_to_keycode_map_[keysym] = keycode; |
| + return keycode; |
| +} |
| + |
| +bool EventRewriter::EventSourceIsChromeOSKeyboard() const { |
| + if (force_chromeos_keyboard_for_testing_) |
| + return true; |
| + |
| + if (last_device_id_ == kBadDeviceId) |
| + return false; |
| + |
| + // Check which device generated |event|. |
| + std::map<int, DeviceType>::const_iterator iter = |
| + device_id_to_type_.find(last_device_id_); |
| + if (iter == device_id_to_type_.end()) { |
| + LOG(ERROR) << "Device ID " << last_device_id_ << " is unknown."; |
| + return false; |
| + } |
| + |
| + const DeviceType type = iter->second; |
| + return type == kDeviceChromeOSKeyboard; |
| +} |
| + |
| +bool EventRewriter::RewriteWithKeyboardRemappingsByKeySym( |
| + const KeyboardRemapping* remappings, |
| + size_t num_remappings, |
| + KeySym keysym, |
| + unsigned int native_mods, |
| + unsigned int mods, |
| + KeySym* remapped_native_keysym, |
| + unsigned int* remapped_native_mods, |
| + ui::KeyboardCode* remapped_keycode, |
| + unsigned int* remapped_mods) { |
| + for (size_t i = 0; i < num_remappings; ++i) { |
| + const KeyboardRemapping& map = remappings[i]; |
| + |
| + if (keysym != map.input_keysym) |
| + continue; |
| + unsigned int matched_mods = native_mods & map.input_native_mods; |
| + if (matched_mods != map.input_native_mods) |
| + continue; |
| + |
| + *remapped_native_keysym = map.output_keysym; |
| + *remapped_keycode = map.output_keycode; |
| + *remapped_native_mods = native_mods & ~map.input_native_mods; |
| + *remapped_mods = mods & ~map.input_mods; |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +bool EventRewriter::RewriteWithKeyboardRemappingsByKeyCode( |
| + const KeyboardRemapping* remappings, |
| + size_t num_remappings, |
| + KeyCode keycode, |
| + unsigned int native_mods, |
| + unsigned int mods, |
| + KeySym* remapped_native_keysym, |
| + unsigned int* remapped_native_mods, |
| + ui::KeyboardCode* remapped_keycode, |
| + unsigned int* remapped_mods) { |
| + for (size_t i = 0; i < num_remappings; ++i) { |
| + const KeyboardRemapping& map = remappings[i]; |
| + |
| + KeyCode input_keycode = NativeKeySymToNativeKeycode(map.input_keysym); |
| + if (keycode != input_keycode) |
| + continue; |
| + unsigned int matched_mods = native_mods & map.input_native_mods; |
| + if (matched_mods != map.input_native_mods) |
| + continue; |
| + |
| + *remapped_native_keysym = map.output_keysym; |
| + *remapped_keycode = map.output_keycode; |
| + *remapped_native_mods = native_mods & ~map.input_native_mods; |
| + *remapped_mods = mods & ~map.input_mods; |
| + return true; |
| } |
| - return 0U; |
| + |
| + return false; |
| } |
| #endif |
| @@ -372,7 +383,7 @@ void EventRewriter::Rewrite(ui::KeyEvent* event) { |
| RewriteModifiers(event); |
| RewriteNumPadKeys(event); |
| RewriteBackspaceAndArrowKeys(event); |
| - // TODO(yusukes): Implement crosbug.com/27167 (allow sending function keys). |
| + RewriteFunctionKeys(event); |
| } |
| bool EventRewriter::IsAppleKeyboard() const { |
| @@ -568,57 +579,68 @@ bool EventRewriter::RewriteNumPadKeys(ui::KeyEvent* event) { |
| const KeySym keysym = XLookupKeysym(xkey, 0); |
| switch (keysym) { |
| case XK_KP_Insert: |
| - OverwriteEvent(event, kp_0_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_0), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD0, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Delete: |
| - OverwriteEvent(event, kp_decimal_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_Decimal), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_DECIMAL, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_End: |
| - OverwriteEvent(event, kp_1_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_1), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD1, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Down: |
| - OverwriteEvent(event, kp_2_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_2), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD2, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Next: |
| - OverwriteEvent(event, kp_3_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_3), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD3, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Left: |
| - OverwriteEvent(event, kp_4_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_4), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD4, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Begin: |
| - OverwriteEvent(event, kp_5_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_5), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD5, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Right: |
| - OverwriteEvent(event, kp_6_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_6), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD6, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Home: |
| - OverwriteEvent(event, kp_7_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_7), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD7, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Up: |
| - OverwriteEvent(event, kp_8_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_8), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD8, event->flags()); |
| rewritten = true; |
| break; |
| case XK_KP_Prior: |
| - OverwriteEvent(event, kp_9_xkeycode_, xkey->state | Mod2Mask, |
| + OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_9), |
| + xkey->state | Mod2Mask, |
| ui::VKEY_NUMPAD9, event->flags()); |
| rewritten = true; |
| break; |
| @@ -642,13 +664,12 @@ bool EventRewriter::RewriteNumPadKeys(ui::KeyEvent* event) { |
| } |
| bool EventRewriter::RewriteBackspaceAndArrowKeys(ui::KeyEvent* event) { |
| - bool rewritten = false; |
| #if defined(OS_CHROMEOS) |
| - // On a Chromebook keyboard, modifier keys can be used to access extended |
| + // On a ChromeOS keyboard, modifier keys can be used to access extended |
| // keyboard shortcuts. On other keyboards, keys such as delete and page up are |
| // already available, so we do not need to rewrite anything here. |
| - if (!EventSourceIsChromebookKeyboard(event)) |
| - return rewritten; |
| + if (!EventSourceIsChromeOSKeyboard()) |
| + return false; |
| const PrefService* pref_service = |
| pref_service_ ? pref_service_ : GetPrefService(); |
| @@ -657,78 +678,212 @@ bool EventRewriter::RewriteBackspaceAndArrowKeys(ui::KeyEvent* event) { |
| bool search_as_function_key = chromebook_function_key && pref_service && |
| pref_service->GetBoolean(prefs::kLanguageSearchKeyActsAsFunctionKey); |
| + if (search_as_function_key) |
| + DCHECK(HasChromeOSKeyboard()); |
| XEvent* xev = event->native_event(); |
| XKeyEvent* xkey = &(xev->xkey); |
| const KeySym keysym = XLookupKeysym(xkey, 0); |
| + KeySym remapped_native_keysym = 0; |
| + unsigned int remapped_native_mods = 0; |
| + ui::KeyboardCode remapped_keycode = ui::VKEY_UNKNOWN; |
| + unsigned int remapped_mods = 0; |
| + |
| if (!search_as_function_key) { |
| - if (keysym == XK_BackSpace && (xkey->state & Mod1Mask)) { |
| - // Without Search as Function key: Remap Alt+Backspace to Delete. |
| - OverwriteEvent(event, delete_xkeycode_, xkey->state & ~Mod1Mask, |
| - ui::VKEY_DELETE, event->flags() & ~ui::EF_ALT_DOWN); |
| - rewritten = true; |
| - } else if (keysym == XK_Up && |
| - (xkey->state & ControlMask) && (xkey->state & Mod1Mask)) { |
| - // Without Search as Function key: Remap Ctrl+Alt+Up to Home. |
| - OverwriteEvent(event, |
| - home_xkeycode_, |
| - xkey->state & ~(Mod1Mask | ControlMask), |
| - ui::VKEY_HOME, |
| - event->flags() & ~(ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN)); |
| - rewritten = true; |
| - } else if (keysym == XK_Up && (xkey->state & Mod1Mask)) { |
| - // Without Search as Function key: Remap Alt+Up to Prior (aka PageUp). |
| - OverwriteEvent(event, prior_xkeycode_, xkey->state & ~Mod1Mask, |
| - ui::VKEY_PRIOR, event->flags() & ~ui::EF_ALT_DOWN); |
| - rewritten = true; |
| - } else if (keysym == XK_Down && |
| - (xkey->state & ControlMask) && (xkey->state & Mod1Mask)) { |
| - // Without Search as Function key: Remap Ctrl+Alt+Down to End. |
| - OverwriteEvent(event, |
| - end_xkeycode_, |
| - xkey->state & ~(Mod1Mask | ControlMask), |
| - ui::VKEY_END, |
| - event->flags() & ~(ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN)); |
| - rewritten = true; |
| - } else if (keysym == XK_Down && (xkey->state & Mod1Mask)) { |
| - // Without Search as Function key: Remap Alt+Down to Next (aka PageDown). |
| - OverwriteEvent(event, next_xkeycode_, xkey->state & ~Mod1Mask, |
| - ui::VKEY_NEXT, event->flags() & ~ui::EF_ALT_DOWN); |
| - rewritten = true; |
| - } |
| + static const KeyboardRemapping remappings[] = { |
| + { // Alt+BackSpace -> Delete |
| + XK_BackSpace, |
| + ui::EF_ALT_DOWN, Mod1Mask, |
| + XK_Delete, ui::VKEY_DELETE, |
| + }, |
| + { // Control+Alt+Up -> Home |
| + XK_Up, |
| + ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask, |
| + XK_Home, ui::VKEY_HOME, |
| + }, |
| + { // Alt+Up -> Prior (aka PageUp) |
| + XK_Up, |
| + ui::EF_ALT_DOWN, Mod1Mask, |
| + XK_Prior, ui::VKEY_PRIOR, |
| + }, |
| + { // Control+Alt+Down -> End |
| + XK_Down, |
| + ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask, |
| + XK_End, ui::VKEY_END, |
| + }, |
| + { // Alt+Down -> Next (aka PageDown) |
| + XK_Down, |
| + ui::EF_ALT_DOWN, Mod1Mask, |
| + XK_Next, ui::VKEY_NEXT, |
| + } |
| + }; |
| + |
| + RewriteWithKeyboardRemappingsByKeySym(remappings, |
| + arraysize(remappings), |
| + keysym, |
| + xkey->state, |
| + event->flags(), |
| + &remapped_native_keysym, |
| + &remapped_native_mods, |
| + &remapped_keycode, |
| + &remapped_mods); |
| } else { |
| - if (keysym == XK_BackSpace && (xkey->state & Mod4Mask)) { |
| - // With Search as Function key: Remap Search+Backspace to Delete. |
| - OverwriteEvent(event, delete_xkeycode_, xkey->state & ~Mod4Mask, |
| - ui::VKEY_DELETE, event->flags()); |
| - rewritten = true; |
| - } else if (keysym == XK_Left && (xkey->state & Mod4Mask)) { |
| - // With Search as Function key: Remap Search+Left to Home. |
| - OverwriteEvent(event, home_xkeycode_, xkey->state & ~Mod4Mask, |
| - ui::VKEY_HOME, event->flags()); |
| - rewritten = true; |
| - } else if (keysym == XK_Up && (xkey->state & Mod4Mask)) { |
| - // With Search as Function key: Remap Search+Up to Prior (aka PageUp). |
| - OverwriteEvent(event, prior_xkeycode_, xkey->state & ~Mod4Mask, |
| - ui::VKEY_PRIOR, event->flags()); |
| - rewritten = true; |
| - } else if (keysym == XK_Right && (xkey->state & Mod4Mask)) { |
| - // With Search as Function key: Remap Search+Right to End. |
| - OverwriteEvent(event, end_xkeycode_, xkey->state & ~Mod4Mask, |
| - ui::VKEY_END, event->flags()); |
| - rewritten = true; |
| - } else if (keysym == XK_Down && (xkey->state & Mod4Mask)) { |
| - // With Search as Function key: Remap Search+Down to Next (aka PageDown). |
| - OverwriteEvent(event, next_xkeycode_, xkey->state & ~Mod4Mask, |
| - ui::VKEY_NEXT, event->flags()); |
| - rewritten = true; |
| - } |
| + static const KeyboardRemapping remappings[] = { |
| + { // Search+BackSpace -> Delete |
| + XK_BackSpace, |
| + 0, Mod4Mask, |
| + XK_Delete, ui::VKEY_DELETE, |
| + }, |
| + { // Search+Left -> Home |
| + XK_Left, |
| + 0, Mod4Mask, |
| + XK_Home, ui::VKEY_HOME, |
| + }, |
| + { // Search+Up -> Prior (aka PageUp) |
| + XK_Up, |
| + 0, Mod4Mask, |
| + XK_Prior, ui::VKEY_PRIOR, |
| + }, |
| + { // Search+Right -> End |
| + XK_Right, |
| + 0, Mod4Mask, |
| + XK_End, ui::VKEY_END, |
| + }, |
| + { // Search+Down -> Next (aka PageDown) |
| + XK_Down, |
| + 0, Mod4Mask, |
| + XK_Next, ui::VKEY_NEXT, |
| + } |
| + }; |
| + |
| + RewriteWithKeyboardRemappingsByKeySym(remappings, |
| + arraysize(remappings), |
| + keysym, |
| + xkey->state, |
| + event->flags(), |
| + &remapped_native_keysym, |
| + &remapped_native_mods, |
| + &remapped_keycode, |
| + &remapped_mods); |
| } |
| + |
| + if (!remapped_native_keysym || remapped_keycode == ui::VKEY_UNKNOWN) |
| + return false; |
| + |
| + OverwriteEvent(event, |
| + NativeKeySymToNativeKeycode(remapped_native_keysym), |
| + remapped_native_mods, |
| + remapped_keycode, |
| + remapped_mods); |
| + return true; |
| #else |
| // TODO(yusukes): Support Ash on other platforms if needed. |
| + return false; |
| +#endif |
| +} |
| + |
| +bool EventRewriter::RewriteFunctionKeys(ui::KeyEvent* event) { |
| +#if defined(OS_CHROMEOS) |
| + XEvent* xev = event->native_event(); |
| + XKeyEvent* xkey = &(xev->xkey); |
| + const KeySym keysym = XLookupKeysym(xkey, 0); |
| + |
| + KeySym remapped_native_keysym = 0; |
| + unsigned int remapped_native_mods = 0; |
| + ui::KeyboardCode remapped_keycode = ui::VKEY_UNKNOWN; |
| + unsigned int remapped_mods = 0; |
| + |
| + // On a ChromeOS keyboard, F<number> keys have special purposes. On other |
| + // keyboards, they should act as usual. |
| + if (!EventSourceIsChromeOSKeyboard()) |
| + return false; |
| + |
| + // Rewrite the actual F1-F12 keys on a Chromebook keyboard to special keys. |
| + static const KeyboardRemapping fkeys_to_special_keys[] = { |
| + { XK_F1, 0, 0, XF86XK_Back, ui::VKEY_BROWSER_BACK, }, |
| + { XK_F2, 0, 0, XF86XK_Forward, ui::VKEY_BROWSER_FORWARD, }, |
| + { XK_F3, 0, 0, XF86XK_Reload, ui::VKEY_BROWSER_REFRESH, }, |
| + { XK_F4, 0, 0, XF86XK_LaunchB, ui::VKEY_MEDIA_LAUNCH_APP2, }, |
| + { XK_F5, 0, 0, XF86XK_LaunchA, ui::VKEY_MEDIA_LAUNCH_APP1, }, |
| + { XK_F6, 0, 0, XF86XK_MonBrightnessDown, ui::VKEY_BRIGHTNESS_DOWN, }, |
| + { XK_F7, 0, 0, XF86XK_MonBrightnessUp, ui::VKEY_BRIGHTNESS_UP, }, |
| + { XK_F8, 0, 0, XF86XK_AudioMute, ui::VKEY_VOLUME_MUTE, }, |
| + { XK_F9, 0, 0, XF86XK_AudioLowerVolume, ui::VKEY_VOLUME_DOWN, }, |
| + { XK_F10, 0, 0, XF86XK_AudioRaiseVolume, ui::VKEY_VOLUME_UP, }, |
| + { XK_F11, 0, 0, XF86XK_PowerOff, ui::VKEY_POWER, } |
|
Daniel Erat
2012/11/29 04:54:23
i don't think this is correct -- the power key on
danakj
2012/11/30 03:07:40
Done.
|
| + }; |
| + |
| + bool remapped = |
| + RewriteWithKeyboardRemappingsByKeySym(fkeys_to_special_keys, |
| + arraysize(fkeys_to_special_keys), |
| + keysym, |
| + xkey->state, |
| + event->flags(), |
| + &remapped_native_keysym, |
| + &remapped_native_mods, |
| + &remapped_keycode, |
| + &remapped_mods); |
| + |
| + if (!remapped) { |
| + const PrefService* pref_service = |
| + pref_service_ ? pref_service_ : GetPrefService(); |
| + bool chromebook_function_key = CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kEnableChromebookFunctionKey); |
| + |
| + bool search_as_function_key = chromebook_function_key && pref_service && |
| + pref_service->GetBoolean(prefs::kLanguageSearchKeyActsAsFunctionKey); |
| + if (search_as_function_key) |
| + DCHECK(HasChromeOSKeyboard()); |
| + |
| + // When using Search as a Function key, remap Search+<number> to F<number>. |
| + if (search_as_function_key && xkey->state & Mod4Mask) { |
| + // We check the keycode here instead of the keysym, as these keys have |
| + // different keysyms when modifiers are pressed, such as shift. |
| + |
| + // TODO(danakj): On some i18n keyboards, these choices will be bad and we |
| + // should make layout-specific choices here. For eg. on a french keyboard |
| + // "-" and "6" are the same key, so F11 will not be accessible. |
| + static const KeyboardRemapping number_keys_to_fkeys[] = { |
| + { XK_1, 0, Mod4Mask, XK_F1, ui::VKEY_F1, }, |
| + { XK_2, 0, Mod4Mask, XK_F2, ui::VKEY_F2, }, |
| + { XK_3, 0, Mod4Mask, XK_F3, ui::VKEY_F3, }, |
| + { XK_4, 0, Mod4Mask, XK_F4, ui::VKEY_F4, }, |
| + { XK_5, 0, Mod4Mask, XK_F5, ui::VKEY_F5, }, |
| + { XK_6, 0, Mod4Mask, XK_F6, ui::VKEY_F6, }, |
| + { XK_7, 0, Mod4Mask, XK_F7, ui::VKEY_F7, }, |
| + { XK_8, 0, Mod4Mask, XK_F8, ui::VKEY_F8, }, |
| + { XK_9, 0, Mod4Mask, XK_F9, ui::VKEY_F9, }, |
| + { XK_0, 0, Mod4Mask, XK_F10, ui::VKEY_F10, }, |
| + { XK_minus, 0, Mod4Mask, XK_F11, ui::VKEY_F11, }, |
| + { XK_equal, 0, Mod4Mask, XK_F12, ui::VKEY_F12, } |
| + }; |
| + |
| + RewriteWithKeyboardRemappingsByKeyCode(number_keys_to_fkeys, |
| + arraysize(number_keys_to_fkeys), |
| + xkey->keycode, |
| + xkey->state, |
| + event->flags(), |
| + &remapped_native_keysym, |
| + &remapped_native_mods, |
| + &remapped_keycode, |
| + &remapped_mods); |
| + } |
| + } |
| + |
| + if (!remapped_native_keysym || remapped_keycode == ui::VKEY_UNKNOWN) |
| + return false; |
| + |
| + OverwriteEvent(event, |
| + NativeKeySymToNativeKeycode(remapped_native_keysym), |
| + remapped_native_mods, |
| + remapped_keycode, |
| + remapped_mods); |
| + return true; |
| +#else |
| + // TODO(danakj): Support Ash on other platforms if needed. |
| + return false; |
| #endif |
| - return rewritten; |
| } |
| void EventRewriter::RewriteLocatedEvent(ui::LocatedEvent* event) { |
| @@ -800,6 +955,9 @@ EventRewriter::DeviceType EventRewriter::DeviceAddedInternal( |
| if (type == kDeviceAppleKeyboard) { |
| VLOG(1) << "Apple keyboard '" << device_name << "' connected: " |
| << "id=" << device_id; |
| + } else if (type == kDeviceChromeOSKeyboard) { |
| + VLOG(1) << "ChromeOS keyboard '" << device_name << "' connected: " |
| + << "id=" << device_id; |
| } |
| // Always overwrite the existing device_id since the X server may reuse a |
| // device id for an unattached device. |