OLD | NEW |
1 // Copyright (c) 2011 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/data_fetcher_mac.h" | 5 #include "content/browser/gamepad/platform_data_fetcher_mac.h" |
6 | 6 |
7 #include "base/mac/foundation_util.h" | 7 #include "base/mac/foundation_util.h" |
8 #include "base/memory/scoped_nsobject.h" | 8 #include "base/memory/scoped_nsobject.h" |
9 #include "base/string16.h" | 9 #include "base/string16.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 | 12 |
13 #include <IOKit/hid/IOHIDKeys.h> | 13 #include <IOKit/hid/IOHIDKeys.h> |
14 #import <Foundation/Foundation.h> | 14 #import <Foundation/Foundation.h> |
15 | 15 |
(...skipping 18 matching lines...) Expand all Loading... |
34 const uint32_t kGenericDesktopUsagePage = 0x01; | 34 const uint32_t kGenericDesktopUsagePage = 0x01; |
35 const uint32_t kButtonUsagePage = 0x09; | 35 const uint32_t kButtonUsagePage = 0x09; |
36 const uint32_t kJoystickUsageNumber = 0x04; | 36 const uint32_t kJoystickUsageNumber = 0x04; |
37 const uint32_t kGameUsageNumber = 0x05; | 37 const uint32_t kGameUsageNumber = 0x05; |
38 const uint32_t kMultiAxisUsageNumber = 0x08; | 38 const uint32_t kMultiAxisUsageNumber = 0x08; |
39 const uint32_t kAxisMinimumUsageNumber = 0x30; | 39 const uint32_t kAxisMinimumUsageNumber = 0x30; |
40 const uint32_t kAxisMaximumUsageNumber = 0x35; | 40 const uint32_t kAxisMaximumUsageNumber = 0x35; |
41 | 41 |
42 } // namespace | 42 } // namespace |
43 | 43 |
44 GamepadDataFetcherMac::GamepadDataFetcherMac() : enabled_(true) { | 44 GamepadPlatformDataFetcherMac::GamepadPlatformDataFetcherMac() |
| 45 : enabled_(true) { |
45 hid_manager_ref_.reset(IOHIDManagerCreate(kCFAllocatorDefault, | 46 hid_manager_ref_.reset(IOHIDManagerCreate(kCFAllocatorDefault, |
46 kIOHIDOptionsTypeNone)); | 47 kIOHIDOptionsTypeNone)); |
47 if (CFGetTypeID(hid_manager_ref_) != IOHIDManagerGetTypeID()) { | 48 if (CFGetTypeID(hid_manager_ref_) != IOHIDManagerGetTypeID()) { |
48 enabled_ = false; | 49 enabled_ = false; |
49 return; | 50 return; |
50 } | 51 } |
51 | 52 |
52 scoped_nsobject<NSArray> criteria([[NSArray alloc] initWithObjects: | 53 scoped_nsobject<NSArray> criteria([[NSArray alloc] initWithObjects: |
53 DeviceMatching(kGenericDesktopUsagePage, kJoystickUsageNumber), | 54 DeviceMatching(kGenericDesktopUsagePage, kJoystickUsageNumber), |
54 DeviceMatching(kGenericDesktopUsagePage, kGameUsageNumber), | 55 DeviceMatching(kGenericDesktopUsagePage, kGameUsageNumber), |
55 DeviceMatching(kGenericDesktopUsagePage, kMultiAxisUsageNumber), | 56 DeviceMatching(kGenericDesktopUsagePage, kMultiAxisUsageNumber), |
56 nil]); | 57 nil]); |
57 IOHIDManagerSetDeviceMatchingMultiple( | 58 IOHIDManagerSetDeviceMatchingMultiple( |
58 hid_manager_ref_, | 59 hid_manager_ref_, |
59 base::mac::NSToCFCast(criteria)); | 60 base::mac::NSToCFCast(criteria)); |
60 | 61 |
61 RegisterForNotifications(); | 62 RegisterForNotifications(); |
62 } | 63 } |
63 | 64 |
64 void GamepadDataFetcherMac::RegisterForNotifications() { | 65 void GamepadPlatformDataFetcherMac::RegisterForNotifications() { |
65 // Register for plug/unplug notifications. | 66 // Register for plug/unplug notifications. |
66 IOHIDManagerRegisterDeviceMatchingCallback( | 67 IOHIDManagerRegisterDeviceMatchingCallback( |
67 hid_manager_ref_, | 68 hid_manager_ref_, |
68 &DeviceAddCallback, | 69 &DeviceAddCallback, |
69 this); | 70 this); |
70 IOHIDManagerRegisterDeviceRemovalCallback( | 71 IOHIDManagerRegisterDeviceRemovalCallback( |
71 hid_manager_ref_, | 72 hid_manager_ref_, |
72 DeviceRemoveCallback, | 73 DeviceRemoveCallback, |
73 this); | 74 this); |
74 | 75 |
75 // Register for value change notifications. | 76 // Register for value change notifications. |
76 IOHIDManagerRegisterInputValueCallback( | 77 IOHIDManagerRegisterInputValueCallback( |
77 hid_manager_ref_, | 78 hid_manager_ref_, |
78 ValueChangedCallback, | 79 ValueChangedCallback, |
79 this); | 80 this); |
80 | 81 |
81 IOHIDManagerScheduleWithRunLoop( | 82 IOHIDManagerScheduleWithRunLoop( |
82 hid_manager_ref_, | 83 hid_manager_ref_, |
83 CFRunLoopGetMain(), | 84 CFRunLoopGetMain(), |
84 kCFRunLoopDefaultMode); | 85 kCFRunLoopDefaultMode); |
85 | 86 |
86 enabled_ = IOHIDManagerOpen(hid_manager_ref_, | 87 enabled_ = IOHIDManagerOpen(hid_manager_ref_, |
87 kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess; | 88 kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess; |
88 } | 89 } |
89 | 90 |
90 void GamepadDataFetcherMac::UnregisterFromNotifications() { | 91 void GamepadPlatformDataFetcherMac::UnregisterFromNotifications() { |
91 IOHIDManagerUnscheduleFromRunLoop( | 92 IOHIDManagerUnscheduleFromRunLoop( |
92 hid_manager_ref_, | 93 hid_manager_ref_, |
93 CFRunLoopGetCurrent(), | 94 CFRunLoopGetCurrent(), |
94 kCFRunLoopDefaultMode); | 95 kCFRunLoopDefaultMode); |
95 IOHIDManagerClose(hid_manager_ref_, kIOHIDOptionsTypeNone); | 96 IOHIDManagerClose(hid_manager_ref_, kIOHIDOptionsTypeNone); |
96 } | 97 } |
97 | 98 |
98 void GamepadDataFetcherMac::PauseHint(bool pause) { | 99 void GamepadPlatformDataFetcherMac::PauseHint(bool pause) { |
99 if (pause) | 100 if (pause) |
100 UnregisterFromNotifications(); | 101 UnregisterFromNotifications(); |
101 else | 102 else |
102 RegisterForNotifications(); | 103 RegisterForNotifications(); |
103 } | 104 } |
104 | 105 |
105 GamepadDataFetcherMac::~GamepadDataFetcherMac() { | 106 GamepadPlatformDataFetcherMac::~GamepadPlatformDataFetcherMac() { |
106 UnregisterFromNotifications(); | 107 UnregisterFromNotifications(); |
107 } | 108 } |
108 | 109 |
109 GamepadDataFetcherMac* GamepadDataFetcherMac::InstanceFromContext( | 110 GamepadPlatformDataFetcherMac* |
| 111 GamepadPlatformDataFetcherMac::InstanceFromContext( |
110 void* context) { | 112 void* context) { |
111 return reinterpret_cast<GamepadDataFetcherMac*>(context); | 113 return reinterpret_cast<GamepadPlatformDataFetcherMac*>(context); |
112 } | 114 } |
113 | 115 |
114 void GamepadDataFetcherMac::DeviceAddCallback(void* context, | 116 void GamepadPlatformDataFetcherMac::DeviceAddCallback(void* context, |
115 IOReturn result, | 117 IOReturn result, |
116 void* sender, | 118 void* sender, |
117 IOHIDDeviceRef ref) { | 119 IOHIDDeviceRef ref) { |
118 InstanceFromContext(context)->DeviceAdd(ref); | 120 InstanceFromContext(context)->DeviceAdd(ref); |
119 } | 121 } |
120 | 122 |
121 void GamepadDataFetcherMac::DeviceRemoveCallback(void* context, | 123 void GamepadPlatformDataFetcherMac::DeviceRemoveCallback(void* context, |
122 IOReturn result, | 124 IOReturn result, |
123 void* sender, | 125 void* sender, |
124 IOHIDDeviceRef ref) { | 126 IOHIDDeviceRef ref) { |
125 InstanceFromContext(context)->DeviceRemove(ref); | 127 InstanceFromContext(context)->DeviceRemove(ref); |
126 } | 128 } |
127 | 129 |
128 void GamepadDataFetcherMac::ValueChangedCallback(void* context, | 130 void GamepadPlatformDataFetcherMac::ValueChangedCallback(void* context, |
129 IOReturn result, | 131 IOReturn result, |
130 void* sender, | 132 void* sender, |
131 IOHIDValueRef ref) { | 133 IOHIDValueRef ref) { |
132 InstanceFromContext(context)->ValueChanged(ref); | 134 InstanceFromContext(context)->ValueChanged(ref); |
133 } | 135 } |
134 | 136 |
135 void GamepadDataFetcherMac::AddButtonsAndAxes(NSArray* elements, | 137 void GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements, |
136 size_t slot) { | 138 size_t slot) { |
137 WebKit::WebGamepad& pad = data_.items[slot]; | 139 WebKit::WebGamepad& pad = data_.items[slot]; |
138 AssociatedData& associated = associated_[slot]; | 140 AssociatedData& associated = associated_[slot]; |
139 | 141 |
140 pad.axesLength = 0; | 142 pad.axesLength = 0; |
141 pad.buttonsLength = 0; | 143 pad.buttonsLength = 0; |
142 memset(pad.axes, 0, sizeof(pad.axes)); | 144 memset(pad.axes, 0, sizeof(pad.axes)); |
143 memset(pad.buttons, 0, sizeof(pad.buttons)); | 145 memset(pad.buttons, 0, sizeof(pad.buttons)); |
144 | 146 |
145 for (id elem in elements) { | 147 for (id elem in elements) { |
(...skipping 15 matching lines...) Expand all Loading... |
161 IOHIDElementGetLogicalMin(element); | 163 IOHIDElementGetLogicalMin(element); |
162 associated.axis_maximums[axis_index] = | 164 associated.axis_maximums[axis_index] = |
163 IOHIDElementGetLogicalMax(element); | 165 IOHIDElementGetLogicalMax(element); |
164 associated.axis_elements[axis_index] = element; | 166 associated.axis_elements[axis_index] = element; |
165 pad.axesLength = std::max(pad.axesLength, axis_index + 1); | 167 pad.axesLength = std::max(pad.axesLength, axis_index + 1); |
166 } | 168 } |
167 } | 169 } |
168 } | 170 } |
169 } | 171 } |
170 | 172 |
171 void GamepadDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { | 173 void GamepadPlatformDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { |
172 using WebKit::WebGamepad; | 174 using WebKit::WebGamepad; |
173 using WebKit::WebGamepads; | 175 using WebKit::WebGamepads; |
174 using base::mac::CFToNSCast; | 176 using base::mac::CFToNSCast; |
175 using base::mac::CFCastStrict; | 177 using base::mac::CFCastStrict; |
176 size_t slot; | 178 size_t slot; |
177 | 179 |
178 if (!enabled_) | 180 if (!enabled_) |
179 return; | 181 return; |
180 | 182 |
181 // Find an index for this device. | 183 // Find an index for this device. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 base::mac::ScopedCFTypeRef<CFArrayRef> elements( | 216 base::mac::ScopedCFTypeRef<CFArrayRef> elements( |
215 IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone)); | 217 IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone)); |
216 AddButtonsAndAxes(CFToNSCast(elements), slot); | 218 AddButtonsAndAxes(CFToNSCast(elements), slot); |
217 | 219 |
218 associated_[slot].device_ref = device; | 220 associated_[slot].device_ref = device; |
219 data_.items[slot].connected = true; | 221 data_.items[slot].connected = true; |
220 if (slot >= data_.length) | 222 if (slot >= data_.length) |
221 data_.length = slot + 1; | 223 data_.length = slot + 1; |
222 } | 224 } |
223 | 225 |
224 void GamepadDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { | 226 void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { |
225 using WebKit::WebGamepads; | 227 using WebKit::WebGamepads; |
226 size_t slot; | 228 size_t slot; |
227 if (!enabled_) | 229 if (!enabled_) |
228 return; | 230 return; |
229 | 231 |
230 // Find the index for this device. | 232 // Find the index for this device. |
231 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { | 233 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { |
232 if (associated_[slot].device_ref == device && data_.items[slot].connected) | 234 if (associated_[slot].device_ref == device && data_.items[slot].connected) |
233 break; | 235 break; |
234 } | 236 } |
235 DCHECK(slot < WebGamepads::itemsLengthCap); | 237 DCHECK(slot < WebGamepads::itemsLengthCap); |
236 // Leave associated device_ref so that it will be reconnected in the same | 238 // Leave associated device_ref so that it will be reconnected in the same |
237 // location. Simply mark it as disconnected. | 239 // location. Simply mark it as disconnected. |
238 data_.items[slot].connected = false; | 240 data_.items[slot].connected = false; |
239 } | 241 } |
240 | 242 |
241 void GamepadDataFetcherMac::ValueChanged(IOHIDValueRef value) { | 243 void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) { |
242 if (!enabled_) | 244 if (!enabled_) |
243 return; | 245 return; |
244 | 246 |
245 IOHIDElementRef element = IOHIDValueGetElement(value); | 247 IOHIDElementRef element = IOHIDValueGetElement(value); |
246 IOHIDDeviceRef device = IOHIDElementGetDevice(element); | 248 IOHIDDeviceRef device = IOHIDElementGetDevice(element); |
247 | 249 |
248 // Find device slot. | 250 // Find device slot. |
249 size_t slot; | 251 size_t slot; |
250 for (slot = 0; slot < data_.length; ++slot) { | 252 for (slot = 0; slot < data_.length; ++slot) { |
251 if (data_.items[slot].connected && associated_[slot].device_ref == device) | 253 if (data_.items[slot].connected && associated_[slot].device_ref == device) |
(...skipping 17 matching lines...) Expand all Loading... |
269 for (size_t i = 0; i < pad.axesLength; ++i) { | 271 for (size_t i = 0; i < pad.axesLength; ++i) { |
270 if (associated.axis_elements[i] == element) { | 272 if (associated.axis_elements[i] == element) { |
271 pad.axes[i] = NormalizeAxis(IOHIDValueGetIntegerValue(value), | 273 pad.axes[i] = NormalizeAxis(IOHIDValueGetIntegerValue(value), |
272 associated.axis_minimums[i], | 274 associated.axis_minimums[i], |
273 associated.axis_maximums[i]); | 275 associated.axis_maximums[i]); |
274 return; | 276 return; |
275 } | 277 } |
276 } | 278 } |
277 } | 279 } |
278 | 280 |
279 void GamepadDataFetcherMac::GetGamepadData(WebKit::WebGamepads* pads, bool) { | 281 void GamepadPlatformDataFetcherMac::GetGamepadData( |
| 282 WebKit::WebGamepads* pads, |
| 283 bool) { |
280 if (!enabled_) { | 284 if (!enabled_) { |
281 pads->length = 0; | 285 pads->length = 0; |
282 return; | 286 return; |
283 } | 287 } |
284 memcpy(pads, &data_, sizeof(WebKit::WebGamepads)); | 288 memcpy(pads, &data_, sizeof(WebKit::WebGamepads)); |
285 } | 289 } |
286 | 290 |
287 } // namespace content | 291 } // namespace content |
OLD | NEW |