Add support for Jack audio server.
[wine.git] / dlls / dinput / device.c
blob5edc956cae0c4c76107ddff6ed1f5a790e787fbc
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 : 0x%08lx - %2ld - 0x%08lx - %s\n",
106 ddoi->guidType.Data1, 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 _dump_cooperativelevel_DI(dwflags);
304 return 0;
307 HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
308 LPDIRECTINPUTDEVICE8A iface,HANDLE hnd
310 ICOM_THIS(IDirectInputDevice2AImpl,iface);
311 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
312 return 0;
315 ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)
317 ICOM_THIS(IDirectInputDevice2AImpl,iface);
318 This->ref--;
319 if (This->ref)
320 return This->ref;
321 HeapFree(GetProcessHeap(),0,This);
322 return 0;
325 HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
326 LPDIRECTINPUTDEVICE8A iface,REFIID riid,LPVOID *ppobj
329 ICOM_THIS(IDirectInputDevice2AImpl,iface);
331 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
332 if (IsEqualGUID(&IID_IUnknown,riid)) {
333 IDirectInputDevice2_AddRef(iface);
334 *ppobj = This;
335 return 0;
337 if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) {
338 IDirectInputDevice2_AddRef(iface);
339 *ppobj = This;
340 return 0;
342 if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) {
343 IDirectInputDevice2_AddRef(iface);
344 *ppobj = This;
345 return 0;
347 TRACE("Unsupported interface !\n");
348 return E_FAIL;
351 ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
352 LPDIRECTINPUTDEVICE8A iface)
354 ICOM_THIS(IDirectInputDevice2AImpl,iface);
355 return ++This->ref;
358 HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
359 LPDIRECTINPUTDEVICE8A iface,
360 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
361 LPVOID lpvRef,
362 DWORD dwFlags)
364 FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
365 if (TRACE_ON(dinput)) {
366 DPRINTF(" - flags = ");
367 _dump_EnumObjects_flags(dwFlags);
368 DPRINTF("\n");
371 return DI_OK;
374 HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
375 LPDIRECTINPUTDEVICE8A iface,
376 REFGUID rguid,
377 LPDIPROPHEADER pdiph)
379 FIXME("(this=%p,%s,%p): stub!\n",
380 iface, debugstr_guid(rguid), pdiph);
382 if (TRACE_ON(dinput))
383 _dump_DIPROPHEADER(pdiph);
385 return DI_OK;
388 HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
389 LPDIRECTINPUTDEVICE8A iface,
390 LPDIDEVICEOBJECTINSTANCEA pdidoi,
391 DWORD dwObj,
392 DWORD dwHow)
394 FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
395 iface, pdidoi, dwObj, dwHow);
397 return DI_OK;
400 HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
401 LPDIRECTINPUTDEVICE8A iface,
402 LPDIDEVICEINSTANCEA pdidi)
404 FIXME("(this=%p,%p): stub!\n",
405 iface, pdidi);
407 return DI_OK;
410 HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
411 LPDIRECTINPUTDEVICE8A iface,
412 HWND hwndOwner,
413 DWORD dwFlags)
415 FIXME("(this=%p,%p,0x%08lx): stub!\n",
416 iface, hwndOwner, dwFlags);
418 return DI_OK;
421 HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
422 LPDIRECTINPUTDEVICE8A iface,
423 HINSTANCE hinst,
424 DWORD dwVersion,
425 REFGUID rguid)
427 FIXME("(this=%p,%p,%ld,%s): stub!\n",
428 iface, hinst, dwVersion, debugstr_guid(rguid));
429 return DI_OK;
432 /******************************************************************************
433 * IDirectInputDevice2A
436 HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
437 LPDIRECTINPUTDEVICE8A iface,
438 REFGUID rguid,
439 LPCDIEFFECT lpeff,
440 LPDIRECTINPUTEFFECT *ppdef,
441 LPUNKNOWN pUnkOuter)
443 FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
444 iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter);
445 return DI_OK;
448 HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
449 LPDIRECTINPUTDEVICE8A iface,
450 LPDIENUMEFFECTSCALLBACKA lpCallback,
451 LPVOID lpvRef,
452 DWORD dwFlags)
454 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
455 iface, lpCallback, lpvRef, dwFlags);
457 if (lpCallback)
458 lpCallback(NULL, lpvRef);
459 return DI_OK;
462 HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
463 LPDIRECTINPUTDEVICE8A iface,
464 LPDIEFFECTINFOA lpdei,
465 REFGUID rguid)
467 FIXME("(this=%p,%p,%s): stub!\n",
468 iface, lpdei, debugstr_guid(rguid));
469 return DI_OK;
472 HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
473 LPDIRECTINPUTDEVICE8A iface,
474 LPDWORD pdwOut)
476 FIXME("(this=%p,%p): stub!\n",
477 iface, pdwOut);
478 return DI_OK;
481 HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
482 LPDIRECTINPUTDEVICE8A iface,
483 DWORD dwFlags)
485 FIXME("(this=%p,0x%08lx): stub!\n",
486 iface, dwFlags);
487 return DI_OK;
490 HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
491 LPDIRECTINPUTDEVICE8A iface,
492 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
493 LPVOID lpvRef,
494 DWORD dwFlags)
496 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
497 iface, lpCallback, lpvRef, dwFlags);
498 if (lpCallback)
499 lpCallback(NULL, lpvRef);
500 return DI_OK;
503 HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
504 LPDIRECTINPUTDEVICE8A iface,
505 LPDIEFFESCAPE lpDIEEsc)
507 FIXME("(this=%p,%p): stub!\n",
508 iface, lpDIEEsc);
509 return DI_OK;
512 HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
513 LPDIRECTINPUTDEVICE8A iface)
515 /* Because wine devices do not need to be polled, just return DI_NOEFFECT */
516 return DI_NOEFFECT;
519 HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
520 LPDIRECTINPUTDEVICE8A iface,
521 DWORD cbObjectData,
522 LPCDIDEVICEOBJECTDATA rgdod,
523 LPDWORD pdwInOut,
524 DWORD dwFlags)
526 FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
527 iface, cbObjectData, rgdod, pdwInOut, dwFlags);
529 return DI_OK;
532 HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface,
533 LPCSTR lpszFileName,
534 LPDIENUMEFFECTSINFILECALLBACK pec,
535 LPVOID pvRef,
536 DWORD dwFlags)
538 FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);
540 return DI_OK;
543 HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface,
544 LPCSTR lpszFileName,
545 DWORD dwEntries,
546 LPDIFILEEFFECT rgDiFileEft,
547 DWORD dwFlags)
549 FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
551 return DI_OK;
554 HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,
555 LPDIACTIONFORMATA lpdiaf,
556 LPCSTR lpszUserName,
557 DWORD dwFlags)
559 FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
561 return DI_OK;
564 HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface,
565 LPDIACTIONFORMATA lpdiaf,
566 LPCSTR lpszUserName,
567 DWORD dwFlags)
569 FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
571 return DI_OK;
574 HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface,
575 LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)
577 FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
579 return DI_OK;