| 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 |