Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(391)

Side by Side Diff: content/browser/gamepad/data_fetcher_win.cc

Issue 8899017: Add gamepad data fetcher for Linux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase again, bots all updated Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/gamepad/data_fetcher_win.h ('k') | content/browser/gamepad/gamepad_provider.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/gamepad/data_fetcher_win.h"
6
7 #include "base/debug/trace_event.h"
8 #include "content/common/gamepad_messages.h"
9 #include "content/common/gamepad_hardware_buffer.h"
10
11 #include <delayimp.h>
12
13 #pragma comment(lib, "delayimp.lib")
14 #pragma comment(lib, "xinput.lib")
15
16 namespace content {
17
18 using namespace WebKit;
19
20 namespace {
21
22 // See http://goo.gl/5VSJR. These are not available in all versions of the
23 // header, but they can be returned from the driver, so we define our own
24 // versions here.
25 static const BYTE kDeviceSubTypeGamepad = 1;
26 static const BYTE kDeviceSubTypeWheel = 2;
27 static const BYTE kDeviceSubTypeArcadeStick = 3;
28 static const BYTE kDeviceSubTypeFlightStick = 4;
29 static const BYTE kDeviceSubTypeDancePad = 5;
30 static const BYTE kDeviceSubTypeGuitar = 6;
31 static const BYTE kDeviceSubTypeGuitarAlternate = 7;
32 static const BYTE kDeviceSubTypeDrumKit = 8;
33 static const BYTE kDeviceSubTypeGuitarBass = 11;
34 static const BYTE kDeviceSubTypeArcadePad = 19;
35
36 const WebUChar* const GamepadSubTypeName(BYTE sub_type) {
37 switch (sub_type) {
38 case kDeviceSubTypeGamepad: return L"GAMEPAD";
39 case kDeviceSubTypeWheel: return L"WHEEL";
40 case kDeviceSubTypeArcadeStick: return L"ARCADE_STICK";
41 case kDeviceSubTypeFlightStick: return L"FLIGHT_STICK";
42 case kDeviceSubTypeDancePad: return L"DANCE_PAD";
43 case kDeviceSubTypeGuitar: return L"GUITAR";
44 case kDeviceSubTypeGuitarAlternate: return L"GUITAR_ALTERNATE";
45 case kDeviceSubTypeDrumKit: return L"DRUM_KIT";
46 case kDeviceSubTypeGuitarBass: return L"GUITAR_BASS";
47 case kDeviceSubTypeArcadePad: return L"ARCADE_PAD";
48 default: return L"<UNKNOWN>";
49 }
50 }
51
52 // Trap only the exceptions that DELAYLOAD can throw, otherwise rethrow.
53 // See http://msdn.microsoft.com/en-us/library/1c9e046h(v=VS.90).aspx.
54 LONG WINAPI DelayLoadDllExceptionFilter(PEXCEPTION_POINTERS pExcPointers) {
55 LONG disposition = EXCEPTION_EXECUTE_HANDLER;
56 switch (pExcPointers->ExceptionRecord->ExceptionCode) {
57 case VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND):
58 case VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND):
59 break;
60 default:
61 // Exception is not related to delay loading.
62 disposition = EXCEPTION_CONTINUE_SEARCH;
63 break;
64 }
65 return disposition;
66 }
67
68 bool EnableXInput() {
69 // We have specified DELAYLOAD for xinput1_3.dll. If the DLL is not
70 // installed (XP w/o DirectX redist installed), we disable functionality.
71 __try {
72 ;//XInputEnable(true);
73 } __except(DelayLoadDllExceptionFilter(GetExceptionInformation())) {
74 return false;
75 }
76 return true;
77 }
78
79 }
80
81 GamepadDataFetcherWindows::GamepadDataFetcherWindows()
82 : xinput_available_(EnableXInput()) {
83 }
84
85 void GamepadDataFetcherWindows::GetGamepadData(WebGamepads* pads,
86 bool devices_changed_hint) {
87 TRACE_EVENT0("GAMEPAD", "GetGamepadData");
88
89 // If there's no XInput DLL on the system, early out so that we don't
90 // call any other XInput functions.
91 if (!xinput_available_) {
92 pads->length = 0;
93 return;
94 }
95
96 pads->length = WebGamepads::itemsLengthCap;
97
98 // If we got notification that system devices have been updated, then
99 // run GetCapabilities to update the connected status and the device
100 // identifier. It can be slow to do to both GetCapabilities and
101 // GetState on unconnected devices, so we want to avoid a 2-5ms pause
102 // here by only doing this when the devices are updated (despite
103 // documentation claiming it's OK to call it any time).
104 if (devices_changed_hint) {
105 for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) {
106 WebGamepad& pad = pads->items[i];
107 TRACE_EVENT1("GAMEPAD", "GetCapabilities", "id", i);
108 XINPUT_CAPABILITIES caps;
109 DWORD res = XInputGetCapabilities(i, XINPUT_FLAG_GAMEPAD, &caps);
110 if (res == ERROR_DEVICE_NOT_CONNECTED) {
111 pad.connected = false;
112 } else {
113 pad.connected = true;
114 base::swprintf(pad.id,
115 WebGamepad::idLengthCap,
116 L"Xbox 360 Controller (XInput %ls)",
117 GamepadSubTypeName(caps.SubType));
118 }
119 }
120 }
121
122 // We've updated the connection state if necessary, now update the actual
123 // data for the devices that are connected.
124 for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) {
125 WebGamepad& pad = pads->items[i];
126
127 // We rely on device_changed and GetCapabilities to tell us that
128 // something's been connected, but we will mark as disconnected if
129 // GetState returns that we've lost the pad.
130 if (!pad.connected)
131 continue;
132
133 XINPUT_STATE state;
134 memset(&state, 0, sizeof(XINPUT_STATE));
135 TRACE_EVENT_BEGIN1("GAMEPAD", "XInputGetState", "id", i);
136 DWORD dwResult = XInputGetState(i, &state);
137 TRACE_EVENT_END1("GAMEPAD", "XInputGetState", "id", i);
138
139 if (dwResult == ERROR_SUCCESS) {
140 pad.timestamp = state.dwPacketNumber;
141 pad.buttonsLength = 0;
142 #define ADD(b) pad.buttons[pad.buttonsLength++] = \
143 ((state.Gamepad.wButtons & (b)) ? 1.0 : 0.0);
144 ADD(XINPUT_GAMEPAD_A);
145 ADD(XINPUT_GAMEPAD_B);
146 ADD(XINPUT_GAMEPAD_X);
147 ADD(XINPUT_GAMEPAD_Y);
148 ADD(XINPUT_GAMEPAD_LEFT_SHOULDER);
149 ADD(XINPUT_GAMEPAD_RIGHT_SHOULDER);
150 pad.buttons[pad.buttonsLength++] = state.Gamepad.bLeftTrigger / 255.0;
151 pad.buttons[pad.buttonsLength++] = state.Gamepad.bRightTrigger / 255.0;
152 ADD(XINPUT_GAMEPAD_BACK);
153 ADD(XINPUT_GAMEPAD_START);
154 ADD(XINPUT_GAMEPAD_LEFT_THUMB);
155 ADD(XINPUT_GAMEPAD_RIGHT_THUMB);
156 ADD(XINPUT_GAMEPAD_DPAD_UP);
157 ADD(XINPUT_GAMEPAD_DPAD_DOWN);
158 ADD(XINPUT_GAMEPAD_DPAD_LEFT);
159 ADD(XINPUT_GAMEPAD_DPAD_RIGHT);
160 #undef ADD
161 pad.axesLength = 0;
162 // XInput are +up/+right, -down/-left, we want -up/-left.
163 pad.axes[pad.axesLength++] = state.Gamepad.sThumbLX / 32767.0;
164 pad.axes[pad.axesLength++] = -state.Gamepad.sThumbLY / 32767.0;
165 pad.axes[pad.axesLength++] = state.Gamepad.sThumbRX / 32767.0;
166 pad.axes[pad.axesLength++] = -state.Gamepad.sThumbRY / 32767.0;
167 } else {
168 pad.connected = false;
169 }
170 }
171 }
172
173 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gamepad/data_fetcher_win.h ('k') | content/browser/gamepad/gamepad_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698