@@ -83,6 +83,7 @@ class Gamepad {
83
83
84
84
public:
85
85
Gamepad () : mDevice (nullptr ), mSuperIndex (-1 ) {}
86
+
86
87
bool operator ==(IOHIDDeviceRef device) const { return mDevice == device; }
87
88
bool empty () const { return mDevice == nullptr ; }
88
89
void clear () {
@@ -92,13 +93,12 @@ class Gamepad {
92
93
mSuperIndex = -1 ;
93
94
}
94
95
void init (IOHIDDeviceRef device);
96
+ void ReportChanged (uint8_t * report, CFIndex report_length);
97
+ size_t WriteOutputReport (const std::vector<uint8_t >& aReport) const ;
98
+
95
99
size_t numButtons () { return buttons.Length (); }
96
100
size_t numAxes () { return axes.Length (); }
97
101
98
- // Index given by our superclass.
99
- uint32_t mSuperIndex ;
100
- RefPtr<GamepadRemapper> mRemapper ;
101
-
102
102
Button* lookupButton (IOHIDElementRef element) {
103
103
for (unsigned i = 0 ; i < buttons.Length (); i++) {
104
104
if (buttons[i].element == element) return &buttons[i];
@@ -112,6 +112,11 @@ class Gamepad {
112
112
}
113
113
return nullptr ;
114
114
}
115
+
116
+ // Index given by our superclass.
117
+ uint32_t mSuperIndex ;
118
+ RefPtr<GamepadRemapper> mRemapper ;
119
+ std::vector<uint8_t > mInputReport ;
115
120
};
116
121
117
122
void Gamepad::init (IOHIDDeviceRef device) {
@@ -192,8 +197,16 @@ class DarwinGamepadService {
192
197
public:
193
198
DarwinGamepadService ();
194
199
~DarwinGamepadService ();
200
+
201
+ static void ReportChangedCallback (void * context, IOReturn result,
202
+ void * sender, IOHIDReportType report_type,
203
+ uint32_t report_id, uint8_t * report,
204
+ CFIndex report_length);
205
+
195
206
void Startup ();
196
207
void Shutdown ();
208
+ void SetLightIndicatorColor (uint32_t aControllerIdx, uint32_t aLightIndex,
209
+ uint8_t aRed, uint8_t aGreen, uint8_t aBlue);
197
210
friend class DarwinGamepadServiceStartupRunnable ;
198
211
friend class DarwinGamepadServiceShutdownRunnable ;
199
212
};
@@ -284,13 +297,27 @@ void DarwinGamepadService::DeviceAdded(IOHIDDeviceRef device) {
284
297
remapper->SetButtonCount (mGamepads [slot].numButtons ());
285
298
286
299
uint32_t index = service->AddGamepad (
287
- buffer, remapper->GetMappingType (),
288
- mozilla::dom::GamepadHand::_empty, remapper->GetButtonCount (),
289
- remapper->GetAxisCount (), 0 , 0 ,
290
- 0 ); // TODO: Bug 680289, implement gamepad haptics for cocoa.
291
- // TODO: Bug 1523355, implement gamepad lighindicator and touch for cocoa.
300
+ buffer, remapper->GetMappingType (), mozilla::dom::GamepadHand::_empty,
301
+ remapper->GetButtonCount (), remapper->GetAxisCount (),
302
+ 0 , // TODO: Bug 680289, implement gamepad haptics for cocoa.
303
+ remapper->GetLightIndicatorCount (), remapper->GetTouchEventCount ());
304
+
305
+ nsTArray<GamepadLightIndicatorType> lightTypes;
306
+ remapper->GetLightIndicators (lightTypes);
307
+ for (uint32_t i = 0 ; i < lightTypes.Length (); ++i) {
308
+ if (lightTypes[i] != GamepadLightIndicator::DefaultType ()) {
309
+ service->NewLightIndicatorTypeEvent (index , i, lightTypes[i]);
310
+ }
311
+ }
312
+
292
313
mGamepads [slot].mSuperIndex = index ;
314
+ mGamepads [slot].mInputReport .resize (remapper->GetMaxInputReportLength ());
293
315
mGamepads [slot].mRemapper = remapper.forget ();
316
+
317
+ IOHIDDeviceRegisterInputReportCallback (
318
+ device, mGamepads [slot].mInputReport .data (),
319
+ mGamepads [slot].mInputReport .size (), ReportChangedCallback,
320
+ &mGamepads [slot]);
294
321
}
295
322
296
323
void DarwinGamepadService::DeviceRemoved (IOHIDDeviceRef device) {
@@ -308,6 +335,29 @@ void DarwinGamepadService::DeviceRemoved(IOHIDDeviceRef device) {
308
335
}
309
336
}
310
337
338
+ // Replace context to be Gamepad.
339
+ void DarwinGamepadService::ReportChangedCallback (
340
+ void * context, IOReturn result, void * sender, IOHIDReportType report_type,
341
+ uint32_t report_id, uint8_t * report, CFIndex report_length) {
342
+ if (report_type == kIOHIDReportTypeInput ) {
343
+ reinterpret_cast <Gamepad*>(context)->ReportChanged (report, report_length);
344
+ }
345
+ }
346
+
347
+ void Gamepad::ReportChanged (uint8_t * report, CFIndex report_len) {
348
+ MOZ_RELEASE_ASSERT (report_len <= mRemapper ->GetMaxInputReportLength ());
349
+ mRemapper ->ProcessTouchData (mSuperIndex , report);
350
+ }
351
+
352
+ size_t Gamepad::WriteOutputReport (const std::vector<uint8_t >& aReport) const {
353
+ IOReturn success =
354
+ IOHIDDeviceSetReport (mDevice , kIOHIDReportTypeOutput , aReport[0 ],
355
+ aReport.data (), aReport.size ());
356
+
357
+ MOZ_ASSERT (success == kIOReturnSuccess );
358
+ return (success == kIOReturnSuccess ) ? aReport.size () : 0 ;
359
+ }
360
+
311
361
void DarwinGamepadService::InputValueChanged (IOHIDValueRef value) {
312
362
RefPtr<GamepadPlatformService> service =
313
363
GamepadPlatformService::GetParentService ();
@@ -507,6 +557,35 @@ void DarwinGamepadService::Shutdown() {
507
557
mIsRunning = false ;
508
558
}
509
559
560
+ void DarwinGamepadService::SetLightIndicatorColor (uint32_t aControllerIdx,
561
+ uint32_t aLightColorIndex,
562
+ uint8_t aRed, uint8_t aGreen,
563
+ uint8_t aBlue) {
564
+ // We get aControllerIdx from GamepadPlatformService::AddGamepad(),
565
+ // It begins from 1 and is stored at Gamepad.id.
566
+ const Gamepad* gamepad = nullptr ;
567
+ for (const auto & pad : mGamepads ) {
568
+ if (pad.mSuperIndex == aControllerIdx) {
569
+ gamepad = &pad;
570
+ break ;
571
+ }
572
+ }
573
+ if (!gamepad) {
574
+ MOZ_ASSERT (false );
575
+ return ;
576
+ }
577
+
578
+ RefPtr<GamepadRemapper> remapper = gamepad->mRemapper ;
579
+ if (!remapper || remapper->GetLightIndicatorCount () <= aLightColorIndex) {
580
+ MOZ_ASSERT (false );
581
+ return ;
582
+ }
583
+
584
+ std::vector<uint8_t > report;
585
+ remapper->GetLightColorReport (aRed, aGreen, aBlue, report);
586
+ gamepad->WriteOutputReport (report);
587
+ }
588
+
510
589
} // namespace
511
590
512
591
namespace mozilla {
@@ -535,8 +614,12 @@ void StopGamepadMonitoring() {
535
614
void SetGamepadLightIndicatorColor (uint32_t aControllerIdx,
536
615
uint32_t aLightColorIndex, uint8_t aRed,
537
616
uint8_t aGreen, uint8_t aBlue) {
538
- // TODO: Bug 1523353.
539
- NS_WARNING (" Mac OS doesn't support gamepad light indicator." );
617
+ MOZ_ASSERT (gService );
618
+ if (!gService ) {
619
+ return ;
620
+ }
621
+ gService ->SetLightIndicatorColor (aControllerIdx, aLightColorIndex, aRed,
622
+ aGreen, aBlue);
540
623
}
541
624
542
625
} // namespace dom
0 commit comments