diff options
author | scottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 22:28:08 +0000 |
---|---|---|
committer | scottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 22:28:08 +0000 |
commit | 47ced5e4a552bee8e0d350804044cd16082242bb (patch) | |
tree | 5d34fb58e3305745d0d32f94db62f019526a91ae /content/browser/gamepad | |
parent | 77a3b1967055e8b3757d19e191ad1def92b2fe4a (diff) | |
download | chromium_src-47ced5e4a552bee8e0d350804044cd16082242bb.zip chromium_src-47ced5e4a552bee8e0d350804044cd16082242bb.tar.gz chromium_src-47ced5e4a552bee8e0d350804044cd16082242bb.tar.bz2 |
Add gamepad data fetcher for Linux
BUG=79050
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=116724
Review URL: http://codereview.chromium.org/8899017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@116752 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/gamepad')
-rw-r--r-- | content/browser/gamepad/gamepad_provider.cc | 38 | ||||
-rw-r--r-- | content/browser/gamepad/gamepad_provider.h | 8 | ||||
-rw-r--r-- | content/browser/gamepad/gamepad_standard_mappings_linux.cc | 156 | ||||
-rw-r--r-- | content/browser/gamepad/gamepad_standard_mappings_linux.h | 26 | ||||
-rw-r--r-- | content/browser/gamepad/platform_data_fetcher.h | 47 | ||||
-rw-r--r-- | content/browser/gamepad/platform_data_fetcher_linux.cc | 228 | ||||
-rw-r--r-- | content/browser/gamepad/platform_data_fetcher_linux.h | 66 | ||||
-rw-r--r-- | content/browser/gamepad/platform_data_fetcher_mac.h (renamed from content/browser/gamepad/data_fetcher_mac.h) | 10 | ||||
-rw-r--r-- | content/browser/gamepad/platform_data_fetcher_mac.mm (renamed from content/browser/gamepad/data_fetcher_mac.mm) | 38 | ||||
-rw-r--r-- | content/browser/gamepad/platform_data_fetcher_win.cc (renamed from content/browser/gamepad/data_fetcher_win.cc) | 10 | ||||
-rw-r--r-- | content/browser/gamepad/platform_data_fetcher_win.h (renamed from content/browser/gamepad/data_fetcher_win.h) | 6 |
11 files changed, 567 insertions, 66 deletions
diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc index 29492fa..4c00cc1 100644 --- a/content/browser/gamepad/gamepad_provider.cc +++ b/content/browser/gamepad/gamepad_provider.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -11,41 +11,14 @@ #include "base/message_loop.h" #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" -#include "content/public/browser/browser_thread.h" -#include "content/browser/gamepad/gamepad_provider.h" #include "content/browser/gamepad/data_fetcher.h" +#include "content/browser/gamepad/gamepad_provider.h" +#include "content/browser/gamepad/platform_data_fetcher.h" #include "content/common/gamepad_messages.h" - -#if defined(OS_WIN) -#include "content/browser/gamepad/data_fetcher_win.h" -#elif defined(OS_MACOSX) -#include "content/browser/gamepad/data_fetcher_mac.h" -#endif +#include "content/public/browser/browser_thread.h" namespace content { -// Define the default data fetcher that GamepadProvider will use if none is -// supplied. (GamepadPlatformDataFetcher). -#if defined(OS_WIN) - -typedef GamepadDataFetcherWindows GamepadPlatformDataFetcher; - -#elif defined(OS_MACOSX) - -typedef GamepadDataFetcherMac GamepadPlatformDataFetcher; - -#else - -class GamepadEmptyDataFetcher : public GamepadDataFetcher { - public: - void GetGamepadData(WebKit::WebGamepads* pads, bool) { - pads->length = 0; - } -}; -typedef GamepadEmptyDataFetcher GamepadPlatformDataFetcher; - -#endif - GamepadProvider::GamepadProvider(GamepadDataFetcher* fetcher) : is_paused_(false), devices_changed_(true), @@ -61,7 +34,8 @@ GamepadProvider::GamepadProvider(GamepadDataFetcher* fetcher) memset(hwbuf, 0, sizeof(GamepadHardwareBuffer)); polling_thread_.reset(new base::Thread("Gamepad polling thread")); - polling_thread_->Start(); + polling_thread_->StartWithOptions( + base::Thread::Options(MessageLoop::TYPE_IO, 0)); MessageLoop* polling_loop = polling_thread_->message_loop(); polling_loop->PostTask( diff --git a/content/browser/gamepad/gamepad_provider.h b/content/browser/gamepad/gamepad_provider.h index f0e25de..b1bdb74 100644 --- a/content/browser/gamepad/gamepad_provider.h +++ b/content/browser/gamepad/gamepad_provider.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_GAMEPAD_PROVIDER_H_ -#define CONTENT_BROWSER_GAMEPAD_PROVIDER_H_ +#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_ +#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" @@ -88,4 +88,4 @@ class CONTENT_EXPORT GamepadProvider : } // namespace content -#endif // CONTENT_BROWSER_GAMEPAD_PROVIDER_H_ +#endif // CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_ diff --git a/content/browser/gamepad/gamepad_standard_mappings_linux.cc b/content/browser/gamepad/gamepad_standard_mappings_linux.cc new file mode 100644 index 0000000..99d9ba7 --- /dev/null +++ b/content/browser/gamepad/gamepad_standard_mappings_linux.cc @@ -0,0 +1,156 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/gamepad/gamepad_standard_mappings_linux.h" + +#include "content/common/gamepad_hardware_buffer.h" + +namespace content { + +namespace { + +// This defines our canonical mapping order for gamepad-like devices. If these +// items cannot all be satisfied, it is a case-by-case judgement as to whether +// it is better to leave the device unmapped, or to partially map it. In +// general, err towards leaving it *unmapped* so that content can handle +// appropriately. + +enum CanonicalButtonIndex { + kButtonPrimary, + kButtonSecondary, + kButtonTertiary, + kButtonQuaternary, + kButtonLeftShoulder, + kButtonRightShoulder, + kButtonLeftTrigger, + kButtonRightTrigger, + kButtonBackSelect, + kButtonStart, + kButtonLeftThumbstick, + kButtonRightThumbstick, + kButtonDpadUp, + kButtonDpadDown, + kButtonDpadLeft, + kButtonDpadRight, + kButtonMeta, + kNumButtons +}; + +enum CanonicalAxisIndex { + kAxisLeftStickX, + kAxisLeftStickY, + kAxisRightStickX, + kAxisRightStickY, + kNumAxes +}; + +float AxisToButton(float input) { + return (input + 1.f) / 2.f; +} + +float AxisNegativeAsButton(float input) { + return (input < -0.5f) ? 1.f : 0.f; +} + +float AxisPositiveAsButton(float input) { + return (input > 0.5f) ? 1.f : 0.f; +} + +void MapperXInputStyleGamepad( + const WebKit::WebGamepad& input, + WebKit::WebGamepad* mapped) { + *mapped = input; + mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[2]); + mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[5]); + mapped->buttons[kButtonBackSelect] = input.buttons[6]; + mapped->buttons[kButtonStart] = input.buttons[7]; + mapped->buttons[kButtonLeftThumbstick] = input.buttons[9]; + mapped->buttons[kButtonRightThumbstick] = input.buttons[10]; + mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[7]); + mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[7]); + mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[6]); + mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[6]); + mapped->buttons[kButtonMeta] = input.buttons[8]; + mapped->axes[kAxisRightStickX] = input.axes[3]; + mapped->axes[kAxisRightStickY] = input.axes[4]; + mapped->buttonsLength = kNumButtons; + mapped->axesLength = kNumAxes; +} + +void MapperMP8866( + const WebKit::WebGamepad& input, + WebKit::WebGamepad* mapped) { + *mapped = input; + mapped->buttons[kButtonPrimary] = input.buttons[2]; + mapped->buttons[kButtonTertiary] = input.buttons[3]; + mapped->buttons[kButtonQuaternary] = input.buttons[0]; + mapped->buttons[kButtonLeftShoulder] = input.buttons[6]; + mapped->buttons[kButtonRightShoulder] = input.buttons[7]; + mapped->buttons[kButtonLeftTrigger] = input.buttons[4]; + mapped->buttons[kButtonRightTrigger] = input.buttons[5]; + mapped->buttons[kButtonBackSelect] = input.buttons[9]; + mapped->buttons[kButtonStart] = input.buttons[8]; + mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[5]); + mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[5]); + mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[4]); + mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[4]); + mapped->buttonsLength = kNumButtons - 1; // no Meta on this device + mapped->axesLength = kNumAxes; +} + +void MapperPlaystationSixAxis( + const WebKit::WebGamepad& input, + WebKit::WebGamepad* mapped) { + *mapped = input; + mapped->buttons[kButtonPrimary] = input.buttons[14]; + mapped->buttons[kButtonSecondary] = input.buttons[13]; + mapped->buttons[kButtonTertiary] = input.buttons[15]; + mapped->buttons[kButtonQuaternary] = input.buttons[12]; + mapped->buttons[kButtonLeftShoulder] = input.buttons[10]; + mapped->buttons[kButtonRightShoulder] = input.buttons[11]; + mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[12]); + mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[13]); + mapped->buttons[kButtonBackSelect] = input.buttons[0]; + mapped->buttons[kButtonStart] = input.buttons[3]; + mapped->buttons[kButtonLeftThumbstick] = input.buttons[1]; + mapped->buttons[kButtonRightThumbstick] = input.buttons[2]; + mapped->buttons[kButtonDpadUp] = AxisToButton(input.axes[8]); + mapped->buttons[kButtonDpadDown] = AxisToButton(input.axes[10]); + mapped->buttons[kButtonDpadLeft] = input.buttons[7]; + mapped->buttons[kButtonDpadRight] = AxisToButton(input.axes[9]); + mapped->buttons[kButtonMeta] = input.buttons[16]; + + mapped->buttonsLength = kNumButtons; + mapped->axesLength = kNumAxes; +} + +struct MappingData { + const char* const vendor_id; + const char* const product_id; + GamepadStandardMappingFunction function; +} AvailableMappings[] = { + // http://www.linux-usb.org/usb.ids + { "045e", "028e", MapperXInputStyleGamepad }, // Xbox 360 Controller + { "045e", "028f", MapperXInputStyleGamepad }, // Xbox 360 Wireless Controller + { "046d", "c21d", MapperXInputStyleGamepad }, // Logitech F310 + { "046d", "c21e", MapperXInputStyleGamepad }, // Logitech F510 + { "046d", "c21f", MapperXInputStyleGamepad }, // Logitech F710 + { "054c", "0268", MapperPlaystationSixAxis }, // Playstation SIXAXIS + { "0925", "8866", MapperMP8866 }, // WiseGroup MP-8866 +}; + +} // namespace + +GamepadStandardMappingFunction GetGamepadStandardMappingFunction( + const base::StringPiece& vendor_id, + const base::StringPiece& product_id) { + for (size_t i = 0; i < arraysize(AvailableMappings); ++i) { + MappingData& item = AvailableMappings[i]; + if (vendor_id == item.vendor_id && product_id == item.product_id) + return item.function; + } + return NULL; +} + +} // namespace content diff --git a/content/browser/gamepad/gamepad_standard_mappings_linux.h b/content/browser/gamepad/gamepad_standard_mappings_linux.h new file mode 100644 index 0000000..6d06fc6 --- /dev/null +++ b/content/browser/gamepad/gamepad_standard_mappings_linux.h @@ -0,0 +1,26 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_STANDARD_MAPPINGS_LINUX_H_ +#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_STANDARD_MAPPINGS_LINUX_H_ + +#include "base/string_piece.h" + +namespace WebKit { +class WebGamepad; +} + +namespace content { + +typedef void (*GamepadStandardMappingFunction)( + const WebKit::WebGamepad& original, + WebKit::WebGamepad* mapped); + +GamepadStandardMappingFunction GetGamepadStandardMappingFunction( + const base::StringPiece& vendor_id, + const base::StringPiece& product_id); + +} // namespace content + +#endif // CONTENT_BROWSER_GAMEPAD_GAMEPAD_STANDARD_MAPPINGS_LINUX_H_ diff --git a/content/browser/gamepad/platform_data_fetcher.h b/content/browser/gamepad/platform_data_fetcher.h new file mode 100644 index 0000000..b9f64af --- /dev/null +++ b/content/browser/gamepad/platform_data_fetcher.h @@ -0,0 +1,47 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Define the default data fetcher that GamepadProvider will use if none is +// supplied. (GamepadPlatformDataFetcher). + +#ifndef CONTENT_BROWSER_GAMEPAD_PLATFORM_DATA_FETCHER_H_ +#define CONTENT_BROWSER_GAMEPAD_PLATFORM_DATA_FETCHER_H_ + +#if defined(OS_WIN) +#include "content/browser/gamepad/platform_data_fetcher_win.h" +#elif defined(OS_MACOSX) +#include "content/browser/gamepad/platform_data_fetcher_mac.h" +#elif defined(OS_LINUX) +#include "content/browser/gamepad/platform_data_fetcher_linux.h" +#endif + +namespace content { + +#if defined(OS_WIN) + +typedef GamepadPlatformDataFetcherWin GamepadPlatformDataFetcher; + +#elif defined(OS_MACOSX) + +typedef GamepadPlatformDataFetcherMac GamepadPlatformDataFetcher; + +#elif defined(OS_LINUX) + +typedef GamepadPlatformDataFetcherLinux GamepadPlatformDataFetcher; + +#else + +class GamepadDataFetcherEmpty : public GamepadDataFetcher { + public: + void GetGamepadData(WebKit::WebGamepads* pads, bool) { + pads->length = 0; + } +}; +typedef GamepadDataFetcherEmpty GamepadPlatformDataFetcher; + +#endif + +} // namespace content + +#endif // CONTENT_BROWSER_GAMEPAD_PLATFORM_DATA_FETCHER_H_ diff --git a/content/browser/gamepad/platform_data_fetcher_linux.cc b/content/browser/gamepad/platform_data_fetcher_linux.cc new file mode 100644 index 0000000..9c2a6bf --- /dev/null +++ b/content/browser/gamepad/platform_data_fetcher_linux.cc @@ -0,0 +1,228 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/gamepad/platform_data_fetcher_linux.h" + +#include <dlfcn.h> +#include <fcntl.h> +#include <libudev.h> +#include <linux/joystick.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "base/debug/trace_event.h" +#include "base/eintr_wrapper.h" +#include "base/message_loop.h" +#include "base/string_number_conversions.h" +#include "base/stringprintf.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "content/common/gamepad_hardware_buffer.h" + +namespace content { + +using WebKit::WebGamepad; +using WebKit::WebGamepads; + +GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() { + for (size_t i = 0; i < arraysize(device_fds_); ++i) + device_fds_[i] = -1; + + udev_ = udev_new(); + + monitor_ = udev_monitor_new_from_netlink(udev_, "udev"); + udev_monitor_filter_add_match_subsystem_devtype(monitor_, "input", NULL); + udev_monitor_enable_receiving(monitor_); + monitor_fd_ = udev_monitor_get_fd(monitor_); + MessageLoopForIO::current()->WatchFileDescriptor(monitor_fd_, true, + MessageLoopForIO::WATCH_READ, &monitor_watcher_, this); + + EnumerateDevices(); +} + +GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() { + monitor_watcher_.StopWatchingFileDescriptor(); + udev_unref(udev_); + for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { + if (device_fds_[i] >= 0) + close(device_fds_[i]); + } +} + +void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) { + TRACE_EVENT0("GAMEPAD", "GetGamepadData"); + + data_.length = WebGamepads::itemsLengthCap; + + // Update our internal state. + for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { + if (device_fds_[i] >= 0) { + ReadDeviceData(i); + } + } + + // Copy to the current state to the output buffer, using the mapping + // function, if there is one available. + pads->length = data_.length; + for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { + if (mappers_[i]) + mappers_[i](data_.items[i], &pads->items[i]); + else + pads->items[i] = data_.items[i]; + } +} + +void GamepadPlatformDataFetcherLinux::OnFileCanReadWithoutBlocking(int fd) { + // Events occur when devices attached to the system are added, removed, or + // change state. udev_monitor_receive_device() will return a device object + // representing the device which changed and what type of change occured. + DCHECK(monitor_fd_ == fd); + udev_device* dev = udev_monitor_receive_device(monitor_); + RefreshDevice(dev); + udev_device_unref(dev); +} + +void GamepadPlatformDataFetcherLinux::OnFileCanWriteWithoutBlocking(int fd) { +} + +bool GamepadPlatformDataFetcherLinux::IsGamepad( + udev_device* dev, + int& index, + std::string& path) { + if (!udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK")) + return false; + + const char* node_path = udev_device_get_devnode(dev); + if (!node_path) + return false; + + static const char kJoystickRoot[] = "/dev/input/js"; + bool is_gamepad = + strncmp(kJoystickRoot, node_path, sizeof(kJoystickRoot) - 1) == 0; + if (is_gamepad) { + const int base_len = sizeof(kJoystickRoot) - 1; + if (!base::StringToInt(base::StringPiece( + &node_path[base_len], + strlen(node_path) - base_len), + &index)) + return false; + if (index < 0 || index >= static_cast<int>(WebGamepads::itemsLengthCap)) + return false; + path = std::string(node_path); + } + return is_gamepad; +} + +// Used during enumeration, and monitor notifications. +void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { + int index; + std::string node_path; + if (IsGamepad(dev, index, node_path)) { + int& device_fd = device_fds_[index]; + WebGamepad& pad = data_.items[index]; + GamepadStandardMappingFunction& mapper = mappers_[index]; + + if (device_fd >= 0) + close(device_fd); + + // The device pointed to by dev contains information about the input + // device. In order to get the information about the USB device, get the + // parent device with the subsystem/devtype pair of "usb"/"usb_device". + // This function walks up the tree several levels. + dev = udev_device_get_parent_with_subsystem_devtype( + dev, + "usb", + "usb_device"); + if (!dev) { + // Unable to get device information, don't use this device. + device_fd = -1; + pad.connected = false; + return; + } + + device_fd = HANDLE_EINTR(open(node_path.c_str(), O_RDONLY | O_NONBLOCK)); + if (device_fd < 0) { + // Unable to open device, don't use. + pad.connected = false; + return; + } + + const char* vendor_id = udev_device_get_sysattr_value(dev, "idVendor"); + const char* product_id = udev_device_get_sysattr_value(dev, "idProduct"); + mapper = GetGamepadStandardMappingFunction(vendor_id, product_id); + + const char* manufacturer = + udev_device_get_sysattr_value(dev, "manufacturer"); + const char* product = udev_device_get_sysattr_value(dev, "product"); + + // Driver returns utf-8 strings here, so combine in utf-8 and then convert + // to WebUChar to build the id string. + std::string id; + if (mapper) { + id = base::StringPrintf("%s %s (STANDARD GAMEPAD)", + manufacturer, + product); + } else { + id = base::StringPrintf("%s %s (Vendor: %s Product: %s)", + manufacturer, + product, + vendor_id, + product_id); + } + TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id); + string16 tmp16 = UTF8ToUTF16(id); + memset(pad.id, 0, sizeof(pad.id)); + tmp16.copy(pad.id, arraysize(pad.id) - 1); + + pad.connected = true; + } +} + +void GamepadPlatformDataFetcherLinux::EnumerateDevices() { + udev_enumerate* enumerate = udev_enumerate_new(udev_); + udev_enumerate_add_match_subsystem(enumerate, "input"); + udev_enumerate_scan_devices(enumerate); + + udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); + for (udev_list_entry* dev_list_entry = devices; + dev_list_entry != NULL; + dev_list_entry = udev_list_entry_get_next(dev_list_entry)) { + // Get the filename of the /sys entry for the device and create a + // udev_device object (dev) representing it + const char* path = udev_list_entry_get_name(dev_list_entry); + udev_device* dev = udev_device_new_from_syspath(udev_, path); + RefreshDevice(dev); + udev_device_unref(dev); + } + // Free the enumerator object + udev_enumerate_unref(enumerate); +} + +void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) { + int& fd = device_fds_[index]; + WebGamepad& pad = data_.items[index]; + DCHECK(fd >= 0); + + js_event event; + while (HANDLE_EINTR(read(fd, &event, sizeof(struct js_event)) > 0)) { + size_t item = event.number; + if (event.type & JS_EVENT_AXIS) { + if (item >= WebGamepad::axesLengthCap) + continue; + pad.axes[item] = event.value / 32767.f; + if (item >= pad.axesLength) + pad.axesLength = item + 1; + } else if (event.type & JS_EVENT_BUTTON) { + if (item >= WebGamepad::buttonsLengthCap) + continue; + pad.buttons[item] = event.value ? 1.0 : 0.0; + if (item >= pad.buttonsLength) + pad.buttonsLength = item + 1; + } + pad.timestamp = event.time; + } +} + + +} // namespace content diff --git a/content/browser/gamepad/platform_data_fetcher_linux.h b/content/browser/gamepad/platform_data_fetcher_linux.h new file mode 100644 index 0000000..3f395cf --- /dev/null +++ b/content/browser/gamepad/platform_data_fetcher_linux.h @@ -0,0 +1,66 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_GAMEPAD_DATA_FETCHER_LINUX_H_ +#define CONTENT_BROWSER_GAMEPAD_DATA_FETCHER_LINUX_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/message_pump_libevent.h" +#include "build/build_config.h" +#include "content/browser/gamepad/data_fetcher.h" +#include "content/browser/gamepad/gamepad_standard_mappings_linux.h" +#include "content/common/gamepad_hardware_buffer.h" + +extern "C" { +struct udev; +struct udev_device; +struct udev_monitor; +} + +namespace content { + +class GamepadPlatformDataFetcherLinux : + public GamepadDataFetcher, + public base::MessagePumpLibevent::Watcher { + public: + GamepadPlatformDataFetcherLinux(); + virtual ~GamepadPlatformDataFetcherLinux(); + + // GamepadDataFetcher: + virtual void GetGamepadData(WebKit::WebGamepads* pads, + bool devices_changed_hint) OVERRIDE; + + // base::MessagePump:Libevent::Watcher: + virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; + virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; + + private: + bool IsGamepad(udev_device* dev, int& index, std::string& path); + void RefreshDevice(udev_device* dev); + void EnumerateDevices(); + void ReadDeviceData(size_t index); + + // libudev-related items, the main context, and the monitoring context to be + // notified about changes to device states. + udev* udev_; + udev_monitor* monitor_; + int monitor_fd_; + base::MessagePumpLibevent::FileDescriptorWatcher monitor_watcher_; + + // File descriptors for the /dev/input/js* devices. -1 if not in use. + int device_fds_[WebKit::WebGamepads::itemsLengthCap]; + + // Functions to map from device data to standard layout, if available. May + // be null if no mapping is available. + GamepadStandardMappingFunction mappers_[WebKit::WebGamepads::itemsLengthCap]; + + // Data that's returned to the consumer. + WebKit::WebGamepads data_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_GAMEPAD_DATA_FETCHER_LINUX_H_ diff --git a/content/browser/gamepad/data_fetcher_mac.h b/content/browser/gamepad/platform_data_fetcher_mac.h index 34f7d4b..360a183 100644 --- a/content/browser/gamepad/data_fetcher_mac.h +++ b/content/browser/gamepad/platform_data_fetcher_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -23,10 +23,10 @@ class NSArray; namespace content { -class GamepadDataFetcherMac : public GamepadDataFetcher { +class GamepadPlatformDataFetcherMac : public GamepadDataFetcher { public: - GamepadDataFetcherMac(); - virtual ~GamepadDataFetcherMac(); + GamepadPlatformDataFetcherMac(); + virtual ~GamepadPlatformDataFetcherMac(); virtual void GetGamepadData(WebKit::WebGamepads* pads, bool devices_changed_hint) OVERRIDE; virtual void PauseHint(bool paused) OVERRIDE; @@ -34,7 +34,7 @@ class GamepadDataFetcherMac : public GamepadDataFetcher { bool enabled_; base::mac::ScopedCFTypeRef<IOHIDManagerRef> hid_manager_ref_; - static GamepadDataFetcherMac* InstanceFromContext(void* context); + static GamepadPlatformDataFetcherMac* InstanceFromContext(void* context); static void DeviceAddCallback(void* context, IOReturn result, void* sender, diff --git a/content/browser/gamepad/data_fetcher_mac.mm b/content/browser/gamepad/platform_data_fetcher_mac.mm index b06f01a..5e4ba8f 100644 --- a/content/browser/gamepad/data_fetcher_mac.mm +++ b/content/browser/gamepad/platform_data_fetcher_mac.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/gamepad/data_fetcher_mac.h" +#include "content/browser/gamepad/platform_data_fetcher_mac.h" #include "base/mac/foundation_util.h" #include "base/memory/scoped_nsobject.h" @@ -41,7 +41,8 @@ const uint32_t kAxisMaximumUsageNumber = 0x35; } // namespace -GamepadDataFetcherMac::GamepadDataFetcherMac() : enabled_(true) { +GamepadPlatformDataFetcherMac::GamepadPlatformDataFetcherMac() + : enabled_(true) { hid_manager_ref_.reset(IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)); if (CFGetTypeID(hid_manager_ref_) != IOHIDManagerGetTypeID()) { @@ -61,7 +62,7 @@ GamepadDataFetcherMac::GamepadDataFetcherMac() : enabled_(true) { RegisterForNotifications(); } -void GamepadDataFetcherMac::RegisterForNotifications() { +void GamepadPlatformDataFetcherMac::RegisterForNotifications() { // Register for plug/unplug notifications. IOHIDManagerRegisterDeviceMatchingCallback( hid_manager_ref_, @@ -87,7 +88,7 @@ void GamepadDataFetcherMac::RegisterForNotifications() { kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess; } -void GamepadDataFetcherMac::UnregisterFromNotifications() { +void GamepadPlatformDataFetcherMac::UnregisterFromNotifications() { IOHIDManagerUnscheduleFromRunLoop( hid_manager_ref_, CFRunLoopGetCurrent(), @@ -95,44 +96,45 @@ void GamepadDataFetcherMac::UnregisterFromNotifications() { IOHIDManagerClose(hid_manager_ref_, kIOHIDOptionsTypeNone); } -void GamepadDataFetcherMac::PauseHint(bool pause) { +void GamepadPlatformDataFetcherMac::PauseHint(bool pause) { if (pause) UnregisterFromNotifications(); else RegisterForNotifications(); } -GamepadDataFetcherMac::~GamepadDataFetcherMac() { +GamepadPlatformDataFetcherMac::~GamepadPlatformDataFetcherMac() { UnregisterFromNotifications(); } -GamepadDataFetcherMac* GamepadDataFetcherMac::InstanceFromContext( +GamepadPlatformDataFetcherMac* +GamepadPlatformDataFetcherMac::InstanceFromContext( void* context) { - return reinterpret_cast<GamepadDataFetcherMac*>(context); + return reinterpret_cast<GamepadPlatformDataFetcherMac*>(context); } -void GamepadDataFetcherMac::DeviceAddCallback(void* context, +void GamepadPlatformDataFetcherMac::DeviceAddCallback(void* context, IOReturn result, void* sender, IOHIDDeviceRef ref) { InstanceFromContext(context)->DeviceAdd(ref); } -void GamepadDataFetcherMac::DeviceRemoveCallback(void* context, +void GamepadPlatformDataFetcherMac::DeviceRemoveCallback(void* context, IOReturn result, void* sender, IOHIDDeviceRef ref) { InstanceFromContext(context)->DeviceRemove(ref); } -void GamepadDataFetcherMac::ValueChangedCallback(void* context, +void GamepadPlatformDataFetcherMac::ValueChangedCallback(void* context, IOReturn result, void* sender, IOHIDValueRef ref) { InstanceFromContext(context)->ValueChanged(ref); } -void GamepadDataFetcherMac::AddButtonsAndAxes(NSArray* elements, +void GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements, size_t slot) { WebKit::WebGamepad& pad = data_.items[slot]; AssociatedData& associated = associated_[slot]; @@ -168,7 +170,7 @@ void GamepadDataFetcherMac::AddButtonsAndAxes(NSArray* elements, } } -void GamepadDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { +void GamepadPlatformDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { using WebKit::WebGamepad; using WebKit::WebGamepads; using base::mac::CFToNSCast; @@ -221,7 +223,7 @@ void GamepadDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { data_.length = slot + 1; } -void GamepadDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { +void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { using WebKit::WebGamepads; size_t slot; if (!enabled_) @@ -238,7 +240,7 @@ void GamepadDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { data_.items[slot].connected = false; } -void GamepadDataFetcherMac::ValueChanged(IOHIDValueRef value) { +void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) { if (!enabled_) return; @@ -276,7 +278,9 @@ void GamepadDataFetcherMac::ValueChanged(IOHIDValueRef value) { } } -void GamepadDataFetcherMac::GetGamepadData(WebKit::WebGamepads* pads, bool) { +void GamepadPlatformDataFetcherMac::GetGamepadData( + WebKit::WebGamepads* pads, + bool) { if (!enabled_) { pads->length = 0; return; diff --git a/content/browser/gamepad/data_fetcher_win.cc b/content/browser/gamepad/platform_data_fetcher_win.cc index 4cb874d..7f6f417 100644 --- a/content/browser/gamepad/data_fetcher_win.cc +++ b/content/browser/gamepad/platform_data_fetcher_win.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/gamepad/data_fetcher_win.h" +#include "content/browser/gamepad/platform_data_fetcher_win.h" #include "base/debug/trace_event.h" #include "content/common/gamepad_messages.h" @@ -78,11 +78,11 @@ bool EnableXInput() { } -GamepadDataFetcherWindows::GamepadDataFetcherWindows() +GamepadPlatformDataFetcherWin::GamepadPlatformDataFetcherWin() : xinput_available_(EnableXInput()) { } -void GamepadDataFetcherWindows::GetGamepadData(WebGamepads* pads, +void GamepadPlatformDataFetcherWin::GetGamepadData(WebGamepads* pads, bool devices_changed_hint) { TRACE_EVENT0("GAMEPAD", "GetGamepadData"); @@ -113,7 +113,7 @@ void GamepadDataFetcherWindows::GetGamepadData(WebGamepads* pads, pad.connected = true; base::swprintf(pad.id, WebGamepad::idLengthCap, - L"Xbox 360 Controller (XInput %ls)", + L"Xbox 360 Controller (XInput STANDARD %ls)", GamepadSubTypeName(caps.SubType)); } } diff --git a/content/browser/gamepad/data_fetcher_win.h b/content/browser/gamepad/platform_data_fetcher_win.h index 9193f67..1c91059 100644 --- a/content/browser/gamepad/data_fetcher_win.h +++ b/content/browser/gamepad/platform_data_fetcher_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,9 +18,9 @@ namespace content { -class GamepadDataFetcherWindows : public GamepadDataFetcher { +class GamepadPlatformDataFetcherWin : public GamepadDataFetcher { public: - GamepadDataFetcherWindows(); + GamepadPlatformDataFetcherWin(); virtual void GetGamepadData(WebKit::WebGamepads* pads, bool devices_changed_hint) OVERRIDE; private: |