Update the modemn status bit that indicates whether the RLSD line is
[wine.git] / windows / dinput.c
blobc2c72d4170c321f1047e9f3029e9523fb8f4f285
1 /* DirectInput
3 * Copyright 1998 Marcus Meissner
4 */
5 /* Status:
7 * - Tomb Raider 2 Demo:
8 * Playable using keyboard only.
9 * - WingCommander Prophecy Demo:
10 * Doesn't get Input Focus.
12 * FIXME: The keyboard handling needs to (and will) be merged into keyboard.c
13 * (The current implementation is currently only a proof of concept and
14 * an utter mess.)
17 #include "config.h"
18 #include <string.h>
19 #include <unistd.h>
20 #include <assert.h>
21 #include <X11/Xlib.h>
22 #include <sys/signal.h>
24 #include "windows.h"
25 #include "winerror.h"
26 #include "shell.h"
27 #include "ole.h"
28 #include "compobj.h"
29 #include "interfaces.h"
30 #include "gdi.h"
31 #include "heap.h"
32 #include "win.h"
33 #include "dinput.h"
34 #include "debug.h"
36 extern BYTE InputKeyStateTable[256];
37 extern BYTE vkey2scode[512];
39 static IDirectInputA_VTable ddiavt;
40 static IDirectInputDeviceA_VTable SysKeyboardAvt;
41 static IDirectInputDeviceA_VTable SysMouseAvt;
43 /******************************************************************************
44 * DirectInputCreate32A
46 HRESULT WINAPI DirectInputCreate32A(HINSTANCE32 hinst, DWORD dwVersion, LPDIRECTINPUT32A *ppDI, LPUNKNOWN punkOuter) {
47 TRACE(dinput, "(0x%08lx,%04lx,%p,%p)\n",
48 (DWORD)hinst,dwVersion,ppDI,punkOuter
50 (*ppDI) = (LPDIRECTINPUT32A)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInput32A));
51 (*ppDI)->ref = 1;
52 (*ppDI)->lpvtbl = &ddiavt;
53 return 0;
55 /******************************************************************************
56 * IDirectInputA_EnumDevices
58 static HRESULT WINAPI IDirectInputA_EnumDevices(
59 LPDIRECTINPUT32A this,DWORD dwFlags,LPDIENUMDEVICESCALLBACK32A cb,
60 LPVOID context,DWORD x
61 ) {
62 FIXME(dinput,"(this=%p,0x%08lx,%p,%p,0x%08lx): stub\n",this,dwFlags,cb,context,x);
63 return 0;
66 static ULONG WINAPI IDirectInputA_AddRef(LPDIRECTINPUT32A this) {
67 return ++(this->ref);
70 static ULONG WINAPI IDirectInputA_Release(LPDIRECTINPUT32A this) {
71 if (!(--this->ref)) {
72 HeapFree(GetProcessHeap(),0,this);
73 return 0;
75 return this->ref;
78 static HRESULT WINAPI IDirectInputA_CreateDevice(
79 LPDIRECTINPUT32A this,REFGUID rguid,LPDIRECTINPUTDEVICE32A* pdev,
80 LPUNKNOWN punk
81 ) {
82 char xbuf[50];
84 WINE_StringFromCLSID(rguid,xbuf);
85 FIXME(dinput,"(this=%p,%s,%p,%p): stub\n",this,xbuf,pdev,punk);
86 if (!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) {
87 *pdev = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboard32A));
88 (*pdev)->ref = 1;
89 (*pdev)->lpvtbl = &SysKeyboardAvt;
90 memcpy(&((*pdev)->guid),rguid,sizeof(*rguid));
91 memset(((LPSYSKEYBOARD32A)(*pdev))->keystate,0,256);
92 return 0;
94 if (!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) {
95 *pdev = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectInputDevice32A));
96 (*pdev)->ref = 1;
97 (*pdev)->lpvtbl = &SysMouseAvt;
98 memcpy(&((*pdev)->guid),rguid,sizeof(*rguid));
99 return 0;
101 return E_FAIL;
104 static HRESULT WINAPI IDirectInputA_QueryInterface(
105 LPDIRECTINPUT32A this,REFIID riid,LPVOID *ppobj
107 char xbuf[50];
109 WINE_StringFromCLSID(riid,xbuf);
110 TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ppobj);
111 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
112 this->lpvtbl->fnAddRef(this);
113 *ppobj = this;
114 return 0;
116 if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
117 this->lpvtbl->fnAddRef(this);
118 *ppobj = this;
119 return 0;
121 return E_FAIL;
124 static HRESULT WINAPI IDirectInputA_Initialize(
125 LPDIRECTINPUT32A this,HINSTANCE32 hinst,DWORD x
127 return DIERR_ALREADYINITIALIZED;
130 static IDirectInputA_VTable ddiavt= {
131 IDirectInputA_QueryInterface,
132 IDirectInputA_AddRef,
133 IDirectInputA_Release,
134 IDirectInputA_CreateDevice,
135 IDirectInputA_EnumDevices,
136 (void*)6,
137 (void*)7,
138 IDirectInputA_Initialize
141 /******************************************************************************
142 * IDirectInputDeviceA
144 static HRESULT WINAPI IDirectInputDeviceA_SetDataFormat(
145 LPDIRECTINPUTDEVICE32A this,LPCDIDATAFORMAT df
148 int i;
149 TRACE(dinput,"(this=%p,%p)\n",this,df);
151 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
152 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
153 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
154 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
155 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
157 for (i=0;i<df->dwNumObjs;i++) {
158 char xbuf[50];
160 if (df->rgodf[i].pguid)
161 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
162 else
163 strcpy(xbuf,"<no guid>");
164 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
165 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
166 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
167 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
170 return 0;
173 static HRESULT WINAPI IDirectInputDeviceA_SetCooperativeLevel(
174 LPDIRECTINPUTDEVICE32A this,HWND32 hwnd,DWORD dwflags
176 FIXME(dinput,"(this=%p,0x%08lx,0x%08lx): stub\n",this,(DWORD)hwnd,dwflags);
177 return 0;
180 static HRESULT WINAPI IDirectInputDeviceA_SetProperty(
181 LPDIRECTINPUTDEVICE32A this,REFGUID rguid,LPCDIPROPHEADER ph
183 char xbuf[50];
185 if (HIWORD(rguid))
186 WINE_StringFromCLSID(rguid,xbuf);
187 else
188 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
189 TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ph);
190 if (!HIWORD(rguid)) {
191 switch ((DWORD)rguid) {
192 case DIPROP_BUFFERSIZE: {
193 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
195 TRACE(dinput,"buffersize = %ld\n",pd->dwData);
196 break;
198 default:
199 WARN(dinput,"Unknown type %ld\n",(DWORD)rguid);
200 break;
203 return 0;
206 static HRESULT WINAPI IDirectInputDeviceA_SetEventNotification(
207 LPDIRECTINPUTDEVICE32A this,HANDLE32 hnd
209 FIXME(dinput,"(this=%p,0x%08lx): stub\n",this,(DWORD)hnd);
210 return 0;
213 static HRESULT WINAPI IDirectInputDeviceA_GetDeviceData(
214 LPDIRECTINPUTDEVICE32A this,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
215 LPDWORD entries,DWORD flags
217 /* TRACE(dinput,"IDirectInputDeviceA(%p)->GetDeviceData(%ld,%p,%p(0x%08lx),0x%08lx)\n",this,dodsize,dod,entries,*entries,flags);*/
218 return 0;
222 static HRESULT WINAPI IDirectInputDeviceA_Acquire(LPDIRECTINPUTDEVICE32A this) {
223 FIXME(dinput,"(this=%p): stub\n",this);
224 return 0;
227 static HRESULT WINAPI IDirectInputDeviceA_Unacquire(LPDIRECTINPUTDEVICE32A this) {
228 FIXME(dinput,"(this=%p): stub\n",this);
229 return 0;
232 static ULONG WINAPI IDirectInputDeviceA_Release(LPDIRECTINPUTDEVICE32A this) {
233 this->ref--;
234 if (this->ref)
235 return this->ref;
236 HeapFree(GetProcessHeap(),0,this);
237 return 0;
240 static HRESULT WINAPI SysKeyboardA_SetProperty(
241 LPDIRECTINPUTDEVICE32A this,REFGUID rguid,LPCDIPROPHEADER ph
243 char xbuf[50];
245 if (HIWORD(rguid))
246 WINE_StringFromCLSID(rguid,xbuf);
247 else
248 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
249 TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ph);
250 TRACE(dinput,"(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
251 ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
252 if (!HIWORD(rguid)) {
253 switch ((DWORD)rguid) {
254 case DIPROP_BUFFERSIZE: {
255 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
257 TRACE(dinput,"(buffersize=%ld)\n",pd->dwData);
258 break;
260 default:
261 WARN(dinput,"Unknown type %ld\n",(DWORD)rguid);
262 break;
265 return 0;
268 static HRESULT WINAPI SysKeyboardA_GetDeviceState(
269 LPDIRECTINPUTDEVICE32A this,DWORD len,LPVOID ptr
271 if (len==256) {
272 int i;
274 memset(ptr,0,256);
275 for (i=0;i<256;i++)
276 if (InputKeyStateTable[i]&0x80) {
277 ((LPBYTE)ptr)[vkey2scode[i] ]=0x80;
278 ((LPBYTE)ptr)[vkey2scode[i]|0x80]=0x80;
280 return 0;
282 WARN(dinput,"whoops, SysKeyboardA_GetDeviceState got len %ld?\n",len);
283 return 0;
286 static HRESULT WINAPI SysKeyboardA_GetDeviceData(
287 LPDIRECTINPUTDEVICE32A this,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
288 LPDWORD entries,DWORD flags
290 int i,n,xentries;
291 LPSYSKEYBOARD32A kthis = (LPSYSKEYBOARD32A)this;
293 TRACE(dinput,"(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
294 this,dodsize,dod,entries,entries?*entries:0,flags);
295 if (entries)
296 xentries = *entries;
297 else
298 xentries = 1;
300 for (n=i=0;(i<256) && (n<*entries);i++) {
301 if (kthis->keystate[i] == (InputKeyStateTable[i]&0x80))
302 continue;
303 if (dod) {
304 /* add an entry */
305 dod[n].dwOfs = vkey2scode[i];
306 dod[n].dwData = InputKeyStateTable[i]&0x80;
307 dod[n].dwTimeStamp = 0; /* umm */
308 dod[n].dwSequence = 0; /* umm */
309 n++;
311 if (!(flags & DIGDD_PEEK))
312 kthis->keystate[i] = InputKeyStateTable[i]&0x80;
314 *entries = n;
315 return 0;
318 static HRESULT WINAPI SysKeyboardA_Acquire(LPDIRECTINPUTDEVICE32A this) {
319 FIXME(dinput,"(this=%p): stub\n",this);
320 return 0;
323 static HRESULT WINAPI SysKeyboardA_Unacquire(LPDIRECTINPUTDEVICE32A this) {
324 FIXME(dinput,"(this=%p): stub\n",this);
325 return 0;
329 static HRESULT WINAPI IDirectInputDeviceA_GetDeviceState(
330 LPDIRECTINPUTDEVICE32A this,DWORD len,LPVOID ptr
332 FIXME(dinput,"(this=%p,0x%08lx,%p): stub\n",this,len,ptr);
333 return 0;
336 static HRESULT WINAPI IDirectInputDeviceA_QueryInterface(
337 LPDIRECTINPUTDEVICE32A this,REFIID riid,LPVOID *ppobj
339 char xbuf[50];
341 WINE_StringFromCLSID(riid,xbuf);
342 TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ppobj);
343 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
344 this->lpvtbl->fnAddRef(this);
345 *ppobj = this;
346 return 0;
348 if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
349 this->lpvtbl->fnAddRef(this);
350 *ppobj = this;
351 return 0;
353 return E_FAIL;
356 static IDirectInputDeviceA_VTable SysKeyboardAvt={
357 IDirectInputDeviceA_QueryInterface,
358 (void*)2,
359 IDirectInputDeviceA_Release,
360 (void*)4,
361 (void*)5,
362 (void*)6,
363 SysKeyboardA_SetProperty,
364 SysKeyboardA_Acquire,
365 SysKeyboardA_Unacquire,
366 SysKeyboardA_GetDeviceState,
367 SysKeyboardA_GetDeviceData,
368 IDirectInputDeviceA_SetDataFormat,
369 IDirectInputDeviceA_SetEventNotification,
370 IDirectInputDeviceA_SetCooperativeLevel,
371 (void*)15,
372 (void*)16,
373 (void*)17,
374 (void*)18,
377 static IDirectInputDeviceA_VTable SysMouseAvt={
378 IDirectInputDeviceA_QueryInterface,
379 (void*)2,
380 IDirectInputDeviceA_Release,
381 (void*)4,
382 (void*)5,
383 (void*)6,
384 IDirectInputDeviceA_SetProperty,
385 IDirectInputDeviceA_Acquire,
386 IDirectInputDeviceA_Unacquire,
387 IDirectInputDeviceA_GetDeviceState,
388 IDirectInputDeviceA_GetDeviceData,
389 IDirectInputDeviceA_SetDataFormat,
390 IDirectInputDeviceA_SetEventNotification,
391 IDirectInputDeviceA_SetCooperativeLevel,
392 (void*)15,
393 (void*)16,
394 (void*)17,
395 (void*)18,