Commit 0978031a authored by kpschoedel's avatar kpschoedel Committed by Commit bot

Generate correct KeyboardCode (VKEY).

BUG=430194

Review URL: https://codereview.chromium.org/786813004

Cr-Commit-Position: refs/heads/master@{#308469}
parent aec301ce
...@@ -332,6 +332,7 @@ test("events_unittests") { ...@@ -332,6 +332,7 @@ test("events_unittests") {
"ozone/evdev/input_injector_evdev_unittest.cc", "ozone/evdev/input_injector_evdev_unittest.cc",
"ozone/evdev/tablet_event_converter_evdev_unittest.cc", "ozone/evdev/tablet_event_converter_evdev_unittest.cc",
"ozone/evdev/touch_event_converter_evdev_unittest.cc", "ozone/evdev/touch_event_converter_evdev_unittest.cc",
"ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc",
] ]
deps += [ deps += [
"//ui/events/ozone:events_ozone", "//ui/events/ozone:events_ozone",
......
...@@ -362,6 +362,11 @@ ...@@ -362,6 +362,11 @@
'ozone/events_ozone.gyp:events_ozone_layout', 'ozone/events_ozone.gyp:events_ozone_layout',
] ]
}], }],
['use_xkbcommon==1', {
'sources': [
'ozone/layout/xkb/xkb_keyboard_layout_engine_unittest.cc',
]
}],
['use_aura==0', { ['use_aura==0', {
'sources!': [ 'sources!': [
'gestures/gesture_provider_aura_unittest.cc', 'gestures/gesture_provider_aura_unittest.cc',
......
...@@ -14,6 +14,11 @@ namespace ui { ...@@ -14,6 +14,11 @@ namespace ui {
namespace { namespace {
bool IsRightSideDomCode(DomCode code) {
return (code == DomCode::SHIFT_RIGHT) || (code == DomCode::CONTROL_RIGHT) ||
(code == DomCode::ALT_RIGHT) || (code == DomCode::OS_RIGHT);
}
// This table, used by DomKeyToKeyboardCode(), maps DOM Level 3 .code // This table, used by DomKeyToKeyboardCode(), maps DOM Level 3 .code
// values to legacy Windows-based VKEY values, where the VKEYs are // values to legacy Windows-based VKEY values, where the VKEYs are
// interpreted positionally. // interpreted positionally.
...@@ -203,21 +208,6 @@ const struct DomCodeToKeyboardCodeEntry { ...@@ -203,21 +208,6 @@ const struct DomCodeToKeyboardCodeEntry {
} // anonymous namespace } // anonymous namespace
// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
// The returned VKEY is positional (e.g. VKEY_LSHIFT).
KeyboardCode DomCodeToKeyboardCode(DomCode dom_code) {
const DomCodeToKeyboardCodeEntry* end =
dom_code_to_keyboard_code + arraysize(dom_code_to_keyboard_code);
const DomCodeToKeyboardCodeEntry* found =
std::lower_bound(dom_code_to_keyboard_code, end, dom_code,
[](const DomCodeToKeyboardCodeEntry& a, DomCode b) {
return static_cast<int>(a.dom_code) < static_cast<int>(b);
});
if ((found != end) && (found->dom_code == dom_code))
return found->key_code;
return VKEY_UNKNOWN;
}
// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|. // Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|.
// The returned VKEY is non-positional (e.g. VKEY_SHIFT). // The returned VKEY is non-positional (e.g. VKEY_SHIFT).
KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) { KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) {
...@@ -458,8 +448,29 @@ KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) { ...@@ -458,8 +448,29 @@ KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key) {
} }
} }
// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
// The returned VKEY is located (e.g. VKEY_LSHIFT).
KeyboardCode DomCodeToKeyboardCode(DomCode dom_code) {
const DomCodeToKeyboardCodeEntry* end =
dom_code_to_keyboard_code + arraysize(dom_code_to_keyboard_code);
const DomCodeToKeyboardCodeEntry* found =
std::lower_bound(dom_code_to_keyboard_code, end, dom_code,
[](const DomCodeToKeyboardCodeEntry& a, DomCode b) {
return static_cast<int>(a.dom_code) < static_cast<int>(b);
});
if ((found != end) && (found->dom_code == dom_code))
return found->key_code;
return VKEY_UNKNOWN;
}
// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
// The returned VKEY is non-located (e.g. VKEY_SHIFT).
KeyboardCode DomCodeToNonLocatedKeyboardCode(DomCode dom_code) {
return NonLocatedKeyboardCode(DomCodeToKeyboardCode(dom_code));
}
// Determine the non-located VKEY corresponding to a located VKEY. // Determine the non-located VKEY corresponding to a located VKEY.
ui::KeyboardCode DeLocateKeyboardCode(ui::KeyboardCode key_code) { KeyboardCode NonLocatedKeyboardCode(KeyboardCode key_code) {
switch (key_code) { switch (key_code) {
case VKEY_RWIN: case VKEY_RWIN:
return VKEY_LWIN; return VKEY_LWIN;
...@@ -477,6 +488,42 @@ ui::KeyboardCode DeLocateKeyboardCode(ui::KeyboardCode key_code) { ...@@ -477,6 +488,42 @@ ui::KeyboardCode DeLocateKeyboardCode(ui::KeyboardCode key_code) {
} }
} }
// Determine the located VKEY corresponding to a non-located VKEY.
KeyboardCode LocatedKeyboardCode(KeyboardCode key_code, DomCode dom_code) {
switch (key_code) {
case VKEY_SHIFT:
return IsRightSideDomCode(dom_code) ? VKEY_RSHIFT : VKEY_LSHIFT;
case VKEY_CONTROL:
return IsRightSideDomCode(dom_code) ? VKEY_RCONTROL : VKEY_LCONTROL;
case VKEY_MENU:
return IsRightSideDomCode(dom_code) ? VKEY_RMENU : VKEY_LMENU;
case VKEY_LWIN:
return IsRightSideDomCode(dom_code) ? VKEY_RWIN : VKEY_LWIN;
case VKEY_0:
return (dom_code == DomCode::NUMPAD0) ? VKEY_NUMPAD0 : VKEY_0;
case VKEY_1:
return (dom_code == DomCode::NUMPAD1) ? VKEY_NUMPAD1 : VKEY_1;
case VKEY_2:
return (dom_code == DomCode::NUMPAD2) ? VKEY_NUMPAD2 : VKEY_2;
case VKEY_3:
return (dom_code == DomCode::NUMPAD3) ? VKEY_NUMPAD3 : VKEY_3;
case VKEY_4:
return (dom_code == DomCode::NUMPAD4) ? VKEY_NUMPAD4 : VKEY_4;
case VKEY_5:
return (dom_code == DomCode::NUMPAD5) ? VKEY_NUMPAD5 : VKEY_5;
case VKEY_6:
return (dom_code == DomCode::NUMPAD6) ? VKEY_NUMPAD6 : VKEY_6;
case VKEY_7:
return (dom_code == DomCode::NUMPAD7) ? VKEY_NUMPAD7 : VKEY_7;
case VKEY_8:
return (dom_code == DomCode::NUMPAD8) ? VKEY_NUMPAD8 : VKEY_8;
case VKEY_9:
return (dom_code == DomCode::NUMPAD9) ? VKEY_NUMPAD9 : VKEY_9;
default:
return key_code;
}
}
bool LookupControlCharacter(DomCode dom_code, bool LookupControlCharacter(DomCode dom_code,
int flags, int flags,
DomKey* dom_key, DomKey* dom_key,
......
...@@ -15,16 +15,23 @@ namespace ui { ...@@ -15,16 +15,23 @@ namespace ui {
enum class DomCode; enum class DomCode;
enum class DomKey; enum class DomKey;
// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|.
// The returned VKEY is non-located (e.g. VKEY_SHIFT).
KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key);
// Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|. // Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
// The returned VKEY is located (e.g. VKEY_LSHIFT). // The returned VKEY is located (e.g. VKEY_LSHIFT).
KeyboardCode DomCodeToKeyboardCode(DomCode dom_code); KeyboardCode DomCodeToKeyboardCode(DomCode dom_code);
// Returns a Windows-based VKEY for a non-printable DOM Level 3 |key|. // Returns the Windows-based VKEY value corresponding to a DOM Level 3 |code|.
// The returned VKEY is non-located (e.g. VKEY_SHIFT). // The returned VKEY is non-located (e.g. VKEY_SHIFT).
KeyboardCode NonPrintableDomKeyToKeyboardCode(DomKey dom_key); KeyboardCode DomCodeToNonLocatedKeyboardCode(DomCode dom_code);
// Determine the non-located VKEY corresponding to a located VKEY. // Determine the non-located VKEY corresponding to a located VKEY.
KeyboardCode DeLocateKeyboardCode(KeyboardCode key_code); KeyboardCode NonLocatedKeyboardCode(KeyboardCode key_code);
// Determine the located VKEY corresponding to a non-located VKEY.
KeyboardCode LocatedKeyboardCode(KeyboardCode key_code, DomCode dom_code);
// Returns true control character corresponding to a physical key. // Returns true control character corresponding to a physical key.
// In some contexts this is used instead of the key layout. // In some contexts this is used instead of the key layout.
......
...@@ -277,7 +277,7 @@ bool StubKeyboardLayoutEngine::Lookup(DomCode dom_code, ...@@ -277,7 +277,7 @@ bool StubKeyboardLayoutEngine::Lookup(DomCode dom_code,
if ((ch >= 'a') && (ch <= 'z')) if ((ch >= 'a') && (ch <= 'z'))
*out_character = e->character[state ^ 1]; *out_character = e->character[state ^ 1];
} }
*out_key_code = DomCodeToKeyboardCode(dom_code); *out_key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
return true; return true;
} }
} }
......
...@@ -11,6 +11,10 @@ namespace ui { ...@@ -11,6 +11,10 @@ namespace ui {
enum class DomCode; enum class DomCode;
// XKB scan code values are platform-dependent; this provides the layout engine
// with the mapping from DomCode to xkb_keycode_t. (This mapping is in principle
// derivable from the XKB keyboard layout, but xkbcommon does not provide a
// practical interface to do so.)
class EVENTS_OZONE_LAYOUT_EXPORT XkbKeyCodeConverter { class EVENTS_OZONE_LAYOUT_EXPORT XkbKeyCodeConverter {
public: public:
XkbKeyCodeConverter(); XkbKeyCodeConverter();
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
namespace ui { namespace ui {
DomKey XkbKeySymToDomKey(xkb_keysym_t keysym) { DomKey NonPrintableXkbKeySymToDomKey(xkb_keysym_t keysym) {
switch (keysym) { switch (keysym) {
case XKB_KEY_BackSpace: case XKB_KEY_BackSpace:
return DomKey::BACKSPACE; return DomKey::BACKSPACE;
...@@ -377,7 +377,7 @@ DomKey XkbKeySymToDomKey(xkb_keysym_t keysym) { ...@@ -377,7 +377,7 @@ DomKey XkbKeySymToDomKey(xkb_keysym_t keysym) {
} }
} }
base::char16 XkbKeySymDeadKey(xkb_keysym_t keysym) { base::char16 DeadXkbKeySymToCombiningCharacter(xkb_keysym_t keysym) {
switch (keysym) { switch (keysym) {
case XKB_KEY_dead_grave: case XKB_KEY_dead_grave:
return 0x0768; // combining grave accent return 0x0768; // combining grave accent
......
...@@ -21,11 +21,11 @@ enum class DomKey; ...@@ -21,11 +21,11 @@ enum class DomKey;
// Returns the DomKey associated with a non-character xkb_keysym_t. // Returns the DomKey associated with a non-character xkb_keysym_t.
// Returns DomKey::NONE for unrecognized keysyms, which includes // Returns DomKey::NONE for unrecognized keysyms, which includes
// all printable characters. // all printable characters.
DomKey XkbKeySymToDomKey(xkb_keysym_t keysym); DomKey NonPrintableXkbKeySymToDomKey(xkb_keysym_t keysym);
// Returns the dead key combining character associated with an xkb_keysym_t, // Returns the dead key combining character associated with an xkb_keysym_t,
// or 0 if the keysym is not recognized. // or 0 if the keysym is not recognized.
base::char16 XkbKeySymDeadKey(xkb_keysym_t keysym); base::char16 DeadXkbKeySymToCombiningCharacter(xkb_keysym_t keysym);
} // namespace ui } // namespace ui
......
...@@ -36,6 +36,28 @@ class EVENTS_OZONE_LAYOUT_EXPORT XkbKeyboardLayoutEngine ...@@ -36,6 +36,28 @@ class EVENTS_OZONE_LAYOUT_EXPORT XkbKeyboardLayoutEngine
base::char16* character, base::char16* character,
KeyboardCode* key_code) const override; KeyboardCode* key_code) const override;
protected:
// Table for EventFlagsToXkbFlags().
struct XkbFlagMapEntry {
int ui_flag;
xkb_mod_mask_t xkb_flag;
};
std::vector<XkbFlagMapEntry> xkb_flag_map_;
// Determines the Windows-based KeyboardCode (VKEY) for a character key,
// accounting for non-US layouts. May return VKEY_UNKNOWN, in which case the
// caller should use |DomCodeToNonLocatedKeyboardCode()| as a last resort.
KeyboardCode DifficultKeyboardCode(DomCode dom_code,
int ui_flags,
xkb_keycode_t xkb_keycode,
xkb_mod_mask_t xkb_flags,
xkb_keysym_t xkb_keysym,
DomKey dom_key,
base::char16 character) const;
// Maps DomCode to xkb_keycode_t.
const XkbKeyCodeConverter& key_code_converter_;
private: private:
// Sets a new XKB keymap, updating object fields. // Sets a new XKB keymap, updating object fields.
void SetKeymap(xkb_keymap* keymap); void SetKeymap(xkb_keymap* keymap);
...@@ -44,26 +66,24 @@ class EVENTS_OZONE_LAYOUT_EXPORT XkbKeyboardLayoutEngine ...@@ -44,26 +66,24 @@ class EVENTS_OZONE_LAYOUT_EXPORT XkbKeyboardLayoutEngine
xkb_mod_mask_t EventFlagsToXkbFlags(int ui_flags) const; xkb_mod_mask_t EventFlagsToXkbFlags(int ui_flags) const;
// Determines the XKB KeySym and character associated with a key. // Determines the XKB KeySym and character associated with a key.
// Returns true on success. // Returns true on success. This is virtual for testing.
bool XkbLookup(xkb_keycode_t xkb_keycode, virtual bool XkbLookup(xkb_keycode_t xkb_keycode,
xkb_mod_mask_t xkb_flags, xkb_mod_mask_t xkb_flags,
xkb_keysym_t* xkb_keysym, xkb_keysym_t* xkb_keysym,
base::char16* character) const; base::char16* character) const;
// Maps DomCode to xkb_keycode_t. // Helper for difficult VKEY lookup. If |ui_flags| matches |base_flags|,
const XkbKeyCodeConverter& key_code_converter_; // returns |base_character|; otherwise returns the XKB character for
// the keycode and mapped |ui_flags|.
base::char16 XkbSubCharacter(xkb_keycode_t xkb_keycode,
xkb_mod_mask_t base_flags,
base::char16 base_character,
int ui_flags) const;
// libxkbcommon uses explicit reference counting for its structures, // libxkbcommon uses explicit reference counting for its structures,
// so we need to trigger its cleanup. // so we need to trigger its cleanup.
scoped_ptr<xkb_context, XkbContextDeleter> xkb_context_; scoped_ptr<xkb_context, XkbContextDeleter> xkb_context_;
scoped_ptr<xkb_state, XkbStateDeleter> xkb_state_; scoped_ptr<xkb_state, XkbStateDeleter> xkb_state_;
// Table for EventFlagsToXkbFlags().
struct XkbFlagMapEntry {
int ui_flag;
xkb_mod_mask_t xkb_flag;
};
std::vector<XkbFlagMapEntry> xkb_flag_map_;
}; };
} // namespace ui } // namespace ui
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment