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

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: restructuring 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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 // Scale the screen area back to the full resolution of the screen. 194 // Scale the screen area back to the full resolution of the screen.
195 y = (y * resolution_y) / (resolution_y - (bottom_ + top_)); 195 y = (y * resolution_y) / (resolution_y - (bottom_ + top_));
196 } 196 }
197 197
198 // Set the modified coordinate back to the event. 198 // Set the modified coordinate back to the event.
199 if (event->root_location() == event->location()) { 199 if (event->root_location() == event->location()) {
200 // Usually those will be equal, 200 // Usually those will be equal,
201 // if not, I am not sure what the correct value should be. 201 // if not, I am not sure what the correct value should be.
202 event->set_root_location(gfx::Point(x, y)); 202 event->set_root_location(gfx::Point(x, y));
203 } 203 }
204
204 event->set_location(gfx::Point(x, y)); 205 event->set_location(gfx::Point(x, y));
205 #endif // defined(USE_XI2_MT) 206 #endif // defined(USE_XI2_MT)
206 } 207 }
207 208
208 private: 209 private:
209 // Overridden from base::MessagePumpObserver: 210 // Overridden from base::MessagePumpObserver:
210 virtual base::EventStatus WillProcessEvent( 211 virtual base::EventStatus WillProcessEvent(
211 const base::NativeEvent& event) OVERRIDE { 212 const base::NativeEvent& event) OVERRIDE {
212 #if defined(USE_XI2_MT) 213 #if defined(USE_XI2_MT)
213 if (event->type == GenericEvent && 214 if (event->type == GenericEvent &&
(...skipping 28 matching lines...) Expand all
242 //////////////////////////////////////////////////////////////////////////////// 243 ////////////////////////////////////////////////////////////////////////////////
243 // WindowTreeHostX11 244 // WindowTreeHostX11
244 245
245 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds) 246 WindowTreeHostX11::WindowTreeHostX11(const gfx::Rect& bounds)
246 : xdisplay_(gfx::GetXDisplay()), 247 : xdisplay_(gfx::GetXDisplay()),
247 xwindow_(0), 248 xwindow_(0),
248 x_root_window_(DefaultRootWindow(xdisplay_)), 249 x_root_window_(DefaultRootWindow(xdisplay_)),
249 current_cursor_(ui::kCursorNull), 250 current_cursor_(ui::kCursorNull),
250 window_mapped_(false), 251 window_mapped_(false),
251 bounds_(bounds), 252 bounds_(bounds),
252 is_internal_display_(false),
253 touch_calibrate_(new internal::TouchEventCalibrate), 253 touch_calibrate_(new internal::TouchEventCalibrate),
254 atom_cache_(xdisplay_, kAtomsToCache) { 254 atom_cache_(xdisplay_, kAtomsToCache) {
255 XSetWindowAttributes swa; 255 XSetWindowAttributes swa;
256 memset(&swa, 0, sizeof(swa)); 256 memset(&swa, 0, sizeof(swa));
257 swa.background_pixmap = None; 257 swa.background_pixmap = None;
258 swa.override_redirect = default_override_redirect; 258 swa.override_redirect = default_override_redirect;
259 xwindow_ = XCreateWindow( 259 xwindow_ = XCreateWindow(
260 xdisplay_, x_root_window_, 260 xdisplay_, x_root_window_,
261 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 261 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
262 0, // border width 262 0, // border width
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 DCHECK_EQ(xwindow_, xev->xconfigure.event); 402 DCHECK_EQ(xwindow_, xev->xconfigure.event);
403 DCHECK_EQ(xwindow_, xev->xconfigure.window); 403 DCHECK_EQ(xwindow_, xev->xconfigure.window);
404 // It's possible that the X window may be resized by some other means 404 // 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 405 // than from within aura (e.g. the X window manager can change the
406 // size). Make sure the root window size is maintained properly. 406 // size). Make sure the root window size is maintained properly.
407 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, 407 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
408 xev->xconfigure.width, xev->xconfigure.height); 408 xev->xconfigure.width, xev->xconfigure.height);
409 bool size_changed = bounds_.size() != bounds.size(); 409 bool size_changed = bounds_.size() != bounds.size();
410 bool origin_changed = bounds_.origin() != bounds.origin(); 410 bool origin_changed = bounds_.origin() != bounds.origin();
411 bounds_ = bounds; 411 bounds_ = bounds;
412 UpdateIsInternalDisplay();
413 // Always update barrier and mouse location because |bounds_| might 412 // Always update barrier and mouse location because |bounds_| might
414 // have already been updated in |SetBounds|. 413 // have already been updated in |SetBounds|.
415 if (pointer_barriers_) { 414 if (pointer_barriers_) {
416 UnConfineCursor(); 415 UnConfineCursor();
417 ConfineCursorToRootWindow(); 416 ConfineCursorToRootWindow();
418 } 417 }
419 if (size_changed) 418 if (size_changed)
420 OnHostResized(bounds.size()); 419 OnHostResized(bounds.size());
421 if (origin_changed) 420 if (origin_changed)
422 OnHostMoved(bounds_.origin()); 421 OnHostMoved(bounds_.origin());
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 } 548 }
550 if (value_mask) 549 if (value_mask)
551 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes); 550 XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
552 551
553 // Assume that the resize will go through as requested, which should be the 552 // 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 553 // 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 554 // 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 555 // (possibly synthetic) ConfigureNotify about the actual size and correct
557 // |bounds_| later. 556 // |bounds_| later.
558 bounds_ = bounds; 557 bounds_ = bounds;
559 UpdateIsInternalDisplay();
560 if (origin_changed) 558 if (origin_changed)
561 OnHostMoved(bounds.origin()); 559 OnHostMoved(bounds.origin());
562 if (size_changed || current_scale != new_scale) { 560 if (size_changed || current_scale != new_scale) {
563 OnHostResized(bounds.size()); 561 OnHostResized(bounds.size());
564 } else { 562 } else {
565 window()->SchedulePaintInRect(window()->bounds()); 563 window()->SchedulePaintInRect(window()->bounds());
566 } 564 }
567 } 565 }
568 566
569 gfx::Insets WindowTreeHostX11::GetInsets() const { 567 gfx::Insets WindowTreeHostX11::GetInsets() const {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 } 715 }
718 716
719 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { 717 void WindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) {
720 SetCrOSTapPaused(!show); 718 SetCrOSTapPaused(!show);
721 } 719 }
722 720
723 void WindowTreeHostX11::OnWindowInitialized(Window* window) { 721 void WindowTreeHostX11::OnWindowInitialized(Window* window) {
724 } 722 }
725 723
726 void WindowTreeHostX11::OnHostInitialized(WindowTreeHost* host) { 724 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) 725 if (host != this)
733 return; 726 return;
734 UpdateIsInternalDisplay();
735 727
736 // We have to enable Tap-to-click by default because the cursor is set to 728 // We have to enable Tap-to-click by default because the cursor is set to
737 // visible in Shell::InitRootWindowController. 729 // visible in Shell::InitRootWindowController.
738 SetCrOSTapPaused(false); 730 SetCrOSTapPaused(false);
739 } 731 }
740 732
741 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() { 733 ui::EventProcessor* WindowTreeHostX11::GetEventProcessor() {
742 return dispatcher(); 734 return dispatcher();
743 } 735 }
744 736
(...skipping 10 matching lines...) Expand all
755 747
756 ui::EventType type = ui::EventTypeFromNative(xev); 748 ui::EventType type = ui::EventTypeFromNative(xev);
757 XEvent last_event; 749 XEvent last_event;
758 int num_coalesced = 0; 750 int num_coalesced = 0;
759 751
760 switch (type) { 752 switch (type) {
761 case ui::ET_TOUCH_MOVED: 753 case ui::ET_TOUCH_MOVED:
762 case ui::ET_TOUCH_PRESSED: 754 case ui::ET_TOUCH_PRESSED:
763 case ui::ET_TOUCH_CANCELLED: 755 case ui::ET_TOUCH_CANCELLED:
764 case ui::ET_TOUCH_RELEASED: { 756 case ui::ET_TOUCH_RELEASED: {
765 #if defined(OS_CHROMEOS)
766 // Bail out early before generating a ui::TouchEvent if this event 757 // Bail out early before generating a ui::TouchEvent if this event
767 // is not within the range of this RootWindow. Converting an xevent 758 // is targeting this RootWindow.
768 // to ui::TouchEvent might change the state of the global touch tracking 759 // 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 760 // the global touch tracking state, e.g. touch release event can
770 // record, and doing this multiple time when there are multiple 761 // remove the touch id from the record, and doing this multiple time
771 // RootWindow will cause problem. So only generate the ui::TouchEvent 762 // when there are multiple RootWindow will cause problem. So only
772 // when we are sure it belongs to this RootWindow. 763 // generate the ui::TouchEvent when we are sure it is targeting this
773 if (base::SysInfo::IsRunningOnChromeOS() && 764 // RootWindow.
774 !bounds_.Contains(ui::EventLocationFromNative(xev))) 765 if (!IsTouchEventTargetingThisRootWindow(xev))
775 break; 766 break;
776 #endif // defined(OS_CHROMEOS)
777 ui::TouchEvent touchev(xev); 767 ui::TouchEvent touchev(xev);
778 #if defined(OS_CHROMEOS) 768 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());
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); 769 SendEventToProcessor(&touchev);
794 break; 770 break;
795 } 771 }
796 case ui::ET_MOUSE_MOVED: 772 case ui::ET_MOUSE_MOVED:
797 case ui::ET_MOUSE_DRAGGED: 773 case ui::ET_MOUSE_DRAGGED:
798 case ui::ET_MOUSE_PRESSED: 774 case ui::ET_MOUSE_PRESSED:
799 case ui::ET_MOUSE_RELEASED: 775 case ui::ET_MOUSE_RELEASED:
800 case ui::ET_MOUSE_ENTERED: 776 case ui::ET_MOUSE_ENTERED:
801 case ui::ET_MOUSE_EXITED: { 777 case ui::ET_MOUSE_EXITED: {
802 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { 778 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. 837 // host window, then convert it back to this host window's coordinate.
862 screen_position_client->ConvertHostPointToScreen(root_window, &location); 838 screen_position_client->ConvertHostPointToScreen(root_window, &location);
863 screen_position_client->ConvertPointFromScreen(root_window, &location); 839 screen_position_client->ConvertPointFromScreen(root_window, &location);
864 ConvertPointToHost(&location); 840 ConvertPointToHost(&location);
865 event->set_location(location); 841 event->set_location(location);
866 event->set_root_location(location); 842 event->set_root_location(location);
867 } 843 }
868 SendEventToProcessor(event); 844 SendEventToProcessor(event);
869 } 845 }
870 846
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) { 847 void WindowTreeHostX11::SetCrOSTapPaused(bool state) {
879 #if defined(OS_CHROMEOS) 848 #if defined(OS_CHROMEOS)
880 if (!ui::IsXInput2Available()) 849 if (!ui::IsXInput2Available())
881 return; 850 return;
882 // Temporarily pause tap-to-click when the cursor is hidden. 851 // Temporarily pause tap-to-click when the cursor is hidden.
883 Atom prop = atom_cache_.GetAtom("Tap Paused"); 852 Atom prop = atom_cache_.GetAtom("Tap Paused");
884 unsigned char value = state; 853 unsigned char value = state;
885 XIDeviceList dev_list = 854 XIDeviceList dev_list =
886 ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(xdisplay_); 855 ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(xdisplay_);
887 856
(...skipping 10 matching lines...) Expand all
898 if (result != Success) 867 if (result != Success)
899 continue; 868 continue;
900 XFree(data); 869 XFree(data);
901 XIChangeProperty(xdisplay_, dev_list[i].deviceid, prop, XA_INTEGER, 8, 870 XIChangeProperty(xdisplay_, dev_list[i].deviceid, prop, XA_INTEGER, 8,
902 PropModeReplace, &value, 1); 871 PropModeReplace, &value, 1);
903 } 872 }
904 } 873 }
905 #endif 874 #endif
906 } 875 }
907 876
877 bool WindowTreeHostX11::IsTouchEventTargetingThisRootWindow(
878 const base::NativeEvent& event) {
879 #if defined(OS_CHROMEOS)
880 XEvent* xev = event;
881 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
882 int64 touch_display_id =
883 ui::DeviceDataManager::GetInstance()->GetDisplayForTouchDevice(
884 xiev->deviceid);
885 // If we don't have record of display id for this touch device, then
886 // fall backt to check if this touch event is within the bounds of
887 // this root window.
888 if (touch_display_id == gfx::Display::kInvalidDisplayID) {
889 if (base::SysInfo::IsRunningOnChromeOS() &&
890 !bounds_.Contains(ui::EventLocationFromNative(xev)))
891 return false;
892 // If we do have record of the display id for this touch device,
893 // then check if this touch display id is associated with this
894 // root window.
895 } else if (touch_display_id != display_ids().first &&
896 touch_display_id != display_ids().second) {
897 return false;
898 }
899 #endif // defined(OS_CHROMEOS)
900 return true;
901 }
902
903 void WindowTreeHostX11::CalibrateTouchEvent(const base::NativeEvent& event,
904 ui::TouchEvent* touchev) {
905 #if defined(OS_CHROMEOS) && defined(USE_XI2_MT)
906 XEvent* xev = event;
907 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
908 int64 touch_display_id =
909 ui::DeviceDataManager::GetInstance()->GetDisplayForTouchDevice(
910 xiev->deviceid);
911 // On ChromeOS, if touch event is from internal display, we need to
912 // calibrate its location for bezel region.
913 if (base::SysInfo::IsRunningOnChromeOS() &&
914 touch_display_id == gfx::Display::InternalDisplayId()) {
915 touch_calibrate_->Calibrate(touchev, bounds_);
916 }
917 #endif // defined(OS_CHROMEOS) && defined(USE_XI2_MT)
918 }
919
908 // static 920 // static
909 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) { 921 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) {
910 return new WindowTreeHostX11(bounds); 922 return new WindowTreeHostX11(bounds);
911 } 923 }
912 924
913 // static 925 // static
914 gfx::Size WindowTreeHost::GetNativeScreenSize() { 926 gfx::Size WindowTreeHost::GetNativeScreenSize() {
915 ::XDisplay* xdisplay = gfx::GetXDisplay(); 927 ::XDisplay* xdisplay = gfx::GetXDisplay();
916 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 928 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
917 } 929 }
918 930
919 namespace test { 931 namespace test {
920 932
921 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) { 933 void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
922 default_override_redirect = override_redirect; 934 default_override_redirect = override_redirect;
923 } 935 }
924 936
925 } // namespace test 937 } // namespace test
926 } // namespace aura 938 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698