OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/aura/window_tree_host_x11.h" | 5 #include "ui/aura/window_tree_host_x11.h" |
6 | 6 |
7 #include <strings.h> | 7 #include <strings.h> |
8 #include <X11/cursorfont.h> | 8 #include <X11/cursorfont.h> |
9 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
10 #include <X11/extensions/Xrandr.h> | 10 #include <X11/extensions/Xrandr.h> |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "ui/base/ui_base_switches.h" | 32 #include "ui/base/ui_base_switches.h" |
33 #include "ui/base/view_prop.h" | 33 #include "ui/base/view_prop.h" |
34 #include "ui/base/x/x11_util.h" | 34 #include "ui/base/x/x11_util.h" |
35 #include "ui/compositor/compositor.h" | 35 #include "ui/compositor/compositor.h" |
36 #include "ui/compositor/dip_util.h" | 36 #include "ui/compositor/dip_util.h" |
37 #include "ui/compositor/layer.h" | 37 #include "ui/compositor/layer.h" |
38 #include "ui/events/event.h" | 38 #include "ui/events/event.h" |
39 #include "ui/events/event_switches.h" | 39 #include "ui/events/event_switches.h" |
40 #include "ui/events/event_utils.h" | 40 #include "ui/events/event_utils.h" |
41 #include "ui/events/keycodes/keyboard_codes.h" | 41 #include "ui/events/keycodes/keyboard_codes.h" |
| 42 #include "ui/events/platform/platform_event_observer.h" |
42 #include "ui/events/platform/x11/x11_event_source.h" | 43 #include "ui/events/platform/x11/x11_event_source.h" |
43 #include "ui/events/x/device_data_manager.h" | 44 #include "ui/events/x/device_data_manager.h" |
44 #include "ui/events/x/device_list_cache_x.h" | 45 #include "ui/events/x/device_list_cache_x.h" |
45 #include "ui/events/x/touch_factory_x11.h" | 46 #include "ui/events/x/touch_factory_x11.h" |
46 #include "ui/gfx/screen.h" | 47 #include "ui/gfx/screen.h" |
47 | 48 |
48 using std::max; | 49 using std::max; |
49 using std::min; | 50 using std::min; |
50 | 51 |
51 namespace aura { | 52 namespace aura { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 XISetMask(mask, XI_TouchEnd); | 96 XISetMask(mask, XI_TouchEnd); |
96 XISelectEvents(display, root_window, &evmask, 1); | 97 XISelectEvents(display, root_window, &evmask, 1); |
97 } | 98 } |
98 #endif | 99 #endif |
99 } | 100 } |
100 | 101 |
101 bool default_override_redirect = false; | 102 bool default_override_redirect = false; |
102 | 103 |
103 } // namespace | 104 } // namespace |
104 | 105 |
| 106 namespace internal { |
| 107 |
| 108 // TODO(miletus) : Move this into DeviceDataManager. |
| 109 // Accomplishes 2 tasks concerning touch event calibration: |
| 110 // 1. Being a message-pump observer, |
| 111 // routes all the touch events to the X root window, |
| 112 // where they can be calibrated later. |
| 113 // 2. Has the Calibrate method that does the actual bezel calibration, |
| 114 // when invoked from X root window's event dispatcher. |
| 115 class TouchEventCalibrate : public ui::PlatformEventObserver { |
| 116 public: |
| 117 TouchEventCalibrate() : left_(0), right_(0), top_(0), bottom_(0) { |
| 118 if (ui::PlatformEventSource::GetInstance()) |
| 119 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); |
| 120 #if defined(USE_XI2_MT) |
| 121 std::vector<std::string> parts; |
| 122 if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 123 switches::kTouchCalibration), |
| 124 ",", |
| 125 &parts) >= 4) { |
| 126 if (!base::StringToInt(parts[0], &left_)) |
| 127 DLOG(ERROR) << "Incorrect left border calibration value passed."; |
| 128 if (!base::StringToInt(parts[1], &right_)) |
| 129 DLOG(ERROR) << "Incorrect right border calibration value passed."; |
| 130 if (!base::StringToInt(parts[2], &top_)) |
| 131 DLOG(ERROR) << "Incorrect top border calibration value passed."; |
| 132 if (!base::StringToInt(parts[3], &bottom_)) |
| 133 DLOG(ERROR) << "Incorrect bottom border calibration value passed."; |
| 134 } |
| 135 #endif // defined(USE_XI2_MT) |
| 136 } |
| 137 |
| 138 virtual ~TouchEventCalibrate() { |
| 139 if (ui::PlatformEventSource::GetInstance()) |
| 140 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this); |
| 141 } |
| 142 |
| 143 // Modify the location of the |event|, |
| 144 // expanding it from |bounds| to (|bounds| + bezels). |
| 145 // Required when touchscreen is bigger than screen (i.e. has bezels), |
| 146 // because we receive events in touchscreen coordinates, |
| 147 // which need to be expanded when converting to screen coordinates, |
| 148 // so that location on bezels will be outside of screen area. |
| 149 void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) { |
| 150 #if defined(USE_XI2_MT) |
| 151 int x = event->x(); |
| 152 int y = event->y(); |
| 153 |
| 154 if (!left_ && !right_ && !top_ && !bottom_) |
| 155 return; |
| 156 |
| 157 const int resolution_x = bounds.width(); |
| 158 const int resolution_y = bounds.height(); |
| 159 // The "grace area" (10% in this case) is to make it easier for the user to |
| 160 // navigate to the corner. |
| 161 const double kGraceAreaFraction = 0.1; |
| 162 if (left_ || right_) { |
| 163 // Offset the x position to the real |
| 164 x -= left_; |
| 165 // Check if we are in the grace area of the left side. |
| 166 // Note: We might not want to do this when the gesture is locked? |
| 167 if (x < 0 && x > -left_ * kGraceAreaFraction) |
| 168 x = 0; |
| 169 // Check if we are in the grace area of the right side. |
| 170 // Note: We might not want to do this when the gesture is locked? |
| 171 if (x > resolution_x - left_ && |
| 172 x < resolution_x - left_ + right_ * kGraceAreaFraction) |
| 173 x = resolution_x - left_; |
| 174 // Scale the screen area back to the full resolution of the screen. |
| 175 x = (x * resolution_x) / (resolution_x - (right_ + left_)); |
| 176 } |
| 177 if (top_ || bottom_) { |
| 178 // When there is a top bezel we add our border, |
| 179 y -= top_; |
| 180 |
| 181 // Check if we are in the grace area of the top side. |
| 182 // Note: We might not want to do this when the gesture is locked? |
| 183 if (y < 0 && y > -top_ * kGraceAreaFraction) |
| 184 y = 0; |
| 185 |
| 186 // Check if we are in the grace area of the bottom side. |
| 187 // Note: We might not want to do this when the gesture is locked? |
| 188 if (y > resolution_y - top_ && |
| 189 y < resolution_y - top_ + bottom_ * kGraceAreaFraction) |
| 190 y = resolution_y - top_; |
| 191 // Scale the screen area back to the full resolution of the screen. |
| 192 y = (y * resolution_y) / (resolution_y - (bottom_ + top_)); |
| 193 } |
| 194 |
| 195 // Set the modified coordinate back to the event. |
| 196 if (event->root_location() == event->location()) { |
| 197 // Usually those will be equal, |
| 198 // if not, I am not sure what the correct value should be. |
| 199 event->set_root_location(gfx::Point(x, y)); |
| 200 } |
| 201 event->set_location(gfx::Point(x, y)); |
| 202 #endif // defined(USE_XI2_MT) |
| 203 } |
| 204 |
| 205 private: |
| 206 // ui::PlatformEventObserver: |
| 207 virtual void WillProcessEvent(const ui::PlatformEvent& event) OVERRIDE { |
| 208 #if defined(USE_XI2_MT) |
| 209 if (event->type == GenericEvent && |
| 210 (event->xgeneric.evtype == XI_TouchBegin || |
| 211 event->xgeneric.evtype == XI_TouchUpdate || |
| 212 event->xgeneric.evtype == XI_TouchEnd)) { |
| 213 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data); |
| 214 LOG(ERROR) << "Raw " << xievent->event_x << " " << xievent->event_y |
| 215 << " " << xievent->root_x << " " << xievent->root_y; |
| 216 xievent->event = xievent->root; |
| 217 xievent->event_x = xievent->root_x; |
| 218 xievent->event_y = xievent->root_y; |
| 219 } |
| 220 #endif // defined(USE_XI2_MT) |
| 221 } |
| 222 |
| 223 virtual void DidProcessEvent(const ui::PlatformEvent& event) OVERRIDE {} |
| 224 |
| 225 // The difference in screen's native resolution pixels between |
| 226 // the border of the touchscreen and the border of the screen, |
| 227 // aka bezel sizes. |
| 228 int left_; |
| 229 int right_; |
| 230 int top_; |
| 231 int bottom_; |
| 232 |
| 233 DISALLOW_COPY_AND_ASSIGN(TouchEventCalibrate); |
| 234 }; |
| 235 |
| 236 } // namespace internal |
| 237 |
105 //////////////////////////////////////////////////////////////////////////////// | 238 //////////////////////////////////////////////////////////////////////////////// |
106 // WindowTreeHostX11 | 239 // WindowTreeHostX11 |
107 | 240 |
108 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds) | 241 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds) |
109 : xdisplay_(gfx::GetXDisplay()), | 242 : xdisplay_(gfx::GetXDisplay()), |
110 xwindow_(0), | 243 xwindow_(0), |
111 x_root_window_(DefaultRootWindow(xdisplay_)), | 244 x_root_window_(DefaultRootWindow(xdisplay_)), |
112 current_cursor_(ui::kCursorNull), | 245 current_cursor_(ui::kCursorNull), |
113 window_mapped_(false), | 246 window_mapped_(false), |
114 bounds_(bounds), | 247 bounds_(bounds), |
| 248 touch_calibrate_(new internal::TouchEventCalibrate), |
115 atom_cache_(xdisplay_, kAtomsToCache) { | 249 atom_cache_(xdisplay_, kAtomsToCache) { |
116 XSetWindowAttributes swa; | 250 XSetWindowAttributes swa; |
117 memset(&swa, 0, sizeof(swa)); | 251 memset(&swa, 0, sizeof(swa)); |
118 swa.background_pixmap = None; | 252 swa.background_pixmap = None; |
119 swa.override_redirect = default_override_redirect; | 253 swa.override_redirect = default_override_redirect; |
120 xwindow_ = XCreateWindow( | 254 xwindow_ = XCreateWindow( |
121 xdisplay_, x_root_window_, | 255 xdisplay_, x_root_window_, |
122 bounds.x(), bounds.y(), bounds.width(), bounds.height(), | 256 bounds.x(), bounds.y(), bounds.width(), bounds.height(), |
123 0, // border width | 257 0, // border width |
124 CopyFromParent, // depth | 258 CopyFromParent, // depth |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { | 625 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { |
492 } | 626 } |
493 | 627 |
494 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() { | 628 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() { |
495 return dispatcher(); | 629 return dispatcher(); |
496 } | 630 } |
497 | 631 |
498 void WindowTreeHostX11::DispatchXI2Event(const base::NativeEvent& event) { | 632 void WindowTreeHostX11::DispatchXI2Event(const base::NativeEvent& event) { |
499 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | 633 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
500 XEvent* xev = event; | 634 XEvent* xev = event; |
| 635 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
501 if (!factory->ShouldProcessXI2Event(xev)) | 636 if (!factory->ShouldProcessXI2Event(xev)) |
502 return; | 637 return; |
503 | 638 |
504 TRACE_EVENT1("input", "WindowTreeHostX11::DispatchXI2Event", | 639 TRACE_EVENT1("input", "WindowTreeHostX11::DispatchXI2Event", |
505 "event_latency_us", | 640 "event_latency_us", |
506 (ui::EventTimeForNow() - ui::EventTimeFromNative(event)). | 641 (ui::EventTimeForNow() - ui::EventTimeFromNative(event)). |
507 InMicroseconds()); | 642 InMicroseconds()); |
508 | 643 |
509 ui::EventType type = ui::EventTypeFromNative(xev); | 644 ui::EventType type = ui::EventTypeFromNative(xev); |
510 XEvent last_event; | 645 XEvent last_event; |
511 int num_coalesced = 0; | 646 int num_coalesced = 0; |
512 | 647 |
513 switch (type) { | 648 switch (type) { |
514 case ui::ET_TOUCH_MOVED: | 649 case ui::ET_TOUCH_MOVED: |
515 case ui::ET_TOUCH_PRESSED: | 650 case ui::ET_TOUCH_PRESSED: |
516 case ui::ET_TOUCH_CANCELLED: | 651 case ui::ET_TOUCH_CANCELLED: |
517 case ui::ET_TOUCH_RELEASED: { | 652 case ui::ET_TOUCH_RELEASED: { |
518 #if defined(OS_CHROMEOS) | |
519 // Bail out early before generating a ui::TouchEvent if this event | |
520 // is not within the range of this RootWindow. Converting an xevent | |
521 // to ui::TouchEvent might change the state of the global touch tracking | |
522 // state, e.g. touch release event can remove the touch id from the | |
523 // record, and doing this multiple time when there are multiple | |
524 // RootWindow will cause problem. So only generate the ui::TouchEvent | |
525 // when we are sure it belongs to this RootWindow. | |
526 if (base::SysInfo::IsRunningOnChromeOS() && | |
527 !bounds().Contains(ui::EventLocationFromNative(xev))) | |
528 return; | |
529 #endif | |
530 ui::TouchEvent touchev(xev); | 653 ui::TouchEvent touchev(xev); |
| 654 if (ui::DeviceDataManager::GetInstance()->TouchEventNeedsCalibrate( |
| 655 xiev->deviceid)) { |
| 656 touch_calibrate_->Calibrate(&touchev, bounds_); |
| 657 } |
531 TranslateAndDispatchLocatedEvent(&touchev); | 658 TranslateAndDispatchLocatedEvent(&touchev); |
532 break; | 659 break; |
533 } | 660 } |
534 case ui::ET_MOUSE_MOVED: | 661 case ui::ET_MOUSE_MOVED: |
535 case ui::ET_MOUSE_DRAGGED: | 662 case ui::ET_MOUSE_DRAGGED: |
536 case ui::ET_MOUSE_PRESSED: | 663 case ui::ET_MOUSE_PRESSED: |
537 case ui::ET_MOUSE_RELEASED: | 664 case ui::ET_MOUSE_RELEASED: |
538 case ui::ET_MOUSE_ENTERED: | 665 case ui::ET_MOUSE_ENTERED: |
539 case ui::ET_MOUSE_EXITED: { | 666 case ui::ET_MOUSE_EXITED: { |
540 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { | 667 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 } | 723 } |
597 | 724 |
598 namespace test { | 725 namespace test { |
599 | 726 |
600 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) { | 727 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) { |
601 default_override_redirect = override_redirect; | 728 default_override_redirect = override_redirect; |
602 } | 729 } |
603 | 730 |
604 } // namespace test | 731 } // namespace test |
605 } // namespace aura | 732 } // namespace aura |
OLD | NEW |