This source file includes following definitions.
- KeyboardCodeFromButton
- ModifierFromButton
- IsLockButton
- modifiers_
- Start
- Stop
- OnFileCanReadWithoutBlocking
- OnFileCanWriteWithoutBlocking
- ProcessEvents
- ConvertKeyEvent
#include "ui/events/ozone/evdev/key_event_converter_evdev.h"
#include <errno.h>
#include <linux/input.h>
#include "base/message_loop/message_pump_ozone.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/ozone/evdev/event_modifiers_evdev.h"
#include "ui/events/ozone/event_factory_ozone.h"
namespace ui {
namespace {
ui::KeyboardCode KeyboardCodeFromButton(unsigned int code) {
static const ui::KeyboardCode kLinuxBaseKeyMap[] = {
ui::VKEY_UNKNOWN,
ui::VKEY_ESCAPE,
ui::VKEY_1,
ui::VKEY_2,
ui::VKEY_3,
ui::VKEY_4,
ui::VKEY_5,
ui::VKEY_6,
ui::VKEY_7,
ui::VKEY_8,
ui::VKEY_9,
ui::VKEY_0,
ui::VKEY_OEM_MINUS,
ui::VKEY_OEM_PLUS,
ui::VKEY_BACK,
ui::VKEY_TAB,
ui::VKEY_Q,
ui::VKEY_W,
ui::VKEY_E,
ui::VKEY_R,
ui::VKEY_T,
ui::VKEY_Y,
ui::VKEY_U,
ui::VKEY_I,
ui::VKEY_O,
ui::VKEY_P,
ui::VKEY_OEM_4,
ui::VKEY_OEM_6,
ui::VKEY_RETURN,
ui::VKEY_CONTROL,
ui::VKEY_A,
ui::VKEY_S,
ui::VKEY_D,
ui::VKEY_F,
ui::VKEY_G,
ui::VKEY_H,
ui::VKEY_J,
ui::VKEY_K,
ui::VKEY_L,
ui::VKEY_OEM_1,
ui::VKEY_OEM_7,
ui::VKEY_OEM_3,
ui::VKEY_SHIFT,
ui::VKEY_OEM_5,
ui::VKEY_Z,
ui::VKEY_X,
ui::VKEY_C,
ui::VKEY_V,
ui::VKEY_B,
ui::VKEY_N,
ui::VKEY_M,
ui::VKEY_OEM_COMMA,
ui::VKEY_OEM_PERIOD,
ui::VKEY_OEM_2,
ui::VKEY_SHIFT,
ui::VKEY_MULTIPLY,
ui::VKEY_MENU,
ui::VKEY_SPACE,
ui::VKEY_CAPITAL,
ui::VKEY_F1,
ui::VKEY_F2,
ui::VKEY_F3,
ui::VKEY_F4,
ui::VKEY_F5,
ui::VKEY_F6,
ui::VKEY_F7,
ui::VKEY_F8,
ui::VKEY_F9,
ui::VKEY_F10,
ui::VKEY_NUMLOCK,
ui::VKEY_SCROLL,
ui::VKEY_NUMPAD7,
ui::VKEY_NUMPAD8,
ui::VKEY_NUMPAD9,
ui::VKEY_SUBTRACT,
ui::VKEY_NUMPAD4,
ui::VKEY_NUMPAD5,
ui::VKEY_NUMPAD6,
ui::VKEY_ADD,
ui::VKEY_NUMPAD1,
ui::VKEY_NUMPAD2,
ui::VKEY_NUMPAD3,
ui::VKEY_NUMPAD0,
ui::VKEY_DECIMAL,
ui::VKEY_UNKNOWN,
ui::VKEY_DBE_DBCSCHAR,
ui::VKEY_OEM_102,
ui::VKEY_F11,
ui::VKEY_F12,
ui::VKEY_UNKNOWN,
ui::VKEY_UNKNOWN,
ui::VKEY_UNKNOWN,
ui::VKEY_CONVERT,
ui::VKEY_UNKNOWN,
ui::VKEY_NONCONVERT,
ui::VKEY_UNKNOWN,
ui::VKEY_RETURN,
ui::VKEY_CONTROL,
ui::VKEY_DIVIDE,
ui::VKEY_PRINT,
ui::VKEY_MENU,
ui::VKEY_RETURN,
ui::VKEY_HOME,
ui::VKEY_UP,
ui::VKEY_PRIOR,
ui::VKEY_LEFT,
ui::VKEY_RIGHT,
ui::VKEY_END,
ui::VKEY_DOWN,
ui::VKEY_NEXT,
ui::VKEY_INSERT,
ui::VKEY_DELETE,
ui::VKEY_UNKNOWN,
ui::VKEY_VOLUME_MUTE,
ui::VKEY_VOLUME_DOWN,
ui::VKEY_VOLUME_UP,
ui::VKEY_POWER,
ui::VKEY_OEM_PLUS,
ui::VKEY_UNKNOWN,
ui::VKEY_PAUSE,
ui::VKEY_MEDIA_LAUNCH_APP1,
ui::VKEY_DECIMAL,
ui::VKEY_HANGUL,
ui::VKEY_HANJA,
ui::VKEY_UNKNOWN,
ui::VKEY_LWIN,
ui::VKEY_RWIN,
ui::VKEY_APPS,
};
if (code < arraysize(kLinuxBaseKeyMap))
return kLinuxBaseKeyMap[code];
LOG(ERROR) << "Unknown key code: " << code;
return ui::VKEY_UNKNOWN;
}
int ModifierFromButton(unsigned int code) {
switch (code) {
case KEY_CAPSLOCK:
return EVDEV_MODIFIER_CAPS_LOCK;
case KEY_LEFTSHIFT:
case KEY_RIGHTSHIFT:
return EVDEV_MODIFIER_SHIFT;
case KEY_LEFTCTRL:
case KEY_RIGHTCTRL:
return EVDEV_MODIFIER_CONTROL;
case KEY_LEFTALT:
case KEY_RIGHTALT:
return EVDEV_MODIFIER_ALT;
case BTN_LEFT:
return EVDEV_MODIFIER_LEFT_MOUSE_BUTTON;
case BTN_MIDDLE:
return EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON;
case BTN_RIGHT:
return EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON;
case KEY_LEFTMETA:
case KEY_RIGHTMETA:
return EVDEV_MODIFIER_COMMAND;
default:
return EVDEV_MODIFIER_NONE;
}
}
bool IsLockButton(unsigned int code) { return code == KEY_CAPSLOCK; }
}
KeyEventConverterEvdev::KeyEventConverterEvdev(int fd,
base::FilePath path,
EventModifiersEvdev* modifiers)
: fd_(fd), path_(path), modifiers_(modifiers) {
}
KeyEventConverterEvdev::~KeyEventConverterEvdev() {
Stop();
close(fd_);
}
void KeyEventConverterEvdev::Start() {
base::MessagePumpOzone::Current()->WatchFileDescriptor(
fd_, true, base::MessagePumpLibevent::WATCH_READ, &controller_, this);
}
void KeyEventConverterEvdev::Stop() {
controller_.StopWatchingFileDescriptor();
}
void KeyEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
input_event inputs[4];
ssize_t read_size = read(fd, inputs, sizeof(inputs));
if (read_size < 0) {
if (errno == EINTR || errno == EAGAIN)
return;
if (errno != ENODEV)
PLOG(ERROR) << "error reading device " << path_.value();
Stop();
return;
}
CHECK_EQ(read_size % sizeof(*inputs), 0u);
ProcessEvents(inputs, read_size / sizeof(*inputs));
}
void KeyEventConverterEvdev::OnFileCanWriteWithoutBlocking(int fd) {
NOTREACHED();
}
void KeyEventConverterEvdev::ProcessEvents(const input_event* inputs,
int count) {
for (int i = 0; i < count; ++i) {
const input_event& input = inputs[i];
if (input.type == EV_KEY) {
ConvertKeyEvent(input.code, input.value);
} else if (input.type == EV_SYN) {
}
}
}
void KeyEventConverterEvdev::ConvertKeyEvent(int key, int value) {
int down = (value != 0);
int repeat = (value == 2);
int modifier = ModifierFromButton(key);
ui::KeyboardCode code = KeyboardCodeFromButton(key);
if (!repeat && (modifier != EVDEV_MODIFIER_NONE)) {
if (IsLockButton(key)) {
modifiers_->UpdateModifierLock(modifier, down);
} else {
modifiers_->UpdateModifier(modifier, down);
}
}
int flags = modifiers_->GetModifierFlags();
KeyEvent key_event(
down ? ET_KEY_PRESSED : ET_KEY_RELEASED, code, flags, true);
DispatchEventToCallback(&key_event);
}
}