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

Side by Side Diff: ui/events/platform/x11/x11_hotplug_event_handler.cc

Issue 2914103002: Remove usages of XInternAtom (Closed)
Patch Set: Address sadrul and sergeyu comments Created 3 years, 6 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/platform/x11/x11_hotplug_event_handler.h ('k') | ui/gfx/icc_profile_x11.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/platform/x11/x11_hotplug_event_handler.h" 5 #include "ui/events/platform/x11/x11_hotplug_event_handler.h"
6 6
7 #include <stdint.h> 7 #include <stdint.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/Xatom.h> 10 #include <X11/Xatom.h>
11 11
12 #include <algorithm> 12 #include <algorithm>
13 #include <cmath> 13 #include <cmath>
14 #include <set> 14 #include <set>
15 #include <string> 15 #include <string>
16 #include <vector> 16 #include <vector>
17 17
18 #include "base/bind.h" 18 #include "base/bind.h"
19 #include "base/command_line.h" 19 #include "base/command_line.h"
20 #include "base/location.h" 20 #include "base/location.h"
21 #include "base/logging.h" 21 #include "base/logging.h"
22 #include "base/process/launch.h" 22 #include "base/process/launch.h"
23 #include "base/single_thread_task_runner.h" 23 #include "base/single_thread_task_runner.h"
24 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
25 #include "base/sys_info.h" 25 #include "base/sys_info.h"
26 #include "base/threading/thread_task_runner_handle.h" 26 #include "base/threading/thread_task_runner_handle.h"
27 #include "base/threading/worker_pool.h" 27 #include "base/threading/worker_pool.h"
28 #include "ui/base/x/x11_util.h"
28 #include "ui/events/devices/device_data_manager.h" 29 #include "ui/events/devices/device_data_manager.h"
29 #include "ui/events/devices/device_hotplug_event_observer.h" 30 #include "ui/events/devices/device_hotplug_event_observer.h"
30 #include "ui/events/devices/device_util_linux.h" 31 #include "ui/events/devices/device_util_linux.h"
31 #include "ui/events/devices/input_device.h" 32 #include "ui/events/devices/input_device.h"
32 #include "ui/events/devices/touchscreen_device.h" 33 #include "ui/events/devices/touchscreen_device.h"
34 #include "ui/gfx/x/x11_atom_cache.h"
33 #include "ui/gfx/x/x11_types.h" 35 #include "ui/gfx/x/x11_types.h"
34 36
35 #ifndef XI_PROP_PRODUCT_ID 37 #ifndef XI_PROP_PRODUCT_ID
36 #define XI_PROP_PRODUCT_ID "Device Product ID" 38 #define XI_PROP_PRODUCT_ID "Device Product ID"
37 #endif 39 #endif
38 40
39 namespace ui { 41 namespace ui {
40 42
41 namespace { 43 namespace {
42 44
43 // Names of all known internal devices that should not be considered as 45 // Names of all known internal devices that should not be considered as
44 // keyboards. 46 // keyboards.
45 // TODO(rsadam@): Identify these devices using udev rules. (Crbug.com/420728.) 47 // TODO(rsadam@): Identify these devices using udev rules. (Crbug.com/420728.)
46 const char* kKnownInvalidKeyboardDeviceNames[] = {"Power Button", 48 const char* kKnownInvalidKeyboardDeviceNames[] = {"Power Button",
47 "Sleep Button", 49 "Sleep Button",
48 "Video Bus", 50 "Video Bus",
49 "gpio-keys.5", 51 "gpio-keys.5",
50 "gpio-keys.12", 52 "gpio-keys.12",
51 "ROCKCHIP-I2S Headset Jack"}; 53 "ROCKCHIP-I2S Headset Jack"};
52 54
53 const char* kCachedAtomList[] = {
54 "Abs MT Position X",
55 "Abs MT Position Y",
56 XI_KEYBOARD,
57 XI_MOUSE,
58 XI_TOUCHPAD,
59 XI_TOUCHSCREEN,
60 XI_PROP_PRODUCT_ID,
61 NULL,
62 };
63
64 enum DeviceType { 55 enum DeviceType {
65 DEVICE_TYPE_KEYBOARD, 56 DEVICE_TYPE_KEYBOARD,
66 DEVICE_TYPE_MOUSE, 57 DEVICE_TYPE_MOUSE,
67 DEVICE_TYPE_TOUCHPAD, 58 DEVICE_TYPE_TOUCHPAD,
68 DEVICE_TYPE_TOUCHSCREEN, 59 DEVICE_TYPE_TOUCHSCREEN,
69 DEVICE_TYPE_OTHER 60 DEVICE_TYPE_OTHER
70 }; 61 };
71 62
72 typedef base::Callback<void(const std::vector<InputDevice>&)> 63 typedef base::Callback<void(const std::vector<InputDevice>&)>
73 KeyboardDeviceCallback; 64 KeyboardDeviceCallback;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 } 190 }
200 191
201 base::FilePath GetDevicePath(XDisplay* dpy, const XIDeviceInfo& device) { 192 base::FilePath GetDevicePath(XDisplay* dpy, const XIDeviceInfo& device) {
202 // Skip the main pointer and keyboard since XOpenDevice() generates a 193 // Skip the main pointer and keyboard since XOpenDevice() generates a
203 // BadDevice error when passed these devices. 194 // BadDevice error when passed these devices.
204 if (device.use == XIMasterPointer || device.use == XIMasterKeyboard) 195 if (device.use == XIMasterPointer || device.use == XIMasterKeyboard)
205 return base::FilePath(); 196 return base::FilePath();
206 197
207 // Input device has a property "Device Node" pointing to its dev input node, 198 // Input device has a property "Device Node" pointing to its dev input node,
208 // e.g. Device Node (250): "/dev/input/event8" 199 // e.g. Device Node (250): "/dev/input/event8"
209 Atom device_node = XInternAtom(dpy, "Device Node", False); 200 Atom device_node = ui::X11AtomCache::GetInstance()->GetAtom("Device Node");
210 if (device_node == None) 201 if (device_node == None)
211 return base::FilePath(); 202 return base::FilePath();
212 203
213 Atom actual_type; 204 Atom actual_type;
214 int actual_format; 205 int actual_format;
215 unsigned long nitems, bytes_after; 206 unsigned long nitems, bytes_after;
216 unsigned char* data; 207 unsigned char* data;
217 XDevice* dev = XOpenDevice(dpy, device.deviceid); 208 XDevice* dev = XOpenDevice(dpy, device.deviceid);
218 209
219 // Sometimes XOpenDevice() doesn't return null but the contents aren't valid. 210 // Sometimes XOpenDevice() doesn't return null but the contents aren't valid.
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 void OnTouchpadDevices(const std::vector<InputDevice>& devices) { 393 void OnTouchpadDevices(const std::vector<InputDevice>& devices) {
403 GetHotplugEventObserver()->OnTouchpadDevicesUpdated(devices); 394 GetHotplugEventObserver()->OnTouchpadDevicesUpdated(devices);
404 } 395 }
405 396
406 void OnHotplugFinished() { 397 void OnHotplugFinished() {
407 GetHotplugEventObserver()->OnDeviceListsComplete(); 398 GetHotplugEventObserver()->OnDeviceListsComplete();
408 } 399 }
409 400
410 } // namespace 401 } // namespace
411 402
412 X11HotplugEventHandler::X11HotplugEventHandler() 403 X11HotplugEventHandler::X11HotplugEventHandler() {}
413 : atom_cache_(gfx::GetXDisplay(), kCachedAtomList) {
414 }
415 404
416 X11HotplugEventHandler::~X11HotplugEventHandler() { 405 X11HotplugEventHandler::~X11HotplugEventHandler() {
417 } 406 }
418 407
419 void X11HotplugEventHandler::OnHotplugEvent() { 408 void X11HotplugEventHandler::OnHotplugEvent() {
420 Display* display = gfx::GetXDisplay(); 409 Display* display = gfx::GetXDisplay();
421 const XDeviceList& device_list_xi = 410 const XDeviceList& device_list_xi =
422 DeviceListCacheX11::GetInstance()->GetXDeviceList(display); 411 DeviceListCacheX11::GetInstance()->GetXDeviceList(display);
423 const XIDeviceList& device_list_xi2 = 412 const XIDeviceList& device_list_xi2 =
424 DeviceListCacheX11::GetInstance()->GetXI2DeviceList(display); 413 DeviceListCacheX11::GetInstance()->GetXI2DeviceList(display);
425 414
426 const int kMaxDeviceNum = 128; 415 const int kMaxDeviceNum = 128;
427 DeviceType device_types[kMaxDeviceNum]; 416 DeviceType device_types[kMaxDeviceNum];
428 for (int i = 0; i < kMaxDeviceNum; ++i) 417 for (int i = 0; i < kMaxDeviceNum; ++i)
429 device_types[i] = DEVICE_TYPE_OTHER; 418 device_types[i] = DEVICE_TYPE_OTHER;
430 419
431 for (int i = 0; i < device_list_xi.count; ++i) { 420 for (int i = 0; i < device_list_xi.count; ++i) {
432 int id = device_list_xi[i].id; 421 int id = device_list_xi[i].id;
433 if (id < 0 || id >= kMaxDeviceNum) 422 if (id < 0 || id >= kMaxDeviceNum)
434 continue; 423 continue;
435 424
436 Atom type = device_list_xi[i].type; 425 Atom type = device_list_xi[i].type;
437 if (type == atom_cache_.GetAtom(XI_KEYBOARD)) 426 if (type == GetAtom(XI_KEYBOARD))
438 device_types[id] = DEVICE_TYPE_KEYBOARD; 427 device_types[id] = DEVICE_TYPE_KEYBOARD;
439 else if (type == atom_cache_.GetAtom(XI_MOUSE)) 428 else if (type == GetAtom(XI_MOUSE))
440 device_types[id] = DEVICE_TYPE_MOUSE; 429 device_types[id] = DEVICE_TYPE_MOUSE;
441 else if (type == atom_cache_.GetAtom(XI_TOUCHPAD)) 430 else if (type == GetAtom(XI_TOUCHPAD))
442 device_types[id] = DEVICE_TYPE_TOUCHPAD; 431 device_types[id] = DEVICE_TYPE_TOUCHPAD;
443 else if (type == atom_cache_.GetAtom(XI_TOUCHSCREEN)) 432 else if (type == GetAtom(XI_TOUCHSCREEN))
444 device_types[id] = DEVICE_TYPE_TOUCHSCREEN; 433 device_types[id] = DEVICE_TYPE_TOUCHSCREEN;
445 } 434 }
446 435
447 std::vector<DeviceInfo> device_infos; 436 std::vector<DeviceInfo> device_infos;
448 for (int i = 0; i < device_list_xi2.count; ++i) { 437 for (int i = 0; i < device_list_xi2.count; ++i) {
449 const XIDeviceInfo& device = device_list_xi2[i]; 438 const XIDeviceInfo& device = device_list_xi2[i];
450 if (!device.enabled || IsTestDevice(device.name)) 439 if (!device.enabled || IsTestDevice(device.name))
451 continue; 440 continue;
452 441
453 DeviceType device_type = 442 DeviceType device_type =
454 (device.deviceid >= 0 && device.deviceid < kMaxDeviceNum) 443 (device.deviceid >= 0 && device.deviceid < kMaxDeviceNum)
455 ? device_types[device.deviceid] 444 ? device_types[device.deviceid]
456 : DEVICE_TYPE_OTHER; 445 : DEVICE_TYPE_OTHER;
457 446
458 // Obtain the USB-style vendor and product identifiers. 447 // Obtain the USB-style vendor and product identifiers.
459 // (On Linux, XI2 makes this available for all evdev devices. 448 // (On Linux, XI2 makes this available for all evdev devices.
460 uint32_t* product_info; 449 uint32_t* product_info;
461 Atom type; 450 Atom type;
462 int format_return; 451 int format_return;
463 unsigned long num_items_return; 452 unsigned long num_items_return;
464 unsigned long bytes_after_return; 453 unsigned long bytes_after_return;
465 uint16_t vendor = 0; 454 uint16_t vendor = 0;
466 uint16_t product = 0; 455 uint16_t product = 0;
467 if (XIGetProperty(gfx::GetXDisplay(), device.deviceid, 456 if (XIGetProperty(gfx::GetXDisplay(), device.deviceid,
468 atom_cache_.GetAtom(XI_PROP_PRODUCT_ID), 0, 2, 0, 457 GetAtom(XI_PROP_PRODUCT_ID), 0, 2, 0, XA_INTEGER, &type,
469 XA_INTEGER, &type, &format_return, &num_items_return, 458 &format_return, &num_items_return, &bytes_after_return,
470 &bytes_after_return,
471 reinterpret_cast<unsigned char**>(&product_info)) == 0 && 459 reinterpret_cast<unsigned char**>(&product_info)) == 0 &&
472 product_info) { 460 product_info) {
473 if (num_items_return == 2) { 461 if (num_items_return == 2) {
474 vendor = product_info[0]; 462 vendor = product_info[0];
475 product = product_info[1]; 463 product = product_info[1];
476 } 464 }
477 XFree(product_info); 465 XFree(product_info);
478 } 466 }
479 467
480 device_infos.push_back(DeviceInfo( 468 device_infos.push_back(DeviceInfo(
481 device, device_type, GetDevicePath(display, device), vendor, product)); 469 device, device_type, GetDevicePath(display, device), vendor, product));
482 } 470 }
483 471
484 // X11 is not thread safe, so first get all the required state. 472 // X11 is not thread safe, so first get all the required state.
485 DisplayState display_state; 473 DisplayState display_state;
486 display_state.mt_position_x = atom_cache_.GetAtom("Abs MT Position X"); 474 display_state.mt_position_x = GetAtom("Abs MT Position X");
487 display_state.mt_position_y = atom_cache_.GetAtom("Abs MT Position Y"); 475 display_state.mt_position_y = GetAtom("Abs MT Position Y");
488 476
489 UiCallbacks callbacks; 477 UiCallbacks callbacks;
490 callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices); 478 callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices);
491 callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices); 479 callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices);
492 callbacks.mouse_callback = base::Bind(&OnMouseDevices); 480 callbacks.mouse_callback = base::Bind(&OnMouseDevices);
493 callbacks.touchpad_callback = base::Bind(&OnTouchpadDevices); 481 callbacks.touchpad_callback = base::Bind(&OnTouchpadDevices);
494 callbacks.hotplug_finished_callback = base::Bind(&OnHotplugFinished); 482 callbacks.hotplug_finished_callback = base::Bind(&OnHotplugFinished);
495 483
496 // Parsing the device information may block, so delegate the operation to a 484 // Parsing the device information may block, so delegate the operation to a
497 // worker thread. Once the device information is extracted the parsed devices 485 // worker thread. Once the device information is extracted the parsed devices
498 // will be returned via the callbacks. 486 // will be returned via the callbacks.
499 base::WorkerPool::PostTask( 487 base::WorkerPool::PostTask(
500 FROM_HERE, 488 FROM_HERE,
501 base::Bind(&HandleHotplugEventInWorker, device_infos, display_state, 489 base::Bind(&HandleHotplugEventInWorker, device_infos, display_state,
502 base::ThreadTaskRunnerHandle::Get(), callbacks), 490 base::ThreadTaskRunnerHandle::Get(), callbacks),
503 true /* task_is_slow */); 491 true /* task_is_slow */);
504 } 492 }
505 493
506 } // namespace ui 494 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/platform/x11/x11_hotplug_event_handler.h ('k') | ui/gfx/icc_profile_x11.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698