diff options
Diffstat (limited to 'Source/WebCore/platform/gamepad')
10 files changed, 763 insertions, 0 deletions
diff --git a/Source/WebCore/platform/gamepad/EmptyGamepadProvider.cpp b/Source/WebCore/platform/gamepad/EmptyGamepadProvider.cpp new file mode 100644 index 000000000..62401c8aa --- /dev/null +++ b/Source/WebCore/platform/gamepad/EmptyGamepadProvider.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 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 "EmptyGamepadProvider.h" + +#if ENABLE(GAMEPAD) + +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +void EmptyGamepadProvider::startMonitoringGamepads(GamepadProviderClient&) +{ +} + +void EmptyGamepadProvider::stopMonitoringGamepads(GamepadProviderClient&) +{ +} + +const Vector<PlatformGamepad*>& EmptyGamepadProvider::platformGamepads() +{ + static NeverDestroyed<Vector<PlatformGamepad*>> emptyGamepads; + return emptyGamepads; +} + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebCore/platform/gamepad/EmptyGamepadProvider.h b/Source/WebCore/platform/gamepad/EmptyGamepadProvider.h new file mode 100644 index 000000000..4b7546aa0 --- /dev/null +++ b/Source/WebCore/platform/gamepad/EmptyGamepadProvider.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016 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. + */ + +#pragma once + +#if ENABLE(GAMEPAD) + +#include "GamepadProvider.h" + +namespace WebCore { + +class EmptyGamepadProvider : public GamepadProvider { +public: + ~EmptyGamepadProvider() final { } + +private: + void startMonitoringGamepads(GamepadProviderClient&) final; + void stopMonitoringGamepads(GamepadProviderClient&) final; + const Vector<PlatformGamepad*>& platformGamepads() final; +}; + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebCore/platform/gamepad/GamepadProvider.cpp b/Source/WebCore/platform/gamepad/GamepadProvider.cpp new file mode 100644 index 000000000..79c47af46 --- /dev/null +++ b/Source/WebCore/platform/gamepad/GamepadProvider.cpp @@ -0,0 +1,63 @@ +/* + * 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 "GamepadProvider.h" + +#if ENABLE(GAMEPAD) + +#include "EmptyGamepadProvider.h" +#include "GamepadProviderClient.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +static GamepadProvider* sharedProvider = nullptr; + +GamepadProvider& GamepadProvider::singleton() +{ + if (!sharedProvider) { + static NeverDestroyed<EmptyGamepadProvider> defaultProvider; + sharedProvider = &defaultProvider.get(); + } + + return *sharedProvider; +} + +void GamepadProvider::setSharedProvider(GamepadProvider& newProvider) +{ + sharedProvider = &newProvider; +} + +void GamepadProvider::dispatchPlatformGamepadInputActivity() +{ + for (auto& client : m_clients) + client->platformGamepadInputActivity(m_shouldMakeGamepadsVisible); + + m_shouldMakeGamepadsVisible = false; +} + +} // namespace WebCore + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebCore/platform/gamepad/GamepadProvider.h b/Source/WebCore/platform/gamepad/GamepadProvider.h new file mode 100644 index 000000000..1d50f2c14 --- /dev/null +++ b/Source/WebCore/platform/gamepad/GamepadProvider.h @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#pragma once + +#if ENABLE(GAMEPAD) + +#include <wtf/HashSet.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class GamepadProviderClient; +class PlatformGamepad; + +class WEBCORE_EXPORT GamepadProvider { +public: + virtual ~GamepadProvider() { } + + WEBCORE_EXPORT static GamepadProvider& singleton(); + WEBCORE_EXPORT static void setSharedProvider(GamepadProvider&); + + virtual void startMonitoringGamepads(GamepadProviderClient&) = 0; + virtual void stopMonitoringGamepads(GamepadProviderClient&) = 0; + virtual const Vector<PlatformGamepad*>& platformGamepads() = 0; + virtual bool isMockGamepadProvider() const { return false; } + +protected: + void dispatchPlatformGamepadInputActivity(); + void setShouldMakeGamepadsVisibile() { m_shouldMakeGamepadsVisible = true; } + HashSet<GamepadProviderClient*> m_clients; + +private: + bool m_shouldMakeGamepadsVisible { false }; +}; + +} // namespace WebCore + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebCore/platform/gamepad/GamepadProviderClient.h b/Source/WebCore/platform/gamepad/GamepadProviderClient.h new file mode 100644 index 000000000..63ea46cd7 --- /dev/null +++ b/Source/WebCore/platform/gamepad/GamepadProviderClient.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +#pragma once + +#if ENABLE(GAMEPAD) + +#include <wtf/Vector.h> + +namespace WebCore { + +class PlatformGamepad; + +class GamepadProviderClient { +public: + virtual ~GamepadProviderClient() { } + + virtual void setInitialConnectedGamepads(const Vector<PlatformGamepad*>&) { } + virtual void platformGamepadConnected(PlatformGamepad&) = 0; + virtual void platformGamepadDisconnected(PlatformGamepad&) = 0; + virtual void platformGamepadInputActivity(bool shouldMakeGamepadVisible) = 0; +}; + +} // namespace WebCore + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebCore/platform/gamepad/PlatformGamepad.h b/Source/WebCore/platform/gamepad/PlatformGamepad.h new file mode 100644 index 000000000..2b8d7a998 --- /dev/null +++ b/Source/WebCore/platform/gamepad/PlatformGamepad.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#pragma once + +#if ENABLE(GAMEPAD) + +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class PlatformGamepad { +public: + virtual ~PlatformGamepad() { } + + const String& id() const { return m_id; } + unsigned index() const { return m_index; } + double lastUpdateTime() const { return m_lastUpdateTime; } + double connectTime() const { return m_connectTime; } + virtual const Vector<double>& axisValues() const = 0; + virtual const Vector<double>& buttonValues() const = 0; + +protected: + explicit PlatformGamepad(unsigned index) + : m_index(index) + , m_lastUpdateTime(0.0) + , m_connectTime(0.0) + { + } + + String m_id; + unsigned m_index; + double m_lastUpdateTime; + double m_connectTime; +}; + +} // namespace WebCore + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebCore/platform/gamepad/deprecated/Gamepads.h b/Source/WebCore/platform/gamepad/deprecated/Gamepads.h new file mode 100644 index 000000000..4538cced8 --- /dev/null +++ b/Source/WebCore/platform/gamepad/deprecated/Gamepads.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011, Google 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 Gamepads_h +#define Gamepads_h + +#if ENABLE(GAMEPAD_DEPRECATED) + +namespace WebCore { + +class GamepadList; + +void sampleGamepads(GamepadList* into); + +} + +#endif // ENABLE(GAMEPAD_DEPRECATED) + +#endif // Gamepads_h diff --git a/Source/WebCore/platform/gamepad/glib/GamepadsGlib.cpp b/Source/WebCore/platform/gamepad/glib/GamepadsGlib.cpp new file mode 100644 index 000000000..b8bd21a5e --- /dev/null +++ b/Source/WebCore/platform/gamepad/glib/GamepadsGlib.cpp @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2012 Zan Dobersek <zandobersek@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_DEPRECATED) + +#include "GamepadDeviceLinux.h" +#include "GamepadList.h" +#include "Logging.h" +#include <gio/gunixinputstream.h> +#include <gudev/gudev.h> +#include <wtf/HashMap.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> +#include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> + +namespace WebCore { + +class GamepadDeviceGlib : public GamepadDeviceLinux { +public: + explicit GamepadDeviceGlib(String deviceFile); + ~GamepadDeviceGlib(); + +private: + static gboolean readCallback(GObject* pollableStream, gpointer data); + GRefPtr<GInputStream> m_inputStream; + GRefPtr<GSource> m_source; +}; + +GamepadDeviceGlib::GamepadDeviceGlib(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); +} + +GamepadDeviceGlib::~GamepadDeviceGlib() +{ + if (m_source) + g_source_destroy(m_source.get()); +} + +gboolean GamepadDeviceGlib::readCallback(GObject* pollableStream, gpointer data) +{ + GamepadDeviceGlib* gamepadDevice = reinterpret_cast<GamepadDeviceGlib*>(data); + GUniqueOutPtr<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_UNUSED(len, len == sizeof(event)); + gamepadDevice->updateForEvent(event); + return TRUE; +} + +class GamepadsGlib { +public: + explicit GamepadsGlib(unsigned length); + + void registerDevice(String deviceFile); + void unregisterDevice(String deviceFile); + + void updateGamepadList(GamepadList*); + +private: + ~GamepadsGlib(); + static void onUEventCallback(GUdevClient*, gchar* action, GUdevDevice*, gpointer data); + static gboolean isGamepadDevice(GUdevDevice*); + + Vector<std::unique_ptr<GamepadDeviceGlib> > m_slots; + HashMap<String, GamepadDeviceGlib*> m_deviceMap; + + GRefPtr<GUdevClient> m_gudevClient; +}; + +GamepadsGlib::GamepadsGlib(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); + + GUniquePtr<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); + } +} + +GamepadsGlib::~GamepadsGlib() +{ + g_signal_handlers_disconnect_matched(m_gudevClient.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); +} + +void GamepadsGlib::registerDevice(String deviceFile) +{ + LOG(Gamepad, "GamepadsGlib::registerDevice %s", deviceFile.ascii().data()); + ASSERT(!m_deviceMap.contains(deviceFile)); + + for (unsigned index = 0; index < m_slots.size(); index++) { + if (!m_slots[index]) { + m_slots[index] = std::make_unique<GamepadDeviceGlib>(deviceFile); + m_deviceMap.add(deviceFile, m_slots[index].get()); + break; + } + } +} + +void GamepadsGlib::unregisterDevice(String deviceFile) +{ + LOG(Gamepad, "GamepadsGlib::unregisterDevice %s", deviceFile.ascii().data()); + ASSERT(m_deviceMap.contains(deviceFile)); + + GamepadDeviceGlib* gamepadDevice = m_deviceMap.take(deviceFile); + size_t index = m_slots.find(gamepadDevice); + ASSERT(index != notFound); + + m_slots[index] = nullptr; +} + +void GamepadsGlib::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()) { + GamepadDeviceGlib* 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 GamepadsGlib::onUEventCallback(GUdevClient*, gchar* action, GUdevDevice* device, gpointer data) +{ + if (!isGamepadDevice(device)) + return; + + GamepadsGlib* gamepadsGlib = reinterpret_cast<GamepadsGlib*>(data); + String deviceFile = String::fromUTF8(g_udev_device_get_device_file(device)); + + if (!g_strcmp0(action, "add")) + gamepadsGlib->registerDevice(deviceFile); + else if (!g_strcmp0(action, "remove")) + gamepadsGlib->unregisterDevice(deviceFile); +} + +gboolean GamepadsGlib::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) +{ + DEPRECATED_DEFINE_STATIC_LOCAL(GamepadsGlib, gamepadsGlib, (into->length())); + gamepadsGlib.updateGamepadList(into); +} + +} // namespace WebCore + +#endif // ENABLE(GAMEPAD_DEPRECATED) diff --git a/Source/WebCore/platform/gamepad/linux/GamepadDeviceLinux.cpp b/Source/WebCore/platform/gamepad/linux/GamepadDeviceLinux.cpp new file mode 100644 index 000000000..c51754d54 --- /dev/null +++ b/Source/WebCore/platform/gamepad/linux/GamepadDeviceLinux.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2012 Zan Dobersek <zandobersek@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_DEPRECATED) + +#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_DEPRECATED) diff --git a/Source/WebCore/platform/gamepad/linux/GamepadDeviceLinux.h b/Source/WebCore/platform/gamepad/linux/GamepadDeviceLinux.h new file mode 100644 index 000000000..99c09b27f --- /dev/null +++ b/Source/WebCore/platform/gamepad/linux/GamepadDeviceLinux.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2012 Zan Dobersek <zandobersek@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_DEPRECATED) + +#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_DEPRECATED) + +#endif // GamepadDeviceLinux_h |