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/event_modifiers.h"
6 
7 #include "ui/events/event.h"
8 
9 namespace ui {
10 
11 namespace {
12 
13 static const int kEventFlagFromModifiers[] = {
14     EF_NONE,                  // MODIFIER_NONE,
15     EF_SHIFT_DOWN,            // MODIFIER_SHIFT
16     EF_CONTROL_DOWN,          // MODIFIER_CONTROL
17     EF_ALT_DOWN,              // MODIFIER_ALT
18     EF_COMMAND_DOWN,          // MODIFIER_COMMAND
19     EF_ALTGR_DOWN,            // MODIFIER_ALTGR
20     EF_MOD3_DOWN,             // MODIFIER_MOD3
21     EF_CAPS_LOCK_ON,          // MODIFIER_CAPS_LOCK
22     EF_LEFT_MOUSE_BUTTON,     // MODIFIER_LEFT_MOUSE_BUTTON
23     EF_MIDDLE_MOUSE_BUTTON,   // MODIFIER_MIDDLE_MOUSE_BUTTON
24     EF_RIGHT_MOUSE_BUTTON,    // MODIFIER_RIGHT_MOUSE_BUTTON
25     EF_BACK_MOUSE_BUTTON,     // MODIFIER_BACK_MOUSE_BUTTON
26     EF_FORWARD_MOUSE_BUTTON,  // MODIFIER_FORWARD_MOUSE_BUTTON
27 };
28 
29 }  // namespace
30 
EventModifiers()31 EventModifiers::EventModifiers() {
32   memset(modifiers_down_, 0, sizeof(modifiers_down_));
33 }
~EventModifiers()34 EventModifiers::~EventModifiers() {}
35 
UpdateModifier(unsigned int modifier,bool down)36 void EventModifiers::UpdateModifier(unsigned int modifier, bool down) {
37   DCHECK_LT(modifier, static_cast<unsigned int>(MODIFIER_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 
UpdateModifierLock(unsigned int modifier,bool down)51 void EventModifiers::UpdateModifierLock(unsigned int modifier, bool down) {
52   DCHECK_LT(modifier, static_cast<unsigned int>(MODIFIER_NUM_MODIFIERS));
53 
54   if (down)
55     modifier_flags_locked_ ^= kEventFlagFromModifiers[modifier];
56 
57   UpdateFlags(modifier);
58 }
59 
SetModifierLock(unsigned int modifier,bool locked)60 void EventModifiers::SetModifierLock(unsigned int modifier, bool locked) {
61   DCHECK_LT(modifier, static_cast<unsigned int>(MODIFIER_NUM_MODIFIERS));
62 
63   if (locked)
64     modifier_flags_locked_ |= kEventFlagFromModifiers[modifier];
65   else
66     modifier_flags_locked_ &= ~kEventFlagFromModifiers[modifier];
67 
68   UpdateFlags(modifier);
69 }
70 
UpdateFlags(unsigned int modifier)71 void EventModifiers::UpdateFlags(unsigned int modifier) {
72   int mask = kEventFlagFromModifiers[modifier];
73   bool down = modifiers_down_[modifier] != 0;
74   bool locked = (modifier_flags_locked_ & mask) != 0;
75   if (down != locked)
76     modifier_flags_ |= mask;
77   else
78     modifier_flags_ &= ~mask;
79 }
80 
GetModifierFlags()81 int EventModifiers::GetModifierFlags() {
82   return modifier_flags_;
83 }
84 
ResetKeyboardModifiers()85 void EventModifiers::ResetKeyboardModifiers() {
86   static const int kKeyboardModifiers[] = {MODIFIER_SHIFT, MODIFIER_CONTROL,
87                                            MODIFIER_ALT,   MODIFIER_COMMAND,
88                                            MODIFIER_ALTGR, MODIFIER_MOD3};
89   for (const int modifier : kKeyboardModifiers) {
90     modifiers_down_[modifier] = 0;
91     UpdateFlags(modifier);
92   }
93 }
94 
95 // static
GetEventFlagFromModifier(unsigned int modifier)96 int EventModifiers::GetEventFlagFromModifier(unsigned int modifier) {
97   return kEventFlagFromModifiers[modifier];
98 }
99 
100 // static
GetModifierFromEventFlag(int flag)101 int EventModifiers::GetModifierFromEventFlag(int flag) {
102   switch (flag) {
103     case EF_SHIFT_DOWN:
104       return MODIFIER_SHIFT;
105     case EF_CONTROL_DOWN:
106       return MODIFIER_CONTROL;
107     case EF_ALT_DOWN:
108       return MODIFIER_ALT;
109     case EF_COMMAND_DOWN:
110       return MODIFIER_COMMAND;
111     case EF_ALTGR_DOWN:
112       return MODIFIER_ALTGR;
113     case EF_MOD3_DOWN:
114       return MODIFIER_MOD3;
115     case EF_CAPS_LOCK_ON:
116       return MODIFIER_CAPS_LOCK;
117     case EF_LEFT_MOUSE_BUTTON:
118       return MODIFIER_LEFT_MOUSE_BUTTON;
119     case EF_MIDDLE_MOUSE_BUTTON:
120       return MODIFIER_MIDDLE_MOUSE_BUTTON;
121     case EF_RIGHT_MOUSE_BUTTON:
122       return MODIFIER_RIGHT_MOUSE_BUTTON;
123     case EF_BACK_MOUSE_BUTTON:
124       return MODIFIER_BACK_MOUSE_BUTTON;
125     case EF_FORWARD_MOUSE_BUTTON:
126       return MODIFIER_FORWARD_MOUSE_BUTTON;
127     default:
128       return MODIFIER_NONE;
129   }
130 }
131 
132 }  // namespace ui
133