dom/gamepad/GamepadService.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "mozilla/Hal.h"
michael@0 6 #include "mozilla/ClearOnShutdown.h"
michael@0 7 #include "mozilla/Preferences.h"
michael@0 8 #include "mozilla/StaticPtr.h"
michael@0 9
michael@0 10 #include "GamepadService.h"
michael@0 11 #include "Gamepad.h"
michael@0 12 #include "nsAutoPtr.h"
michael@0 13 #include "nsIDOMEvent.h"
michael@0 14 #include "nsIDOMDocument.h"
michael@0 15 #include "GeneratedEvents.h"
michael@0 16 #include "nsIDOMWindow.h"
michael@0 17 #include "nsIObserver.h"
michael@0 18 #include "nsIObserverService.h"
michael@0 19 #include "nsIServiceManager.h"
michael@0 20 #include "nsITimer.h"
michael@0 21 #include "nsThreadUtils.h"
michael@0 22 #include "mozilla/Services.h"
michael@0 23
michael@0 24 #include "mozilla/dom/GamepadAxisMoveEvent.h"
michael@0 25 #include "mozilla/dom/GamepadButtonEvent.h"
michael@0 26 #include "mozilla/dom/GamepadEvent.h"
michael@0 27
michael@0 28 #include <cstddef>
michael@0 29
michael@0 30 namespace mozilla {
michael@0 31 namespace dom {
michael@0 32
michael@0 33 namespace {
michael@0 34 const char* kGamepadEnabledPref = "dom.gamepad.enabled";
michael@0 35 const char* kGamepadEventsEnabledPref =
michael@0 36 "dom.gamepad.non_standard_events.enabled";
michael@0 37 // Amount of time to wait before cleaning up gamepad resources
michael@0 38 // when no pages are listening for events.
michael@0 39 const int kCleanupDelayMS = 2000;
michael@0 40 const nsTArray<nsRefPtr<nsGlobalWindow> >::index_type NoIndex =
michael@0 41 nsTArray<nsRefPtr<nsGlobalWindow> >::NoIndex;
michael@0 42
michael@0 43 StaticRefPtr<GamepadService> gGamepadServiceSingleton;
michael@0 44
michael@0 45 } // namespace
michael@0 46
michael@0 47 bool GamepadService::sShutdown = false;
michael@0 48
michael@0 49 NS_IMPL_ISUPPORTS(GamepadService, nsIObserver)
michael@0 50
michael@0 51 GamepadService::GamepadService()
michael@0 52 : mStarted(false),
michael@0 53 mShuttingDown(false)
michael@0 54 {
michael@0 55 mEnabled = IsAPIEnabled();
michael@0 56 mNonstandardEventsEnabled =
michael@0 57 Preferences::GetBool(kGamepadEventsEnabledPref, false);
michael@0 58 nsCOMPtr<nsIObserverService> observerService =
michael@0 59 mozilla::services::GetObserverService();
michael@0 60 observerService->AddObserver(this,
michael@0 61 NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
michael@0 62 false);
michael@0 63 }
michael@0 64
michael@0 65 NS_IMETHODIMP
michael@0 66 GamepadService::Observe(nsISupports* aSubject,
michael@0 67 const char* aTopic,
michael@0 68 const char16_t* aData)
michael@0 69 {
michael@0 70 nsCOMPtr<nsIObserverService> observerService =
michael@0 71 mozilla::services::GetObserverService();
michael@0 72 observerService->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
michael@0 73
michael@0 74 BeginShutdown();
michael@0 75 return NS_OK;
michael@0 76 }
michael@0 77
michael@0 78 void
michael@0 79 GamepadService::BeginShutdown()
michael@0 80 {
michael@0 81 mShuttingDown = true;
michael@0 82 if (mTimer) {
michael@0 83 mTimer->Cancel();
michael@0 84 }
michael@0 85 if (mStarted) {
michael@0 86 mozilla::hal::StopMonitoringGamepadStatus();
michael@0 87 mStarted = false;
michael@0 88 }
michael@0 89 // Don't let windows call back to unregister during shutdown
michael@0 90 for (uint32_t i = 0; i < mListeners.Length(); i++) {
michael@0 91 mListeners[i]->SetHasGamepadEventListener(false);
michael@0 92 }
michael@0 93 mListeners.Clear();
michael@0 94 mGamepads.Clear();
michael@0 95 sShutdown = true;
michael@0 96 }
michael@0 97
michael@0 98 void
michael@0 99 GamepadService::AddListener(nsGlobalWindow* aWindow)
michael@0 100 {
michael@0 101 if (mShuttingDown) {
michael@0 102 return;
michael@0 103 }
michael@0 104
michael@0 105 if (mListeners.IndexOf(aWindow) != NoIndex) {
michael@0 106 return; // already exists
michael@0 107 }
michael@0 108
michael@0 109 if (!mStarted && mEnabled) {
michael@0 110 mozilla::hal::StartMonitoringGamepadStatus();
michael@0 111 mStarted = true;
michael@0 112 }
michael@0 113
michael@0 114 mListeners.AppendElement(aWindow);
michael@0 115 }
michael@0 116
michael@0 117 void
michael@0 118 GamepadService::RemoveListener(nsGlobalWindow* aWindow)
michael@0 119 {
michael@0 120 if (mShuttingDown) {
michael@0 121 // Doesn't matter at this point. It's possible we're being called
michael@0 122 // as a result of our own destructor here, so just bail out.
michael@0 123 return;
michael@0 124 }
michael@0 125
michael@0 126 if (mListeners.IndexOf(aWindow) == NoIndex) {
michael@0 127 return; // doesn't exist
michael@0 128 }
michael@0 129
michael@0 130 mListeners.RemoveElement(aWindow);
michael@0 131
michael@0 132 if (mListeners.Length() == 0 && !mShuttingDown && mStarted) {
michael@0 133 StartCleanupTimer();
michael@0 134 }
michael@0 135 }
michael@0 136
michael@0 137 uint32_t
michael@0 138 GamepadService::AddGamepad(const char* aId,
michael@0 139 GamepadMappingType aMapping,
michael@0 140 uint32_t aNumButtons,
michael@0 141 uint32_t aNumAxes)
michael@0 142 {
michael@0 143 //TODO: bug 852258: get initial button/axis state
michael@0 144 nsRefPtr<Gamepad> gamepad =
michael@0 145 new Gamepad(nullptr,
michael@0 146 NS_ConvertUTF8toUTF16(nsDependentCString(aId)),
michael@0 147 0,
michael@0 148 aMapping,
michael@0 149 aNumButtons,
michael@0 150 aNumAxes);
michael@0 151 int index = -1;
michael@0 152 for (uint32_t i = 0; i < mGamepads.Length(); i++) {
michael@0 153 if (!mGamepads[i]) {
michael@0 154 mGamepads[i] = gamepad;
michael@0 155 index = i;
michael@0 156 break;
michael@0 157 }
michael@0 158 }
michael@0 159 if (index == -1) {
michael@0 160 mGamepads.AppendElement(gamepad);
michael@0 161 index = mGamepads.Length() - 1;
michael@0 162 }
michael@0 163
michael@0 164 gamepad->SetIndex(index);
michael@0 165 NewConnectionEvent(index, true);
michael@0 166
michael@0 167 return index;
michael@0 168 }
michael@0 169
michael@0 170 void
michael@0 171 GamepadService::RemoveGamepad(uint32_t aIndex)
michael@0 172 {
michael@0 173 if (aIndex < mGamepads.Length()) {
michael@0 174 mGamepads[aIndex]->SetConnected(false);
michael@0 175 NewConnectionEvent(aIndex, false);
michael@0 176 // If this is the last entry in the list, just remove it.
michael@0 177 if (aIndex == mGamepads.Length() - 1) {
michael@0 178 mGamepads.RemoveElementAt(aIndex);
michael@0 179 } else {
michael@0 180 // Otherwise just null it out and leave it, so the
michael@0 181 // indices of the following entries remain valid.
michael@0 182 mGamepads[aIndex] = nullptr;
michael@0 183 }
michael@0 184 }
michael@0 185 }
michael@0 186
michael@0 187 void
michael@0 188 GamepadService::NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed)
michael@0 189 {
michael@0 190 // Synthesize a value: 1.0 for pressed, 0.0 for unpressed.
michael@0 191 NewButtonEvent(aIndex, aButton, aPressed, aPressed ? 1.0L : 0.0L);
michael@0 192 }
michael@0 193
michael@0 194 void
michael@0 195 GamepadService::NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed,
michael@0 196 double aValue)
michael@0 197 {
michael@0 198 if (mShuttingDown || aIndex >= mGamepads.Length()) {
michael@0 199 return;
michael@0 200 }
michael@0 201
michael@0 202 mGamepads[aIndex]->SetButton(aButton, aPressed, aValue);
michael@0 203
michael@0 204 // Hold on to listeners in a separate array because firing events
michael@0 205 // can mutate the mListeners array.
michael@0 206 nsTArray<nsRefPtr<nsGlobalWindow> > listeners(mListeners);
michael@0 207
michael@0 208 for (uint32_t i = listeners.Length(); i > 0 ; ) {
michael@0 209 --i;
michael@0 210
michael@0 211 // Only send events to non-background windows
michael@0 212 if (!listeners[i]->IsCurrentInnerWindow() ||
michael@0 213 listeners[i]->GetOuterWindow()->IsBackground()) {
michael@0 214 continue;
michael@0 215 }
michael@0 216
michael@0 217 bool first_time = false;
michael@0 218 if (!WindowHasSeenGamepad(listeners[i], aIndex)) {
michael@0 219 // This window hasn't seen this gamepad before, so
michael@0 220 // send a connection event first.
michael@0 221 SetWindowHasSeenGamepad(listeners[i], aIndex);
michael@0 222 first_time = true;
michael@0 223 }
michael@0 224
michael@0 225 nsRefPtr<Gamepad> gamepad = listeners[i]->GetGamepad(aIndex);
michael@0 226 if (gamepad) {
michael@0 227 gamepad->SetButton(aButton, aPressed, aValue);
michael@0 228 if (first_time) {
michael@0 229 FireConnectionEvent(listeners[i], gamepad, true);
michael@0 230 }
michael@0 231 if (mNonstandardEventsEnabled) {
michael@0 232 // Fire event
michael@0 233 FireButtonEvent(listeners[i], gamepad, aButton, aValue);
michael@0 234 }
michael@0 235 }
michael@0 236 }
michael@0 237 }
michael@0 238
michael@0 239 void
michael@0 240 GamepadService::FireButtonEvent(EventTarget* aTarget,
michael@0 241 Gamepad* aGamepad,
michael@0 242 uint32_t aButton,
michael@0 243 double aValue)
michael@0 244 {
michael@0 245 nsString name = aValue == 1.0L ? NS_LITERAL_STRING("gamepadbuttondown") :
michael@0 246 NS_LITERAL_STRING("gamepadbuttonup");
michael@0 247 GamepadButtonEventInit init;
michael@0 248 init.mBubbles = false;
michael@0 249 init.mCancelable = false;
michael@0 250 init.mGamepad = aGamepad;
michael@0 251 init.mButton = aButton;
michael@0 252 nsRefPtr<GamepadButtonEvent> event =
michael@0 253 GamepadButtonEvent::Constructor(aTarget, name, init);
michael@0 254
michael@0 255 event->SetTrusted(true);
michael@0 256
michael@0 257 bool defaultActionEnabled = true;
michael@0 258 aTarget->DispatchEvent(event, &defaultActionEnabled);
michael@0 259 }
michael@0 260
michael@0 261 void
michael@0 262 GamepadService::NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis, double aValue)
michael@0 263 {
michael@0 264 if (mShuttingDown || aIndex >= mGamepads.Length()) {
michael@0 265 return;
michael@0 266 }
michael@0 267 mGamepads[aIndex]->SetAxis(aAxis, aValue);
michael@0 268
michael@0 269 // Hold on to listeners in a separate array because firing events
michael@0 270 // can mutate the mListeners array.
michael@0 271 nsTArray<nsRefPtr<nsGlobalWindow> > listeners(mListeners);
michael@0 272
michael@0 273 for (uint32_t i = listeners.Length(); i > 0 ; ) {
michael@0 274 --i;
michael@0 275
michael@0 276 // Only send events to non-background windows
michael@0 277 if (!listeners[i]->IsCurrentInnerWindow() ||
michael@0 278 listeners[i]->GetOuterWindow()->IsBackground()) {
michael@0 279 continue;
michael@0 280 }
michael@0 281
michael@0 282 bool first_time = false;
michael@0 283 if (!WindowHasSeenGamepad(listeners[i], aIndex)) {
michael@0 284 // This window hasn't seen this gamepad before, so
michael@0 285 // send a connection event first.
michael@0 286 SetWindowHasSeenGamepad(listeners[i], aIndex);
michael@0 287 first_time = true;
michael@0 288 }
michael@0 289
michael@0 290 nsRefPtr<Gamepad> gamepad = listeners[i]->GetGamepad(aIndex);
michael@0 291 if (gamepad) {
michael@0 292 gamepad->SetAxis(aAxis, aValue);
michael@0 293 if (first_time) {
michael@0 294 FireConnectionEvent(listeners[i], gamepad, true);
michael@0 295 }
michael@0 296 if (mNonstandardEventsEnabled) {
michael@0 297 // Fire event
michael@0 298 FireAxisMoveEvent(listeners[i], gamepad, aAxis, aValue);
michael@0 299 }
michael@0 300 }
michael@0 301 }
michael@0 302 }
michael@0 303
michael@0 304 void
michael@0 305 GamepadService::FireAxisMoveEvent(EventTarget* aTarget,
michael@0 306 Gamepad* aGamepad,
michael@0 307 uint32_t aAxis,
michael@0 308 double aValue)
michael@0 309 {
michael@0 310 GamepadAxisMoveEventInit init;
michael@0 311 init.mBubbles = false;
michael@0 312 init.mCancelable = false;
michael@0 313 init.mGamepad = aGamepad;
michael@0 314 init.mAxis = aAxis;
michael@0 315 init.mValue = aValue;
michael@0 316 nsRefPtr<GamepadAxisMoveEvent> event =
michael@0 317 GamepadAxisMoveEvent::Constructor(aTarget,
michael@0 318 NS_LITERAL_STRING("gamepadaxismove"),
michael@0 319 init);
michael@0 320
michael@0 321 event->SetTrusted(true);
michael@0 322
michael@0 323 bool defaultActionEnabled = true;
michael@0 324 aTarget->DispatchEvent(event, &defaultActionEnabled);
michael@0 325 }
michael@0 326
michael@0 327 void
michael@0 328 GamepadService::NewConnectionEvent(uint32_t aIndex, bool aConnected)
michael@0 329 {
michael@0 330 if (mShuttingDown || aIndex >= mGamepads.Length()) {
michael@0 331 return;
michael@0 332 }
michael@0 333
michael@0 334 // Hold on to listeners in a separate array because firing events
michael@0 335 // can mutate the mListeners array.
michael@0 336 nsTArray<nsRefPtr<nsGlobalWindow> > listeners(mListeners);
michael@0 337
michael@0 338 if (aConnected) {
michael@0 339 for (uint32_t i = listeners.Length(); i > 0 ; ) {
michael@0 340 --i;
michael@0 341
michael@0 342 // Only send events to non-background windows
michael@0 343 if (!listeners[i]->IsCurrentInnerWindow() ||
michael@0 344 listeners[i]->GetOuterWindow()->IsBackground()) {
michael@0 345 continue;
michael@0 346 }
michael@0 347
michael@0 348 // We don't fire a connected event here unless the window
michael@0 349 // has seen input from at least one device.
michael@0 350 if (!listeners[i]->HasSeenGamepadInput()) {
michael@0 351 continue;
michael@0 352 }
michael@0 353
michael@0 354 SetWindowHasSeenGamepad(listeners[i], aIndex);
michael@0 355
michael@0 356 nsRefPtr<Gamepad> gamepad = listeners[i]->GetGamepad(aIndex);
michael@0 357 if (gamepad) {
michael@0 358 // Fire event
michael@0 359 FireConnectionEvent(listeners[i], gamepad, aConnected);
michael@0 360 }
michael@0 361 }
michael@0 362 } else {
michael@0 363 // For disconnection events, fire one at every window that has received
michael@0 364 // data from this gamepad.
michael@0 365 for (uint32_t i = listeners.Length(); i > 0 ; ) {
michael@0 366 --i;
michael@0 367
michael@0 368 // Even background windows get these events, so we don't have to
michael@0 369 // deal with the hassle of syncing the state of removed gamepads.
michael@0 370
michael@0 371 if (WindowHasSeenGamepad(listeners[i], aIndex)) {
michael@0 372 nsRefPtr<Gamepad> gamepad = listeners[i]->GetGamepad(aIndex);
michael@0 373 if (gamepad) {
michael@0 374 gamepad->SetConnected(false);
michael@0 375 // Fire event
michael@0 376 FireConnectionEvent(listeners[i], gamepad, false);
michael@0 377 listeners[i]->RemoveGamepad(aIndex);
michael@0 378 }
michael@0 379 }
michael@0 380 }
michael@0 381 }
michael@0 382 }
michael@0 383
michael@0 384 void
michael@0 385 GamepadService::FireConnectionEvent(EventTarget* aTarget,
michael@0 386 Gamepad* aGamepad,
michael@0 387 bool aConnected)
michael@0 388 {
michael@0 389 nsString name = aConnected ? NS_LITERAL_STRING("gamepadconnected") :
michael@0 390 NS_LITERAL_STRING("gamepaddisconnected");
michael@0 391 GamepadEventInit init;
michael@0 392 init.mBubbles = false;
michael@0 393 init.mCancelable = false;
michael@0 394 init.mGamepad = aGamepad;
michael@0 395 nsRefPtr<GamepadEvent> event =
michael@0 396 GamepadEvent::Constructor(aTarget, name, init);
michael@0 397
michael@0 398 event->SetTrusted(true);
michael@0 399
michael@0 400 bool defaultActionEnabled = true;
michael@0 401 aTarget->DispatchEvent(event, &defaultActionEnabled);
michael@0 402 }
michael@0 403
michael@0 404 void
michael@0 405 GamepadService::SyncGamepadState(uint32_t aIndex, Gamepad* aGamepad)
michael@0 406 {
michael@0 407 if (mShuttingDown || !mEnabled || aIndex > mGamepads.Length()) {
michael@0 408 return;
michael@0 409 }
michael@0 410
michael@0 411 aGamepad->SyncState(mGamepads[aIndex]);
michael@0 412 }
michael@0 413
michael@0 414 // static
michael@0 415 already_AddRefed<GamepadService>
michael@0 416 GamepadService::GetService()
michael@0 417 {
michael@0 418 if (sShutdown) {
michael@0 419 return nullptr;
michael@0 420 }
michael@0 421
michael@0 422 if (!gGamepadServiceSingleton) {
michael@0 423 gGamepadServiceSingleton = new GamepadService();
michael@0 424 ClearOnShutdown(&gGamepadServiceSingleton);
michael@0 425 }
michael@0 426 nsRefPtr<GamepadService> service(gGamepadServiceSingleton);
michael@0 427 return service.forget();
michael@0 428 }
michael@0 429
michael@0 430 // static
michael@0 431 bool
michael@0 432 GamepadService::IsAPIEnabled() {
michael@0 433 return Preferences::GetBool(kGamepadEnabledPref, false);
michael@0 434 }
michael@0 435
michael@0 436 bool
michael@0 437 GamepadService::WindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex)
michael@0 438 {
michael@0 439 nsRefPtr<Gamepad> gamepad = aWindow->GetGamepad(aIndex);
michael@0 440 return gamepad != nullptr;
michael@0 441 }
michael@0 442
michael@0 443 void
michael@0 444 GamepadService::SetWindowHasSeenGamepad(nsGlobalWindow* aWindow,
michael@0 445 uint32_t aIndex,
michael@0 446 bool aHasSeen)
michael@0 447 {
michael@0 448 if (mListeners.IndexOf(aWindow) == NoIndex) {
michael@0 449 // This window isn't even listening for gamepad events.
michael@0 450 return;
michael@0 451 }
michael@0 452
michael@0 453 if (aHasSeen) {
michael@0 454 aWindow->SetHasSeenGamepadInput(true);
michael@0 455 nsCOMPtr<nsISupports> window = ToSupports(aWindow);
michael@0 456 nsRefPtr<Gamepad> gamepad = mGamepads[aIndex]->Clone(window);
michael@0 457 aWindow->AddGamepad(aIndex, gamepad);
michael@0 458 } else {
michael@0 459 aWindow->RemoveGamepad(aIndex);
michael@0 460 }
michael@0 461 }
michael@0 462
michael@0 463 // static
michael@0 464 void
michael@0 465 GamepadService::TimeoutHandler(nsITimer* aTimer, void* aClosure)
michael@0 466 {
michael@0 467 // the reason that we use self, instead of just using nsITimerCallback or nsIObserver
michael@0 468 // is so that subclasses are free to use timers without worry about the base classes's
michael@0 469 // usage.
michael@0 470 GamepadService* self = reinterpret_cast<GamepadService*>(aClosure);
michael@0 471 if (!self) {
michael@0 472 NS_ERROR("no self");
michael@0 473 return;
michael@0 474 }
michael@0 475
michael@0 476 if (self->mShuttingDown) {
michael@0 477 return;
michael@0 478 }
michael@0 479
michael@0 480 if (self->mListeners.Length() == 0) {
michael@0 481 mozilla::hal::StopMonitoringGamepadStatus();
michael@0 482 self->mStarted = false;
michael@0 483 if (!self->mGamepads.IsEmpty()) {
michael@0 484 self->mGamepads.Clear();
michael@0 485 }
michael@0 486 }
michael@0 487 }
michael@0 488
michael@0 489 void
michael@0 490 GamepadService::StartCleanupTimer()
michael@0 491 {
michael@0 492 if (mTimer) {
michael@0 493 mTimer->Cancel();
michael@0 494 }
michael@0 495
michael@0 496 mTimer = do_CreateInstance("@mozilla.org/timer;1");
michael@0 497 if (mTimer) {
michael@0 498 mTimer->InitWithFuncCallback(TimeoutHandler,
michael@0 499 this,
michael@0 500 kCleanupDelayMS,
michael@0 501 nsITimer::TYPE_ONE_SHOT);
michael@0 502 }
michael@0 503 }
michael@0 504
michael@0 505 /*
michael@0 506 * Implementation of the test service. This is just to provide a simple binding
michael@0 507 * of the GamepadService to JavaScript via XPCOM so that we can write Mochitests
michael@0 508 * that add and remove fake gamepads, avoiding the platform-specific backends.
michael@0 509 */
michael@0 510 NS_IMPL_ISUPPORTS(GamepadServiceTest, nsIGamepadServiceTest)
michael@0 511
michael@0 512 GamepadServiceTest* GamepadServiceTest::sSingleton = nullptr;
michael@0 513
michael@0 514 // static
michael@0 515 already_AddRefed<GamepadServiceTest>
michael@0 516 GamepadServiceTest::CreateService()
michael@0 517 {
michael@0 518 if (sSingleton == nullptr) {
michael@0 519 sSingleton = new GamepadServiceTest();
michael@0 520 }
michael@0 521 nsRefPtr<GamepadServiceTest> service = sSingleton;
michael@0 522 return service.forget();
michael@0 523 }
michael@0 524
michael@0 525 GamepadServiceTest::GamepadServiceTest()
michael@0 526 {
michael@0 527 /* member initializers and constructor code */
michael@0 528 nsRefPtr<GamepadService> service = GamepadService::GetService();
michael@0 529 }
michael@0 530
michael@0 531 /* uint32_t addGamepad (in string id, in unsigned long mapping, in unsigned long numButtons, in unsigned long numAxes); */
michael@0 532 NS_IMETHODIMP GamepadServiceTest::AddGamepad(const char* aID,
michael@0 533 uint32_t aMapping,
michael@0 534 uint32_t aNumButtons,
michael@0 535 uint32_t aNumAxes,
michael@0 536 uint32_t* aRetval)
michael@0 537 {
michael@0 538 *aRetval = gGamepadServiceSingleton->AddGamepad(aID,
michael@0 539 static_cast<GamepadMappingType>(aMapping),
michael@0 540 aNumButtons,
michael@0 541 aNumAxes);
michael@0 542 return NS_OK;
michael@0 543 }
michael@0 544
michael@0 545 /* void removeGamepad (in uint32_t index); */
michael@0 546 NS_IMETHODIMP GamepadServiceTest::RemoveGamepad(uint32_t aIndex)
michael@0 547 {
michael@0 548 gGamepadServiceSingleton->RemoveGamepad(aIndex);
michael@0 549 return NS_OK;
michael@0 550 }
michael@0 551
michael@0 552 /* void newButtonEvent (in uint32_t index, in uint32_t button,
michael@0 553 in boolean pressed); */
michael@0 554 NS_IMETHODIMP GamepadServiceTest::NewButtonEvent(uint32_t aIndex,
michael@0 555 uint32_t aButton,
michael@0 556 bool aPressed)
michael@0 557 {
michael@0 558 gGamepadServiceSingleton->NewButtonEvent(aIndex, aButton, aPressed);
michael@0 559 return NS_OK;
michael@0 560 }
michael@0 561
michael@0 562 /* void newAxisMoveEvent (in uint32_t index, in uint32_t axis,
michael@0 563 in double value); */
michael@0 564 NS_IMETHODIMP GamepadServiceTest::NewAxisMoveEvent(uint32_t aIndex,
michael@0 565 uint32_t aAxis,
michael@0 566 double aValue)
michael@0 567 {
michael@0 568 gGamepadServiceSingleton->NewAxisMoveEvent(aIndex, aAxis, aValue);
michael@0 569 return NS_OK;
michael@0 570 }
michael@0 571
michael@0 572 } // namespace dom
michael@0 573 } // namespace mozilla

mercurial