Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / ui / events / ozone / evdev / keyboard_evdev.cc
1 // Copyright 2014 The Chromium Authors. 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 "ui/events/ozone/evdev/keyboard_evdev.h"
6
7 #include "ui/events/event.h"
8 #include "ui/events/keycodes/dom4/keycode_converter.h"
9 #include "ui/events/ozone/evdev/event_modifiers_evdev.h"
10
11 namespace ui {
12
13 namespace {
14
15 const int kXkbKeycodeOffset = 8;
16
17 ui::KeyboardCode KeyboardCodeFromEvdevKey(unsigned int code) {
18   static const ui::KeyboardCode kLinuxBaseKeyMap[] = {
19       ui::VKEY_UNKNOWN,            // KEY_RESERVED
20       ui::VKEY_ESCAPE,             // KEY_ESC
21       ui::VKEY_1,                  // KEY_1
22       ui::VKEY_2,                  // KEY_2
23       ui::VKEY_3,                  // KEY_3
24       ui::VKEY_4,                  // KEY_4
25       ui::VKEY_5,                  // KEY_5
26       ui::VKEY_6,                  // KEY_6
27       ui::VKEY_7,                  // KEY_7
28       ui::VKEY_8,                  // KEY_8
29       ui::VKEY_9,                  // KEY_9
30       ui::VKEY_0,                  // KEY_0
31       ui::VKEY_OEM_MINUS,          // KEY_MINUS
32       ui::VKEY_OEM_PLUS,           // KEY_EQUAL
33       ui::VKEY_BACK,               // KEY_BACKSPACE
34       ui::VKEY_TAB,                // KEY_TAB
35       ui::VKEY_Q,                  // KEY_Q
36       ui::VKEY_W,                  // KEY_W
37       ui::VKEY_E,                  // KEY_E
38       ui::VKEY_R,                  // KEY_R
39       ui::VKEY_T,                  // KEY_T
40       ui::VKEY_Y,                  // KEY_Y
41       ui::VKEY_U,                  // KEY_U
42       ui::VKEY_I,                  // KEY_I
43       ui::VKEY_O,                  // KEY_O
44       ui::VKEY_P,                  // KEY_P
45       ui::VKEY_OEM_4,              // KEY_LEFTBRACE
46       ui::VKEY_OEM_6,              // KEY_RIGHTBRACE
47       ui::VKEY_RETURN,             // KEY_ENTER
48       ui::VKEY_CONTROL,            // KEY_LEFTCTRL
49       ui::VKEY_A,                  // KEY_A
50       ui::VKEY_S,                  // KEY_S
51       ui::VKEY_D,                  // KEY_D
52       ui::VKEY_F,                  // KEY_F
53       ui::VKEY_G,                  // KEY_G
54       ui::VKEY_H,                  // KEY_H
55       ui::VKEY_J,                  // KEY_J
56       ui::VKEY_K,                  // KEY_K
57       ui::VKEY_L,                  // KEY_L
58       ui::VKEY_OEM_1,              // KEY_SEMICOLON
59       ui::VKEY_OEM_7,              // KEY_APOSTROPHE
60       ui::VKEY_OEM_3,              // KEY_GRAVE
61       ui::VKEY_SHIFT,              // KEY_LEFTSHIFT
62       ui::VKEY_OEM_5,              // KEY_BACKSLASH
63       ui::VKEY_Z,                  // KEY_Z
64       ui::VKEY_X,                  // KEY_X
65       ui::VKEY_C,                  // KEY_C
66       ui::VKEY_V,                  // KEY_V
67       ui::VKEY_B,                  // KEY_B
68       ui::VKEY_N,                  // KEY_N
69       ui::VKEY_M,                  // KEY_M
70       ui::VKEY_OEM_COMMA,          // KEY_COMMA
71       ui::VKEY_OEM_PERIOD,         // KEY_DOT
72       ui::VKEY_OEM_2,              // KEY_SLASH
73       ui::VKEY_SHIFT,              // KEY_RIGHTSHIFT
74       ui::VKEY_MULTIPLY,           // KEY_KPASTERISK
75       ui::VKEY_MENU,               // KEY_LEFTALT
76       ui::VKEY_SPACE,              // KEY_SPACE
77       ui::VKEY_CAPITAL,            // KEY_CAPSLOCK
78       ui::VKEY_F1,                 // KEY_F1
79       ui::VKEY_F2,                 // KEY_F2
80       ui::VKEY_F3,                 // KEY_F3
81       ui::VKEY_F4,                 // KEY_F4
82       ui::VKEY_F5,                 // KEY_F5
83       ui::VKEY_F6,                 // KEY_F6
84       ui::VKEY_F7,                 // KEY_F7
85       ui::VKEY_F8,                 // KEY_F8
86       ui::VKEY_F9,                 // KEY_F9
87       ui::VKEY_F10,                // KEY_F10
88       ui::VKEY_NUMLOCK,            // KEY_NUMLOCK
89       ui::VKEY_SCROLL,             // KEY_SCROLLLOCK
90       ui::VKEY_NUMPAD7,            // KEY_KP7
91       ui::VKEY_NUMPAD8,            // KEY_KP8
92       ui::VKEY_NUMPAD9,            // KEY_KP9
93       ui::VKEY_SUBTRACT,           // KEY_KPMINUS
94       ui::VKEY_NUMPAD4,            // KEY_KP4
95       ui::VKEY_NUMPAD5,            // KEY_KP5
96       ui::VKEY_NUMPAD6,            // KEY_KP6
97       ui::VKEY_ADD,                // KEY_KPPLUS
98       ui::VKEY_NUMPAD1,            // KEY_KP1
99       ui::VKEY_NUMPAD2,            // KEY_KP2
100       ui::VKEY_NUMPAD3,            // KEY_KP3
101       ui::VKEY_NUMPAD0,            // KEY_KP0
102       ui::VKEY_DECIMAL,            // KEY_KPDOT
103       ui::VKEY_UNKNOWN,            // (unassigned)
104       ui::VKEY_DBE_DBCSCHAR,       // KEY_ZENKAKUHANKAKU
105       ui::VKEY_OEM_102,            // KEY_102ND
106       ui::VKEY_F11,                // KEY_F11
107       ui::VKEY_F12,                // KEY_F12
108       ui::VKEY_UNKNOWN,            // KEY_RO
109       ui::VKEY_UNKNOWN,            // KEY_KATAKANA
110       ui::VKEY_UNKNOWN,            // KEY_HIRAGANA
111       ui::VKEY_CONVERT,            // KEY_HENKAN
112       ui::VKEY_UNKNOWN,            // KEY_KATAKANAHIRAGANA
113       ui::VKEY_NONCONVERT,         // KEY_MUHENKAN
114       ui::VKEY_UNKNOWN,            // KEY_KPJPCOMMA
115       ui::VKEY_RETURN,             // KEY_KPENTER
116       ui::VKEY_CONTROL,            // KEY_RIGHTCTRL
117       ui::VKEY_DIVIDE,             // KEY_KPSLASH
118       ui::VKEY_PRINT,              // KEY_SYSRQ
119       ui::VKEY_MENU,               // KEY_RIGHTALT
120       ui::VKEY_RETURN,             // KEY_LINEFEED
121       ui::VKEY_HOME,               // KEY_HOME
122       ui::VKEY_UP,                 // KEY_UP
123       ui::VKEY_PRIOR,              // KEY_PAGEUP
124       ui::VKEY_LEFT,               // KEY_LEFT
125       ui::VKEY_RIGHT,              // KEY_RIGHT
126       ui::VKEY_END,                // KEY_END
127       ui::VKEY_DOWN,               // KEY_DOWN
128       ui::VKEY_NEXT,               // KEY_PAGEDOWN
129       ui::VKEY_INSERT,             // KEY_INSERT
130       ui::VKEY_DELETE,             // KEY_DELETE
131       ui::VKEY_UNKNOWN,            // KEY_MACRO
132       ui::VKEY_VOLUME_MUTE,        // KEY_MUTE
133       ui::VKEY_VOLUME_DOWN,        // KEY_VOLUMEDOWN
134       ui::VKEY_VOLUME_UP,          // KEY_VOLUMEUP
135       ui::VKEY_POWER,              // KEY_POWER
136       ui::VKEY_OEM_PLUS,           // KEY_KPEQUAL
137       ui::VKEY_UNKNOWN,            // KEY_KPPLUSMINUS
138       ui::VKEY_PAUSE,              // KEY_PAUSE
139       ui::VKEY_MEDIA_LAUNCH_APP1,  // KEY_SCALE
140       ui::VKEY_DECIMAL,            // KEY_KPCOMMA
141       ui::VKEY_HANGUL,             // KEY_HANGEUL
142       ui::VKEY_HANJA,              // KEY_HANJA
143       ui::VKEY_UNKNOWN,            // KEY_YEN
144       ui::VKEY_LWIN,               // KEY_LEFTMETA
145       ui::VKEY_RWIN,               // KEY_RIGHTMETA
146       ui::VKEY_APPS,               // KEY_COMPOSE
147   };
148
149   if (code < arraysize(kLinuxBaseKeyMap))
150     return kLinuxBaseKeyMap[code];
151
152   LOG(ERROR) << "Unknown key code: " << code;
153   return ui::VKEY_UNKNOWN;
154 }
155
156 int ModifierFromEvdevKey(unsigned int code) {
157   switch (code) {
158     case KEY_CAPSLOCK:
159       return EVDEV_MODIFIER_CAPS_LOCK;
160     case KEY_LEFTSHIFT:
161     case KEY_RIGHTSHIFT:
162       return EVDEV_MODIFIER_SHIFT;
163     case KEY_LEFTCTRL:
164     case KEY_RIGHTCTRL:
165       return EVDEV_MODIFIER_CONTROL;
166     case KEY_LEFTALT:
167     case KEY_RIGHTALT:
168       return EVDEV_MODIFIER_ALT;
169     case BTN_LEFT:
170       return EVDEV_MODIFIER_LEFT_MOUSE_BUTTON;
171     case BTN_MIDDLE:
172       return EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON;
173     case BTN_RIGHT:
174       return EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON;
175     case KEY_LEFTMETA:
176     case KEY_RIGHTMETA:
177       return EVDEV_MODIFIER_COMMAND;
178     default:
179       return EVDEV_MODIFIER_NONE;
180   }
181 }
182
183 bool IsModifierLockKeyFromEvdevKey(unsigned int code) {
184   return code == KEY_CAPSLOCK;
185 }
186
187 }  // namespace
188
189 KeyboardEvdev::KeyboardEvdev(EventModifiersEvdev* modifiers,
190                              const EventDispatchCallback& callback)
191     : callback_(callback), modifiers_(modifiers) {
192 }
193
194 KeyboardEvdev::~KeyboardEvdev() {
195 }
196
197 void KeyboardEvdev::OnKeyChange(unsigned int key, bool down) {
198   if (key > KEY_MAX)
199     return;
200
201   if (down != key_state_.test(key)) {
202     // State transition: !(down) -> (down)
203     if (down)
204       key_state_.set(key);
205     else
206       key_state_.reset(key);
207
208     UpdateModifier(key, down);
209   }
210
211   DispatchKey(key, down);
212 }
213
214 void KeyboardEvdev::UpdateModifier(unsigned int key, bool down) {
215   int modifier = ModifierFromEvdevKey(key);
216   int locking = IsModifierLockKeyFromEvdevKey(key);
217
218   if (modifier == EVDEV_MODIFIER_NONE)
219     return;
220
221   if (locking)
222     modifiers_->UpdateModifierLock(modifier, down);
223   else
224     modifiers_->UpdateModifier(modifier, down);
225 }
226
227 void KeyboardEvdev::DispatchKey(unsigned int key, bool down) {
228   ui::KeyboardCode code = KeyboardCodeFromEvdevKey(key);
229   int flags = modifiers_->GetModifierFlags();
230
231   if (code == VKEY_UNKNOWN)
232     return;
233
234   callback_.Run(make_scoped_ptr(new KeyEvent(
235       down ? ET_KEY_PRESSED : ET_KEY_RELEASED,
236       code,
237       KeycodeConverter::NativeKeycodeToCode(key + kXkbKeycodeOffset),
238       flags)));
239 }
240
241 }  // namespace ui