15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/events/ozone/evdev/key_event_converter_evdev.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <errno.h>
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <linux/input.h>
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/message_loop/message_loop.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/events/keycodes/dom4/keycode_converter.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/events/ozone/evdev/event_modifiers_evdev.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace ui {
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kXkbKeycodeOffset = 8;
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ui::KeyboardCode KeyboardCodeFromButton(unsigned int code) {
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static const ui::KeyboardCode kLinuxBaseKeyMap[] = {
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_RESERVED
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_ESCAPE,             // KEY_ESC
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_1,                  // KEY_1
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_2,                  // KEY_2
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_3,                  // KEY_3
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_4,                  // KEY_4
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_5,                  // KEY_5
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_6,                  // KEY_6
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_7,                  // KEY_7
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_8,                  // KEY_8
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_9,                  // KEY_9
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_0,                  // KEY_0
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_MINUS,          // KEY_MINUS
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_PLUS,           // KEY_EQUAL
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_BACK,               // KEY_BACKSPACE
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_TAB,                // KEY_TAB
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_Q,                  // KEY_Q
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_W,                  // KEY_W
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_E,                  // KEY_E
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_R,                  // KEY_R
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_T,                  // KEY_T
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_Y,                  // KEY_Y
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_U,                  // KEY_U
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_I,                  // KEY_I
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_O,                  // KEY_O
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_P,                  // KEY_P
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_4,              // KEY_LEFTBRACE
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_6,              // KEY_RIGHTBRACE
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_RETURN,             // KEY_ENTER
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_CONTROL,            // KEY_LEFTCTRL
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_A,                  // KEY_A
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_S,                  // KEY_S
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_D,                  // KEY_D
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F,                  // KEY_F
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_G,                  // KEY_G
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_H,                  // KEY_H
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_J,                  // KEY_J
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_K,                  // KEY_K
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_L,                  // KEY_L
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_1,              // KEY_SEMICOLON
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_7,              // KEY_APOSTROPHE
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_3,              // KEY_GRAVE
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_SHIFT,              // KEY_LEFTSHIFT
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_5,              // KEY_BACKSLASH
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_Z,                  // KEY_Z
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_X,                  // KEY_X
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_C,                  // KEY_C
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_V,                  // KEY_V
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_B,                  // KEY_B
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_N,                  // KEY_N
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_M,                  // KEY_M
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_COMMA,          // KEY_COMMA
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_PERIOD,         // KEY_DOT
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_2,              // KEY_SLASH
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_SHIFT,              // KEY_RIGHTSHIFT
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_MULTIPLY,           // KEY_KPASTERISK
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_MENU,               // KEY_LEFTALT
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_SPACE,              // KEY_SPACE
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_CAPITAL,            // KEY_CAPSLOCK
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F1,                 // KEY_F1
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F2,                 // KEY_F2
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F3,                 // KEY_F3
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F4,                 // KEY_F4
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F5,                 // KEY_F5
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F6,                 // KEY_F6
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F7,                 // KEY_F7
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F8,                 // KEY_F8
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F9,                 // KEY_F9
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F10,                // KEY_F10
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMLOCK,            // KEY_NUMLOCK
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_SCROLL,             // KEY_SCROLLLOCK
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD7,            // KEY_KP7
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD8,            // KEY_KP8
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD9,            // KEY_KP9
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_SUBTRACT,           // KEY_KPMINUS
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD4,            // KEY_KP4
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD5,            // KEY_KP5
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD6,            // KEY_KP6
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_ADD,                // KEY_KPPLUS
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD1,            // KEY_KP1
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD2,            // KEY_KP2
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD3,            // KEY_KP3
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NUMPAD0,            // KEY_KP0
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_DECIMAL,            // KEY_KPDOT
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // (unassigned)
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_DBE_DBCSCHAR,       // KEY_ZENKAKUHANKAKU
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_102,            // KEY_102ND
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F11,                // KEY_F11
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_F12,                // KEY_F12
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_RO
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_KATAKANA
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_HIRAGANA
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_CONVERT,            // KEY_HENKAN
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_KATAKANAHIRAGANA
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NONCONVERT,         // KEY_MUHENKAN
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_KPJPCOMMA
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_RETURN,             // KEY_KPENTER
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_CONTROL,            // KEY_RIGHTCTRL
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_DIVIDE,             // KEY_KPSLASH
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_PRINT,              // KEY_SYSRQ
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_MENU,               // KEY_RIGHTALT
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_RETURN,             // KEY_LINEFEED
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_HOME,               // KEY_HOME
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UP,                 // KEY_UP
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_PRIOR,              // KEY_PAGEUP
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_LEFT,               // KEY_LEFT
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_RIGHT,              // KEY_RIGHT
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_END,                // KEY_END
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_DOWN,               // KEY_DOWN
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_NEXT,               // KEY_PAGEDOWN
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_INSERT,             // KEY_INSERT
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_DELETE,             // KEY_DELETE
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_MACRO
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_VOLUME_MUTE,        // KEY_MUTE
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_VOLUME_DOWN,        // KEY_VOLUMEDOWN
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_VOLUME_UP,          // KEY_VOLUMEUP
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_POWER,              // KEY_POWER
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_OEM_PLUS,           // KEY_KPEQUAL
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_KPPLUSMINUS
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_PAUSE,              // KEY_PAUSE
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_MEDIA_LAUNCH_APP1,  // KEY_SCALE
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_DECIMAL,            // KEY_KPCOMMA
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_HANGUL,             // KEY_HANGEUL
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_HANJA,              // KEY_HANJA
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_UNKNOWN,            // KEY_YEN
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_LWIN,               // KEY_LEFTMETA
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_RWIN,               // KEY_RIGHTMETA
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ui::VKEY_APPS,               // KEY_COMPOSE
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (code < arraysize(kLinuxBaseKeyMap))
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return kLinuxBaseKeyMap[code];
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LOG(ERROR) << "Unknown key code: " << code;
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ui::VKEY_UNKNOWN;
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int ModifierFromButton(unsigned int code) {
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  switch (code) {
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_CAPSLOCK:
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_CAPS_LOCK;
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_LEFTSHIFT:
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_RIGHTSHIFT:
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_SHIFT;
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_LEFTCTRL:
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_RIGHTCTRL:
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_CONTROL;
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_LEFTALT:
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_RIGHTALT:
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_ALT;
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case BTN_LEFT:
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_LEFT_MOUSE_BUTTON;
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case BTN_MIDDLE:
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON;
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case BTN_RIGHT:
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON;
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_LEFTMETA:
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case KEY_RIGHTMETA:
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_COMMAND;
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    default:
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return EVDEV_MODIFIER_NONE;
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool IsLockButton(unsigned int code) { return code == KEY_CAPSLOCK; }
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1920529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochKeyEventConverterEvdev::KeyEventConverterEvdev(
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int fd,
1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::FilePath path,
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EventModifiersEvdev* modifiers,
1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const EventDispatchCallback& callback)
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : EventConverterEvdev(fd, path),
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      callback_(callback),
1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      modifiers_(modifiers) {
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(spang): Initialize modifiers using EVIOCGKEY.
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)KeyEventConverterEvdev::~KeyEventConverterEvdev() {
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Stop();
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  close(fd_);
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void KeyEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  input_event inputs[4];
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssize_t read_size = read(fd, inputs, sizeof(inputs));
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (read_size < 0) {
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (errno == EINTR || errno == EAGAIN)
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (errno != ENODEV)
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PLOG(ERROR) << "error reading device " << path_.value();
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Stop();
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(read_size % sizeof(*inputs), 0u);
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ProcessEvents(inputs, read_size / sizeof(*inputs));
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void KeyEventConverterEvdev::ProcessEvents(const input_event* inputs,
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                           int count) {
2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (int i = 0; i < count; ++i) {
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const input_event& input = inputs[i];
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (input.type == EV_KEY) {
2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ConvertKeyEvent(input.code, input.value);
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (input.type == EV_SYN) {
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // TODO(sadrul): Handle this case appropriately.
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void KeyEventConverterEvdev::ConvertKeyEvent(int key, int value) {
2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int down = (value != 0);
2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int repeat = (value == 2);
2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int modifier = ModifierFromButton(key);
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ui::KeyboardCode code = KeyboardCodeFromButton(key);
2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!repeat && (modifier != EVDEV_MODIFIER_NONE)) {
2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (IsLockButton(key)) {
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // Locking modifier keys: CapsLock.
2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      modifiers_->UpdateModifierLock(modifier, down);
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else {
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // Regular modifier keys: Shift, Ctrl, Alt, etc.
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      modifiers_->UpdateModifier(modifier, down);
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int flags = modifiers_->GetModifierFlags();
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  KeyEvent key_event(
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      down ? ET_KEY_PRESSED : ET_KEY_RELEASED,
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      code,
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      KeycodeConverter::NativeKeycodeToCode(key + kXkbKeycodeOffset),
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      flags);
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callback_.Run(&key_event);
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace ui
263