Small fix in IDirectInputDevice2Impl_QueryInterface.
[wine.git] / dlls / dinput / device.c
blob07c045616f95eb08753690cf60505db0d69f971b
1 /* DirectInput Device
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* This file contains all the Device specific functions that can be used as stubs
23 by real device implementations.
25 It also contains all the helper functions.
27 #include "config.h"
29 #include <string.h>
30 #include "wine/debug.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "windef.h"
34 #include "dinput.h"
35 #include "device_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
39 /******************************************************************************
40 * Various debugging tools
42 void _dump_cooperativelevel_DI(DWORD dwFlags) {
43 int i;
44 const struct {
45 DWORD mask;
46 char *name;
47 } flags[] = {
48 #define FE(x) { x, #x},
49 FE(DISCL_BACKGROUND)
50 FE(DISCL_EXCLUSIVE)
51 FE(DISCL_FOREGROUND)
52 FE(DISCL_NONEXCLUSIVE)
53 #undef FE
55 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
56 if (flags[i].mask & dwFlags)
57 DPRINTF("%s ",flags[i].name);
58 DPRINTF("\n");
61 void _dump_EnumObjects_flags(DWORD dwFlags) {
62 int i;
63 const struct {
64 DWORD mask;
65 char *name;
66 } flags[] = {
67 #define FE(x) { x, #x},
68 FE(DIDFT_ABSAXIS)
69 FE(DIDFT_ALL)
70 FE(DIDFT_AXIS)
71 FE(DIDFT_BUTTON)
72 FE(DIDFT_COLLECTION)
73 FE(DIDFT_FFACTUATOR)
74 FE(DIDFT_FFEFFECTTRIGGER)
75 FE(DIDFT_NOCOLLECTION)
76 FE(DIDFT_NODATA)
77 FE(DIDFT_OUTPUT)
78 FE(DIDFT_POV)
79 FE(DIDFT_PSHBUTTON)
80 FE(DIDFT_RELAXIS)
81 FE(DIDFT_TGLBUTTON)
82 #undef FE
84 if (dwFlags == DIDFT_ALL) {
85 DPRINTF("DIDFT_ALL");
86 return;
88 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
89 if (flags[i].mask & dwFlags)
90 DPRINTF("%s ",flags[i].name);
91 if (dwFlags & DIDFT_INSTANCEMASK)
92 DPRINTF("Instance(%04lx) ", dwFlags >> 8);
95 void _dump_DIPROPHEADER(DIPROPHEADER *diph) {
96 DPRINTF(" - dwObj = 0x%08lx\n", diph->dwObj);
97 DPRINTF(" - dwHow = %s\n",
98 ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" :
99 ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" :
100 ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown")));
103 void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) {
104 if (TRACE_ON(dinput)) {
105 DPRINTF(" - enumerating : %s - %2ld - 0x%08lx - %s\n",
106 debugstr_guid(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, ddoi->tszName);
110 /* Conversion between internal data buffer and external data buffer */
111 void fill_DataFormat(void *out, void *in, DataFormat *df) {
112 int i;
113 char *in_c = (char *) in;
114 char *out_c = (char *) out;
116 if (df->dt == NULL) {
117 /* This means that the app uses Wine's internal data format */
118 memcpy(out, in, df->internal_format_size);
119 } else {
120 for (i = 0; i < df->size; i++) {
121 if (df->dt[i].offset_in >= 0) {
122 switch (df->dt[i].size) {
123 case 1:
124 TRACE("Copying (c) to %d from %d (value %d)\n",
125 df->dt[i].offset_out, df->dt[i].offset_in, *((char *) (in_c + df->dt[i].offset_in)));
126 *((char *) (out_c + df->dt[i].offset_out)) = *((char *) (in_c + df->dt[i].offset_in));
127 break;
129 case 2:
130 TRACE("Copying (s) to %d from %d (value %d)\n",
131 df->dt[i].offset_out, df->dt[i].offset_in, *((short *) (in_c + df->dt[i].offset_in)));
132 *((short *) (out_c + df->dt[i].offset_out)) = *((short *) (in_c + df->dt[i].offset_in));
133 break;
135 case 4:
136 TRACE("Copying (i) to %d from %d (value %d)\n",
137 df->dt[i].offset_out, df->dt[i].offset_in, *((int *) (in_c + df->dt[i].offset_in)));
138 *((int *) (out_c + df->dt[i].offset_out)) = *((int *) (in_c + df->dt[i].offset_in));
139 break;
141 default:
142 memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size);
144 } else {
145 switch (df->dt[i].size) {
146 case 1:
147 TRACE("Copying (c) to %d default value %d\n",
148 df->dt[i].offset_out, df->dt[i].value);
149 *((char *) (out_c + df->dt[i].offset_out)) = (char) df->dt[i].value;
150 break;
152 case 2:
153 TRACE("Copying (s) to %d default value %d\n",
154 df->dt[i].offset_out, df->dt[i].value);
155 *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value;
156 break;
158 case 4:
159 TRACE("Copying (i) to %d default value %d\n",
160 df->dt[i].offset_out, df->dt[i].value);
161 *((int *) (out_c + df->dt[i].offset_out)) = (int) df->dt[i].value;
162 break;
164 default:
165 memset((out_c + df->dt[i].offset_out), df->dt[i].size, 0);
172 DataFormat *create_DataFormat(DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) {
173 DataFormat *ret;
174 DataTransform *dt;
175 int i, j;
176 int same = 1;
177 int *done;
178 int index = 0;
180 ret = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat));
182 done = (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format->dwNumObjs);
183 memset(done, 0, sizeof(int) * asked_format->dwNumObjs);
185 dt = (DataTransform *) HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform));
187 TRACE("Creating DataTransform : \n");
189 for (i = 0; i < wine_format->dwNumObjs; i++) {
190 offset[i] = -1;
192 for (j = 0; j < asked_format->dwNumObjs; j++) {
193 if (done[j] == 1)
194 continue;
196 if (((asked_format->rgodf[j].pguid == NULL) || (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid)))
198 (wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType)) {
200 done[j] = 1;
202 TRACE("Matching : \n");
203 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
204 j, debugstr_guid(asked_format->rgodf[j].pguid),
205 asked_format->rgodf[j].dwOfs,
206 DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType));
208 TRACE(" - Wine (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
209 j, debugstr_guid(wine_format->rgodf[i].pguid),
210 wine_format->rgodf[i].dwOfs,
211 DIDFT_GETTYPE(wine_format->rgodf[i].dwType), DIDFT_GETINSTANCE(wine_format->rgodf[i].dwType));
213 if (wine_format->rgodf[i].dwType & DIDFT_BUTTON)
214 dt[index].size = sizeof(BYTE);
215 else
216 dt[index].size = sizeof(DWORD);
217 dt[index].offset_in = wine_format ->rgodf[i].dwOfs;
218 dt[index].offset_out = asked_format->rgodf[j].dwOfs;
219 dt[index].value = 0;
220 index++;
222 if (wine_format->rgodf[i].dwOfs != asked_format->rgodf[j].dwOfs)
223 same = 0;
225 offset[i] = asked_format->rgodf[j].dwOfs;
226 break;
230 if (j == asked_format->dwNumObjs)
231 same = 0;
234 TRACE("Setting to default value :\n");
235 for (j = 0; j < asked_format->dwNumObjs; j++) {
236 if (done[j] == 0) {
237 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
238 j, debugstr_guid(asked_format->rgodf[j].pguid),
239 asked_format->rgodf[j].dwOfs,
240 DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType));
243 if (asked_format->rgodf[j].dwType & DIDFT_BUTTON)
244 dt[index].size = sizeof(BYTE);
245 else
246 dt[index].size = sizeof(DWORD);
247 dt[index].offset_in = -1;
248 dt[index].offset_out = asked_format->rgodf[j].dwOfs;
249 dt[index].value = 0;
250 index++;
252 same = 0;
256 ret->internal_format_size = wine_format->dwDataSize;
257 ret->size = index;
258 if (same) {
259 ret->dt = NULL;
260 HeapFree(GetProcessHeap(), 0, dt);
261 } else {
262 ret->dt = dt;
265 HeapFree(GetProcessHeap(), 0, done);
267 return ret;
270 /******************************************************************************
271 * IDirectInputDeviceA
274 HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
275 LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df
277 int i;
278 ICOM_THIS(IDirectInputDevice2AImpl,iface);
280 TRACE("(this=%p,%p)\n",This,df);
282 TRACE("df.dwSize=%ld\n",df->dwSize);
283 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
284 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
285 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
286 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
288 for (i=0;i<df->dwNumObjs;i++) {
289 TRACE("df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid));
290 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
291 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
292 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
294 return 0;
297 HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
298 LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags
300 ICOM_THIS(IDirectInputDevice2AImpl,iface);
301 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
302 if (TRACE_ON(dinput)) {
303 TRACE(" cooperative level : ");
304 _dump_cooperativelevel_DI(dwflags);
306 return 0;
309 HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
310 LPDIRECTINPUTDEVICE8A iface,HANDLE hnd
312 ICOM_THIS(IDirectInputDevice2AImpl,iface);
313 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
314 return 0;
317 ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)
319 ICOM_THIS(IDirectInputDevice2AImpl,iface);
320 This->ref--;
321 if (This->ref)
322 return This->ref;
323 HeapFree(GetProcessHeap(),0,This);
324 return 0;
327 HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
328 LPDIRECTINPUTDEVICE8A iface,REFIID riid,LPVOID *ppobj
331 ICOM_THIS(IDirectInputDevice2AImpl,iface);
333 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
334 if (IsEqualGUID(&IID_IUnknown,riid)) {
335 IDirectInputDevice2_AddRef(iface);
336 *ppobj = This;
337 return 0;
339 if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) {
340 IDirectInputDevice2_AddRef(iface);
341 *ppobj = This;
342 return 0;
344 if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) {
345 IDirectInputDevice7_AddRef(iface);
346 *ppobj = This;
347 return 0;
349 TRACE("Unsupported interface !\n");
350 return E_FAIL;
353 ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
354 LPDIRECTINPUTDEVICE8A iface)
356 ICOM_THIS(IDirectInputDevice2AImpl,iface);
357 return ++This->ref;
360 HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
361 LPDIRECTINPUTDEVICE8A iface,
362 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
363 LPVOID lpvRef,
364 DWORD dwFlags)
366 FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
367 if (TRACE_ON(dinput)) {
368 DPRINTF(" - flags = ");
369 _dump_EnumObjects_flags(dwFlags);
370 DPRINTF("\n");
373 return DI_OK;
376 HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
377 LPDIRECTINPUTDEVICE8A iface,
378 REFGUID rguid,
379 LPDIPROPHEADER pdiph)
381 FIXME("(this=%p,%s,%p): stub!\n",
382 iface, debugstr_guid(rguid), pdiph);
384 if (TRACE_ON(dinput))
385 _dump_DIPROPHEADER(pdiph);
387 return DI_OK;
390 HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
391 LPDIRECTINPUTDEVICE8A iface,
392 LPDIDEVICEOBJECTINSTANCEA pdidoi,
393 DWORD dwObj,
394 DWORD dwHow)
396 FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
397 iface, pdidoi, dwObj, dwHow);
399 return DI_OK;
402 HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
403 LPDIRECTINPUTDEVICE8A iface,
404 LPDIDEVICEINSTANCEA pdidi)
406 FIXME("(this=%p,%p): stub!\n",
407 iface, pdidi);
409 return DI_OK;
412 HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
413 LPDIRECTINPUTDEVICE8A iface,
414 HWND hwndOwner,
415 DWORD dwFlags)
417 FIXME("(this=%p,%p,0x%08lx): stub!\n",
418 iface, hwndOwner, dwFlags);
420 return DI_OK;
423 HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
424 LPDIRECTINPUTDEVICE8A iface,
425 HINSTANCE hinst,
426 DWORD dwVersion,
427 REFGUID rguid)
429 FIXME("(this=%p,%p,%ld,%s): stub!\n",
430 iface, hinst, dwVersion, debugstr_guid(rguid));
431 return DI_OK;
434 /******************************************************************************
435 * IDirectInputDevice2A
438 HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
439 LPDIRECTINPUTDEVICE8A iface,
440 REFGUID rguid,
441 LPCDIEFFECT lpeff,
442 LPDIRECTINPUTEFFECT *ppdef,
443 LPUNKNOWN pUnkOuter)
445 FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
446 iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter);
447 return DI_OK;
450 HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
451 LPDIRECTINPUTDEVICE8A iface,
452 LPDIENUMEFFECTSCALLBACKA lpCallback,
453 LPVOID lpvRef,
454 DWORD dwFlags)
456 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
457 iface, lpCallback, lpvRef, dwFlags);
459 if (lpCallback)
460 lpCallback(NULL, lpvRef);
461 return DI_OK;
464 HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
465 LPDIRECTINPUTDEVICE8A iface,
466 LPDIEFFECTINFOA lpdei,
467 REFGUID rguid)
469 FIXME("(this=%p,%p,%s): stub!\n",
470 iface, lpdei, debugstr_guid(rguid));
471 return DI_OK;
474 HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
475 LPDIRECTINPUTDEVICE8A iface,
476 LPDWORD pdwOut)
478 FIXME("(this=%p,%p): stub!\n",
479 iface, pdwOut);
480 return DI_OK;
483 HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
484 LPDIRECTINPUTDEVICE8A iface,
485 DWORD dwFlags)
487 FIXME("(this=%p,0x%08lx): stub!\n",
488 iface, dwFlags);
489 return DI_OK;
492 HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
493 LPDIRECTINPUTDEVICE8A iface,
494 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
495 LPVOID lpvRef,
496 DWORD dwFlags)
498 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
499 iface, lpCallback, lpvRef, dwFlags);
500 if (lpCallback)
501 lpCallback(NULL, lpvRef);
502 return DI_OK;
505 HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
506 LPDIRECTINPUTDEVICE8A iface,
507 LPDIEFFESCAPE lpDIEEsc)
509 FIXME("(this=%p,%p): stub!\n",
510 iface, lpDIEEsc);
511 return DI_OK;
514 HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
515 LPDIRECTINPUTDEVICE8A iface)
517 /* Because wine devices do not need to be polled, just return DI_NOEFFECT */
518 return DI_NOEFFECT;
521 HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
522 LPDIRECTINPUTDEVICE8A iface,
523 DWORD cbObjectData,
524 LPCDIDEVICEOBJECTDATA rgdod,
525 LPDWORD pdwInOut,
526 DWORD dwFlags)
528 FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
529 iface, cbObjectData, rgdod, pdwInOut, dwFlags);
531 return DI_OK;
534 HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface,
535 LPCSTR lpszFileName,
536 LPDIENUMEFFECTSINFILECALLBACK pec,
537 LPVOID pvRef,
538 DWORD dwFlags)
540 FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);
542 return DI_OK;
545 HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface,
546 LPCSTR lpszFileName,
547 DWORD dwEntries,
548 LPDIFILEEFFECT rgDiFileEft,
549 DWORD dwFlags)
551 FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
553 return DI_OK;
556 HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,
557 LPDIACTIONFORMATA lpdiaf,
558 LPCSTR lpszUserName,
559 DWORD dwFlags)
561 FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
563 return DI_OK;
566 HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface,
567 LPDIACTIONFORMATA lpdiaf,
568 LPCSTR lpszUserName,
569 DWORD dwFlags)
571 FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
573 return DI_OK;
576 HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface,
577 LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)
579 FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
581 return DI_OK;