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/event_modifiers_evdev.h"
6
7#include <linux/input.h>
8
9#include "ui/events/event.h"
10
11namespace ui {
12
13namespace {
14
15static const int kEventFlagFromModifiers[] = {
16    EF_NONE,                 // EVDEV_MODIFIER_NONE,
17    EF_CAPS_LOCK_DOWN,       // EVDEV_MODIFIER_CAPS_LOCK
18    EF_SHIFT_DOWN,           // EVDEV_MODIFIER_SHIFT
19    EF_CONTROL_DOWN,         // EVDEV_MODIFIER_CONTROL
20    EF_ALT_DOWN,             // EVDEV_MODIFIER_ALT
21    EF_LEFT_MOUSE_BUTTON,    // EVDEV_MODIFIER_LEFT_MOUSE_BUTTON
22    EF_MIDDLE_MOUSE_BUTTON,  // EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON
23    EF_RIGHT_MOUSE_BUTTON,   // EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON
24    EF_COMMAND_DOWN,         // EVDEV_MODIFIER_COMMAND
25    EF_ALTGR_DOWN,           // EVDEV_MODIFIER_ALTGR
26};
27
28}  // namespace
29
30EventModifiersEvdev::EventModifiersEvdev()
31    : modifier_flags_locked_(0), modifier_flags_(0) {
32  memset(modifiers_down_, 0, sizeof(modifiers_down_));
33}
34EventModifiersEvdev::~EventModifiersEvdev() {}
35
36void EventModifiersEvdev::UpdateModifier(unsigned int modifier, bool down) {
37  DCHECK_LT(modifier, EVDEV_NUM_MODIFIERS);
38
39  if (down) {
40    modifiers_down_[modifier]++;
41  } else {
42    // Ignore spurious modifier "up" events. This might happen if the
43    // button is down during startup.
44    if (modifiers_down_[modifier])
45      modifiers_down_[modifier]--;
46  }
47
48  UpdateFlags(modifier);
49}
50
51void EventModifiersEvdev::UpdateModifierLock(unsigned int modifier, bool down) {
52  DCHECK_LT(modifier, EVDEV_NUM_MODIFIERS);
53
54  if (down)
55    modifier_flags_locked_ ^= kEventFlagFromModifiers[modifier];
56
57  // TODO(spang): Synchronize with the CapsLock LED.
58
59  UpdateFlags(modifier);
60}
61
62void EventModifiersEvdev::UpdateFlags(unsigned int modifier) {
63  int mask = kEventFlagFromModifiers[modifier];
64  bool down = modifiers_down_[modifier];
65  bool locked = (modifier_flags_locked_ & mask);
66  if (down != locked)
67    modifier_flags_ |= mask;
68  else
69    modifier_flags_ &= ~mask;
70}
71
72int EventModifiersEvdev::GetModifierFlags() { return modifier_flags_; }
73
74// static
75int EventModifiersEvdev::GetEventFlagFromModifier(unsigned int modifier) {
76  return kEventFlagFromModifiers[modifier];
77}
78
79}  // namespace ui
80