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/base/events/event_constants.h" | 5 #include "ui/base/events/event_constants.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <X11/extensions/XInput.h> | 8 #include <X11/extensions/XInput.h> |
9 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
10 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> |
11 | 11 |
12 #include "base/command_line.h" | |
13 #include "base/logging.h" | 12 #include "base/logging.h" |
14 #include "base/memory/singleton.h" | 13 #include "base/memory/singleton.h" |
15 #include "base/message_pump_aurax11.h" | 14 #include "base/message_pump_aurax11.h" |
16 #include "base/string_number_conversions.h" | |
17 #include "base/strings/string_split.h" | |
18 #include "ui/base/events/event_utils.h" | 15 #include "ui/base/events/event_utils.h" |
19 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 16 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
20 #include "ui/base/touch/touch_factory.h" | 17 #include "ui/base/touch/touch_factory.h" |
21 #include "ui/base/ui_base_switches.h" | |
22 #include "ui/base/x/device_list_cache_x.h" | 18 #include "ui/base/x/device_list_cache_x.h" |
23 #include "ui/base/x/valuators.h" | 19 #include "ui/base/x/valuators.h" |
24 #include "ui/base/x/x11_atom_cache.h" | 20 #include "ui/base/x/x11_atom_cache.h" |
25 #include "ui/base/x/x11_util.h" | 21 #include "ui/base/x/x11_util.h" |
26 #include "ui/gfx/display.h" | 22 #include "ui/gfx/display.h" |
27 #include "ui/gfx/point.h" | 23 #include "ui/gfx/point.h" |
28 #include "ui/gfx/rect.h" | 24 #include "ui/gfx/rect.h" |
29 #include "ui/gfx/screen.h" | 25 #include "ui/gfx/screen.h" |
30 | 26 |
31 // Copied from xserver-properties.h | 27 // Copied from xserver-properties.h |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 AXIS_LABEL_PROP_ABS_DBL_END_TIME, | 68 AXIS_LABEL_PROP_ABS_DBL_END_TIME, |
73 AXIS_LABEL_PROP_ABS_FLING_X, | 69 AXIS_LABEL_PROP_ABS_FLING_X, |
74 AXIS_LABEL_PROP_ABS_FLING_Y, | 70 AXIS_LABEL_PROP_ABS_FLING_Y, |
75 AXIS_LABEL_PROP_ABS_DBL_FLING_VX, | 71 AXIS_LABEL_PROP_ABS_DBL_FLING_VX, |
76 AXIS_LABEL_PROP_ABS_DBL_FLING_VY, | 72 AXIS_LABEL_PROP_ABS_DBL_FLING_VY, |
77 AXIS_LABEL_PROP_ABS_FLING_STATE, | 73 AXIS_LABEL_PROP_ABS_FLING_STATE, |
78 AXIS_LABEL_PROP_ABS_FINGER_COUNT, | 74 AXIS_LABEL_PROP_ABS_FINGER_COUNT, |
79 NULL | 75 NULL |
80 }; | 76 }; |
81 | 77 |
82 #if defined(USE_XI2_MT) | |
83 // If the calibration values were read, if this is true. | |
84 bool calibration_values_read = false; | |
85 | |
86 // The (positive) calibration values for the four border sides. | |
87 int left_border_touch_calibration = 0; | |
88 int top_border_touch_calibration = 0; | |
89 int right_border_touch_calibration = 0; | |
90 int bottom_border_touch_calibration = 0; | |
91 #endif | |
92 | |
93 // A class to support the detection of scroll events, using X11 valuators. | 78 // A class to support the detection of scroll events, using X11 valuators. |
94 class CMTEventData { | 79 class CMTEventData { |
95 public: | 80 public: |
96 // Returns the ScrollEventData singleton. | 81 // Returns the ScrollEventData singleton. |
97 static CMTEventData* GetInstance() { | 82 static CMTEventData* GetInstance() { |
98 return Singleton<CMTEventData>::get(); | 83 return Singleton<CMTEventData>::get(); |
99 } | 84 } |
100 | 85 |
101 // Updates the list of devices. | 86 // Updates the list of devices. |
102 void UpdateDeviceList(Display* display) { | 87 void UpdateDeviceList(Display* display) { |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 *xev, val, &default_value); | 664 *xev, val, &default_value); |
680 return default_value; | 665 return default_value; |
681 } | 666 } |
682 | 667 |
683 Atom GetNoopEventAtom() { | 668 Atom GetNoopEventAtom() { |
684 return XInternAtom( | 669 return XInternAtom( |
685 base::MessagePumpAuraX11::GetDefaultXDisplay(), | 670 base::MessagePumpAuraX11::GetDefaultXDisplay(), |
686 "noop", False); | 671 "noop", False); |
687 } | 672 } |
688 | 673 |
689 #if defined(USE_XI2_MT) | |
690 | |
691 void ReadTouchCalibrationValues() { | |
692 calibration_values_read = true; | |
693 | |
694 std::vector<std::string> parts; | |
695 base::SplitString(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
696 switches::kTouchCalibration), ',', &parts); | |
697 if (parts.size() >= 4) { | |
698 if (!base::StringToInt(parts[0], &left_border_touch_calibration)) | |
699 DLOG(ERROR) << "Incorrect left border calibration value passed."; | |
700 if (!base::StringToInt(parts[1], &right_border_touch_calibration)) | |
701 DLOG(ERROR) << "Incorrect right border calibration value passed."; | |
702 if (!base::StringToInt(parts[2], &top_border_touch_calibration)) | |
703 DLOG(ERROR) << "Incorrect top border calibration value passed."; | |
704 if (!base::StringToInt(parts[3], &bottom_border_touch_calibration)) | |
705 DLOG(ERROR) << "Incorrect bottom border calibration value passed."; | |
706 } | |
707 } | |
708 | |
709 gfx::Point CalibrateTouchCoordinates( | |
710 const XIDeviceEvent* xievent) { | |
711 int x = static_cast<int>(xievent->event_x); | |
712 int y = static_cast<int>(xievent->event_y); | |
713 | |
714 if (!calibration_values_read) | |
715 ReadTouchCalibrationValues(); | |
716 | |
717 if (!left_border_touch_calibration && !right_border_touch_calibration && | |
718 !top_border_touch_calibration && !bottom_border_touch_calibration) | |
719 return gfx::Point(x, y); | |
720 | |
721 gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); | |
722 gfx::Rect bounds = display.bounds(); | |
723 const int resolution_x = bounds.width() * display.device_scale_factor(); | |
724 const int resolution_y = bounds.height() * display.device_scale_factor(); | |
725 // The "grace area" (10% in this case) is to make it easier for the user to | |
726 // navigate to the corner. | |
727 const double kGraceAreaFraction = 0.1; | |
728 if (left_border_touch_calibration || right_border_touch_calibration) { | |
729 // Offset the x position to the real | |
730 x -= left_border_touch_calibration; | |
731 // Check if we are in the grace area of the left side. | |
732 // Note: We might not want to do this when the gesture is locked? | |
733 if (x < 0 && x > -left_border_touch_calibration * kGraceAreaFraction) | |
734 x = 0; | |
735 // Check if we are in the grace area of the right side. | |
736 // Note: We might not want to do this when the gesture is locked? | |
737 if (x > resolution_x - left_border_touch_calibration && | |
738 x < resolution_x - left_border_touch_calibration + | |
739 right_border_touch_calibration * kGraceAreaFraction) | |
740 x = resolution_x - left_border_touch_calibration; | |
741 // Scale the screen area back to the full resolution of the screen. | |
742 x = (x * resolution_x) / (resolution_x - (right_border_touch_calibration + | |
743 left_border_touch_calibration)); | |
744 } | |
745 if (top_border_touch_calibration || bottom_border_touch_calibration) { | |
746 // When there is a top bezel we add our border, | |
747 y -= top_border_touch_calibration; | |
748 | |
749 // Check if we are in the grace area of the top side. | |
750 // Note: We might not want to do this when the gesture is locked? | |
751 if (y < 0 && y > -top_border_touch_calibration * kGraceAreaFraction) | |
752 y = 0; | |
753 | |
754 // Check if we are in the grace area of the bottom side. | |
755 // Note: We might not want to do this when the gesture is locked? | |
756 if (y > resolution_y - top_border_touch_calibration && | |
757 y < resolution_y - top_border_touch_calibration + | |
758 bottom_border_touch_calibration * kGraceAreaFraction) | |
759 y = resolution_y - top_border_touch_calibration; | |
760 // Scale the screen area back to the full resolution of the screen. | |
761 y = (y * resolution_y) / (resolution_y - (bottom_border_touch_calibration + | |
762 top_border_touch_calibration)); | |
763 } | |
764 // Set the modified coordinate back to the event. | |
765 return gfx::Point(x, y); | |
766 } | |
767 #endif // defined(USE_XI2_MT) | |
768 | |
769 } // namespace | 674 } // namespace |
770 | 675 |
771 namespace ui { | 676 namespace ui { |
772 | 677 |
773 void UpdateDeviceList() { | 678 void UpdateDeviceList() { |
774 Display* display = GetXDisplay(); | 679 Display* display = GetXDisplay(); |
775 DeviceListCacheX::GetInstance()->UpdateDeviceList(display); | 680 DeviceListCacheX::GetInstance()->UpdateDeviceList(display); |
776 CMTEventData::GetInstance()->UpdateDeviceList(display); | 681 CMTEventData::GetInstance()->UpdateDeviceList(display); |
777 TouchFactory::GetInstance()->UpdateDeviceList(display); | 682 TouchFactory::GetInstance()->UpdateDeviceList(display); |
778 ValuatorTracker::GetInstance()->SetupValuator(); | 683 ValuatorTracker::GetInstance()->SetupValuator(); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 XIDeviceEvent* xievent = | 864 XIDeviceEvent* xievent = |
960 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 865 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
961 | 866 |
962 #if defined(USE_XI2_MT) | 867 #if defined(USE_XI2_MT) |
963 // Touch event valuators aren't coordinates. | 868 // Touch event valuators aren't coordinates. |
964 // Return the |event_x|/|event_y| directly as event's position. | 869 // Return the |event_x|/|event_y| directly as event's position. |
965 if (xievent->evtype == XI_TouchBegin || | 870 if (xievent->evtype == XI_TouchBegin || |
966 xievent->evtype == XI_TouchUpdate || | 871 xievent->evtype == XI_TouchUpdate || |
967 xievent->evtype == XI_TouchEnd) | 872 xievent->evtype == XI_TouchEnd) |
968 // Note: Touch events are always touch screen events. | 873 // Note: Touch events are always touch screen events. |
969 return CalibrateTouchCoordinates(xievent); | 874 return gfx::Point(static_cast<int>(xievent->event_x), |
| 875 static_cast<int>(xievent->event_y)); |
970 #endif | 876 #endif |
971 // Read the position from the valuators, because the location reported in | 877 // Read the position from the valuators, because the location reported in |
972 // event_x/event_y seems to be different (and doesn't match for events | 878 // event_x/event_y seems to be different (and doesn't match for events |
973 // coming from slave device and master device) from the values in the | 879 // coming from slave device and master device) from the values in the |
974 // valuators. See more on crbug.com/103981. The position in the valuators | 880 // valuators. See more on crbug.com/103981. The position in the valuators |
975 // is in the global screen coordinates. But it is necessary to convert it | 881 // is in the global screen coordinates. But it is necessary to convert it |
976 // into the window's coordinates. If the valuator is not set, that means | 882 // into the window's coordinates. If the valuator is not set, that means |
977 // the value hasn't changed, and so we can use the value from | 883 // the value hasn't changed, and so we can use the value from |
978 // event_x/event_y (which are in the window's coordinates). | 884 // event_x/event_y (which are in the window's coordinates). |
979 double* valuators = xievent->valuators.values; | 885 double* valuators = xievent->valuators.values; |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 noop->xclient.format = 8; | 1117 noop->xclient.format = 8; |
1212 DCHECK(!noop->xclient.display); | 1118 DCHECK(!noop->xclient.display); |
1213 } | 1119 } |
1214 // Make sure we use atom from current xdisplay, which may | 1120 // Make sure we use atom from current xdisplay, which may |
1215 // change during the test. | 1121 // change during the test. |
1216 noop->xclient.message_type = GetNoopEventAtom(); | 1122 noop->xclient.message_type = GetNoopEventAtom(); |
1217 return noop; | 1123 return noop; |
1218 } | 1124 } |
1219 | 1125 |
1220 } // namespace ui | 1126 } // namespace ui |
OLD | NEW |