Title: [121332] trunk
Revision
121332
Author
zandober...@gmail.com
Date
2012-06-27 02:19:15 -0700 (Wed, 27 Jun 2012)

Log Message

[Gtk] Add support for the Gamepad API
https://bugs.webkit.org/show_bug.cgi?id=87503

Reviewed by Carlos Garcia Campos.

.: 

Only enable the Gamepad feature on Linux as support
for other operating systems is not present.

Check for the GIO Unix and GUdev dependencies when the
Gamepad feature is enabled.

* configure.ac:

Source/WebCore: 

Add support for the Gamepad feature on the GTK port.

The support is available only on Linux, with each gamepad device being presented
through a GamepadDeviceLinux object. The implementation of this class relies on
the Linux kernel joystick API.

Gamepad devices are recognized through the GamepadsGtk class, of which implementation
is based on GUdev. This way devices are properly registered on connection as objects of
the GamepadDeviceGtk class which inherits GamepadDeviceLinux. GamepadDeviceGtk reads the
joystick data through GIO pollable streams and updates the device state accordingly. The
GamepadsGtk object is then polled for gamepads data through the sampleGamepads method.

No new tests - tests already exist but require additional testing infrastructure.

* GNUmakefile.am:
* GNUmakefile.list.am:
* bindings/gobject/GNUmakefile.am:
* bindings/js/JSDOMBinding.h: Add the jsArray method that operates on a Vector of floats.
(WebCore):
(WebCore::jsArray):
* platform/gtk/GamepadsGtk.cpp: Added.
(WebCore):
(GamepadDeviceGtk):
(WebCore::GamepadDeviceGtk::create):
(WebCore::GamepadDeviceGtk::GamepadDeviceGtk):
(WebCore::GamepadDeviceGtk::~GamepadDeviceGtk):
(WebCore::GamepadDeviceGtk::readCallback):
(GamepadsGtk):
(WebCore::GamepadsGtk::GamepadsGtk):
(WebCore::GamepadsGtk::~GamepadsGtk):
(WebCore::GamepadsGtk::registerDevice):
(WebCore::GamepadsGtk::unregisterDevice):
(WebCore::GamepadsGtk::updateGamepadList):
(WebCore::GamepadsGtk::onUEventCallback):
(WebCore::GamepadsGtk::isGamepadDevice):
(WebCore::sampleGamepads):
* platform/linux/GamepadDeviceLinux.cpp: Added.
(WebCore):
(WebCore::GamepadDeviceLinux::GamepadDeviceLinux):
(WebCore::GamepadDeviceLinux::~GamepadDeviceLinux):
(WebCore::GamepadDeviceLinux::updateForEvent):
(WebCore::GamepadDeviceLinux::normalizeAxisValue):
(WebCore::GamepadDeviceLinux::normalizeButtonValue):
* platform/linux/GamepadDeviceLinux.h: Added.
(WebCore):
(GamepadDeviceLinux):
(WebCore::GamepadDeviceLinux::connected):
(WebCore::GamepadDeviceLinux::id):
(WebCore::GamepadDeviceLinux::timestamp):
(WebCore::GamepadDeviceLinux::axesCount):
(WebCore::GamepadDeviceLinux::axesData):
(WebCore::GamepadDeviceLinux::buttonsCount):
(WebCore::GamepadDeviceLinux::buttonsData):

Source/WebKit/gtk: 

Add the Gamepad feature dependencies libraries to the LIBADD
list for the libwebkitgtk library.

* GNUmakefile.am:

Source/WebKit2: 

Add the Gamepad feature dependencies libraries to the LIBADD
list for the libwebkitgtk2 library.

* GNUmakefile.am:

Tools: 

Enable the gamepad support for the GTK port.

* Scripts/webkitperl/FeatureList.pm:

Modified Paths

Added Paths

Diff

Modified: trunk/ChangeLog (121331 => 121332)


--- trunk/ChangeLog	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/ChangeLog	2012-06-27 09:19:15 UTC (rev 121332)
@@ -1,3 +1,18 @@
+2012-06-27  Zan Dobersek  <zandober...@gmail.com>
+
+        [Gtk] Add support for the Gamepad API
+        https://bugs.webkit.org/show_bug.cgi?id=87503
+
+        Reviewed by Carlos Garcia Campos.
+
+        Only enable the Gamepad feature on Linux as support
+        for other operating systems is not present.
+
+        Check for the GIO Unix and GUdev dependencies when the
+        Gamepad feature is enabled.
+
+        * configure.ac:
+
 2012-06-25  Simon Hausmann  <simon.hausm...@nokia.com>
 
         [Qt] Make it possible to build WebKit without QtWidgets

Modified: trunk/Source/WebCore/ChangeLog (121331 => 121332)


--- trunk/Source/WebCore/ChangeLog	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebCore/ChangeLog	2012-06-27 09:19:15 UTC (rev 121332)
@@ -1,3 +1,64 @@
+2012-06-27  Zan Dobersek  <zandober...@gmail.com>
+
+        [Gtk] Add support for the Gamepad API
+        https://bugs.webkit.org/show_bug.cgi?id=87503
+
+        Reviewed by Carlos Garcia Campos.
+
+        Add support for the Gamepad feature on the GTK port.
+
+        The support is available only on Linux, with each gamepad device being presented
+        through a GamepadDeviceLinux object. The implementation of this class relies on
+        the Linux kernel joystick API.
+
+        Gamepad devices are recognized through the GamepadsGtk class, of which implementation
+        is based on GUdev. This way devices are properly registered on connection as objects of
+        the GamepadDeviceGtk class which inherits GamepadDeviceLinux. GamepadDeviceGtk reads the
+        joystick data through GIO pollable streams and updates the device state accordingly. The
+        GamepadsGtk object is then polled for gamepads data through the sampleGamepads method.
+
+        No new tests - tests already exist but require additional testing infrastructure.
+
+        * GNUmakefile.am:
+        * GNUmakefile.list.am:
+        * bindings/gobject/GNUmakefile.am:
+        * bindings/js/JSDOMBinding.h: Add the jsArray method that operates on a Vector of floats.
+        (WebCore):
+        (WebCore::jsArray):
+        * platform/gtk/GamepadsGtk.cpp: Added.
+        (WebCore):
+        (GamepadDeviceGtk):
+        (WebCore::GamepadDeviceGtk::create):
+        (WebCore::GamepadDeviceGtk::GamepadDeviceGtk):
+        (WebCore::GamepadDeviceGtk::~GamepadDeviceGtk):
+        (WebCore::GamepadDeviceGtk::readCallback):
+        (GamepadsGtk):
+        (WebCore::GamepadsGtk::GamepadsGtk):
+        (WebCore::GamepadsGtk::~GamepadsGtk):
+        (WebCore::GamepadsGtk::registerDevice):
+        (WebCore::GamepadsGtk::unregisterDevice):
+        (WebCore::GamepadsGtk::updateGamepadList):
+        (WebCore::GamepadsGtk::onUEventCallback):
+        (WebCore::GamepadsGtk::isGamepadDevice):
+        (WebCore::sampleGamepads):
+        * platform/linux/GamepadDeviceLinux.cpp: Added.
+        (WebCore):
+        (WebCore::GamepadDeviceLinux::GamepadDeviceLinux):
+        (WebCore::GamepadDeviceLinux::~GamepadDeviceLinux):
+        (WebCore::GamepadDeviceLinux::updateForEvent):
+        (WebCore::GamepadDeviceLinux::normalizeAxisValue):
+        (WebCore::GamepadDeviceLinux::normalizeButtonValue):
+        * platform/linux/GamepadDeviceLinux.h: Added.
+        (WebCore):
+        (GamepadDeviceLinux):
+        (WebCore::GamepadDeviceLinux::connected):
+        (WebCore::GamepadDeviceLinux::id):
+        (WebCore::GamepadDeviceLinux::timestamp):
+        (WebCore::GamepadDeviceLinux::axesCount):
+        (WebCore::GamepadDeviceLinux::axesData):
+        (WebCore::GamepadDeviceLinux::buttonsCount):
+        (WebCore::GamepadDeviceLinux::buttonsData):
+
 2012-06-27  Kentaro Hara  <hara...@chromium.org>
 
         Rename rareSVGData() to svgRareData()

Modified: trunk/Source/WebCore/GNUmakefile.am (121331 => 121332)


--- trunk/Source/WebCore/GNUmakefile.am	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebCore/GNUmakefile.am	2012-06-27 09:19:15 UTC (rev 121332)
@@ -12,6 +12,7 @@
 	-I$(srcdir)/Source/ThirdParty/ANGLE/include/GLSLANG \
 	-I$(srcdir)/Source/WebCore \
 	-I$(srcdir)/Source/WebCore/Modules/filesystem \
+	-I$(srcdir)/Source/WebCore/Modules/gamepad \
 	-I$(srcdir)/Source/WebCore/Modules/geolocation \
 	-I$(srcdir)/Source/WebCore/Modules/indexeddb \
 	-I$(srcdir)/Source/WebCore/Modules/mediastream \
@@ -67,6 +68,7 @@
 	-I$(srcdir)/Source/WebCore/platform/image-decoders/webp \
 	-I$(srcdir)/Source/WebCore/platform/image-decoders/png \
 	-I$(srcdir)/Source/WebCore/platform/leveldb \
+	-I$(srcdir)/Source/WebCore/platform/linux \
 	-I$(srcdir)/Source/WebCore/platform/mediastream \
 	-I$(srcdir)/Source/WebCore/platform/mediastream/gstreamer \
 	-I$(srcdir)/Source/WebCore/platform/mock \
@@ -866,6 +868,7 @@
 
 IDL_PATH := \
     $(WebCore)/Modules/filesystem \
+    $(WebCore)/Modules/gamepad \
     $(WebCore)/Modules/geolocation \
     $(WebCore)/Modules/indexeddb \
     $(WebCore)/Modules/mediastream \
@@ -961,6 +964,7 @@
 	$(CLUTTER_CFLAGS) \
 	$(COVERAGE_CFLAGS) \
 	$(ENCHANT_CFLAGS) \
+	$(GAMEPAD_CFLAGS) \
 	$(GEOCLUE_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	$(GSTREAMER_CFLAGS) \
@@ -1032,6 +1036,7 @@
 
 EXTRA_DIST += \
 	$(shell ls $(srcdir)/Source/WebCore/Modules/filesystem/*.idl) \
+	$(shell ls $(srcdir)/Source/WebCore/Modules/gamepad/*.idl) \
 	$(shell ls $(srcdir)/Source/WebCore/Modules/geolocation/*.idl) \
 	$(shell ls $(srcdir)/Source/WebCore/Modules/indexeddb/*.idl) \
 	$(shell ls $(srcdir)/Source/WebCore/Modules/mediastream/*.idl) \

Modified: trunk/Source/WebCore/GNUmakefile.list.am (121331 => 121332)


--- trunk/Source/WebCore/GNUmakefile.list.am	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2012-06-27 09:19:15 UTC (rev 121332)
@@ -192,6 +192,10 @@
 	DerivedSources/WebCore/JSFloat32Array.h \
 	DerivedSources/WebCore/JSFloat64Array.cpp \
 	DerivedSources/WebCore/JSFloat64Array.h \
+	DerivedSources/WebCore/JSGamepad.cpp \
+	DerivedSources/WebCore/JSGamepad.h \
+	DerivedSources/WebCore/JSGamepadList.cpp \
+	DerivedSources/WebCore/JSGamepadList.h \
 	DerivedSources/WebCore/JSGeolocation.cpp \
 	DerivedSources/WebCore/JSGeolocation.h \
 	DerivedSources/WebCore/JSGeoposition.cpp \
@@ -677,6 +681,9 @@
 	DerivedSources/WebCore/XPathGrammar.h
 
 dom_binding_idls += \
+	$(WebCore)/Modules/gamepad/Gamepad.idl \
+	$(WebCore)/Modules/gamepad/GamepadList.idl \
+	$(WebCore)/Modules/gamepad/NavigatorGamepad.idl \
 	$(WebCore)/Modules/geolocation/Geolocation.idl \
 	$(WebCore)/Modules/geolocation/Geoposition.idl \
 	$(WebCore)/Modules/geolocation/NavigatorGeolocation.idl \
@@ -1053,6 +1060,12 @@
 	Source/WebCore/Modules/filesystem/WebKitFlags.h \
 	Source/WebCore/Modules/filesystem/WorkerContextFileSystem.cpp \
 	Source/WebCore/Modules/filesystem/WorkerContextFileSystem.h \
+	Source/WebCore/Modules/gamepad/Gamepad.cpp \
+	Source/WebCore/Modules/gamepad/Gamepad.h \
+	Source/WebCore/Modules/gamepad/GamepadList.cpp \
+	Source/WebCore/Modules/gamepad/GamepadList.h \
+	Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp \
+	Source/WebCore/Modules/gamepad/NavigatorGamepad.h \
 	Source/WebCore/Modules/geolocation/Geolocation.cpp \
 	Source/WebCore/Modules/geolocation/Geolocation.h \
 	Source/WebCore/Modules/geolocation/GeolocationController.cpp \
@@ -3160,6 +3173,7 @@
 	Source/WebCore/platform/FileSystem.h \
 	Source/WebCore/platform/FloatConversion.h \
 	Source/WebCore/platform/FractionalLayoutUnit.h \
+	Source/WebCore/platform/Gamepads.h \
 	Source/WebCore/platform/HashTools.h \
 	Source/WebCore/platform/HistogramSupport.cpp \
 	Source/WebCore/platform/HistogramSupport.h \
@@ -3408,6 +3422,7 @@
 	Source/WebCore/platform/graphics/WOFFFileFormat.h \
 	Source/WebCore/platform/gtk/ErrorsGtk.cpp \
 	Source/WebCore/platform/gtk/ErrorsGtk.h \
+	Source/WebCore/platform/gtk/GamepadsGtk.cpp \
 	Source/WebCore/platform/gtk/KURLGtk.cpp \
 	Source/WebCore/platform/gtk/LanguageGtk.cpp \
 	Source/WebCore/platform/gtk/LoggingGtk.cpp \
@@ -3468,6 +3483,8 @@
 	Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h \
 	Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp \
 	Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h \
+	Source/WebCore/platform/linux/GamepadDeviceLinux.cpp \
+	Source/WebCore/platform/linux/GamepadDeviceLinux.h \
 	Source/WebCore/platform/mediastream/DeprecatedPeerConnectionHandler.h \
 	Source/WebCore/platform/mediastream/DeprecatedPeerConnectionHandlerClient.h \
 	Source/WebCore/platform/mediastream/IceCandidateDescriptor.cpp \

Modified: trunk/Source/WebCore/bindings/gobject/GNUmakefile.am (121331 => 121332)


--- trunk/Source/WebCore/bindings/gobject/GNUmakefile.am	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebCore/bindings/gobject/GNUmakefile.am	2012-06-27 09:19:15 UTC (rev 121332)
@@ -66,6 +66,10 @@
 	DerivedSources/webkit/WebKitDOMFileList.cpp \
 	DerivedSources/webkit/WebKitDOMFileListPrivate.h \
 	DerivedSources/webkit/WebKitDOMFilePrivate.h \
+	DerivedSources/webkit/WebKitDOMGamepad.cpp \
+	DerivedSources/webkit/WebKitDOMGamepadList.cpp \
+	DerivedSources/webkit/WebKitDOMGamepadListPrivate.h \
+	DerivedSources/webkit/WebKitDOMGamepadPrivate.h \
 	DerivedSources/webkit/WebKitDOMGeolocation.cpp \
 	DerivedSources/webkit/WebKitDOMGeolocationPrivate.h \
 	DerivedSources/webkit/WebKitDOMHistory.cpp \
@@ -295,6 +299,8 @@
 	DerivedSources/webkit/WebKitDOMBlob.h \
 	DerivedSources/webkit/WebKitDOMFile.h \
 	DerivedSources/webkit/WebKitDOMFileList.h \
+	DerivedSources/webkit/WebKitDOMGamepad.h \
+	DerivedSources/webkit/WebKitDOMGamepadList.h \
 	DerivedSources/webkit/WebKitDOMGeolocation.h \
 	DerivedSources/webkit/WebKitDOMHTMLAnchorElement.h \
 	DerivedSources/webkit/WebKitDOMHTMLAppletElement.h \
@@ -428,7 +434,6 @@
 	DerivedSources/webkit/WebKitDOMHTMLPropertiesCollectionPrivate.h
 endif
 
-
 if ENABLE_WEB_TIMING
 webkitgtk_built_h_api += \
 	$(top_builddir)/DerivedSources/webkit/WebKitDOMPerformance.h \

Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (121331 => 121332)


--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2012-06-27 09:19:15 UTC (rev 121332)
@@ -307,6 +307,18 @@
         return JSC::constructArray(exec, globalObject, array);
     }
 
+    template<>
+    inline JSC::JSValue jsArray(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<float>& iterator)
+    {
+        JSC::MarkedArgumentBuffer array;
+        Vector<float>::const_iterator end = iterator.end();
+
+        for (Vector<float>::const_iterator it = iterator.begin(); it != end; ++it)
+            array.append(JSC::jsNumber(*it));
+
+        return JSC::constructArray(exec, globalObject, array);
+    }
+
     template <class T>
     Vector<T> toNativeArray(JSC::ExecState* exec, JSC::JSValue value)
     {

Added: trunk/Source/WebCore/platform/gtk/GamepadsGtk.cpp (0 => 121332)


--- trunk/Source/WebCore/platform/gtk/GamepadsGtk.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/gtk/GamepadsGtk.cpp	2012-06-27 09:19:15 UTC (rev 121332)
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2012 Zan Dobersek <zandober...@gmail.com>
+ *
+ * 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 "Gamepads.h"
+
+#if ENABLE(GAMEPAD)
+
+#include "GamepadDeviceLinux.h"
+#include "GamepadList.h"
+#include <gio/gunixinputstream.h>
+#include <gudev/gudev.h>
+#include <wtf/HashMap.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class GamepadDeviceGtk : public GamepadDeviceLinux {
+public:
+    static PassOwnPtr<GamepadDeviceGtk> create(String deviceFile)
+    {
+        return adoptPtr(new GamepadDeviceGtk(deviceFile));
+    }
+    ~GamepadDeviceGtk();
+
+private:
+    GamepadDeviceGtk(String deviceFile);
+
+    static gboolean readCallback(GObject* pollableStream, gpointer data);
+    GRefPtr<GInputStream> m_inputStream;
+    GRefPtr<GSource> m_source;
+};
+
+GamepadDeviceGtk::GamepadDeviceGtk(String deviceFile)
+    : GamepadDeviceLinux(deviceFile)
+{
+    if (m_fileDescriptor == -1)
+        return;
+
+    m_inputStream = adoptGRef(g_unix_input_stream_new(m_fileDescriptor, FALSE));
+    m_source = adoptGRef(g_pollable_input_stream_create_source(G_POLLABLE_INPUT_STREAM(m_inputStream.get()), 0));
+    g_source_set_callback(m_source.get(), reinterpret_cast<GSourceFunc>(readCallback), this, 0);
+    g_source_attach(m_source.get(), 0);
+}
+
+GamepadDeviceGtk::~GamepadDeviceGtk()
+{
+    if (m_source)
+        g_source_destroy(m_source.get());
+}
+
+gboolean GamepadDeviceGtk::readCallback(GObject* pollableStream, gpointer data)
+{
+    GamepadDeviceGtk* gamepadDevice = reinterpret_cast<GamepadDeviceGtk*>(data);
+    GOwnPtr<GError> error;
+    struct js_event event;
+
+    gssize len = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(pollableStream),
+                                                          &event, sizeof(event), 0, &error.outPtr());
+
+    // FIXME: Properly log the error.
+    // In the case of G_IO_ERROR_WOULD_BLOCK error return TRUE to wait until
+    // the source becomes readable again and FALSE otherwise.
+    if (error)
+        return g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
+
+    ASSERT(len == sizeof(event));
+    gamepadDevice->updateForEvent(event);
+    return TRUE;
+}
+
+class GamepadsGtk {
+public:
+    GamepadsGtk(unsigned length);
+
+    void registerDevice(String deviceFile);
+    void unregisterDevice(String deviceFile);
+
+    void updateGamepadList(GamepadList*);
+
+private:
+    ~GamepadsGtk();
+    static void onUEventCallback(GUdevClient*, gchar* action, GUdevDevice*, gpointer data);
+    static gboolean isGamepadDevice(GUdevDevice*);
+
+    Vector<OwnPtr<GamepadDeviceGtk> > m_slots;
+    HashMap<String, GamepadDeviceGtk*> m_deviceMap;
+
+    GRefPtr<GUdevClient> m_gudevClient;
+};
+
+GamepadsGtk::GamepadsGtk(unsigned length)
+    : m_slots(length)
+{
+    static const char* subsystems[] = { "input", 0 };
+    m_gudevClient = adoptGRef(g_udev_client_new(subsystems));
+    g_signal_connect(m_gudevClient.get(), "uevent", G_CALLBACK(onUEventCallback), this);
+
+    GOwnPtr<GList> devicesList(g_udev_client_query_by_subsystem(m_gudevClient.get(), subsystems[0]));
+    for (GList* listItem = devicesList.get(); listItem; listItem = g_list_next(listItem)) {
+        GUdevDevice* device = G_UDEV_DEVICE(listItem->data);
+        String deviceFile = String::fromUTF8(g_udev_device_get_device_file(device));
+        if (isGamepadDevice(device))
+            registerDevice(deviceFile);
+        g_object_unref(device);
+    }
+}
+
+GamepadsGtk::~GamepadsGtk()
+{
+    g_signal_handlers_disconnect_matched(m_gudevClient.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+}
+
+void GamepadsGtk::registerDevice(String deviceFile)
+{
+    ASSERT(!m_deviceMap.contains(deviceFile));
+
+    for (unsigned index = 0; index < m_slots.size(); index++) {
+        if (!m_slots[index]) {
+            m_slots[index] = GamepadDeviceGtk::create(deviceFile);
+            m_deviceMap.add(deviceFile, m_slots[index].get());
+            break;
+        }
+    }
+}
+
+void GamepadsGtk::unregisterDevice(String deviceFile)
+{
+    ASSERT(m_deviceMap.contains(deviceFile));
+
+    GamepadDeviceGtk* gamepadDevice = m_deviceMap.take(deviceFile);
+    unsigned index = m_slots.find(gamepadDevice);
+    ASSERT(index != notFound);
+
+    m_slots[index].clear();
+}
+
+void GamepadsGtk::updateGamepadList(GamepadList* into)
+{
+    ASSERT(m_slots.size() == into->length());
+
+    for (unsigned i = 0; i < m_slots.size(); i++) {
+        if (m_slots[i].get() && m_slots[i]->connected()) {
+            GamepadDeviceGtk* gamepadDevice = m_slots[i].get();
+            RefPtr<Gamepad> gamepad = into->item(i);
+            if (!gamepad)
+                gamepad = Gamepad::create();
+
+            gamepad->index(i);
+            gamepad->id(gamepadDevice->id());
+            gamepad->timestamp(gamepadDevice->timestamp());
+            gamepad->axes(gamepadDevice->axesCount(), gamepadDevice->axesData());
+            gamepad->buttons(gamepadDevice->buttonsCount(), gamepadDevice->buttonsData());
+
+            into->set(i, gamepad);
+        } else
+            into->set(i, 0);
+    }
+}
+
+void GamepadsGtk::onUEventCallback(GUdevClient* udevClient, gchar* action, GUdevDevice* device, gpointer data)
+{
+    if (!isGamepadDevice(device))
+        return;
+
+    GamepadsGtk* gamepadsGtk = reinterpret_cast<GamepadsGtk*>(data);
+    String deviceFile = String::fromUTF8(g_udev_device_get_device_file(device));
+
+    if (!g_strcmp0(action, "add"))
+        gamepadsGtk->registerDevice(deviceFile);
+    else if (!g_strcmp0(action, "remove"))
+        gamepadsGtk->unregisterDevice(deviceFile);
+}
+
+gboolean GamepadsGtk::isGamepadDevice(GUdevDevice* device)
+{
+    const gchar* deviceFile = g_udev_device_get_device_file(device);
+    const gchar* sysfsPath = g_udev_device_get_sysfs_path(device);
+    if (!deviceFile || !sysfsPath)
+        return FALSE;
+
+    if (!g_udev_device_has_property(device, "ID_INPUT") || !g_udev_device_has_property(device, "ID_INPUT_JOYSTICK"))
+        return FALSE;
+
+    return g_str_has_prefix(deviceFile, "/dev/input/js");
+}
+
+void sampleGamepads(GamepadList* into)
+{
+    DEFINE_STATIC_LOCAL(GamepadsGtk, gamepadsGtk, (into->length()));
+    gamepadsGtk.updateGamepadList(into);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)

Added: trunk/Source/WebCore/platform/linux/GamepadDeviceLinux.cpp (0 => 121332)


--- trunk/Source/WebCore/platform/linux/GamepadDeviceLinux.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/linux/GamepadDeviceLinux.cpp	2012-06-27 09:19:15 UTC (rev 121332)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2012 Zan Dobersek <zandober...@gmail.com>
+ *
+ * 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 "GamepadDeviceLinux.h"
+
+#if ENABLE(GAMEPAD)
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+GamepadDeviceLinux::GamepadDeviceLinux(String deviceFile)
+    : m_fileDescriptor(-1)
+    , m_connected(false)
+    , m_lastTimestamp(0)
+{
+    // FIXME: Log errors when returning early.
+    m_fileDescriptor = open(deviceFile.utf8().data(), O_RDONLY | O_NONBLOCK);
+    if (m_fileDescriptor == -1)
+        return;
+
+    char deviceName[1024];
+    if (ioctl(m_fileDescriptor, JSIOCGNAME(sizeof(deviceName)), deviceName) < 0)
+        return;
+    m_deviceName = String(deviceName).simplifyWhiteSpace();
+
+    uint8_t numberOfAxes;
+    uint8_t numberOfButtons;
+    if (ioctl(m_fileDescriptor, JSIOCGAXES, &numberOfAxes) < 0 || ioctl(m_fileDescriptor, JSIOCGBUTTONS, &numberOfButtons) < 0)
+        return;
+    m_axes.fill(0.0, numberOfAxes);
+    m_buttons.fill(0.0, numberOfButtons);
+}
+
+GamepadDeviceLinux::~GamepadDeviceLinux()
+{
+    if (m_fileDescriptor != -1)
+        close(m_fileDescriptor);
+}
+
+void GamepadDeviceLinux::updateForEvent(struct js_event event)
+{
+    if (!(event.type & JS_EVENT_AXIS || event.type & JS_EVENT_BUTTON))
+        return;
+
+    // Mark the device as connected only if it is not yet connected, the event is not an initialization
+    // and the value is not 0 (indicating a genuine interaction with the device).
+    if (!m_connected && !(event.type & JS_EVENT_INIT) && event.value)
+        m_connected = true;
+
+    if (event.type & JS_EVENT_AXIS)
+        m_axes[event.number] = normalizeAxisValue(event.value);
+    else if (event.type & JS_EVENT_BUTTON)
+        m_buttons[event.number] = normalizeButtonValue(event.value);
+
+    m_lastTimestamp = event.time;
+}
+
+float GamepadDeviceLinux::normalizeAxisValue(short value)
+{
+    // Normalize from range [-32767, 32767] into range [-1.0, 1.0]
+    return value / 32767.0f;
+}
+
+float GamepadDeviceLinux::normalizeButtonValue(short value)
+{
+    // Normalize from range [0, 1] into range [0.0, 1.0]
+    return value / 1.0f;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)

Added: trunk/Source/WebCore/platform/linux/GamepadDeviceLinux.h (0 => 121332)


--- trunk/Source/WebCore/platform/linux/GamepadDeviceLinux.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/linux/GamepadDeviceLinux.h	2012-06-27 09:19:15 UTC (rev 121332)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 Zan Dobersek <zandober...@gmail.com>
+ *
+ * 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 GamepadDeviceLinux_h
+#define GamepadDeviceLinux_h
+
+#if ENABLE(GAMEPAD)
+
+#include <linux/joystick.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class GamepadDeviceLinux {
+public:
+    bool connected() { return m_connected; };
+
+    String id() { return m_deviceName; }
+    unsigned long long timestamp() { return m_lastTimestamp; }
+
+    unsigned axesCount() { return m_axes.size(); }
+    float* axesData() { return m_axes.data(); }
+
+    unsigned buttonsCount() { return m_buttons.size(); }
+    float* buttonsData() { return m_buttons.data(); }
+
+protected:
+    GamepadDeviceLinux(String deviceFile);
+    ~GamepadDeviceLinux();
+
+    void updateForEvent(struct js_event);
+    int m_fileDescriptor;
+
+private:
+    float normalizeAxisValue(short value);
+    float normalizeButtonValue(short value);
+
+    bool m_connected;
+    String m_deviceName;
+    unsigned long long m_lastTimestamp;
+
+    Vector<float> m_axes;
+    Vector<float> m_buttons;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
+
+#endif // GamepadDeviceLinux_h

Modified: trunk/Source/WebKit/gtk/ChangeLog (121331 => 121332)


--- trunk/Source/WebKit/gtk/ChangeLog	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebKit/gtk/ChangeLog	2012-06-27 09:19:15 UTC (rev 121332)
@@ -1,3 +1,15 @@
+2012-06-27  Zan Dobersek  <zandober...@gmail.com>
+
+        [Gtk] Add support for the Gamepad API
+        https://bugs.webkit.org/show_bug.cgi?id=87503
+
+        Reviewed by Carlos Garcia Campos.
+
+        Add the Gamepad feature dependencies libraries to the LIBADD
+        list for the libwebkitgtk library.
+
+        * GNUmakefile.am:
+
 2012-06-25  Carlos Garcia Campos  <cgar...@igalia.com>
 
         Unreviewed. Update NEWS and configure.ac for 1.9.4 release

Modified: trunk/Source/WebKit/gtk/GNUmakefile.am (121331 => 121332)


--- trunk/Source/WebKit/gtk/GNUmakefile.am	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebKit/gtk/GNUmakefile.am	2012-06-27 09:19:15 UTC (rev 121332)
@@ -87,6 +87,7 @@
 	$(ENCHANT_LIBS) \
 	$(FREETYPE_LIBS) \
 	$(GAIL_LIBS) \
+	$(GAMEPAD_LIBS) \
 	$(GEOCLUE_LIBS) \
 	$(GLIB_LIBS) \
 	$(GSTREAMER_LIBS) \

Modified: trunk/Source/WebKit2/ChangeLog (121331 => 121332)


--- trunk/Source/WebKit2/ChangeLog	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebKit2/ChangeLog	2012-06-27 09:19:15 UTC (rev 121332)
@@ -1,3 +1,15 @@
+2012-06-27  Zan Dobersek  <zandober...@gmail.com>
+
+        [Gtk] Add support for the Gamepad API
+        https://bugs.webkit.org/show_bug.cgi?id=87503
+
+        Reviewed by Carlos Garcia Campos.
+
+        Add the Gamepad feature dependencies libraries to the LIBADD
+        list for the libwebkitgtk2 library.
+
+        * GNUmakefile.am:
+
 2012-06-26  Simon Hausmann  <simon.hausm...@nokia.com>
 
         [Qt] Avoid use of deprecated Qt API

Modified: trunk/Source/WebKit2/GNUmakefile.am (121331 => 121332)


--- trunk/Source/WebKit2/GNUmakefile.am	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Source/WebKit2/GNUmakefile.am	2012-06-27 09:19:15 UTC (rev 121332)
@@ -160,6 +160,7 @@
 	$(COVERAGE_LDFLAGS) \
 	$(ENCHANT_LIBS) \
 	$(GAIL_LIBS) \
+	$(GAMEPAD_LIBS) \
 	$(GEOCLUE_LIBS) \
 	$(GLIB_LIBS) \
 	$(GSTREAMER_LIBS) \

Modified: trunk/Tools/ChangeLog (121331 => 121332)


--- trunk/Tools/ChangeLog	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Tools/ChangeLog	2012-06-27 09:19:15 UTC (rev 121332)
@@ -1,3 +1,14 @@
+2012-06-27  Zan Dobersek  <zandober...@gmail.com>
+
+        [Gtk] Add support for the Gamepad API
+        https://bugs.webkit.org/show_bug.cgi?id=87503
+
+        Reviewed by Carlos Garcia Campos.
+
+        Enable the gamepad support for the GTK port.
+
+        * Scripts/webkitperl/FeatureList.pm:
+
 2012-06-27  Ryosuke Niwa  <rn...@webkit.org>
 
         Fix gcc build after r121302

Modified: trunk/Tools/Scripts/webkitperl/FeatureList.pm (121331 => 121332)


--- trunk/Tools/Scripts/webkitperl/FeatureList.pm	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/Tools/Scripts/webkitperl/FeatureList.pm	2012-06-27 09:19:15 UTC (rev 121332)
@@ -214,7 +214,7 @@
       define => "ENABLE_FULLSCREEN_API", default => (isAppleMacWebKit() || isEfl() || isGtk() || isBlackBerry() || isQt()), value => \$fullscreenAPISupport },
 
     { option => "gamepad", desc => "Toggle Gamepad support",
-      define => "ENABLE_GAMEPAD", default => 0, value => \$gamepadSupport },
+      define => "ENABLE_GAMEPAD", default => isGtk(), value => \$gamepadSupport },
 
     { option => "geolocation", desc => "Toggle Geolocation support",
       define => "ENABLE_GEOLOCATION", default => (isAppleWebKit() || isGtk() || isBlackBerry()), value => \$geolocationSupport },

Modified: trunk/configure.ac (121331 => 121332)


--- trunk/configure.ac	2012-06-27 09:15:18 UTC (rev 121331)
+++ trunk/configure.ac	2012-06-27 09:19:15 UTC (rev 121332)
@@ -653,6 +653,11 @@
               [],[enable_gamepad="no"])
 AC_MSG_RESULT([$enable_gamepad])
 
+if test "$enable_gamepad" = "yes" && test "$os_linux" = no; then
+   AC_MSG_WARN([Gamepad support is only available on Linux. Disabling Gamepad support.])
+   enable_gamepad=no;
+fi
+
 # check whether to build with data transfer items support
 AC_MSG_CHECKING([whether to enable HTML5 data transfer items support])
 AC_ARG_ENABLE(data_transfer_items,
@@ -1276,6 +1281,13 @@
    AC_SUBST([ATSPI2_LIBS])
 fi
 
+if test "$enable_gamepad" = "yes"; then
+   PKG_CHECK_MODULES([GAMEPAD], [gio-unix-2.0 gudev-1.0])
+
+   AC_SUBST(GAMEPAD_CFLAGS)
+   AC_SUBST(GAMEPAD_LIBS)
+fi
+
 # check for code coverage support
 if test "$enable_coverage" = "yes"; then
    COVERAGE_CFLAGS="-MD"
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to