xref: /reactos/dll/directx/wine/dinput/device.c (revision 41c8c312)
1c2c66affSColin Finck /*		DirectInput Device
2c2c66affSColin Finck  *
3c2c66affSColin Finck  * Copyright 1998 Marcus Meissner
4c2c66affSColin Finck  * Copyright 1998,1999 Lionel Ulmer
5c2c66affSColin Finck  *
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22c2c66affSColin Finck /* This file contains all the Device specific functions that can be used as stubs
23c2c66affSColin Finck    by real device implementations.
24c2c66affSColin Finck 
25c2c66affSColin Finck    It also contains all the helper functions.
26c2c66affSColin Finck */
277016dd6dSAmine Khaldi #include "config.h"
28c2c66affSColin Finck 
297016dd6dSAmine Khaldi #include <stdarg.h>
307016dd6dSAmine Khaldi #include <string.h>
317016dd6dSAmine Khaldi #include "wine/debug.h"
327016dd6dSAmine Khaldi #include "wine/unicode.h"
33*41c8c312SAmine Khaldi #include "wine/heap.h"
347016dd6dSAmine Khaldi #include "windef.h"
357016dd6dSAmine Khaldi #include "winbase.h"
367016dd6dSAmine Khaldi #include "winreg.h"
377016dd6dSAmine Khaldi #include "winuser.h"
387016dd6dSAmine Khaldi #include "winerror.h"
397016dd6dSAmine Khaldi #include "dinput.h"
407016dd6dSAmine Khaldi #include "device_private.h"
41c2c66affSColin Finck #include "dinput_private.h"
42c2c66affSColin Finck 
43ad21be5eSAmine Khaldi #define WM_WINE_NOTIFY_ACTIVITY WM_USER
44ad21be5eSAmine Khaldi 
457016dd6dSAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(dinput);
467016dd6dSAmine Khaldi 
impl_from_IDirectInputDevice8A(IDirectInputDevice8A * iface)47c2c66affSColin Finck static inline IDirectInputDeviceImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
48c2c66affSColin Finck {
49c2c66affSColin Finck     return CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8A_iface);
50c2c66affSColin Finck }
impl_from_IDirectInputDevice8W(IDirectInputDevice8W * iface)51c2c66affSColin Finck static inline IDirectInputDeviceImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
52c2c66affSColin Finck {
53c2c66affSColin Finck     return CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface);
54c2c66affSColin Finck }
55c2c66affSColin Finck 
IDirectInputDevice8A_from_impl(IDirectInputDeviceImpl * This)56c2c66affSColin Finck static inline IDirectInputDevice8A *IDirectInputDevice8A_from_impl(IDirectInputDeviceImpl *This)
57c2c66affSColin Finck {
58c2c66affSColin Finck     return &This->IDirectInputDevice8A_iface;
59c2c66affSColin Finck }
IDirectInputDevice8W_from_impl(IDirectInputDeviceImpl * This)60c2c66affSColin Finck static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(IDirectInputDeviceImpl *This)
61c2c66affSColin Finck {
62c2c66affSColin Finck     return &This->IDirectInputDevice8W_iface;
63c2c66affSColin Finck }
64c2c66affSColin Finck 
65c2c66affSColin Finck /******************************************************************************
66c2c66affSColin Finck  *	Various debugging tools
67c2c66affSColin Finck  */
_dump_cooperativelevel_DI(DWORD dwFlags)68c2c66affSColin Finck static void _dump_cooperativelevel_DI(DWORD dwFlags) {
69c2c66affSColin Finck     if (TRACE_ON(dinput)) {
70c2c66affSColin Finck 	unsigned int   i;
71c2c66affSColin Finck 	static const struct {
72c2c66affSColin Finck 	    DWORD       mask;
73c2c66affSColin Finck 	    const char  *name;
74c2c66affSColin Finck 	} flags[] = {
75c2c66affSColin Finck #define FE(x) { x, #x}
76c2c66affSColin Finck 	    FE(DISCL_BACKGROUND),
77c2c66affSColin Finck 	    FE(DISCL_EXCLUSIVE),
78c2c66affSColin Finck 	    FE(DISCL_FOREGROUND),
79c2c66affSColin Finck 	    FE(DISCL_NONEXCLUSIVE),
80c2c66affSColin Finck 	    FE(DISCL_NOWINKEY)
81c2c66affSColin Finck #undef FE
82c2c66affSColin Finck 	};
83c2c66affSColin Finck 	TRACE(" cooperative level : ");
8498e62237SAmine Khaldi 	for (i = 0; i < ARRAY_SIZE(flags); i++)
85c2c66affSColin Finck 	    if (flags[i].mask & dwFlags)
86c2c66affSColin Finck 		TRACE("%s ",flags[i].name);
87c2c66affSColin Finck 	TRACE("\n");
88c2c66affSColin Finck     }
89c2c66affSColin Finck }
90c2c66affSColin Finck 
_dump_ObjectDataFormat_flags(DWORD dwFlags)91c2c66affSColin Finck static void _dump_ObjectDataFormat_flags(DWORD dwFlags) {
92c2c66affSColin Finck     unsigned int   i;
93c2c66affSColin Finck     static const struct {
94c2c66affSColin Finck         DWORD       mask;
95c2c66affSColin Finck         const char  *name;
96c2c66affSColin Finck     } flags[] = {
97c2c66affSColin Finck #define FE(x) { x, #x}
98c2c66affSColin Finck         FE(DIDOI_FFACTUATOR),
99c2c66affSColin Finck         FE(DIDOI_FFEFFECTTRIGGER),
100c2c66affSColin Finck         FE(DIDOI_POLLED),
101c2c66affSColin Finck         FE(DIDOI_GUIDISUSAGE)
102c2c66affSColin Finck #undef FE
103c2c66affSColin Finck     };
104c2c66affSColin Finck 
105c2c66affSColin Finck     if (!dwFlags) return;
106c2c66affSColin Finck 
107c2c66affSColin Finck     TRACE("Flags:");
108c2c66affSColin Finck 
109c2c66affSColin Finck     /* First the flags */
11098e62237SAmine Khaldi     for (i = 0; i < ARRAY_SIZE(flags); i++) {
111c2c66affSColin Finck         if (flags[i].mask & dwFlags)
112c2c66affSColin Finck         TRACE(" %s",flags[i].name);
113c2c66affSColin Finck     }
114c2c66affSColin Finck 
115c2c66affSColin Finck     /* Now specific values */
116c2c66affSColin Finck #define FE(x) case x: TRACE(" "#x); break
117c2c66affSColin Finck     switch (dwFlags & DIDOI_ASPECTMASK) {
118c2c66affSColin Finck         FE(DIDOI_ASPECTACCEL);
119c2c66affSColin Finck         FE(DIDOI_ASPECTFORCE);
120c2c66affSColin Finck         FE(DIDOI_ASPECTPOSITION);
121c2c66affSColin Finck         FE(DIDOI_ASPECTVELOCITY);
122c2c66affSColin Finck     }
123c2c66affSColin Finck #undef FE
124c2c66affSColin Finck 
125c2c66affSColin Finck }
126c2c66affSColin Finck 
_dump_EnumObjects_flags(DWORD dwFlags)127c2c66affSColin Finck static void _dump_EnumObjects_flags(DWORD dwFlags) {
128c2c66affSColin Finck     if (TRACE_ON(dinput)) {
129c2c66affSColin Finck 	unsigned int   i;
130c2c66affSColin Finck 	DWORD type, instance;
131c2c66affSColin Finck 	static const struct {
132c2c66affSColin Finck 	    DWORD       mask;
133c2c66affSColin Finck 	    const char  *name;
134c2c66affSColin Finck 	} flags[] = {
135c2c66affSColin Finck #define FE(x) { x, #x}
136c2c66affSColin Finck 	    FE(DIDFT_RELAXIS),
137c2c66affSColin Finck 	    FE(DIDFT_ABSAXIS),
138c2c66affSColin Finck 	    FE(DIDFT_PSHBUTTON),
139c2c66affSColin Finck 	    FE(DIDFT_TGLBUTTON),
140c2c66affSColin Finck 	    FE(DIDFT_POV),
141c2c66affSColin Finck 	    FE(DIDFT_COLLECTION),
142c2c66affSColin Finck 	    FE(DIDFT_NODATA),
143c2c66affSColin Finck 	    FE(DIDFT_FFACTUATOR),
144c2c66affSColin Finck 	    FE(DIDFT_FFEFFECTTRIGGER),
145c2c66affSColin Finck 	    FE(DIDFT_OUTPUT),
146c2c66affSColin Finck 	    FE(DIDFT_VENDORDEFINED),
147c2c66affSColin Finck 	    FE(DIDFT_ALIAS),
148c2c66affSColin Finck 	    FE(DIDFT_OPTIONAL)
149c2c66affSColin Finck #undef FE
150c2c66affSColin Finck 	};
151c2c66affSColin Finck 	type = (dwFlags & 0xFF0000FF);
152c2c66affSColin Finck 	instance = ((dwFlags >> 8) & 0xFFFF);
153c2c66affSColin Finck 	TRACE("Type:");
154c2c66affSColin Finck 	if (type == DIDFT_ALL) {
155c2c66affSColin Finck 	    TRACE(" DIDFT_ALL");
156c2c66affSColin Finck 	} else {
15798e62237SAmine Khaldi 	    for (i = 0; i < ARRAY_SIZE(flags); i++) {
158c2c66affSColin Finck 		if (flags[i].mask & type) {
159c2c66affSColin Finck 		    type &= ~flags[i].mask;
160c2c66affSColin Finck 		    TRACE(" %s",flags[i].name);
161c2c66affSColin Finck 		}
162c2c66affSColin Finck 	    }
163c2c66affSColin Finck 	    if (type) {
164c2c66affSColin Finck                 TRACE(" (unhandled: %08x)", type);
165c2c66affSColin Finck 	    }
166c2c66affSColin Finck 	}
167c2c66affSColin Finck 	TRACE(" / Instance: ");
168c2c66affSColin Finck 	if (instance == ((DIDFT_ANYINSTANCE >> 8) & 0xFFFF)) {
169c2c66affSColin Finck 	    TRACE("DIDFT_ANYINSTANCE");
170c2c66affSColin Finck 	} else {
171c2c66affSColin Finck             TRACE("%3d", instance);
172c2c66affSColin Finck 	}
173c2c66affSColin Finck     }
174c2c66affSColin Finck }
175c2c66affSColin Finck 
_dump_DIPROPHEADER(LPCDIPROPHEADER diph)176c2c66affSColin Finck void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) {
177c2c66affSColin Finck     if (TRACE_ON(dinput)) {
178c2c66affSColin Finck         TRACE("  - dwObj = 0x%08x\n", diph->dwObj);
179c2c66affSColin Finck         TRACE("  - dwHow = %s\n",
180c2c66affSColin Finck             ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" :
181c2c66affSColin Finck             ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" :
182c2c66affSColin Finck             ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown")));
183c2c66affSColin Finck     }
184c2c66affSColin Finck }
185c2c66affSColin Finck 
_dump_OBJECTINSTANCEA(const DIDEVICEOBJECTINSTANCEA * ddoi)186c2c66affSColin Finck void _dump_OBJECTINSTANCEA(const DIDEVICEOBJECTINSTANCEA *ddoi) {
187c2c66affSColin Finck     TRACE("    - enumerating : %s ('%s') - %2d - 0x%08x - %s - 0x%x\n",
188c2c66affSColin Finck         debugstr_guid(&ddoi->guidType), _dump_dinput_GUID(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, ddoi->tszName, ddoi->dwFlags);
189c2c66affSColin Finck }
190c2c66affSColin Finck 
_dump_OBJECTINSTANCEW(const DIDEVICEOBJECTINSTANCEW * ddoi)191c2c66affSColin Finck void _dump_OBJECTINSTANCEW(const DIDEVICEOBJECTINSTANCEW *ddoi) {
192c2c66affSColin Finck     TRACE("    - enumerating : %s ('%s'), - %2d - 0x%08x - %s - 0x%x\n",
193c2c66affSColin Finck         debugstr_guid(&ddoi->guidType), _dump_dinput_GUID(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, debugstr_w(ddoi->tszName), ddoi->dwFlags);
194c2c66affSColin Finck }
195c2c66affSColin Finck 
196c2c66affSColin Finck /* This function is a helper to convert a GUID into any possible DInput GUID out there */
_dump_dinput_GUID(const GUID * guid)197c2c66affSColin Finck const char *_dump_dinput_GUID(const GUID *guid) {
198c2c66affSColin Finck     unsigned int i;
199c2c66affSColin Finck     static const struct {
200c2c66affSColin Finck 	const GUID *guid;
201c2c66affSColin Finck 	const char *name;
202c2c66affSColin Finck     } guids[] = {
203c2c66affSColin Finck #define FE(x) { &x, #x}
204c2c66affSColin Finck 	FE(GUID_XAxis),
205c2c66affSColin Finck 	FE(GUID_YAxis),
206c2c66affSColin Finck 	FE(GUID_ZAxis),
207c2c66affSColin Finck 	FE(GUID_RxAxis),
208c2c66affSColin Finck 	FE(GUID_RyAxis),
209c2c66affSColin Finck 	FE(GUID_RzAxis),
210c2c66affSColin Finck 	FE(GUID_Slider),
211c2c66affSColin Finck 	FE(GUID_Button),
212c2c66affSColin Finck 	FE(GUID_Key),
213c2c66affSColin Finck 	FE(GUID_POV),
214c2c66affSColin Finck 	FE(GUID_Unknown),
215c2c66affSColin Finck 	FE(GUID_SysMouse),
216c2c66affSColin Finck 	FE(GUID_SysKeyboard),
217c2c66affSColin Finck 	FE(GUID_Joystick),
218c2c66affSColin Finck 	FE(GUID_ConstantForce),
219c2c66affSColin Finck 	FE(GUID_RampForce),
220c2c66affSColin Finck 	FE(GUID_Square),
221c2c66affSColin Finck 	FE(GUID_Sine),
222c2c66affSColin Finck 	FE(GUID_Triangle),
223c2c66affSColin Finck 	FE(GUID_SawtoothUp),
224c2c66affSColin Finck 	FE(GUID_SawtoothDown),
225c2c66affSColin Finck 	FE(GUID_Spring),
226c2c66affSColin Finck 	FE(GUID_Damper),
227c2c66affSColin Finck 	FE(GUID_Inertia),
228c2c66affSColin Finck 	FE(GUID_Friction),
229c2c66affSColin Finck 	FE(GUID_CustomForce)
230c2c66affSColin Finck #undef FE
231c2c66affSColin Finck     };
232c2c66affSColin Finck     if (guid == NULL)
233c2c66affSColin Finck 	return "null GUID";
23498e62237SAmine Khaldi     for (i = 0; i < ARRAY_SIZE(guids); i++) {
235c2c66affSColin Finck 	if (IsEqualGUID(guids[i].guid, guid)) {
236c2c66affSColin Finck 	    return guids[i].name;
237c2c66affSColin Finck 	}
238c2c66affSColin Finck     }
239c2c66affSColin Finck     return debugstr_guid(guid);
240c2c66affSColin Finck }
241c2c66affSColin Finck 
_dump_DIDATAFORMAT(const DIDATAFORMAT * df)242c2c66affSColin Finck void _dump_DIDATAFORMAT(const DIDATAFORMAT *df) {
243c2c66affSColin Finck     unsigned int i;
244c2c66affSColin Finck 
245c2c66affSColin Finck     TRACE("Dumping DIDATAFORMAT structure:\n");
246c2c66affSColin Finck     TRACE("  - dwSize: %d\n", df->dwSize);
247c2c66affSColin Finck     if (df->dwSize != sizeof(DIDATAFORMAT)) {
248c2c66affSColin Finck         WARN("Non-standard DIDATAFORMAT structure size %d\n", df->dwSize);
249c2c66affSColin Finck     }
250c2c66affSColin Finck     TRACE("  - dwObjsize: %d\n", df->dwObjSize);
251c2c66affSColin Finck     if (df->dwObjSize != sizeof(DIOBJECTDATAFORMAT)) {
252c2c66affSColin Finck         WARN("Non-standard DIOBJECTDATAFORMAT structure size %d\n", df->dwObjSize);
253c2c66affSColin Finck     }
254c2c66affSColin Finck     TRACE("  - dwFlags: 0x%08x (", df->dwFlags);
255c2c66affSColin Finck     switch (df->dwFlags) {
256c2c66affSColin Finck         case DIDF_ABSAXIS: TRACE("DIDF_ABSAXIS"); break;
257c2c66affSColin Finck 	case DIDF_RELAXIS: TRACE("DIDF_RELAXIS"); break;
258c2c66affSColin Finck 	default: TRACE("unknown"); break;
259c2c66affSColin Finck     }
260c2c66affSColin Finck     TRACE(")\n");
261c2c66affSColin Finck     TRACE("  - dwDataSize: %d\n", df->dwDataSize);
262c2c66affSColin Finck     TRACE("  - dwNumObjs: %d\n", df->dwNumObjs);
263c2c66affSColin Finck 
264c2c66affSColin Finck     for (i = 0; i < df->dwNumObjs; i++) {
265c2c66affSColin Finck 	TRACE("  - Object %d:\n", i);
266c2c66affSColin Finck 	TRACE("      * GUID: %s ('%s')\n", debugstr_guid(df->rgodf[i].pguid), _dump_dinput_GUID(df->rgodf[i].pguid));
267c2c66affSColin Finck         TRACE("      * dwOfs: %d\n", df->rgodf[i].dwOfs);
268c2c66affSColin Finck         TRACE("      * dwType: 0x%08x\n", df->rgodf[i].dwType);
269c2c66affSColin Finck 	TRACE("        "); _dump_EnumObjects_flags(df->rgodf[i].dwType); TRACE("\n");
270c2c66affSColin Finck         TRACE("      * dwFlags: 0x%08x\n", df->rgodf[i].dwFlags);
271c2c66affSColin Finck 	TRACE("        "); _dump_ObjectDataFormat_flags(df->rgodf[i].dwFlags); TRACE("\n");
272c2c66affSColin Finck     }
273c2c66affSColin Finck }
274c2c66affSColin Finck 
275c2c66affSColin Finck /******************************************************************************
276c2c66affSColin Finck  * Get the default and the app-specific config keys.
277c2c66affSColin Finck  */
get_app_key(HKEY * defkey,HKEY * appkey)278c2c66affSColin Finck BOOL get_app_key(HKEY *defkey, HKEY *appkey)
279c2c66affSColin Finck {
280c2c66affSColin Finck     char buffer[MAX_PATH+16];
281c2c66affSColin Finck     DWORD len;
282c2c66affSColin Finck 
283c2c66affSColin Finck     *appkey = 0;
284c2c66affSColin Finck 
285c2c66affSColin Finck     /* @@ Wine registry key: HKCU\Software\Wine\DirectInput */
286c2c66affSColin Finck     if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\DirectInput", defkey))
287c2c66affSColin Finck         *defkey = 0;
288c2c66affSColin Finck 
289c2c66affSColin Finck     len = GetModuleFileNameA(0, buffer, MAX_PATH);
290c2c66affSColin Finck     if (len && len < MAX_PATH)
291c2c66affSColin Finck     {
292c2c66affSColin Finck         HKEY tmpkey;
293c2c66affSColin Finck 
294c2c66affSColin Finck         /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DirectInput */
295c2c66affSColin Finck         if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey))
296c2c66affSColin Finck         {
297c2c66affSColin Finck             char *p, *appname = buffer;
298c2c66affSColin Finck             if ((p = strrchr(appname, '/'))) appname = p + 1;
299c2c66affSColin Finck             if ((p = strrchr(appname, '\\'))) appname = p + 1;
300c2c66affSColin Finck             strcat(appname, "\\DirectInput");
301c2c66affSColin Finck 
302c2c66affSColin Finck             if (RegOpenKeyA(tmpkey, appname, appkey)) *appkey = 0;
303c2c66affSColin Finck             RegCloseKey(tmpkey);
304c2c66affSColin Finck         }
305c2c66affSColin Finck     }
306c2c66affSColin Finck 
307c2c66affSColin Finck     return *defkey || *appkey;
308c2c66affSColin Finck }
309c2c66affSColin Finck 
310c2c66affSColin Finck /******************************************************************************
311c2c66affSColin Finck  * Get a config key from either the app-specific or the default config
312c2c66affSColin Finck  */
get_config_key(HKEY defkey,HKEY appkey,const char * name,char * buffer,DWORD size)313c2c66affSColin Finck DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
314c2c66affSColin Finck                              char *buffer, DWORD size )
315c2c66affSColin Finck {
316c2c66affSColin Finck     if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size ))
317c2c66affSColin Finck         return 0;
318c2c66affSColin Finck 
319c2c66affSColin Finck     if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size ))
320c2c66affSColin Finck         return 0;
321c2c66affSColin Finck 
322c2c66affSColin Finck     return ERROR_FILE_NOT_FOUND;
323c2c66affSColin Finck }
324c2c66affSColin Finck 
325c2c66affSColin Finck /* Conversion between internal data buffer and external data buffer */
fill_DataFormat(void * out,DWORD size,const void * in,const DataFormat * df)326c2c66affSColin Finck void fill_DataFormat(void *out, DWORD size, const void *in, const DataFormat *df)
327c2c66affSColin Finck {
328c2c66affSColin Finck     int i;
329c2c66affSColin Finck     const char *in_c = in;
330c2c66affSColin Finck     char *out_c = out;
331c2c66affSColin Finck 
332c2c66affSColin Finck     memset(out, 0, size);
333c2c66affSColin Finck     if (df->dt == NULL) {
334c2c66affSColin Finck 	/* This means that the app uses Wine's internal data format */
335c2c66affSColin Finck         memcpy(out, in, min(size, df->internal_format_size));
336c2c66affSColin Finck     } else {
337c2c66affSColin Finck 	for (i = 0; i < df->size; i++) {
338c2c66affSColin Finck 	    if (df->dt[i].offset_in >= 0) {
339c2c66affSColin Finck 		switch (df->dt[i].size) {
340c2c66affSColin Finck 		    case 1:
341c2c66affSColin Finck 		        TRACE("Copying (c) to %d from %d (value %d)\n",
342c2c66affSColin Finck                               df->dt[i].offset_out, df->dt[i].offset_in, *(in_c + df->dt[i].offset_in));
343c2c66affSColin Finck 			*(out_c + df->dt[i].offset_out) = *(in_c + df->dt[i].offset_in);
344c2c66affSColin Finck 			break;
345c2c66affSColin Finck 
346c2c66affSColin Finck 		    case 2:
347c2c66affSColin Finck 			TRACE("Copying (s) to %d from %d (value %d)\n",
348c2c66affSColin Finck 			      df->dt[i].offset_out, df->dt[i].offset_in, *((const short *)(in_c + df->dt[i].offset_in)));
349c2c66affSColin Finck 			*((short *)(out_c + df->dt[i].offset_out)) = *((const short *)(in_c + df->dt[i].offset_in));
350c2c66affSColin Finck 			break;
351c2c66affSColin Finck 
352c2c66affSColin Finck 		    case 4:
353c2c66affSColin Finck 			TRACE("Copying (i) to %d from %d (value %d)\n",
354c2c66affSColin Finck                               df->dt[i].offset_out, df->dt[i].offset_in, *((const int *)(in_c + df->dt[i].offset_in)));
355c2c66affSColin Finck                         *((int *)(out_c + df->dt[i].offset_out)) = *((const int *)(in_c + df->dt[i].offset_in));
356c2c66affSColin Finck 			break;
357c2c66affSColin Finck 
358c2c66affSColin Finck 		    default:
359c2c66affSColin Finck 			memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size);
360c2c66affSColin Finck 			break;
361c2c66affSColin Finck 		}
362c2c66affSColin Finck 	    } else {
363c2c66affSColin Finck 		switch (df->dt[i].size) {
364c2c66affSColin Finck 		    case 1:
365c2c66affSColin Finck 		        TRACE("Copying (c) to %d default value %d\n",
366c2c66affSColin Finck 			      df->dt[i].offset_out, df->dt[i].value);
367c2c66affSColin Finck 			*(out_c + df->dt[i].offset_out) = (char) df->dt[i].value;
368c2c66affSColin Finck 			break;
369c2c66affSColin Finck 
370c2c66affSColin Finck 		    case 2:
371c2c66affSColin Finck 			TRACE("Copying (s) to %d default value %d\n",
372c2c66affSColin Finck 			      df->dt[i].offset_out, df->dt[i].value);
373c2c66affSColin Finck 			*((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value;
374c2c66affSColin Finck 			break;
375c2c66affSColin Finck 
376c2c66affSColin Finck 		    case 4:
377c2c66affSColin Finck 			TRACE("Copying (i) to %d default value %d\n",
378c2c66affSColin Finck 			      df->dt[i].offset_out, df->dt[i].value);
379c2c66affSColin Finck 			*((int *) (out_c + df->dt[i].offset_out)) = df->dt[i].value;
380c2c66affSColin Finck 			break;
381c2c66affSColin Finck 
382c2c66affSColin Finck 		    default:
383c2c66affSColin Finck 			memset((out_c + df->dt[i].offset_out), 0, df->dt[i].size);
384c2c66affSColin Finck 			break;
385c2c66affSColin Finck 		}
386c2c66affSColin Finck 	    }
387c2c66affSColin Finck 	}
388c2c66affSColin Finck     }
389c2c66affSColin Finck }
390c2c66affSColin Finck 
release_DataFormat(DataFormat * format)391c2c66affSColin Finck void release_DataFormat(DataFormat * format)
392c2c66affSColin Finck {
393c2c66affSColin Finck     TRACE("Deleting DataFormat: %p\n", format);
394c2c66affSColin Finck 
395c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, format->dt);
396c2c66affSColin Finck     format->dt = NULL;
397c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, format->offsets);
398c2c66affSColin Finck     format->offsets = NULL;
399c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, format->user_df);
400c2c66affSColin Finck     format->user_df = NULL;
401c2c66affSColin Finck }
402c2c66affSColin Finck 
dataformat_to_odf(LPCDIDATAFORMAT df,int idx)403c2c66affSColin Finck static inline LPDIOBJECTDATAFORMAT dataformat_to_odf(LPCDIDATAFORMAT df, int idx)
404c2c66affSColin Finck {
405c2c66affSColin Finck     if (idx < 0 || idx >= df->dwNumObjs) return NULL;
406c2c66affSColin Finck     return (LPDIOBJECTDATAFORMAT)((LPBYTE)df->rgodf + idx * df->dwObjSize);
407c2c66affSColin Finck }
408c2c66affSColin Finck 
409c2c66affSColin Finck /* dataformat_to_odf_by_type
410c2c66affSColin Finck  *  Find the Nth object of the selected type in the DataFormat
411c2c66affSColin Finck  */
dataformat_to_odf_by_type(LPCDIDATAFORMAT df,int n,DWORD type)412c2c66affSColin Finck LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD type)
413c2c66affSColin Finck {
414c2c66affSColin Finck     int i, nfound = 0;
415c2c66affSColin Finck 
416c2c66affSColin Finck     for (i=0; i < df->dwNumObjs; i++)
417c2c66affSColin Finck     {
418c2c66affSColin Finck         LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(df, i);
419c2c66affSColin Finck 
420c2c66affSColin Finck         if (odf->dwType & type)
421c2c66affSColin Finck         {
422c2c66affSColin Finck             if (n == nfound)
423c2c66affSColin Finck                 return odf;
424c2c66affSColin Finck 
425c2c66affSColin Finck             nfound++;
426c2c66affSColin Finck         }
427c2c66affSColin Finck     }
428c2c66affSColin Finck 
429c2c66affSColin Finck     return NULL;
430c2c66affSColin Finck }
431c2c66affSColin Finck 
create_DataFormat(LPCDIDATAFORMAT asked_format,DataFormat * format)432c2c66affSColin Finck static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *format)
433c2c66affSColin Finck {
434c2c66affSColin Finck     DataTransform *dt;
435c2c66affSColin Finck     unsigned int i, j;
436c2c66affSColin Finck     int same = 1;
437c2c66affSColin Finck     int *done;
438c2c66affSColin Finck     int index = 0;
439c2c66affSColin Finck     DWORD next = 0;
440c2c66affSColin Finck 
441c2c66affSColin Finck     if (!format->wine_df) return DIERR_INVALIDPARAM;
442c2c66affSColin Finck     done = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, asked_format->dwNumObjs * sizeof(int));
443c2c66affSColin Finck     dt = HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform));
444c2c66affSColin Finck     if (!dt || !done) goto failed;
445c2c66affSColin Finck 
446c2c66affSColin Finck     if (!(format->offsets = HeapAlloc(GetProcessHeap(), 0, format->wine_df->dwNumObjs * sizeof(int))))
447c2c66affSColin Finck         goto failed;
448c2c66affSColin Finck 
449c2c66affSColin Finck     if (!(format->user_df = HeapAlloc(GetProcessHeap(), 0, asked_format->dwSize)))
450c2c66affSColin Finck         goto failed;
451c2c66affSColin Finck     memcpy(format->user_df, asked_format, asked_format->dwSize);
452c2c66affSColin Finck 
453c2c66affSColin Finck     TRACE("Creating DataTransform :\n");
454c2c66affSColin Finck 
455c2c66affSColin Finck     for (i = 0; i < format->wine_df->dwNumObjs; i++)
456c2c66affSColin Finck     {
457c2c66affSColin Finck         format->offsets[i] = -1;
458c2c66affSColin Finck 
459c2c66affSColin Finck 	for (j = 0; j < asked_format->dwNumObjs; j++) {
460c2c66affSColin Finck 	    if (done[j] == 1)
461c2c66affSColin Finck 		continue;
462c2c66affSColin Finck 
463c2c66affSColin Finck 	    if (/* Check if the application either requests any GUID and if not, it if matches
464c2c66affSColin Finck 		 * the GUID of the Wine object.
465c2c66affSColin Finck 		 */
466c2c66affSColin Finck 		((asked_format->rgodf[j].pguid == NULL) ||
467c2c66affSColin Finck 		 (format->wine_df->rgodf[i].pguid == NULL) ||
468c2c66affSColin Finck 		 (IsEqualGUID(format->wine_df->rgodf[i].pguid, asked_format->rgodf[j].pguid)))
469c2c66affSColin Finck 		&&
470c2c66affSColin Finck 		(/* Then check if it accepts any instance id, and if not, if it matches Wine's
471c2c66affSColin Finck 		  * instance id.
472c2c66affSColin Finck 		  */
473c2c66affSColin Finck 		 ((asked_format->rgodf[j].dwType & DIDFT_INSTANCEMASK) == DIDFT_ANYINSTANCE) ||
474c2c66affSColin Finck 		 (DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType) == 0x00FF) || /* This is mentioned in no DX docs, but it works fine - tested on WinXP */
475c2c66affSColin Finck 		 (DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType) == DIDFT_GETINSTANCE(format->wine_df->rgodf[i].dwType)))
476c2c66affSColin Finck 		&&
477c2c66affSColin Finck 		( /* Then if the asked type matches the one Wine provides */
478c2c66affSColin Finck                  DIDFT_GETTYPE(asked_format->rgodf[j].dwType) & format->wine_df->rgodf[i].dwType))
479c2c66affSColin Finck             {
480c2c66affSColin Finck 		done[j] = 1;
481c2c66affSColin Finck 
482c2c66affSColin Finck 		TRACE("Matching :\n");
483c2c66affSColin Finck 		TRACE("   - Asked (%d) :\n", j);
484c2c66affSColin Finck 		TRACE("       * GUID: %s ('%s')\n",
485c2c66affSColin Finck 		      debugstr_guid(asked_format->rgodf[j].pguid),
486c2c66affSColin Finck 		      _dump_dinput_GUID(asked_format->rgodf[j].pguid));
487c2c66affSColin Finck                 TRACE("       * Offset: %3d\n", asked_format->rgodf[j].dwOfs);
488c2c66affSColin Finck                 TRACE("       * dwType: 0x%08x\n", asked_format->rgodf[j].dwType);
489c2c66affSColin Finck 		TRACE("         "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n");
490c2c66affSColin Finck                 TRACE("       * dwFlags: 0x%08x\n", asked_format->rgodf[j].dwFlags);
491c2c66affSColin Finck 		TRACE("         "); _dump_ObjectDataFormat_flags(asked_format->rgodf[j].dwFlags); TRACE("\n");
492c2c66affSColin Finck 
493c2c66affSColin Finck 		TRACE("   - Wine  (%d) :\n", i);
494c2c66affSColin Finck 		TRACE("       * GUID: %s ('%s')\n",
495c2c66affSColin Finck                       debugstr_guid(format->wine_df->rgodf[i].pguid),
496c2c66affSColin Finck                       _dump_dinput_GUID(format->wine_df->rgodf[i].pguid));
497c2c66affSColin Finck                 TRACE("       * Offset: %3d\n", format->wine_df->rgodf[i].dwOfs);
498c2c66affSColin Finck                 TRACE("       * dwType: 0x%08x\n", format->wine_df->rgodf[i].dwType);
499c2c66affSColin Finck                 TRACE("         "); _dump_EnumObjects_flags(format->wine_df->rgodf[i].dwType); TRACE("\n");
500c2c66affSColin Finck                 TRACE("       * dwFlags: 0x%08x\n", format->wine_df->rgodf[i].dwFlags);
501c2c66affSColin Finck                 TRACE("         "); _dump_ObjectDataFormat_flags(format->wine_df->rgodf[i].dwFlags); TRACE("\n");
502c2c66affSColin Finck 
503c2c66affSColin Finck                 if (format->wine_df->rgodf[i].dwType & DIDFT_BUTTON)
504c2c66affSColin Finck 		    dt[index].size = sizeof(BYTE);
505c2c66affSColin Finck 		else
506c2c66affSColin Finck 		    dt[index].size = sizeof(DWORD);
507c2c66affSColin Finck                 dt[index].offset_in = format->wine_df->rgodf[i].dwOfs;
508c2c66affSColin Finck                 dt[index].offset_out = asked_format->rgodf[j].dwOfs;
509c2c66affSColin Finck                 format->offsets[i]   = asked_format->rgodf[j].dwOfs;
510c2c66affSColin Finck 		dt[index].value = 0;
511c2c66affSColin Finck                 next = next + dt[index].size;
512c2c66affSColin Finck 
513c2c66affSColin Finck                 if (format->wine_df->rgodf[i].dwOfs != dt[index].offset_out)
514c2c66affSColin Finck 		    same = 0;
515c2c66affSColin Finck 
516c2c66affSColin Finck 		index++;
517c2c66affSColin Finck 		break;
518c2c66affSColin Finck 	    }
519c2c66affSColin Finck 	}
520c2c66affSColin Finck     }
521c2c66affSColin Finck 
522c2c66affSColin Finck     TRACE("Setting to default value :\n");
523c2c66affSColin Finck     for (j = 0; j < asked_format->dwNumObjs; j++) {
524c2c66affSColin Finck 	if (done[j] == 0) {
525c2c66affSColin Finck 	    TRACE("   - Asked (%d) :\n", j);
526c2c66affSColin Finck 	    TRACE("       * GUID: %s ('%s')\n",
527c2c66affSColin Finck 		  debugstr_guid(asked_format->rgodf[j].pguid),
528c2c66affSColin Finck 		  _dump_dinput_GUID(asked_format->rgodf[j].pguid));
529c2c66affSColin Finck             TRACE("       * Offset: %3d\n", asked_format->rgodf[j].dwOfs);
530c2c66affSColin Finck             TRACE("       * dwType: 0x%08x\n", asked_format->rgodf[j].dwType);
531c2c66affSColin Finck 	    TRACE("         "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n");
532c2c66affSColin Finck             TRACE("       * dwFlags: 0x%08x\n", asked_format->rgodf[j].dwFlags);
533c2c66affSColin Finck 	    TRACE("         "); _dump_ObjectDataFormat_flags(asked_format->rgodf[j].dwFlags); TRACE("\n");
534c2c66affSColin Finck 
535c2c66affSColin Finck 	    if (asked_format->rgodf[j].dwType & DIDFT_BUTTON)
536c2c66affSColin Finck 		dt[index].size = sizeof(BYTE);
537c2c66affSColin Finck 	    else
538c2c66affSColin Finck 		dt[index].size = sizeof(DWORD);
539c2c66affSColin Finck 	    dt[index].offset_in  = -1;
540c2c66affSColin Finck 	    dt[index].offset_out = asked_format->rgodf[j].dwOfs;
541c2c66affSColin Finck             if (asked_format->rgodf[j].dwType & DIDFT_POV)
542c2c66affSColin Finck                 dt[index].value = -1;
543c2c66affSColin Finck             else
544c2c66affSColin Finck                 dt[index].value = 0;
545c2c66affSColin Finck 	    index++;
546c2c66affSColin Finck 
547c2c66affSColin Finck 	    same = 0;
548c2c66affSColin Finck 	}
549c2c66affSColin Finck     }
550c2c66affSColin Finck 
551c2c66affSColin Finck     format->internal_format_size = format->wine_df->dwDataSize;
552c2c66affSColin Finck     format->size = index;
553c2c66affSColin Finck     if (same) {
554c2c66affSColin Finck 	HeapFree(GetProcessHeap(), 0, dt);
555c2c66affSColin Finck         dt = NULL;
556c2c66affSColin Finck     }
557c2c66affSColin Finck     format->dt = dt;
558c2c66affSColin Finck 
559c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, done);
560c2c66affSColin Finck 
561c2c66affSColin Finck     return DI_OK;
562c2c66affSColin Finck 
563c2c66affSColin Finck failed:
564c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, done);
565c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, dt);
566c2c66affSColin Finck     format->dt = NULL;
567c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, format->offsets);
568c2c66affSColin Finck     format->offsets = NULL;
569c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, format->user_df);
570c2c66affSColin Finck     format->user_df = NULL;
571c2c66affSColin Finck 
572c2c66affSColin Finck     return DIERR_OUTOFMEMORY;
573c2c66affSColin Finck }
574c2c66affSColin Finck 
575c2c66affSColin Finck /* find an object by its offset in a data format */
offset_to_object(const DataFormat * df,int offset)576c2c66affSColin Finck static int offset_to_object(const DataFormat *df, int offset)
577c2c66affSColin Finck {
578c2c66affSColin Finck     int i;
579c2c66affSColin Finck 
580c2c66affSColin Finck     if (!df->offsets) return -1;
581c2c66affSColin Finck 
582c2c66affSColin Finck     for (i = 0; i < df->wine_df->dwNumObjs; i++)
583c2c66affSColin Finck         if (df->offsets[i] == offset) return i;
584c2c66affSColin Finck 
585c2c66affSColin Finck     return -1;
586c2c66affSColin Finck }
587c2c66affSColin Finck 
id_to_object(LPCDIDATAFORMAT df,int id)588c2c66affSColin Finck int id_to_object(LPCDIDATAFORMAT df, int id)
589c2c66affSColin Finck {
590c2c66affSColin Finck     int i;
591c2c66affSColin Finck 
592c2c66affSColin Finck     id &= 0x00ffffff;
593c2c66affSColin Finck     for (i = 0; i < df->dwNumObjs; i++)
594c2c66affSColin Finck         if ((dataformat_to_odf(df, i)->dwType & 0x00ffffff) == id)
595c2c66affSColin Finck             return i;
596c2c66affSColin Finck 
597c2c66affSColin Finck     return -1;
598c2c66affSColin Finck }
599c2c66affSColin Finck 
id_to_offset(const DataFormat * df,int id)600c2c66affSColin Finck static int id_to_offset(const DataFormat *df, int id)
601c2c66affSColin Finck {
602c2c66affSColin Finck     int obj = id_to_object(df->wine_df, id);
603c2c66affSColin Finck 
604c2c66affSColin Finck     return obj >= 0 && df->offsets ? df->offsets[obj] : -1;
605c2c66affSColin Finck }
606c2c66affSColin Finck 
find_property(const DataFormat * df,LPCDIPROPHEADER ph)607c2c66affSColin Finck int find_property(const DataFormat *df, LPCDIPROPHEADER ph)
608c2c66affSColin Finck {
609c2c66affSColin Finck     switch (ph->dwHow)
610c2c66affSColin Finck     {
611c2c66affSColin Finck         case DIPH_BYID:     return id_to_object(df->wine_df, ph->dwObj);
612c2c66affSColin Finck         case DIPH_BYOFFSET: return offset_to_object(df, ph->dwObj);
613c2c66affSColin Finck     }
614c2c66affSColin Finck     FIXME("Unhandled ph->dwHow=='%04X'\n", (unsigned int)ph->dwHow);
615c2c66affSColin Finck 
616c2c66affSColin Finck     return -1;
617c2c66affSColin Finck }
618c2c66affSColin Finck 
semantic_to_obj_id(IDirectInputDeviceImpl * This,DWORD dwSemantic)619c2c66affSColin Finck static DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic)
620c2c66affSColin Finck {
621c2c66affSColin Finck     DWORD type = (0x0000ff00 & dwSemantic) >> 8;
622c2c66affSColin Finck     DWORD offset = 0x000000ff & dwSemantic;
623c2c66affSColin Finck     DWORD obj_instance = 0;
624c2c66affSColin Finck     BOOL found = FALSE;
625c2c66affSColin Finck     int i;
626c2c66affSColin Finck 
627c2c66affSColin Finck     for (i = 0; i < This->data_format.wine_df->dwNumObjs; i++)
628c2c66affSColin Finck     {
629c2c66affSColin Finck         LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(This->data_format.wine_df, i);
630c2c66affSColin Finck 
631c2c66affSColin Finck         if (odf->dwOfs == offset)
632c2c66affSColin Finck         {
633c2c66affSColin Finck             obj_instance = DIDFT_GETINSTANCE(odf->dwType);
634c2c66affSColin Finck             found = TRUE;
635c2c66affSColin Finck             break;
636c2c66affSColin Finck         }
637c2c66affSColin Finck     }
638c2c66affSColin Finck 
639c2c66affSColin Finck     if (!found) return 0;
640c2c66affSColin Finck 
641c2c66affSColin Finck     if (type & DIDFT_AXIS)   type = DIDFT_RELAXIS;
642c2c66affSColin Finck     if (type & DIDFT_BUTTON) type = DIDFT_PSHBUTTON;
643c2c66affSColin Finck 
644c2c66affSColin Finck     return type | (0x0000ff00 & (obj_instance << 8));
645c2c66affSColin Finck }
646c2c66affSColin Finck 
del_mapping_key(const WCHAR * device,const WCHAR * username,const WCHAR * guid)647*41c8c312SAmine Khaldi static void del_mapping_key(const WCHAR *device, const WCHAR *username, const WCHAR *guid) {
648*41c8c312SAmine Khaldi     static const WCHAR subkey[] = {
649*41c8c312SAmine Khaldi         'S','o','f','t','w','a','r','e','\\',
650*41c8c312SAmine Khaldi         'W','i','n','e','\\',
651*41c8c312SAmine Khaldi         'D','i','r','e','c','t','I','n','p','u','t','\\',
652*41c8c312SAmine Khaldi         'M','a','p','p','i','n','g','s','\\','%','s','\\','%','s','\\','%','s','\0'};
653*41c8c312SAmine Khaldi     WCHAR *keyname;
654*41c8c312SAmine Khaldi 
655*41c8c312SAmine Khaldi     keyname = heap_alloc(sizeof(WCHAR) * (lstrlenW(subkey) + strlenW(username) + strlenW(device) + strlenW(guid)));
656*41c8c312SAmine Khaldi     sprintfW(keyname, subkey, username, device, guid);
657*41c8c312SAmine Khaldi 
658*41c8c312SAmine Khaldi     /* Remove old key mappings so there will be no overlapping mappings */
659*41c8c312SAmine Khaldi     RegDeleteKeyW(HKEY_CURRENT_USER, keyname);
660*41c8c312SAmine Khaldi 
661*41c8c312SAmine Khaldi     heap_free(keyname);
662*41c8c312SAmine Khaldi }
663*41c8c312SAmine Khaldi 
664c2c66affSColin Finck /*
665c2c66affSColin Finck  * get_mapping_key
666c2c66affSColin Finck  * Retrieves an open registry key to save the mapping, parametrized for an username,
667c2c66affSColin Finck  * specific device and specific action mapping guid.
668c2c66affSColin Finck  */
get_mapping_key(const WCHAR * device,const WCHAR * username,const WCHAR * guid,BOOL create)669*41c8c312SAmine Khaldi static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WCHAR *guid, BOOL create)
670c2c66affSColin Finck {
671c2c66affSColin Finck     static const WCHAR subkey[] = {
672c2c66affSColin Finck         'S','o','f','t','w','a','r','e','\\',
673c2c66affSColin Finck         'W','i','n','e','\\',
674c2c66affSColin Finck         'D','i','r','e','c','t','I','n','p','u','t','\\',
675c2c66affSColin Finck         'M','a','p','p','i','n','g','s','\\','%','s','\\','%','s','\\','%','s','\0'};
676c2c66affSColin Finck     HKEY hkey;
677c2c66affSColin Finck     WCHAR *keyname;
678c2c66affSColin Finck 
679c2c66affSColin Finck     keyname = HeapAlloc(GetProcessHeap(), 0,
680c2c66affSColin Finck         sizeof(WCHAR) * (lstrlenW(subkey) + strlenW(username) + strlenW(device) + strlenW(guid)));
681c2c66affSColin Finck     sprintfW(keyname, subkey, username, device, guid);
682c2c66affSColin Finck 
683c2c66affSColin Finck     /* The key used is HKCU\Software\Wine\DirectInput\Mappings\[username]\[device]\[mapping_guid] */
684*41c8c312SAmine Khaldi     if (create) {
685c2c66affSColin Finck         if (RegCreateKeyW(HKEY_CURRENT_USER, keyname, &hkey))
686c2c66affSColin Finck             hkey = 0;
687*41c8c312SAmine Khaldi     } else if (RegOpenKeyW(HKEY_CURRENT_USER, keyname, &hkey))
688*41c8c312SAmine Khaldi             hkey = 0;
689c2c66affSColin Finck 
690c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, keyname);
691c2c66affSColin Finck 
692c2c66affSColin Finck     return hkey;
693c2c66affSColin Finck }
694c2c66affSColin Finck 
save_mapping_settings(IDirectInputDevice8W * iface,LPDIACTIONFORMATW lpdiaf,LPCWSTR lpszUsername)695*41c8c312SAmine Khaldi HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUsername)
696c2c66affSColin Finck {
697c2c66affSColin Finck     WCHAR *guid_str = NULL;
698c2c66affSColin Finck     DIDEVICEINSTANCEW didev;
699c2c66affSColin Finck     HKEY hkey;
700c2c66affSColin Finck     int i;
701c2c66affSColin Finck 
702c2c66affSColin Finck     didev.dwSize = sizeof(didev);
703c2c66affSColin Finck     IDirectInputDevice8_GetDeviceInfo(iface, &didev);
704c2c66affSColin Finck 
705c2c66affSColin Finck     if (StringFromCLSID(&lpdiaf->guidActionMap, &guid_str) != S_OK)
706c2c66affSColin Finck         return DI_SETTINGSNOTSAVED;
707c2c66affSColin Finck 
708*41c8c312SAmine Khaldi     del_mapping_key(didev.tszInstanceName, lpszUsername, guid_str);
709*41c8c312SAmine Khaldi 
710*41c8c312SAmine Khaldi     hkey = get_mapping_key(didev.tszInstanceName, lpszUsername, guid_str, TRUE);
711c2c66affSColin Finck 
712c2c66affSColin Finck     if (!hkey)
713c2c66affSColin Finck     {
714c2c66affSColin Finck         CoTaskMemFree(guid_str);
715c2c66affSColin Finck         return DI_SETTINGSNOTSAVED;
716c2c66affSColin Finck     }
717c2c66affSColin Finck 
718c2c66affSColin Finck     /* Write each of the actions mapped for this device.
719c2c66affSColin Finck        Format is "dwSemantic"="dwObjID" and key is of type REG_DWORD
720c2c66affSColin Finck     */
721c2c66affSColin Finck     for (i = 0; i < lpdiaf->dwNumActions; i++)
722c2c66affSColin Finck     {
723c2c66affSColin Finck         static const WCHAR format[] = {'%','x','\0'};
724c2c66affSColin Finck         WCHAR label[9];
725c2c66affSColin Finck 
726c2c66affSColin Finck         if (IsEqualGUID(&didev.guidInstance, &lpdiaf->rgoAction[i].guidInstance) &&
727c2c66affSColin Finck             lpdiaf->rgoAction[i].dwHow != DIAH_UNMAPPED)
728c2c66affSColin Finck         {
729c2c66affSColin Finck              sprintfW(label, format, lpdiaf->rgoAction[i].dwSemantic);
730c2c66affSColin Finck              RegSetValueExW(hkey, label, 0, REG_DWORD, (const BYTE*) &lpdiaf->rgoAction[i].dwObjID, sizeof(DWORD));
731c2c66affSColin Finck         }
732c2c66affSColin Finck     }
733c2c66affSColin Finck 
734c2c66affSColin Finck     RegCloseKey(hkey);
735c2c66affSColin Finck     CoTaskMemFree(guid_str);
736c2c66affSColin Finck 
737c2c66affSColin Finck     return DI_OK;
738c2c66affSColin Finck }
739c2c66affSColin Finck 
load_mapping_settings(IDirectInputDeviceImpl * This,LPDIACTIONFORMATW lpdiaf,const WCHAR * username)740*41c8c312SAmine Khaldi BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdiaf, const WCHAR *username)
741c2c66affSColin Finck {
742c2c66affSColin Finck     HKEY hkey;
743c2c66affSColin Finck     WCHAR *guid_str;
744c2c66affSColin Finck     DIDEVICEINSTANCEW didev;
745*41c8c312SAmine Khaldi     int i;
746c2c66affSColin Finck 
747c2c66affSColin Finck     didev.dwSize = sizeof(didev);
748c2c66affSColin Finck     IDirectInputDevice8_GetDeviceInfo(&This->IDirectInputDevice8W_iface, &didev);
749c2c66affSColin Finck 
750c2c66affSColin Finck     if (StringFromCLSID(&lpdiaf->guidActionMap, &guid_str) != S_OK)
751c2c66affSColin Finck         return FALSE;
752c2c66affSColin Finck 
753*41c8c312SAmine Khaldi     hkey = get_mapping_key(didev.tszInstanceName, username, guid_str, FALSE);
754c2c66affSColin Finck 
755c2c66affSColin Finck     if (!hkey)
756c2c66affSColin Finck     {
757c2c66affSColin Finck         CoTaskMemFree(guid_str);
758c2c66affSColin Finck         return FALSE;
759c2c66affSColin Finck     }
760c2c66affSColin Finck 
761c2c66affSColin Finck     /* Try to read each action in the DIACTIONFORMAT from registry */
762c2c66affSColin Finck     for (i = 0; i < lpdiaf->dwNumActions; i++)
763c2c66affSColin Finck     {
764c2c66affSColin Finck         static const WCHAR format[] = {'%','x','\0'};
765c2c66affSColin Finck         DWORD id, size = sizeof(DWORD);
766c2c66affSColin Finck         WCHAR label[9];
767c2c66affSColin Finck 
768c2c66affSColin Finck         sprintfW(label, format, lpdiaf->rgoAction[i].dwSemantic);
769c2c66affSColin Finck 
770c2c66affSColin Finck         if (!RegQueryValueExW(hkey, label, 0, NULL, (LPBYTE) &id, &size))
771c2c66affSColin Finck         {
772c2c66affSColin Finck             lpdiaf->rgoAction[i].dwObjID = id;
773c2c66affSColin Finck             lpdiaf->rgoAction[i].guidInstance = didev.guidInstance;
774*41c8c312SAmine Khaldi             lpdiaf->rgoAction[i].dwHow = DIAH_USERCONFIG;
775c2c66affSColin Finck         }
776*41c8c312SAmine Khaldi         else
777*41c8c312SAmine Khaldi         {
778*41c8c312SAmine Khaldi             memset(&lpdiaf->rgoAction[i].guidInstance, 0, sizeof(GUID));
779*41c8c312SAmine Khaldi             lpdiaf->rgoAction[i].dwHow = DIAH_UNMAPPED;
780*41c8c312SAmine Khaldi         }
781*41c8c312SAmine Khaldi 
782c2c66affSColin Finck     }
783c2c66affSColin Finck 
784c2c66affSColin Finck     RegCloseKey(hkey);
785c2c66affSColin Finck     CoTaskMemFree(guid_str);
786c2c66affSColin Finck 
787*41c8c312SAmine Khaldi     /* On Windows BuildActionMap can open empty mapping, so always return TRUE if get_mapping_key is success */
788*41c8c312SAmine Khaldi     return TRUE;
789c2c66affSColin Finck }
790c2c66affSColin Finck 
_build_action_map(LPDIRECTINPUTDEVICE8W iface,LPDIACTIONFORMATW lpdiaf,LPCWSTR lpszUserName,DWORD dwFlags,DWORD devMask,LPCDIDATAFORMAT df)791c2c66affSColin Finck HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, DWORD devMask, LPCDIDATAFORMAT df)
792c2c66affSColin Finck {
793c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
794c2c66affSColin Finck     WCHAR username[MAX_PATH];
795c2c66affSColin Finck     DWORD username_size = MAX_PATH;
796c2c66affSColin Finck     int i;
797c2c66affSColin Finck     BOOL load_success = FALSE, has_actions = FALSE;
798c2c66affSColin Finck 
799c2c66affSColin Finck     /* Unless asked the contrary by these flags, try to load a previous mapping */
800c2c66affSColin Finck     if (!(dwFlags & DIDBAM_HWDEFAULTS))
801c2c66affSColin Finck     {
802c2c66affSColin Finck         /* Retrieve logged user name if necessary */
803c2c66affSColin Finck         if (lpszUserName == NULL)
804c2c66affSColin Finck             GetUserNameW(username, &username_size);
805c2c66affSColin Finck         else
806c2c66affSColin Finck             lstrcpynW(username, lpszUserName, MAX_PATH);
807c2c66affSColin Finck 
808c2c66affSColin Finck         load_success = load_mapping_settings(This, lpdiaf, username);
809c2c66affSColin Finck     }
810c2c66affSColin Finck 
811*41c8c312SAmine Khaldi     if (load_success) {
812*41c8c312SAmine Khaldi         /* Update dwCRC to track if action format has changed */
813*41c8c312SAmine Khaldi         for (i=0; i < lpdiaf->dwNumActions; i++)
814*41c8c312SAmine Khaldi         {
815*41c8c312SAmine Khaldi             lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2));
816*41c8c312SAmine Khaldi             lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5)));
817*41c8c312SAmine Khaldi         }
818*41c8c312SAmine Khaldi         return DI_OK;
819*41c8c312SAmine Khaldi     }
820c2c66affSColin Finck 
821c2c66affSColin Finck     for (i=0; i < lpdiaf->dwNumActions; i++)
822c2c66affSColin Finck     {
823c2c66affSColin Finck         if ((lpdiaf->rgoAction[i].dwSemantic & devMask) == devMask)
824c2c66affSColin Finck         {
825c2c66affSColin Finck             DWORD obj_id = semantic_to_obj_id(This, lpdiaf->rgoAction[i].dwSemantic);
826c2c66affSColin Finck             DWORD type = DIDFT_GETTYPE(obj_id);
827c2c66affSColin Finck             DWORD inst = DIDFT_GETINSTANCE(obj_id);
828c2c66affSColin Finck 
829c2c66affSColin Finck             LPDIOBJECTDATAFORMAT odf;
830c2c66affSColin Finck 
831c2c66affSColin Finck             if (type == DIDFT_PSHBUTTON) type = DIDFT_BUTTON;
832c2c66affSColin Finck             if (type == DIDFT_RELAXIS) type = DIDFT_AXIS;
833c2c66affSColin Finck 
834c2c66affSColin Finck             /* Make sure the object exists */
835c2c66affSColin Finck             odf = dataformat_to_odf_by_type(df, inst, type);
836c2c66affSColin Finck 
837c2c66affSColin Finck             if (odf != NULL)
838c2c66affSColin Finck             {
839c2c66affSColin Finck                 lpdiaf->rgoAction[i].dwObjID = obj_id;
840c2c66affSColin Finck                 lpdiaf->rgoAction[i].guidInstance = This->guid;
841c2c66affSColin Finck                 lpdiaf->rgoAction[i].dwHow = DIAH_DEFAULT;
842c2c66affSColin Finck                 has_actions = TRUE;
843c2c66affSColin Finck             }
844c2c66affSColin Finck         }
845c2c66affSColin Finck         else if (!(dwFlags & DIDBAM_PRESERVE))
846c2c66affSColin Finck         {
847c2c66affSColin Finck             /* We must clear action data belonging to other devices */
848c2c66affSColin Finck             memset(&lpdiaf->rgoAction[i].guidInstance, 0, sizeof(GUID));
849c2c66affSColin Finck             lpdiaf->rgoAction[i].dwHow = DIAH_UNMAPPED;
850c2c66affSColin Finck         }
851c2c66affSColin Finck     }
852c2c66affSColin Finck 
853*41c8c312SAmine Khaldi     /* Update dwCRC to track if action format has changed */
854*41c8c312SAmine Khaldi     lpdiaf->dwCRC = 0;
855*41c8c312SAmine Khaldi     for (i=0; i < lpdiaf->dwNumActions; i++)
856*41c8c312SAmine Khaldi     {
857*41c8c312SAmine Khaldi         lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2));
858*41c8c312SAmine Khaldi         lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5)));
859*41c8c312SAmine Khaldi     }
860*41c8c312SAmine Khaldi 
861c2c66affSColin Finck     if (!has_actions) return DI_NOEFFECT;
862c2c66affSColin Finck 
863c2c66affSColin Finck     return  IDirectInputDevice8WImpl_BuildActionMap(iface, lpdiaf, lpszUserName, dwFlags);
864c2c66affSColin Finck }
865c2c66affSColin Finck 
_set_action_map(LPDIRECTINPUTDEVICE8W iface,LPDIACTIONFORMATW lpdiaf,LPCWSTR lpszUserName,DWORD dwFlags,LPCDIDATAFORMAT df)866c2c66affSColin Finck HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, LPCDIDATAFORMAT df)
867c2c66affSColin Finck {
868c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
869c2c66affSColin Finck     DIDATAFORMAT data_format;
870c2c66affSColin Finck     DIOBJECTDATAFORMAT *obj_df = NULL;
871c2c66affSColin Finck     DIPROPDWORD dp;
872c2c66affSColin Finck     DIPROPRANGE dpr;
873c2c66affSColin Finck     DIPROPSTRING dps;
874c2c66affSColin Finck     WCHAR username[MAX_PATH];
875c2c66affSColin Finck     DWORD username_size = MAX_PATH;
876*41c8c312SAmine Khaldi     DWORD new_crc = 0;
877c2c66affSColin Finck     int i, action = 0, num_actions = 0;
878c2c66affSColin Finck     unsigned int offset = 0;
879c2c66affSColin Finck 
880c2c66affSColin Finck     if (This->acquired) return DIERR_ACQUIRED;
881c2c66affSColin Finck 
882c2c66affSColin Finck     data_format.dwSize = sizeof(data_format);
883c2c66affSColin Finck     data_format.dwObjSize = sizeof(DIOBJECTDATAFORMAT);
884c2c66affSColin Finck     data_format.dwFlags = DIDF_RELAXIS;
885c2c66affSColin Finck     data_format.dwDataSize = lpdiaf->dwDataSize;
886c2c66affSColin Finck 
887*41c8c312SAmine Khaldi     /* Calculate checksum for actionformat */
888*41c8c312SAmine Khaldi     for (i=0; i < lpdiaf->dwNumActions; i++)
889*41c8c312SAmine Khaldi     {
890*41c8c312SAmine Khaldi         new_crc ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2));
891*41c8c312SAmine Khaldi         new_crc ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5)));
892*41c8c312SAmine Khaldi     }
893*41c8c312SAmine Khaldi 
894c2c66affSColin Finck     /* Count the actions */
895c2c66affSColin Finck     for (i=0; i < lpdiaf->dwNumActions; i++)
896*41c8c312SAmine Khaldi     {
897*41c8c312SAmine Khaldi         if (IsEqualGUID(&This->guid, &lpdiaf->rgoAction[i].guidInstance) ||
898*41c8c312SAmine Khaldi                 (IsEqualGUID(&IID_NULL, &lpdiaf->rgoAction[i].guidInstance) &&
899*41c8c312SAmine Khaldi                   ((lpdiaf->rgoAction[i].dwSemantic & lpdiaf->dwGenre) == lpdiaf->dwGenre ||
900*41c8c312SAmine Khaldi                    (lpdiaf->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */) ))
901*41c8c312SAmine Khaldi         {
902c2c66affSColin Finck             num_actions++;
903*41c8c312SAmine Khaldi         }
904*41c8c312SAmine Khaldi     }
905c2c66affSColin Finck 
906*41c8c312SAmine Khaldi     /* Should return DI_NOEFFECT if we dont have any actions and actionformat has not changed */
907*41c8c312SAmine Khaldi     if (num_actions == 0 && lpdiaf->dwCRC == new_crc && !(dwFlags & DIDSAM_FORCESAVE)) return DI_NOEFFECT;
908*41c8c312SAmine Khaldi 
909*41c8c312SAmine Khaldi     /* update dwCRC to track if action format has changed */
910*41c8c312SAmine Khaldi     lpdiaf->dwCRC = new_crc;
911c2c66affSColin Finck 
912c2c66affSColin Finck     This->num_actions = num_actions;
913c2c66affSColin Finck 
914c2c66affSColin Finck     /* Construct the dataformat and actionmap */
915c2c66affSColin Finck     obj_df = HeapAlloc(GetProcessHeap(), 0, sizeof(DIOBJECTDATAFORMAT)*num_actions);
916c2c66affSColin Finck     data_format.rgodf = (LPDIOBJECTDATAFORMAT)obj_df;
917c2c66affSColin Finck     data_format.dwNumObjs = num_actions;
918c2c66affSColin Finck 
919c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, This->action_map);
920c2c66affSColin Finck     This->action_map = HeapAlloc(GetProcessHeap(), 0, sizeof(ActionMap)*num_actions);
921c2c66affSColin Finck 
922c2c66affSColin Finck     for (i = 0; i < lpdiaf->dwNumActions; i++)
923c2c66affSColin Finck     {
924c2c66affSColin Finck         if (IsEqualGUID(&This->guid, &lpdiaf->rgoAction[i].guidInstance))
925c2c66affSColin Finck         {
926c2c66affSColin Finck             DWORD inst = DIDFT_GETINSTANCE(lpdiaf->rgoAction[i].dwObjID);
927c2c66affSColin Finck             DWORD type = DIDFT_GETTYPE(lpdiaf->rgoAction[i].dwObjID);
928c2c66affSColin Finck             LPDIOBJECTDATAFORMAT obj;
929c2c66affSColin Finck 
930c2c66affSColin Finck             if (type == DIDFT_PSHBUTTON) type = DIDFT_BUTTON;
931c2c66affSColin Finck             if (type == DIDFT_RELAXIS) type = DIDFT_AXIS;
932c2c66affSColin Finck 
933c2c66affSColin Finck             obj = dataformat_to_odf_by_type(df, inst, type);
934c2c66affSColin Finck 
935c2c66affSColin Finck             memcpy(&obj_df[action], obj, df->dwObjSize);
936c2c66affSColin Finck 
937c2c66affSColin Finck             This->action_map[action].uAppData = lpdiaf->rgoAction[i].uAppData;
938c2c66affSColin Finck             This->action_map[action].offset = offset;
939c2c66affSColin Finck             obj_df[action].dwOfs = offset;
940c2c66affSColin Finck             offset += (type & DIDFT_BUTTON) ? 1 : 4;
941c2c66affSColin Finck 
942c2c66affSColin Finck             action++;
943c2c66affSColin Finck         }
944*41c8c312SAmine Khaldi         else if ((lpdiaf->rgoAction[i].dwSemantic & lpdiaf->dwGenre) == lpdiaf->dwGenre ||
945*41c8c312SAmine Khaldi                  (lpdiaf->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */)
946*41c8c312SAmine Khaldi         {
947*41c8c312SAmine Khaldi             DWORD obj_id = semantic_to_obj_id(This, lpdiaf->rgoAction[i].dwSemantic);
948*41c8c312SAmine Khaldi             DWORD type = DIDFT_GETTYPE(obj_id);
949*41c8c312SAmine Khaldi             DWORD inst = DIDFT_GETINSTANCE(obj_id);
950*41c8c312SAmine Khaldi             LPDIOBJECTDATAFORMAT obj;
951*41c8c312SAmine Khaldi 
952*41c8c312SAmine Khaldi             if (type == DIDFT_PSHBUTTON) type = DIDFT_BUTTON;
953*41c8c312SAmine Khaldi             else if (type == DIDFT_RELAXIS) type = DIDFT_AXIS;
954*41c8c312SAmine Khaldi 
955*41c8c312SAmine Khaldi             obj = dataformat_to_odf_by_type(df, inst, type);
956*41c8c312SAmine Khaldi             TRACE("obj %p, inst 0x%08x, type 0x%08x\n", obj, inst, type);
957*41c8c312SAmine Khaldi             if(obj)
958*41c8c312SAmine Khaldi             {
959*41c8c312SAmine Khaldi                 memcpy(&obj_df[action], obj, df->dwObjSize);
960*41c8c312SAmine Khaldi 
961*41c8c312SAmine Khaldi                 This->action_map[action].uAppData = lpdiaf->rgoAction[i].uAppData;
962*41c8c312SAmine Khaldi                 This->action_map[action].offset = offset;
963*41c8c312SAmine Khaldi                 obj_df[action].dwOfs = offset;
964*41c8c312SAmine Khaldi                 offset += (type & DIDFT_BUTTON) ? 1 : 4;
965*41c8c312SAmine Khaldi 
966*41c8c312SAmine Khaldi                 action++;
967c2c66affSColin Finck             }
968*41c8c312SAmine Khaldi         }
969*41c8c312SAmine Khaldi     }
970*41c8c312SAmine Khaldi 
971*41c8c312SAmine Khaldi     if (action == 0)
972*41c8c312SAmine Khaldi     {
973*41c8c312SAmine Khaldi         HeapFree(GetProcessHeap(), 0, obj_df);
974*41c8c312SAmine Khaldi         return DI_NOEFFECT;
975*41c8c312SAmine Khaldi     }
976*41c8c312SAmine Khaldi     data_format.dwNumObjs = action;
977c2c66affSColin Finck 
978c2c66affSColin Finck     IDirectInputDevice8_SetDataFormat(iface, &data_format);
979c2c66affSColin Finck 
980c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, obj_df);
981c2c66affSColin Finck 
982c2c66affSColin Finck     /* Set the device properties according to the action format */
983c2c66affSColin Finck     dpr.diph.dwSize = sizeof(DIPROPRANGE);
984c2c66affSColin Finck     dpr.lMin = lpdiaf->lAxisMin;
985c2c66affSColin Finck     dpr.lMax = lpdiaf->lAxisMax;
986c2c66affSColin Finck     dpr.diph.dwHeaderSize = sizeof(DIPROPHEADER);
987c2c66affSColin Finck     dpr.diph.dwHow = DIPH_DEVICE;
988c2c66affSColin Finck     IDirectInputDevice8_SetProperty(iface, DIPROP_RANGE, &dpr.diph);
989c2c66affSColin Finck 
990c2c66affSColin Finck     if (lpdiaf->dwBufferSize > 0)
991c2c66affSColin Finck     {
992c2c66affSColin Finck         dp.diph.dwSize = sizeof(DIPROPDWORD);
993c2c66affSColin Finck         dp.dwData = lpdiaf->dwBufferSize;
994c2c66affSColin Finck         dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
995c2c66affSColin Finck         dp.diph.dwHow = DIPH_DEVICE;
996c2c66affSColin Finck         IDirectInputDevice8_SetProperty(iface, DIPROP_BUFFERSIZE, &dp.diph);
997c2c66affSColin Finck     }
998c2c66affSColin Finck 
999c2c66affSColin Finck     /* Retrieve logged user name if necessary */
1000c2c66affSColin Finck     if (lpszUserName == NULL)
1001c2c66affSColin Finck         GetUserNameW(username, &username_size);
1002c2c66affSColin Finck     else
1003c2c66affSColin Finck         lstrcpynW(username, lpszUserName, MAX_PATH);
1004c2c66affSColin Finck 
1005c2c66affSColin Finck     dps.diph.dwSize = sizeof(dps);
1006c2c66affSColin Finck     dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
1007c2c66affSColin Finck     dps.diph.dwObj = 0;
1008c2c66affSColin Finck     dps.diph.dwHow = DIPH_DEVICE;
1009c2c66affSColin Finck     if (dwFlags & DIDSAM_NOUSER)
1010c2c66affSColin Finck         dps.wsz[0] = '\0';
1011c2c66affSColin Finck     else
101298e62237SAmine Khaldi         lstrcpynW(dps.wsz, username, ARRAY_SIZE(dps.wsz));
1013c2c66affSColin Finck     IDirectInputDevice8_SetProperty(iface, DIPROP_USERNAME, &dps.diph);
1014c2c66affSColin Finck 
1015c2c66affSColin Finck     /* Save the settings to disk */
1016c2c66affSColin Finck     save_mapping_settings(iface, lpdiaf, username);
1017c2c66affSColin Finck 
1018c2c66affSColin Finck     return DI_OK;
1019c2c66affSColin Finck }
1020c2c66affSColin Finck 
1021c2c66affSColin Finck /******************************************************************************
1022c2c66affSColin Finck  *	queue_event - add new event to the ring queue
1023c2c66affSColin Finck  */
1024c2c66affSColin Finck 
queue_event(LPDIRECTINPUTDEVICE8A iface,int inst_id,DWORD data,DWORD time,DWORD seq)1025c2c66affSColin Finck void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD time, DWORD seq)
1026c2c66affSColin Finck {
1027c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1028c2c66affSColin Finck     int next_pos, ofs = id_to_offset(&This->data_format, inst_id);
1029c2c66affSColin Finck 
1030c2c66affSColin Finck     /* Event is being set regardless of the queue state */
1031c2c66affSColin Finck     if (This->hEvent) SetEvent(This->hEvent);
1032c2c66affSColin Finck 
1033ad21be5eSAmine Khaldi     PostMessageW(GetDesktopWindow(), WM_WINE_NOTIFY_ACTIVITY, 0, 0);
1034ad21be5eSAmine Khaldi 
1035c2c66affSColin Finck     if (!This->queue_len || This->overflow || ofs < 0) return;
1036c2c66affSColin Finck 
1037c2c66affSColin Finck     next_pos = (This->queue_head + 1) % This->queue_len;
1038c2c66affSColin Finck     if (next_pos == This->queue_tail)
1039c2c66affSColin Finck     {
1040c2c66affSColin Finck         TRACE(" queue overflowed\n");
1041c2c66affSColin Finck         This->overflow = TRUE;
1042c2c66affSColin Finck         return;
1043c2c66affSColin Finck     }
1044c2c66affSColin Finck 
1045c2c66affSColin Finck     TRACE(" queueing %d at offset %d (queue head %d / size %d)\n",
1046c2c66affSColin Finck           data, ofs, This->queue_head, This->queue_len);
1047c2c66affSColin Finck 
1048c2c66affSColin Finck     This->data_queue[This->queue_head].dwOfs       = ofs;
1049c2c66affSColin Finck     This->data_queue[This->queue_head].dwData      = data;
1050c2c66affSColin Finck     This->data_queue[This->queue_head].dwTimeStamp = time;
1051c2c66affSColin Finck     This->data_queue[This->queue_head].dwSequence  = seq;
1052c2c66affSColin Finck 
1053c2c66affSColin Finck     /* Set uAppData by means of action mapping */
1054c2c66affSColin Finck     if (This->num_actions > 0)
1055c2c66affSColin Finck     {
1056c2c66affSColin Finck         int i;
1057c2c66affSColin Finck         for (i=0; i < This->num_actions; i++)
1058c2c66affSColin Finck         {
1059c2c66affSColin Finck             if (This->action_map[i].offset == ofs)
1060c2c66affSColin Finck             {
1061c2c66affSColin Finck                 TRACE("Offset %d mapped to uAppData %lu\n", ofs, This->action_map[i].uAppData);
1062c2c66affSColin Finck                 This->data_queue[This->queue_head].uAppData = This->action_map[i].uAppData;
1063c2c66affSColin Finck                 break;
1064c2c66affSColin Finck             }
1065c2c66affSColin Finck         }
1066c2c66affSColin Finck     }
1067c2c66affSColin Finck 
1068c2c66affSColin Finck     This->queue_head = next_pos;
1069c2c66affSColin Finck     /* Send event if asked */
1070c2c66affSColin Finck }
1071c2c66affSColin Finck 
1072c2c66affSColin Finck /******************************************************************************
1073c2c66affSColin Finck  *	Acquire
1074c2c66affSColin Finck  */
1075c2c66affSColin Finck 
IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)1076c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
1077c2c66affSColin Finck {
1078c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1079c2c66affSColin Finck     HRESULT res;
1080c2c66affSColin Finck 
1081c2c66affSColin Finck     TRACE("(%p)\n", This);
1082c2c66affSColin Finck 
1083c2c66affSColin Finck     if (!This->data_format.user_df) return DIERR_INVALIDPARAM;
1084c2c66affSColin Finck     if (This->dwCoopLevel & DISCL_FOREGROUND && This->win != GetForegroundWindow())
1085c2c66affSColin Finck         return DIERR_OTHERAPPHASPRIO;
1086c2c66affSColin Finck 
1087c2c66affSColin Finck     EnterCriticalSection(&This->crit);
1088c2c66affSColin Finck     res = This->acquired ? S_FALSE : DI_OK;
1089c2c66affSColin Finck     This->acquired = 1;
10900b35adc2SAmine Khaldi     LeaveCriticalSection(&This->crit);
10917016dd6dSAmine Khaldi     if (res == DI_OK)
10927016dd6dSAmine Khaldi         check_dinput_hooks(iface, TRUE);
1093c2c66affSColin Finck 
1094c2c66affSColin Finck     return res;
1095c2c66affSColin Finck }
1096c2c66affSColin Finck 
IDirectInputDevice2AImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)1097c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
1098c2c66affSColin Finck {
1099c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1100c2c66affSColin Finck     return IDirectInputDevice2WImpl_Acquire(IDirectInputDevice8W_from_impl(This));
1101c2c66affSColin Finck }
1102c2c66affSColin Finck 
1103c2c66affSColin Finck 
1104c2c66affSColin Finck /******************************************************************************
1105c2c66affSColin Finck  *	Unacquire
1106c2c66affSColin Finck  */
1107c2c66affSColin Finck 
IDirectInputDevice2WImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)1108c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
1109c2c66affSColin Finck {
1110c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1111c2c66affSColin Finck     HRESULT res;
1112c2c66affSColin Finck 
1113c2c66affSColin Finck     TRACE("(%p)\n", This);
1114c2c66affSColin Finck 
1115c2c66affSColin Finck     EnterCriticalSection(&This->crit);
1116c2c66affSColin Finck     res = !This->acquired ? DI_NOEFFECT : DI_OK;
1117c2c66affSColin Finck     This->acquired = 0;
11180b35adc2SAmine Khaldi     LeaveCriticalSection(&This->crit);
11197016dd6dSAmine Khaldi     if (res == DI_OK)
11207016dd6dSAmine Khaldi         check_dinput_hooks(iface, FALSE);
1121c2c66affSColin Finck 
1122c2c66affSColin Finck     return res;
1123c2c66affSColin Finck }
1124c2c66affSColin Finck 
IDirectInputDevice2AImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)1125c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
1126c2c66affSColin Finck {
1127c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1128c2c66affSColin Finck     return IDirectInputDevice2WImpl_Unacquire(IDirectInputDevice8W_from_impl(This));
1129c2c66affSColin Finck }
1130c2c66affSColin Finck 
1131c2c66affSColin Finck /******************************************************************************
1132c2c66affSColin Finck  *	IDirectInputDeviceA
1133c2c66affSColin Finck  */
1134c2c66affSColin Finck 
IDirectInputDevice2WImpl_SetDataFormat(LPDIRECTINPUTDEVICE8W iface,LPCDIDATAFORMAT df)1135c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_SetDataFormat(LPDIRECTINPUTDEVICE8W iface, LPCDIDATAFORMAT df)
1136c2c66affSColin Finck {
1137c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1138c2c66affSColin Finck     HRESULT res = DI_OK;
1139c2c66affSColin Finck 
1140c2c66affSColin Finck     if (!df) return E_POINTER;
1141c2c66affSColin Finck     TRACE("(%p) %p\n", This, df);
1142c2c66affSColin Finck     _dump_DIDATAFORMAT(df);
1143c2c66affSColin Finck 
1144c2c66affSColin Finck     if (df->dwSize != sizeof(DIDATAFORMAT)) return DIERR_INVALIDPARAM;
1145c2c66affSColin Finck     if (This->acquired) return DIERR_ACQUIRED;
1146c2c66affSColin Finck 
1147c2c66affSColin Finck     EnterCriticalSection(&This->crit);
1148c2c66affSColin Finck 
1149c2c66affSColin Finck     release_DataFormat(&This->data_format);
1150c2c66affSColin Finck     res = create_DataFormat(df, &This->data_format);
1151c2c66affSColin Finck 
1152c2c66affSColin Finck     LeaveCriticalSection(&This->crit);
1153c2c66affSColin Finck     return res;
1154c2c66affSColin Finck }
1155c2c66affSColin Finck 
IDirectInputDevice2AImpl_SetDataFormat(LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df)1156c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(LPDIRECTINPUTDEVICE8A iface, LPCDIDATAFORMAT df)
1157c2c66affSColin Finck {
1158c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1159c2c66affSColin Finck     return IDirectInputDevice2WImpl_SetDataFormat(IDirectInputDevice8W_from_impl(This), df);
1160c2c66affSColin Finck }
1161c2c66affSColin Finck 
1162c2c66affSColin Finck /******************************************************************************
1163c2c66affSColin Finck   *     SetCooperativeLevel
1164c2c66affSColin Finck   *
1165c2c66affSColin Finck   *  Set cooperative level and the source window for the events.
1166c2c66affSColin Finck   */
IDirectInputDevice2WImpl_SetCooperativeLevel(LPDIRECTINPUTDEVICE8W iface,HWND hwnd,DWORD dwflags)1167c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_SetCooperativeLevel(LPDIRECTINPUTDEVICE8W iface, HWND hwnd, DWORD dwflags)
1168c2c66affSColin Finck {
1169c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1170c2c66affSColin Finck 
1171c2c66affSColin Finck     TRACE("(%p) %p,0x%08x\n", This, hwnd, dwflags);
1172c2c66affSColin Finck     _dump_cooperativelevel_DI(dwflags);
1173c2c66affSColin Finck 
1174c2c66affSColin Finck     if ((dwflags & (DISCL_EXCLUSIVE | DISCL_NONEXCLUSIVE)) == 0 ||
1175c2c66affSColin Finck         (dwflags & (DISCL_EXCLUSIVE | DISCL_NONEXCLUSIVE)) == (DISCL_EXCLUSIVE | DISCL_NONEXCLUSIVE) ||
1176c2c66affSColin Finck         (dwflags & (DISCL_FOREGROUND | DISCL_BACKGROUND)) == 0 ||
1177c2c66affSColin Finck         (dwflags & (DISCL_FOREGROUND | DISCL_BACKGROUND)) == (DISCL_FOREGROUND | DISCL_BACKGROUND))
1178c2c66affSColin Finck         return DIERR_INVALIDPARAM;
1179c2c66affSColin Finck 
1180c2c66affSColin Finck     if (hwnd && GetWindowLongW(hwnd, GWL_STYLE) & WS_CHILD) return E_HANDLE;
1181c2c66affSColin Finck 
1182c2c66affSColin Finck     if (!hwnd && dwflags == (DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))
1183c2c66affSColin Finck         hwnd = GetDesktopWindow();
1184c2c66affSColin Finck 
1185c2c66affSColin Finck     if (!IsWindow(hwnd)) return E_HANDLE;
1186c2c66affSColin Finck 
1187c2c66affSColin Finck     /* For security reasons native does not allow exclusive background level
1188c2c66affSColin Finck        for mouse and keyboard only */
1189c2c66affSColin Finck     if (dwflags & DISCL_EXCLUSIVE && dwflags & DISCL_BACKGROUND &&
1190c2c66affSColin Finck         (IsEqualGUID(&This->guid, &GUID_SysMouse) ||
1191c2c66affSColin Finck          IsEqualGUID(&This->guid, &GUID_SysKeyboard)))
1192c2c66affSColin Finck         return DIERR_UNSUPPORTED;
1193c2c66affSColin Finck 
1194c2c66affSColin Finck     /* Store the window which asks for the mouse */
1195c2c66affSColin Finck     EnterCriticalSection(&This->crit);
1196c2c66affSColin Finck     This->win = hwnd;
1197c2c66affSColin Finck     This->dwCoopLevel = dwflags;
1198c2c66affSColin Finck     LeaveCriticalSection(&This->crit);
1199c2c66affSColin Finck 
1200c2c66affSColin Finck     return DI_OK;
1201c2c66affSColin Finck }
1202c2c66affSColin Finck 
IDirectInputDevice2AImpl_SetCooperativeLevel(LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags)1203c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(LPDIRECTINPUTDEVICE8A iface, HWND hwnd, DWORD dwflags)
1204c2c66affSColin Finck {
1205c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1206c2c66affSColin Finck     return IDirectInputDevice2WImpl_SetCooperativeLevel(IDirectInputDevice8W_from_impl(This), hwnd, dwflags);
1207c2c66affSColin Finck }
1208c2c66affSColin Finck 
1209c2c66affSColin Finck /******************************************************************************
1210c2c66affSColin Finck   *     SetEventNotification : specifies event to be sent on state change
1211c2c66affSColin Finck   */
IDirectInputDevice2WImpl_SetEventNotification(LPDIRECTINPUTDEVICE8W iface,HANDLE event)1212c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_SetEventNotification(LPDIRECTINPUTDEVICE8W iface, HANDLE event)
1213c2c66affSColin Finck {
1214c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1215c2c66affSColin Finck 
1216c2c66affSColin Finck     TRACE("(%p) %p\n", This, event);
1217c2c66affSColin Finck 
1218c2c66affSColin Finck     EnterCriticalSection(&This->crit);
1219c2c66affSColin Finck     This->hEvent = event;
1220c2c66affSColin Finck     LeaveCriticalSection(&This->crit);
1221c2c66affSColin Finck     return DI_OK;
1222c2c66affSColin Finck }
1223c2c66affSColin Finck 
IDirectInputDevice2AImpl_SetEventNotification(LPDIRECTINPUTDEVICE8A iface,HANDLE event)1224c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(LPDIRECTINPUTDEVICE8A iface, HANDLE event)
1225c2c66affSColin Finck {
1226c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1227c2c66affSColin Finck     return IDirectInputDevice2WImpl_SetEventNotification(IDirectInputDevice8W_from_impl(This), event);
1228c2c66affSColin Finck }
1229c2c66affSColin Finck 
1230c2c66affSColin Finck 
IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)1231c2c66affSColin Finck ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
1232c2c66affSColin Finck {
1233c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1234c2c66affSColin Finck     ULONG ref = InterlockedDecrement(&(This->ref));
1235c2c66affSColin Finck 
1236*41c8c312SAmine Khaldi     TRACE("(%p) ref %d\n", This, ref);
1237c2c66affSColin Finck 
1238c2c66affSColin Finck     if (ref) return ref;
1239c2c66affSColin Finck 
1240c2c66affSColin Finck     IDirectInputDevice_Unacquire(iface);
1241c2c66affSColin Finck     /* Reset the FF state, free all effects, etc */
1242c2c66affSColin Finck     IDirectInputDevice8_SendForceFeedbackCommand(iface, DISFFC_RESET);
1243c2c66affSColin Finck 
1244c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, This->data_queue);
1245c2c66affSColin Finck 
1246c2c66affSColin Finck     /* Free data format */
1247c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, This->data_format.wine_df->rgodf);
1248c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, This->data_format.wine_df);
1249c2c66affSColin Finck     release_DataFormat(&This->data_format);
1250c2c66affSColin Finck 
1251c2c66affSColin Finck     /* Free action mapping */
1252c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, This->action_map);
1253c2c66affSColin Finck 
1254c2c66affSColin Finck     EnterCriticalSection( &This->dinput->crit );
1255c2c66affSColin Finck     list_remove( &This->entry );
1256c2c66affSColin Finck     LeaveCriticalSection( &This->dinput->crit );
1257c2c66affSColin Finck 
1258c2c66affSColin Finck     IDirectInput_Release(&This->dinput->IDirectInput7A_iface);
1259c2c66affSColin Finck     This->crit.DebugInfo->Spare[0] = 0;
1260c2c66affSColin Finck     DeleteCriticalSection(&This->crit);
1261c2c66affSColin Finck 
1262c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, This);
1263c2c66affSColin Finck 
1264*41c8c312SAmine Khaldi     return ref;
1265c2c66affSColin Finck }
1266c2c66affSColin Finck 
IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)1267c2c66affSColin Finck ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)
1268c2c66affSColin Finck {
1269c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1270c2c66affSColin Finck     return IDirectInputDevice2WImpl_Release(IDirectInputDevice8W_from_impl(This));
1271c2c66affSColin Finck }
1272c2c66affSColin Finck 
IDirectInputDevice2WImpl_QueryInterface(LPDIRECTINPUTDEVICE8W iface,REFIID riid,LPVOID * ppobj)1273c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(LPDIRECTINPUTDEVICE8W iface, REFIID riid, LPVOID *ppobj)
1274c2c66affSColin Finck {
1275c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1276c2c66affSColin Finck 
1277*41c8c312SAmine Khaldi     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppobj);
1278c2c66affSColin Finck     if (IsEqualGUID(&IID_IUnknown, riid) ||
1279c2c66affSColin Finck         IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
1280c2c66affSColin Finck         IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
1281c2c66affSColin Finck         IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
1282c2c66affSColin Finck         IsEqualGUID(&IID_IDirectInputDevice8A, riid))
1283c2c66affSColin Finck     {
1284c2c66affSColin Finck         IDirectInputDevice2_AddRef(iface);
1285c2c66affSColin Finck         *ppobj = IDirectInputDevice8A_from_impl(This);
1286c2c66affSColin Finck         return DI_OK;
1287c2c66affSColin Finck     }
1288c2c66affSColin Finck     if (IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
1289c2c66affSColin Finck         IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
1290c2c66affSColin Finck         IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
1291c2c66affSColin Finck         IsEqualGUID(&IID_IDirectInputDevice8W, riid))
1292c2c66affSColin Finck     {
1293c2c66affSColin Finck         IDirectInputDevice2_AddRef(iface);
1294c2c66affSColin Finck         *ppobj = IDirectInputDevice8W_from_impl(This);
1295c2c66affSColin Finck         return DI_OK;
1296c2c66affSColin Finck     }
1297c2c66affSColin Finck 
1298c2c66affSColin Finck     WARN("Unsupported interface!\n");
1299*41c8c312SAmine Khaldi     return E_NOINTERFACE;
1300c2c66affSColin Finck }
1301c2c66affSColin Finck 
IDirectInputDevice2AImpl_QueryInterface(LPDIRECTINPUTDEVICE8A iface,REFIID riid,LPVOID * ppobj)1302c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(LPDIRECTINPUTDEVICE8A iface, REFIID riid, LPVOID *ppobj)
1303c2c66affSColin Finck {
1304c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1305c2c66affSColin Finck     return IDirectInputDevice2WImpl_QueryInterface(IDirectInputDevice8W_from_impl(This), riid, ppobj);
1306c2c66affSColin Finck }
1307c2c66affSColin Finck 
IDirectInputDevice2WImpl_AddRef(LPDIRECTINPUTDEVICE8W iface)1308c2c66affSColin Finck ULONG WINAPI IDirectInputDevice2WImpl_AddRef(LPDIRECTINPUTDEVICE8W iface)
1309c2c66affSColin Finck {
1310c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1311*41c8c312SAmine Khaldi     ULONG ref = InterlockedIncrement(&This->ref);
1312*41c8c312SAmine Khaldi     TRACE( "(%p) ref %d\n", This, ref );
1313*41c8c312SAmine Khaldi     return ref;
1314c2c66affSColin Finck }
1315c2c66affSColin Finck 
IDirectInputDevice2AImpl_AddRef(LPDIRECTINPUTDEVICE8A iface)1316c2c66affSColin Finck ULONG WINAPI IDirectInputDevice2AImpl_AddRef(LPDIRECTINPUTDEVICE8A iface)
1317c2c66affSColin Finck {
1318c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1319c2c66affSColin Finck     return IDirectInputDevice2WImpl_AddRef(IDirectInputDevice8W_from_impl(This));
1320c2c66affSColin Finck }
1321c2c66affSColin Finck 
IDirectInputDevice2AImpl_EnumObjects(LPDIRECTINPUTDEVICE8A iface,LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,LPVOID lpvRef,DWORD dwFlags)1322c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(LPDIRECTINPUTDEVICE8A iface,
1323c2c66affSColin Finck         LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID lpvRef, DWORD dwFlags)
1324c2c66affSColin Finck {
1325c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1326c2c66affSColin Finck     DIDEVICEOBJECTINSTANCEA ddoi;
1327c2c66affSColin Finck     int i;
1328c2c66affSColin Finck 
1329*41c8c312SAmine Khaldi     TRACE("(%p)->(%p,%p flags:%08x)\n", This, lpCallback, lpvRef, dwFlags);
1330c2c66affSColin Finck     TRACE("  - flags = ");
1331c2c66affSColin Finck     _dump_EnumObjects_flags(dwFlags);
1332c2c66affSColin Finck     TRACE("\n");
1333c2c66affSColin Finck 
1334c2c66affSColin Finck     /* Only the fields till dwFFMaxForce are relevant */
1335c2c66affSColin Finck     memset(&ddoi, 0, sizeof(ddoi));
1336c2c66affSColin Finck     ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce);
1337c2c66affSColin Finck 
1338c2c66affSColin Finck     for (i = 0; i < This->data_format.wine_df->dwNumObjs; i++)
1339c2c66affSColin Finck     {
1340c2c66affSColin Finck         LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(This->data_format.wine_df, i);
1341c2c66affSColin Finck 
1342c2c66affSColin Finck         if (dwFlags != DIDFT_ALL && !(dwFlags & DIDFT_GETTYPE(odf->dwType))) continue;
1343c2c66affSColin Finck         if (IDirectInputDevice_GetObjectInfo(iface, &ddoi, odf->dwType, DIPH_BYID) != DI_OK)
1344c2c66affSColin Finck             continue;
1345c2c66affSColin Finck 
1346c2c66affSColin Finck 	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) break;
1347c2c66affSColin Finck     }
1348c2c66affSColin Finck 
1349c2c66affSColin Finck     return DI_OK;
1350c2c66affSColin Finck }
1351c2c66affSColin Finck 
IDirectInputDevice2WImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface,LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,LPVOID lpvRef,DWORD dwFlags)1352c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface,
1353c2c66affSColin Finck         LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID lpvRef, DWORD dwFlags)
1354c2c66affSColin Finck {
1355c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1356c2c66affSColin Finck     DIDEVICEOBJECTINSTANCEW ddoi;
1357c2c66affSColin Finck     int i;
1358c2c66affSColin Finck 
1359*41c8c312SAmine Khaldi     TRACE("(%p)->(%p,%p flags:%08x)\n", This, lpCallback, lpvRef, dwFlags);
1360c2c66affSColin Finck     TRACE("  - flags = ");
1361c2c66affSColin Finck     _dump_EnumObjects_flags(dwFlags);
1362c2c66affSColin Finck     TRACE("\n");
1363c2c66affSColin Finck 
1364c2c66affSColin Finck     /* Only the fields till dwFFMaxForce are relevant */
1365c2c66affSColin Finck     memset(&ddoi, 0, sizeof(ddoi));
1366c2c66affSColin Finck     ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEW, dwFFMaxForce);
1367c2c66affSColin Finck 
1368c2c66affSColin Finck     for (i = 0; i < This->data_format.wine_df->dwNumObjs; i++)
1369c2c66affSColin Finck     {
1370c2c66affSColin Finck         LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(This->data_format.wine_df, i);
1371c2c66affSColin Finck 
1372c2c66affSColin Finck         if (dwFlags != DIDFT_ALL && !(dwFlags & DIDFT_GETTYPE(odf->dwType))) continue;
1373c2c66affSColin Finck         if (IDirectInputDevice_GetObjectInfo(iface, &ddoi, odf->dwType, DIPH_BYID) != DI_OK)
1374c2c66affSColin Finck             continue;
1375c2c66affSColin Finck 
1376c2c66affSColin Finck 	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) break;
1377c2c66affSColin Finck     }
1378c2c66affSColin Finck 
1379c2c66affSColin Finck     return DI_OK;
1380c2c66affSColin Finck }
1381c2c66affSColin Finck 
1382c2c66affSColin Finck /******************************************************************************
1383c2c66affSColin Finck  *	GetProperty
1384c2c66affSColin Finck  */
1385c2c66affSColin Finck 
IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface,REFGUID rguid,LPDIPROPHEADER pdiph)1386c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
1387c2c66affSColin Finck {
1388c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1389c2c66affSColin Finck 
1390*41c8c312SAmine Khaldi     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph);
1391c2c66affSColin Finck     _dump_DIPROPHEADER(pdiph);
1392c2c66affSColin Finck 
1393c2c66affSColin Finck     if (!IS_DIPROP(rguid)) return DI_OK;
1394c2c66affSColin Finck 
1395c2c66affSColin Finck     switch (LOWORD(rguid))
1396c2c66affSColin Finck     {
1397c2c66affSColin Finck         case (DWORD_PTR) DIPROP_BUFFERSIZE:
1398c2c66affSColin Finck         {
1399c2c66affSColin Finck             LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
1400c2c66affSColin Finck 
1401c2c66affSColin Finck             if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
1402c2c66affSColin Finck 
1403c2c66affSColin Finck             pd->dwData = This->queue_len;
1404c2c66affSColin Finck             TRACE("buffersize = %d\n", pd->dwData);
1405c2c66affSColin Finck             break;
1406c2c66affSColin Finck         }
1407c2c66affSColin Finck         case (DWORD_PTR) DIPROP_USERNAME:
1408c2c66affSColin Finck         {
1409c2c66affSColin Finck             LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph;
1410c2c66affSColin Finck             struct DevicePlayer *device_player;
1411c2c66affSColin Finck 
1412c2c66affSColin Finck             if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
1413c2c66affSColin Finck 
1414c2c66affSColin Finck             LIST_FOR_EACH_ENTRY(device_player, &This->dinput->device_players,
1415c2c66affSColin Finck                 struct DevicePlayer, entry)
1416c2c66affSColin Finck             {
1417c2c66affSColin Finck                 if (IsEqualGUID(&device_player->instance_guid, &This->guid))
1418c2c66affSColin Finck                 {
1419c2c66affSColin Finck                     if (*device_player->username)
1420c2c66affSColin Finck                     {
142198e62237SAmine Khaldi                         lstrcpynW(ps->wsz, device_player->username, ARRAY_SIZE(ps->wsz));
1422c2c66affSColin Finck                         return DI_OK;
1423c2c66affSColin Finck                     }
1424c2c66affSColin Finck                     else break;
1425c2c66affSColin Finck                 }
1426c2c66affSColin Finck             }
1427c2c66affSColin Finck             return S_FALSE;
1428c2c66affSColin Finck         }
1429c2c66affSColin Finck         case (DWORD_PTR) DIPROP_VIDPID:
1430c2c66affSColin Finck             FIXME("DIPROP_VIDPID not implemented\n");
1431c2c66affSColin Finck             return DIERR_UNSUPPORTED;
1432c2c66affSColin Finck         default:
1433c2c66affSColin Finck             FIXME("Unknown property %s\n", debugstr_guid(rguid));
1434c2c66affSColin Finck             return DIERR_INVALIDPARAM;
1435c2c66affSColin Finck     }
1436c2c66affSColin Finck 
1437c2c66affSColin Finck     return DI_OK;
1438c2c66affSColin Finck }
1439c2c66affSColin Finck 
IDirectInputDevice2AImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,REFGUID rguid,LPDIPROPHEADER pdiph)1440c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph)
1441c2c66affSColin Finck {
1442c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1443c2c66affSColin Finck     return IDirectInputDevice2WImpl_GetProperty(IDirectInputDevice8W_from_impl(This), rguid, pdiph);
1444c2c66affSColin Finck }
1445c2c66affSColin Finck 
1446c2c66affSColin Finck /******************************************************************************
1447c2c66affSColin Finck  *	SetProperty
1448c2c66affSColin Finck  */
1449c2c66affSColin Finck 
IDirectInputDevice2WImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface,REFGUID rguid,LPCDIPROPHEADER pdiph)1450c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty(
1451c2c66affSColin Finck         LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIPROPHEADER pdiph)
1452c2c66affSColin Finck {
1453c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1454c2c66affSColin Finck 
1455*41c8c312SAmine Khaldi     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph);
1456c2c66affSColin Finck     _dump_DIPROPHEADER(pdiph);
1457c2c66affSColin Finck 
1458c2c66affSColin Finck     if (!IS_DIPROP(rguid)) return DI_OK;
1459c2c66affSColin Finck 
1460c2c66affSColin Finck     switch (LOWORD(rguid))
1461c2c66affSColin Finck     {
1462c2c66affSColin Finck         case (DWORD_PTR) DIPROP_AXISMODE:
1463c2c66affSColin Finck         {
1464c2c66affSColin Finck             LPCDIPROPDWORD pd = (LPCDIPROPDWORD)pdiph;
1465c2c66affSColin Finck 
1466c2c66affSColin Finck             if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
1467c2c66affSColin Finck             if (pdiph->dwHow == DIPH_DEVICE && pdiph->dwObj) return DIERR_INVALIDPARAM;
1468c2c66affSColin Finck             if (This->acquired) return DIERR_ACQUIRED;
1469c2c66affSColin Finck             if (pdiph->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED;
1470c2c66affSColin Finck             if (!This->data_format.user_df) return DI_OK;
1471c2c66affSColin Finck 
1472c2c66affSColin Finck             TRACE("Axis mode: %s\n", pd->dwData == DIPROPAXISMODE_ABS ? "absolute" :
1473c2c66affSColin Finck                                                                         "relative");
1474c2c66affSColin Finck 
1475c2c66affSColin Finck             EnterCriticalSection(&This->crit);
1476c2c66affSColin Finck             This->data_format.user_df->dwFlags &= ~DIDFT_AXIS;
1477c2c66affSColin Finck             This->data_format.user_df->dwFlags |= pd->dwData == DIPROPAXISMODE_ABS ?
1478c2c66affSColin Finck                                                   DIDF_ABSAXIS : DIDF_RELAXIS;
1479c2c66affSColin Finck             LeaveCriticalSection(&This->crit);
1480c2c66affSColin Finck             break;
1481c2c66affSColin Finck         }
1482c2c66affSColin Finck         case (DWORD_PTR) DIPROP_BUFFERSIZE:
1483c2c66affSColin Finck         {
1484c2c66affSColin Finck             LPCDIPROPDWORD pd = (LPCDIPROPDWORD)pdiph;
1485c2c66affSColin Finck 
1486c2c66affSColin Finck             if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM;
1487c2c66affSColin Finck             if (This->acquired) return DIERR_ACQUIRED;
1488c2c66affSColin Finck 
1489c2c66affSColin Finck             TRACE("buffersize = %d\n", pd->dwData);
1490c2c66affSColin Finck 
1491c2c66affSColin Finck             EnterCriticalSection(&This->crit);
1492c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, This->data_queue);
1493c2c66affSColin Finck 
1494c2c66affSColin Finck             This->data_queue = !pd->dwData ? NULL : HeapAlloc(GetProcessHeap(), 0,
1495c2c66affSColin Finck                                 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
1496c2c66affSColin Finck             This->queue_head = This->queue_tail = This->overflow = 0;
1497c2c66affSColin Finck             This->queue_len  = pd->dwData;
1498c2c66affSColin Finck 
1499c2c66affSColin Finck             LeaveCriticalSection(&This->crit);
1500c2c66affSColin Finck             break;
1501c2c66affSColin Finck         }
1502c2c66affSColin Finck         case (DWORD_PTR) DIPROP_USERNAME:
1503c2c66affSColin Finck         {
1504c2c66affSColin Finck             LPCDIPROPSTRING ps = (LPCDIPROPSTRING)pdiph;
1505c2c66affSColin Finck             struct DevicePlayer *device_player;
1506c2c66affSColin Finck             BOOL found = FALSE;
1507c2c66affSColin Finck 
1508c2c66affSColin Finck             if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
1509c2c66affSColin Finck 
1510c2c66affSColin Finck             LIST_FOR_EACH_ENTRY(device_player, &This->dinput->device_players,
1511c2c66affSColin Finck                 struct DevicePlayer, entry)
1512c2c66affSColin Finck             {
1513c2c66affSColin Finck                 if (IsEqualGUID(&device_player->instance_guid, &This->guid))
1514c2c66affSColin Finck                 {
1515c2c66affSColin Finck                     found = TRUE;
1516c2c66affSColin Finck                     break;
1517c2c66affSColin Finck                 }
1518c2c66affSColin Finck             }
1519c2c66affSColin Finck             if (!found && (device_player =
1520c2c66affSColin Finck                     HeapAlloc(GetProcessHeap(), 0, sizeof(struct DevicePlayer))))
1521c2c66affSColin Finck             {
1522c2c66affSColin Finck                 list_add_tail(&This->dinput->device_players, &device_player->entry);
1523c2c66affSColin Finck                 device_player->instance_guid = This->guid;
1524c2c66affSColin Finck             }
1525c2c66affSColin Finck             if (device_player)
152698e62237SAmine Khaldi                 lstrcpynW(device_player->username, ps->wsz, ARRAY_SIZE(device_player->username));
1527c2c66affSColin Finck             break;
1528c2c66affSColin Finck         }
1529c2c66affSColin Finck         default:
1530c2c66affSColin Finck             WARN("Unknown property %s\n", debugstr_guid(rguid));
1531c2c66affSColin Finck             return DIERR_UNSUPPORTED;
1532c2c66affSColin Finck     }
1533c2c66affSColin Finck 
1534c2c66affSColin Finck     return DI_OK;
1535c2c66affSColin Finck }
1536c2c66affSColin Finck 
IDirectInputDevice2AImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,REFGUID rguid,LPCDIPROPHEADER pdiph)1537c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_SetProperty(
1538c2c66affSColin Finck         LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIPROPHEADER pdiph)
1539c2c66affSColin Finck {
1540c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1541c2c66affSColin Finck     return IDirectInputDevice2WImpl_SetProperty(IDirectInputDevice8W_from_impl(This), rguid, pdiph);
1542c2c66affSColin Finck }
1543c2c66affSColin Finck 
IDirectInputDevice2AImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8A iface,LPDIDEVICEOBJECTINSTANCEA pdidoi,DWORD dwObj,DWORD dwHow)1544c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
1545c2c66affSColin Finck 	LPDIRECTINPUTDEVICE8A iface,
1546c2c66affSColin Finck 	LPDIDEVICEOBJECTINSTANCEA pdidoi,
1547c2c66affSColin Finck 	DWORD dwObj,
1548c2c66affSColin Finck 	DWORD dwHow)
1549c2c66affSColin Finck {
1550c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1551c2c66affSColin Finck     DIDEVICEOBJECTINSTANCEW didoiW;
1552c2c66affSColin Finck     HRESULT res;
1553c2c66affSColin Finck 
1554c2c66affSColin Finck     if (!pdidoi ||
1555c2c66affSColin Finck         (pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCEA) &&
1556c2c66affSColin Finck          pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3A)))
1557c2c66affSColin Finck         return DIERR_INVALIDPARAM;
1558c2c66affSColin Finck 
1559c2c66affSColin Finck     didoiW.dwSize = sizeof(didoiW);
1560c2c66affSColin Finck     res = IDirectInputDevice2WImpl_GetObjectInfo(IDirectInputDevice8W_from_impl(This), &didoiW, dwObj, dwHow);
1561c2c66affSColin Finck     if (res == DI_OK)
1562c2c66affSColin Finck     {
1563c2c66affSColin Finck         DWORD dwSize = pdidoi->dwSize;
1564c2c66affSColin Finck 
1565c2c66affSColin Finck         memset(pdidoi, 0, pdidoi->dwSize);
1566c2c66affSColin Finck         pdidoi->dwSize   = dwSize;
1567c2c66affSColin Finck         pdidoi->guidType = didoiW.guidType;
1568c2c66affSColin Finck         pdidoi->dwOfs    = didoiW.dwOfs;
1569c2c66affSColin Finck         pdidoi->dwType   = didoiW.dwType;
1570c2c66affSColin Finck         pdidoi->dwFlags  = didoiW.dwFlags;
1571c2c66affSColin Finck     }
1572c2c66affSColin Finck 
1573c2c66affSColin Finck     return res;
1574c2c66affSColin Finck }
1575c2c66affSColin Finck 
IDirectInputDevice2WImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,LPDIDEVICEOBJECTINSTANCEW pdidoi,DWORD dwObj,DWORD dwHow)1576c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(
1577c2c66affSColin Finck 	LPDIRECTINPUTDEVICE8W iface,
1578c2c66affSColin Finck 	LPDIDEVICEOBJECTINSTANCEW pdidoi,
1579c2c66affSColin Finck 	DWORD dwObj,
1580c2c66affSColin Finck 	DWORD dwHow)
1581c2c66affSColin Finck {
1582c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1583c2c66affSColin Finck     DWORD dwSize;
1584c2c66affSColin Finck     LPDIOBJECTDATAFORMAT odf;
1585c2c66affSColin Finck     int idx = -1;
1586c2c66affSColin Finck 
1587c2c66affSColin Finck     TRACE("(%p) %d(0x%08x) -> %p\n", This, dwHow, dwObj, pdidoi);
1588c2c66affSColin Finck 
1589c2c66affSColin Finck     if (!pdidoi ||
1590c2c66affSColin Finck         (pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCEW) &&
1591c2c66affSColin Finck          pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3W)))
1592c2c66affSColin Finck         return DIERR_INVALIDPARAM;
1593c2c66affSColin Finck 
1594c2c66affSColin Finck     switch (dwHow)
1595c2c66affSColin Finck     {
1596c2c66affSColin Finck     case DIPH_BYOFFSET:
1597c2c66affSColin Finck         if (!This->data_format.offsets) break;
1598c2c66affSColin Finck         for (idx = This->data_format.wine_df->dwNumObjs - 1; idx >= 0; idx--)
1599c2c66affSColin Finck             if (This->data_format.offsets[idx] == dwObj) break;
1600c2c66affSColin Finck         break;
1601c2c66affSColin Finck     case DIPH_BYID:
1602c2c66affSColin Finck         dwObj &= 0x00ffffff;
1603c2c66affSColin Finck         for (idx = This->data_format.wine_df->dwNumObjs - 1; idx >= 0; idx--)
1604c2c66affSColin Finck             if ((dataformat_to_odf(This->data_format.wine_df, idx)->dwType & 0x00ffffff) == dwObj)
1605c2c66affSColin Finck                 break;
1606c2c66affSColin Finck         break;
1607c2c66affSColin Finck 
1608c2c66affSColin Finck     case DIPH_BYUSAGE:
1609c2c66affSColin Finck         FIXME("dwHow = DIPH_BYUSAGE not implemented\n");
1610c2c66affSColin Finck         break;
1611c2c66affSColin Finck     default:
1612c2c66affSColin Finck         WARN("invalid parameter: dwHow = %08x\n", dwHow);
1613c2c66affSColin Finck         return DIERR_INVALIDPARAM;
1614c2c66affSColin Finck     }
1615c2c66affSColin Finck     if (idx < 0) return DIERR_OBJECTNOTFOUND;
1616c2c66affSColin Finck 
1617c2c66affSColin Finck     odf = dataformat_to_odf(This->data_format.wine_df, idx);
1618c2c66affSColin Finck     dwSize = pdidoi->dwSize; /* save due to memset below */
1619c2c66affSColin Finck     memset(pdidoi, 0, pdidoi->dwSize);
1620c2c66affSColin Finck     pdidoi->dwSize   = dwSize;
1621c2c66affSColin Finck     if (odf->pguid) pdidoi->guidType = *odf->pguid;
1622c2c66affSColin Finck     pdidoi->dwOfs    = This->data_format.offsets ? This->data_format.offsets[idx] : odf->dwOfs;
1623c2c66affSColin Finck     pdidoi->dwType   = odf->dwType;
1624c2c66affSColin Finck     pdidoi->dwFlags  = odf->dwFlags;
1625c2c66affSColin Finck 
1626c2c66affSColin Finck     return DI_OK;
1627c2c66affSColin Finck }
1628c2c66affSColin Finck 
IDirectInputDevice2WImpl_GetDeviceData(LPDIRECTINPUTDEVICE8W iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,LPDWORD entries,DWORD flags)1629c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_GetDeviceData(LPDIRECTINPUTDEVICE8W iface, DWORD dodsize,
1630c2c66affSColin Finck                                                       LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags)
1631c2c66affSColin Finck {
1632c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1633c2c66affSColin Finck     HRESULT ret = DI_OK;
1634c2c66affSColin Finck     int len;
1635c2c66affSColin Finck 
1636c2c66affSColin Finck     TRACE("(%p) %p -> %p(%d) x%d, 0x%08x\n",
1637c2c66affSColin Finck           This, dod, entries, entries ? *entries : 0, dodsize, flags);
1638c2c66affSColin Finck 
1639c2c66affSColin Finck     if (This->dinput->dwVersion == 0x0800 || dodsize == sizeof(DIDEVICEOBJECTDATA_DX3))
1640c2c66affSColin Finck     {
1641c2c66affSColin Finck         if (!This->queue_len) return DIERR_NOTBUFFERED;
1642c2c66affSColin Finck         if (!This->acquired) return DIERR_NOTACQUIRED;
1643c2c66affSColin Finck     }
1644c2c66affSColin Finck 
1645c2c66affSColin Finck     if (!This->queue_len)
1646c2c66affSColin Finck         return DI_OK;
1647c2c66affSColin Finck     if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3))
1648c2c66affSColin Finck         return DIERR_INVALIDPARAM;
1649c2c66affSColin Finck 
1650c2c66affSColin Finck     IDirectInputDevice2_Poll(iface);
1651c2c66affSColin Finck     EnterCriticalSection(&This->crit);
1652c2c66affSColin Finck 
1653c2c66affSColin Finck     len = This->queue_head - This->queue_tail;
1654c2c66affSColin Finck     if (len < 0) len += This->queue_len;
1655c2c66affSColin Finck 
1656c2c66affSColin Finck     if ((*entries != INFINITE) && (len > *entries)) len = *entries;
1657c2c66affSColin Finck 
1658c2c66affSColin Finck     if (dod)
1659c2c66affSColin Finck     {
1660c2c66affSColin Finck         int i;
1661c2c66affSColin Finck         for (i = 0; i < len; i++)
1662c2c66affSColin Finck         {
1663c2c66affSColin Finck             int n = (This->queue_tail + i) % This->queue_len;
1664c2c66affSColin Finck             memcpy((char *)dod + dodsize * i, This->data_queue + n, dodsize);
1665c2c66affSColin Finck         }
1666c2c66affSColin Finck     }
1667c2c66affSColin Finck     *entries = len;
1668c2c66affSColin Finck 
1669c2c66affSColin Finck     if (This->overflow && This->dinput->dwVersion == 0x0800)
1670c2c66affSColin Finck         ret = DI_BUFFEROVERFLOW;
1671c2c66affSColin Finck 
1672c2c66affSColin Finck     if (!(flags & DIGDD_PEEK))
1673c2c66affSColin Finck     {
1674c2c66affSColin Finck         /* Advance reading position */
1675c2c66affSColin Finck         This->queue_tail = (This->queue_tail + len) % This->queue_len;
1676c2c66affSColin Finck         This->overflow = FALSE;
1677c2c66affSColin Finck     }
1678c2c66affSColin Finck 
1679c2c66affSColin Finck     LeaveCriticalSection(&This->crit);
1680c2c66affSColin Finck 
1681c2c66affSColin Finck     TRACE("Returning %d events queued\n", *entries);
1682c2c66affSColin Finck     return ret;
1683c2c66affSColin Finck }
1684c2c66affSColin Finck 
IDirectInputDevice2AImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,LPDWORD entries,DWORD flags)1685c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface, DWORD dodsize,
1686c2c66affSColin Finck                                                       LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags)
1687c2c66affSColin Finck {
1688c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1689c2c66affSColin Finck     return IDirectInputDevice2WImpl_GetDeviceData(IDirectInputDevice8W_from_impl(This), dodsize, dod, entries, flags);
1690c2c66affSColin Finck }
1691c2c66affSColin Finck 
IDirectInputDevice2WImpl_RunControlPanel(LPDIRECTINPUTDEVICE8W iface,HWND hwndOwner,DWORD dwFlags)1692c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_RunControlPanel(LPDIRECTINPUTDEVICE8W iface, HWND hwndOwner, DWORD dwFlags)
1693c2c66affSColin Finck {
1694*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1695*41c8c312SAmine Khaldi     FIXME("%p)->(%p,0x%08x): stub!\n", This, hwndOwner, dwFlags);
1696c2c66affSColin Finck 
1697c2c66affSColin Finck     return DI_OK;
1698c2c66affSColin Finck }
1699c2c66affSColin Finck 
IDirectInputDevice2AImpl_RunControlPanel(LPDIRECTINPUTDEVICE8A iface,HWND hwndOwner,DWORD dwFlags)1700c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(LPDIRECTINPUTDEVICE8A iface, HWND hwndOwner, DWORD dwFlags)
1701c2c66affSColin Finck {
1702c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1703c2c66affSColin Finck     return IDirectInputDevice2WImpl_RunControlPanel(IDirectInputDevice8W_from_impl(This), hwndOwner, dwFlags);
1704c2c66affSColin Finck }
1705c2c66affSColin Finck 
IDirectInputDevice2WImpl_Initialize(LPDIRECTINPUTDEVICE8W iface,HINSTANCE hinst,DWORD dwVersion,REFGUID rguid)1706c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_Initialize(LPDIRECTINPUTDEVICE8W iface, HINSTANCE hinst, DWORD dwVersion,
1707c2c66affSColin Finck                                                    REFGUID rguid)
1708c2c66affSColin Finck {
1709*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1710*41c8c312SAmine Khaldi     FIXME("(%p)->(%p,%d,%s): stub!\n", This, hinst, dwVersion, debugstr_guid(rguid));
1711c2c66affSColin Finck     return DI_OK;
1712c2c66affSColin Finck }
1713c2c66affSColin Finck 
IDirectInputDevice2AImpl_Initialize(LPDIRECTINPUTDEVICE8A iface,HINSTANCE hinst,DWORD dwVersion,REFGUID rguid)1714c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(LPDIRECTINPUTDEVICE8A iface, HINSTANCE hinst, DWORD dwVersion,
1715c2c66affSColin Finck                                                    REFGUID rguid)
1716c2c66affSColin Finck {
1717c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1718c2c66affSColin Finck     return IDirectInputDevice2WImpl_Initialize(IDirectInputDevice8W_from_impl(This), hinst, dwVersion, rguid);
1719c2c66affSColin Finck }
1720c2c66affSColin Finck 
1721c2c66affSColin Finck /******************************************************************************
1722c2c66affSColin Finck  *	IDirectInputDevice2A
1723c2c66affSColin Finck  */
1724c2c66affSColin Finck 
IDirectInputDevice2WImpl_CreateEffect(LPDIRECTINPUTDEVICE8W iface,REFGUID rguid,LPCDIEFFECT lpeff,LPDIRECTINPUTEFFECT * ppdef,LPUNKNOWN pUnkOuter)1725c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_CreateEffect(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIEFFECT lpeff,
1726c2c66affSColin Finck                                                      LPDIRECTINPUTEFFECT *ppdef, LPUNKNOWN pUnkOuter)
1727c2c66affSColin Finck {
1728*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1729*41c8c312SAmine Khaldi     FIXME("(%p)->(%s,%p,%p,%p): stub!\n", This, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter);
1730c2c66affSColin Finck 
1731c2c66affSColin Finck     FIXME("not available in the generic implementation\n");
1732c2c66affSColin Finck     *ppdef = NULL;
1733c2c66affSColin Finck     return DIERR_UNSUPPORTED;
1734c2c66affSColin Finck }
1735c2c66affSColin Finck 
IDirectInputDevice2AImpl_CreateEffect(LPDIRECTINPUTDEVICE8A iface,REFGUID rguid,LPCDIEFFECT lpeff,LPDIRECTINPUTEFFECT * ppdef,LPUNKNOWN pUnkOuter)1736c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIEFFECT lpeff,
1737c2c66affSColin Finck                                                      LPDIRECTINPUTEFFECT *ppdef, LPUNKNOWN pUnkOuter)
1738c2c66affSColin Finck {
1739c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1740c2c66affSColin Finck     return IDirectInputDevice2WImpl_CreateEffect(IDirectInputDevice8W_from_impl(This), rguid, lpeff, ppdef, pUnkOuter);
1741c2c66affSColin Finck }
1742c2c66affSColin Finck 
IDirectInputDevice2AImpl_EnumEffects(LPDIRECTINPUTDEVICE8A iface,LPDIENUMEFFECTSCALLBACKA lpCallback,LPVOID lpvRef,DWORD dwFlags)1743c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
1744c2c66affSColin Finck 	LPDIRECTINPUTDEVICE8A iface,
1745c2c66affSColin Finck 	LPDIENUMEFFECTSCALLBACKA lpCallback,
1746c2c66affSColin Finck 	LPVOID lpvRef,
1747c2c66affSColin Finck 	DWORD dwFlags)
1748c2c66affSColin Finck {
1749*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1750*41c8c312SAmine Khaldi     FIXME("%p)->(%p,%p,0x%08x): stub!\n", This, lpCallback, lpvRef, dwFlags);
1751c2c66affSColin Finck 
1752c2c66affSColin Finck     return DI_OK;
1753c2c66affSColin Finck }
1754c2c66affSColin Finck 
IDirectInputDevice2WImpl_EnumEffects(LPDIRECTINPUTDEVICE8W iface,LPDIENUMEFFECTSCALLBACKW lpCallback,LPVOID lpvRef,DWORD dwFlags)1755c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_EnumEffects(
1756c2c66affSColin Finck 	LPDIRECTINPUTDEVICE8W iface,
1757c2c66affSColin Finck 	LPDIENUMEFFECTSCALLBACKW lpCallback,
1758c2c66affSColin Finck 	LPVOID lpvRef,
1759c2c66affSColin Finck 	DWORD dwFlags)
1760c2c66affSColin Finck {
1761*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1762*41c8c312SAmine Khaldi     FIXME("(%p)->(%p,%p,0x%08x): stub!\n", This, lpCallback, lpvRef, dwFlags);
1763c2c66affSColin Finck 
1764c2c66affSColin Finck     return DI_OK;
1765c2c66affSColin Finck }
1766c2c66affSColin Finck 
IDirectInputDevice2AImpl_GetEffectInfo(LPDIRECTINPUTDEVICE8A iface,LPDIEFFECTINFOA lpdei,REFGUID rguid)1767c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
1768c2c66affSColin Finck 	LPDIRECTINPUTDEVICE8A iface,
1769c2c66affSColin Finck 	LPDIEFFECTINFOA lpdei,
1770c2c66affSColin Finck 	REFGUID rguid)
1771c2c66affSColin Finck {
1772*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1773*41c8c312SAmine Khaldi     FIXME("(%p)->(%p,%s): stub!\n", This, lpdei, debugstr_guid(rguid));
1774c2c66affSColin Finck     return DI_OK;
1775c2c66affSColin Finck }
1776c2c66affSColin Finck 
IDirectInputDevice2WImpl_GetEffectInfo(LPDIRECTINPUTDEVICE8W iface,LPDIEFFECTINFOW lpdei,REFGUID rguid)1777c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_GetEffectInfo(
1778c2c66affSColin Finck 	LPDIRECTINPUTDEVICE8W iface,
1779c2c66affSColin Finck 	LPDIEFFECTINFOW lpdei,
1780c2c66affSColin Finck 	REFGUID rguid)
1781c2c66affSColin Finck {
1782*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1783*41c8c312SAmine Khaldi     FIXME("(%p)->(%p,%s): stub!\n", This, lpdei, debugstr_guid(rguid));
1784c2c66affSColin Finck     return DI_OK;
1785c2c66affSColin Finck }
1786c2c66affSColin Finck 
IDirectInputDevice2WImpl_GetForceFeedbackState(LPDIRECTINPUTDEVICE8W iface,LPDWORD pdwOut)1787c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_GetForceFeedbackState(LPDIRECTINPUTDEVICE8W iface, LPDWORD pdwOut)
1788c2c66affSColin Finck {
1789*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1790*41c8c312SAmine Khaldi     FIXME("(%p)->(%p): stub!\n", This, pdwOut);
1791c2c66affSColin Finck     return DI_OK;
1792c2c66affSColin Finck }
1793c2c66affSColin Finck 
IDirectInputDevice2AImpl_GetForceFeedbackState(LPDIRECTINPUTDEVICE8A iface,LPDWORD pdwOut)1794c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(LPDIRECTINPUTDEVICE8A iface, LPDWORD pdwOut)
1795c2c66affSColin Finck {
1796c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1797c2c66affSColin Finck     return IDirectInputDevice2WImpl_GetForceFeedbackState(IDirectInputDevice8W_from_impl(This), pdwOut);
1798c2c66affSColin Finck }
1799c2c66affSColin Finck 
IDirectInputDevice2WImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8W iface,DWORD dwFlags)1800c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8W iface, DWORD dwFlags)
1801c2c66affSColin Finck {
1802*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1803*41c8c312SAmine Khaldi     TRACE("(%p)->(0x%08x)\n", This, dwFlags);
1804c2c66affSColin Finck     return DI_NOEFFECT;
1805c2c66affSColin Finck }
1806c2c66affSColin Finck 
IDirectInputDevice2AImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8A iface,DWORD dwFlags)1807c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8A iface, DWORD dwFlags)
1808c2c66affSColin Finck {
1809c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1810c2c66affSColin Finck     return IDirectInputDevice2WImpl_SendForceFeedbackCommand(IDirectInputDevice8W_from_impl(This), dwFlags);
1811c2c66affSColin Finck }
1812c2c66affSColin Finck 
IDirectInputDevice2WImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDEVICE8W iface,LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,LPVOID lpvRef,DWORD dwFlags)1813c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDEVICE8W iface,
1814c2c66affSColin Finck         LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID lpvRef, DWORD dwFlags)
1815c2c66affSColin Finck {
1816*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1817*41c8c312SAmine Khaldi     FIXME("(%p)0>(%p,%p,0x%08x): stub!\n", This, lpCallback, lpvRef, dwFlags);
1818c2c66affSColin Finck     return DI_OK;
1819c2c66affSColin Finck }
1820c2c66affSColin Finck 
IDirectInputDevice2AImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDEVICE8A iface,LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,LPVOID lpvRef,DWORD dwFlags)1821c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDEVICE8A iface,
1822c2c66affSColin Finck         LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID lpvRef, DWORD dwFlags)
1823c2c66affSColin Finck {
1824c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1825c2c66affSColin Finck     return IDirectInputDevice2WImpl_EnumCreatedEffectObjects(IDirectInputDevice8W_from_impl(This), lpCallback, lpvRef, dwFlags);
1826c2c66affSColin Finck }
1827c2c66affSColin Finck 
IDirectInputDevice2WImpl_Escape(LPDIRECTINPUTDEVICE8W iface,LPDIEFFESCAPE lpDIEEsc)1828c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_Escape(LPDIRECTINPUTDEVICE8W iface, LPDIEFFESCAPE lpDIEEsc)
1829c2c66affSColin Finck {
1830*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1831*41c8c312SAmine Khaldi     FIXME("(%p)->(%p): stub!\n", This, lpDIEEsc);
1832c2c66affSColin Finck     return DI_OK;
1833c2c66affSColin Finck }
1834c2c66affSColin Finck 
IDirectInputDevice2AImpl_Escape(LPDIRECTINPUTDEVICE8A iface,LPDIEFFESCAPE lpDIEEsc)1835c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_Escape(LPDIRECTINPUTDEVICE8A iface, LPDIEFFESCAPE lpDIEEsc)
1836c2c66affSColin Finck {
1837c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1838c2c66affSColin Finck     return IDirectInputDevice2WImpl_Escape(IDirectInputDevice8W_from_impl(This), lpDIEEsc);
1839c2c66affSColin Finck }
1840c2c66affSColin Finck 
IDirectInputDevice2WImpl_Poll(LPDIRECTINPUTDEVICE8W iface)1841c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_Poll(LPDIRECTINPUTDEVICE8W iface)
1842c2c66affSColin Finck {
1843c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1844c2c66affSColin Finck 
1845c2c66affSColin Finck     if (!This->acquired) return DIERR_NOTACQUIRED;
1846c2c66affSColin Finck 
1847c2c66affSColin Finck     check_dinput_events();
1848c2c66affSColin Finck     return DI_OK;
1849c2c66affSColin Finck }
1850c2c66affSColin Finck 
IDirectInputDevice2AImpl_Poll(LPDIRECTINPUTDEVICE8A iface)1851c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_Poll(LPDIRECTINPUTDEVICE8A iface)
1852c2c66affSColin Finck {
1853c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1854c2c66affSColin Finck     return IDirectInputDevice2WImpl_Poll(IDirectInputDevice8W_from_impl(This));
1855c2c66affSColin Finck }
1856c2c66affSColin Finck 
IDirectInputDevice2WImpl_SendDeviceData(LPDIRECTINPUTDEVICE8W iface,DWORD cbObjectData,LPCDIDEVICEOBJECTDATA rgdod,LPDWORD pdwInOut,DWORD dwFlags)1857c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2WImpl_SendDeviceData(LPDIRECTINPUTDEVICE8W iface, DWORD cbObjectData,
1858c2c66affSColin Finck                                                        LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut,
1859c2c66affSColin Finck                                                        DWORD dwFlags)
1860c2c66affSColin Finck {
1861*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1862*41c8c312SAmine Khaldi     FIXME("(%p)->(0x%08x,%p,%p,0x%08x): stub!\n", This, cbObjectData, rgdod, pdwInOut, dwFlags);
1863c2c66affSColin Finck 
1864c2c66affSColin Finck     return DI_OK;
1865c2c66affSColin Finck }
1866c2c66affSColin Finck 
IDirectInputDevice2AImpl_SendDeviceData(LPDIRECTINPUTDEVICE8A iface,DWORD cbObjectData,LPCDIDEVICEOBJECTDATA rgdod,LPDWORD pdwInOut,DWORD dwFlags)1867c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(LPDIRECTINPUTDEVICE8A iface, DWORD cbObjectData,
1868c2c66affSColin Finck                                                        LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut,
1869c2c66affSColin Finck                                                        DWORD dwFlags)
1870c2c66affSColin Finck {
1871c2c66affSColin Finck     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1872c2c66affSColin Finck     return IDirectInputDevice2WImpl_SendDeviceData(IDirectInputDevice8W_from_impl(This), cbObjectData, rgdod,
1873c2c66affSColin Finck                                                    pdwInOut, dwFlags);
1874c2c66affSColin Finck }
1875c2c66affSColin Finck 
IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface,LPCSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags)1876c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface,
1877c2c66affSColin Finck 							  LPCSTR lpszFileName,
1878c2c66affSColin Finck 							  LPDIENUMEFFECTSINFILECALLBACK pec,
1879c2c66affSColin Finck 							  LPVOID pvRef,
1880c2c66affSColin Finck 							  DWORD dwFlags)
1881c2c66affSColin Finck {
1882*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1883*41c8c312SAmine Khaldi     FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", This, lpszFileName, pec, pvRef, dwFlags);
1884c2c66affSColin Finck 
1885c2c66affSColin Finck     return DI_OK;
1886c2c66affSColin Finck }
1887c2c66affSColin Finck 
IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W iface,LPCWSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags)1888c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W iface,
1889c2c66affSColin Finck 							  LPCWSTR lpszFileName,
1890c2c66affSColin Finck 							  LPDIENUMEFFECTSINFILECALLBACK pec,
1891c2c66affSColin Finck 							  LPVOID pvRef,
1892c2c66affSColin Finck 							  DWORD dwFlags)
1893c2c66affSColin Finck {
1894*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1895*41c8c312SAmine Khaldi     FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", This, debugstr_w(lpszFileName), pec, pvRef, dwFlags);
1896c2c66affSColin Finck 
1897c2c66affSColin Finck     return DI_OK;
1898c2c66affSColin Finck }
1899c2c66affSColin Finck 
IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface,LPCSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags)1900c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface,
1901c2c66affSColin Finck 							  LPCSTR lpszFileName,
1902c2c66affSColin Finck 							  DWORD dwEntries,
1903c2c66affSColin Finck 							  LPDIFILEEFFECT rgDiFileEft,
1904c2c66affSColin Finck 							  DWORD dwFlags)
1905c2c66affSColin Finck {
1906*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1907*41c8c312SAmine Khaldi     FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", This, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
1908c2c66affSColin Finck 
1909c2c66affSColin Finck     return DI_OK;
1910c2c66affSColin Finck }
1911c2c66affSColin Finck 
IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W iface,LPCWSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags)1912c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W iface,
1913c2c66affSColin Finck 							  LPCWSTR lpszFileName,
1914c2c66affSColin Finck 							  DWORD dwEntries,
1915c2c66affSColin Finck 							  LPDIFILEEFFECT rgDiFileEft,
1916c2c66affSColin Finck 							  DWORD dwFlags)
1917c2c66affSColin Finck {
1918*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1919*41c8c312SAmine Khaldi     FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", This, debugstr_w(lpszFileName), dwEntries, rgDiFileEft, dwFlags);
1920c2c66affSColin Finck 
1921c2c66affSColin Finck     return DI_OK;
1922c2c66affSColin Finck }
1923c2c66affSColin Finck 
IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,LPDIACTIONFORMATW lpdiaf,LPCWSTR lpszUserName,DWORD dwFlags)1924c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
1925c2c66affSColin Finck 						       LPDIACTIONFORMATW lpdiaf,
1926c2c66affSColin Finck 						       LPCWSTR lpszUserName,
1927c2c66affSColin Finck 						       DWORD dwFlags)
1928c2c66affSColin Finck {
1929*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1930*41c8c312SAmine Khaldi     FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags);
1931c2c66affSColin Finck #define X(x) if (dwFlags & x) FIXME("\tdwFlags =|"#x"\n");
1932c2c66affSColin Finck 	X(DIDBAM_DEFAULT)
1933c2c66affSColin Finck 	X(DIDBAM_PRESERVE)
1934c2c66affSColin Finck 	X(DIDBAM_INITIALIZE)
1935c2c66affSColin Finck 	X(DIDBAM_HWDEFAULTS)
1936c2c66affSColin Finck #undef X
1937c2c66affSColin Finck 
1938c2c66affSColin Finck     return DI_OK;
1939c2c66affSColin Finck }
1940c2c66affSColin Finck 
IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface,LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)1941c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface,
1942c2c66affSColin Finck 						     LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)
1943c2c66affSColin Finck {
1944*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface);
1945*41c8c312SAmine Khaldi     FIXME("(%p)->(%p): stub !\n", This, lpdiDevImageInfoHeader);
1946c2c66affSColin Finck 
1947c2c66affSColin Finck     return DI_OK;
1948c2c66affSColin Finck }
1949c2c66affSColin Finck 
IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface,LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader)1950c2c66affSColin Finck HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface,
1951c2c66affSColin Finck 						     LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader)
1952c2c66affSColin Finck {
1953*41c8c312SAmine Khaldi     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
1954*41c8c312SAmine Khaldi     FIXME("(%p)->(%p): stub !\n", This, lpdiDevImageInfoHeader);
1955c2c66affSColin Finck 
1956c2c66affSColin Finck     return DI_OK;
1957c2c66affSColin Finck }
1958