8d62ffc46987aa25392f71d4588c0b11b06ed490
[reactos.git] / rostests / winetests / dinput / keyboard.c
1 /*
2 * Copyright (c) 2005 Robert Reif
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #define WIN32_NO_STATUS
20 #define _INC_WINDOWS
21 #define COM_NO_WINDOWS_H
22
23 #define DIRECTINPUT_VERSION 0x0700
24
25 #define COBJMACROS
26 //#include <windows.h>
27
28 //#include <math.h>
29 //#include <stdio.h>
30 //#include <stdlib.h>
31
32 #include <wine/test.h>
33 //#include "windef.h"
34 //#include "wingdi.h"
35 #include <dinput.h>
36
37 static void acquire_tests(IDirectInputA *pDI, HWND hwnd)
38 {
39 HRESULT hr;
40 IDirectInputDeviceA *pKeyboard;
41 BYTE kbd_state[256];
42 LONG custom_state[6];
43 int i;
44 DIOBJECTDATAFORMAT dodf[] =
45 {
46 { &GUID_Key, sizeof(LONG) * 0, DIDFT_MAKEINSTANCE(DIK_Q)|DIDFT_BUTTON, 0 },
47 { &GUID_Key, sizeof(LONG) * 1, DIDFT_MAKEINSTANCE(DIK_W)|DIDFT_BUTTON, 0 },
48 { &GUID_Key, sizeof(LONG) * 2, DIDFT_MAKEINSTANCE(DIK_E)|DIDFT_BUTTON, 0 },
49 { &GUID_Key, sizeof(LONG) * 4, DIDFT_MAKEINSTANCE(DIK_R)|DIDFT_BUTTON, 0 },
50 };
51
52 DIDATAFORMAT df;
53 df.dwSize = sizeof( df );
54 df.dwObjSize = sizeof( DIOBJECTDATAFORMAT );
55 df.dwFlags = DIDF_RELAXIS;
56 df.dwDataSize = sizeof( custom_state );
57 df.dwNumObjs = sizeof( dodf )/sizeof( dodf[0] );
58 df.rgodf = dodf;
59
60 hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKeyboard, NULL);
61 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
62 if (FAILED(hr)) return;
63
64 hr = IDirectInputDevice_SetDataFormat(pKeyboard, &c_dfDIKeyboard);
65 ok(SUCCEEDED(hr), "IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
66 hr = IDirectInputDevice_SetCooperativeLevel(pKeyboard, NULL, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
67 ok(SUCCEEDED(hr), "IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
68 hr = IDirectInputDevice_GetDeviceState(pKeyboard, 10, kbd_state);
69 ok(hr == DIERR_NOTACQUIRED, "IDirectInputDevice_GetDeviceState(10,) should have failed: %08x\n", hr);
70 hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(kbd_state), kbd_state);
71 ok(hr == DIERR_NOTACQUIRED, "IDirectInputDevice_GetDeviceState() should have failed: %08x\n", hr);
72 hr = IDirectInputDevice_Unacquire(pKeyboard);
73 ok(hr == S_FALSE, "IDirectInputDevice_Unacquire() should have failed: %08x\n", hr);
74 hr = IDirectInputDevice_Acquire(pKeyboard);
75 ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
76 hr = IDirectInputDevice_Acquire(pKeyboard);
77 ok(hr == S_FALSE, "IDirectInputDevice_Acquire() should have failed: %08x\n", hr);
78 hr = IDirectInputDevice_GetDeviceState(pKeyboard, 10, kbd_state);
79 ok(hr == DIERR_INVALIDPARAM, "IDirectInputDevice_GetDeviceState(10,) should have failed: %08x\n", hr);
80 hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(kbd_state), kbd_state);
81 ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
82 hr = IDirectInputDevice_Unacquire(pKeyboard);
83 ok(SUCCEEDED(hr), "IDirectInputDevice_Uncquire() failed: %08x\n", hr);
84 hr = IDirectInputDevice_SetDataFormat( pKeyboard , &df );
85 ok(SUCCEEDED(hr), "IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
86 hr = IDirectInputDevice_Acquire(pKeyboard);
87 ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
88 hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
89 ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState(4,) failed: %08x\n", hr);
90 hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(kbd_state), kbd_state);
91 ok(hr == DIERR_INVALIDPARAM, "IDirectInputDevice_GetDeviceState(256,) should have failed: %08x\n", hr);
92
93 memset(custom_state, 0x56, sizeof(custom_state));
94 IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
95 for (i = 0; i < sizeof(custom_state) / sizeof(custom_state[0]); i++)
96 ok(custom_state[i] == 0, "Should be zeroed, got 0x%08x\n", custom_state[i]);
97
98 /* simulate some keyboard input */
99 SetFocus(hwnd);
100 keybd_event('Q', 0, 0, 0);
101 hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
102 ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
103 if (!custom_state[0])
104 win_skip("Keyboard event not processed, skipping test\n");
105 else
106 {
107 /* unacquiring should reset the device state */
108 hr = IDirectInputDevice_Unacquire(pKeyboard);
109 ok(SUCCEEDED(hr), "IDirectInputDevice_Unacquire() failed: %08x\n", hr);
110 hr = IDirectInputDevice_Acquire(pKeyboard);
111 ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
112 hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
113 ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState failed: %08x\n", hr);
114 for (i = 0; i < sizeof(custom_state) / sizeof(custom_state[0]); i++)
115 ok(custom_state[i] == 0, "Should be zeroed, got 0x%08x\n", custom_state[i]);
116 }
117 keybd_event('Q', 0, KEYEVENTF_KEYUP, 0);
118
119 if (pKeyboard) IUnknown_Release(pKeyboard);
120 }
121
122 static const HRESULT SetCoop_null_window[16] = {
123 E_INVALIDARG, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG,
124 E_INVALIDARG, E_HANDLE, E_HANDLE, E_INVALIDARG,
125 E_INVALIDARG, E_HANDLE, S_OK, E_INVALIDARG,
126 E_INVALIDARG, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG};
127
128 static const HRESULT SetCoop_real_window[16] = {
129 E_INVALIDARG, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG,
130 E_INVALIDARG, S_OK, S_OK, E_INVALIDARG,
131 E_INVALIDARG, E_NOTIMPL, S_OK, E_INVALIDARG,
132 E_INVALIDARG, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG};
133
134 static const HRESULT SetCoop_child_window[16] = {
135 E_INVALIDARG, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG,
136 E_INVALIDARG, E_HANDLE, E_HANDLE, E_INVALIDARG,
137 E_INVALIDARG, E_HANDLE, E_HANDLE, E_INVALIDARG,
138 E_INVALIDARG, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG};
139
140 static void test_set_coop(IDirectInputA *pDI, HWND hwnd)
141 {
142 HRESULT hr;
143 IDirectInputDeviceA *pKeyboard = NULL;
144 int i;
145 HWND child;
146
147 hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKeyboard, NULL);
148 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
149 if (FAILED(hr)) return;
150
151 for (i=0; i<16; i++)
152 {
153 hr = IDirectInputDevice_SetCooperativeLevel(pKeyboard, NULL, i);
154 ok(hr == SetCoop_null_window[i], "SetCooperativeLevel(NULL, %d): %08x\n", i, hr);
155 }
156 for (i=0; i<16; i++)
157 {
158 hr = IDirectInputDevice_SetCooperativeLevel(pKeyboard, hwnd, i);
159 ok(hr == SetCoop_real_window[i], "SetCooperativeLevel(hwnd, %d): %08x\n", i, hr);
160 }
161
162 child = CreateWindowA("static", "Title", WS_CHILD | WS_VISIBLE, 10, 10, 50, 50, hwnd, NULL,
163 NULL, NULL);
164 ok(child != NULL, "err: %d\n", GetLastError());
165
166 for (i=0; i<16; i++)
167 {
168 hr = IDirectInputDevice_SetCooperativeLevel(pKeyboard, child, i);
169 ok(hr == SetCoop_child_window[i], "SetCooperativeLevel(child, %d): %08x\n", i, hr);
170 }
171
172 DestroyWindow(child);
173 if (pKeyboard) IUnknown_Release(pKeyboard);
174 }
175
176 static void test_get_prop(IDirectInputA *pDI, HWND hwnd)
177 {
178 HRESULT hr;
179 IDirectInputDeviceA *pKeyboard = NULL;
180 DIPROPRANGE diprg;
181
182 hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKeyboard, NULL);
183 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
184 if (FAILED(hr)) return;
185
186 memset(&diprg, 0, sizeof(diprg));
187 diprg.diph.dwSize = sizeof(DIPROPRANGE);
188 diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
189 diprg.diph.dwHow = DIPH_DEVICE;
190 diprg.diph.dwObj = 0;
191
192 hr = IDirectInputDevice_GetProperty(pKeyboard, DIPROP_RANGE, &diprg.diph);
193 ok(hr == DIERR_UNSUPPORTED, "IDirectInputDevice_GetProperty() did not return DIPROP_RANGE but: %08x\n", hr);
194
195 if (pKeyboard) IUnknown_Release(pKeyboard);
196 }
197
198 static void test_capabilities(IDirectInputA *pDI, HWND hwnd)
199 {
200 HRESULT hr;
201 IDirectInputDeviceA *pKeyboard = NULL;
202 DIDEVCAPS caps;
203
204 hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKeyboard, NULL);
205 ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
206 if (FAILED(hr)) return;
207
208 caps.dwSize = sizeof(caps);
209 hr = IDirectInputDevice_GetCapabilities(pKeyboard, &caps);
210
211 ok (SUCCEEDED(hr), "GetCapabilities failed: 0x%08x\n", hr);
212 ok (caps.dwFlags & DIDC_ATTACHED, "GetCapabilities dwFlags: 0x%08x\n", caps.dwFlags);
213 ok (LOWORD(LOBYTE(caps.dwDevType)) == DIDEVTYPE_KEYBOARD,
214 "GetCapabilities invalid device type for dwDevType: 0x%08x\n", caps.dwDevType);
215 ok (LOWORD(HIBYTE(caps.dwDevType)) != DIDEVTYPEKEYBOARD_UNKNOWN,
216 "GetCapabilities invalid device subtype for dwDevType: 0x%08x\n", caps.dwDevType);
217
218 IUnknown_Release(pKeyboard);
219 }
220
221 static void keyboard_tests(DWORD version)
222 {
223 HRESULT hr;
224 IDirectInputA *pDI = NULL;
225 HINSTANCE hInstance = GetModuleHandleW(NULL);
226 HWND hwnd;
227 ULONG ref = 0;
228
229 hr = DirectInputCreateA(hInstance, version, &pDI, NULL);
230 if (hr == DIERR_OLDDIRECTINPUTVERSION)
231 {
232 skip("Tests require a newer dinput version\n");
233 return;
234 }
235 ok(SUCCEEDED(hr), "DirectInputCreateA() failed: %08x\n", hr);
236 if (FAILED(hr)) return;
237
238 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 200, 200,
239 NULL, NULL, NULL, NULL);
240 ok(hwnd != NULL, "err: %d\n", GetLastError());
241
242 if (hwnd)
243 {
244 acquire_tests(pDI, hwnd);
245 test_set_coop(pDI, hwnd);
246 test_get_prop(pDI, hwnd);
247 test_capabilities(pDI, hwnd);
248 }
249
250 DestroyWindow(hwnd);
251 if (pDI) ref = IUnknown_Release(pDI);
252 ok(!ref, "IDirectInput_Release() reference count = %d\n", ref);
253 }
254
255 START_TEST(keyboard)
256 {
257 CoInitialize(NULL);
258
259 keyboard_tests(0x0700);
260
261 CoUninitialize();
262 }