| 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 "content/browser/gamepad/platform_data_fetcher_linux.h" | 5 #include "content/browser/gamepad/platform_data_fetcher_linux.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <libudev.h> | 8 #include <libudev.h> |
| 9 #include <linux/joystick.h> | 9 #include <linux/joystick.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 namespace content { | 64 namespace content { |
| 65 | 65 |
| 66 using WebKit::WebGamepad; | 66 using WebKit::WebGamepad; |
| 67 using WebKit::WebGamepads; | 67 using WebKit::WebGamepads; |
| 68 | 68 |
| 69 GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() { | 69 GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() { |
| 70 for (size_t i = 0; i < arraysize(device_fds_); ++i) | 70 for (size_t i = 0; i < arraysize(device_fds_); ++i) |
| 71 device_fds_[i] = -1; | 71 device_fds_[i] = -1; |
| 72 memset(mappers_, 0, sizeof(mappers_)); | 72 memset(mappers_, 0, sizeof(mappers_)); |
| 73 | 73 |
| 74 udev_ = udev_new(); | 74 int ret = udev_monitor_filter_add_match_subsystem_devtype(monitor(), |
| 75 CHECK(udev_); | |
| 76 | |
| 77 monitor_ = udev_monitor_new_from_netlink(udev_, "udev"); | |
| 78 CHECK(monitor_); | |
| 79 int ret = udev_monitor_filter_add_match_subsystem_devtype(monitor_, | |
| 80 kInputSubsystem, | 75 kInputSubsystem, |
| 81 NULL); | 76 NULL); |
| 82 CHECK_EQ(0, ret); | 77 CHECK_EQ(0, ret); |
| 83 ret = udev_monitor_enable_receiving(monitor_); | 78 StartMonitoring(); |
| 84 CHECK_EQ(0, ret); | |
| 85 monitor_fd_ = udev_monitor_get_fd(monitor_); | |
| 86 CHECK_GE(monitor_fd_, 0); | |
| 87 bool success = MessageLoopForIO::current()->WatchFileDescriptor(monitor_fd_, | |
| 88 true, MessageLoopForIO::WATCH_READ, &monitor_watcher_, this); | |
| 89 CHECK(success); | |
| 90 | 79 |
| 91 EnumerateDevices(); | 80 EnumerateDevices(); |
| 92 } | 81 } |
| 93 | 82 |
| 94 GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() { | 83 GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() { |
| 95 monitor_watcher_.StopWatchingFileDescriptor(); | |
| 96 udev_monitor_unref(monitor_); | |
| 97 udev_unref(udev_); | |
| 98 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) | 84 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) |
| 99 CloseFileDescriptorIfValid(device_fds_[i]); | 85 CloseFileDescriptorIfValid(device_fds_[i]); |
| 100 } | 86 } |
| 101 | 87 |
| 102 void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) { | 88 void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) { |
| 103 TRACE_EVENT0("GAMEPAD", "GetGamepadData"); | 89 TRACE_EVENT0("GAMEPAD", "GetGamepadData"); |
| 104 | 90 |
| 105 data_.length = WebGamepads::itemsLengthCap; | 91 data_.length = WebGamepads::itemsLengthCap; |
| 106 | 92 |
| 107 // Update our internal state. | 93 // Update our internal state. |
| 108 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { | 94 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { |
| 109 if (device_fds_[i] >= 0) { | 95 if (device_fds_[i] >= 0) { |
| 110 ReadDeviceData(i); | 96 ReadDeviceData(i); |
| 111 } | 97 } |
| 112 } | 98 } |
| 113 | 99 |
| 114 // Copy to the current state to the output buffer, using the mapping | 100 // Copy to the current state to the output buffer, using the mapping |
| 115 // function, if there is one available. | 101 // function, if there is one available. |
| 116 pads->length = data_.length; | 102 pads->length = data_.length; |
| 117 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { | 103 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { |
| 118 if (mappers_[i]) | 104 if (mappers_[i]) |
| 119 mappers_[i](data_.items[i], &pads->items[i]); | 105 mappers_[i](data_.items[i], &pads->items[i]); |
| 120 else | 106 else |
| 121 pads->items[i] = data_.items[i]; | 107 pads->items[i] = data_.items[i]; |
| 122 } | 108 } |
| 123 } | 109 } |
| 124 | 110 |
| 125 void GamepadPlatformDataFetcherLinux::OnFileCanReadWithoutBlocking(int fd) { | 111 void GamepadPlatformDataFetcherLinux::Notify(udev_device* device) { |
| 126 // Events occur when devices attached to the system are added, removed, or | 112 RefreshDevice(device); |
| 127 // change state. udev_monitor_receive_device() will return a device object | |
| 128 // representing the device which changed and what type of change occured. | |
| 129 DCHECK_EQ(monitor_fd_, fd); | |
| 130 udev_device* dev = udev_monitor_receive_device(monitor_); | |
| 131 if (!dev) | |
| 132 return; | |
| 133 RefreshDevice(dev); | |
| 134 udev_device_unref(dev); | |
| 135 } | |
| 136 | |
| 137 void GamepadPlatformDataFetcherLinux::OnFileCanWriteWithoutBlocking(int fd) { | |
| 138 } | 113 } |
| 139 | 114 |
| 140 // Used during enumeration, and monitor notifications. | 115 // Used during enumeration, and monitor notifications. |
| 141 void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { | 116 void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { |
| 142 int index; | 117 int index; |
| 143 std::string node_path; | 118 std::string node_path; |
| 144 if (IsGamepad(dev, &index, &node_path)) { | 119 if (IsGamepad(dev, &index, &node_path)) { |
| 145 int& device_fd = device_fds_[index]; | 120 int& device_fd = device_fds_[index]; |
| 146 WebGamepad& pad = data_.items[index]; | 121 WebGamepad& pad = data_.items[index]; |
| 147 GamepadStandardMappingFunction& mapper = mappers_[index]; | 122 GamepadStandardMappingFunction& mapper = mappers_[index]; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id); | 191 TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id); |
| 217 string16 tmp16 = UTF8ToUTF16(id); | 192 string16 tmp16 = UTF8ToUTF16(id); |
| 218 memset(pad.id, 0, sizeof(pad.id)); | 193 memset(pad.id, 0, sizeof(pad.id)); |
| 219 tmp16.copy(pad.id, arraysize(pad.id) - 1); | 194 tmp16.copy(pad.id, arraysize(pad.id) - 1); |
| 220 | 195 |
| 221 pad.connected = true; | 196 pad.connected = true; |
| 222 } | 197 } |
| 223 } | 198 } |
| 224 | 199 |
| 225 void GamepadPlatformDataFetcherLinux::EnumerateDevices() { | 200 void GamepadPlatformDataFetcherLinux::EnumerateDevices() { |
| 226 udev_enumerate* enumerate = udev_enumerate_new(udev_); | 201 udev_enumerate* enumerate = udev_enumerate_new(udev_handle()); |
| 227 if (!enumerate) | 202 if (!enumerate) |
| 228 return; | 203 return; |
| 229 int ret = udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem); | 204 int ret = udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem); |
| 230 if (ret != 0) | 205 if (ret != 0) |
| 231 return; | 206 return; |
| 232 ret = udev_enumerate_scan_devices(enumerate); | 207 ret = udev_enumerate_scan_devices(enumerate); |
| 233 if (ret != 0) | 208 if (ret != 0) |
| 234 return; | 209 return; |
| 235 | 210 |
| 236 udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); | 211 udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); |
| 237 for (udev_list_entry* dev_list_entry = devices; | 212 for (udev_list_entry* dev_list_entry = devices; |
| 238 dev_list_entry != NULL; | 213 dev_list_entry != NULL; |
| 239 dev_list_entry = udev_list_entry_get_next(dev_list_entry)) { | 214 dev_list_entry = udev_list_entry_get_next(dev_list_entry)) { |
| 240 // Get the filename of the /sys entry for the device and create a | 215 // Get the filename of the /sys entry for the device and create a |
| 241 // udev_device object (dev) representing it | 216 // udev_device object (dev) representing it |
| 242 const char* path = udev_list_entry_get_name(dev_list_entry); | 217 const char* path = udev_list_entry_get_name(dev_list_entry); |
| 243 udev_device* dev = udev_device_new_from_syspath(udev_, path); | 218 udev_device* dev = udev_device_new_from_syspath(udev_handle(), path); |
| 244 if (!dev) | 219 if (!dev) |
| 245 continue; | 220 continue; |
| 246 RefreshDevice(dev); | 221 RefreshDevice(dev); |
| 247 udev_device_unref(dev); | 222 udev_device_unref(dev); |
| 248 } | 223 } |
| 249 // Free the enumerator object | 224 // Free the enumerator object |
| 250 udev_enumerate_unref(enumerate); | 225 udev_enumerate_unref(enumerate); |
| 251 } | 226 } |
| 252 | 227 |
| 253 void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) { | 228 void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 275 continue; | 250 continue; |
| 276 pad.buttons[item] = event.value ? 1.0 : 0.0; | 251 pad.buttons[item] = event.value ? 1.0 : 0.0; |
| 277 if (item >= pad.buttonsLength) | 252 if (item >= pad.buttonsLength) |
| 278 pad.buttonsLength = item + 1; | 253 pad.buttonsLength = item + 1; |
| 279 } | 254 } |
| 280 pad.timestamp = event.time; | 255 pad.timestamp = event.time; |
| 281 } | 256 } |
| 282 } | 257 } |
| 283 | 258 |
| 284 } // namespace content | 259 } // namespace content |
| OLD | NEW |