new file mode 100644
--- /dev/null
+++ b/dom/base/Pose.cpp
@@ -0,0 +1,94 @@
+/* -*- 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/. */
+
+#include "mozilla/HoldDropJSObjects.h"
+#include "mozilla/dom/TypedArray.h"
+#include "mozilla/dom/PoseBinding.h"
+#include "mozilla/dom/Pose.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(Pose)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Pose)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+ tmp->mPosition = nullptr;
+ tmp->mLinearVelocity = nullptr;
+ tmp->mLinearAcceleration = nullptr;
+ tmp->mOrientation = nullptr;
+ tmp->mAngularVelocity = nullptr;
+ tmp->mAngularAcceleration = nullptr;
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Pose)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Pose)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+ NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPosition)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLinearVelocity)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLinearAcceleration)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mOrientation)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAngularVelocity)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAngularAcceleration)
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Pose, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Pose, Release)
+
+
+Pose::Pose(nsISupports* aParent)
+ : mParent(aParent),
+ mPosition(nullptr),
+ mLinearVelocity(nullptr),
+ mLinearAcceleration(nullptr),
+ mOrientation(nullptr),
+ mAngularVelocity(nullptr),
+ mAngularAcceleration(nullptr)
+{
+ mozilla::HoldJSObjects(this);
+}
+
+Pose::~Pose()
+{
+ mozilla::DropJSObjects(this);
+}
+
+nsISupports*
+Pose::GetParentObject() const
+{
+ return mParent;
+}
+
+void
+Pose::SetFloat32Array(JSContext* aJSContext, JS::MutableHandle<JSObject*> aRetVal,
+ JS::Heap<JSObject*>& aObj, float* aVal, uint32_t sizeOfVal,
+ bool bCreate, ErrorResult& aRv)
+{
+ if (bCreate) {
+ aObj = Float32Array::Create(aJSContext, this,
+ sizeOfVal, aVal);
+ if (!aObj) {
+ aRv.NoteJSContextException(aJSContext);
+ return;
+ }
+ }
+
+ aRetVal.set(aObj);
+}
+
+/* virtual */ JSObject*
+Pose::WrapObject(JSContext* aJSContext, JS::Handle<JSObject*> aGivenProto)
+{
+ return PoseBinding::Wrap(aJSContext, this, aGivenProto);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/base/Pose.h
@@ -0,0 +1,67 @@
+/* -*- 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_Pose_h
+#define mozilla_dom_Pose_h
+
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+namespace dom {
+
+class Pose : public nsWrapperCache
+{
+public:
+ explicit Pose(nsISupports* aParent);
+
+ NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Pose)
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(Pose)
+
+ nsISupports* GetParentObject() const;
+
+ virtual void GetPosition(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) = 0;
+ virtual void GetLinearVelocity(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) = 0;
+ virtual void GetLinearAcceleration(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) = 0;
+ virtual void GetOrientation(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) = 0;
+ virtual void GetAngularVelocity(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) = 0;
+ virtual void GetAngularAcceleration(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) = 0;
+
+ virtual JSObject* WrapObject(JSContext* aJSContext,
+ JS::Handle<JSObject*> aGivenProto) override;
+
+protected:
+ virtual ~Pose();
+
+ void SetFloat32Array(JSContext* aJSContext, JS::MutableHandle<JSObject*> aRetVal,
+ JS::Heap<JSObject*>& aObj, float* aVal, uint32_t sizeOfVal,
+ bool bCreate, ErrorResult& aRv);
+
+ nsCOMPtr<nsISupports> mParent;
+
+ JS::Heap<JSObject*> mPosition;
+ JS::Heap<JSObject*> mLinearVelocity;
+ JS::Heap<JSObject*> mLinearAcceleration;
+ JS::Heap<JSObject*> mOrientation;
+ JS::Heap<JSObject*> mAngularVelocity;
+ JS::Heap<JSObject*> mAngularAcceleration;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_Pose_h
--- a/dom/base/Timeout.cpp
+++ b/dom/base/Timeout.cpp
@@ -4,17 +4,16 @@
* 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/. */
#include "Timeout.h"
#include "nsGlobalWindow.h"
#include "nsITimeoutHandler.h"
#include "nsITimer.h"
-#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
Timeout::Timeout()
: mCleared(false),
mRunning(false),
mIsInterval(false),
--- a/dom/base/Timeout.h
+++ b/dom/base/Timeout.h
@@ -6,21 +6,23 @@
#ifndef mozilla_dom_timeout_h
#define mozilla_dom_timeout_h
#include "mozilla/LinkedList.h"
#include "mozilla/TimeStamp.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
+#include "nsPIDOMWindow.h"
class nsGlobalWindow;
class nsIPrincipal;
class nsITimeoutHandler;
class nsITimer;
+class nsIEventTarget;
namespace mozilla {
namespace dom {
/*
* Timeout struct that holds information about each script
* timeout. Holds a strong reference to an nsITimeoutHandler, which
* abstracts the language specific cruft.
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -196,16 +196,17 @@ EXPORTS.mozilla.dom += [
'MutableBlobStorage.h',
'MutableBlobStreamListener.h',
'NameSpaceConstants.h',
'Navigator.h',
'NodeInfo.h',
'NodeInfoInlines.h',
'NodeIterator.h',
'PartialSHistory.h',
+ 'Pose.h',
'ProcessGlobal.h',
'ResponsiveImageSelector.h',
'SameProcessMessageQueue.h',
'ScreenOrientation.h',
'ScriptSettings.h',
'ShadowRoot.h',
'StructuredCloneHolder.h',
'StructuredCloneTags.h',
@@ -340,16 +341,17 @@ UNIFIED_SOURCES += [
'nsViewportInfo.cpp',
'nsWindowMemoryReporter.cpp',
'nsWindowRoot.cpp',
'nsWrapperCache.cpp',
'nsXHTMLContentSerializer.cpp',
'nsXMLContentSerializer.cpp',
'nsXMLNameSpaceMap.cpp',
'PartialSHistory.cpp',
+ 'Pose.cpp',
'PostMessageEvent.cpp',
'ProcessGlobal.cpp',
'ResponsiveImageSelector.cpp',
'SameProcessMessageQueue.cpp',
'ScreenOrientation.cpp',
'ScriptSettings.cpp',
'ShadowRoot.cpp',
'StructuredCloneHolder.cpp',
--- a/dom/gamepad/Gamepad.cpp
+++ b/dom/gamepad/Gamepad.cpp
@@ -16,17 +16,17 @@ namespace dom {
NS_IMPL_CYCLE_COLLECTING_ADDREF(Gamepad)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Gamepad)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Gamepad)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Gamepad, mParent, mButtons)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Gamepad, mParent, mButtons, mPose)
void
Gamepad::UpdateTimestamp()
{
nsCOMPtr<nsPIDOMWindowInner> newWindow(do_QueryInterface(mParent));
if(newWindow) {
Performance* perf = newWindow->GetPerformance();
if (perf) {
@@ -47,16 +47,17 @@ Gamepad::Gamepad(nsISupports* aParent,
mButtons(aNumButtons),
mAxes(aNumAxes),
mTimestamp(0)
{
for (unsigned i = 0; i < aNumButtons; i++) {
mButtons.InsertElementAt(i, new GamepadButton(mParent));
}
mAxes.InsertElementsAt(0, aNumAxes, 0.0f);
+ mPose = new GamepadPose(aParent);
UpdateTimestamp();
}
void
Gamepad::SetIndex(uint32_t aIndex)
{
mIndex = aIndex;
}
@@ -83,36 +84,51 @@ Gamepad::SetAxis(uint32_t aAxis, double
if (mAxes[aAxis] != aValue) {
mAxes[aAxis] = aValue;
GamepadBinding::ClearCachedAxesValue(this);
}
UpdateTimestamp();
}
void
+Gamepad::SetPose(const GamepadPoseState& aPose)
+{
+ mPose->SetPoseState(aPose);
+}
+
+void
Gamepad::SyncState(Gamepad* aOther)
{
+ const char* kGamepadExtEnabledPref = "dom.gamepad.extensions.enabled";
+
if (mButtons.Length() != aOther->mButtons.Length() ||
mAxes.Length() != aOther->mAxes.Length()) {
return;
}
mConnected = aOther->mConnected;
for (uint32_t i = 0; i < mButtons.Length(); ++i) {
mButtons[i]->SetPressed(aOther->mButtons[i]->Pressed());
mButtons[i]->SetValue(aOther->mButtons[i]->Value());
}
+
bool changed = false;
for (uint32_t i = 0; i < mAxes.Length(); ++i) {
changed = changed || (mAxes[i] != aOther->mAxes[i]);
mAxes[i] = aOther->mAxes[i];
}
if (changed) {
GamepadBinding::ClearCachedAxesValue(this);
}
+
+ if (Preferences::GetBool(kGamepadExtEnabledPref)) {
+ MOZ_ASSERT(aOther->GetPose());
+ mPose->SetPoseState(aOther->GetPose()->GetPoseState());
+ }
+
UpdateTimestamp();
}
already_AddRefed<Gamepad>
Gamepad::Clone(nsISupports* aParent)
{
RefPtr<Gamepad> out =
new Gamepad(aParent, mID, mIndex, mMapping,
--- a/dom/gamepad/Gamepad.h
+++ b/dom/gamepad/Gamepad.h
@@ -5,16 +5,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_gamepad_Gamepad_h
#define mozilla_dom_gamepad_Gamepad_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/GamepadBinding.h"
#include "mozilla/dom/GamepadButton.h"
+#include "mozilla/dom/GamepadPose.h"
#include "mozilla/dom/Performance.h"
#include <stdint.h>
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsWrapperCache.h"
namespace mozilla {
@@ -44,16 +45,17 @@ public:
uint32_t aNumButtons, uint32_t aNumAxes);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Gamepad)
void SetConnected(bool aConnected);
void SetButton(uint32_t aButton, bool aPressed, double aValue);
void SetAxis(uint32_t aAxis, double aValue);
void SetIndex(uint32_t aIndex);
+ void SetPose(const GamepadPoseState& aPose);
// Make the state of this gamepad equivalent to other.
void SyncState(Gamepad* aOther);
// Return a new Gamepad containing the same data as this object,
// parented to aParent.
already_AddRefed<Gamepad> Clone(nsISupports* aParent);
@@ -94,16 +96,21 @@ public:
aButtons = mButtons;
}
void GetAxes(nsTArray<double>& aAxes) const
{
aAxes = mAxes;
}
+ GamepadPose* GetPose() const
+ {
+ return mPose;
+ }
+
private:
virtual ~Gamepad() {}
void UpdateTimestamp();
protected:
nsCOMPtr<nsISupports> mParent;
nsString mID;
uint32_t mIndex;
@@ -113,14 +120,15 @@ protected:
// true if this gamepad is currently connected.
bool mConnected;
// Current state of buttons, axes.
nsTArray<RefPtr<GamepadButton>> mButtons;
nsTArray<double> mAxes;
DOMHighResTimeStamp mTimestamp;
+ RefPtr<GamepadPose> mPose;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_gamepad_Gamepad_h
new file mode 100644
--- /dev/null
+++ b/dom/gamepad/GamepadPose.cpp
@@ -0,0 +1,120 @@
+/* -*- 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/. */
+
+#include "nsWrapperCache.h"
+
+#include "mozilla/HoldDropJSObjects.h"
+#include "mozilla/dom/GamepadPoseBinding.h"
+#include "mozilla/dom/GamepadPose.h"
+
+namespace mozilla {
+namespace dom {
+
+GamepadPose::GamepadPose(nsISupports* aParent, const GamepadPoseState& aState)
+ : Pose(aParent),
+ mPoseState(aState)
+{
+ mozilla::HoldJSObjects(this);
+}
+
+GamepadPose::GamepadPose(nsISupports* aParent)
+ : Pose(aParent)
+{
+ mozilla::HoldJSObjects(this);
+ mPoseState.Clear();
+}
+
+GamepadPose::~GamepadPose()
+{
+ mozilla::DropJSObjects(this);
+}
+
+/* virtual */ JSObject*
+GamepadPose::WrapObject(JSContext* aJSContext, JS::Handle<JSObject*> aGivenProto)
+{
+ return GamepadPoseBinding::Wrap(aJSContext, this, aGivenProto);
+}
+
+bool
+GamepadPose::HasOrientation() const
+{
+ return bool(mPoseState.flags & GamepadCapabilityFlags::Cap_Position);
+}
+
+bool
+GamepadPose::HasPosition() const
+{
+ return bool(mPoseState.flags & GamepadCapabilityFlags::Cap_Orientation);
+}
+
+void
+GamepadPose::GetPosition(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv)
+{
+ SetFloat32Array(aJSContext, aRetval, mPosition, mPoseState.position, 3,
+ bool(mPoseState.flags & GamepadCapabilityFlags::Cap_Position), aRv);
+}
+
+void
+GamepadPose::GetLinearVelocity(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv)
+{
+ SetFloat32Array(aJSContext, aRetval, mLinearVelocity, mPoseState.linearVelocity, 3,
+ bool(mPoseState.flags & GamepadCapabilityFlags::Cap_Position), aRv);
+}
+
+void
+GamepadPose::GetLinearAcceleration(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv)
+{
+ SetFloat32Array(aJSContext, aRetval, mLinearAcceleration, mPoseState.linearAcceleration, 3,
+ bool(mPoseState.flags & GamepadCapabilityFlags::Cap_LinearAcceleration), aRv);
+}
+
+void
+GamepadPose::GetOrientation(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv)
+{
+ SetFloat32Array(aJSContext, aRetval, mOrientation, mPoseState.orientation, 4,
+ bool(mPoseState.flags & GamepadCapabilityFlags::Cap_Orientation), aRv);
+}
+
+void
+GamepadPose::GetAngularVelocity(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv)
+{
+ SetFloat32Array(aJSContext, aRetval, mAngularVelocity, mPoseState.angularVelocity, 3,
+ bool(mPoseState.flags & GamepadCapabilityFlags::Cap_Orientation), aRv);
+}
+
+void
+GamepadPose::GetAngularAcceleration(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv)
+{
+ SetFloat32Array(aJSContext, aRetval, mAngularAcceleration, mPoseState.angularAcceleration, 3,
+ bool(mPoseState.flags & GamepadCapabilityFlags::Cap_AngularAcceleration), aRv);
+}
+
+void
+GamepadPose::SetPoseState(const GamepadPoseState& aPose)
+{
+ mPoseState = aPose;
+}
+
+const GamepadPoseState&
+GamepadPose::GetPoseState()
+{
+ return mPoseState;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/gamepad/GamepadPose.h
@@ -0,0 +1,58 @@
+/* -*- 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_gamepad_GamepadPose_h
+#define mozilla_dom_gamepad_GamepadPose_h
+
+#include "mozilla/TypedEnumBits.h"
+#include "mozilla/dom/Pose.h"
+#include "mozilla/dom/GamepadPoseState.h"
+
+namespace mozilla {
+namespace dom {
+
+class GamepadPose final : public Pose
+{
+public:
+ GamepadPose(nsISupports* aParent, const GamepadPoseState& aState);
+ explicit GamepadPose(nsISupports* aParent);
+
+ virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+ bool HasOrientation() const;
+ bool HasPosition() const;
+ virtual void GetPosition(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetLinearVelocity(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetLinearAcceleration(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetOrientation(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetAngularVelocity(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetAngularAcceleration(JSContext* aJSContext,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ void SetPoseState(const GamepadPoseState& aPose);
+ const GamepadPoseState& GetPoseState();
+
+private:
+ virtual ~GamepadPose();
+
+ nsCOMPtr<nsISupports> mParent;
+ GamepadPoseState mPoseState;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_gamepad_GamepadPose_h
new file mode 100644
--- /dev/null
+++ b/dom/gamepad/GamepadPoseState.h
@@ -0,0 +1,88 @@
+
+#ifndef mozilla_dom_gamepad_GamepadPoseState_h_
+#define mozilla_dom_gamepad_GamepadPoseState_h_
+
+namespace mozilla{
+namespace dom{
+
+enum class GamepadCapabilityFlags : uint16_t {
+ Cap_None = 0,
+ /**
+ * Cap_Position is set if the Gamepad is capable of tracking its position.
+ */
+ Cap_Position = 1 << 1,
+ /**
+ * Cap_Orientation is set if the Gamepad is capable of tracking its orientation.
+ */
+ Cap_Orientation = 1 << 2,
+ /**
+ * Cap_AngularAcceleration is set if the Gamepad is capable of tracking its
+ * angular acceleration.
+ */
+ Cap_AngularAcceleration = 1 << 3,
+ /**
+ * Cap_LinearAcceleration is set if the Gamepad is capable of tracking its
+ * linear acceleration.
+ */
+ Cap_LinearAcceleration = 1 << 4,
+ /**
+ * Cap_All used for validity checking during IPC serialization
+ */
+ Cap_All = (1 << 5) - 1
+};
+
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(GamepadCapabilityFlags)
+
+struct GamepadPoseState
+{
+ GamepadCapabilityFlags flags;
+ float orientation[4];
+ float position[3];
+ float angularVelocity[3];
+ float angularAcceleration[3];
+ float linearVelocity[3];
+ float linearAcceleration[3];
+
+ GamepadPoseState()
+ {
+ Clear();
+ }
+
+ bool operator==(const GamepadPoseState& aPose) const
+ {
+ return flags == aPose.flags
+ && orientation[0] == aPose.orientation[0]
+ && orientation[1] == aPose.orientation[1]
+ && orientation[2] == aPose.orientation[2]
+ && orientation[3] == aPose.orientation[3]
+ && position[0] == aPose.position[0]
+ && position[1] == aPose.position[1]
+ && position[2] == aPose.position[2]
+ && angularVelocity[0] == aPose.angularVelocity[0]
+ && angularVelocity[1] == aPose.angularVelocity[1]
+ && angularVelocity[2] == aPose.angularVelocity[2]
+ && angularAcceleration[0] == aPose.angularAcceleration[0]
+ && angularAcceleration[1] == aPose.angularAcceleration[1]
+ && angularAcceleration[2] == aPose.angularAcceleration[2]
+ && linearVelocity[0] == aPose.linearVelocity[0]
+ && linearVelocity[1] == aPose.linearVelocity[1]
+ && linearVelocity[2] == aPose.linearVelocity[2]
+ && linearAcceleration[0] == aPose.linearAcceleration[0]
+ && linearAcceleration[1] == aPose.linearAcceleration[1]
+ && linearAcceleration[2] == aPose.linearAcceleration[2];
+ }
+
+ bool operator!=(const GamepadPoseState& aPose) const
+ {
+ return !(*this == aPose);
+ }
+
+ void Clear() {
+ memset(this, 0, sizeof(GamepadPoseState));
+ }
+};
+
+}// namespace dom
+}// namespace mozilla
+
+#endif // mozilla_dom_gamepad_GamepadPoseState_h_
\ No newline at end of file
--- a/dom/gamepad/ipc/GamepadMessageUtils.h
+++ b/dom/gamepad/ipc/GamepadMessageUtils.h
@@ -1,14 +1,15 @@
#ifndef mozilla_dom_gamepad_GamepadMessageUtils_h
#define mozilla_dom_gamepad_GamepadMessageUtils_h
#include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/GamepadServiceType.h"
+#include "mozilla/dom/GamepadPoseState.h"
namespace IPC {
template<>
struct ParamTraits<mozilla::dom::GamepadServiceType> :
public ContiguousEnumSerializer<mozilla::dom::GamepadServiceType,
mozilla::dom::GamepadServiceType(0),
mozilla::dom::GamepadServiceType(
--- a/dom/gamepad/moz.build
+++ b/dom/gamepad/moz.build
@@ -6,40 +6,43 @@
IPDL_SOURCES += [
'ipc/GamepadEventTypes.ipdlh',
'ipc/PGamepadEventChannel.ipdl',
'ipc/PGamepadTestChannel.ipdl'
]
EXPORTS.mozilla.dom += [
+ 'GamepadPoseState.h',
'ipc/GamepadMessageUtils.h',
'ipc/GamepadServiceType.h'
]
if CONFIG['MOZ_GAMEPAD']:
EXPORTS.mozilla.dom += [
'Gamepad.h',
'GamepadButton.h',
'GamepadManager.h',
'GamepadMonitoring.h',
'GamepadPlatformService.h',
+ 'GamepadPose.h',
'GamepadServiceTest.h',
'ipc/GamepadEventChannelChild.h',
'ipc/GamepadEventChannelParent.h',
'ipc/GamepadTestChannelChild.h',
'ipc/GamepadTestChannelParent.h'
]
UNIFIED_SOURCES = [
'Gamepad.cpp',
'GamepadButton.cpp',
'GamepadManager.cpp',
'GamepadMonitoring.cpp',
'GamepadPlatformService.cpp',
+ 'GamepadPose.cpp',
'GamepadServiceTest.cpp',
'ipc/GamepadEventChannelChild.cpp',
'ipc/GamepadEventChannelParent.cpp',
'ipc/GamepadTestChannelChild.cpp',
'ipc/GamepadTestChannelParent.cpp'
]
if CONFIG['MOZ_GAMEPAD_BACKEND'] == 'stub':
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -400,16 +400,18 @@ var interfaceNamesInGlobalScope =
"GamepadAxisMoveEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"GamepadButtonEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"GamepadButton",
// IMPORTANT: Do not change this list without review from a DOM peer!
"GamepadEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
+ {name: "GamepadPose", release: false},
+// IMPORTANT: Do not change this list without review from a DOM peer!
"HashChangeEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Headers",
// IMPORTANT: Do not change this list without review from a DOM peer!
"History",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLAllCollection",
// IMPORTANT: Do not change this list without review from a DOM peer!
@@ -770,16 +772,18 @@ var interfaceNamesInGlobalScope =
{name: "PointerEvent", nightly: true, desktop: true, disabled: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
"PopStateEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"PopupBlockedEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PopupBoxObject", xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
+ {name: "Pose", release: false},
+// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PresentationDeviceInfoManager",
disabled: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Presentation", disabled: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PresentationAvailability", disabled: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PresentationConnection", disabled: true},
--- a/dom/vr/VRDisplay.cpp
+++ b/dom/vr/VRDisplay.cpp
@@ -251,174 +251,96 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRD
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRDisplayCapabilities, Release)
JSObject*
VRDisplayCapabilities::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return VRDisplayCapabilitiesBinding::Wrap(aCx, this, aGivenProto);
}
-NS_IMPL_CYCLE_COLLECTION_CLASS(VRPose)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRPose)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
- tmp->mPosition = nullptr;
- tmp->mLinearVelocity = nullptr;
- tmp->mLinearAcceleration = nullptr;
- tmp->mOrientation = nullptr;
- tmp->mAngularVelocity = nullptr;
- tmp->mAngularAcceleration = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRPose)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRPose)
- NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPosition)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLinearVelocity)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLinearAcceleration)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mOrientation)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAngularVelocity)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAngularAcceleration)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRPose, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRPose, Release)
-
VRPose::VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
- : mParent(aParent)
+ : Pose(aParent)
, mVRState(aState)
- , mPosition(nullptr)
- , mLinearVelocity(nullptr)
- , mLinearAcceleration(nullptr)
- , mOrientation(nullptr)
- , mAngularVelocity(nullptr)
- , mAngularAcceleration(nullptr)
{
mFrameId = aState.inputFrameID;
mozilla::HoldJSObjects(this);
}
VRPose::VRPose(nsISupports* aParent)
- : mParent(aParent)
- , mPosition(nullptr)
- , mLinearVelocity(nullptr)
- , mLinearAcceleration(nullptr)
- , mOrientation(nullptr)
- , mAngularVelocity(nullptr)
- , mAngularAcceleration(nullptr)
+ : Pose(aParent)
{
mFrameId = 0;
mVRState.Clear();
mozilla::HoldJSObjects(this);
}
VRPose::~VRPose()
{
mozilla::DropJSObjects(this);
}
void
VRPose::GetPosition(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
- if (!mPosition && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
- // Lazily create the Float32Array
- mPosition = dom::Float32Array::Create(aCx, this, 3, mVRState.position);
- if (!mPosition) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mPosition);
+ SetFloat32Array(aCx, aRetval, mPosition, mVRState.position, 3,
+ !mPosition && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position),
+ aRv);
}
void
VRPose::GetLinearVelocity(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
- if (!mLinearVelocity && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
- // Lazily create the Float32Array
- mLinearVelocity = dom::Float32Array::Create(aCx, this, 3, mVRState.linearVelocity);
- if (!mLinearVelocity) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mLinearVelocity);
+ SetFloat32Array(aCx, aRetval, mLinearVelocity, mVRState.linearVelocity, 3,
+ !mLinearVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position),
+ aRv);
}
void
VRPose::GetLinearAcceleration(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
- if (!mLinearAcceleration && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_LinearAcceleration) {
- // Lazily create the Float32Array
- mLinearAcceleration = dom::Float32Array::Create(aCx, this, 3, mVRState.linearAcceleration);
- if (!mLinearAcceleration) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mLinearAcceleration);
+ SetFloat32Array(aCx, aRetval, mLinearAcceleration, mVRState.linearAcceleration, 3,
+ !mLinearAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_LinearAcceleration),
+ aRv);
+
}
void
VRPose::GetOrientation(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
- if (!mOrientation && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
- // Lazily create the Float32Array
- mOrientation = dom::Float32Array::Create(aCx, this, 4, mVRState.orientation);
- if (!mOrientation) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mOrientation);
+ SetFloat32Array(aCx, aRetval, mOrientation, mVRState.orientation, 4,
+ !mOrientation && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation),
+ aRv);
}
void
VRPose::GetAngularVelocity(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
- if (!mAngularVelocity && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
- // Lazily create the Float32Array
- mAngularVelocity = dom::Float32Array::Create(aCx, this, 3, mVRState.angularVelocity);
- if (!mAngularVelocity) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mAngularVelocity);
+ SetFloat32Array(aCx, aRetval, mAngularVelocity, mVRState.angularVelocity, 3,
+ !mAngularVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation),
+ aRv);
}
void
VRPose::GetAngularAcceleration(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
- if (!mAngularAcceleration && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_AngularAcceleration) {
- // Lazily create the Float32Array
- mAngularAcceleration = dom::Float32Array::Create(aCx, this, 3, mVRState.angularAcceleration);
- if (!mAngularAcceleration) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mAngularAcceleration);
+ SetFloat32Array(aCx, aRetval, mAngularAcceleration, mVRState.angularAcceleration, 3,
+ !mAngularAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_AngularAcceleration),
+ aRv);
}
JSObject*
VRPose::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return VRPoseBinding::Wrap(aCx, this, aGivenProto);
}
--- a/dom/vr/VRDisplay.h
+++ b/dom/vr/VRDisplay.h
@@ -10,21 +10,21 @@
#include <stdint.h>
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/VRDisplayBinding.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/DOMPoint.h"
#include "mozilla/dom/DOMRect.h"
+#include "mozilla/dom/Pose.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsTArray.h"
-#include "nsWrapperCache.h"
#include "gfxVR.h"
namespace mozilla {
namespace gfx {
class VRDisplayClient;
class VRDisplayPresentation;
struct VRFieldOfView;
@@ -90,64 +90,51 @@ public:
uint32_t MaxLayers() const;
protected:
~VRDisplayCapabilities() {}
nsCOMPtr<nsISupports> mParent;
gfx::VRDisplayCapabilityFlags mFlags;
};
-class VRPose final : public nsWrapperCache
+class VRPose final : public Pose
{
public:
VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
explicit VRPose(nsISupports* aParent);
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRPose)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRPose)
-
uint32_t FrameID() const { return mFrameId; }
- void GetPosition(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetLinearVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetLinearAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetOrientation(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetAngularVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetAngularAcceleration(JSContext* aCx,
+ virtual void GetPosition(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetLinearVelocity(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetLinearAcceleration(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetOrientation(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
+ ErrorResult& aRv) override;
+ virtual void GetAngularVelocity(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
+ virtual void GetAngularAcceleration(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aRv) override;
- nsISupports* GetParentObject() const { return mParent; }
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
~VRPose();
- nsCOMPtr<nsISupports> mParent;
uint32_t mFrameId;
gfx::VRHMDSensorState mVRState;
-
- JS::Heap<JSObject*> mPosition;
- JS::Heap<JSObject*> mLinearVelocity;
- JS::Heap<JSObject*> mLinearAcceleration;
- JS::Heap<JSObject*> mOrientation;
- JS::Heap<JSObject*> mAngularVelocity;
- JS::Heap<JSObject*> mAngularAcceleration;
-
};
struct VRFrameInfo
{
VRFrameInfo();
void Update(const gfx::VRDisplayInfo& aInfo,
const gfx::VRHMDSensorState& aState,
--- a/dom/webidl/Gamepad.webidl
+++ b/dom/webidl/Gamepad.webidl
@@ -51,9 +51,15 @@ interface Gamepad {
*/
[Pure, Cached, Frozen]
readonly attribute sequence<double> axes;
/**
* Timestamp from when the data of this device was last updated.
*/
readonly attribute DOMHighResTimeStamp timestamp;
+
+ /**
+ * The current pose of the device, a GamepadPose.
+ */
+ [Pref="dom.gamepad.extensions.enabled"]
+ readonly attribute GamepadPose? pose;
};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/GamepadPose.webidl
@@ -0,0 +1,13 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+[Pref="dom.gamepad.extensions.enabled",
+ HeaderFile="mozilla/dom/GamepadPose.h"]
+interface GamepadPose : Pose
+{
+ readonly attribute boolean hasOrientation;
+ readonly attribute boolean hasPosition;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/Pose.webidl
@@ -0,0 +1,23 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+interface Pose
+{
+ /**
+ * position, linearVelocity, and linearAcceleration are 3-component vectors.
+ * position is relative to a sitting space. Transforming this point with
+ * VRStageParameters.sittingToStandingTransform converts this to standing space.
+ */
+ [Constant, Throws] readonly attribute Float32Array? position;
+ [Constant, Throws] readonly attribute Float32Array? linearVelocity;
+ [Constant, Throws] readonly attribute Float32Array? linearAcceleration;
+
+ /* orientation is a 4-entry array representing the components of a quaternion. */
+ [Constant, Throws] readonly attribute Float32Array? orientation;
+ /* angularVelocity and angularAcceleration are the components of 3-dimensional vectors. */
+ [Constant, Throws] readonly attribute Float32Array? angularVelocity;
+ [Constant, Throws] readonly attribute Float32Array? angularAcceleration;
+};
--- a/dom/webidl/VRDisplay.webidl
+++ b/dom/webidl/VRDisplay.webidl
@@ -111,31 +111,19 @@ interface VRStageParameters {
* this rectangle.
*/
readonly attribute float sizeX;
readonly attribute float sizeZ;
};
[Pref="dom.vr.enabled",
HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRPose {
- /**
- * position, linearVelocity, and linearAcceleration are 3-component vectors.
- * position is relative to a sitting space. Transforming this point with
- * VRStageParameters.sittingToStandingTransform converts this to standing space.
- */
- [Constant, Throws] readonly attribute Float32Array? position;
- [Constant, Throws] readonly attribute Float32Array? linearVelocity;
- [Constant, Throws] readonly attribute Float32Array? linearAcceleration;
+interface VRPose : Pose
+{
- /* orientation is a 4-entry array representing the components of a quaternion. */
- [Constant, Throws] readonly attribute Float32Array? orientation;
- /* angularVelocity and angularAcceleration are the components of 3-dimensional vectors. */
- [Constant, Throws] readonly attribute Float32Array? angularVelocity;
- [Constant, Throws] readonly attribute Float32Array? angularAcceleration;
};
[Constructor,
Pref="dom.vr.enabled",
HeaderFile="mozilla/dom/VRDisplay.h"]
interface VRFrameData {
readonly attribute DOMHighResTimeStamp timestamp;
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -362,16 +362,17 @@ WEBIDL_FILES = [
'PeriodicWave.webidl',
'Permissions.webidl',
'PermissionSettings.webidl',
'PermissionStatus.webidl',
'Plugin.webidl',
'PluginArray.webidl',
'PointerEvent.webidl',
'PopupBoxObject.webidl',
+ 'Pose.webidl',
'Position.webidl',
'PositionError.webidl',
'Presentation.webidl',
'PresentationAvailability.webidl',
'PresentationConnection.webidl',
'PresentationConnectionList.webidl',
'PresentationDeviceInfoManager.webidl',
'PresentationReceiver.webidl',
@@ -642,16 +643,17 @@ if CONFIG['MOZ_WEBSPEECH']:
'SpeechSynthesisEvent.webidl',
'SpeechSynthesisUtterance.webidl',
'SpeechSynthesisVoice.webidl',
]
if CONFIG['MOZ_GAMEPAD']:
WEBIDL_FILES += [
'Gamepad.webidl',
+ 'GamepadPose.webidl',
'GamepadServiceTest.webidl'
]
WEBIDL_FILES += [
'CloseEvent.webidl',
'CustomEvent.webidl',
'DeviceOrientationEvent.webidl',
'DeviceStorageChangeEvent.webidl',
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -198,16 +198,17 @@ pref("dom.requestIdleCallback.enabled",
// Whether the Gamepad API is enabled
pref("dom.gamepad.enabled", true);
pref("dom.gamepad.test.enabled", false);
#ifdef RELEASE_OR_BETA
pref("dom.gamepad.non_standard_events.enabled", false);
#else
pref("dom.gamepad.non_standard_events.enabled", true);
#endif
+pref("dom.gamepad.extensions.enabled", false);
// Whether the KeyboardEvent.code is enabled
pref("dom.keyboardevent.code.enabled", true);
// If this is true, TextEventDispatcher dispatches keydown and keyup events
// even during composition (keypress events are never fired during composition
// even if this is true).
pref("dom.keyboardevent.dispatch_during_composition", false);