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/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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 AXIS_LABEL_PROP_ABS_DBL_END_TIME, | 62 AXIS_LABEL_PROP_ABS_DBL_END_TIME, |
67 AXIS_LABEL_PROP_ABS_FLING_X, | 63 AXIS_LABEL_PROP_ABS_FLING_X, |
68 AXIS_LABEL_PROP_ABS_FLING_Y, | 64 AXIS_LABEL_PROP_ABS_FLING_Y, |
69 AXIS_LABEL_PROP_ABS_DBL_FLING_VX, | 65 AXIS_LABEL_PROP_ABS_DBL_FLING_VX, |
70 AXIS_LABEL_PROP_ABS_DBL_FLING_VY, | 66 AXIS_LABEL_PROP_ABS_DBL_FLING_VY, |
71 AXIS_LABEL_PROP_ABS_FLING_STATE, | 67 AXIS_LABEL_PROP_ABS_FLING_STATE, |
72 AXIS_LABEL_PROP_ABS_FINGER_COUNT, | 68 AXIS_LABEL_PROP_ABS_FINGER_COUNT, |
73 NULL | 69 NULL |
74 }; | 70 }; |
75 | 71 |
76 #if defined(USE_XI2_MT) | |
77 // If the calibration values were read, if this is true. | |
78 bool calibration_values_read = false; | |
79 | |
80 // The (positive) calibration values for the four border sides. | |
81 int left_border_touch_calibration = 0; | |
82 int top_border_touch_calibration = 0; | |
83 int right_border_touch_calibration = 0; | |
84 int bottom_border_touch_calibration = 0; | |
85 #endif | |
86 | |
87 // A class to support the detection of scroll events, using X11 valuators. | 72 // A class to support the detection of scroll events, using X11 valuators. |
88 class CMTEventData { | 73 class CMTEventData { |
89 public: | 74 public: |
90 // Returns the ScrollEventData singleton. | 75 // Returns the ScrollEventData singleton. |
91 static CMTEventData* GetInstance() { | 76 static CMTEventData* GetInstance() { |
92 return Singleton<CMTEventData>::get(); | 77 return Singleton<CMTEventData>::get(); |
93 } | 78 } |
94 | 79 |
95 // Updates the list of devices. | 80 // Updates the list of devices. |
96 void UpdateDeviceList(Display* display) { | 81 void UpdateDeviceList(Display* display) { |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 *xev, val, &default_value); | 624 *xev, val, &default_value); |
640 return default_value; | 625 return default_value; |
641 } | 626 } |
642 | 627 |
643 Atom GetNoopEventAtom() { | 628 Atom GetNoopEventAtom() { |
644 return XInternAtom( | 629 return XInternAtom( |
645 base::MessagePumpAuraX11::GetDefaultXDisplay(), | 630 base::MessagePumpAuraX11::GetDefaultXDisplay(), |
646 "noop", False); | 631 "noop", False); |
647 } | 632 } |
648 | 633 |
649 #if defined(USE_XI2_MT) | |
650 | 634 |
651 void ReadTouchCalibrationValues() { | |
652 calibration_values_read = true; | |
653 | |
654 std::vector<std::string> parts; | |
655 base::SplitString(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
656 switches::kTouchCalibration), ',', &parts); | |
657 if (parts.size() >= 4) { | |
658 if (!base::StringToInt(parts[0], &left_border_touch_calibration)) | |
659 DLOG(ERROR) << "Incorrect left border calibration value passed."; | |
660 if (!base::StringToInt(parts[1], &right_border_touch_calibration)) | |
661 DLOG(ERROR) << "Incorrect right border calibration value passed."; | |
662 if (!base::StringToInt(parts[2], &top_border_touch_calibration)) | |
663 DLOG(ERROR) << "Incorrect top border calibration value passed."; | |
664 if (!base::StringToInt(parts[3], &bottom_border_touch_calibration)) | |
665 DLOG(ERROR) << "Incorrect bottom border calibration value passed."; | |
666 } | |
667 } | |
668 | |
669 gfx::Point CalibrateTouchCoordinates( | |
670 const XIDeviceEvent* xievent) { | |
671 int x = static_cast<int>(xievent->event_x); | |
672 int y = static_cast<int>(xievent->event_y); | |
673 | |
674 if (!calibration_values_read) | |
675 ReadTouchCalibrationValues(); | |
676 | |
677 if (!left_border_touch_calibration && !right_border_touch_calibration && | |
678 !top_border_touch_calibration && !bottom_border_touch_calibration) | |
679 return gfx::Point(x, y); | |
680 | |
681 gfx::Rect bounds = | |
682 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().bounds_in_pixel(); | |
683 const int resolution_x = bounds.width(); | |
684 const int resolution_y = bounds.height(); | |
685 // The "grace area" (10% in this case) is to make it easier for the user to | |
686 // navigate to the corner. | |
687 const double kGraceAreaFraction = 0.1; | |
688 if (left_border_touch_calibration || right_border_touch_calibration) { | |
689 // Offset the x position to the real | |
690 x -= left_border_touch_calibration; | |
691 // Check if we are in the grace area of the left side. | |
692 // Note: We might not want to do this when the gesture is locked? | |
693 if (x < 0 && x > -left_border_touch_calibration * kGraceAreaFraction) | |
694 x = 0; | |
695 // Check if we are in the grace area of the right side. | |
696 // Note: We might not want to do this when the gesture is locked? | |
697 if (x > resolution_x - left_border_touch_calibration && | |
698 x < resolution_x - left_border_touch_calibration + | |
699 right_border_touch_calibration * kGraceAreaFraction) | |
700 x = resolution_x - left_border_touch_calibration; | |
701 // Scale the screen area back to the full resolution of the screen. | |
702 x = (x * resolution_x) / (resolution_x - (right_border_touch_calibration + | |
703 left_border_touch_calibration)); | |
704 } | |
705 if (top_border_touch_calibration || bottom_border_touch_calibration) { | |
706 // When there is a top bezel we add our border, | |
707 y -= top_border_touch_calibration; | |
708 | |
709 // Check if we are in the grace area of the top side. | |
710 // Note: We might not want to do this when the gesture is locked? | |
711 if (y < 0 && y > -top_border_touch_calibration * kGraceAreaFraction) | |
712 y = 0; | |
713 | |
714 // Check if we are in the grace area of the bottom side. | |
715 // Note: We might not want to do this when the gesture is locked? | |
716 if (y > resolution_y - top_border_touch_calibration && | |
717 y < resolution_y - top_border_touch_calibration + | |
718 bottom_border_touch_calibration * kGraceAreaFraction) | |
719 y = resolution_y - top_border_touch_calibration; | |
720 // Scale the screen area back to the full resolution of the screen. | |
721 y = (y * resolution_y) / (resolution_y - (bottom_border_touch_calibration + | |
722 top_border_touch_calibration)); | |
723 } | |
724 // Set the modified coordinate back to the event. | |
725 return gfx::Point(x, y); | |
726 } | |
727 #endif // defined(USE_XI2_MT) | |
728 | 635 |
729 } // namespace | 636 } // namespace |
730 | 637 |
731 namespace ui { | 638 namespace ui { |
732 | 639 |
733 void UpdateDeviceList() { | 640 void UpdateDeviceList() { |
734 Display* display = GetXDisplay(); | 641 Display* display = GetXDisplay(); |
735 DeviceListCacheX::GetInstance()->UpdateDeviceList(display); | 642 DeviceListCacheX::GetInstance()->UpdateDeviceList(display); |
736 CMTEventData::GetInstance()->UpdateDeviceList(display); | 643 CMTEventData::GetInstance()->UpdateDeviceList(display); |
737 TouchFactory::GetInstance()->UpdateDeviceList(display); | 644 TouchFactory::GetInstance()->UpdateDeviceList(display); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 XIDeviceEvent* xievent = | 826 XIDeviceEvent* xievent = |
920 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 827 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
921 | 828 |
922 #if defined(USE_XI2_MT) | 829 #if defined(USE_XI2_MT) |
923 // Touch event valuators aren't coordinates. | 830 // Touch event valuators aren't coordinates. |
924 // Return the |event_x|/|event_y| directly as event's position. | 831 // Return the |event_x|/|event_y| directly as event's position. |
925 if (xievent->evtype == XI_TouchBegin || | 832 if (xievent->evtype == XI_TouchBegin || |
926 xievent->evtype == XI_TouchUpdate || | 833 xievent->evtype == XI_TouchUpdate || |
927 xievent->evtype == XI_TouchEnd) | 834 xievent->evtype == XI_TouchEnd) |
928 // Note: Touch events are always touch screen events. | 835 // Note: Touch events are always touch screen events. |
929 return CalibrateTouchCoordinates(xievent); | 836 return gfx::Point(static_cast<int>(xievent->event_x), |
| 837 static_cast<int>(xievent->event_y)); |
930 #endif | 838 #endif |
931 // Read the position from the valuators, because the location reported in | 839 // Read the position from the valuators, because the location reported in |
932 // event_x/event_y seems to be different (and doesn't match for events | 840 // event_x/event_y seems to be different (and doesn't match for events |
933 // coming from slave device and master device) from the values in the | 841 // coming from slave device and master device) from the values in the |
934 // valuators. See more on crbug.com/103981. The position in the valuators | 842 // valuators. See more on crbug.com/103981. The position in the valuators |
935 // is in the global screen coordinates. But it is necessary to convert it | 843 // is in the global screen coordinates. But it is necessary to convert it |
936 // into the window's coordinates. If the valuator is not set, that means | 844 // into the window's coordinates. If the valuator is not set, that means |
937 // the value hasn't changed, and so we can use the value from | 845 // the value hasn't changed, and so we can use the value from |
938 // event_x/event_y (which are in the window's coordinates). | 846 // event_x/event_y (which are in the window's coordinates). |
939 double* valuators = xievent->valuators.values; | 847 double* valuators = xievent->valuators.values; |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 noop->xclient.format = 8; | 1067 noop->xclient.format = 8; |
1160 DCHECK(!noop->xclient.display); | 1068 DCHECK(!noop->xclient.display); |
1161 } | 1069 } |
1162 // Make sure we use atom from current xdisplay, which may | 1070 // Make sure we use atom from current xdisplay, which may |
1163 // change during the test. | 1071 // change during the test. |
1164 noop->xclient.message_type = GetNoopEventAtom(); | 1072 noop->xclient.message_type = GetNoopEventAtom(); |
1165 return noop; | 1073 return noop; |
1166 } | 1074 } |
1167 | 1075 |
1168 } // namespace ui | 1076 } // namespace ui |
OLD | NEW |