| 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 |