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

Side by Side Diff: ui/events/x/device_data_manager.cc

Issue 191223007: Move touch CTM from X into Chrome (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: fix events/BUILD.gn Created 6 years, 7 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
« no previous file with comments | « ui/events/x/device_data_manager.h ('k') | ui/events/x/events_x.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/events/x/device_data_manager.h" 5 #include "ui/events/x/device_data_manager.h"
6 6
7 #include <X11/extensions/XInput.h> 7 #include <X11/extensions/XInput.h>
8 #include <X11/extensions/XInput2.h> 8 #include <X11/extensions/XInput2.h>
9 #include <X11/Xlib.h> 9 #include <X11/Xlib.h>
10 10
11 #include "base/command_line.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/memory/singleton.h" 13 #include "base/memory/singleton.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "base/sys_info.h"
13 #include "ui/events/event_constants.h" 17 #include "ui/events/event_constants.h"
18 #include "ui/events/event_switches.h"
19 #include "ui/events/platform/platform_event_observer.h"
20 #include "ui/events/platform/x11/x11_event_source.h"
14 #include "ui/events/x/device_list_cache_x.h" 21 #include "ui/events/x/device_list_cache_x.h"
15 #include "ui/events/x/touch_factory_x11.h" 22 #include "ui/events/x/touch_factory_x11.h"
23 #include "ui/gfx/display.h"
24 #include "ui/gfx/point3_f.h"
16 #include "ui/gfx/x/x11_types.h" 25 #include "ui/gfx/x/x11_types.h"
17 26
18 // XIScrollClass was introduced in XI 2.1 so we need to define it here 27 // XIScrollClass was introduced in XI 2.1 so we need to define it here
19 // for backward-compatibility with older versions of XInput. 28 // for backward-compatibility with older versions of XInput.
20 #if !defined(XIScrollClass) 29 #if !defined(XIScrollClass)
21 #define XIScrollClass 3 30 #define XIScrollClass 3
22 #endif 31 #endif
23 32
24 // Multi-touch support was introduced in XI 2.2. Add XI event types here 33 // Multi-touch support was introduced in XI 2.2. Add XI event types here
25 // for backward-compatibility with older versions of XInput. 34 // for backward-compatibility with older versions of XInput.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 99
91 // Constants for checking if a data type lies in the range of CMT/Touch data 100 // Constants for checking if a data type lies in the range of CMT/Touch data
92 // types. 101 // types.
93 const int kCMTDataTypeStart = ui::DeviceDataManager::DT_CMT_SCROLL_X; 102 const int kCMTDataTypeStart = ui::DeviceDataManager::DT_CMT_SCROLL_X;
94 const int kCMTDataTypeEnd = ui::DeviceDataManager::DT_CMT_FINGER_COUNT; 103 const int kCMTDataTypeEnd = ui::DeviceDataManager::DT_CMT_FINGER_COUNT;
95 const int kTouchDataTypeStart = ui::DeviceDataManager::DT_TOUCH_MAJOR; 104 const int kTouchDataTypeStart = ui::DeviceDataManager::DT_TOUCH_MAJOR;
96 const int kTouchDataTypeEnd = ui::DeviceDataManager::DT_TOUCH_RAW_TIMESTAMP; 105 const int kTouchDataTypeEnd = ui::DeviceDataManager::DT_TOUCH_RAW_TIMESTAMP;
97 106
98 namespace ui { 107 namespace ui {
99 108
109 // Accomplishes 2 tasks concerning touch event calibration:
110 // 1. Being a message-pump observer,
111 // routes all the touch events to the X root window,
112 // where they can be calibrated later.
113 // 2. Has the Calibrate method that does the actual bezel calibration,
114 // when invoked from X root window's event dispatcher.
115 class DeviceDataManager::TouchEventCalibrate
116 : public ui::PlatformEventObserver {
117 public:
118 TouchEventCalibrate() : left_(0), right_(0), top_(0), bottom_(0) {
119 if (ui::PlatformEventSource::GetInstance())
120 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
121 #if defined(USE_XI2_MT)
122 std::vector<std::string> parts;
123 if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
124 switches::kTouchCalibration),
125 ",",
126 &parts) >= 4) {
127 if (!base::StringToInt(parts[0], &left_))
128 DLOG(ERROR) << "Incorrect left border calibration value passed.";
129 if (!base::StringToInt(parts[1], &right_))
130 DLOG(ERROR) << "Incorrect right border calibration value passed.";
131 if (!base::StringToInt(parts[2], &top_))
132 DLOG(ERROR) << "Incorrect top border calibration value passed.";
133 if (!base::StringToInt(parts[3], &bottom_))
134 DLOG(ERROR) << "Incorrect bottom border calibration value passed.";
135 }
136 #endif // defined(USE_XI2_MT)
137 }
138
139 virtual ~TouchEventCalibrate() {
140 if (ui::PlatformEventSource::GetInstance())
141 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
142 }
143
144 // Modify the location of the |event|,
145 // expanding it from |bounds| to (|bounds| + bezels).
146 // Required when touchscreen is bigger than screen (i.e. has bezels),
147 // because we receive events in touchscreen coordinates,
148 // which need to be expanded when converting to screen coordinates,
149 // so that location on bezels will be outside of screen area.
150 void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) {
151 #if defined(USE_XI2_MT)
152 int x = event->x();
153 int y = event->y();
154
155 if (!left_ && !right_ && !top_ && !bottom_)
156 return;
157
158 const int resolution_x = bounds.width();
159 const int resolution_y = bounds.height();
160 // The "grace area" (10% in this case) is to make it easier for the user to
161 // navigate to the corner.
162 const double kGraceAreaFraction = 0.1;
163 if (left_ || right_) {
164 // Offset the x position to the real
165 x -= left_;
166 // Check if we are in the grace area of the left side.
167 // Note: We might not want to do this when the gesture is locked?
168 if (x < 0 && x > -left_ * kGraceAreaFraction)
169 x = 0;
170 // Check if we are in the grace area of the right side.
171 // Note: We might not want to do this when the gesture is locked?
172 if (x > resolution_x - left_ &&
173 x < resolution_x - left_ + right_ * kGraceAreaFraction)
174 x = resolution_x - left_;
175 // Scale the screen area back to the full resolution of the screen.
176 x = (x * resolution_x) / (resolution_x - (right_ + left_));
177 }
178 if (top_ || bottom_) {
179 // When there is a top bezel we add our border,
180 y -= top_;
181
182 // Check if we are in the grace area of the top side.
183 // Note: We might not want to do this when the gesture is locked?
184 if (y < 0 && y > -top_ * kGraceAreaFraction)
185 y = 0;
186
187 // Check if we are in the grace area of the bottom side.
188 // Note: We might not want to do this when the gesture is locked?
189 if (y > resolution_y - top_ &&
190 y < resolution_y - top_ + bottom_ * kGraceAreaFraction)
191 y = resolution_y - top_;
192 // Scale the screen area back to the full resolution of the screen.
193 y = (y * resolution_y) / (resolution_y - (bottom_ + top_));
194 }
195
196 // Set the modified coordinate back to the event.
197 if (event->root_location() == event->location()) {
198 // Usually those will be equal,
199 // if not, I am not sure what the correct value should be.
200 event->set_root_location(gfx::Point(x, y));
201 }
202 event->set_location(gfx::Point(x, y));
203 #endif // defined(USE_XI2_MT)
204 }
205
206 private:
207 // ui::PlatformEventObserver:
208 virtual void WillProcessEvent(const ui::PlatformEvent& event) OVERRIDE {
209 #if defined(USE_XI2_MT)
210 if (event->type == GenericEvent &&
211 (event->xgeneric.evtype == XI_TouchBegin ||
212 event->xgeneric.evtype == XI_TouchUpdate ||
213 event->xgeneric.evtype == XI_TouchEnd)) {
214 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data);
215 LOG(ERROR) << "Raw " << xievent->event_x << " " << xievent->event_y
216 << " " << xievent->root_x << " " << xievent->root_y;
217 xievent->event = xievent->root;
218 xievent->event_x = xievent->root_x;
219 xievent->event_y = xievent->root_y;
220 }
221 #endif // defined(USE_XI2_MT)
222 }
223
224 virtual void DidProcessEvent(const ui::PlatformEvent& event) OVERRIDE {}
225
226 // The difference in screen's native resolution pixels between
227 // the border of the touchscreen and the border of the screen,
228 // aka bezel sizes.
229 int left_;
230 int right_;
231 int top_;
232 int bottom_;
233
234 DISALLOW_COPY_AND_ASSIGN(TouchEventCalibrate);
235 };
236
237 ////////////////////////////////////////////////////////////////////////////////
238 // DeviceDataManager
239
100 bool DeviceDataManager::IsCMTDataType(const int type) { 240 bool DeviceDataManager::IsCMTDataType(const int type) {
101 return (type >= kCMTDataTypeStart) && (type <= kCMTDataTypeEnd); 241 return (type >= kCMTDataTypeStart) && (type <= kCMTDataTypeEnd);
102 } 242 }
103 243
104 bool DeviceDataManager::IsTouchDataType(const int type) { 244 bool DeviceDataManager::IsTouchDataType(const int type) {
105 return (type >= kTouchDataTypeStart) && (type <= kTouchDataTypeEnd); 245 return (type >= kTouchDataTypeStart) && (type <= kTouchDataTypeEnd);
106 } 246 }
107 247
108 DeviceDataManager* DeviceDataManager::GetInstance() { 248 DeviceDataManager* DeviceDataManager::GetInstance() {
109 return Singleton<DeviceDataManager>::get(); 249 return Singleton<DeviceDataManager>::get();
110 } 250 }
111 251
112 DeviceDataManager::DeviceDataManager() 252 DeviceDataManager::DeviceDataManager()
113 : xi_opcode_(-1), 253 : xi_opcode_(-1),
114 atom_cache_(gfx::GetXDisplay(), kCachedAtoms), 254 atom_cache_(gfx::GetXDisplay(), kCachedAtoms),
115 button_map_count_(0) { 255 button_map_count_(0),
256 touch_calibrate_(new TouchEventCalibrate) {
116 CHECK(gfx::GetXDisplay()); 257 CHECK(gfx::GetXDisplay());
117 InitializeXInputInternal(); 258 InitializeXInputInternal();
118 259
119 // Make sure the sizes of enum and kCachedAtoms are aligned. 260 // Make sure the sizes of enum and kCachedAtoms are aligned.
120 CHECK(arraysize(kCachedAtoms) == static_cast<size_t>(DT_LAST_ENTRY) + 1); 261 CHECK(arraysize(kCachedAtoms) == static_cast<size_t>(DT_LAST_ENTRY) + 1);
121 UpdateDeviceList(gfx::GetXDisplay()); 262 UpdateDeviceList(gfx::GetXDisplay());
122 UpdateButtonMap(); 263 UpdateButtonMap();
264 for (int i = 0; i < kMaxDeviceNum; i++)
265 touch_device_to_display_map_[i] = gfx::Display::kInvalidDisplayID;
123 } 266 }
124 267
125 DeviceDataManager::~DeviceDataManager() { 268 DeviceDataManager::~DeviceDataManager() {
126 } 269 }
127 270
128 bool DeviceDataManager::InitializeXInputInternal() { 271 bool DeviceDataManager::InitializeXInputInternal() {
129 // Check if XInput is available on the system. 272 // Check if XInput is available on the system.
130 xi_opcode_ = -1; 273 xi_opcode_ = -1;
131 int opcode, event, error; 274 int opcode, event, error;
132 if (!XQueryExtension( 275 if (!XQueryExtension(
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 last_seen_valuator_[deviceid][j].resize(DT_LAST_ENTRY, 0); 770 last_seen_valuator_[deviceid][j].resize(DT_LAST_ENTRY, 0);
628 for (int j = start_valuator; j <= end_valuator; ++j) { 771 for (int j = start_valuator; j <= end_valuator; ++j) {
629 valuator_lookup_[deviceid][j] = valuator_count_[deviceid]; 772 valuator_lookup_[deviceid][j] = valuator_count_[deviceid];
630 data_type_lookup_[deviceid][valuator_count_[deviceid]] = j; 773 data_type_lookup_[deviceid][valuator_count_[deviceid]] = j;
631 valuator_min_[deviceid][j] = min_value; 774 valuator_min_[deviceid][j] = min_value;
632 valuator_max_[deviceid][j] = max_value; 775 valuator_max_[deviceid][j] = max_value;
633 valuator_count_[deviceid]++; 776 valuator_count_[deviceid]++;
634 } 777 }
635 } 778 }
636 779
780 void DeviceDataManager::CalibrateTouchEvent(TouchEvent* event,
781 int touch_device_id,
782 const gfx::Rect& bounds) {
783 #if defined(OS_CHROMEOS) && defined(USE_XI2_MT)
784 int64 touch_display_id = GetDisplayForTouchDevice(touch_device_id);
785 if (base::SysInfo::IsRunningOnChromeOS() &&
786 touch_display_id == gfx::Display::InternalDisplayId()) {
787 touch_calibrate_->Calibrate(event, bounds);
788 }
789 #endif // defined(OS_CHROMEOS) && defined(USE_XI2_MT)
790 }
791
792 void DeviceDataManager::ClearTouchTransformerRecord() {
793 for (int i = 0; i < kMaxDeviceNum; i++) {
794 touch_device_transformer_map_[i] = gfx::Transform();
795 touch_device_to_display_map_[i] = gfx::Display::kInvalidDisplayID;
796 }
797 }
798
799 bool DeviceDataManager::IsTouchDeviceIdValid(int touch_device_id) const {
800 return (touch_device_id > 0 && touch_device_id < kMaxDeviceNum);
801 }
802
803 void DeviceDataManager::UpdateTouchInfoForDisplay(
804 int64 display_id,
805 int touch_device_id,
806 const gfx::Transform& touch_transformer) {
807 if (IsTouchDeviceIdValid(touch_device_id)) {
808 touch_device_to_display_map_[touch_device_id] = display_id;
809 touch_device_transformer_map_[touch_device_id] = touch_transformer;
810 }
811 }
812
813 void DeviceDataManager::ApplyTouchTransformer(int touch_device_id,
814 float* x, float* y) {
815 if (IsTouchDeviceIdValid(touch_device_id)) {
816 gfx::Point3F point(*x, *y, 0.0);
817 const gfx::Transform& trans =
818 touch_device_transformer_map_[touch_device_id];
819 trans.TransformPoint(&point);
820 *x = point.x();
821 *y = point.y();
822 }
823 }
824
825 int64 DeviceDataManager::GetDisplayForTouchDevice(int touch_device_id) const {
826 if (IsTouchDeviceIdValid(touch_device_id))
827 return touch_device_to_display_map_[touch_device_id];
828 return gfx::Display::kInvalidDisplayID;
829 }
830
637 } // namespace ui 831 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/x/device_data_manager.h ('k') | ui/events/x/events_x.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698