Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(499)

Side by Side Diff: ui/aura/window_tree_host_x11.cc

Issue 191223007: Move touch CTM from X into Chrome (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: move CTM update code into a separate file ash/touch/touch_ctm_controller.cc Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/Xfixes.h> 9 #include <X11/extensions/Xfixes.h>
10 #include <X11/extensions/XInput2.h> 10 #include <X11/extensions/XInput2.h>
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 virtual ~TouchEventCalibrate() { 142 virtual ~TouchEventCalibrate() {
143 base::MessageLoopForUI::current()->RemoveObserver(this); 143 base::MessageLoopForUI::current()->RemoveObserver(this);
144 } 144 }
145 145
146 // Modify the location of the |event|, 146 // Modify the location of the |event|,
147 // expanding it from |bounds| to (|bounds| + bezels). 147 // expanding it from |bounds| to (|bounds| + bezels).
148 // Required when touchscreen is bigger than screen (i.e. has bezels), 148 // Required when touchscreen is bigger than screen (i.e. has bezels),
149 // because we receive events in touchscreen coordinates, 149 // because we receive events in touchscreen coordinates,
150 // which need to be expanded when converting to screen coordinates, 150 // which need to be expanded when converting to screen coordinates,
151 // so that location on bezels will be outside of screen area. 151 // so that location on bezels will be outside of screen area.
152 void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) { 152 void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) {
sadrul 2014/03/15 19:32:51 Why do we still need this? Shouldn't this be part
ynovikov 2014/03/27 23:35:53 I agree. Originally the second calibration was nee
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Lets do this in a separate CL if necessary.
153 #if defined(USE_XI2_MT) 153 #if defined(USE_XI2_MT)
154 int x = event->x(); 154 int x = event->x();
155 int y = event->y(); 155 int y = event->y();
156 156
157 if (!left_ && !right_ && !top_ && !bottom_) 157 if (!left_ && !right_ && !top_ && !bottom_)
158 return; 158 return;
159 159
160 const int resolution_x = bounds.width(); 160 const int resolution_x = bounds.width();
161 const int resolution_y = bounds.height(); 161 const int resolution_y = bounds.height();
162 // The "grace area" (10% in this case) is to make it easier for the user to 162 // The "grace area" (10% in this case) is to make it easier for the user to
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 //////////////////////////////////////////////////////////////////////////////// 242 ////////////////////////////////////////////////////////////////////////////////
243 // WindowTreeHostX11 243 // WindowTreeHostX11
244 244
245 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds) 245 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds)
246 : xdisplay_(gfx::GetXDisplay()), 246 : xdisplay_(gfx::GetXDisplay()),
247 xwindow_(0), 247 xwindow_(0),
248 x_root_window_(DefaultRootWindow(xdisplay_)), 248 x_root_window_(DefaultRootWindow(xdisplay_)),
249 current_cursor_(ui::kCursorNull), 249 current_cursor_(ui::kCursorNull),
250 window_mapped_(false), 250 window_mapped_(false),
251 bounds_(bounds), 251 bounds_(bounds),
252 is_internal_display_(false),
253 touch_calibrate_(new internal::TouchEventCalibrate), 252 touch_calibrate_(new internal::TouchEventCalibrate),
254 atom_cache_(xdisplay_, kAtomsToCache) { 253 atom_cache_(xdisplay_, kAtomsToCache) {
255 XSetWindowAttributes swa; 254 XSetWindowAttributes swa;
256 memset(&swa, 0, sizeof(swa)); 255 memset(&swa, 0, sizeof(swa));
257 swa.background_pixmap = None; 256 swa.background_pixmap = None;
258 swa.override_redirect = default_override_redirect; 257 swa.override_redirect = default_override_redirect;
259 xwindow_ = XCreateWindow( 258 xwindow_ = XCreateWindow(
260 xdisplay_, x_root_window_, 259 xdisplay_, x_root_window_,
261 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 260 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
262 0, // border width 261 0, // border width
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 DCHECK_EQ(xwindow_, xev->xconfigure.event); 401 DCHECK_EQ(xwindow_, xev->xconfigure.event);
403 DCHECK_EQ(xwindow_, xev->xconfigure.window); 402 DCHECK_EQ(xwindow_, xev->xconfigure.window);
404 // It's possible that the X window may be resized by some other means 403 // It's possible that the X window may be resized by some other means
405 // than from within aura (e.g. the X window manager can change the 404 // than from within aura (e.g. the X window manager can change the
406 // size). Make sure the root window size is maintained properly. 405 // size). Make sure the root window size is maintained properly.
407 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, 406 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
408 xev->xconfigure.width, xev->xconfigure.height); 407 xev->xconfigure.width, xev->xconfigure.height);
409 bool size_changed = bounds_.size() != bounds.size(); 408 bool size_changed = bounds_.size() != bounds.size();
410 bool origin_changed = bounds_.origin() != bounds.origin(); 409 bool origin_changed = bounds_.origin() != bounds.origin();
411 bounds_ = bounds; 410 bounds_ = bounds;
412 UpdateIsInternalDisplay();
413 // Always update barrier and mouse location because |bounds_| might 411 // Always update barrier and mouse location because |bounds_| might
414 // have already been updated in |SetBounds|. 412 // have already been updated in |SetBounds|.
415 if (pointer_barriers_) { 413 if (pointer_barriers_) {
416 UnConfineCursor(); 414 UnConfineCursor();
417 ConfineCursorToRootWindow(); 415 ConfineCursorToRootWindow();
418 } 416 }
419 if (size_changed) 417 if (size_changed)
420 OnHostResized(bounds.size()); 418 OnHostResized(bounds.size());
421 if (origin_changed) 419 if (origin_changed)
422 OnHostMoved(bounds_.origin()); 420 OnHostMoved(bounds_.origin());
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 } 547 }
550 if (value_mask) 548 if (value_mask)
551 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes); 549 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
552 550
553 // Assume that the resize will go through as requested, which should be the 551 // Assume that the resize will go through as requested, which should be the
554 // case if we're running without a window manager. If there's a window 552 // case if we're running without a window manager. If there's a window
555 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a 553 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a
556 // (possibly synthetic) ConfigureNotify about the actual size and correct 554 // (possibly synthetic) ConfigureNotify about the actual size and correct
557 // |bounds_| later. 555 // |bounds_| later.
558 bounds_ = bounds; 556 bounds_ = bounds;
559 UpdateIsInternalDisplay();
560 if (origin_changed) 557 if (origin_changed)
561 OnHostMoved(bounds.origin()); 558 OnHostMoved(bounds.origin());
562 if (size_changed || current_scale != new_scale) { 559 if (size_changed || current_scale != new_scale) {
563 OnHostResized(bounds.size()); 560 OnHostResized(bounds.size());
564 } else { 561 } else {
565 window()->SchedulePaintInRect(window()->bounds()); 562 window()->SchedulePaintInRect(window()->bounds());
566 } 563 }
567 } 564 }
568 565
569 gfx::Insets WindowTreeHostX11::GetInsets() const { 566 gfx::Insets WindowTreeHostX11::GetInsets() const {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 } 714 }
718 715
719 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { 716 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) {
720 SetCrOSTapPaused(!show); 717 SetCrOSTapPaused(!show);
721 } 718 }
722 719
723 void WindowTreeHostX11::OnWindowInitialized(Window* window) { 720 void WindowTreeHostX11::OnWindowInitialized(Window* window) {
724 } 721 }
725 722
726 void WindowTreeHostX11::OnHostInitialized(WindowTreeHost* host) { 723 void WindowTreeHostX11::OnHostInitialized(WindowTreeHost* host) {
727 // TODO(beng): I'm not sure that this comment makes much sense anymore??
728 // UpdateIsInternalDisplay relies on WED's kDisplayIdKey property being set
729 // available by the time WED::Init is called. (set in
730 // DisplayManager::CreateRootWindowForDisplay)
731 // Ready when NotifyHostInitialized is called from WED::Init.
732 if (host != this) 724 if (host != this)
733 return; 725 return;
734 UpdateIsInternalDisplay();
735 726
736 // We have to enable Tap-to-click by default because the cursor is set to 727 // We have to enable Tap-to-click by default because the cursor is set to
737 // visible in Shell::InitRootWindowController. 728 // visible in Shell::InitRootWindowController.
738 SetCrOSTapPaused(false); 729 SetCrOSTapPaused(false);
739 } 730 }
740 731
741 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() { 732 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() {
742 return dispatcher(); 733 return dispatcher();
743 } 734 }
744 735
(...skipping 10 matching lines...) Expand all
755 746
756 ui::EventType type = ui::EventTypeFromNative(xev); 747 ui::EventType type = ui::EventTypeFromNative(xev);
757 XEvent last_event; 748 XEvent last_event;
758 int num_coalesced = 0; 749 int num_coalesced = 0;
759 750
760 switch (type) { 751 switch (type) {
761 case ui::ET_TOUCH_MOVED: 752 case ui::ET_TOUCH_MOVED:
762 case ui::ET_TOUCH_PRESSED: 753 case ui::ET_TOUCH_PRESSED:
763 case ui::ET_TOUCH_CANCELLED: 754 case ui::ET_TOUCH_CANCELLED:
764 case ui::ET_TOUCH_RELEASED: { 755 case ui::ET_TOUCH_RELEASED: {
765 #if defined(OS_CHROMEOS)
766 // Bail out early before generating a ui::TouchEvent if this event 756 // Bail out early before generating a ui::TouchEvent if this event
767 // is not within the range of this RootWindow. Converting an xevent 757 // is targeting this RootWindow.
oshima 2014/03/14 21:53:53 then you can do something like if (GetTouchCalibr
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 I moved TouchCalibrate into DeviceDataManager.
768 // to ui::TouchEvent might change the state of the global touch tracking 758 // Converting an xevent to ui::TouchEvent might change the state of
769 // state, e.g. touch release event can remove the touch id from the 759 // the global touch tracking state, e.g. touch release event can
770 // record, and doing this multiple time when there are multiple 760 // remove the touch id from the record, and doing this multiple time
771 // RootWindow will cause problem. So only generate the ui::TouchEvent 761 // when there are multiple RootWindow will cause problem. So only
772 // when we are sure it belongs to this RootWindow. 762 // generate the ui::TouchEvent when we are sure it is targeting this
773 if (base::SysInfo::IsRunningOnChromeOS() && 763 // RootWindow.
774 !bounds_.Contains(ui::EventLocationFromNative(xev))) 764 if (!IsTouchEventTargetingThisRootWindow(xev))
775 break; 765 break;
776 #endif // defined(OS_CHROMEOS)
777 ui::TouchEvent touchev(xev); 766 ui::TouchEvent touchev(xev);
778 #if defined(OS_CHROMEOS) 767 CalibrateTouchEvent(xev, &touchev);
779 if (base::SysInfo::IsRunningOnChromeOS()) {
780 // X maps the touch-surface to the size of the X root-window.
781 // In multi-monitor setup, Coordinate Transformation Matrix
782 // repositions the touch-surface onto part of X root-window
783 // containing aura root-window corresponding to the touchscreen.
784 // However, if aura root-window has non-zero origin,
785 // we need to relocate the event into aura root-window coordinates.
786 touchev.Relocate(bounds_.origin());
ynovikov 2014/03/27 23:35:53 I think this is the only use of Relocate(), could
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
787 #if defined(USE_XI2_MT)
788 if (is_internal_display_)
789 touch_calibrate_->Calibrate(&touchev, bounds_);
790 #endif // defined(USE_XI2_MT)
791 }
792 #endif // defined(OS_CHROMEOS)
793 SendEventToProcessor(&touchev); 768 SendEventToProcessor(&touchev);
794 break; 769 break;
795 } 770 }
796 case ui::ET_MOUSE_MOVED: 771 case ui::ET_MOUSE_MOVED:
797 case ui::ET_MOUSE_DRAGGED: 772 case ui::ET_MOUSE_DRAGGED:
798 case ui::ET_MOUSE_PRESSED: 773 case ui::ET_MOUSE_PRESSED:
799 case ui::ET_MOUSE_RELEASED: 774 case ui::ET_MOUSE_RELEASED:
800 case ui::ET_MOUSE_ENTERED: 775 case ui::ET_MOUSE_ENTERED:
801 case ui::ET_MOUSE_EXITED: { 776 case ui::ET_MOUSE_EXITED: {
802 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { 777 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 // host window, then convert it back to this host window's coordinate. 836 // host window, then convert it back to this host window's coordinate.
862 screen_position_client->ConvertHostPointToScreen(root_window, &location); 837 screen_position_client->ConvertHostPointToScreen(root_window, &location);
863 screen_position_client->ConvertPointFromScreen(root_window, &location); 838 screen_position_client->ConvertPointFromScreen(root_window, &location);
864 ConvertPointToHost(&location); 839 ConvertPointToHost(&location);
865 event->set_location(location); 840 event->set_location(location);
866 event->set_root_location(location); 841 event->set_root_location(location);
867 } 842 }
868 SendEventToProcessor(event); 843 SendEventToProcessor(event);
869 } 844 }
870 845
871 void WindowTreeHostX11::UpdateIsInternalDisplay() {
872 Window* root_window = window();
873 gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window);
874 gfx::Display display = screen->GetDisplayNearestWindow(root_window);
875 is_internal_display_ = display.IsInternal();
876 }
877
878 void WindowTreeHostX11::SetCrOSTapPaused(bool state) { 846 void WindowTreeHostX11::SetCrOSTapPaused(bool state) {
879 #if defined(OS_CHROMEOS) 847 #if defined(OS_CHROMEOS)
880 if (!ui::IsXInput2Available()) 848 if (!ui::IsXInput2Available())
881 return; 849 return;
882 // Temporarily pause tap-to-click when the cursor is hidden. 850 // Temporarily pause tap-to-click when the cursor is hidden.
883 Atom prop = atom_cache_.GetAtom("Tap Paused"); 851 Atom prop = atom_cache_.GetAtom("Tap Paused");
884 unsigned char value = state; 852 unsigned char value = state;
885 XIDeviceList dev_list = 853 XIDeviceList dev_list =
886 ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(xdisplay_); 854 ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(xdisplay_);
887 855
(...skipping 10 matching lines...) Expand all
898 if (result != Success) 866 if (result != Success)
899 continue; 867 continue;
900 XFree(data); 868 XFree(data);
901 XIChangeProperty(xdisplay_, dev_list[i].deviceid, prop, XA_INTEGER, 8, 869 XIChangeProperty(xdisplay_, dev_list[i].deviceid, prop, XA_INTEGER, 8,
902 PropModeReplace, &value, 1); 870 PropModeReplace, &value, 1);
903 } 871 }
904 } 872 }
905 #endif 873 #endif
906 } 874 }
907 875
876 bool WindowTreeHostX11::IsTouchEventTargetingThisRootWindow(
877 const base::NativeEvent& event) {
sadrul 2014/03/15 19:32:51 Just use XEvent* here.
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
878 #if defined(OS_CHROMEOS)
879 XEvent* xev = event;
880 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
881 int64 touch_display_id =
882 ui::DeviceDataManager::GetInstance()->GetDisplayForTouchDevice(
883 xiev->deviceid);
884 // If we don't have record of display id for this touch device, then
885 // fall backt to check if this touch event is within the bounds of
sadrul 2014/03/15 19:32:51 *back
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
886 // this root window.
887 if (touch_display_id == gfx::Display::kInvalidDisplayID) {
888 if (base::SysInfo::IsRunningOnChromeOS() &&
889 !bounds_.Contains(ui::EventLocationFromNative(xev)))
ynovikov 2014/03/27 23:35:53 As I understand it, this check will be wrong most
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 I am more interested in not regress the 1 monitor
890 return false;
891 // If we do have record of the display id for this touch device,
sadrul 2014/03/15 19:32:51 I don't think this comment is necessary here.
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
892 // then check if this touch display id is associated with this
893 // root window.
894 } else if (touch_display_id != display_ids().first &&
895 touch_display_id != display_ids().second) {
896 return false;
897 }
898 #endif // defined(OS_CHROMEOS)
899 return true;
sadrul 2014/03/15 19:32:51 non-CHROMEOS case should do the bounds check. Thi
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 The original code does not do the bounds check in
900 }
901
902 void WindowTreeHostX11::CalibrateTouchEvent(const base::NativeEvent& event,
903 ui::TouchEvent* touchev) {
904 #if defined(OS_CHROMEOS) && defined(USE_XI2_MT)
905 XEvent* xev = event;
906 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
907 int64 touch_display_id =
908 ui::DeviceDataManager::GetInstance()->GetDisplayForTouchDevice(
909 xiev->deviceid);
910 // On ChromeOS, if touch event is from internal display, we need to
911 // calibrate its location for bezel region.
912 if (base::SysInfo::IsRunningOnChromeOS() &&
913 touch_display_id == gfx::Display::InternalDisplayId()) {
914 touch_calibrate_->Calibrate(touchev, bounds_);
915 }
916 #endif // defined(OS_CHROMEOS) && defined(USE_XI2_MT)
917 }
918
908 // static 919 // static
909 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) { 920 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) {
910 return new WindowTreeHostX11(bounds); 921 return new WindowTreeHostX11(bounds);
911 } 922 }
912 923
913 // static 924 // static
914 gfx::Size WindowTreeHost::GetNativeScreenSize() { 925 gfx::Size WindowTreeHost::GetNativeScreenSize() {
915 ::XDisplay* xdisplay = gfx::GetXDisplay(); 926 ::XDisplay* xdisplay = gfx::GetXDisplay();
916 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 927 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
917 } 928 }
918 929
919 namespace test { 930 namespace test {
920 931
921 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) { 932 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
922 default_override_redirect = override_redirect; 933 default_override_redirect = override_redirect;
923 } 934 }
924 935
925 } // namespace test 936 } // namespace test
926 } // namespace aura 937 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698