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

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

Resync with last X11 licensed Wine

File size: 13.8 KB
Line 
1/* DirectInput Device
2 *
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 *
6 */
7
8/* This file contains all the Device specific functions that can be used as stubs
9 by real device implementations.
10
11 It also contains all the helper functions.
12*/
13#include "config.h"
14
15#include <string.h>
16#include "debugtools.h"
17#include "winbase.h"
18#include "winerror.h"
19#include "windef.h"
20#include "dinput.h"
21#include "device_private.h"
22
23DEFAULT_DEBUG_CHANNEL(dinput);
24
25/******************************************************************************
26 * Various debugging tools
27 */
28void _dump_cooperativelevel_DI(DWORD dwFlags) {
29 int i;
30 const struct {
31 DWORD mask;
32 char *name;
33 } flags[] = {
34#define FE(x) { x, #x},
35 FE(DISCL_BACKGROUND)
36 FE(DISCL_EXCLUSIVE)
37 FE(DISCL_FOREGROUND)
38 FE(DISCL_NONEXCLUSIVE)
39#undef FE
40 };
41 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
42 if (flags[i].mask & dwFlags)
43 DPRINTF("%s ",flags[i].name);
44 DPRINTF("\n");
45}
46
47void _dump_EnumObjects_flags(DWORD dwFlags) {
48 int i;
49 const struct {
50 DWORD mask;
51 char *name;
52 } flags[] = {
53#define FE(x) { x, #x},
54 FE(DIDFT_ABSAXIS)
55 FE(DIDFT_ALL)
56 FE(DIDFT_AXIS)
57 FE(DIDFT_BUTTON)
58 FE(DIDFT_COLLECTION)
59 FE(DIDFT_FFACTUATOR)
60 FE(DIDFT_FFEFFECTTRIGGER)
61 FE(DIDFT_NOCOLLECTION)
62 FE(DIDFT_NODATA)
63 FE(DIDFT_OUTPUT)
64 FE(DIDFT_POV)
65 FE(DIDFT_PSHBUTTON)
66 FE(DIDFT_RELAXIS)
67 FE(DIDFT_TGLBUTTON)
68#undef FE
69 };
70 if (dwFlags == DIDFT_ALL) {
71 DPRINTF("DIDFT_ALL");
72 return;
73 }
74 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
75 if (flags[i].mask & dwFlags)
76 DPRINTF("%s ",flags[i].name);
77 if (dwFlags & DIDFT_INSTANCEMASK)
78 DPRINTF("Instance(%04lx) ", dwFlags >> 8);
79}
80
81void _dump_DIPROPHEADER(DIPROPHEADER *diph) {
82 DPRINTF(" - dwObj = 0x%08lx\n", diph->dwObj);
83 DPRINTF(" - dwHow = %s\n",
84 ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" :
85 ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" :
86 ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown")));
87}
88
89void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) {
90 if (TRACE_ON(dinput)) {
91 DPRINTF(" - enumerating : 0x%08lx - %2ld - 0x%08lx - %s\n",
92 ddoi->guidType.Data1, ddoi->dwOfs, ddoi->dwType, ddoi->tszName);
93 }
94}
95
96/* Conversion between internal data buffer and external data buffer */
97void fill_DataFormat(void *out, void *in, DataFormat *df) {
98 int i;
99 char *in_c = (char *) in;
100 char *out_c = (char *) out;
101
102 if (df->dt == NULL) {
103 /* This means that the app uses Wine's internal data format */
104 memcpy(out, in, df->internal_format_size);
105 } else {
106 for (i = 0; i < df->size; i++) {
107 if (df->dt[i].offset_in >= 0) {
108 switch (df->dt[i].size) {
109 case 1:
110 TRACE("Copying (c) to %d from %d (value %d)\n",
111 df->dt[i].offset_out, df->dt[i].offset_in, *((char *) (in_c + df->dt[i].offset_in)));
112 *((char *) (out_c + df->dt[i].offset_out)) = *((char *) (in_c + df->dt[i].offset_in));
113 break;
114
115 case 2:
116 TRACE("Copying (s) to %d from %d (value %d)\n",
117 df->dt[i].offset_out, df->dt[i].offset_in, *((short *) (in_c + df->dt[i].offset_in)));
118 *((short *) (out_c + df->dt[i].offset_out)) = *((short *) (in_c + df->dt[i].offset_in));
119 break;
120
121 case 4:
122 TRACE("Copying (i) to %d from %d (value %d)\n",
123 df->dt[i].offset_out, df->dt[i].offset_in, *((int *) (in_c + df->dt[i].offset_in)));
124 *((int *) (out_c + df->dt[i].offset_out)) = *((int *) (in_c + df->dt[i].offset_in));
125 break;
126
127 default:
128 memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size);
129 }
130 } else {
131 switch (df->dt[i].size) {
132 case 1:
133 TRACE("Copying (c) to %d default value %d\n",
134 df->dt[i].offset_out, df->dt[i].value);
135 *((char *) (out_c + df->dt[i].offset_out)) = (char) df->dt[i].value;
136 break;
137
138 case 2:
139 TRACE("Copying (s) to %d default value %d\n",
140 df->dt[i].offset_out, df->dt[i].value);
141 *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value;
142 break;
143
144 case 4:
145 TRACE("Copying (i) to %d default value %d\n",
146 df->dt[i].offset_out, df->dt[i].value);
147 *((int *) (out_c + df->dt[i].offset_out)) = (int) df->dt[i].value;
148 break;
149
150 default:
151 memset((out_c + df->dt[i].offset_out), df->dt[i].size, 0);
152 }
153 }
154 }
155 }
156}
157
158DataFormat *create_DataFormat(DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) {
159 DataFormat *ret;
160 DataTransform *dt;
161 int i, j;
162 int same = 1;
163 int *done;
164 int index = 0;
165
166 ret = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat));
167
168 done = (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format->dwNumObjs);
169 memset(done, 0, sizeof(int) * asked_format->dwNumObjs);
170
171 dt = (DataTransform *) HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform));
172
173 TRACE("Creating DataTransform : \n");
174
175 for (i = 0; i < wine_format->dwNumObjs; i++) {
176 offset[i] = -1;
177
178 for (j = 0; j < asked_format->dwNumObjs; j++) {
179 if (done[j] == 1)
180 continue;
181
182 if (((asked_format->rgodf[j].pguid == NULL) || (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid)))
183 &&
184 (wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType)) {
185
186 done[j] = 1;
187
188 TRACE("Matching : \n");
189 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
190 j, debugstr_guid(asked_format->rgodf[j].pguid),
191 asked_format->rgodf[j].dwOfs,
192 DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType));
193
194 TRACE(" - Wine (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
195 j, debugstr_guid(wine_format->rgodf[i].pguid),
196 wine_format->rgodf[i].dwOfs,
197 DIDFT_GETTYPE(wine_format->rgodf[i].dwType), DIDFT_GETINSTANCE(wine_format->rgodf[i].dwType));
198
199 if (wine_format->rgodf[i].dwType & DIDFT_BUTTON)
200 dt[index].size = sizeof(BYTE);
201 else
202 dt[index].size = sizeof(DWORD);
203 dt[index].offset_in = wine_format ->rgodf[i].dwOfs;
204 dt[index].offset_out = asked_format->rgodf[j].dwOfs;
205 dt[index].value = 0;
206 index++;
207
208 if (wine_format->rgodf[i].dwOfs != asked_format->rgodf[j].dwOfs)
209 same = 0;
210
211 offset[i] = asked_format->rgodf[j].dwOfs;
212 break;
213 }
214 }
215
216 if (j == asked_format->dwNumObjs)
217 same = 0;
218 }
219
220 TRACE("Setting to default value :\n");
221 for (j = 0; j < asked_format->dwNumObjs; j++) {
222 if (done[j] == 0) {
223 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
224 j, debugstr_guid(asked_format->rgodf[j].pguid),
225 asked_format->rgodf[j].dwOfs,
226 DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType));
227
228
229 if (asked_format->rgodf[j].dwType & DIDFT_BUTTON)
230 dt[index].size = sizeof(BYTE);
231 else
232 dt[index].size = sizeof(DWORD);
233 dt[index].offset_in = -1;
234 dt[index].offset_out = asked_format->rgodf[j].dwOfs;
235 dt[index].value = 0;
236 index++;
237
238 same = 0;
239 }
240 }
241
242 ret->internal_format_size = wine_format->dwDataSize;
243 ret->size = index;
244 if (same) {
245 ret->dt = NULL;
246 HeapFree(GetProcessHeap(), 0, dt);
247 } else {
248 ret->dt = dt;
249 }
250
251 HeapFree(GetProcessHeap(), 0, done);
252
253 return ret;
254}
255
256/******************************************************************************
257 * IDirectInputDeviceA
258 */
259
260HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
261 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
262) {
263 int i;
264 ICOM_THIS(IDirectInputDevice2AImpl,iface);
265
266 TRACE("(this=%p,%p)\n",This,df);
267
268 TRACE("df.dwSize=%ld\n",df->dwSize);
269 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
270 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
271 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
272 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
273
274 for (i=0;i<df->dwNumObjs;i++) {
275 TRACE("df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid));
276 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
277 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
278 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
279 }
280 return 0;
281}
282
283HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
284 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
285) {
286 ICOM_THIS(IDirectInputDevice2AImpl,iface);
287 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
288 if (TRACE_ON(dinput))
289 _dump_cooperativelevel_DI(dwflags);
290 return 0;
291}
292
293HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
294 LPDIRECTINPUTDEVICE2A iface,HANDLE hnd
295) {
296 ICOM_THIS(IDirectInputDevice2AImpl,iface);
297 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
298 return 0;
299}
300
301ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface)
302{
303 ICOM_THIS(IDirectInputDevice2AImpl,iface);
304 This->ref--;
305 if (This->ref)
306 return This->ref;
307 HeapFree(GetProcessHeap(),0,This);
308 return 0;
309}
310
311HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
312 LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj
313)
314{
315 ICOM_THIS(IDirectInputDevice2AImpl,iface);
316
317 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
318 if (IsEqualGUID(&IID_IUnknown,riid)) {
319 IDirectInputDevice2_AddRef(iface);
320 *ppobj = This;
321 return 0;
322 }
323 if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) {
324 IDirectInputDevice2_AddRef(iface);
325 *ppobj = This;
326 return 0;
327 }
328 if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) {
329 IDirectInputDevice2_AddRef(iface);
330 *ppobj = This;
331 return 0;
332 }
333 TRACE("Unsupported interface !\n");
334 return E_FAIL;
335}
336
337ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
338 LPDIRECTINPUTDEVICE2A iface)
339{
340 ICOM_THIS(IDirectInputDevice2AImpl,iface);
341 return ++This->ref;
342}
343
344HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
345 LPDIRECTINPUTDEVICE2A iface,
346 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
347 LPVOID lpvRef,
348 DWORD dwFlags)
349{
350 FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
351 if (TRACE_ON(dinput)) {
352 DPRINTF(" - flags = ");
353 _dump_EnumObjects_flags(dwFlags);
354 DPRINTF("\n");
355 }
356
357 return DI_OK;
358}
359
360HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
361 LPDIRECTINPUTDEVICE2A iface,
362 REFGUID rguid,
363 LPDIPROPHEADER pdiph)
364{
365 FIXME("(this=%p,%s,%p): stub!\n",
366 iface, debugstr_guid(rguid), pdiph);
367
368 if (TRACE_ON(dinput))
369 _dump_DIPROPHEADER(pdiph);
370
371 return DI_OK;
372}
373
374HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
375 LPDIRECTINPUTDEVICE2A iface,
376 LPDIDEVICEOBJECTINSTANCEA pdidoi,
377 DWORD dwObj,
378 DWORD dwHow)
379{
380 FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
381 iface, pdidoi, dwObj, dwHow);
382
383 return DI_OK;
384}
385
386HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
387 LPDIRECTINPUTDEVICE2A iface,
388 LPDIDEVICEINSTANCEA pdidi)
389{
390 FIXME("(this=%p,%p): stub!\n",
391 iface, pdidi);
392
393 return DI_OK;
394}
395
396HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
397 LPDIRECTINPUTDEVICE2A iface,
398 HWND hwndOwner,
399 DWORD dwFlags)
400{
401 FIXME("(this=%p,0x%08x,0x%08lx): stub!\n",
402 iface, hwndOwner, dwFlags);
403
404 return DI_OK;
405}
406
407HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
408 LPDIRECTINPUTDEVICE2A iface,
409 HINSTANCE hinst,
410 DWORD dwVersion,
411 REFGUID rguid)
412{
413 FIXME("(this=%p,%d,%ld,%s): stub!\n",
414 iface, hinst, dwVersion, debugstr_guid(rguid));
415 return DI_OK;
416}
417
418/******************************************************************************
419 * IDirectInputDevice2A
420 */
421
422HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
423 LPDIRECTINPUTDEVICE2A iface,
424 REFGUID rguid,
425 LPCDIEFFECT lpeff,
426 LPDIRECTINPUTEFFECT *ppdef,
427 LPUNKNOWN pUnkOuter)
428{
429 FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
430 iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter);
431 return DI_OK;
432}
433
434HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
435 LPDIRECTINPUTDEVICE2A iface,
436 LPDIENUMEFFECTSCALLBACKA lpCallback,
437 LPVOID lpvRef,
438 DWORD dwFlags)
439{
440 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
441 iface, lpCallback, lpvRef, dwFlags);
442
443 if (lpCallback)
444 lpCallback(NULL, lpvRef);
445 return DI_OK;
446}
447
448HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
449 LPDIRECTINPUTDEVICE2A iface,
450 LPDIEFFECTINFOA lpdei,
451 REFGUID rguid)
452{
453 FIXME("(this=%p,%p,%s): stub!\n",
454 iface, lpdei, debugstr_guid(rguid));
455 return DI_OK;
456}
457
458HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
459 LPDIRECTINPUTDEVICE2A iface,
460 LPDWORD pdwOut)
461{
462 FIXME("(this=%p,%p): stub!\n",
463 iface, pdwOut);
464 return DI_OK;
465}
466
467HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
468 LPDIRECTINPUTDEVICE2A iface,
469 DWORD dwFlags)
470{
471 FIXME("(this=%p,0x%08lx): stub!\n",
472 iface, dwFlags);
473 return DI_OK;
474}
475
476HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
477 LPDIRECTINPUTDEVICE2A iface,
478 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
479 LPVOID lpvRef,
480 DWORD dwFlags)
481{
482 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
483 iface, lpCallback, lpvRef, dwFlags);
484 if (lpCallback)
485 lpCallback(NULL, lpvRef);
486 return DI_OK;
487}
488
489HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
490 LPDIRECTINPUTDEVICE2A iface,
491 LPDIEFFESCAPE lpDIEEsc)
492{
493 FIXME("(this=%p,%p): stub!\n",
494 iface, lpDIEEsc);
495 return DI_OK;
496}
497
498HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
499 LPDIRECTINPUTDEVICE2A iface)
500{
501 /* Because wine devices do not need to be polled, just return DI_NOEFFECT */
502 return DI_NOEFFECT;
503}
504
505HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
506 LPDIRECTINPUTDEVICE2A iface,
507 DWORD cbObjectData,
508 LPDIDEVICEOBJECTDATA rgdod,
509 LPDWORD pdwInOut,
510 DWORD dwFlags)
511{
512 FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
513 iface, cbObjectData, rgdod, pdwInOut, dwFlags);
514
515 return DI_OK;
516}
517
518HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE7A iface,
519 LPCSTR lpszFileName,
520 LPDIENUMEFFECTSINFILECALLBACK pec,
521 LPVOID pvRef,
522 DWORD dwFlags)
523{
524 FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);
525
526 return DI_OK;
527}
528
529HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE7A iface,
530 LPCSTR lpszFileName,
531 DWORD dwEntries,
532 LPDIFILEEFFECT rgDiFileEft,
533 DWORD dwFlags)
534{
535 FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
536
537 return DI_OK;
538}
Note: See TracBrowser for help on using the repository browser.