michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_dom_GamepadService_h_ michael@0: #define mozilla_dom_GamepadService_h_ michael@0: michael@0: #include michael@0: #include "Gamepad.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsCOMArray.h" michael@0: #include "nsIGamepadServiceTest.h" michael@0: #include "nsGlobalWindow.h" michael@0: #include "nsIFocusManager.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsITimer.h" michael@0: #include "nsTArray.h" michael@0: michael@0: class nsIDOMDocument; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: class EventTarget; michael@0: michael@0: class GamepadService : public nsIObserver michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: // Get the singleton service michael@0: static already_AddRefed GetService(); michael@0: // Return true if the API is preffed on. michael@0: static bool IsAPIEnabled(); michael@0: michael@0: void BeginShutdown(); michael@0: michael@0: // Indicate that |aWindow| wants to receive gamepad events. michael@0: void AddListener(nsGlobalWindow* aWindow); michael@0: // Indicate that |aWindow| should no longer receive gamepad events. michael@0: void RemoveListener(nsGlobalWindow* aWindow); michael@0: michael@0: // Add a gamepad to the list of known gamepads, and return its index. michael@0: uint32_t AddGamepad(const char* aID, GamepadMappingType aMapping, michael@0: uint32_t aNumButtons, uint32_t aNumAxes); michael@0: // Remove the gamepad at |aIndex| from the list of known gamepads. michael@0: void RemoveGamepad(uint32_t aIndex); michael@0: michael@0: // Update the state of |aButton| for the gamepad at |aIndex| for all michael@0: // windows that are listening and visible, and fire one of michael@0: // a gamepadbutton{up,down} event at them as well. michael@0: // aPressed is used for digital buttons, aValue is for analog buttons. michael@0: void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed, michael@0: double aValue); michael@0: // When only a digital button is available the value will be synthesized. michael@0: void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed); michael@0: michael@0: // Update the state of |aAxis| for the gamepad at |aIndex| for all michael@0: // windows that are listening and visible, and fire a gamepadaxismove michael@0: // event at them as well. michael@0: void NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis, double aValue); michael@0: michael@0: // Synchronize the state of |aGamepad| to match the gamepad stored at |aIndex| michael@0: void SyncGamepadState(uint32_t aIndex, Gamepad* aGamepad); michael@0: michael@0: protected: michael@0: GamepadService(); michael@0: virtual ~GamepadService() {}; michael@0: void StartCleanupTimer(); michael@0: michael@0: // Fire a gamepadconnected or gamepaddisconnected event for the gamepad michael@0: // at |aIndex| to all windows that are listening and have received michael@0: // gamepad input. michael@0: void NewConnectionEvent(uint32_t aIndex, bool aConnected); michael@0: michael@0: // Fire a gamepadaxismove event to the window at |aTarget| for |aGamepad|. michael@0: void FireAxisMoveEvent(EventTarget* aTarget, michael@0: Gamepad* aGamepad, michael@0: uint32_t axis, michael@0: double value); michael@0: michael@0: // Fire one of gamepadbutton{up,down} event at the window at |aTarget| for michael@0: // |aGamepad|. michael@0: void FireButtonEvent(EventTarget* aTarget, michael@0: Gamepad* aGamepad, michael@0: uint32_t aButton, michael@0: double aValue); michael@0: michael@0: // Fire one of gamepad{connected,disconnected} event at the window at michael@0: // |aTarget| for |aGamepad|. michael@0: void FireConnectionEvent(EventTarget* aTarget, michael@0: Gamepad* aGamepad, michael@0: bool aConnected); michael@0: michael@0: // true if this feature is enabled in preferences michael@0: bool mEnabled; michael@0: // true if non-standard events are enabled in preferences michael@0: bool mNonstandardEventsEnabled; michael@0: // true if the platform-specific backend has started work michael@0: bool mStarted; michael@0: // true when shutdown has begun michael@0: bool mShuttingDown; michael@0: michael@0: private: michael@0: // Returns true if we have already sent data from this gamepad michael@0: // to this window. This should only return true if the user michael@0: // explicitly interacted with a gamepad while this window michael@0: // was focused, by pressing buttons or similar actions. michael@0: bool WindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex); michael@0: // Indicate that a window has recieved data from a gamepad. michael@0: void SetWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex, michael@0: bool aHasSeen = true); michael@0: michael@0: static void TimeoutHandler(nsITimer* aTimer, void* aClosure); michael@0: static bool sShutdown; michael@0: michael@0: // Gamepads connected to the system. Copies of these are handed out michael@0: // to each window. michael@0: nsTArray > mGamepads; michael@0: // nsGlobalWindows that are listening for gamepad events. michael@0: // has been sent to that window. michael@0: nsTArray > mListeners; michael@0: nsCOMPtr mTimer; michael@0: nsCOMPtr mFocusManager; michael@0: nsCOMPtr mObserver; michael@0: }; michael@0: michael@0: // Service for testing purposes michael@0: class GamepadServiceTest : public nsIGamepadServiceTest michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIGAMEPADSERVICETEST michael@0: michael@0: GamepadServiceTest(); michael@0: michael@0: static already_AddRefed CreateService(); michael@0: michael@0: private: michael@0: static GamepadServiceTest* sSingleton; michael@0: virtual ~GamepadServiceTest() {}; michael@0: }; michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: #define NS_GAMEPAD_TEST_CID \ michael@0: { 0xfb1fcb57, 0xebab, 0x4cf4, \ michael@0: { 0x96, 0x3b, 0x1e, 0x4d, 0xb8, 0x52, 0x16, 0x96 } } michael@0: #define NS_GAMEPAD_TEST_CONTRACTID "@mozilla.org/gamepad-test;1" michael@0: michael@0: #endif // mozilla_dom_GamepadService_h_