OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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 "aura/event.h" |
| 6 |
| 7 #include <X11/Xlib.h> |
| 8 #include <X11/extensions/XInput2.h> |
| 9 |
| 10 #include "base/logging.h" |
| 11 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
| 12 |
| 13 namespace aura { |
| 14 |
| 15 namespace { |
| 16 |
| 17 int GetEventFlagsFromXState(unsigned int state) { |
| 18 int flags = 0; |
| 19 if (state & ControlMask) |
| 20 flags |= ui::EF_CONTROL_DOWN; |
| 21 if (state & ShiftMask) |
| 22 flags |= ui::EF_SHIFT_DOWN; |
| 23 if (state & Mod1Mask) |
| 24 flags |= ui::EF_ALT_DOWN; |
| 25 if (state & LockMask) |
| 26 flags |= ui::EF_CAPS_LOCK_DOWN; |
| 27 if (state & Button1Mask) |
| 28 flags |= ui::EF_LEFT_BUTTON_DOWN; |
| 29 if (state & Button2Mask) |
| 30 flags |= ui::EF_MIDDLE_BUTTON_DOWN; |
| 31 if (state & Button3Mask) |
| 32 flags |= ui::EF_RIGHT_BUTTON_DOWN; |
| 33 |
| 34 return flags; |
| 35 } |
| 36 |
| 37 // Get the event flag for the button in XButtonEvent. During a ButtonPress |
| 38 // event, |state| in XButtonEvent does not include the button that has just been |
| 39 // pressed. Instead |state| contains flags for the buttons (if any) that had |
| 40 // already been pressed before the current button, and |button| stores the most |
| 41 // current pressed button. So, if you press down left mouse button, and while |
| 42 // pressing it down, press down the right mouse button, then for the latter |
| 43 // event, |state| would have Button1Mask set but not Button3Mask, and |button| |
| 44 // would be 3. |
| 45 int GetEventFlagsForButton(int button) { |
| 46 switch (button) { |
| 47 case 1: |
| 48 return ui::EF_LEFT_BUTTON_DOWN; |
| 49 case 2: |
| 50 return ui::EF_MIDDLE_BUTTON_DOWN; |
| 51 case 3: |
| 52 return ui::EF_RIGHT_BUTTON_DOWN; |
| 53 } |
| 54 |
| 55 DLOG(WARNING) << "Unexpected button (" << button << ") received."; |
| 56 return 0; |
| 57 } |
| 58 |
| 59 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { |
| 60 int buttonflags = 0; |
| 61 |
| 62 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { |
| 63 if (XIMaskIsSet(xievent->buttons.mask, i)) { |
| 64 buttonflags |= GetEventFlagsForButton(i); |
| 65 } |
| 66 } |
| 67 |
| 68 return buttonflags; |
| 69 } |
| 70 |
| 71 ui::EventType EventTypeFromNative(NativeEvent native_event) { |
| 72 switch (native_event->type) { |
| 73 case KeyPress: |
| 74 return ui::ET_KEY_PRESSED; |
| 75 case KeyRelease: |
| 76 return ui::ET_KEY_RELEASED; |
| 77 case ButtonPress: |
| 78 if (native_event->xbutton.button == 4 || |
| 79 native_event->xbutton.button == 5) |
| 80 return ui::ET_MOUSEWHEEL; |
| 81 return ui::ET_MOUSE_PRESSED; |
| 82 case ButtonRelease: |
| 83 if (native_event->xbutton.button == 4 || |
| 84 native_event->xbutton.button == 5) |
| 85 return ui::ET_MOUSEWHEEL; |
| 86 return ui::ET_MOUSE_RELEASED; |
| 87 case MotionNotify: |
| 88 if (native_event->xmotion.state & |
| 89 (Button1Mask | Button2Mask | Button3Mask)) |
| 90 return ui::ET_MOUSE_DRAGGED; |
| 91 return ui::ET_MOUSE_MOVED; |
| 92 case GenericEvent: { |
| 93 XIDeviceEvent* xievent = |
| 94 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 95 // TODO(sad): Determine if sourceid is a touch device. |
| 96 switch (xievent->evtype) { |
| 97 case XI_ButtonPress: |
| 98 return (xievent->detail == 4 || xievent->detail == 5) ? |
| 99 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_PRESSED; |
| 100 case XI_ButtonRelease: |
| 101 return (xievent->detail == 4 || xievent->detail == 5) ? |
| 102 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_RELEASED; |
| 103 case XI_Motion: |
| 104 return GetButtonMaskForX2Event(xievent) ? ui::ET_MOUSE_DRAGGED : |
| 105 ui::ET_MOUSE_MOVED; |
| 106 } |
| 107 } |
| 108 default: |
| 109 NOTREACHED(); |
| 110 break; |
| 111 } |
| 112 return ui::ET_UNKNOWN; |
| 113 } |
| 114 |
| 115 gfx::Point GetEventLocation(XEvent* xev) { |
| 116 switch (xev->type) { |
| 117 case ButtonPress: |
| 118 case ButtonRelease: |
| 119 return gfx::Point(xev->xbutton.x, xev->xbutton.y); |
| 120 |
| 121 case MotionNotify: |
| 122 return gfx::Point(xev->xmotion.x, xev->xmotion.y); |
| 123 |
| 124 case GenericEvent: { |
| 125 XIDeviceEvent* xievent = |
| 126 static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 127 return gfx::Point(static_cast<int>(xievent->event_x), |
| 128 static_cast<int>(xievent->event_y)); |
| 129 } |
| 130 } |
| 131 |
| 132 return gfx::Point(); |
| 133 } |
| 134 |
| 135 int GetLocatedEventFlags(XEvent* xev) { |
| 136 switch (xev->type) { |
| 137 case ButtonPress: |
| 138 case ButtonRelease: |
| 139 return GetEventFlagsFromXState(xev->xbutton.state) | |
| 140 GetEventFlagsForButton(xev->xbutton.button); |
| 141 |
| 142 case MotionNotify: |
| 143 return GetEventFlagsFromXState(xev->xmotion.state); |
| 144 |
| 145 case GenericEvent: { |
| 146 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 147 bool touch = false; // TODO(sad): Determine if xievent->sourceid is a |
| 148 // touch device. |
| 149 switch (xievent->evtype) { |
| 150 case XI_ButtonPress: |
| 151 case XI_ButtonRelease: |
| 152 return GetButtonMaskForX2Event(xievent) | |
| 153 GetEventFlagsFromXState(xievent->mods.effective) | |
| 154 (touch ? 0 : GetEventFlagsForButton(xievent->detail)); |
| 155 |
| 156 case XI_Motion: |
| 157 return GetButtonMaskForX2Event(xievent) | |
| 158 GetEventFlagsFromXState(xievent->mods.effective); |
| 159 } |
| 160 } |
| 161 } |
| 162 |
| 163 return 0; |
| 164 } |
| 165 |
| 166 } // namespace |
| 167 |
| 168 void Event::Init() { |
| 169 memset(&native_event_, 0, sizeof(native_event_)); |
| 170 } |
| 171 |
| 172 void Event::InitWithNativeEvent(NativeEvent native_event) { |
| 173 native_event_ = native_event; |
| 174 } |
| 175 |
| 176 LocatedEvent::LocatedEvent(NativeEvent native_event) |
| 177 : Event(native_event, EventTypeFromNative(native_event), |
| 178 GetLocatedEventFlags(native_event)), |
| 179 location_(GetEventLocation(native_event)) { |
| 180 } |
| 181 |
| 182 MouseEvent::MouseEvent(NativeEvent native_event) |
| 183 : LocatedEvent(native_event) { |
| 184 } |
| 185 |
| 186 KeyEvent::KeyEvent(NativeEvent native_event) |
| 187 : Event(native_event, |
| 188 EventTypeFromNative(native_event), |
| 189 GetEventFlagsFromXState(native_event->xbutton.state)), |
| 190 key_code_(ui::KeyboardCodeFromXKeyEvent(native_event)) { |
| 191 } |
| 192 |
| 193 } // namespace aura |
OLD | NEW |