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