1 // Copyright 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ozone/ui/events/keyboard_engine_xkb.h"
9 #include "ozone/ui/events/keyboard_codes_ozone.h"
10 #include "ui/events/event.h"
14 KeyboardEngineXKB::KeyboardEngineXKB() : keyboard_modifiers_(0),
21 cached_sym_(XKB_KEY_NoSymbol),
27 KeyboardEngineXKB::~KeyboardEngineXKB() {
31 void KeyboardEngineXKB::OnKeyboardKeymap(int fd, uint32_t size) {
33 reinterpret_cast<char*>(mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0));
34 if (map_str == MAP_FAILED)
38 keymap_ = xkb_map_new_from_string(context_,
40 XKB_KEYMAP_FORMAT_TEXT_V1,
41 (xkb_map_compile_flags)0);
42 munmap(map_str, size);
46 state_ = xkb_state_new(keymap_);
48 xkb_map_unref(keymap_);
53 void KeyboardEngineXKB::OnKeyModifiers(uint32_t mods_depressed,
54 uint32_t mods_latched,
60 if ((mods_depressed_ == mods_depressed) && (mods_locked_ == mods_locked)
61 && (mods_latched_ == mods_latched) && (group_ == group)) {
65 mods_depressed_ = mods_depressed;
66 mods_locked_ = mods_locked;
67 mods_latched_ = mods_latched;
69 xkb_state_update_mask(state_,
77 keyboard_modifiers_ = 0;
78 if (xkb_state_mod_name_is_active(
79 state_, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE))
80 keyboard_modifiers_ |= ui::EF_SHIFT_DOWN;
82 if (xkb_state_mod_name_is_active(
83 state_, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE))
84 keyboard_modifiers_ |= ui::EF_CONTROL_DOWN;
86 if (xkb_state_mod_name_is_active(
87 state_, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE))
88 keyboard_modifiers_ |= ui::EF_ALT_DOWN;
90 if (xkb_state_mod_name_is_active(
91 state_, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_EFFECTIVE))
92 keyboard_modifiers_ |= ui::EF_CAPS_LOCK_DOWN;
95 unsigned KeyboardEngineXKB::ConvertKeyCodeFromEvdev(unsigned hardwarecode) {
96 if (hardwarecode == last_key_ && last_modifiers_ == keyboard_modifiers_)
99 const xkb_keysym_t *syms;
101 uint32_t code = hardwarecode + 8;
102 uint32_t num_syms = xkb_key_get_syms(state_, code, &syms);
106 sym = XKB_KEY_NoSymbol;
108 last_key_ = hardwarecode;
109 last_modifiers_ = keyboard_modifiers_;
116 void KeyboardEngineXKB::InitXKB() {
120 context_ = xkb_context_new((xkb_context_flags)0);
123 void KeyboardEngineXKB::FiniXKB() {
125 xkb_state_unref(state_);
130 xkb_map_unref(keymap_);
135 xkb_context_unref(context_);
140 bool KeyboardEngineXKB::IsOnlyCapsLocked() const {
141 if ((keyboard_modifiers_ & ui::EF_CONTROL_DOWN) != 0)
144 if ((keyboard_modifiers_ & ui::EF_ALT_DOWN) != 0)
147 if ((keyboard_modifiers_ & ui::EF_SHIFT_DOWN) != 0)
153 void KeyboardEngineXKB::NormalizeKey() {
154 if ((cached_sym_ >= XKB_KEY_A && cached_sym_ <= XKB_KEY_Z) ||
155 (cached_sym_ >= XKB_KEY_a && cached_sym_ <= XKB_KEY_z) ||
156 (cached_sym_ >= XKB_KEY_0 && cached_sym_ <= XKB_KEY_9))
159 if (cached_sym_ >= XKB_KEY_KP_0 && cached_sym_ <= XKB_KEY_KP_9) {
160 // Numpad Number-keys can be represented by a keysym value of 0-9 nos.
161 cached_sym_ = XKB_KEY_0 + (cached_sym_ - XKB_KEY_KP_0);
162 } else if (cached_sym_ > 0x01000100 && cached_sym_ < 0x01ffffff) {
163 // Any UCS character in this range will simply be the character's
164 // Unicode number plus 0x01000000.
165 cached_sym_ = cached_sym_ - 0x001000000;
166 } else if (cached_sym_ >= XKB_KEY_F1 && cached_sym_ <= XKB_KEY_F24) {
167 cached_sym_ = ui::OZONEACTIONKEY_F1 + (cached_sym_ - XKB_KEY_F1);
168 } else if (cached_sym_ >= XKB_KEY_KP_F1 && cached_sym_ <= XKB_KEY_KP_F4) {
169 cached_sym_ = ui::OZONEACTIONKEY_F1 + (cached_sym_ - XKB_KEY_KP_F1);
171 switch (cached_sym_) {
172 case XKB_KEY_dead_circumflex:
173 cached_sym_ = ui::OZONECHARCODE_CARET_CIRCUMFLEX;
175 case XKB_KEY_dead_diaeresis:
176 cached_sym_ = ui::OZONECHARCODE_SPACING_DIAERESIS;
178 case XKB_KEY_dead_perispomeni:
179 cached_sym_ = ui::OZONECHARCODE_TILDE;
181 case XKB_KEY_dead_acute:
182 cached_sym_ = ui::OZONECHARCODE_SPACING_ACUTE;
184 case XKB_KEY_dead_grave:
185 cached_sym_ = ui::OZONECHARCODE_GRAVE_ASSCENT;
188 cached_sym_ = ui::OZONECHARCODE_ENDASH;
190 case XKB_KEY_singlelowquotemark:
191 cached_sym_ = ui::OZONECHARCODE_SINGLE_LOW_QUOTATION_MARK;
193 case XKB_KEY_dead_cedilla:
194 cached_sym_ = ui::OZONECHARCODE_SPACING_CEDILLA;
196 case XKB_KEY_KP_Equal:
197 cached_sym_ = ui::OZONECHARCODE_EQUAL;
199 case XKB_KEY_KP_Multiply:
200 cached_sym_ = ui::OZONECHARCODE_MULTIPLY;
203 cached_sym_ = ui::OZONECHARCODE_PLUS;
205 case XKB_KEY_KP_Separator:
206 cached_sym_ = ui::OZONECHARCODE_COMMA;
208 case XKB_KEY_KP_Subtract:
209 cached_sym_ = ui::OZONECHARCODE_MINUS;
211 case XKB_KEY_KP_Decimal:
212 cached_sym_ = ui::OZONECHARCODE_PERIOD;
214 case XKB_KEY_KP_Divide:
215 cached_sym_ = ui::OZONECHARCODE_DIVISION;
218 case XKB_KEY_KP_Delete:
219 cached_sym_ = ui::OZONEACTIONKEY_DELETE;
222 case XKB_KEY_ISO_Left_Tab:
224 case XKB_KEY_3270_BackTab:
225 cached_sym_ = ui::OZONEACTIONKEY_TAB;
227 case XKB_KEY_Sys_Req:
229 cached_sym_ = ui::OZONEACTIONKEY_ESCAPE;
231 case XKB_KEY_Linefeed:
232 cached_sym_ = ui::OZONECHARCODE_LINEFEED;
235 case XKB_KEY_KP_Enter:
236 case XKB_KEY_ISO_Enter:
237 cached_sym_ = ui::OZONEACTIONKEY_RETURN;
239 case XKB_KEY_KP_Space:
241 cached_sym_ = ui::OZONEACTIONKEY_SPACE;
243 case XKB_KEY_dead_caron:
244 cached_sym_ = ui::OZONECHARCODE_CARON;
246 case XKB_KEY_BackSpace:
247 cached_sym_ = ui::OZONEACTIONKEY_BACK;
249 case XKB_KEY_dead_doubleacute:
250 cached_sym_ = ui::OZONECHARCODE_DOUBLE_ACUTE_ACCENT;
252 case XKB_KEY_dead_horn:
253 cached_sym_ = ui::OZONECHARCODE_COMBINING_HORN;
256 cached_sym_ = ui::OZONECHARCODE_LSMALL_OE;
259 cached_sym_ = ui::OZONECHARCODE_LOE;
261 case XKB_KEY_idotless:
262 cached_sym_ = ui::OZONECHARCODE_LSMALL_DOT_LESS_I;
265 cached_sym_ = ui::OZONECHARCODE_LSMALL_KRA;
267 case XKB_KEY_dead_stroke:
268 cached_sym_ = ui::OZONECHARCODE_MINUS;
271 cached_sym_ = ui::OZONECHARCODE_LSMALL_ENG;
274 cached_sym_ = ui::OZONECHARCODE_LENG;
276 case XKB_KEY_leftsinglequotemark:
277 cached_sym_ = ui::OZONECHARCODE_LEFT_SINGLE_QUOTATION_MARK;
279 case XKB_KEY_rightsinglequotemark:
280 cached_sym_ = ui::OZONECHARCODE_RIGHT_SINGLE_QUOTATION_MARK;
282 case XKB_KEY_dead_belowdot:
283 cached_sym_ = ui::OZONECHARCODE_COMBINING_DOT_BELOW;
285 case XKB_KEY_dead_belowdiaeresis:
286 cached_sym_ = ui::OZONECHARCODE_COMBINING_DIAERESIS_BELOW;
289 case XKB_KEY_KP_Begin:
290 cached_sym_ = ui::OZONEACTIONKEY_CLEAR;
293 case XKB_KEY_KP_Home:
294 cached_sym_ = ui::OZONEACTIONKEY_HOME;
298 cached_sym_ = ui::OZONEACTIONKEY_END;
300 case XKB_KEY_Page_Up:
301 case XKB_KEY_KP_Page_Up: // aka XKB_KEY_KP_Prior
302 cached_sym_ = ui::OZONEACTIONKEY_PRIOR;
304 case XKB_KEY_Page_Down:
305 case XKB_KEY_KP_Page_Down: // aka XKB_KEY_KP_Next
306 cached_sym_ = ui::OZONEACTIONKEY_NEXT;
309 case XKB_KEY_KP_Left:
310 cached_sym_ = ui::OZONEACTIONKEY_LEFT;
313 case XKB_KEY_KP_Right:
314 cached_sym_ = ui::OZONEACTIONKEY_RIGHT;
317 case XKB_KEY_KP_Down:
318 cached_sym_ = ui::OZONEACTIONKEY_DOWN;
322 cached_sym_ = ui::OZONEACTIONKEY_UP;
324 case XKB_KEY_Kana_Lock:
325 case XKB_KEY_Kana_Shift:
326 cached_sym_ = ui::OZONEACTIONKEY_KANA;
329 cached_sym_ = ui::OZONEACTIONKEY_HANGUL;
331 case XKB_KEY_Hangul_Hanja:
332 cached_sym_ = ui::OZONEACTIONKEY_HANJA;
335 cached_sym_ = ui::OZONEACTIONKEY_KANJI;
338 cached_sym_ = ui::OZONEACTIONKEY_CONVERT;
340 case XKB_KEY_Muhenkan:
341 cached_sym_ = ui::OZONEACTIONKEY_NONCONVERT;
343 case XKB_KEY_Zenkaku_Hankaku:
344 cached_sym_ = ui::OZONEACTIONKEY_DBE_DBCSCHAR;
346 case XKB_KEY_ISO_Level5_Shift:
347 cached_sym_ = ui::OZONEACTIONKEY_OEM_8;
349 case XKB_KEY_Shift_L:
350 case XKB_KEY_Shift_R:
351 cached_sym_ = ui::OZONEACTIONKEY_SHIFT;
353 case XKB_KEY_Control_L:
354 case XKB_KEY_Control_R:
355 cached_sym_ = ui::OZONEACTIONKEY_CONTROL;
361 cached_sym_ = ui::OZONEACTIONKEY_MENU;
363 case XKB_KEY_ISO_Level3_Shift:
364 cached_sym_ = ui::OZONEACTIONKEY_ALTGR;
366 case XKB_KEY_Multi_key:
370 cached_sym_ = ui::OZONEACTIONKEY_PAUSE;
372 case XKB_KEY_Caps_Lock:
373 cached_sym_ = ui::OZONEACTIONKEY_CAPITAL;
375 case XKB_KEY_Num_Lock:
376 cached_sym_ = ui::OZONEACTIONKEY_NUMLOCK;
378 case XKB_KEY_Scroll_Lock:
379 cached_sym_ = ui::OZONEACTIONKEY_SCROLL;
382 cached_sym_ = ui::OZONEACTIONKEY_SELECT;
385 cached_sym_ = ui::OZONEACTIONKEY_PRINT;
387 case XKB_KEY_Execute:
388 cached_sym_ = ui::OZONEACTIONKEY_EXECUTE;
391 case XKB_KEY_KP_Insert:
392 cached_sym_ = ui::OZONEACTIONKEY_INSERT;
395 cached_sym_ = ui::OZONEACTIONKEY_HELP;
397 case XKB_KEY_Super_L:
398 cached_sym_ = ui::OZONEACTIONKEY_LWIN;
400 case XKB_KEY_Super_R:
401 cached_sym_ = ui::OZONEACTIONKEY_RWIN;
404 cached_sym_ = ui::OZONEACTIONKEY_APPS;
406 case XKB_KEY_XF86Tools:
407 cached_sym_ = ui::OZONEACTIONKEY_F13;
409 case XKB_KEY_XF86Launch5:
410 cached_sym_ = ui::OZONEACTIONKEY_F14;
412 case XKB_KEY_XF86Launch6:
413 cached_sym_ = ui::OZONEACTIONKEY_F15;
415 case XKB_KEY_XF86Launch7:
416 cached_sym_ = ui::OZONEACTIONKEY_F16;
418 case XKB_KEY_XF86Launch8:
419 cached_sym_ = ui::OZONEACTIONKEY_F17;
421 case XKB_KEY_XF86Launch9:
422 cached_sym_ = ui::OZONEACTIONKEY_F18;
425 // For supporting multimedia buttons on a USB keyboard.
426 case XKB_KEY_XF86Back:
427 cached_sym_ = ui::OZONEACTIONKEY_BROWSER_BACK;
429 case XKB_KEY_XF86Forward:
430 cached_sym_ = ui::OZONEACTIONKEY_BROWSER_FORWARD;
432 case XKB_KEY_XF86Reload:
433 cached_sym_ = ui::OZONEACTIONKEY_BROWSER_REFRESH;
435 case XKB_KEY_XF86Stop:
436 cached_sym_ = ui::OZONEACTIONKEY_BROWSER_STOP;
438 case XKB_KEY_XF86Search:
439 cached_sym_ = ui::OZONEACTIONKEY_BROWSER_SEARCH;
441 case XKB_KEY_XF86Favorites:
442 cached_sym_ = ui::OZONEACTIONKEY_BROWSER_FAVORITES;
444 case XKB_KEY_XF86HomePage:
445 cached_sym_ = ui::OZONEACTIONKEY_BROWSER_HOME;
447 case XKB_KEY_XF86AudioMute:
448 cached_sym_ = ui::OZONEACTIONKEY_VOLUME_MUTE;
450 case XKB_KEY_XF86AudioLowerVolume:
451 cached_sym_ = ui::OZONEACTIONKEY_VOLUME_DOWN;
453 case XKB_KEY_XF86AudioRaiseVolume:
454 cached_sym_ = ui::OZONEACTIONKEY_VOLUME_UP;
456 case XKB_KEY_XF86AudioNext:
457 cached_sym_ = ui::OZONEACTIONKEY_MEDIA_NEXT_TRACK;
459 case XKB_KEY_XF86AudioPrev:
460 cached_sym_ = ui::OZONEACTIONKEY_MEDIA_PREV_TRACK;
462 case XKB_KEY_XF86AudioStop:
463 cached_sym_ = ui::OZONEACTIONKEY_MEDIA_STOP;
465 case XKB_KEY_XF86AudioPlay:
466 cached_sym_ = ui::OZONEACTIONKEY_MEDIA_PLAY_PAUSE;
468 case XKB_KEY_XF86Mail:
469 cached_sym_ = ui::OZONEACTIONKEY_MEDIA_LAUNCH_MAIL;
471 case XKB_KEY_XF86LaunchA:
472 cached_sym_ = ui::OZONEACTIONKEY_MEDIA_LAUNCH_APP1;
474 case XKB_KEY_XF86LaunchB:
475 case XKB_KEY_XF86Calculator:
476 cached_sym_ = ui::OZONEACTIONKEY_MEDIA_LAUNCH_APP2;
478 case XKB_KEY_XF86WLAN:
479 cached_sym_ = ui::OZONEACTIONKEY_WLAN;
481 case XKB_KEY_XF86PowerOff:
482 cached_sym_ = ui::OZONEACTIONKEY_POWER;
484 case XKB_KEY_XF86MonBrightnessDown:
485 cached_sym_ = ui::OZONEACTIONKEY_BRIGHTNESS_DOWN;
487 case XKB_KEY_XF86MonBrightnessUp:
488 cached_sym_ = ui::OZONEACTIONKEY_BRIGHTNESS_UP;
490 case XKB_KEY_XF86KbdBrightnessDown:
491 cached_sym_ = ui::OZONEACTIONKEY_KBD_BRIGHTNESS_DOWN;
493 case XKB_KEY_XF86KbdBrightnessUp:
494 cached_sym_ = ui::OZONEACTIONKEY_KBD_BRIGHTNESS_UP;
496 case XKB_KEY_emptyset:
497 case XKB_KEY_NoSymbol:
498 cached_sym_ = ui::OZONECHARCODE_NULL;