| 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 |