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 |