Upstream version 11.39.252.0
[platform/framework/web/crosswalk.git] / src / ozone / ui / events / keyboard_engine_xkb.cc
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.
4
5 #include "ozone/ui/events/keyboard_engine_xkb.h"
6
7 #include <sys/mman.h>
8
9 #include "ozone/ui/events/keyboard_codes_ozone.h"
10 #include "ui/events/event.h"
11
12 namespace ui {
13
14 KeyboardEngineXKB::KeyboardEngineXKB() : keyboard_modifiers_(0),
15     mods_depressed_(0),
16     mods_latched_(0),
17     mods_locked_(0),
18     group_(0),
19     last_key_(-1),
20     last_modifiers_(0),
21     cached_sym_(XKB_KEY_NoSymbol),
22     keymap_(NULL),
23     state_(NULL),
24     context_(NULL) {
25 }
26
27 KeyboardEngineXKB::~KeyboardEngineXKB() {
28   FiniXKB();
29 }
30
31 void KeyboardEngineXKB::OnKeyboardKeymap(int fd, uint32_t size) {
32   char *map_str =
33       reinterpret_cast<char*>(mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0));
34   if (map_str == MAP_FAILED)
35     return;
36
37   InitXKB();
38   keymap_ = xkb_map_new_from_string(context_,
39                                     map_str,
40                                     XKB_KEYMAP_FORMAT_TEXT_V1,
41                                     (xkb_map_compile_flags)0);
42   munmap(map_str, size);
43   if (!keymap_)
44     return;
45
46   state_ = xkb_state_new(keymap_);
47   if (state_) {
48     xkb_map_unref(keymap_);
49     keymap_ = NULL;
50   }
51 }
52
53 void KeyboardEngineXKB::OnKeyModifiers(uint32_t mods_depressed,
54                                         uint32_t mods_latched,
55                                         uint32_t mods_locked,
56                                         uint32_t group) {
57   if (!state_)
58     return;
59
60   if ((mods_depressed_ == mods_depressed) && (mods_locked_ == mods_locked)
61       && (mods_latched_ == mods_latched) && (group_ == group)) {
62     return;
63   }
64
65   mods_depressed_ = mods_depressed;
66   mods_locked_ = mods_locked;
67   mods_latched_ = mods_latched;
68   group_ = group;
69   xkb_state_update_mask(state_,
70                         mods_depressed_,
71                         mods_latched_,
72                         mods_locked_,
73                         0,
74                         0,
75                         group_);
76
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;
81
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;
85
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;
89
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;
93 }
94
95 unsigned KeyboardEngineXKB::ConvertKeyCodeFromEvdev(unsigned hardwarecode) {
96   if (hardwarecode == last_key_ && last_modifiers_ ==  keyboard_modifiers_)
97     return cached_sym_;
98
99   const xkb_keysym_t *syms;
100   xkb_keysym_t sym;
101   uint32_t code = hardwarecode + 8;
102   uint32_t num_syms = xkb_key_get_syms(state_, code, &syms);
103   if (num_syms == 1)
104     sym = syms[0];
105   else
106     sym = XKB_KEY_NoSymbol;
107
108   last_key_ = hardwarecode;
109   last_modifiers_ =  keyboard_modifiers_;
110   cached_sym_ = sym;
111   NormalizeKey();
112
113   return cached_sym_;
114 }
115
116 void KeyboardEngineXKB::InitXKB() {
117   if (context_)
118     return;
119
120   context_ = xkb_context_new((xkb_context_flags)0);
121 }
122
123 void KeyboardEngineXKB::FiniXKB() {
124   if (state_) {
125     xkb_state_unref(state_);
126     state_ = NULL;
127   }
128
129   if (keymap_) {
130     xkb_map_unref(keymap_);
131     keymap_ = NULL;
132   }
133
134   if (context_) {
135     xkb_context_unref(context_);
136     context_ = NULL;
137   }
138 }
139
140 bool KeyboardEngineXKB::IsOnlyCapsLocked() const {
141   if ((keyboard_modifiers_ & ui::EF_CONTROL_DOWN) != 0)
142     return false;
143
144   if ((keyboard_modifiers_ & ui::EF_ALT_DOWN) != 0)
145     return false;
146
147   if ((keyboard_modifiers_ & ui::EF_SHIFT_DOWN) != 0)
148     return false;
149
150   return true;
151 }
152
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))
157     return;
158
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);
170   } else {
171       switch (cached_sym_) {
172         case XKB_KEY_dead_circumflex:
173           cached_sym_ = ui::OZONECHARCODE_CARET_CIRCUMFLEX;
174           break;
175         case XKB_KEY_dead_diaeresis:
176           cached_sym_ = ui::OZONECHARCODE_SPACING_DIAERESIS;
177           break;
178         case XKB_KEY_dead_perispomeni:
179           cached_sym_ = ui::OZONECHARCODE_TILDE;
180           break;
181         case XKB_KEY_dead_acute:
182           cached_sym_ = ui::OZONECHARCODE_SPACING_ACUTE;
183           break;
184         case XKB_KEY_dead_grave:
185           cached_sym_ = ui::OZONECHARCODE_GRAVE_ASSCENT;
186           break;
187         case XKB_KEY_endash:
188           cached_sym_ = ui::OZONECHARCODE_ENDASH;
189           break;
190         case XKB_KEY_singlelowquotemark:
191           cached_sym_ = ui::OZONECHARCODE_SINGLE_LOW_QUOTATION_MARK;
192           break;
193         case XKB_KEY_dead_cedilla:
194           cached_sym_ = ui::OZONECHARCODE_SPACING_CEDILLA;
195           break;
196         case XKB_KEY_KP_Equal:
197           cached_sym_ = ui::OZONECHARCODE_EQUAL;
198           break;
199         case XKB_KEY_KP_Multiply:
200           cached_sym_ = ui::OZONECHARCODE_MULTIPLY;
201           break;
202         case XKB_KEY_KP_Add:
203           cached_sym_ = ui::OZONECHARCODE_PLUS;
204           break;
205         case XKB_KEY_KP_Separator:
206           cached_sym_ = ui::OZONECHARCODE_COMMA;
207           break;
208         case XKB_KEY_KP_Subtract:
209           cached_sym_ = ui::OZONECHARCODE_MINUS;
210           break;
211         case XKB_KEY_KP_Decimal:
212           cached_sym_ = ui::OZONECHARCODE_PERIOD;
213           break;
214         case XKB_KEY_KP_Divide:
215           cached_sym_ = ui::OZONECHARCODE_DIVISION;
216           break;
217         case XKB_KEY_Delete:
218         case XKB_KEY_KP_Delete:
219           cached_sym_ = ui::OZONEACTIONKEY_DELETE;
220           break;
221         case XKB_KEY_KP_Tab:
222         case XKB_KEY_ISO_Left_Tab:
223         case XKB_KEY_Tab:
224         case XKB_KEY_3270_BackTab:
225           cached_sym_ = ui::OZONEACTIONKEY_TAB;
226           break;
227         case XKB_KEY_Sys_Req:
228         case XKB_KEY_Escape:
229           cached_sym_ = ui::OZONEACTIONKEY_ESCAPE;
230           break;
231         case XKB_KEY_Linefeed:
232           cached_sym_ = ui::OZONECHARCODE_LINEFEED;
233           break;
234         case XKB_KEY_Return:
235         case XKB_KEY_KP_Enter:
236         case XKB_KEY_ISO_Enter:
237           cached_sym_ = ui::OZONEACTIONKEY_RETURN;
238           break;
239         case XKB_KEY_KP_Space:
240         case XKB_KEY_space:
241           cached_sym_ = ui::OZONEACTIONKEY_SPACE;
242           break;
243         case XKB_KEY_dead_caron:
244           cached_sym_ = ui::OZONECHARCODE_CARON;
245           break;
246         case XKB_KEY_BackSpace:
247           cached_sym_ = ui::OZONEACTIONKEY_BACK;
248           break;
249         case XKB_KEY_dead_doubleacute:
250           cached_sym_ = ui::OZONECHARCODE_DOUBLE_ACUTE_ACCENT;
251           break;
252         case XKB_KEY_dead_horn:
253           cached_sym_ = ui::OZONECHARCODE_COMBINING_HORN;
254           break;
255         case XKB_KEY_oe:
256           cached_sym_ = ui::OZONECHARCODE_LSMALL_OE;
257           break;
258         case XKB_KEY_OE:
259           cached_sym_ = ui::OZONECHARCODE_LOE;
260           break;
261         case XKB_KEY_idotless:
262           cached_sym_ = ui::OZONECHARCODE_LSMALL_DOT_LESS_I;
263           break;
264         case XKB_KEY_kra:
265           cached_sym_ = ui::OZONECHARCODE_LSMALL_KRA;
266           break;
267         case XKB_KEY_dead_stroke:
268           cached_sym_ = ui::OZONECHARCODE_MINUS;
269           break;
270         case XKB_KEY_eng:
271           cached_sym_ = ui::OZONECHARCODE_LSMALL_ENG;
272           break;
273         case XKB_KEY_ENG:
274           cached_sym_ = ui::OZONECHARCODE_LENG;
275           break;
276         case XKB_KEY_leftsinglequotemark:
277           cached_sym_ = ui::OZONECHARCODE_LEFT_SINGLE_QUOTATION_MARK;
278           break;
279         case XKB_KEY_rightsinglequotemark:
280           cached_sym_ = ui::OZONECHARCODE_RIGHT_SINGLE_QUOTATION_MARK;
281           break;
282         case XKB_KEY_dead_belowdot:
283           cached_sym_ = ui::OZONECHARCODE_COMBINING_DOT_BELOW;
284           break;
285         case XKB_KEY_dead_belowdiaeresis:
286           cached_sym_ = ui::OZONECHARCODE_COMBINING_DIAERESIS_BELOW;
287           break;
288         case XKB_KEY_Clear:
289         case XKB_KEY_KP_Begin:
290           cached_sym_ = ui::OZONEACTIONKEY_CLEAR;
291           break;
292         case XKB_KEY_Home:
293         case XKB_KEY_KP_Home:
294           cached_sym_ = ui::OZONEACTIONKEY_HOME;
295           break;
296         case XKB_KEY_End:
297         case XKB_KEY_KP_End:
298           cached_sym_ = ui::OZONEACTIONKEY_END;
299           break;
300         case XKB_KEY_Page_Up:
301         case XKB_KEY_KP_Page_Up:  // aka XKB_KEY_KP_Prior
302           cached_sym_ = ui::OZONEACTIONKEY_PRIOR;
303           break;
304         case XKB_KEY_Page_Down:
305         case XKB_KEY_KP_Page_Down:  // aka XKB_KEY_KP_Next
306           cached_sym_ = ui::OZONEACTIONKEY_NEXT;
307           break;
308         case XKB_KEY_Left:
309         case XKB_KEY_KP_Left:
310           cached_sym_ = ui::OZONEACTIONKEY_LEFT;
311           break;
312         case XKB_KEY_Right:
313         case XKB_KEY_KP_Right:
314           cached_sym_ = ui::OZONEACTIONKEY_RIGHT;
315           break;
316         case XKB_KEY_Down:
317         case XKB_KEY_KP_Down:
318           cached_sym_ = ui::OZONEACTIONKEY_DOWN;
319           break;
320         case XKB_KEY_Up:
321         case XKB_KEY_KP_Up:
322           cached_sym_ = ui::OZONEACTIONKEY_UP;
323           break;
324         case XKB_KEY_Kana_Lock:
325         case XKB_KEY_Kana_Shift:
326           cached_sym_ = ui::OZONEACTIONKEY_KANA;
327           break;
328         case XKB_KEY_Hangul:
329           cached_sym_ = ui::OZONEACTIONKEY_HANGUL;
330           break;
331         case XKB_KEY_Hangul_Hanja:
332           cached_sym_ = ui::OZONEACTIONKEY_HANJA;
333           break;
334         case XKB_KEY_Kanji:
335           cached_sym_ = ui::OZONEACTIONKEY_KANJI;
336           break;
337         case XKB_KEY_Henkan:
338           cached_sym_ = ui::OZONEACTIONKEY_CONVERT;
339           break;
340         case XKB_KEY_Muhenkan:
341           cached_sym_ = ui::OZONEACTIONKEY_NONCONVERT;
342           break;
343         case XKB_KEY_Zenkaku_Hankaku:
344           cached_sym_ = ui::OZONEACTIONKEY_DBE_DBCSCHAR;
345           break;
346         case XKB_KEY_ISO_Level5_Shift:
347           cached_sym_ = ui::OZONEACTIONKEY_OEM_8;
348           break;
349         case XKB_KEY_Shift_L:
350         case XKB_KEY_Shift_R:
351           cached_sym_ = ui::OZONEACTIONKEY_SHIFT;
352           break;
353         case XKB_KEY_Control_L:
354         case XKB_KEY_Control_R:
355           cached_sym_ = ui::OZONEACTIONKEY_CONTROL;
356           break;
357         case XKB_KEY_Meta_L:
358         case XKB_KEY_Meta_R:
359         case XKB_KEY_Alt_L:
360         case XKB_KEY_Alt_R:
361           cached_sym_ = ui::OZONEACTIONKEY_MENU;
362           break;
363         case XKB_KEY_ISO_Level3_Shift:
364           cached_sym_ = ui::OZONEACTIONKEY_ALTGR;
365           break;
366         case XKB_KEY_Multi_key:
367           cached_sym_ = 0xE6;
368           break;
369         case XKB_KEY_Pause:
370           cached_sym_ = ui::OZONEACTIONKEY_PAUSE;
371           break;
372         case XKB_KEY_Caps_Lock:
373           cached_sym_ = ui::OZONEACTIONKEY_CAPITAL;
374           break;
375         case XKB_KEY_Num_Lock:
376           cached_sym_ = ui::OZONEACTIONKEY_NUMLOCK;
377           break;
378         case XKB_KEY_Scroll_Lock:
379           cached_sym_ = ui::OZONEACTIONKEY_SCROLL;
380           break;
381         case XKB_KEY_Select:
382           cached_sym_ = ui::OZONEACTIONKEY_SELECT;
383           break;
384         case XKB_KEY_Print:
385           cached_sym_ = ui::OZONEACTIONKEY_PRINT;
386           break;
387         case XKB_KEY_Execute:
388           cached_sym_ = ui::OZONEACTIONKEY_EXECUTE;
389           break;
390         case XKB_KEY_Insert:
391         case XKB_KEY_KP_Insert:
392           cached_sym_ = ui::OZONEACTIONKEY_INSERT;
393           break;
394         case XKB_KEY_Help:
395           cached_sym_ = ui::OZONEACTIONKEY_HELP;
396           break;
397         case XKB_KEY_Super_L:
398           cached_sym_ = ui::OZONEACTIONKEY_LWIN;
399           break;
400         case XKB_KEY_Super_R:
401           cached_sym_ = ui::OZONEACTIONKEY_RWIN;
402           break;
403         case XKB_KEY_Menu:
404           cached_sym_ = ui::OZONEACTIONKEY_APPS;
405           break;
406         case XKB_KEY_XF86Tools:
407           cached_sym_ = ui::OZONEACTIONKEY_F13;
408           break;
409         case XKB_KEY_XF86Launch5:
410           cached_sym_ = ui::OZONEACTIONKEY_F14;
411           break;
412         case XKB_KEY_XF86Launch6:
413           cached_sym_ = ui::OZONEACTIONKEY_F15;
414           break;
415         case XKB_KEY_XF86Launch7:
416           cached_sym_ = ui::OZONEACTIONKEY_F16;
417           break;
418         case XKB_KEY_XF86Launch8:
419           cached_sym_ = ui::OZONEACTIONKEY_F17;
420           break;
421         case XKB_KEY_XF86Launch9:
422           cached_sym_ = ui::OZONEACTIONKEY_F18;
423           break;
424
425         // For supporting multimedia buttons on a USB keyboard.
426         case XKB_KEY_XF86Back:
427           cached_sym_ = ui::OZONEACTIONKEY_BROWSER_BACK;
428           break;
429         case XKB_KEY_XF86Forward:
430           cached_sym_ = ui::OZONEACTIONKEY_BROWSER_FORWARD;
431           break;
432         case XKB_KEY_XF86Reload:
433           cached_sym_ = ui::OZONEACTIONKEY_BROWSER_REFRESH;
434           break;
435         case XKB_KEY_XF86Stop:
436           cached_sym_ = ui::OZONEACTIONKEY_BROWSER_STOP;
437           break;
438         case XKB_KEY_XF86Search:
439           cached_sym_ = ui::OZONEACTIONKEY_BROWSER_SEARCH;
440           break;
441         case XKB_KEY_XF86Favorites:
442           cached_sym_ = ui::OZONEACTIONKEY_BROWSER_FAVORITES;
443           break;
444         case XKB_KEY_XF86HomePage:
445           cached_sym_ = ui::OZONEACTIONKEY_BROWSER_HOME;
446           break;
447         case XKB_KEY_XF86AudioMute:
448           cached_sym_ = ui::OZONEACTIONKEY_VOLUME_MUTE;
449           break;
450         case XKB_KEY_XF86AudioLowerVolume:
451           cached_sym_ = ui::OZONEACTIONKEY_VOLUME_DOWN;
452           break;
453         case XKB_KEY_XF86AudioRaiseVolume:
454           cached_sym_ = ui::OZONEACTIONKEY_VOLUME_UP;
455           break;
456         case XKB_KEY_XF86AudioNext:
457           cached_sym_ = ui::OZONEACTIONKEY_MEDIA_NEXT_TRACK;
458           break;
459         case XKB_KEY_XF86AudioPrev:
460           cached_sym_ = ui::OZONEACTIONKEY_MEDIA_PREV_TRACK;
461           break;
462         case XKB_KEY_XF86AudioStop:
463           cached_sym_ = ui::OZONEACTIONKEY_MEDIA_STOP;
464           break;
465         case XKB_KEY_XF86AudioPlay:
466           cached_sym_ = ui::OZONEACTIONKEY_MEDIA_PLAY_PAUSE;
467           break;
468         case XKB_KEY_XF86Mail:
469           cached_sym_ = ui::OZONEACTIONKEY_MEDIA_LAUNCH_MAIL;
470           break;
471         case XKB_KEY_XF86LaunchA:
472           cached_sym_ = ui::OZONEACTIONKEY_MEDIA_LAUNCH_APP1;
473           break;
474         case XKB_KEY_XF86LaunchB:
475         case XKB_KEY_XF86Calculator:
476           cached_sym_ = ui::OZONEACTIONKEY_MEDIA_LAUNCH_APP2;
477           break;
478         case XKB_KEY_XF86WLAN:
479           cached_sym_ = ui::OZONEACTIONKEY_WLAN;
480           break;
481         case XKB_KEY_XF86PowerOff:
482           cached_sym_ = ui::OZONEACTIONKEY_POWER;
483           break;
484         case XKB_KEY_XF86MonBrightnessDown:
485           cached_sym_ = ui::OZONEACTIONKEY_BRIGHTNESS_DOWN;
486           break;
487         case XKB_KEY_XF86MonBrightnessUp:
488           cached_sym_ = ui::OZONEACTIONKEY_BRIGHTNESS_UP;
489           break;
490         case XKB_KEY_XF86KbdBrightnessDown:
491           cached_sym_ = ui::OZONEACTIONKEY_KBD_BRIGHTNESS_DOWN;
492           break;
493         case XKB_KEY_XF86KbdBrightnessUp:
494           cached_sym_ = ui::OZONEACTIONKEY_KBD_BRIGHTNESS_UP;
495           break;
496         case XKB_KEY_emptyset:
497         case XKB_KEY_NoSymbol:
498           cached_sym_ = ui::OZONECHARCODE_NULL;
499           break;
500         default:
501           break;
502     }
503   }
504 }
505
506 }  // namespace ui