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 "ui/base/events.h" |
| 6 |
| 7 #include <X11/extensions/XInput2.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
| 11 #include "ui/base/touchui/touch_factory.h" |
| 12 #include "ui/gfx/point.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. |
| 17 static int kWheelScrollAmount = 53; |
| 18 |
| 19 int GetEventFlagsFromXState(unsigned int state) { |
| 20 int flags = 0; |
| 21 if (state & ControlMask) |
| 22 flags |= ui::EF_CONTROL_DOWN; |
| 23 if (state & ShiftMask) |
| 24 flags |= ui::EF_SHIFT_DOWN; |
| 25 if (state & Mod1Mask) |
| 26 flags |= ui::EF_ALT_DOWN; |
| 27 if (state & LockMask) |
| 28 flags |= ui::EF_CAPS_LOCK_DOWN; |
| 29 if (state & Button1Mask) |
| 30 flags |= ui::EF_LEFT_BUTTON_DOWN; |
| 31 if (state & Button2Mask) |
| 32 flags |= ui::EF_MIDDLE_BUTTON_DOWN; |
| 33 if (state & Button3Mask) |
| 34 flags |= ui::EF_RIGHT_BUTTON_DOWN; |
| 35 return flags; |
| 36 } |
| 37 |
| 38 // Get the event flag for the button in XButtonEvent. During a ButtonPress |
| 39 // event, |state| in XButtonEvent does not include the button that has just been |
| 40 // pressed. Instead |state| contains flags for the buttons (if any) that had |
| 41 // already been pressed before the current button, and |button| stores the most |
| 42 // current pressed button. So, if you press down left mouse button, and while |
| 43 // pressing it down, press down the right mouse button, then for the latter |
| 44 // event, |state| would have Button1Mask set but not Button3Mask, and |button| |
| 45 // would be 3. |
| 46 int GetEventFlagsForButton(int button) { |
| 47 switch (button) { |
| 48 case 1: |
| 49 return ui::EF_LEFT_BUTTON_DOWN; |
| 50 case 2: |
| 51 return ui::EF_MIDDLE_BUTTON_DOWN; |
| 52 case 3: |
| 53 return ui::EF_RIGHT_BUTTON_DOWN; |
| 54 } |
| 55 DLOG(WARNING) << "Unexpected button (" << button << ") received."; |
| 56 return 0; |
| 57 } |
| 58 |
| 59 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { |
| 60 int buttonflags = 0; |
| 61 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { |
| 62 if (XIMaskIsSet(xievent->buttons.mask, i)) { |
| 63 buttonflags |= GetEventFlagsForButton(i); |
| 64 } |
| 65 } |
| 66 return buttonflags; |
| 67 } |
| 68 |
| 69 ui::EventType GetTouchEventType(const ui::NativeEvent2& native_event) { |
| 70 XGenericEventCookie* cookie = &native_event->xcookie; |
| 71 DCHECK_EQ(cookie->evtype, XI_Motion); |
| 72 |
| 73 // Note: We will not generate a _STATIONARY event here. It will be created, |
| 74 // when necessary, by a RWHVV. |
| 75 // TODO(sad): When should _CANCELLED be generated? |
| 76 |
| 77 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
| 78 float slot; |
| 79 if (!factory->ExtractTouchParam(*native_event, ui::TouchFactory::TP_SLOT_ID, |
| 80 &slot)) |
| 81 return ui::ET_UNKNOWN; |
| 82 |
| 83 if (!factory->IsSlotUsed(slot)) { |
| 84 // This is a new touch point. |
| 85 return ui::ET_TOUCH_PRESSED; |
| 86 } |
| 87 |
| 88 float tracking; |
| 89 if (!factory->ExtractTouchParam(*native_event, |
| 90 ui::TouchFactory::TP_TRACKING_ID, &tracking)) |
| 91 return ui::ET_UNKNOWN; |
| 92 |
| 93 if (tracking == 0l) { |
| 94 // The touch point has been released. |
| 95 return ui::ET_TOUCH_RELEASED; |
| 96 } |
| 97 |
| 98 return ui::ET_TOUCH_MOVED; |
| 99 } |
| 100 |
| 101 } // namespace |
| 102 |
| 103 namespace ui { |
| 104 |
| 105 EventType EventTypeFromNative(const NativeEvent2& native_event) { |
| 106 switch (native_event->type) { |
| 107 case KeyPress: |
| 108 return ET_KEY_PRESSED; |
| 109 case KeyRelease: |
| 110 return ET_KEY_RELEASED; |
| 111 case ButtonPress: |
| 112 if (native_event->xbutton.button == 4 || |
| 113 native_event->xbutton.button == 5) |
| 114 return ET_MOUSEWHEEL; |
| 115 return ET_MOUSE_PRESSED; |
| 116 case ButtonRelease: |
| 117 if (native_event->xbutton.button == 4 || |
| 118 native_event->xbutton.button == 5) |
| 119 return ET_MOUSEWHEEL; |
| 120 return ET_MOUSE_RELEASED; |
| 121 case MotionNotify: |
| 122 if (native_event->xmotion.state & |
| 123 (Button1Mask | Button2Mask | Button3Mask)) |
| 124 return ET_MOUSE_DRAGGED; |
| 125 return ET_MOUSE_MOVED; |
| 126 case GenericEvent: { |
| 127 XIDeviceEvent* xievent = |
| 128 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 129 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) |
| 130 return GetTouchEventType(native_event); |
| 131 switch (xievent->evtype) { |
| 132 case XI_ButtonPress: |
| 133 return (xievent->detail == 4 || xievent->detail == 5) ? |
| 134 ET_MOUSEWHEEL : ET_MOUSE_PRESSED; |
| 135 case XI_ButtonRelease: |
| 136 return (xievent->detail == 4 || xievent->detail == 5) ? |
| 137 ET_MOUSEWHEEL : ET_MOUSE_RELEASED; |
| 138 case XI_Motion: |
| 139 return GetButtonMaskForX2Event(xievent) ? |
| 140 ET_MOUSE_DRAGGED : ET_MOUSE_MOVED; |
| 141 } |
| 142 } |
| 143 default: |
| 144 NOTREACHED(); |
| 145 break; |
| 146 } |
| 147 return ET_UNKNOWN; |
| 148 } |
| 149 |
| 150 int EventFlagsFromNative(const NativeEvent2& native_event) { |
| 151 switch (native_event->type) { |
| 152 case KeyPress: |
| 153 case KeyRelease: |
| 154 return GetEventFlagsFromXState(native_event->xbutton.state); |
| 155 case ButtonPress: |
| 156 case ButtonRelease: |
| 157 return GetEventFlagsFromXState(native_event->xbutton.state) | |
| 158 GetEventFlagsForButton(native_event->xbutton.button); |
| 159 case MotionNotify: |
| 160 return GetEventFlagsFromXState(native_event->xmotion.state); |
| 161 case GenericEvent: { |
| 162 XIDeviceEvent* xievent = |
| 163 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 164 bool touch = |
| 165 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); |
| 166 switch (xievent->evtype) { |
| 167 case XI_ButtonPress: |
| 168 case XI_ButtonRelease: |
| 169 return GetButtonMaskForX2Event(xievent) | |
| 170 GetEventFlagsFromXState(xievent->mods.effective) | |
| 171 (touch ? 0 : GetEventFlagsForButton(xievent->detail)); |
| 172 case XI_Motion: |
| 173 return GetButtonMaskForX2Event(xievent) | |
| 174 GetEventFlagsFromXState(xievent->mods.effective); |
| 175 } |
| 176 } |
| 177 } |
| 178 return 0; |
| 179 } |
| 180 |
| 181 gfx::Point EventLocationFromNative(const NativeEvent2& native_event) { |
| 182 switch (native_event->type) { |
| 183 case ButtonPress: |
| 184 case ButtonRelease: |
| 185 return gfx::Point(native_event->xbutton.x, native_event->xbutton.y); |
| 186 case MotionNotify: |
| 187 return gfx::Point(native_event->xmotion.x, native_event->xmotion.y); |
| 188 case GenericEvent: { |
| 189 XIDeviceEvent* xievent = |
| 190 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 191 return gfx::Point(static_cast<int>(xievent->event_x), |
| 192 static_cast<int>(xievent->event_y)); |
| 193 } |
| 194 } |
| 195 return gfx::Point(); |
| 196 } |
| 197 |
| 198 KeyboardCode KeyboardCodeFromNative(const NativeEvent2& native_event) { |
| 199 return KeyboardCodeFromXKeyEvent(native_event); |
| 200 } |
| 201 |
| 202 bool IsMouseEvent(const NativeEvent2& native_event) { |
| 203 if (native_event->type == ButtonPress || |
| 204 native_event->type == ButtonRelease || |
| 205 native_event->type == MotionNotify) |
| 206 return true; |
| 207 if (native_event->type == GenericEvent) { |
| 208 XIDeviceEvent* xievent = |
| 209 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 210 return xievent->evtype == XI_ButtonPress || |
| 211 xievent->evtype == XI_ButtonRelease || |
| 212 xievent->evtype == XI_Motion; |
| 213 } |
| 214 return false; |
| 215 } |
| 216 |
| 217 int GetMouseWheelOffset(const NativeEvent2& native_event) { |
| 218 if (native_event->type == GenericEvent) { |
| 219 XIDeviceEvent* xiev = |
| 220 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 221 return xiev->detail == 4 ? kWheelScrollAmount : -kWheelScrollAmount; |
| 222 } |
| 223 return native_event->xbutton.button == 4 ? |
| 224 kWheelScrollAmount : -kWheelScrollAmount; |
| 225 } |
| 226 |
| 227 } // namespace ui |
OLD | NEW |