#include "ui/events/event_constants.h"
+#include <cmath>
#include <string.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/XKBlib.h>
#include "base/logging.h"
#include "base/memory/singleton.h"
-#include "base/message_loop/message_pump_x11.h"
+#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
-#include "ui/events/x/device_data_manager.h"
+#include "ui/events/x/device_data_manager_x11.h"
#include "ui/events/x/device_list_cache_x.h"
#include "ui/events/x/touch_factory_x11.h"
#include "ui/gfx/display.h"
return Singleton<XModifierStateWatcher>::get();
}
- void UpdateStateFromEvent(const base::NativeEvent& native_event) {
+ int StateFromKeyboardCode(ui::KeyboardCode keyboard_code) {
+ switch (keyboard_code) {
+ case ui::VKEY_CONTROL:
+ return ControlMask;
+ case ui::VKEY_SHIFT:
+ return ShiftMask;
+ case ui::VKEY_MENU:
+ return Mod1Mask;
+ case ui::VKEY_CAPITAL:
+ return LockMask;
+ default:
+ return 0;
+ }
+ }
+
+ void UpdateStateFromXEvent(const base::NativeEvent& native_event) {
+ ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event);
+ unsigned int mask = StateFromKeyboardCode(keyboard_code);
// Floating device can't access the modifer state from master device.
// We need to track the states of modifier keys in a singleton for
// floating devices such as touch screen. Issue 106426 is one example
// of why we need the modifier states for floating device.
- state_ = native_event->xkey.state;
- // master_state is the state before key press. We need to track the
- // state after key press for floating device. Currently only ctrl,
- // shift, alt and caps lock keys are tracked.
- ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event);
- unsigned int mask = 0;
-
- switch (keyboard_code) {
- case ui::VKEY_CONTROL: {
- mask = ControlMask;
+ switch (native_event->type) {
+ case KeyPress:
+ state_ = native_event->xkey.state | mask;
break;
- }
- case ui::VKEY_SHIFT: {
- mask = ShiftMask;
- break;
- }
- case ui::VKEY_MENU: {
- mask = Mod1Mask;
+ case KeyRelease:
+ state_ = native_event->xkey.state & ~mask;
break;
- }
- case ui::VKEY_CAPITAL: {
- mask = LockMask;
+ case GenericEvent: {
+ XIDeviceEvent* xievent =
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data);
+ switch (xievent->evtype) {
+ case XI_KeyPress:
+ state_ = xievent->mods.effective |= mask;
+ break;
+ case XI_KeyRelease:
+ state_ = xievent->mods.effective &= ~mask;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
break;
}
default:
+ NOTREACHED();
break;
}
-
- if (native_event->type == KeyPress)
- state_ |= mask;
- else
- state_ &= ~mask;
}
// Returns the current modifer state in master device. It only contains the
double radius = ui::GetTouchRadiusX(native_event), min, max;
unsigned int deviceid =
static_cast<XIDeviceEvent*>(native_event->xcookie.data)->sourceid;
- if (!ui::DeviceDataManager::GetInstance()->GetDataRange(
- deviceid, ui::DeviceDataManager::DT_TOUCH_MAJOR, &min, &max)) {
+ if (!ui::DeviceDataManagerX11::GetInstance()->GetDataRange(
+ deviceid, ui::DeviceDataManagerX11::DT_TOUCH_MAJOR, &min, &max)) {
return false;
}
flags |= ui::EF_ALT_DOWN;
if (state & LockMask)
flags |= ui::EF_CAPS_LOCK_DOWN;
+ if (state & Mod3Mask)
+ flags |= ui::EF_MOD3_DOWN;
+ if (state & Mod4Mask)
+ flags |= ui::EF_COMMAND_DOWN;
if (state & Mod5Mask)
flags |= ui::EF_ALTGR_DOWN;
if (state & Button1Mask)
return flags;
}
+int GetEventFlagsFromXKeyEvent(XEvent* xevent) {
+ DCHECK(xevent->type == KeyPress || xevent->type == KeyRelease);
+
+#if defined(OS_CHROMEOS)
+ const int ime_fabricated_flag = 0;
+#else
+ // XIM fabricates key events for the character compositions by XK_Multi_key.
+ // For example, when a user hits XK_Multi_key, XK_apostrophe, and XK_e in
+ // order to input "é", then XIM generates a key event with keycode=0 and
+ // state=0 for the composition, and the sequence of X11 key events will be
+ // XK_Multi_key, XK_apostrophe, **NoSymbol**, and XK_e. If the user used
+ // shift key and/or caps lock key, state can be ShiftMask, LockMask or both.
+ //
+ // We have to send these fabricated key events to XIM so it can correctly
+ // handle the character compositions.
+ const unsigned int shift_lock_mask = ShiftMask | LockMask;
+ const bool fabricated_by_xim =
+ xevent->xkey.keycode == 0 &&
+ (xevent->xkey.state & ~shift_lock_mask) == 0;
+ const int ime_fabricated_flag =
+ fabricated_by_xim ? ui::EF_IME_FABRICATED_KEY : 0;
+#endif
+
+ return GetEventFlagsFromXState(xevent->xkey.state) |
+ (xevent->xkey.send_event ? ui::EF_FINAL : 0) |
+ (IsKeypadKey(XLookupKeysym(&xevent->xkey, 0)) ? ui::EF_NUMPAD_KEY : 0) |
+ (IsFunctionKey(XLookupKeysym(&xevent->xkey, 0)) ?
+ ui::EF_FUNCTION_KEY : 0) |
+ ime_fabricated_flag;
+}
+
+int GetEventFlagsFromXGenericEvent(XEvent* xevent) {
+ DCHECK(xevent->type == GenericEvent);
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
+ DCHECK((xievent->evtype == XI_KeyPress) ||
+ (xievent->evtype == XI_KeyRelease));
+ return GetEventFlagsFromXState(xievent->mods.effective) |
+ (xevent->xkey.send_event ? ui::EF_FINAL : 0) |
+ (IsKeypadKey(
+ XkbKeycodeToKeysym(xievent->display, xievent->detail, 0, 0))
+ ? ui::EF_NUMPAD_KEY
+ : 0);
+}
+
// Get the event flag for the button in XButtonEvent. During a ButtonPress
// event, |state| in XButtonEvent does not include the button that has just been
// pressed. Instead |state| contains flags for the buttons (if any) that had
for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) {
if (XIMaskIsSet(xievent->buttons.mask, i)) {
int button = (xievent->sourceid == xievent->deviceid) ?
- ui::DeviceDataManager::GetInstance()->GetMappedButton(i) : i;
+ ui::DeviceDataManagerX11::GetInstance()->GetMappedButton(i) : i;
buttonflags |= GetEventFlagsForButton(button);
}
}
return TouchEventIsGeneratedHack(native_event) ? ui::ET_TOUCH_CANCELLED :
ui::ET_TOUCH_RELEASED;
}
+#endif // defined(USE_XI2_MT)
- return ui::ET_UNKNOWN;
-#else
- ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
-
- // If this device doesn't support multi-touch, then just use the normal
- // pressed/release events to indicate touch start/end. With multi-touch,
- // these events are sent only for the first (pressed) or last (released)
- // touch point, and so we must infer start/end from motion events.
- if (!factory->IsMultiTouchDevice(event->sourceid)) {
- switch (event->evtype) {
- case XI_ButtonPress:
- return ui::ET_TOUCH_PRESSED;
- case XI_ButtonRelease:
- return ui::ET_TOUCH_RELEASED;
- case XI_Motion:
- if (GetButtonMaskForX2Event(event))
- return ui::ET_TOUCH_MOVED;
- return ui::ET_UNKNOWN;
- default:
- NOTREACHED();
- }
- }
-
- DCHECK_EQ(event->evtype, XI_Motion);
-
- // Note: We will not generate a _STATIONARY event here. It will be created,
- // when necessary, by a RWHVV.
- // TODO(sad): When should _CANCELLED be generated?
-
- ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
-
- double slot;
- if (!manager->GetEventData(
- *native_event, ui::DeviceDataManager::DT_TOUCH_SLOT_ID, &slot))
- return ui::ET_UNKNOWN;
-
- if (!factory->IsSlotUsed(slot)) {
- // This is a new touch point.
- return ui::ET_TOUCH_PRESSED;
- }
-
- double tracking;
- if (!manager->GetEventData(
- *native_event, ui::DeviceDataManager::DT_TOUCH_TRACKING_ID, &tracking))
- return ui::ET_UNKNOWN;
-
- if (tracking == 0l) {
- // The touch point has been released.
- return ui::ET_TOUCH_RELEASED;
+ DCHECK(ui::TouchFactory::GetInstance()->IsTouchDevice(event->sourceid));
+ switch (event->evtype) {
+ case XI_ButtonPress:
+ return ui::ET_TOUCH_PRESSED;
+ case XI_ButtonRelease:
+ return ui::ET_TOUCH_RELEASED;
+ case XI_Motion:
+ // Should not convert any emulated Motion event from touch device to
+ // touch event.
+ if (!(event->flags & XIPointerEmulated) &&
+ GetButtonMaskForX2Event(event))
+ return ui::ET_TOUCH_MOVED;
+ return ui::ET_UNKNOWN;
+ default:
+ NOTREACHED();
}
-
- return ui::ET_TOUCH_MOVED;
-#endif // defined(USE_XI2_MT)
+ return ui::ET_UNKNOWN;
}
double GetTouchParamFromXEvent(XEvent* xev,
- ui::DeviceDataManager::DataType val,
+ ui::DeviceDataManagerX11::DataType val,
double default_value) {
- ui::DeviceDataManager::GetInstance()->GetEventData(
+ ui::DeviceDataManagerX11::GetInstance()->GetEventData(
*xev, val, &default_value);
return default_value;
}
-Atom GetNoopEventAtom() {
- return XInternAtom(gfx::GetXDisplay(), "noop", False);
+void ScaleTouchRadius(XEvent* xev, double* radius) {
+ DCHECK_EQ(GenericEvent, xev->type);
+ XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ ui::DeviceDataManagerX11::GetInstance()->ApplyTouchRadiusScale(
+ xiev->sourceid, radius);
+}
+
+unsigned int UpdateX11EventFlags(int ui_flags, unsigned int old_x_flags) {
+ static struct {
+ int ui;
+ int x;
+ } flags[] = {
+ {ui::EF_CONTROL_DOWN, ControlMask},
+ {ui::EF_SHIFT_DOWN, ShiftMask},
+ {ui::EF_ALT_DOWN, Mod1Mask},
+ {ui::EF_CAPS_LOCK_DOWN, LockMask},
+ {ui::EF_ALTGR_DOWN, Mod5Mask},
+ {ui::EF_COMMAND_DOWN, Mod4Mask},
+ {ui::EF_MOD3_DOWN, Mod3Mask},
+ {ui::EF_NUMPAD_KEY, Mod2Mask},
+ {ui::EF_LEFT_MOUSE_BUTTON, Button1Mask},
+ {ui::EF_MIDDLE_MOUSE_BUTTON, Button2Mask},
+ {ui::EF_RIGHT_MOUSE_BUTTON, Button3Mask},
+ };
+ unsigned int new_x_flags = old_x_flags;
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flags); ++i) {
+ if (ui_flags & flags[i].ui)
+ new_x_flags |= flags[i].x;
+ else
+ new_x_flags &= ~flags[i].x;
+ }
+ return new_x_flags;
+}
+
+unsigned int UpdateX11EventButton(int ui_flag, unsigned int old_x_button) {
+ switch (ui_flag) {
+ case ui::EF_LEFT_MOUSE_BUTTON:
+ return Button1;
+ case ui::EF_MIDDLE_MOUSE_BUTTON:
+ return Button2;
+ case ui::EF_RIGHT_MOUSE_BUTTON:
+ return Button3;
+ default:
+ return old_x_button;
+ }
+ NOTREACHED();
+}
+
+bool GetGestureTimes(const base::NativeEvent& native_event,
+ double* start_time,
+ double* end_time) {
+ if (!ui::DeviceDataManagerX11::GetInstance()->HasGestureTimes(native_event))
+ return false;
+
+ double start_time_, end_time_;
+ if (!start_time)
+ start_time = &start_time_;
+ if (!end_time)
+ end_time = &end_time_;
+
+ ui::DeviceDataManagerX11::GetInstance()->GetGestureTimes(
+ native_event, start_time, end_time);
+ return true;
}
} // namespace
XDisplay* display = gfx::GetXDisplay();
DeviceListCacheX::GetInstance()->UpdateDeviceList(display);
TouchFactory::GetInstance()->UpdateDeviceList(display);
- DeviceDataManager::GetInstance()->UpdateDeviceList(display);
+ DeviceDataManagerX11::GetInstance()->UpdateDeviceList(display);
}
EventType EventTypeFromNative(const base::NativeEvent& native_event) {
+ // Allow the DeviceDataManager to block the event. If blocked return
+ // ET_UNKNOWN as the type so this event will not be further processed.
+ // NOTE: During some events unittests there is no device data manager.
+ if (DeviceDataManager::HasInstance() &&
+ static_cast<DeviceDataManagerX11*>(DeviceDataManager::GetInstance())->
+ IsEventBlocked(native_event)) {
+ return ET_UNKNOWN;
+ }
+
switch (native_event->type) {
case KeyPress:
return ET_KEY_PRESSED;
XIDeviceEvent* xievent =
static_cast<XIDeviceEvent*>(native_event->xcookie.data);
+ // This check works only for master and floating slave devices. That is
+ // why it is necessary to check for the XI_Touch* events in the following
+ // switch statement to account for attached-slave touchscreens.
if (factory->IsTouchDevice(xievent->sourceid))
return GetTouchEventType(native_event);
switch (xievent->evtype) {
+ case XI_TouchBegin:
+ return ui::ET_TOUCH_PRESSED;
+ case XI_TouchUpdate:
+ return ui::ET_TOUCH_MOVED;
+ case XI_TouchEnd:
+ return ui::ET_TOUCH_RELEASED;
case XI_ButtonPress: {
int button = EventButtonFromNative(native_event);
if (button >= kMinWheelButton && button <= kMaxWheelButton)
}
case XI_Motion: {
bool is_cancel;
- if (GetFlingData(native_event, NULL, NULL, NULL, NULL, &is_cancel)) {
+ DeviceDataManagerX11* devices = DeviceDataManagerX11::GetInstance();
+ if (GetFlingData(native_event, NULL, NULL, NULL, NULL, &is_cancel))
return is_cancel ? ET_SCROLL_FLING_CANCEL : ET_SCROLL_FLING_START;
- } else if (DeviceDataManager::GetInstance()->IsScrollEvent(
- native_event)) {
- return IsTouchpadEvent(native_event) ? ET_SCROLL : ET_MOUSEWHEEL;
- } else if (DeviceDataManager::GetInstance()->IsCMTMetricsEvent(
- native_event)) {
+ if (devices->IsScrollEvent(native_event)) {
+ return devices->IsTouchpadXInputEvent(native_event) ? ET_SCROLL
+ : ET_MOUSEWHEEL;
+ }
+ if (devices->IsCMTMetricsEvent(native_event))
return ET_UMA_DATA;
- } else if (GetButtonMaskForX2Event(xievent)) {
+ if (GetButtonMaskForX2Event(xievent))
return ET_MOUSE_DRAGGED;
- } else {
- return ET_MOUSE_MOVED;
- }
+ return ET_MOUSE_MOVED;
}
+ case XI_KeyPress:
+ return ET_KEY_PRESSED;
+ case XI_KeyRelease:
+ return ET_KEY_RELEASED;
}
}
default:
switch (native_event->type) {
case KeyPress:
case KeyRelease: {
- XModifierStateWatcher::GetInstance()->UpdateStateFromEvent(native_event);
- return GetEventFlagsFromXState(native_event->xkey.state);
+ XModifierStateWatcher::GetInstance()->UpdateStateFromXEvent(native_event);
+ return GetEventFlagsFromXKeyEvent(native_event);
}
case ButtonPress:
case ButtonRelease: {
flags |= GetEventFlagsForButton(native_event->xbutton.button);
return flags;
}
+ case EnterNotify:
+ case LeaveNotify:
+ return GetEventFlagsFromXState(native_event->xcrossing.state);
case MotionNotify:
return GetEventFlagsFromXState(native_event->xmotion.state);
case GenericEvent: {
const bool touch =
TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid);
int flags = GetButtonMaskForX2Event(xievent) |
- GetEventFlagsFromXState(xievent->mods.effective);
+ GetEventFlagsFromXState(xievent->mods.effective);
if (touch) {
flags |= GetEventFlagsFromXState(
XModifierStateWatcher::GetInstance()->state());
return flags;
}
case XI_Motion:
- return GetButtonMaskForX2Event(xievent) |
- GetEventFlagsFromXState(xievent->mods.effective);
+ return GetButtonMaskForX2Event(xievent) |
+ GetEventFlagsFromXState(xievent->mods.effective);
+ case XI_KeyPress:
+ case XI_KeyRelease: {
+ XModifierStateWatcher::GetInstance()->UpdateStateFromXEvent(
+ native_event);
+ return GetEventFlagsFromXGenericEvent(native_event);
+ }
}
}
}
if (GetGestureTimes(native_event, &start, &end)) {
// If the driver supports gesture times, use them.
return base::TimeDelta::FromMicroseconds(end * 1000000);
- } else if (DeviceDataManager::GetInstance()->GetEventData(*native_event,
- DeviceDataManager::DT_TOUCH_RAW_TIMESTAMP, &touch_timestamp)) {
+ } else if (DeviceDataManagerX11::GetInstance()->GetEventData(
+ *native_event,
+ DeviceDataManagerX11::DT_TOUCH_RAW_TIMESTAMP,
+ &touch_timestamp)) {
return base::TimeDelta::FromMicroseconds(touch_timestamp * 1000000);
} else {
XIDeviceEvent* xide =
case GenericEvent: {
XIDeviceEvent* xievent =
static_cast<XIDeviceEvent*>(native_event->xcookie.data);
- return gfx::Point(static_cast<int>(xievent->event_x),
- static_cast<int>(xievent->event_y));
+ float x = xievent->event_x;
+ float y = xievent->event_y;
+#if defined(OS_CHROMEOS)
+ switch (xievent->evtype) {
+ case XI_TouchBegin:
+ case XI_TouchUpdate:
+ case XI_TouchEnd:
+ ui::DeviceDataManagerX11::GetInstance()->ApplyTouchTransformer(
+ xievent->deviceid, &x, &y);
+ break;
+ default:
+ break;
+ }
+#endif // defined(OS_CHROMEOS)
+ return gfx::Point(static_cast<int>(x), static_cast<int>(y));
}
}
return gfx::Point();
int button = xievent->detail;
return (xievent->sourceid == xievent->deviceid) ?
- DeviceDataManager::GetInstance()->GetMappedButton(button) : button;
+ DeviceDataManagerX11::GetInstance()->GetMappedButton(button) : button;
}
KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) {
return KeyboardCodeFromXKeyEvent(native_event);
}
-bool IsMouseEvent(const base::NativeEvent& native_event) {
- if (native_event->type == EnterNotify ||
- native_event->type == LeaveNotify ||
- native_event->type == ButtonPress ||
- native_event->type == ButtonRelease ||
- native_event->type == MotionNotify)
- return true;
- if (native_event->type == GenericEvent) {
- XIDeviceEvent* xievent =
- static_cast<XIDeviceEvent*>(native_event->xcookie.data);
- return xievent->evtype == XI_ButtonPress ||
- xievent->evtype == XI_ButtonRelease ||
- xievent->evtype == XI_Motion;
+const char* CodeFromNative(const base::NativeEvent& native_event) {
+ return CodeFromXEvent(native_event);
+}
+
+uint32 PlatformKeycodeFromNative(const base::NativeEvent& native_event) {
+ XKeyEvent* xkey = NULL;
+ XEvent xkey_from_xi2;
+ switch (native_event->type) {
+ case KeyPress:
+ case KeyRelease:
+ xkey = &native_event->xkey;
+ break;
+ case GenericEvent: {
+ XIDeviceEvent* xievent =
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data);
+ switch (xievent->evtype) {
+ case XI_KeyPress:
+ case XI_KeyRelease:
+ // Build an XKeyEvent corresponding to the XI2 event,
+ // so that we can call XLookupString on it.
+ InitXKeyEventFromXIDeviceEvent(*native_event, &xkey_from_xi2);
+ xkey = &xkey_from_xi2.xkey;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
}
+ KeySym keysym = XK_VoidSymbol;
+ if (xkey)
+ XLookupString(xkey, NULL, 0, &keysym, NULL);
+ return keysym;
+}
+
+bool IsCharFromNative(const base::NativeEvent& native_event) {
return false;
}
return gfx::Vector2d(0, kWheelScrollAmount);
case 5:
return gfx::Vector2d(0, -kWheelScrollAmount);
+ case 6:
+ return gfx::Vector2d(kWheelScrollAmount, 0);
+ case 7:
+ return gfx::Vector2d(-kWheelScrollAmount, 0);
default:
- // TODO(derat): Do something for horizontal scrolls (buttons 6 and 7)?
return gfx::Vector2d();
}
}
+base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
+ if (!event || event->type == GenericEvent)
+ return NULL;
+ XEvent* copy = new XEvent;
+ *copy = *event;
+ return copy;
+}
+
+void ReleaseCopiedNativeEvent(const base::NativeEvent& event) {
+ delete event;
+}
+
+void IncrementTouchIdRefCount(const base::NativeEvent& xev) {
+ ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
+ double tracking_id;
+ if (!manager->GetEventData(
+ *xev, ui::DeviceDataManagerX11::DT_TOUCH_TRACKING_ID, &tracking_id)) {
+ return;
+ }
+
+ ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
+ factory->AcquireSlotForTrackingID(tracking_id);
+}
+
void ClearTouchIdIfReleased(const base::NativeEvent& xev) {
-#if defined(USE_XI2_MT)
ui::EventType type = ui::EventTypeFromNative(xev);
if (type == ui::ET_TOUCH_CANCELLED ||
type == ui::ET_TOUCH_RELEASED) {
ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
- ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
+ ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
double tracking_id;
if (manager->GetEventData(
- *xev, ui::DeviceDataManager::DT_TOUCH_TRACKING_ID, &tracking_id)) {
+ *xev, ui::DeviceDataManagerX11::DT_TOUCH_TRACKING_ID, &tracking_id)) {
factory->ReleaseSlotForTrackingID(tracking_id);
}
}
-#endif
}
int GetTouchId(const base::NativeEvent& xev) {
double slot = 0;
- ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
- XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
-#if defined(ENABLE_XI21_MT)
- // If using XInput2.1 for multi-touch support, the slot is tracked by the
- // source id of each device event.
- slot = xievent->sourceid;
-#endif
- if (!factory->IsMultiTouchDevice(xievent->sourceid)) {
- // TODO(sad): Come up with a way to generate touch-ids for multi-touch
- // events when touch-events are generated from a single-touch device.
- return slot;
- }
-
- ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
-
-#if defined(USE_XI2_MT)
+ ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
double tracking_id;
if (!manager->GetEventData(
- *xev, ui::DeviceDataManager::DT_TOUCH_TRACKING_ID, &tracking_id)) {
+ *xev, ui::DeviceDataManagerX11::DT_TOUCH_TRACKING_ID, &tracking_id)) {
LOG(ERROR) << "Could not get the tracking ID for the event. Using 0.";
} else {
+ ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
slot = factory->GetSlotForTrackingID(tracking_id);
}
-#else
- if (!manager->GetEventData(
- *xev, ui::DeviceDataManager::DT_TOUCH_SLOT_ID, &slot))
- LOG(ERROR) << "Could not get the slot ID for the event. Using 0.";
-#endif
return slot;
}
float GetTouchRadiusX(const base::NativeEvent& native_event) {
- return GetTouchParamFromXEvent(native_event,
- ui::DeviceDataManager::DT_TOUCH_MAJOR, 0.0) / 2.0;
+ double radius = GetTouchParamFromXEvent(native_event,
+ ui::DeviceDataManagerX11::DT_TOUCH_MAJOR, 0.0) / 2.0;
+ ScaleTouchRadius(native_event, &radius);
+ return radius;
}
float GetTouchRadiusY(const base::NativeEvent& native_event) {
- return GetTouchParamFromXEvent(native_event,
- ui::DeviceDataManager::DT_TOUCH_MINOR, 0.0) / 2.0;
+ double radius = GetTouchParamFromXEvent(native_event,
+ ui::DeviceDataManagerX11::DT_TOUCH_MINOR, 0.0) / 2.0;
+ ScaleTouchRadius(native_event, &radius);
+ return radius;
}
float GetTouchAngle(const base::NativeEvent& native_event) {
return GetTouchParamFromXEvent(native_event,
- ui::DeviceDataManager::DT_TOUCH_ORIENTATION, 0.0) / 2.0;
+ ui::DeviceDataManagerX11::DT_TOUCH_ORIENTATION, 0.0) / 2.0;
}
float GetTouchForce(const base::NativeEvent& native_event) {
double force = 0.0;
force = GetTouchParamFromXEvent(native_event,
- ui::DeviceDataManager::DT_TOUCH_PRESSURE, 0.0);
+ ui::DeviceDataManagerX11::DT_TOUCH_PRESSURE, 0.0);
unsigned int deviceid =
static_cast<XIDeviceEvent*>(native_event->xcookie.data)->sourceid;
// Force is normalized to fall into [0, 1]
- if (!ui::DeviceDataManager::GetInstance()->NormalizeData(
- deviceid, ui::DeviceDataManager::DT_TOUCH_PRESSURE, &force))
+ if (!ui::DeviceDataManagerX11::GetInstance()->NormalizeData(
+ deviceid, ui::DeviceDataManagerX11::DT_TOUCH_PRESSURE, &force))
force = 0.0;
return force;
}
float* x_offset_ordinal,
float* y_offset_ordinal,
int* finger_count) {
- if (!DeviceDataManager::GetInstance()->IsScrollEvent(native_event))
+ if (!DeviceDataManagerX11::GetInstance()->IsScrollEvent(native_event))
return false;
// Temp values to prevent passing NULLs to DeviceDataManager.
if (!finger_count)
finger_count = &finger_count_;
- DeviceDataManager::GetInstance()->GetScrollOffsets(
+ DeviceDataManagerX11::GetInstance()->GetScrollOffsets(
native_event,
x_offset, y_offset,
x_offset_ordinal, y_offset_ordinal,
float* vx_ordinal,
float* vy_ordinal,
bool* is_cancel) {
- if (!DeviceDataManager::GetInstance()->IsFlingEvent(native_event))
+ if (!DeviceDataManagerX11::GetInstance()->IsFlingEvent(native_event))
return false;
float vx_, vy_;
if (!is_cancel)
is_cancel = &is_cancel_;
- DeviceDataManager::GetInstance()->GetFlingData(
+ DeviceDataManagerX11::GetInstance()->GetFlingData(
native_event, vx, vy, vx_ordinal, vy_ordinal, is_cancel);
return true;
}
-bool GetGestureTimes(const base::NativeEvent& native_event,
- double* start_time,
- double* end_time) {
- if (!DeviceDataManager::GetInstance()->HasGestureTimes(native_event))
- return false;
-
- double start_time_, end_time_;
- if (!start_time)
- start_time = &start_time_;
- if (!end_time)
- end_time = &end_time_;
-
- DeviceDataManager::GetInstance()->GetGestureTimes(
- native_event, start_time, end_time);
- return true;
-}
-
-void SetNaturalScroll(bool enabled) {
- DeviceDataManager::GetInstance()->set_natural_scroll_enabled(enabled);
-}
-
-bool IsNaturalScrollEnabled() {
- return DeviceDataManager::GetInstance()->natural_scroll_enabled();
-}
-
-bool IsTouchpadEvent(const base::NativeEvent& event) {
- return DeviceDataManager::GetInstance()->IsTouchpadXInputEvent(event);
-}
-
-bool IsNoopEvent(const base::NativeEvent& event) {
- return (event->type == ClientMessage &&
- event->xclient.message_type == GetNoopEventAtom());
+void UpdateX11EventForFlags(Event* event) {
+ XEvent* xev = event->native_event();
+ if (!xev)
+ return;
+ switch (xev->type) {
+ case KeyPress:
+ case KeyRelease:
+ xev->xkey.state = UpdateX11EventFlags(event->flags(), xev->xkey.state);
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ xev->xbutton.state =
+ UpdateX11EventFlags(event->flags(), xev->xbutton.state);
+ break;
+ case GenericEvent: {
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ DCHECK(xievent);
+ xievent->mods.effective =
+ UpdateX11EventFlags(event->flags(), xievent->mods.effective);
+ break;
+ }
+ default:
+ break;
+ }
}
-base::NativeEvent CreateNoopEvent() {
- static XEvent* noop = NULL;
- if (!noop) {
- noop = new XEvent();
- memset(noop, 0, sizeof(XEvent));
- noop->xclient.type = ClientMessage;
- noop->xclient.window = None;
- noop->xclient.format = 8;
- DCHECK(!noop->xclient.display);
+void UpdateX11EventForChangedButtonFlags(MouseEvent* event) {
+ XEvent* xev = event->native_event();
+ if (!xev)
+ return;
+ switch (xev->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ xev->xbutton.button = UpdateX11EventButton(event->changed_button_flags(),
+ xev->xbutton.button);
+ break;
+ case GenericEvent: {
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ CHECK(xievent && (xievent->evtype == XI_ButtonPress ||
+ xievent->evtype == XI_ButtonRelease));
+ xievent->detail =
+ UpdateX11EventButton(event->changed_button_flags(), xievent->detail);
+ break;
+ }
+ default:
+ break;
}
- // Make sure we use atom from current xdisplay, which may
- // change during the test.
- noop->xclient.message_type = GetNoopEventAtom();
- return noop;
}
} // namespace ui