source: trunk/src/dinput/device.c@ 10010

Last change on this file since 10010 was 9016, checked in by sandervl, 23 years ago

Wine resync; added missing bugfix

File size: 15.3 KB
Line 
1/* DirectInput Device
2 *
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 *
6 *
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.
11 *
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.
16 *
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
20 */
21
22/* This file contains all the Device specific functions that can be used as stubs
23 by real device implementations.
24
25 It also contains all the helper functions.
26*/
27#include "config.h"
28
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"
36
37WINE_DEFAULT_DEBUG_CHANNEL(dinput);
38
39/******************************************************************************
40 * Various debugging tools
41 */
42void _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
54 };
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");
59}
60
61void _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
83 };
84 if (dwFlags == DIDFT_ALL) {
85 DPRINTF("DIDFT_ALL");
86 return;
87 }
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);
93}
94
95void _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")));
101}
102
103void _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);
107 }
108}
109
110/* Conversion between internal data buffer and external data buffer */
111void fill_DataFormat(void *out, void *in, DataFormat *df) {
112 int i;
113 char *in_c = (char *) in;
114 char *out_c = (char *) out;
115
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;
128
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;
134
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;
140
141 default:
142 memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size);
143 }
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;
151
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;
157
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;
163
164 default:
165 memset((out_c + df->dt[i].offset_out), df->dt[i].size, 0);
166 }
167 }
168 }
169 }
170}
171
172DataFormat *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;
179
180 ret = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat));
181
182 done = (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format->dwNumObjs);
183 memset(done, 0, sizeof(int) * asked_format->dwNumObjs);
184
185 dt = (DataTransform *) HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform));
186
187 TRACE("Creating DataTransform : \n");
188
189 for (i = 0; i < wine_format->dwNumObjs; i++) {
190 offset[i] = -1;
191
192 for (j = 0; j < asked_format->dwNumObjs; j++) {
193 if (done[j] == 1)
194 continue;
195
196 if (((asked_format->rgodf[j].pguid == NULL) || (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid)))
197 &&
198 (wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType)) {
199
200 done[j] = 1;
201
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));
207
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));
212
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++;
221
222 if (wine_format->rgodf[i].dwOfs != asked_format->rgodf[j].dwOfs)
223 same = 0;
224
225 offset[i] = asked_format->rgodf[j].dwOfs;
226 break;
227 }
228 }
229
230 if (j == asked_format->dwNumObjs)
231 same = 0;
232 }
233
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));
241
242
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++;
251
252 same = 0;
253 }
254 }
255
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;
263 }
264
265 HeapFree(GetProcessHeap(), 0, done);
266
267 return ret;
268}
269
270/******************************************************************************
271 * IDirectInputDeviceA
272 */
273
274HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
275 LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df
276) {
277 int i;
278 ICOM_THIS(IDirectInputDevice2AImpl,iface);
279
280 TRACE("(this=%p,%p)\n",This,df);
281
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);
287
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);
293 }
294 return 0;
295}
296
297HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
298 LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags
299) {
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;
305}
306
307HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
308 LPDIRECTINPUTDEVICE8A iface,HANDLE hnd
309) {
310 ICOM_THIS(IDirectInputDevice2AImpl,iface);
311 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
312 return 0;
313}
314
315ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)
316{
317 ICOM_THIS(IDirectInputDevice2AImpl,iface);
318 This->ref--;
319 if (This->ref)
320 return This->ref;
321 HeapFree(GetProcessHeap(),0,This);
322 return 0;
323}
324
325HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
326 LPDIRECTINPUTDEVICE8A iface,REFIID riid,LPVOID *ppobj
327)
328{
329 ICOM_THIS(IDirectInputDevice2AImpl,iface);
330
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;
336 }
337 if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) {
338 IDirectInputDevice2_AddRef(iface);
339 *ppobj = This;
340 return 0;
341 }
342 if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) {
343 IDirectInputDevice2_AddRef(iface);
344 *ppobj = This;
345 return 0;
346 }
347 TRACE("Unsupported interface !\n");
348 return E_FAIL;
349}
350
351ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
352 LPDIRECTINPUTDEVICE8A iface)
353{
354 ICOM_THIS(IDirectInputDevice2AImpl,iface);
355 return ++This->ref;
356}
357
358HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
359 LPDIRECTINPUTDEVICE8A iface,
360 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
361 LPVOID lpvRef,
362 DWORD dwFlags)
363{
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");
369 }
370
371 return DI_OK;
372}
373
374HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
375 LPDIRECTINPUTDEVICE8A iface,
376 REFGUID rguid,
377 LPDIPROPHEADER pdiph)
378{
379 FIXME("(this=%p,%s,%p): stub!\n",
380 iface, debugstr_guid(rguid), pdiph);
381
382 if (TRACE_ON(dinput))
383 _dump_DIPROPHEADER(pdiph);
384
385 return DI_OK;
386}
387
388HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
389 LPDIRECTINPUTDEVICE8A iface,
390 LPDIDEVICEOBJECTINSTANCEA pdidoi,
391 DWORD dwObj,
392 DWORD dwHow)
393{
394 FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
395 iface, pdidoi, dwObj, dwHow);
396
397 return DI_OK;
398}
399
400HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
401 LPDIRECTINPUTDEVICE8A iface,
402 LPDIDEVICEINSTANCEA pdidi)
403{
404 FIXME("(this=%p,%p): stub!\n",
405 iface, pdidi);
406
407 return DI_OK;
408}
409
410HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
411 LPDIRECTINPUTDEVICE8A iface,
412 HWND hwndOwner,
413 DWORD dwFlags)
414{
415 FIXME("(this=%p,0x%08x,0x%08lx): stub!\n",
416 iface, hwndOwner, dwFlags);
417
418 return DI_OK;
419}
420
421HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
422 LPDIRECTINPUTDEVICE8A iface,
423 HINSTANCE hinst,
424 DWORD dwVersion,
425 REFGUID rguid)
426{
427 FIXME("(this=%p,%d,%ld,%s): stub!\n",
428 iface, hinst, dwVersion, debugstr_guid(rguid));
429 return DI_OK;
430}
431
432/******************************************************************************
433 * IDirectInputDevice2A
434 */
435
436HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
437 LPDIRECTINPUTDEVICE8A iface,
438 REFGUID rguid,
439 LPCDIEFFECT lpeff,
440 LPDIRECTINPUTEFFECT *ppdef,
441 LPUNKNOWN pUnkOuter)
442{
443 FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
444 iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter);
445 return DI_OK;
446}
447
448HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
449 LPDIRECTINPUTDEVICE8A iface,
450 LPDIENUMEFFECTSCALLBACKA lpCallback,
451 LPVOID lpvRef,
452 DWORD dwFlags)
453{
454 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
455 iface, lpCallback, lpvRef, dwFlags);
456
457 if (lpCallback)
458 lpCallback(NULL, lpvRef);
459 return DI_OK;
460}
461
462HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
463 LPDIRECTINPUTDEVICE8A iface,
464 LPDIEFFECTINFOA lpdei,
465 REFGUID rguid)
466{
467 FIXME("(this=%p,%p,%s): stub!\n",
468 iface, lpdei, debugstr_guid(rguid));
469 return DI_OK;
470}
471
472HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
473 LPDIRECTINPUTDEVICE8A iface,
474 LPDWORD pdwOut)
475{
476 FIXME("(this=%p,%p): stub!\n",
477 iface, pdwOut);
478 return DI_OK;
479}
480
481HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
482 LPDIRECTINPUTDEVICE8A iface,
483 DWORD dwFlags)
484{
485 FIXME("(this=%p,0x%08lx): stub!\n",
486 iface, dwFlags);
487 return DI_OK;
488}
489
490HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
491 LPDIRECTINPUTDEVICE8A iface,
492 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
493 LPVOID lpvRef,
494 DWORD dwFlags)
495{
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;
501}
502
503HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
504 LPDIRECTINPUTDEVICE8A iface,
505 LPDIEFFESCAPE lpDIEEsc)
506{
507 FIXME("(this=%p,%p): stub!\n",
508 iface, lpDIEEsc);
509 return DI_OK;
510}
511
512HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
513 LPDIRECTINPUTDEVICE8A iface)
514{
515 /* Because wine devices do not need to be polled, just return DI_NOEFFECT */
516 return DI_NOEFFECT;
517}
518
519HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
520 LPDIRECTINPUTDEVICE8A iface,
521 DWORD cbObjectData,
522 LPCDIDEVICEOBJECTDATA rgdod,
523 LPDWORD pdwInOut,
524 DWORD dwFlags)
525{
526 FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
527 iface, cbObjectData, rgdod, pdwInOut, dwFlags);
528
529 return DI_OK;
530}
531
532HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface,
533 LPCSTR lpszFileName,
534 LPDIENUMEFFECTSINFILECALLBACK pec,
535 LPVOID pvRef,
536 DWORD dwFlags)
537{
538 FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);
539
540 return DI_OK;
541}
542
543HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface,
544 LPCSTR lpszFileName,
545 DWORD dwEntries,
546 LPDIFILEEFFECT rgDiFileEft,
547 DWORD dwFlags)
548{
549 FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
550
551 return DI_OK;
552}
553
554HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,
555 LPDIACTIONFORMATA lpdiaf,
556 LPCSTR lpszUserName,
557 DWORD dwFlags)
558{
559 FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
560
561 return DI_OK;
562}
563
564HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface,
565 LPDIACTIONFORMATA lpdiaf,
566 LPCSTR lpszUserName,
567 DWORD dwFlags)
568{
569 FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
570
571 return DI_OK;
572}
573
574HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface,
575 LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)
576{
577 FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
578
579 return DI_OK;
580}
Note: See TracBrowser for help on using the repository browser.