summaryrefslogtreecommitdiffstats
path: root/chromium/ui/events/x/events_x.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/events/x/events_x.cc')
-rw-r--r--chromium/ui/events/x/events_x.cc136
1 files changed, 83 insertions, 53 deletions
diff --git a/chromium/ui/events/x/events_x.cc b/chromium/ui/events/x/events_x.cc
index 5e3b9dd5462..bd12bd835db 100644
--- a/chromium/ui/events/x/events_x.cc
+++ b/chromium/ui/events/x/events_x.cc
@@ -9,10 +9,10 @@
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
#include "base/logging.h"
#include "base/memory/singleton.h"
-#include "base/message_loop/message_pump_x11.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
#include "ui/events/x/device_data_manager.h"
@@ -137,6 +137,10 @@ int GetEventFlagsFromXState(unsigned int state) {
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)
@@ -148,6 +152,36 @@ int GetEventFlagsFromXState(unsigned int state) {
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) |
+ (IsKeypadKey(XLookupKeysym(&xevent->xkey, 0)) ? ui::EF_NUMPAD_KEY : 0) |
+ (IsFunctionKey(XLookupKeysym(&xevent->xkey, 0)) ?
+ ui::EF_FUNCTION_KEY : 0) |
+ ime_fabricated_flag;
+}
+
// 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
@@ -225,10 +259,6 @@ double GetTouchParamFromXEvent(XEvent* xev,
return default_value;
}
-Atom GetNoopEventAtom() {
- return XInternAtom(gfx::GetXDisplay(), "noop", False);
-}
-
} // namespace
namespace ui {
@@ -277,10 +307,19 @@ EventType EventTypeFromNative(const base::NativeEvent& native_event) {
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)
@@ -323,7 +362,7 @@ int EventFlagsFromNative(const base::NativeEvent& native_event) {
case KeyPress:
case KeyRelease: {
XModifierStateWatcher::GetInstance()->UpdateStateFromEvent(native_event);
- return GetEventFlagsFromXState(native_event->xkey.state);
+ return GetEventFlagsFromXKeyEvent(native_event);
}
case ButtonPress:
case ButtonRelease: {
@@ -333,6 +372,9 @@ int EventFlagsFromNative(const base::NativeEvent& native_event) {
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: {
@@ -426,8 +468,21 @@ gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
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::DeviceDataManager::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();
@@ -478,21 +533,10 @@ const char* CodeFromNative(const base::NativeEvent& native_event) {
return CodeFromXEvent(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;
- }
- return false;
+uint32 PlatformKeycodeFromNative(const base::NativeEvent& native_event) {
+ KeySym keysym;
+ XLookupString(&native_event->xkey, NULL, 0, &keysym, NULL);
+ return keysym;
}
int GetChangedMouseButtonFlagsFromNative(
@@ -534,12 +578,27 @@ gfx::Vector2d GetMouseWheelOffset(const base::NativeEvent& native_event) {
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 ClearTouchIdIfReleased(const base::NativeEvent& xev) {
ui::EventType type = ui::EventTypeFromNative(xev);
if (type == ui::ET_TOUCH_CANCELLED ||
@@ -673,37 +732,8 @@ bool GetGestureTimes(const base::NativeEvent& native_event,
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());
-}
-
-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);
- }
- // Make sure we use atom from current xdisplay, which may
- // change during the test.
- noop->xclient.message_type = GetNoopEventAtom();
- return noop;
-}
-
} // namespace ui