2016-06-28 01:25:00 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_dom_GamepadManager_h_
|
|
|
|
#define mozilla_dom_GamepadManager_h_
|
|
|
|
|
|
|
|
#include "nsIObserver.h"
|
|
|
|
// Needed for GamepadMappingType
|
|
|
|
#include "mozilla/dom/GamepadBinding.h"
|
2016-11-04 10:43:55 +03:00
|
|
|
#include "mozilla/dom/GamepadServiceType.h"
|
2016-06-28 01:25:00 +03:00
|
|
|
|
2017-11-04 01:25:38 +03:00
|
|
|
class nsGlobalWindowInner;
|
2016-06-28 01:25:00 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
2016-10-04 11:30:04 +03:00
|
|
|
namespace gfx {
|
|
|
|
class VRManagerChild;
|
|
|
|
} // namespace gfx
|
2016-06-28 01:25:00 +03:00
|
|
|
namespace dom {
|
|
|
|
|
|
|
|
class EventTarget;
|
|
|
|
class Gamepad;
|
|
|
|
class GamepadChangeEvent;
|
|
|
|
class GamepadEventChannelChild;
|
|
|
|
|
2017-10-24 13:02:40 +03:00
|
|
|
class GamepadManager final : public nsIObserver {
|
2016-06-28 01:25:00 +03:00
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIOBSERVER
|
|
|
|
|
|
|
|
// Returns true if we actually have a service up and running
|
|
|
|
static bool IsServiceRunning();
|
|
|
|
// Get the singleton service
|
|
|
|
static already_AddRefed<GamepadManager> GetService();
|
|
|
|
|
2020-04-08 06:23:34 +03:00
|
|
|
// Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType
|
|
|
|
// is from VRManager.
|
|
|
|
static uint32_t GetGamepadIndexWithServiceType(
|
|
|
|
uint32_t aIndex, GamepadServiceType aServiceType);
|
|
|
|
|
2016-06-28 01:25:00 +03:00
|
|
|
void BeginShutdown();
|
|
|
|
void StopMonitoring();
|
|
|
|
|
|
|
|
// Indicate that |aWindow| wants to receive gamepad events.
|
2017-11-04 01:25:38 +03:00
|
|
|
void AddListener(nsGlobalWindowInner* aWindow);
|
2016-06-28 01:25:00 +03:00
|
|
|
// Indicate that |aWindow| should no longer receive gamepad events.
|
2017-11-04 01:25:38 +03:00
|
|
|
void RemoveListener(nsGlobalWindowInner* aWindow);
|
2016-06-28 01:25:00 +03:00
|
|
|
|
|
|
|
// Add a gamepad to the list of known gamepads.
|
|
|
|
void AddGamepad(uint32_t aIndex, const nsAString& aID,
|
|
|
|
GamepadMappingType aMapping, GamepadHand aHand,
|
2017-07-14 11:55:52 +03:00
|
|
|
GamepadServiceType aServiceType, uint32_t aDisplayID,
|
2019-05-30 01:15:23 +03:00
|
|
|
uint32_t aNumButtons, uint32_t aNumAxes, uint32_t aNumHaptics,
|
|
|
|
uint32_t aNumLightIndicator, uint32_t aNumTouchEvents);
|
2016-06-28 01:25:00 +03:00
|
|
|
|
|
|
|
// Remove the gamepad at |aIndex| from the list of known gamepads.
|
2016-10-04 05:57:04 +03:00
|
|
|
void RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType);
|
2016-06-28 01:25:00 +03:00
|
|
|
|
|
|
|
// Synchronize the state of |aGamepad| to match the gamepad stored at |aIndex|
|
2019-03-05 15:42:51 +03:00
|
|
|
void SyncGamepadState(uint32_t aIndex, nsGlobalWindowInner* aWindow,
|
|
|
|
Gamepad* aGamepad);
|
2016-06-28 01:25:00 +03:00
|
|
|
|
|
|
|
// Returns gamepad object if index exists, null otherwise
|
|
|
|
already_AddRefed<Gamepad> GetGamepad(uint32_t aIndex) const;
|
|
|
|
|
2018-08-29 22:10:55 +03:00
|
|
|
// Returns gamepad object if GamepadId exists, null otherwise
|
|
|
|
already_AddRefed<Gamepad> GetGamepad(uint32_t aGamepadId,
|
|
|
|
GamepadServiceType aServiceType) const;
|
|
|
|
|
2016-06-28 01:25:00 +03:00
|
|
|
// Receive GamepadChangeEvent messages from parent process to fire DOM events
|
|
|
|
void Update(const GamepadChangeEvent& aGamepadEvent);
|
|
|
|
|
2017-02-02 09:33:18 +03:00
|
|
|
// Trigger vibrate haptic event to gamepad channels.
|
2017-02-02 09:59:44 +03:00
|
|
|
already_AddRefed<Promise> VibrateHaptic(uint32_t aControllerIdx,
|
|
|
|
uint32_t aHapticIndex,
|
|
|
|
double aIntensity, double aDuration,
|
2017-03-07 05:17:57 +03:00
|
|
|
nsIGlobalObject* aGlobal,
|
|
|
|
ErrorResult& aRv);
|
|
|
|
// Send stop haptic events to gamepad channels.
|
|
|
|
void StopHaptics();
|
2017-02-02 09:33:18 +03:00
|
|
|
|
2019-05-30 01:15:23 +03:00
|
|
|
// Set light indicator color event to gamepad channels.
|
|
|
|
already_AddRefed<Promise> SetLightIndicatorColor(uint32_t aControllerIdx,
|
|
|
|
uint32_t aLightColorIndex,
|
|
|
|
uint8_t aRed, uint8_t aGreen,
|
|
|
|
uint8_t aBlue,
|
|
|
|
nsIGlobalObject* aGlobal,
|
|
|
|
ErrorResult& aRv);
|
|
|
|
|
2016-06-28 01:25:00 +03:00
|
|
|
protected:
|
|
|
|
GamepadManager();
|
2020-02-20 19:03:33 +03:00
|
|
|
~GamepadManager() = default;
|
2016-06-28 01:25:00 +03:00
|
|
|
|
|
|
|
// Fire a gamepadconnected or gamepaddisconnected event for the gamepad
|
|
|
|
// at |aIndex| to all windows that are listening and have received
|
|
|
|
// gamepad input.
|
|
|
|
void NewConnectionEvent(uint32_t aIndex, bool aConnected);
|
|
|
|
|
|
|
|
// Fire a gamepadaxismove event to the window at |aTarget| for |aGamepad|.
|
|
|
|
void FireAxisMoveEvent(EventTarget* aTarget, Gamepad* aGamepad, uint32_t axis,
|
|
|
|
double value);
|
|
|
|
|
|
|
|
// Fire one of gamepadbutton{up,down} event at the window at |aTarget| for
|
|
|
|
// |aGamepad|.
|
|
|
|
void FireButtonEvent(EventTarget* aTarget, Gamepad* aGamepad,
|
|
|
|
uint32_t aButton, double aValue);
|
|
|
|
|
|
|
|
// Fire one of gamepad{connected,disconnected} event at the window at
|
|
|
|
// |aTarget| for |aGamepad|.
|
|
|
|
void FireConnectionEvent(EventTarget* aTarget, Gamepad* aGamepad,
|
|
|
|
bool aConnected);
|
|
|
|
|
|
|
|
// true if this feature is enabled in preferences
|
|
|
|
bool mEnabled;
|
|
|
|
// true if non-standard events are enabled in preferences
|
|
|
|
bool mNonstandardEventsEnabled;
|
|
|
|
// true when shutdown has begun
|
|
|
|
bool mShuttingDown;
|
|
|
|
|
|
|
|
// Gamepad IPDL child
|
|
|
|
// This pointer is only used by this singleton instance and
|
|
|
|
// will be destroyed during the IPDL shutdown chain, so we
|
2016-09-07 13:31:53 +03:00
|
|
|
// don't need to refcount it here.
|
|
|
|
nsTArray<GamepadEventChannelChild*> mChannelChildren;
|
2016-06-28 01:25:00 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
nsresult Init();
|
|
|
|
|
2017-04-21 06:34:30 +03:00
|
|
|
void MaybeConvertToNonstandardGamepadEvent(const GamepadChangeEvent& aEvent,
|
2017-11-04 01:25:38 +03:00
|
|
|
nsGlobalWindowInner* aWindow);
|
2017-04-21 06:34:30 +03:00
|
|
|
|
2017-11-04 01:25:38 +03:00
|
|
|
bool SetGamepadByEvent(const GamepadChangeEvent& aEvent,
|
|
|
|
nsGlobalWindowInner* aWindow = nullptr);
|
2017-04-21 06:34:30 +03:00
|
|
|
|
2017-11-04 01:25:38 +03:00
|
|
|
bool MaybeWindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex);
|
2016-06-28 01:25:00 +03:00
|
|
|
// Returns true if we have already sent data from this gamepad
|
|
|
|
// to this window. This should only return true if the user
|
|
|
|
// explicitly interacted with a gamepad while this window
|
|
|
|
// was focused, by pressing buttons or similar actions.
|
2017-11-04 01:25:38 +03:00
|
|
|
bool WindowHasSeenGamepad(nsGlobalWindowInner* aWindow,
|
|
|
|
uint32_t aIndex) const;
|
2016-10-05 22:24:16 +03:00
|
|
|
// Indicate that a window has received data from a gamepad.
|
2017-11-04 01:25:38 +03:00
|
|
|
void SetWindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex,
|
2016-06-28 01:25:00 +03:00
|
|
|
bool aHasSeen = true);
|
|
|
|
|
|
|
|
// Gamepads connected to the system. Copies of these are handed out
|
|
|
|
// to each window.
|
|
|
|
nsRefPtrHashtable<nsUint32HashKey, Gamepad> mGamepads;
|
|
|
|
// Inner windows that are listening for gamepad events.
|
|
|
|
// has been sent to that window.
|
2017-11-04 01:25:38 +03:00
|
|
|
nsTArray<RefPtr<nsGlobalWindowInner>> mListeners;
|
2017-02-02 09:59:44 +03:00
|
|
|
uint32_t mPromiseID;
|
2016-06-28 01:25:00 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_dom_GamepadManager_h_
|