OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/events/platform/x11/x11_event_source.h" | 5 #include "ui/events/platform/x11/x11_event_source.h" |
6 | 6 |
7 #include <X11/XKBlib.h> | 7 #include <X11/XKBlib.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 // crbug.com/138092 | 33 // crbug.com/138092 |
34 Bool supported_return; | 34 Bool supported_return; |
35 if (!XkbSetDetectableAutoRepeat(display, True, &supported_return)) { | 35 if (!XkbSetDetectableAutoRepeat(display, True, &supported_return)) { |
36 DVLOG(1) << "XKB not supported in the server."; | 36 DVLOG(1) << "XKB not supported in the server."; |
37 return false; | 37 return false; |
38 } | 38 } |
39 | 39 |
40 return true; | 40 return true; |
41 } | 41 } |
42 | 42 |
| 43 Time ExtractTimeFromXEvent(const XEvent& xevent) { |
| 44 switch (xevent.type) { |
| 45 case KeyPress: |
| 46 case KeyRelease: |
| 47 return xevent.xkey.time; |
| 48 case ButtonPress: |
| 49 case ButtonRelease: |
| 50 return xevent.xbutton.time; |
| 51 case MotionNotify: |
| 52 return xevent.xmotion.time; |
| 53 case EnterNotify: |
| 54 case LeaveNotify: |
| 55 return xevent.xcrossing.time; |
| 56 case PropertyNotify: |
| 57 return xevent.xproperty.time; |
| 58 case SelectionClear: |
| 59 return xevent.xselectionclear.time; |
| 60 case SelectionRequest: |
| 61 return xevent.xselectionrequest.time; |
| 62 case SelectionNotify: |
| 63 return xevent.xselection.time; |
| 64 case GenericEvent: |
| 65 if (DeviceDataManagerX11::GetInstance()->IsXIDeviceEvent(xevent)) |
| 66 return static_cast<XIDeviceEvent*>(xevent.xcookie.data)->time; |
| 67 else |
| 68 break; |
| 69 } |
| 70 return CurrentTime; |
| 71 } |
| 72 |
43 } // namespace | 73 } // namespace |
44 | 74 |
45 X11EventSource* X11EventSource::instance_ = nullptr; | 75 X11EventSource* X11EventSource::instance_ = nullptr; |
46 | 76 |
47 X11EventSource::X11EventSource(X11EventSourceDelegate* delegate, | 77 X11EventSource::X11EventSource(X11EventSourceDelegate* delegate, |
48 XDisplay* display) | 78 XDisplay* display) |
49 : delegate_(delegate), display_(display), continue_stream_(true) { | 79 : delegate_(delegate), |
| 80 display_(display), |
| 81 last_seen_server_time_(CurrentTime), |
| 82 continue_stream_(true) { |
50 DCHECK(!instance_); | 83 DCHECK(!instance_); |
51 instance_ = this; | 84 instance_ = this; |
52 | 85 |
53 DCHECK(delegate_); | 86 DCHECK(delegate_); |
54 DCHECK(display_); | 87 DCHECK(display_); |
55 DeviceDataManagerX11::CreateInstance(); | 88 DeviceDataManagerX11::CreateInstance(); |
56 InitializeXkb(display_); | 89 InitializeXkb(display_); |
57 } | 90 } |
58 | 91 |
59 X11EventSource::~X11EventSource() { | 92 X11EventSource::~X11EventSource() { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 | 128 |
96 //////////////////////////////////////////////////////////////////////////////// | 129 //////////////////////////////////////////////////////////////////////////////// |
97 // X11EventSource, protected | 130 // X11EventSource, protected |
98 | 131 |
99 void X11EventSource::ExtractCookieDataDispatchEvent(XEvent* xevent) { | 132 void X11EventSource::ExtractCookieDataDispatchEvent(XEvent* xevent) { |
100 bool have_cookie = false; | 133 bool have_cookie = false; |
101 if (xevent->type == GenericEvent && | 134 if (xevent->type == GenericEvent && |
102 XGetEventData(xevent->xgeneric.display, &xevent->xcookie)) { | 135 XGetEventData(xevent->xgeneric.display, &xevent->xcookie)) { |
103 have_cookie = true; | 136 have_cookie = true; |
104 } | 137 } |
| 138 Time event_time = ExtractTimeFromXEvent(*xevent); |
| 139 if (event_time != CurrentTime) { |
| 140 int64_t event_time_64 = event_time; |
| 141 int64_t time_difference = last_seen_server_time_ - event_time_64; |
| 142 // Ignore timestamps that go backwards. However, X server time is a 32-bit |
| 143 // millisecond counter, so if the time goes backwards by more than half the |
| 144 // range of the 32-bit counter, treat it as a rollover. |
| 145 if (time_difference < 0 || time_difference > (UINT32_MAX >> 1)) |
| 146 last_seen_server_time_ = event_time; |
| 147 } |
105 delegate_->ProcessXEvent(xevent); | 148 delegate_->ProcessXEvent(xevent); |
106 PostDispatchEvent(xevent); | 149 PostDispatchEvent(xevent); |
107 if (have_cookie) | 150 if (have_cookie) |
108 XFreeEventData(xevent->xgeneric.display, &xevent->xcookie); | 151 XFreeEventData(xevent->xgeneric.display, &xevent->xcookie); |
109 } | 152 } |
110 | 153 |
111 void X11EventSource::PostDispatchEvent(XEvent* xevent) { | 154 void X11EventSource::PostDispatchEvent(XEvent* xevent) { |
112 if (xevent->type == GenericEvent && | 155 if (xevent->type == GenericEvent && |
113 (xevent->xgeneric.evtype == XI_HierarchyChanged || | 156 (xevent->xgeneric.evtype == XI_HierarchyChanged || |
114 (xevent->xgeneric.evtype == XI_DeviceChanged && | 157 (xevent->xgeneric.evtype == XI_DeviceChanged && |
(...skipping 17 matching lines...) Expand all Loading... |
132 | 175 |
133 void X11EventSource::OnDispatcherListChanged() { | 176 void X11EventSource::OnDispatcherListChanged() { |
134 if (!hotplug_event_handler_) { | 177 if (!hotplug_event_handler_) { |
135 hotplug_event_handler_.reset(new X11HotplugEventHandler()); | 178 hotplug_event_handler_.reset(new X11HotplugEventHandler()); |
136 // Force the initial device query to have an update list of active devices. | 179 // Force the initial device query to have an update list of active devices. |
137 hotplug_event_handler_->OnHotplugEvent(); | 180 hotplug_event_handler_->OnHotplugEvent(); |
138 } | 181 } |
139 } | 182 } |
140 | 183 |
141 } // namespace ui | 184 } // namespace ui |
OLD | NEW |