<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[170465] trunk/Source</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/170465">170465</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2014-06-25 21:49:34 -0700 (Wed, 25 Jun 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Add HID-based gamepad implementation for Mac
https://bugs.webkit.org/show_bug.cgi?id=134324
Reviewed by Dean Jackson.
Source/WebCore:
No new tests (Not yet a tested config)
* Modules/gamepad/Gamepad.cpp:
(WebCore::Gamepad::Gamepad):
(WebCore::Gamepad::updateFromPlatformGamepad): Update the Gamepad’s data from the passed-in PlatformGamepad.
* Modules/gamepad/Gamepad.h:
* Modules/gamepad/GamepadButton.h:
(WebCore::GamepadButton::create): Change to use Ref instead of RefPtr.
GamepadManager is a GamepadStrategyClient that receives notifications from the platform gamepad implementation
and forwards them to NavigatorGamepad objects. In the future it will also handle event dispatch and exposing
gamepads to the API layer when a button is pressed:
* Modules/gamepad/GamepadManager.cpp: Added.
(WebCore::GamepadManager::shared):
(WebCore::GamepadManager::GamepadManager):
(WebCore::GamepadManager::platformGamepadConnected):
(WebCore::GamepadManager::platformGamepadDisconnected):
(WebCore::GamepadManager::registerNavigator):
(WebCore::GamepadManager::unregisterNavigator):
* Modules/gamepad/GamepadManager.h:
The NavigatorGamepad supplement actually manages visibility of Gamepads on a per-DOMWindow basis:
* Modules/gamepad/NavigatorGamepad.cpp:
(WebCore::NavigatorGamepad::NavigatorGamepad):
(WebCore::NavigatorGamepad::~NavigatorGamepad):
(WebCore::NavigatorGamepad::from):
(WebCore::NavigatorGamepad::gamepads):
(WebCore::NavigatorGamepad::gamepadsBecameVisible):
(WebCore::NavigatorGamepad::gamepadConnected):
(WebCore::NavigatorGamepad::gamepadDisconnected):
* Modules/gamepad/NavigatorGamepad.h:
(WebCore::NavigatorGamepad::navigationStart):
HIDGamepad is a PlatformGamepad that wraps an IOHIDDeviceRef and keeps input values updated:
* platform/mac/HIDGamepad.cpp: Added.
(WebCore::HIDGamepad::HIDGamepad):
(WebCore::HIDGamepad::initElements):
(WebCore::HIDGamepad::initElementsFromArray):
(WebCore::HIDGamepad::maybeAddButton):
(WebCore::HIDGamepad::maybeAddAxis):
(WebCore::HIDGamepad::valueChanged):
* platform/mac/HIDGamepad.h: Added.
(WebCore::HIDGamepadElement::HIDGamepadElement):
(WebCore::HIDGamepadElement::~HIDGamepadElement):
(WebCore::HIDGamepadElement::isButton):
(WebCore::HIDGamepadElement::isAxis):
(WebCore::HIDGamepadButton::HIDGamepadButton):
(WebCore::HIDGamepadAxis::HIDGamepadAxis):
(WebCore::HIDGamepad::hidDevice):
HIDGamepadListener wraps an IOHIDManagerRef and continuously listens for changes to Gamepad-type
devices plugged in to the system:
* platform/mac/HIDGamepadListener.cpp: Added.
(WebCore::deviceMatchingDictionary):
(WebCore::deviceAddedCallback):
(WebCore::deviceRemovedCallback):
(WebCore::deviceValuesChangedCallback):
(WebCore::HIDGamepadListener::shared):
(WebCore::HIDGamepadListener::HIDGamepadListener):
(WebCore::HIDGamepadListener::indexForNewlyConnectedDevice):
(WebCore::HIDGamepadListener::deviceAdded):
(WebCore::HIDGamepadListener::deviceRemoved):
(WebCore::HIDGamepadListener::valuesChanged):
(WebCore::HIDGamepadListener::removeGamepadForDevice):
* platform/mac/HIDGamepadListener.h: Copied from Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp.
(WebCore::HIDGamepadListenerClient::~HIDGamepadListenerClient):
(WebCore::HIDGamepadListener::setClient):
(WebCore::HIDGamepadListener::platformGamepads):
(WebCore::HIDGamepadListener::setShouldDispatchCallbacks):
* WebCore.exp.in:
* WebCore.xcodeproj/project.pbxproj:
Source/WebKit:
* WebKit.xcodeproj/project.pbxproj:
Source/WebKit/mac:
Add a class that acts as an intermediary between the GamepadStrategyClient
and the HIDGamepadListener:
* WebCoreSupport/WebHIDGamepadController.h:
* WebCoreSupport/WebHIDGamepadController.mm:
(WebHIDGamepadController::shared):
(WebHIDGamepadController::WebHIDGamepadController):
(WebHIDGamepadController::gamepadConnected):
(WebHIDGamepadController::gamepadDisconnected):
(WebHIDGamepadController::registerGamepadStrategyClient):
(WebHIDGamepadController::unregisterGamepadStrategyClient):
Implement the strategies by using the HIDGamepadListener:
* WebCoreSupport/WebPlatformStrategies.mm:
(WebPlatformStrategies::startMonitoringGamepads):
(WebPlatformStrategies::stopMonitoringGamepads):
(WebPlatformStrategies::platformGamepads):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesgamepadGamepadcpp">trunk/Source/WebCore/Modules/gamepad/Gamepad.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesgamepadGamepadh">trunk/Source/WebCore/Modules/gamepad/Gamepad.h</a></li>
<li><a href="#trunkSourceWebCoreModulesgamepadGamepadButtonh">trunk/Source/WebCore/Modules/gamepad/GamepadButton.h</a></li>
<li><a href="#trunkSourceWebCoreModulesgamepadNavigatorGamepadcpp">trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesgamepadNavigatorGamepadh">trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitWebKitxcodeprojprojectpbxproj">trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebPlatformStrategiesmm">trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesgamepadGamepadManagercpp">trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesgamepadGamepadManagerh">trunk/Source/WebCore/Modules/gamepad/GamepadManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmacHIDGamepadcpp">trunk/Source/WebCore/platform/mac/HIDGamepad.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmacHIDGamepadh">trunk/Source/WebCore/platform/mac/HIDGamepad.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmacHIDGamepadListenercpp">trunk/Source/WebCore/platform/mac/HIDGamepadListener.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmacHIDGamepadListenerh">trunk/Source/WebCore/platform/mac/HIDGamepadListener.h</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebHIDGamepadControllerh">trunk/Source/WebKit/mac/WebCoreSupport/WebHIDGamepadController.h</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebHIDGamepadControllermm">trunk/Source/WebKit/mac/WebCoreSupport/WebHIDGamepadController.mm</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebCore/ChangeLog        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -1,3 +1,84 @@
</span><ins>+2014-06-25 Brady Eidson <beidson@apple.com>
+
+ Add HID-based gamepad implementation for Mac
+ https://bugs.webkit.org/show_bug.cgi?id=134324
+
+ Reviewed by Dean Jackson.
+
+ No new tests (Not yet a tested config)
+
+ * Modules/gamepad/Gamepad.cpp:
+ (WebCore::Gamepad::Gamepad):
+ (WebCore::Gamepad::updateFromPlatformGamepad): Update the Gamepad’s data from the passed-in PlatformGamepad.
+ * Modules/gamepad/Gamepad.h:
+
+ * Modules/gamepad/GamepadButton.h:
+ (WebCore::GamepadButton::create): Change to use Ref instead of RefPtr.
+
+ GamepadManager is a GamepadStrategyClient that receives notifications from the platform gamepad implementation
+ and forwards them to NavigatorGamepad objects. In the future it will also handle event dispatch and exposing
+ gamepads to the API layer when a button is pressed:
+ * Modules/gamepad/GamepadManager.cpp: Added.
+ (WebCore::GamepadManager::shared):
+ (WebCore::GamepadManager::GamepadManager):
+ (WebCore::GamepadManager::platformGamepadConnected):
+ (WebCore::GamepadManager::platformGamepadDisconnected):
+ (WebCore::GamepadManager::registerNavigator):
+ (WebCore::GamepadManager::unregisterNavigator):
+ * Modules/gamepad/GamepadManager.h:
+
+ The NavigatorGamepad supplement actually manages visibility of Gamepads on a per-DOMWindow basis:
+ * Modules/gamepad/NavigatorGamepad.cpp:
+ (WebCore::NavigatorGamepad::NavigatorGamepad):
+ (WebCore::NavigatorGamepad::~NavigatorGamepad):
+ (WebCore::NavigatorGamepad::from):
+ (WebCore::NavigatorGamepad::gamepads):
+ (WebCore::NavigatorGamepad::gamepadsBecameVisible):
+ (WebCore::NavigatorGamepad::gamepadConnected):
+ (WebCore::NavigatorGamepad::gamepadDisconnected):
+ * Modules/gamepad/NavigatorGamepad.h:
+ (WebCore::NavigatorGamepad::navigationStart):
+
+ HIDGamepad is a PlatformGamepad that wraps an IOHIDDeviceRef and keeps input values updated:
+ * platform/mac/HIDGamepad.cpp: Added.
+ (WebCore::HIDGamepad::HIDGamepad):
+ (WebCore::HIDGamepad::initElements):
+ (WebCore::HIDGamepad::initElementsFromArray):
+ (WebCore::HIDGamepad::maybeAddButton):
+ (WebCore::HIDGamepad::maybeAddAxis):
+ (WebCore::HIDGamepad::valueChanged):
+ * platform/mac/HIDGamepad.h: Added.
+ (WebCore::HIDGamepadElement::HIDGamepadElement):
+ (WebCore::HIDGamepadElement::~HIDGamepadElement):
+ (WebCore::HIDGamepadElement::isButton):
+ (WebCore::HIDGamepadElement::isAxis):
+ (WebCore::HIDGamepadButton::HIDGamepadButton):
+ (WebCore::HIDGamepadAxis::HIDGamepadAxis):
+ (WebCore::HIDGamepad::hidDevice):
+
+ HIDGamepadListener wraps an IOHIDManagerRef and continuously listens for changes to Gamepad-type
+ devices plugged in to the system:
+ * platform/mac/HIDGamepadListener.cpp: Added.
+ (WebCore::deviceMatchingDictionary):
+ (WebCore::deviceAddedCallback):
+ (WebCore::deviceRemovedCallback):
+ (WebCore::deviceValuesChangedCallback):
+ (WebCore::HIDGamepadListener::shared):
+ (WebCore::HIDGamepadListener::HIDGamepadListener):
+ (WebCore::HIDGamepadListener::indexForNewlyConnectedDevice):
+ (WebCore::HIDGamepadListener::deviceAdded):
+ (WebCore::HIDGamepadListener::deviceRemoved):
+ (WebCore::HIDGamepadListener::valuesChanged):
+ (WebCore::HIDGamepadListener::removeGamepadForDevice):
+ * platform/mac/HIDGamepadListener.h: Copied from Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp.
+ (WebCore::HIDGamepadListenerClient::~HIDGamepadListenerClient):
+ (WebCore::HIDGamepadListener::setClient):
+ (WebCore::HIDGamepadListener::platformGamepads):
+ (WebCore::HIDGamepadListener::setShouldDispatchCallbacks):
+
+ * WebCore.exp.in:
+ * WebCore.xcodeproj/project.pbxproj:
+
</ins><span class="cx"> 2014-06-25 Ryosuke Niwa <rniwa@webkit.org>
</span><span class="cx">
</span><span class="cx"> WebProgressTracker updates progress too frequently
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesgamepadGamepadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/gamepad/Gamepad.cpp (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/gamepad/Gamepad.cpp        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebCore/Modules/gamepad/Gamepad.cpp        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -28,15 +28,22 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(GAMEPAD)
</span><span class="cx">
</span><ins>+#include "GamepadButton.h"
+#include "PlatformGamepad.h"
</ins><span class="cx"> #include <wtf/text/WTFString.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-Gamepad::Gamepad()
- : m_index(0)
</del><ins>+Gamepad::Gamepad(const PlatformGamepad& platformGamepad, unsigned index)
+ : m_id(platformGamepad.id())
+ , m_index(index)
</ins><span class="cx"> , m_connected(true)
</span><del>- , m_timestamp(0.0)
</del><ins>+ , m_timestamp(platformGamepad.lastUpdateTime())
</ins><span class="cx"> {
</span><ins>+ m_axes.resize(platformGamepad.axisValues().size());
+ unsigned buttonCount = platformGamepad.buttonValues().size();
+ for (unsigned i = 0; i < buttonCount; ++i)
+ m_buttons.append(GamepadButton::create());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Gamepad::~Gamepad()
</span><span class="lines">@@ -53,6 +60,16 @@
</span><span class="cx"> return m_buttons;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void Gamepad::updateFromPlatformGamepad(const PlatformGamepad& platformGamepad)
+{
+ for (unsigned i = 0; i < m_axes.size(); ++i)
+ m_axes[i] = platformGamepad.axisValues()[i];
+ for (unsigned i = 0; i < m_buttons.size(); ++i)
+ m_buttons[i]->setValue(platformGamepad.buttonValues()[i]);
+
+ m_timestamp = platformGamepad.lastUpdateTime();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(GAMEPAD)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesgamepadGamepadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/gamepad/Gamepad.h (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/gamepad/Gamepad.h        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebCore/Modules/gamepad/Gamepad.h        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -28,18 +28,20 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(GAMEPAD)
</span><span class="cx">
</span><del>-#include "GamepadButton.h"
-#include <wtf/Ref.h>
</del><ins>+#include <wtf/RefCounted.h>
</ins><span class="cx"> #include <wtf/Vector.h>
</span><span class="cx"> #include <wtf/text/WTFString.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><ins>+class GamepadButton;
+class PlatformGamepad;
+
</ins><span class="cx"> class Gamepad: public RefCounted<Gamepad> {
</span><span class="cx"> public:
</span><del>- static PassRefPtr<Gamepad> create()
</del><ins>+ static PassRefPtr<Gamepad> create(const PlatformGamepad& platformGamepad, unsigned index)
</ins><span class="cx"> {
</span><del>- return adoptRef(new Gamepad);
</del><ins>+ return adoptRef(new Gamepad(platformGamepad, index));
</ins><span class="cx"> }
</span><span class="cx"> ~Gamepad();
</span><span class="cx">
</span><span class="lines">@@ -52,8 +54,10 @@
</span><span class="cx"> const Vector<double>& axes() const;
</span><span class="cx"> const Vector<Ref<GamepadButton>>& buttons() const;
</span><span class="cx">
</span><ins>+ void updateFromPlatformGamepad(const PlatformGamepad&);
+
</ins><span class="cx"> private:
</span><del>- Gamepad();
</del><ins>+ Gamepad(const PlatformGamepad&, unsigned index);
</ins><span class="cx"> String m_id;
</span><span class="cx"> unsigned m_index;
</span><span class="cx"> bool m_connected;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesgamepadGamepadButtonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/gamepad/GamepadButton.h (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/gamepad/GamepadButton.h        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebCore/Modules/gamepad/GamepadButton.h        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -28,16 +28,16 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(GAMEPAD)
</span><span class="cx">
</span><del>-#include <wtf/PassRefPtr.h>
</del><ins>+#include <wtf/PassRef.h>
</ins><span class="cx"> #include <wtf/RefCounted.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> class GamepadButton : public RefCounted<GamepadButton> {
</span><span class="cx"> public:
</span><del>- static PassRefPtr<GamepadButton> create()
</del><ins>+ static PassRef<GamepadButton> create()
</ins><span class="cx"> {
</span><del>- return adoptRef(new GamepadButton);
</del><ins>+ return adoptRef(*new GamepadButton);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool pressed() const;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesgamepadGamepadManagercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp (0 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp         (rev 0)
+++ trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -0,0 +1,91 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#include "GamepadManager.h"
+
+#if ENABLE(GAMEPAD)
+
+#include "Gamepad.h"
+#include "GamepadStrategy.h"
+#include "NavigatorGamepad.h"
+#include "PlatformGamepad.h"
+#include "PlatformStrategies.h"
+
+namespace WebCore {
+
+GamepadManager& GamepadManager::shared()
+{
+ static NeverDestroyed<GamepadManager> sharedManager;
+ return sharedManager;
+}
+
+GamepadManager::GamepadManager()
+{
+ platformStrategies()->gamepadStrategy()->stopMonitoringGamepads(this);
+}
+
+void GamepadManager::platformGamepadConnected(unsigned index)
+{
+ for (auto& navigator : m_navigators)
+ navigator->gamepadConnected(index);
+
+ // FIXME: Fire connected event to all pages with listeners.
+}
+
+void GamepadManager::platformGamepadDisconnected(unsigned index)
+{
+ // FIXME: Fire disconnected event to all pages with listeners.
+
+ for (auto& navigator : m_navigators)
+ navigator->gamepadDisconnected(index);
+}
+
+void GamepadManager::registerNavigator(NavigatorGamepad* navigator)
+{
+ ASSERT(!m_navigators.contains(navigator));
+ m_navigators.add(navigator);
+
+ // FIXME: Monitoring gamepads will also be reliant on whether or not there are any
+ // connected/disconnected event listeners.
+ // Those event listeners will also need to register with the GamepadManager.
+ if (m_navigators.size() == 1)
+ platformStrategies()->gamepadStrategy()->startMonitoringGamepads(this);
+}
+
+void GamepadManager::unregisterNavigator(NavigatorGamepad* navigator)
+{
+ ASSERT(m_navigators.contains(navigator));
+ m_navigators.remove(navigator);
+
+ // FIXME: Monitoring gamepads will also be reliant on whether or not there are any
+ // connected/disconnected event listeners.
+ // Those event listeners will also need to register with the GamepadManager.
+ if (m_navigators.isEmpty())
+ platformStrategies()->gamepadStrategy()->stopMonitoringGamepads(this);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesgamepadGamepadManagerhfromrev170464trunkSourceWebCoreModulesgamepadNavigatorGamepadh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/Modules/gamepad/GamepadManager.h (from rev 170464, trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h) (0 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/gamepad/GamepadManager.h         (rev 0)
+++ trunk/Source/WebCore/Modules/gamepad/GamepadManager.h        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GamepadManager_h
+#define GamepadManager_h
+
+#if ENABLE(GAMEPAD)
+
+#include "GamepadStrategyClient.h"
+#include <wtf/HashSet.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Gamepad;
+class NavigatorGamepad;
+
+class GamepadManager : public GamepadStrategyClient {
+ WTF_MAKE_NONCOPYABLE(GamepadManager);
+ friend class NeverDestroyed<GamepadManager>;
+public:
+ static GamepadManager& shared();
+
+ virtual void platformGamepadConnected(unsigned index) override final;
+ virtual void platformGamepadDisconnected(unsigned index) override final;
+
+ void registerNavigator(NavigatorGamepad*);
+ void unregisterNavigator(NavigatorGamepad*);
+
+private:
+ GamepadManager();
+
+ HashSet<NavigatorGamepad*> m_navigators;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
+#endif // GamepadManager_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesgamepadNavigatorGamepadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -28,16 +28,30 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(GAMEPAD)
</span><span class="cx">
</span><ins>+#include "DocumentLoader.h"
+#include "Frame.h"
</ins><span class="cx"> #include "Gamepad.h"
</span><ins>+#include "GamepadManager.h"
+#include "GamepadStrategy.h"
</ins><span class="cx"> #include "Navigator.h"
</span><ins>+#include "PlatformGamepad.h"
+#include "PlatformStrategies.h"
</ins><span class="cx"> #include <wtf/NeverDestroyed.h>
</span><ins>+#include <wtf/RunLoop.h>
</ins><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> NavigatorGamepad::NavigatorGamepad()
</span><ins>+ : m_navigationStart(std::numeric_limits<double>::infinity())
</ins><span class="cx"> {
</span><ins>+ GamepadManager::shared().registerNavigator(this);
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+NavigatorGamepad::~NavigatorGamepad()
+{
+ GamepadManager::shared().unregisterNavigator(this);
+}
+
</ins><span class="cx"> const char* NavigatorGamepad::supplementName()
</span><span class="cx"> {
</span><span class="cx"> return "NavigatorGamepad";
</span><span class="lines">@@ -50,6 +64,11 @@
</span><span class="cx"> auto newSupplement = std::make_unique<NavigatorGamepad>();
</span><span class="cx"> supplement = newSupplement.get();
</span><span class="cx"> provideTo(navigator, supplementName(), std::move(newSupplement));
</span><ins>+
+ if (Frame* frame = navigator->frame()) {
+ if (DocumentLoader* documentLoader = frame->loader().documentLoader())
+ supplement->m_navigationStart = documentLoader->timing()->navigationStart();
+ }
</ins><span class="cx"> }
</span><span class="cx"> return supplement;
</span><span class="cx"> }
</span><span class="lines">@@ -61,9 +80,70 @@
</span><span class="cx">
</span><span class="cx"> const Vector<RefPtr<Gamepad>>& NavigatorGamepad::gamepads()
</span><span class="cx"> {
</span><ins>+ if (m_gamepads.isEmpty())
+ return m_gamepads;
+
+ const Vector<PlatformGamepad*>& platformGamepads = platformStrategies()->gamepadStrategy()->platformGamepads();
+
+ for (unsigned i = 0; i < platformGamepads.size(); ++i) {
+ if (!platformGamepads[i]) {
+ ASSERT(!m_gamepads[i]);
+ continue;
+ }
+
+ ASSERT(m_gamepads[i]);
+ m_gamepads[i]->updateFromPlatformGamepad(*platformGamepads[i]);
+ }
+
</ins><span class="cx"> return m_gamepads;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void NavigatorGamepad::gamepadsBecameVisible()
+{
+ const Vector<PlatformGamepad*>& platformGamepads = platformStrategies()->gamepadStrategy()->platformGamepads();
+ m_gamepads.resize(platformGamepads.size());
+
+ for (unsigned i = 0; i < platformGamepads.size(); ++i) {
+ if (!platformGamepads[i])
+ continue;
+
+ m_gamepads[i] = Gamepad::create(*platformGamepads[i], i);
+ }
+}
+
+void NavigatorGamepad::gamepadConnected(unsigned index)
+{
+ // If this is the first gamepad this Navigator object has seen, then all gamepads just became visible.
+ if (m_gamepads.isEmpty()) {
+ gamepadsBecameVisible();
+ return;
+ }
+
+ // The new index should already fit in the existing array, or should be exactly one past-the-end of the existing array.
+ ASSERT(index <= m_gamepads.size());
+
+ const Vector<PlatformGamepad*>& platformGamepads = platformStrategies()->gamepadStrategy()->platformGamepads();
+ ASSERT(index < platformGamepads.size());
+ ASSERT(platformGamepads[index]);
+
+ if (index < m_gamepads.size())
+ m_gamepads[index] = Gamepad::create(*platformGamepads[index], index);
+ else if (index == m_gamepads.size())
+ m_gamepads.append(Gamepad::create(*platformGamepads[index], index));
+}
+
+void NavigatorGamepad::gamepadDisconnected(unsigned index)
+{
+ // If this Navigator hasn't seen any gamepads yet its Vector will still be empty.
+ if (!m_gamepads.size())
+ return;
+
+ ASSERT(index < m_gamepads.size());
+ ASSERT(m_gamepads[index]);
+
+ m_gamepads[index] = nullptr;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(GAMEPAD)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesgamepadNavigatorGamepadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -39,16 +39,27 @@
</span><span class="cx"> class NavigatorGamepad : public Supplement<Navigator> {
</span><span class="cx"> public:
</span><span class="cx"> NavigatorGamepad();
</span><ins>+ virtual ~NavigatorGamepad();
</ins><span class="cx">
</span><span class="cx"> static NavigatorGamepad* from(Navigator*);
</span><span class="cx">
</span><ins>+ // The array of Gamepads might be sparse.
+ // Null checking each entry is necessary.
</ins><span class="cx"> static const Vector<RefPtr<Gamepad>>& getGamepads(Navigator*);
</span><span class="cx">
</span><ins>+ double navigationStart() const { return m_navigationStart; }
+
+ void gamepadConnected(unsigned index);
+ void gamepadDisconnected(unsigned index);
+
</ins><span class="cx"> private:
</span><span class="cx"> static const char* supplementName();
</span><span class="cx">
</span><ins>+ void gamepadsBecameVisible();
+
</ins><span class="cx"> const Vector<RefPtr<Gamepad>>& gamepads();
</span><span class="cx">
</span><ins>+ double m_navigationStart;
</ins><span class="cx"> Vector<RefPtr<Gamepad>> m_gamepads;
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -3439,3 +3439,7 @@
</span><span class="cx"> #if ENABLE(WEB_TIMING)
</span><span class="cx"> __ZNK7WebCore20ResourceResponseBase18resourceLoadTimingEv
</span><span class="cx"> #endif
</span><ins>+
+#if ENABLE(GAMEPAD)
+__ZN7WebCore18HIDGamepadListener6sharedEv
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -1923,6 +1923,12 @@
</span><span class="cx">                 51A4BB0A1954D61600FA5C2E /* Gamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A4BB071954D61600FA5C2E /* Gamepad.cpp */; };
</span><span class="cx">                 51A4BB101954D62700FA5C2E /* NavigatorGamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A4BB0D1954D62700FA5C2E /* NavigatorGamepad.cpp */; };
</span><span class="cx">                 51A9D9E6195B8F47001B2B5C /* GamepadStrategyClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A9D9E5195B8F47001B2B5C /* GamepadStrategyClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                51A9D9E9195B931F001B2B5C /* GamepadManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A9D9E7195B931F001B2B5C /* GamepadManager.cpp */; };
+                51A9D9EA195B931F001B2B5C /* GamepadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A9D9E8195B931F001B2B5C /* GamepadManager.h */; };
+                51A9D9F3195B9503001B2B5C /* HIDGamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A9D9EF195B9503001B2B5C /* HIDGamepad.cpp */; };
+                51A9D9F4195B9503001B2B5C /* HIDGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A9D9F0195B9503001B2B5C /* HIDGamepad.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                51A9D9F5195B9503001B2B5C /* HIDGamepadListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A9D9F1195B9503001B2B5C /* HIDGamepadListener.cpp */; };
+                51A9D9F6195B9503001B2B5C /* HIDGamepadListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A9D9F2195B9503001B2B5C /* HIDGamepadListener.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 51AA3F6F0BD5AA9E00892971 /* ResourceLoaderMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51AA3F6E0BD5AA9E00892971 /* ResourceLoaderMac.mm */; };
</span><span class="cx">                 51ABAE1B103C18FF008C5260 /* SocketStreamError.h in Headers */ = {isa = PBXBuildFile; fileRef = 51ABAE1A103C18FF008C5260 /* SocketStreamError.h */; };
</span><span class="cx">                 51ABAE1E103C1913008C5260 /* SocketStreamHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 51ABAE1C103C1913008C5260 /* SocketStreamHandle.h */; };
</span><span class="lines">@@ -9001,6 +9007,12 @@
</span><span class="cx">                 51A4BB0E1954D62700FA5C2E /* NavigatorGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigatorGamepad.h; sourceTree = "<group>"; };
</span><span class="cx">                 51A4BB0F1954D62700FA5C2E /* NavigatorGamepad.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NavigatorGamepad.idl; sourceTree = "<group>"; };
</span><span class="cx">                 51A9D9E5195B8F47001B2B5C /* GamepadStrategyClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GamepadStrategyClient.h; sourceTree = "<group>"; };
</span><ins>+                51A9D9E7195B931F001B2B5C /* GamepadManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GamepadManager.cpp; sourceTree = "<group>"; };
+                51A9D9E8195B931F001B2B5C /* GamepadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GamepadManager.h; sourceTree = "<group>"; };
+                51A9D9EF195B9503001B2B5C /* HIDGamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HIDGamepad.cpp; sourceTree = "<group>"; };
+                51A9D9F0195B9503001B2B5C /* HIDGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDGamepad.h; sourceTree = "<group>"; };
+                51A9D9F1195B9503001B2B5C /* HIDGamepadListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HIDGamepadListener.cpp; sourceTree = "<group>"; };
+                51A9D9F2195B9503001B2B5C /* HIDGamepadListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDGamepadListener.h; sourceTree = "<group>"; };
</ins><span class="cx">                 51AA3F6E0BD5AA9E00892971 /* ResourceLoaderMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceLoaderMac.mm; sourceTree = "<group>"; };
</span><span class="cx">                 51ABAE1A103C18FF008C5260 /* SocketStreamError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamError.h; sourceTree = "<group>"; };
</span><span class="cx">                 51ABAE1C103C1913008C5260 /* SocketStreamHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamHandle.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -16070,6 +16082,8 @@
</span><span class="cx">                                 516C621D1950D48700337E75 /* GamepadEvent.cpp */,
</span><span class="cx">                                 516C621E1950D48700337E75 /* GamepadEvent.h */,
</span><span class="cx">                                 516C621F1950D48700337E75 /* GamepadEvent.idl */,
</span><ins>+                                51A9D9E7195B931F001B2B5C /* GamepadManager.cpp */,
+                                51A9D9E8195B931F001B2B5C /* GamepadManager.h */,
</ins><span class="cx">                                 51A4BB0D1954D62700FA5C2E /* NavigatorGamepad.cpp */,
</span><span class="cx">                                 51A4BB0E1954D62700FA5C2E /* NavigatorGamepad.h */,
</span><span class="cx">                                 51A4BB0F1954D62700FA5C2E /* NavigatorGamepad.idl */,
</span><span class="lines">@@ -16371,6 +16385,10 @@
</span><span class="cx">                                 E1BA66F01742BD8600C20251 /* DynamicLinkerInterposing.h */,
</span><span class="cx">                                 1CA19E030DC255950065A994 /* EventLoopMac.mm */,
</span><span class="cx">                                 514B3F750C722055000530DF /* FileSystemMac.mm */,
</span><ins>+                                51A9D9EF195B9503001B2B5C /* HIDGamepad.cpp */,
+                                51A9D9F0195B9503001B2B5C /* HIDGamepad.h */,
+                                51A9D9F1195B9503001B2B5C /* HIDGamepadListener.cpp */,
+                                51A9D9F2195B9503001B2B5C /* HIDGamepadListener.h */,
</ins><span class="cx">                                 935C476E09AC4D7300A6AAB4 /* KeyEventMac.mm */,
</span><span class="cx">                                 521D46F511AEC98100514613 /* KillRingMac.mm */,
</span><span class="cx">                                 9352084409BD43B900F2038D /* Language.mm */,
</span><span class="lines">@@ -24815,6 +24833,7 @@
</span><span class="cx">                                 BC3C39B70C0D3D8D005F4D7A /* JSMediaList.h in Headers */,
</span><span class="cx">                                 D3A94A47122DC40F00A37BBC /* JSMediaQueryList.h in Headers */,
</span><span class="cx">                                 7C5343FD17B74B63004232F0 /* JSMediaQueryListListener.h in Headers */,
</span><ins>+                                51A9D9F6195B9503001B2B5C /* HIDGamepadListener.h in Headers */,
</ins><span class="cx">                                 CD9DE17517AAC74C00EA386D /* JSMediaSource.h in Headers */,
</span><span class="cx">                                 07C59B7217F79C7C000FBCBB /* JSMediaSourceStates.h in Headers */,
</span><span class="cx">                                 07277E4D17D018CC0015534D /* JSMediaStream.h in Headers */,
</span><span class="lines">@@ -25593,6 +25612,7 @@
</span><span class="cx">                                 439046DC12DA25E800AF80A2 /* RenderMathMLFraction.h in Headers */,
</span><span class="cx">                                 07AB996F18DA3C740018771E /* RTCConfigurationPrivate.h in Headers */,
</span><span class="cx">                                 439046DE12DA25E800AF80A2 /* RenderMathMLMath.h in Headers */,
</span><ins>+                                51A9D9F4195B9503001B2B5C /* HIDGamepad.h in Headers */,
</ins><span class="cx">                                 439046E012DA25E800AF80A2 /* RenderMathMLOperator.h in Headers */,
</span><span class="cx">                                 439046E012DA25E800BF80A3 /* RenderMathMLRadicalOperator.h in Headers */,
</span><span class="cx">                                 439046E212DA25E800AF80A2 /* RenderMathMLRoot.h in Headers */,
</span><span class="lines">@@ -26559,6 +26579,7 @@
</span><span class="cx">                                 85031B510A44EFC700F992E0 /* WheelEvent.h in Headers */,
</span><span class="cx">                                 93EC44A2188F4BB800661DF1 /* WheelEventDeltaTracker.h in Headers */,
</span><span class="cx">                                 9380F47409A11AB4001FDB34 /* Widget.h in Headers */,
</span><ins>+                                51A9D9EA195B931F001B2B5C /* GamepadManager.h in Headers */,
</ins><span class="cx">                                 1411DCB1164C39A800D49BC1 /* WidthCache.h in Headers */,
</span><span class="cx">                                 939B02EF0EA2DBC400C54570 /* WidthIterator.h in Headers */,
</span><span class="cx">                                 BC8243E90D0CFD7500460C8F /* WindowFeatures.h in Headers */,
</span><span class="lines">@@ -28469,6 +28490,7 @@
</span><span class="cx">                                 B2FA3D3E0AB75A6F000E5AC4 /* JSSVGAnimatedInteger.cpp in Sources */,
</span><span class="cx">                                 B2FA3D400AB75A6F000E5AC4 /* JSSVGAnimatedLength.cpp in Sources */,
</span><span class="cx">                                 B2FA3D420AB75A6F000E5AC4 /* JSSVGAnimatedLengthList.cpp in Sources */,
</span><ins>+                                51A9D9F3195B9503001B2B5C /* HIDGamepad.cpp in Sources */,
</ins><span class="cx">                                 B2FA3D440AB75A6F000E5AC4 /* JSSVGAnimatedNumber.cpp in Sources */,
</span><span class="cx">                                 B2FA3D460AB75A6F000E5AC4 /* JSSVGAnimatedNumberList.cpp in Sources */,
</span><span class="cx">                                 B2FA3D4A0AB75A6F000E5AC4 /* JSSVGAnimatedPreserveAspectRatio.cpp in Sources */,
</span><span class="lines">@@ -29469,6 +29491,7 @@
</span><span class="cx">                                 B25599840D00D8BA00BB825C /* SVGFEImage.cpp in Sources */,
</span><span class="cx">                                 B22279EE0D00BF220071B782 /* SVGFEImageElement.cpp in Sources */,
</span><span class="cx">                                 B22279F10D00BF220071B782 /* SVGFELightElement.cpp in Sources */,
</span><ins>+                                51A9D9F5195B9503001B2B5C /* HIDGamepadListener.cpp in Sources */,
</ins><span class="cx">                                 B22279F30D00BF220071B782 /* SVGFEMergeElement.cpp in Sources */,
</span><span class="cx">                                 B22279F60D00BF220071B782 /* SVGFEMergeNodeElement.cpp in Sources */,
</span><span class="cx">                                 84224193107E78A700766A87 /* SVGFEMorphologyElement.cpp in Sources */,
</span><span class="lines">@@ -29871,6 +29894,7 @@
</span><span class="cx">                                 7AF9B20218CFB2DF00C64BEF /* VTTRegion.cpp in Sources */,
</span><span class="cx">                                 E15A36D91104572700B7B639 /* XMLNSNames.cpp in Sources */,
</span><span class="cx">                                 1ACE53EA0A8D18E70022947D /* XMLSerializer.cpp in Sources */,
</span><ins>+                                51A9D9E9195B931F001B2B5C /* GamepadManager.cpp in Sources */,
</ins><span class="cx">                                 5905ADBF1302F3CE00F116DF /* XMLTreeViewer.cpp in Sources */,
</span><span class="cx">                                 1AB7FC680A8B92EC00D9D37B /* XPathEvaluator.cpp in Sources */,
</span><span class="cx">                                 978D07CC145A102E0096908D /* XPathException.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacHIDGamepadcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mac/HIDGamepad.cpp (0 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/HIDGamepad.cpp         (rev 0)
+++ trunk/Source/WebCore/platform/mac/HIDGamepad.cpp        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -0,0 +1,175 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HIDGamepad.h"
+
+#if ENABLE(GAMEPAD)
+
+#include <IOKit/hid/IOHIDElement.h>
+#include <IOKit/hid/IOHIDUsageTables.h>
+#include <IOKit/hid/IOHIDValue.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+HIDGamepad::HIDGamepad(IOHIDDeviceRef hidDevice)
+ : m_hidDevice(hidDevice)
+{
+ m_connectTime = m_lastUpdateTime = monotonicallyIncreasingTime();
+
+ CFNumberRef cfVendorID = (CFNumberRef)IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDVendorIDKey));
+ CFNumberRef cfProductID = (CFNumberRef)IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductIDKey));
+
+ int vendorID, productID;
+ CFNumberGetValue(cfVendorID, kCFNumberIntType, &vendorID);
+ CFNumberGetValue(cfProductID, kCFNumberIntType, &productID);
+
+ CFStringRef cfProductName = (CFStringRef)IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductKey));
+ String productName(cfProductName);
+
+ // Currently the spec has no formatting for the id string.
+ // This string formatting matches Firefox.
+ m_id = String::format("%x-%x-%s", vendorID, productID, productName.utf8().data());
+
+ initElements();
+}
+
+void HIDGamepad::initElements()
+{
+ RetainPtr<CFArrayRef> elements = adoptCF(IOHIDDeviceCopyMatchingElements(m_hidDevice.get(), NULL, kIOHIDOptionsTypeNone));
+ initElementsFromArray(elements.get());
+
+ // Buttons are specified to appear highest priority first in the array.
+ std::sort(m_buttons.begin(), m_buttons.end(), [](const std::unique_ptr<HIDGamepadButton>& a, const std::unique_ptr<HIDGamepadButton>& b) {
+ return a->priority < b->priority;
+ });
+
+ m_axisValues.resize(m_axes.size());
+ m_buttonValues.resize(m_buttons.size());
+}
+
+void HIDGamepad::initElementsFromArray(CFArrayRef elements)
+{
+ for (unsigned i = 0; i < CFArrayGetCount(elements); ++i) {
+ IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
+ if (CFGetTypeID(element) != IOHIDElementGetTypeID())
+ continue;
+
+ // As a physical element can appear in the device twice (in different collections) and can be
+ // represented by different IOHIDElementRef objects, we look at the IOHIDElementCookie which
+ // is meant to be unique for each physical element.
+ IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
+ if (m_elementMap.contains(cookie))
+ continue;
+
+ IOHIDElementType type = IOHIDElementGetType(element);
+
+ if ((type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Button) && maybeAddButton(element))
+ continue;
+
+ if ((type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Axis) && maybeAddAxis(element))
+ continue;
+
+ if (type == kIOHIDElementTypeCollection)
+ initElementsFromArray(IOHIDElementGetChildren(element));
+ }
+}
+
+bool HIDGamepad::maybeAddButton(IOHIDElementRef element)
+{
+ uint32_t usagePage = IOHIDElementGetUsagePage(element);
+ if (usagePage != kHIDPage_Button)
+ return false;
+
+ uint32_t usage = IOHIDElementGetUsage(element);
+ if (!usage)
+ return false;
+
+ CFIndex min = IOHIDElementGetLogicalMin(element);
+ CFIndex max = IOHIDElementGetLogicalMax(element);
+
+ m_buttons.append(std::make_unique<HIDGamepadButton>(usage, min, max));
+
+ IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
+ m_elementMap.set(cookie, m_buttons.last().get());
+
+ return true;
+}
+
+bool HIDGamepad::maybeAddAxis(IOHIDElementRef element)
+{
+ uint32_t usagePage = IOHIDElementGetUsagePage(element);
+ if (usagePage != kHIDPage_GenericDesktop)
+ return false;
+
+ uint32_t usage = IOHIDElementGetUsage(element);
+ // This range covers the standard axis usages.
+ if (usage < kHIDUsage_GD_X || usage > kHIDUsage_GD_Rz)
+ return false;
+
+ CFIndex min = IOHIDElementGetPhysicalMin(element);
+ CFIndex max = IOHIDElementGetPhysicalMax(element);
+
+ m_axes.append(std::make_unique<HIDGamepadAxis>(min, max));
+
+ IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
+ m_elementMap.set(cookie, m_axes.last().get());
+
+ return true;
+}
+
+void HIDGamepad::valueChanged(IOHIDValueRef value)
+{
+ IOHIDElementCookie cookie = IOHIDElementGetCookie(IOHIDValueGetElement(value));
+ HIDGamepadElement* element = m_elementMap.get(cookie);
+
+ // This might be an element we don't currently handle as input so we can skip it.
+ if (!element)
+ return;
+
+ element->rawValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
+
+ if (element->isButton()) {
+ for (unsigned i = 0; i < m_buttons.size(); ++i) {
+ if (m_buttons[i].get() == element)
+ m_buttonValues[i] = element->normalizedValue();
+ }
+ } else if (element->isAxis()) {
+ for (unsigned i = 0; i < m_axes.size(); ++i) {
+ if (m_axes[i].get() == element)
+ m_axisValues[i] = element->normalizedValue();
+ }
+ } else
+ ASSERT_NOT_REACHED();
+
+ m_lastUpdateTime = monotonicallyIncreasingTime();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmacHIDGamepadh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mac/HIDGamepad.h (0 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/HIDGamepad.h         (rev 0)
+++ trunk/Source/WebCore/platform/mac/HIDGamepad.h        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -0,0 +1,124 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HIDGamepad_h
+#define HIDGamepad_h
+
+#if ENABLE(GAMEPAD)
+
+#include "PlatformGamepad.h"
+#include <IOKit/hid/IOHIDDevice.h>
+#include <wtf/HashMap.h>
+#include <wtf/RetainPtr.h>
+
+namespace WebCore {
+
+struct HIDGamepadElement {
+ HIDGamepadElement(double theMin, double theMax)
+ : min(theMin)
+ , max(theMax)
+ , rawValue(theMin)
+ {
+ }
+
+ virtual ~HIDGamepadElement()
+ {
+ }
+
+ double min;
+ double max;
+ double rawValue;
+
+ virtual bool isButton() const { return false; }
+ virtual bool isAxis() const { return false; }
+
+ virtual double normalizedValue() = 0;
+};
+
+struct HIDGamepadButton : public HIDGamepadElement {
+ HIDGamepadButton(uint32_t thePriority, double min, double max)
+ : HIDGamepadElement(min, max)
+ , priority(thePriority)
+ {
+ }
+
+ uint32_t priority;
+
+ virtual bool isButton() const override { return true; }
+
+ // Buttons normalize to the range (0.0) - (1.0)
+ virtual double normalizedValue() override
+ {
+ return (rawValue - min) / (max - min);
+ }
+};
+
+struct HIDGamepadAxis : public HIDGamepadElement {
+ HIDGamepadAxis(double min, double max)
+ : HIDGamepadElement(min, max)
+ {
+ }
+
+ virtual bool isAxis() const override { return true; }
+
+ // Axes normalize to the range (-1.0) - (1.0)
+ virtual double normalizedValue() override
+ {
+ return (((rawValue - min) / (max - min)) * 2) - 1;
+ }
+};
+
+class HIDGamepad : public PlatformGamepad {
+public:
+ HIDGamepad(IOHIDDeviceRef);
+
+ IOHIDDeviceRef hidDevice() const { return m_hidDevice.get(); }
+
+ void valueChanged(IOHIDValueRef);
+
+ virtual const Vector<double>& axisValues() const override final { return m_axisValues; }
+ virtual const Vector<double>& buttonValues() const override final { return m_buttonValues; }
+
+private:
+ void initElements();
+ void initElementsFromArray(CFArrayRef);
+
+ bool maybeAddButton(IOHIDElementRef);
+ bool maybeAddAxis(IOHIDElementRef);
+
+ RetainPtr<IOHIDDeviceRef> m_hidDevice;
+
+ HashMap<IOHIDElementCookie, HIDGamepadElement*> m_elementMap;
+
+ Vector<std::unique_ptr<HIDGamepadButton>> m_buttons;
+ Vector<std::unique_ptr<HIDGamepadAxis>> m_axes;
+ Vector<double> m_buttonValues;
+ Vector<double> m_axisValues;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
+#endif // HIDGamepadListener_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmacHIDGamepadListenercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mac/HIDGamepadListener.cpp (0 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/HIDGamepadListener.cpp         (rev 0)
+++ trunk/Source/WebCore/platform/mac/HIDGamepadListener.cpp        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -0,0 +1,174 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HIDGamepadListener.h"
+
+#if ENABLE(GAMEPAD)
+
+#include "PlatformGamepad.h"
+#include <wtf/MainThread.h>
+
+namespace WebCore {
+
+static RetainPtr<CFDictionaryRef> deviceMatchingDictionary(uint32_t usagePage, uint32_t usage)
+{
+ ASSERT(usagePage);
+ ASSERT(usage);
+
+ RetainPtr<CFNumberRef> pageNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePage));
+ RetainPtr<CFNumberRef> usageNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage));
+
+ CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) };
+ CFNumberRef values[] = { pageNumber.get(), usageNumber.get() };
+
+ return adoptCF(CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+}
+
+static void deviceAddedCallback(void* context, IOReturn, void*, IOHIDDeviceRef device)
+{
+ HIDGamepadListener* listener = static_cast<HIDGamepadListener*>(context);
+ listener->deviceAdded(device);
+}
+
+static void deviceRemovedCallback(void* context, IOReturn, void*, IOHIDDeviceRef device)
+{
+ HIDGamepadListener* listener = static_cast<HIDGamepadListener*>(context);
+ listener->deviceRemoved(device);
+}
+
+static void deviceValuesChangedCallback(void* context, IOReturn result, void*, IOHIDValueRef value)
+{
+ // A non-zero result value indicates an error that we can do nothing about for input values.
+ if (result)
+ return;
+
+ HIDGamepadListener* listener = static_cast<HIDGamepadListener*>(context);
+ listener->valuesChanged(value);
+}
+
+HIDGamepadListener& HIDGamepadListener::shared()
+{
+ static NeverDestroyed<HIDGamepadListener> sharedListener;
+ return sharedListener;
+}
+
+HIDGamepadListener::HIDGamepadListener()
+ : m_client(nullptr)
+ , m_shouldDispatchCallbacks(false)
+{
+ m_manager = adoptCF(IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone));
+
+ RetainPtr<CFDictionaryRef> joystickDictionary = deviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
+ RetainPtr<CFDictionaryRef> gamepadDictionary = deviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
+
+ CFDictionaryRef devices[] = { joystickDictionary.get(), gamepadDictionary.get() };
+
+ RetainPtr<CFArrayRef> matchingArray = adoptCF(CFArrayCreate(kCFAllocatorDefault, (const void**)devices, 2, &kCFTypeArrayCallBacks));
+
+ IOHIDManagerSetDeviceMatchingMultiple(m_manager.get(), matchingArray.get());
+ IOHIDManagerRegisterDeviceMatchingCallback(m_manager.get(), deviceAddedCallback, this);
+ IOHIDManagerRegisterDeviceRemovalCallback(m_manager.get(), deviceRemovedCallback, this);
+ IOHIDManagerScheduleWithRunLoop(m_manager.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ IOHIDManagerOpen(m_manager.get(), kIOHIDOptionsTypeNone);
+
+ IOHIDManagerRegisterInputValueCallback(m_manager.get(), deviceValuesChangedCallback, this);
+
+ // We'll immediately get a series of connection and value callbacks for already-connected gamepads
+ // but we don't want to notify WebCore of those events.
+ // This callOnMainThread call re-enables those callbacks after the runloop empties out.
+ callOnMainThread([]() {
+ HIDGamepadListener::shared().setShouldDispatchCallbacks(true);
+ });
+}
+
+unsigned HIDGamepadListener::indexForNewlyConnectedDevice()
+{
+ unsigned index = 0;
+ while (index < m_gamepadVector.size() && m_gamepadVector[index])
+ ++index;
+
+ return index;
+}
+
+void HIDGamepadListener::deviceAdded(IOHIDDeviceRef device)
+{
+ ASSERT(!m_gamepadMap.get(device));
+
+ std::unique_ptr<HIDGamepad> gamepad = std::make_unique<HIDGamepad>(device);
+ unsigned index = indexForNewlyConnectedDevice();
+
+ if (m_gamepadVector.size() <= index)
+ m_gamepadVector.resize(index + 1);
+
+ m_gamepadVector[index] = gamepad.get();
+ m_gamepadMap.set(device, std::move(gamepad));
+
+ if (m_client && m_shouldDispatchCallbacks)
+ m_client->gamepadConnected(index);
+}
+
+void HIDGamepadListener::deviceRemoved(IOHIDDeviceRef device)
+{
+ std::pair<std::unique_ptr<HIDGamepad>, unsigned> removedGamepad = removeGamepadForDevice(device);
+ ASSERT(removedGamepad.first);
+
+ if (m_client && m_shouldDispatchCallbacks)
+ m_client->gamepadDisconnected(removedGamepad.second);
+}
+
+void HIDGamepadListener::valuesChanged(IOHIDValueRef value)
+{
+ IOHIDDeviceRef device = IOHIDElementGetDevice(IOHIDValueGetElement(value));
+
+ HIDGamepad* gamepad = m_gamepadMap.get(device);
+
+ // When starting monitoring we might get a value changed callback before we even know the device is connected.
+ if (!gamepad)
+ return;
+
+ gamepad->valueChanged(value);
+}
+
+std::pair<std::unique_ptr<HIDGamepad>, unsigned> HIDGamepadListener::removeGamepadForDevice(IOHIDDeviceRef device)
+{
+ std::pair<std::unique_ptr<HIDGamepad>, unsigned> result;
+ result.first = m_gamepadMap.take(device);
+ ASSERT(result.first);
+
+ for (unsigned i = 0; i < m_gamepadVector.size(); ++i) {
+ if (m_gamepadVector[i] == result.first.get()) {
+ result.second = i;
+ m_gamepadVector[i] = nullptr;
+ break;
+ }
+ }
+
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmacHIDGamepadListenerhfromrev170464trunkSourceWebCoreModulesgamepadNavigatorGamepadcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/mac/HIDGamepadListener.h (from rev 170464, trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp) (0 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/HIDGamepadListener.h         (rev 0)
+++ trunk/Source/WebCore/platform/mac/HIDGamepadListener.h        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -0,0 +1,83 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HIDGamepadListener_h
+#define HIDGamepadListener_h
+
+#if ENABLE(GAMEPAD)
+
+#include "HIDGamepad.h"
+#include <IOKit/hid/IOHIDManager.h>
+#include <wtf/Deque.h>
+#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/RetainPtr.h>
+
+namespace WebCore {
+
+class HIDGamepadListenerClient {
+public:
+ virtual ~HIDGamepadListenerClient() { }
+
+ virtual void gamepadConnected(unsigned index) = 0;
+ virtual void gamepadDisconnected(unsigned index) = 0;
+};
+
+class HIDGamepadListener {
+ WTF_MAKE_NONCOPYABLE(HIDGamepadListener);
+ friend class NeverDestroyed<HIDGamepadListener>;
+public:
+ static HIDGamepadListener& shared();
+
+ void setClient(HIDGamepadListenerClient* client) { m_client = client; }
+
+ void deviceAdded(IOHIDDeviceRef);
+ void deviceRemoved(IOHIDDeviceRef);
+ void valuesChanged(IOHIDValueRef);
+
+ const Vector<PlatformGamepad*>& platformGamepads() const { return m_gamepadVector; }
+
+ void setShouldDispatchCallbacks(bool shouldDispatchCallbacks) { m_shouldDispatchCallbacks = shouldDispatchCallbacks; }
+
+private:
+ HIDGamepadListener();
+
+ std::pair<std::unique_ptr<HIDGamepad>, unsigned> removeGamepadForDevice(IOHIDDeviceRef);
+
+ unsigned indexForNewlyConnectedDevice();
+
+ Vector<PlatformGamepad*> m_gamepadVector;
+ HashMap<IOHIDDeviceRef, std::unique_ptr<HIDGamepad>> m_gamepadMap;
+
+ RetainPtr<IOHIDManagerRef> m_manager;
+
+ HIDGamepadListenerClient* m_client;
+ bool m_shouldDispatchCallbacks;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
+#endif // HIDGamepadListener_h
</ins></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebKit/ChangeLog        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2014-06-25 Brady Eidson <beidson@apple.com>
+
+ Add HID-based gamepad implementation for Mac
+ https://bugs.webkit.org/show_bug.cgi?id=134324
+
+ Reviewed by Dean Jackson.
+
+ * WebKit.xcodeproj/project.pbxproj:
+
</ins><span class="cx"> 2014-06-23 Ryuan Choi <ryuan.choi@samsung.com>
</span><span class="cx">
</span><span class="cx"> [EFL] Remove the WebKit1 EFL code
</span></span></pre></div>
<a id="trunkSourceWebKitWebKitxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -113,6 +113,8 @@
</span><span class="cx">                 5158F6EF106D862A00AF457C /* WebHistoryDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5158F6EE106D862A00AF457C /* WebHistoryDelegate.h */; };
</span><span class="cx">                 5185F62610712B80007AA393 /* WebNavigationData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5185F62510712B80007AA393 /* WebNavigationData.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 5185F62810712B97007AA393 /* WebNavigationData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5185F62710712B97007AA393 /* WebNavigationData.mm */; };
</span><ins>+                51A9D9ED195B949F001B2B5C /* WebHIDGamepadController.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A9D9EB195B949F001B2B5C /* WebHIDGamepadController.h */; };
+                51A9D9EE195B949F001B2B5C /* WebHIDGamepadController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51A9D9EC195B949F001B2B5C /* WebHIDGamepadController.mm */; };
</ins><span class="cx">                 51AEDEF10CECF45700854328 /* WebDatabaseManagerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 51AEDEF00CECF45700854328 /* WebDatabaseManagerInternal.h */; };
</span><span class="cx">                 51B2A1000ADB15D0002A9BEE /* WebIconDatabaseDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 51B2A0FF0ADB15D0002A9BEE /* WebIconDatabaseDelegate.h */; };
</span><span class="cx">                 51C714FB0B20F79F00E5E33C /* WebBackForwardListInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 51C714FA0B20F79F00E5E33C /* WebBackForwardListInternal.h */; };
</span><span class="lines">@@ -599,6 +601,8 @@
</span><span class="cx">                 51A8B579042834F700CA2D3A /* WebView.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebView.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
</span><span class="cx">                 51A8B57A042834F700CA2D3A /* WebView.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebView.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
</span><span class="cx">                 51A8B57D0428353A00CA2D3A /* WebViewPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebViewPrivate.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
</span><ins>+                51A9D9EB195B949F001B2B5C /* WebHIDGamepadController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebHIDGamepadController.h; sourceTree = "<group>"; };
+                51A9D9EC195B949F001B2B5C /* WebHIDGamepadController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebHIDGamepadController.mm; sourceTree = "<group>"; };
</ins><span class="cx">                 51AEDEF00CECF45700854328 /* WebDatabaseManagerInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDatabaseManagerInternal.h; sourceTree = "<group>"; };
</span><span class="cx">                 51B2A0FF0ADB15D0002A9BEE /* WebIconDatabaseDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebIconDatabaseDelegate.h; sourceTree = "<group>"; };
</span><span class="cx">                 51C714FA0B20F79F00E5E33C /* WebBackForwardListInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebBackForwardListInternal.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -1547,6 +1551,8 @@
</span><span class="cx">                                 9391F274121B38BD00EBF7E8 /* WebFrameNetworkingContext.mm */,
</span><span class="cx">                                 BC7F884910C8775A00D6133D /* WebGeolocationClient.h */,
</span><span class="cx">                                 BC7F884A10C8775A00D6133D /* WebGeolocationClient.mm */,
</span><ins>+                                51A9D9EB195B949F001B2B5C /* WebHIDGamepadController.h */,
+                                51A9D9EC195B949F001B2B5C /* WebHIDGamepadController.mm */,
</ins><span class="cx">                                 51494CD40C7EBDE0004178C5 /* WebIconDatabaseClient.h */,
</span><span class="cx">                                 51494CD50C7EBDE0004178C5 /* WebIconDatabaseClient.mm */,
</span><span class="cx">                                 06693DDA0BFBA85200216072 /* WebInspectorClient.h */,
</span><span class="lines">@@ -1759,6 +1765,7 @@
</span><span class="cx">                                 A10C1D4218202FEF0036883A /* WebSQLiteDatabaseTrackerClient.h in Headers */,
</span><span class="cx">                                 939810540824BF01008DF038 /* WebFramePrivate.h in Headers */,
</span><span class="cx">                                 A10C1D621820300E0036883A /* SearchPopupMenuIOS.h in Headers */,
</span><ins>+                                51A9D9ED195B949F001B2B5C /* WebHIDGamepadController.h in Headers */,
</ins><span class="cx">                                 9398106E0824BF01008DF038 /* WebFrameView.h in Headers */,
</span><span class="cx">                                 9398106F0824BF01008DF038 /* WebFrameViewInternal.h in Headers */,
</span><span class="cx">                                 939810AF0824BF01008DF038 /* WebFrameViewPrivate.h in Headers */,
</span><span class="lines">@@ -2137,6 +2144,7 @@
</span><span class="cx">                                 070F549C17F1E42B00169E04 /* WebUserMediaClient.mm in Sources */,
</span><span class="cx">                                 E169836C11346D5600894115 /* ProxyRuntimeObject.mm in Sources */,
</span><span class="cx">                                 7C01CB88173435C900C5D807 /* SearchPopupMenuMac.mm in Sources */,
</span><ins>+                                51A9D9EE195B949F001B2B5C /* WebHIDGamepadController.mm in Sources */,
</ins><span class="cx">                                 CEDA12DB152CBE6800D9E08D /* WebAlternativeTextClient.mm in Sources */,
</span><span class="cx">                                 A10C1D601820300E0036883A /* PopupMenuIOS.mm in Sources */,
</span><span class="cx">                                 B6CE5C24100BC5CE00219936 /* WebApplicationCache.mm in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebKit/mac/ChangeLog        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -1,5 +1,29 @@
</span><span class="cx"> 2014-06-25 Brady Eidson <beidson@apple.com>
</span><span class="cx">
</span><ins>+ Add HID-based gamepad implementation for Mac
+ https://bugs.webkit.org/show_bug.cgi?id=134324
+
+ Reviewed by Dean Jackson.
+
+ Add a class that acts as an intermediary between the GamepadStrategyClient
+ and the HIDGamepadListener:
+ * WebCoreSupport/WebHIDGamepadController.h:
+ * WebCoreSupport/WebHIDGamepadController.mm:
+ (WebHIDGamepadController::shared):
+ (WebHIDGamepadController::WebHIDGamepadController):
+ (WebHIDGamepadController::gamepadConnected):
+ (WebHIDGamepadController::gamepadDisconnected):
+ (WebHIDGamepadController::registerGamepadStrategyClient):
+ (WebHIDGamepadController::unregisterGamepadStrategyClient):
+
+ Implement the strategies by using the HIDGamepadListener:
+ * WebCoreSupport/WebPlatformStrategies.mm:
+ (WebPlatformStrategies::startMonitoringGamepads):
+ (WebPlatformStrategies::stopMonitoringGamepads):
+ (WebPlatformStrategies::platformGamepads):
+
+2014-06-25 Brady Eidson <beidson@apple.com>
+
</ins><span class="cx"> Add new platform gamepad abstractions
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=134325
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebHIDGamepadControllerhfromrev170464trunkSourceWebCoreModulesgamepadNavigatorGamepadh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit/mac/WebCoreSupport/WebHIDGamepadController.h (from rev 170464, trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h) (0 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebHIDGamepadController.h         (rev 0)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebHIDGamepadController.h        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebHIDGamepadController_h
+#define WebHIDGamepadController_h
+
+#if ENABLE(GAMEPAD)
+
+#include <WebCore/HIDGamepadListener.h>
+#include <wtf/HashSet.h>
+
+namespace WebCore {
+class GamepadStrategyClient;
+}
+
+class WebHIDGamepadController : public WebCore::HIDGamepadListenerClient {
+public:
+ static WebHIDGamepadController& shared();
+
+ virtual void gamepadConnected(unsigned index) override final;
+ virtual void gamepadDisconnected(unsigned index) override final;
+
+ void registerGamepadStrategyClient(WebCore::GamepadStrategyClient*);
+ void unregisterGamepadStrategyClient(WebCore::GamepadStrategyClient*);
+
+private:
+ friend NeverDestroyed<WebHIDGamepadController>;
+
+ WebHIDGamepadController();
+
+ HashSet<WebCore::GamepadStrategyClient*> m_clients;
+};
+
+#endif // ENABLE(GAMEPAD)
+#endif // WebHIDGamepadController_h
</ins></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebHIDGamepadControllermmfromrev170464trunkSourceWebCoreModulesgamepadNavigatorGamepadcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit/mac/WebCoreSupport/WebHIDGamepadController.mm (from rev 170464, trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp) (0 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebHIDGamepadController.mm         (rev 0)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebHIDGamepadController.mm        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(GAMEPAD)
+
+#import "WebHIDGamepadController.h"
+#import <WebCore/GamepadStrategyClient.h>
+#import <WebCore/HIDGamepadListener.h>
+
+using namespace WebCore;
+
+WebHIDGamepadController& WebHIDGamepadController::shared()
+{
+ static NeverDestroyed<WebHIDGamepadController> sharedClient;
+ return sharedClient;
+}
+
+WebHIDGamepadController::WebHIDGamepadController()
+{
+ HIDGamepadListener::shared().setClient(this);
+}
+
+void WebHIDGamepadController::gamepadConnected(unsigned index)
+{
+ for (auto& client : m_clients)
+ client->platformGamepadConnected(index);
+}
+
+void WebHIDGamepadController::gamepadDisconnected(unsigned index)
+{
+ for (auto& client : m_clients)
+ client->platformGamepadDisconnected(index);
+}
+
+void WebHIDGamepadController::registerGamepadStrategyClient(GamepadStrategyClient* client)
+{
+ m_clients.add(client);
+}
+
+void WebHIDGamepadController::unregisterGamepadStrategyClient(GamepadStrategyClient* client)
+{
+ m_clients.remove(client);
+}
+
+#endif // ENABLE(GAMEPAD)
</ins></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebPlatformStrategiesmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm (170464 => 170465)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm        2014-06-26 04:44:24 UTC (rev 170464)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm        2014-06-26 04:49:34 UTC (rev 170465)
</span><span class="lines">@@ -40,6 +40,10 @@
</span><span class="cx"> #import <WebKitSystemInterface.h>
</span><span class="cx"> #import <wtf/NeverDestroyed.h>
</span><span class="cx">
</span><ins>+#if ENABLE(GAMEPAD)
+#import "WebHIDGamepadController.h"
+#endif
+
</ins><span class="cx"> using namespace WebCore;
</span><span class="cx">
</span><span class="cx"> void WebPlatformStrategies::initializeIfNecessary()
</span><span class="lines">@@ -221,18 +225,19 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(GAMEPAD)
</span><del>-void WebPlatformStrategies::startMonitoringGamepads(GamepadStrategyClient*)
</del><ins>+void WebPlatformStrategies::startMonitoringGamepads(GamepadStrategyClient* client)
</ins><span class="cx"> {
</span><ins>+ WebHIDGamepadController::shared().registerGamepadStrategyClient(client);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void WebPlatformStrategies::stopMonitoringGamepads(GamepadStrategyClient*)
</del><ins>+void WebPlatformStrategies::stopMonitoringGamepads(GamepadStrategyClient* client)
</ins><span class="cx"> {
</span><ins>+ WebHIDGamepadController::shared().unregisterGamepadStrategyClient(client);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const Vector<PlatformGamepad*>& WebPlatformStrategies::platformGamepads()
</span><span class="cx"> {
</span><del>- NeverDestroyed<Vector<PlatformGamepad*>> dummyGamepads;
- return dummyGamepads;
</del><ins>+ return HIDGamepadListener::shared().platformGamepads();
</ins><span class="cx"> }
</span><span class="cx"> #endif // ENABLE(GAMEPAD)
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>