ReactOS 0.4.15-dev-7712-gbbbcd8e
joystick.c File Reference
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "wine/test.h"
#include "windef.h"
#include "wingdi.h"
#include "dinput.h"
Include dependency graph for joystick.c:

Go to the source code of this file.

Classes

struct  tagUserData
 
struct  tagJoystickInfo
 
struct  effect_id
 
struct  effect_enum
 

Macros

#define DIRECTINPUT_VERSION   0x0700
 
#define COBJMACROS
 

Typedefs

typedef struct tagUserData UserData
 
typedef struct tagJoystickInfo JoystickInfo
 

Functions

static HWND get_hwnd (void)
 
static int get_refcount (IUnknown *object)
 
static BOOL CALLBACK EnumAxes (const DIDEVICEOBJECTINSTANCEA *pdidoi, void *pContext)
 
static const struct effect_ideffect_from_guid (const GUID *guid)
 
static BOOL CALLBACK EnumEffects (const DIEFFECTINFOA *lpef, void *ref)
 
static BOOL CALLBACK EnumAllFeedback (const DIDEVICEINSTANCEA *lpddi, void *pvRef)
 
static BOOL CALLBACK EnumJoysticks (const DIDEVICEINSTANCEA *lpddi, void *pvRef)
 
static void joystick_tests (DWORD version)
 
static void test_enum_feedback (void)
 
 START_TEST (joystick)
 

Variables

static const DIOBJECTDATAFORMAT dfDIJoystickTest []
 
static const DIDATAFORMAT c_dfDIJoystickTest
 
static const struct effect_id effect_conversion []
 
static const HRESULT SetCoop_null_window [16]
 
static const HRESULT SetCoop_real_window [16]
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 21 of file joystick.c.

◆ DIRECTINPUT_VERSION

#define DIRECTINPUT_VERSION   0x0700

Definition at line 19 of file joystick.c.

Typedef Documentation

◆ JoystickInfo

◆ UserData

Function Documentation

◆ effect_from_guid()

static const struct effect_id * effect_from_guid ( const GUID guid)
static

Definition at line 176 of file joystick.c.

177{
178 unsigned int i;
179 for (i = 0; i < ARRAY_SIZE(effect_conversion); i++)
181 return &effect_conversion[i];
182 return NULL;
183}
#define ARRAY_SIZE(A)
Definition: main.h:33
#define NULL
Definition: types.h:112
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const GUID * guid
static const struct effect_id effect_conversion[]
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147

Referenced by EnumEffects().

◆ EnumAllFeedback()

static BOOL CALLBACK EnumAllFeedback ( const DIDEVICEINSTANCEA lpddi,
void pvRef 
)
static

Definition at line 273 of file joystick.c.

274{
275 trace("---- Device Information ----\n"
276 "Product Name : %s\n"
277 "Instance Name : %s\n"
278 "devType : 0x%08x\n"
279 "GUID Product : %s\n"
280 "GUID Instance : %s\n"
281 "HID Page : 0x%04x\n"
282 "HID Usage : 0x%04x\n",
283 lpddi->tszProductName,
284 lpddi->tszInstanceName,
285 lpddi->dwDevType,
288 lpddi->wUsagePage,
289 lpddi->wUsage);
290
291 ok(!(IsEqualGUID(&GUID_SysMouse, &lpddi->guidProduct) || IsEqualGUID(&GUID_SysKeyboard, &lpddi->guidProduct)), "Invalid device returned.\n");
292
293 return DIENUM_CONTINUE;
294}
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define DIENUM_CONTINUE
Definition: dinput.h:188
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
GUID guidProduct
Definition: dinput.h:414
GUID guidInstance
Definition: dinput.h:413
CHAR tszInstanceName[MAX_PATH]
Definition: dinput.h:416
CHAR tszProductName[MAX_PATH]
Definition: dinput.h:417
DWORD dwDevType
Definition: dinput.h:415

Referenced by test_enum_feedback().

◆ EnumAxes()

static BOOL CALLBACK EnumAxes ( const DIDEVICEOBJECTINSTANCEA pdidoi,
void pContext 
)
static

Definition at line 91 of file joystick.c.

92{
93 HRESULT hr;
94 JoystickInfo * info = pContext;
95
96 if (IsEqualIID(&pdidoi->guidType, &GUID_XAxis) ||
97 IsEqualIID(&pdidoi->guidType, &GUID_YAxis) ||
98 IsEqualIID(&pdidoi->guidType, &GUID_ZAxis) ||
99 IsEqualIID(&pdidoi->guidType, &GUID_RxAxis) ||
100 IsEqualIID(&pdidoi->guidType, &GUID_RyAxis) ||
101 IsEqualIID(&pdidoi->guidType, &GUID_RzAxis) ||
102 IsEqualIID(&pdidoi->guidType, &GUID_Slider))
103 {
104 DIPROPRANGE diprg;
105 DIPROPDWORD dipdw;
106
107 diprg.diph.dwSize = sizeof(DIPROPRANGE);
108 diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
109 diprg.diph.dwHow = DIPH_BYID;
110 diprg.diph.dwObj = pdidoi->dwType;
111
112 dipdw.diph.dwSize = sizeof(dipdw);
113 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
114 dipdw.diph.dwHow = DIPH_BYID;
115 dipdw.diph.dwObj = pdidoi->dwType;
116
118 ok(SUCCEEDED(hr), "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
119 ok(info->lMin == diprg.lMin && info->lMax == diprg.lMax, "Min/Max range invalid: "
120 "expected %d..%d got %d..%d\n", info->lMin, info->lMax, diprg.lMin, diprg.lMax);
121
122 diprg.lMin = -2000;
123 diprg.lMax = +2000;
124
126 ok(hr==E_INVALIDARG,"IDirectInputDevice_SetProperty() should have returned "
127 "E_INVALIDARG, returned: %08x\n", hr);
128
130 ok(hr==DI_OK,"IDirectInputDevice_SetProperty() failed: %08x\n", hr);
131
132 /* dead zone */
134 ok(SUCCEEDED(hr), "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
135 ok(info->dZone == dipdw.dwData, "deadzone invalid: expected %d got %d\n",
136 info->dZone, dipdw.dwData);
137
138 dipdw.dwData = 123;
139
141 ok(hr==DI_OK,"IDirectInputDevice_SetProperty() failed: %08x\n", hr);
142
143 /* ensure DIDOI_ASPECTPOSITION is set for axes objects */
144 ok(pdidoi->dwFlags & DIDOI_ASPECTPOSITION, "Missing DIDOI_ASPECTPOSITION, flags are 0x%x\n",
145 pdidoi->dwFlags);
146
147 info->axis++;
148 } else if (IsEqualIID(&pdidoi->guidType, &GUID_POV))
149 info->pov++;
150 else if (IsEqualIID(&pdidoi->guidType, &GUID_Button))
151 info->button++;
152
153 return DIENUM_CONTINUE;
154}
#define E_INVALIDARG
Definition: ddrawi.h:101
#define DIPROP_RANGE
Definition: dinput.h:892
#define IDirectInputDevice_GetProperty(p, a, b)
Definition: dinput.h:1606
#define DIPH_BYID
Definition: dinput.h:837
#define DIDOI_ASPECTPOSITION
Definition: dinput.h:820
#define DI_OK
Definition: dinput.h:128
#define IDirectInputDevice_SetProperty(p, a, b)
Definition: dinput.h:1607
#define DIPROP_DEADZONE
Definition: dinput.h:893
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
HRESULT hr
Definition: shlfolder.c:183
DIPROPHEADER diph
Definition: dinput.h:843
DWORD dwData
Definition: dinput.h:844
DWORD dwObj
Definition: dinput.h:830
DWORD dwSize
Definition: dinput.h:828
DWORD dwHeaderSize
Definition: dinput.h:829
DWORD dwHow
Definition: dinput.h:831
LONG lMin
Definition: dinput.h:850
LONG lMax
Definition: dinput.h:851
DIPROPHEADER diph
Definition: dinput.h:849

Referenced by EnumJoysticks().

◆ EnumEffects()

static BOOL CALLBACK EnumEffects ( const DIEFFECTINFOA lpef,
void ref 
)
static

Definition at line 194 of file joystick.c.

195{
196 const struct effect_id *id = effect_from_guid(&lpef->guid);
197 static union
198 {
200 DIPERIODIC periodic;
203 } specific;
204 struct effect_enum *data = ref;
205 int type = DIDFT_GETTYPE(lpef->dwEffType);
206
207 /* Insanity check */
208 if (!id)
209 {
210 ok(0, "unsupported effect enumerated, GUID %s!\n", wine_dbgstr_guid(&lpef->guid));
211 return DIENUM_CONTINUE;
212 }
213 trace("controller supports '%s' effect\n", id->name);
214 ok(type == id->dieft, "Invalid effect type, expected 0x%x, got 0x%x\n",
215 id->dieft, lpef->dwEffType);
216
217 /* Can't use custom for test as we don't know the data format */
218 if (type == DIEFT_CUSTOMFORCE)
219 return DIENUM_CONTINUE;
220
221 data->effect_count++;
222 data->effect_name = id->name;
223 data->guid = *id->guid;
224
225 ZeroMemory(&specific, sizeof(specific));
226 switch (type)
227 {
228 case DIEFT_PERIODIC:
229 data->eff.cbTypeSpecificParams = sizeof(specific.periodic);
230 data->eff.lpvTypeSpecificParams = &specific.periodic;
231 specific.periodic.dwMagnitude = DI_FFNOMINALMAX / 2;
232 specific.periodic.dwPeriod = DI_SECONDS; /* 1 second */
233 break;
235 data->eff.cbTypeSpecificParams = sizeof(specific.constant);
236 data->eff.lpvTypeSpecificParams = &specific.constant;
237 specific.constant.lMagnitude = DI_FFNOMINALMAX / 2;
238 break;
239 case DIEFT_RAMPFORCE:
240 data->eff.cbTypeSpecificParams = sizeof(specific.ramp);
241 data->eff.lpvTypeSpecificParams = &specific.ramp;
242 specific.ramp.lStart = -DI_FFNOMINALMAX / 2;
243 specific.ramp.lEnd = +DI_FFNOMINALMAX / 2;
244 break;
245 case DIEFT_CONDITION:
246 {
247 int i;
248 data->eff.cbTypeSpecificParams = sizeof(specific.condition);
249 data->eff.lpvTypeSpecificParams = specific.condition;
250 for (i = 0; i < 2; i++)
251 {
252 specific.condition[i].lNegativeCoefficient = -DI_FFNOMINALMAX / 2;
253 specific.condition[i].lPositiveCoefficient = +DI_FFNOMINALMAX / 2;
254 }
255 break;
256 }
257 }
258 return DIENUM_CONTINUE;
259}
#define DIEFT_CONDITION
Definition: dinput.h:996
#define DIEFT_CUSTOMFORCE
Definition: dinput.h:997
#define DIEFT_PERIODIC
Definition: dinput.h:995
#define DIEFT_CONSTANTFORCE
Definition: dinput.h:993
#define DI_FFNOMINALMAX
Definition: dinput.h:1038
#define DIEFT_RAMPFORCE
Definition: dinput.h:994
#define DIDFT_GETTYPE(n)
Definition: dinput.h:763
#define DI_SECONDS
Definition: dinput.h:1039
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum condition
Definition: glext.h:9255
GLuint id
Definition: glext.h:5910
static const struct effect_id * effect_from_guid(const GUID *guid)
Definition: joystick.c:176
static const BYTE ramp[17]
Definition: dib.c:2709
DWORD dwEffType
Definition: dinput.h:1127
char * name
Definition: compiler.c:66
Definition: send.c:48
#define ZeroMemory
Definition: winbase.h:1712

Referenced by DECLARE_INTERFACE_(), and EnumJoysticks().

◆ EnumJoysticks()

static BOOL CALLBACK EnumJoysticks ( const DIDEVICEINSTANCEA lpddi,
void pvRef 
)
static

Definition at line 296 of file joystick.c.

297{
298 HRESULT hr;
299 UserData * data = pvRef;
300 IDirectInputDeviceA *pJoystick;
302 DIDEVCAPS caps;
303 DIJOYSTATE2 js;
305 int i, count;
306 ULONG ref;
309 DIPROPDWORD dipw;
310 DIPROPSTRING dps;
312 WCHAR nameBuffer[MAX_PATH];
313 HWND hWnd = get_hwnd();
314 char oldstate[248], curstate[248];
315 DWORD axes[2] = {DIJOFS_X, DIJOFS_Y};
316 LONG direction[2] = {0, 0};
317 LPDIRECTINPUTEFFECT effect = NULL;
318 LONG cnt1, cnt2;
319 HWND real_hWnd;
321 DIPROPDWORD dip_gain_set, dip_gain_get;
322 struct effect_enum effect_data;
323
324 ok(data->version >= 0x0300, "Joysticks not supported in version 0x%04x\n", data->version);
325
327 ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
328 "E_POINTER, returned: %08x\n", hr);
329
330 hr = IDirectInput_CreateDevice(data->pDI, NULL, &pJoystick, NULL);
331 ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
332 "E_POINTER, returned: %08x\n", hr);
333
335 ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
336 "E_POINTER, returned: %08x\n", hr);
337
339 &pJoystick, NULL);
340 ok(hr==DI_OK,"IDirectInput_CreateDevice() failed: %08x\n", hr);
341 if (hr!=DI_OK)
342 goto DONE;
343
344 trace("---- Controller Information ----\n"
345 "Product Name : %s\n"
346 "Instance Name : %s\n"
347 "devType : 0x%08x\n"
348 "GUID Product : %s\n"
349 "GUID Instance : %s\n"
350 "HID Page : 0x%04x\n"
351 "HID Usage : 0x%04x\n",
352 lpddi->tszProductName,
353 lpddi->tszInstanceName,
354 lpddi->dwDevType,
357 lpddi->wUsagePage,
358 lpddi->wUsage);
359
360 /* Check if this is a HID device */
361 if (lpddi->dwDevType & DIDEVTYPE_HID)
362 ok(lpddi->wUsagePage == 0x01 && (lpddi->wUsage == 0x04 || lpddi->wUsage == 0x05),
363 "Expected a game controller HID UsagePage and Usage, got page 0x%x usage 0x%x\n",
364 lpddi->wUsagePage, lpddi->wUsage);
365
366 /* Test for joystick ID property */
367 ZeroMemory(&dipw, sizeof(dipw));
368 dipw.diph.dwSize = sizeof(DIPROPDWORD);
369 dipw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
370 dipw.diph.dwObj = 0;
371 dipw.diph.dwHow = DIPH_DEVICE;
372
374 ok(SUCCEEDED(hr), "IDirectInputDevice_GetProperty() for DIPROP_JOYSTICKID failed\n");
375
376 /* Test for INSTANCENAME property */
377 memset(&dps, 0, sizeof(dps));
378 dps.diph.dwSize = sizeof(DIPROPSTRING);
379 dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
380 dps.diph.dwHow = DIPH_DEVICE;
381
383 ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_INSTANCENAME failed: %08x\n", hr);
384
385 /* Test if instance name is the same as present in DIDEVICEINSTANCE */
386 MultiByteToWideChar(CP_ACP, 0, lpddi->tszInstanceName, -1, nameBuffer, MAX_PATH);
387 ok(!lstrcmpW(nameBuffer, dps.wsz), "DIPROP_INSTANCENAME returned is wrong. Expected: %s Got: %s\n",
388 wine_dbgstr_w(nameBuffer), wine_dbgstr_w(dps.wsz));
389
391 ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_PRODUCTNAME failed: %08x\n", hr);
392
393 /* Test if product name is the same as present in DIDEVICEINSTANCE */
394 MultiByteToWideChar(CP_ACP, 0, lpddi->tszProductName, -1, nameBuffer, MAX_PATH);
395 ok(!lstrcmpW(nameBuffer, dps.wsz), "DIPROP_PRODUCTNAME returned is wrong. Expected: %s Got: %s\n",
396 wine_dbgstr_w(nameBuffer), wine_dbgstr_w(dps.wsz));
397
398 /* Test for GUIDPATH properties */
399 memset(&dpg, 0, sizeof(dpg));
400 dpg.diph.dwSize = sizeof(DIPROPGUIDANDPATH);
401 dpg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
402 dpg.diph.dwHow = DIPH_DEVICE;
403
405 ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_GUIDANDPATH failed: %08x\n", hr);
406
407 {
408 static const WCHAR formatW[] = {'\\','\\','?','\\','%','*','[','^','#',']','#','v','i','d','_',
409 '%','0','4','x','&','p','i','d','_','%','0','4','x',0};
410 static const WCHAR miW[] = {'m','i','_',0};
411 static const WCHAR igW[] = {'i','g','_',0};
412 int vid, pid;
413
414 _wcslwr(dpg.wszPath);
415 count = swscanf(dpg.wszPath, formatW, &vid, &pid);
416 ok(count == 2, "DIPROP_GUIDANDPATH path has wrong format. Expected count: 2 Got: %i Path: %s\n",
418 ok(wcsstr(dpg.wszPath, miW) != 0 || wcsstr(dpg.wszPath, igW) != 0,
419 "DIPROP_GUIDANDPATH path should contain either 'ig_' or 'mi_' substring. Path: %s\n",
421 }
422
424 ok(hr==E_POINTER,"IDirectInputDevice_SetDataFormat() should have returned "
425 "E_POINTER, returned: %08x\n", hr);
426
427 ZeroMemory(&format, sizeof(format));
429 ok(hr==DIERR_INVALIDPARAM,"IDirectInputDevice_SetDataFormat() should have "
430 "returned DIERR_INVALIDPARAM, returned: %08x\n", hr);
431
432 /* try the default formats */
434 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
435
437 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
438
439 /* try an alternate format */
441 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
442
444 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
445 if (hr != DI_OK)
446 goto RELEASE;
447
448 for (i=0; i<16; i++)
449 {
451 ok(hr == SetCoop_null_window[i], "SetCooperativeLevel(NULL, %d): %08x\n", i, hr);
452 }
453 for (i=0; i<16; i++)
454 {
456 ok(hr == SetCoop_real_window[i], "SetCooperativeLevel(hwnd, %d): %08x\n", i, hr);
457 }
458
461 ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
462
463 /* get capabilities */
465 ok(hr==E_POINTER,"IDirectInputDevice_GetCapabilities() "
466 "should have returned E_POINTER, returned: %08x\n", hr);
467
468 ZeroMemory(&caps, sizeof(caps));
469 hr = IDirectInputDevice_GetCapabilities(pJoystick, &caps);
470 ok(hr==DIERR_INVALIDPARAM,"IDirectInputDevice_GetCapabilities() "
471 "should have returned DIERR_INVALIDPARAM, returned: %08x\n", hr);
472
473 caps.dwSize = sizeof(caps);
474 hr = IDirectInputDevice_GetCapabilities(pJoystick, &caps);
475 ok(hr==DI_OK,"IDirectInputDevice_GetCapabilities() failed: %08x\n", hr);
476
477 ZeroMemory(&info, sizeof(info));
478 info.pJoystick = pJoystick;
479
480 /* default min/max limits */
481 info.lMin = 0;
482 info.lMax = 0xffff;
483 /* enumerate objects */
485 ok(hr==DI_OK,"IDirectInputDevice_EnumObjects() failed: %08x\n", hr);
486
487 ok(caps.dwAxes == info.axis, "Number of enumerated axes (%d) doesn't match capabilities (%d)\n", info.axis, caps.dwAxes);
488 ok(caps.dwButtons == info.button, "Number of enumerated buttons (%d) doesn't match capabilities (%d)\n", info.button, caps.dwButtons);
489 ok(caps.dwPOVs == info.pov, "Number of enumerated POVs (%d) doesn't match capabilities (%d)\n", info.pov, caps.dwPOVs);
490
491 /* Set format and check limits again */
493 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
494 info.lMin = -2000;
495 info.lMax = +2000;
496 info.dZone= 123;
498 ok(hr==DI_OK,"IDirectInputDevice_EnumObjects() failed: %08x\n", hr);
499
500 hr = IDirectInputDevice_GetDeviceInfo(pJoystick, 0);
501 ok(hr==E_POINTER, "IDirectInputDevice_GetDeviceInfo() "
502 "should have returned E_POINTER, returned: %08x\n", hr);
503
504 ZeroMemory(&inst, sizeof(inst));
505 ZeroMemory(&inst3, sizeof(inst3));
506
507 hr = IDirectInputDevice_GetDeviceInfo(pJoystick, &inst);
508 ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_GetDeviceInfo() "
509 "should have returned DIERR_INVALIDPARAM, returned: %08x\n", hr);
510
511 inst.dwSize = sizeof(inst);
512 hr = IDirectInputDevice_GetDeviceInfo(pJoystick, &inst);
513 ok(hr==DI_OK,"IDirectInputDevice_GetDeviceInfo() failed: %08x\n", hr);
514
515 inst3.dwSize = sizeof(inst3);
517 ok(hr==DI_OK,"IDirectInputDevice_GetDeviceInfo() failed: %08x\n", hr);
518
519 hr = IDirectInputDevice_Unacquire(pJoystick);
520 ok(hr == S_FALSE, "IDirectInputDevice_Unacquire() should have returned S_FALSE, got: %08x\n", hr);
521
522 hr = IDirectInputDevice_Acquire(pJoystick);
523 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
524 if (hr != DI_OK)
525 goto RELEASE;
526
527 hr = IDirectInputDevice_Acquire(pJoystick);
528 ok(hr == S_FALSE, "IDirectInputDevice_Acquire() should have returned S_FALSE, got: %08x\n", hr);
529
530 if (info.pov < 4)
531 {
532 hr = IDirectInputDevice_GetDeviceState(pJoystick, sizeof(DIJOYSTATE2), &js);
533 ok(hr == DI_OK, "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
534 ok(js.rgdwPOV[3] == -1, "Default for unassigned POV should be -1 not: %d\n", js.rgdwPOV[3]);
535 }
536
537 trace("Testing force feedback\n");
538 ZeroMemory(&effect_data, sizeof(effect_data));
539 effect_data.eff.dwSize = sizeof(effect_data.eff);
540 effect_data.eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
541 effect_data.eff.dwDuration = INFINITE;
542 effect_data.eff.dwGain = DI_FFNOMINALMAX;
543 effect_data.eff.dwTriggerButton = DIEB_NOTRIGGER;
544 effect_data.eff.cAxes = ARRAY_SIZE(axes);
545 effect_data.eff.rgdwAxes = axes;
546 effect_data.eff.rglDirection = direction;
547
548 /* Sending effects to joystick requires
549 * calling IDirectInputEffect_Initialize, which requires
550 * having exclusive access to the device, which requires
551 * - not having acquired the joystick when calling
552 * IDirectInputDevice_SetCooperativeLevel
553 * - a visible window
554 */
555 real_hWnd = CreateWindowExA(0, "EDIT", "Test text", 0, 10, 10, 300, 300, NULL, NULL,
556 hInstance, NULL);
557 ok(real_hWnd!=0,"CreateWindowExA failed: %p\n", real_hWnd);
558 ShowWindow(real_hWnd, SW_SHOW);
559 hr = IDirectInputDevice_Unacquire(pJoystick);
560 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
561 hr = IDirectInputDevice_SetCooperativeLevel(pJoystick, real_hWnd,
563 ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
564 hr = IDirectInputDevice_Acquire(pJoystick);
565 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
566
567 cnt1 = get_refcount((IUnknown*)pJoystick);
568
569 hr = IDirectInputDevice2_EnumEffects((IDirectInputDevice2A*)pJoystick, EnumEffects, &effect_data, DIEFT_ALL);
570 ok(hr==DI_OK,"IDirectInputDevice2_EnumEffects() failed: %08x\n", hr);
571
572 /* If the controller does not support ANY effect use the constant effect to make
573 * CreateEffect fail but with the unsupported reason instead of invalid parameters. */
574 if (!effect_data.effect_count)
575 {
577 effect_data.guid = GUID_ConstantForce;
578 effect_data.eff.cbTypeSpecificParams = sizeof(constant);
579 effect_data.eff.lpvTypeSpecificParams = &constant;
580 effect_data.effect_name = "Constant";
581 constant.lMagnitude = DI_FFNOMINALMAX / 2;
582
583 ok(!(caps.dwFlags & DIDC_FORCEFEEDBACK), "effect count is zero but controller supports force feedback?\n");
584 }
585
586 effect = (void *)0xdeadbeef;
587 hr = IDirectInputDevice2_CreateEffect((IDirectInputDevice2A*)pJoystick, &effect_data.guid,
588 &effect_data.eff, &effect, NULL);
589 if (caps.dwFlags & DIDC_FORCEFEEDBACK)
590 {
591 trace("force feedback supported with %d effects, using '%s' for test\n",
592 effect_data.effect_count, effect_data.effect_name);
593 ok(hr == DI_OK, "IDirectInputDevice_CreateEffect() failed: %08x\n", hr);
594 cnt2 = get_refcount((IUnknown*)pJoystick);
595 ok(cnt1 == cnt2, "Ref count is wrong %d != %d\n", cnt1, cnt2);
596
597 if (effect)
598 {
599 DWORD effect_status;
600 struct DIPROPDWORD diprop_word;
601 GUID guid = {0};
602
604 &effect_data.guid);
605 ok(hr==DI_OK,"IDirectInputEffect_Initialize failed: %08x\n", hr);
606 hr = IDirectInputEffect_SetParameters(effect, &effect_data.eff, DIEP_AXES | DIEP_DIRECTION |
608 ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
609 if (hr==DI_OK) {
610 /* Test that upload, unacquire, acquire still permits updating
611 * uploaded effect. */
612 hr = IDirectInputDevice_Unacquire(pJoystick);
613 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
614 hr = IDirectInputDevice_Acquire(pJoystick);
615 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
616 hr = IDirectInputEffect_SetParameters(effect, &effect_data.eff, DIEP_GAIN);
617 ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
618 }
619
620 /* Check effect status.
621 * State: initially stopped
622 * start
623 * State: started
624 * unacquire, acquire, download
625 * State: stopped
626 * start
627 * State: started
628 *
629 * Shows that:
630 * - effects are stopped after Unacquire + Acquire
631 * - effects are preserved (Download + Start doesn't complain
632 * about incomplete effect)
633 */
635 ok(hr==E_POINTER,"IDirectInputEffect_GetEffectStatus() must fail with E_POINTER, got: %08x\n", hr);
636 effect_status = 0xdeadbeef;
637 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
638 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
639 ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
640 hr = IDirectInputEffect_SetParameters(effect, &effect_data.eff, DIEP_START);
641 ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
642 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
643 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
644 todo_wine ok(effect_status!=0,"IDirectInputEffect_GetEffectStatus() reported effect as stopped\n");
645 hr = IDirectInputDevice_Unacquire(pJoystick);
646 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
647 hr = IDirectInputDevice_Acquire(pJoystick);
648 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
650 ok(hr==DI_OK,"IDirectInputEffect_Download() failed: %08x\n", hr);
651 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
652 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
653 ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
654 hr = IDirectInputEffect_Start(effect, 1, 0);
655 ok(hr==DI_OK,"IDirectInputEffect_Start() failed: %08x\n", hr);
656 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
657 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
658 Sleep(250); /* feel the magic */
659 todo_wine ok(effect_status!=0,"IDirectInputEffect_GetEffectStatus() reported effect as stopped\n");
661 ok(hr==DI_OK,"IDirectInputEffect_GetEffectGuid() failed: %08x\n", hr);
662 ok(IsEqualGUID(&effect_data.guid, &guid), "Wrong guid returned\n");
663
664 /* Check autocenter status
665 * State: initially stopped
666 * enable
667 * State: enabled
668 * acquire
669 * State: enabled
670 * unacquire
671 * State: enabled
672 *
673 * IDirectInputDevice2_SetProperty(DIPROP_AUTOCENTER) can only be
674 * executed when the device is released.
675 *
676 * If Executed interactively, user can feel that autocenter is
677 * only disabled when the joystick is acquired.
678 */
679 diprop_word.diph.dwSize = sizeof(diprop_word);
680 diprop_word.diph.dwHeaderSize = sizeof(diprop_word.diph);
681 diprop_word.diph.dwObj = 0;
682 diprop_word.diph.dwHow = DIPH_DEVICE;
683 hr = IDirectInputDevice_Unacquire(pJoystick);
684 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
685 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
686 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
687 ok(diprop_word.dwData==DIPROPAUTOCENTER_ON,"IDirectInputDevice2_GetProperty() reported autocenter as disabled\n");
688 diprop_word.dwData = DIPROPAUTOCENTER_OFF;
689 hr = IDirectInputDevice2_SetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
690 ok(hr==DI_OK,"IDirectInputDevice2_SetProperty() failed: %08x\n", hr);
691 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
692 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
693 ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
695 trace("Acquiring in 2s, autocenter will be disabled.\n");
696 Sleep(2000);
697 }
698 hr = IDirectInputDevice_Acquire(pJoystick);
699 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
701 trace("Acquired.\n");
702 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
703 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
704 ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
706 trace("Releasing in 2s, autocenter will be re-enabled.\n");
707 Sleep(2000);
708 }
709 hr = IDirectInputDevice_Unacquire(pJoystick);
710 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
712 trace("Released\n");
713 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
714 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
715 ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
716 hr = IDirectInputDevice_Acquire(pJoystick);
717 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
718 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
719 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
720
721 /* Device gain (DIPROP_FFGAIN).
722 * From MSDN:
723 * 0..10000 range, otherwise DIERR_INVALIDPARAM.
724 * Can be changed even if device is acquired.
725 * Difference found by tests:
726 * <0 is refused, >10000 is accepted
727 */
728 dip_gain_set.diph.dwSize = sizeof(DIPROPDWORD);
729 dip_gain_set.diph.dwHeaderSize = sizeof(DIPROPHEADER);
730 dip_gain_set.diph.dwObj = 0;
731 dip_gain_set.diph.dwHow = DIPH_DEVICE;
732 dip_gain_get.diph.dwSize = sizeof(DIPROPDWORD);
733 dip_gain_get.diph.dwHeaderSize = sizeof(DIPROPHEADER);
734 dip_gain_get.diph.dwObj = 0;
735 dip_gain_get.diph.dwHow = DIPH_DEVICE;
736 dip_gain_get.dwData = 0;
737
738 /* Test device is acquisition (non)impact. */
739 hr = IDirectInputDevice_Unacquire(pJoystick);
740 ok(hr == DI_OK, "IDirectInputDevice_Unacquire() should have returned S_FALSE, got: %08x\n", hr);
741 dip_gain_set.dwData = 1;
742 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
743 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
744 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
745 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
746 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
747 hr = IDirectInputDevice_Acquire(pJoystick);
748 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
749 dip_gain_set.dwData = 2;
750 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
751 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
752 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
753 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
754 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
755 /* Test range and internal clamping. */
756 dip_gain_set.dwData = -1;
757 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
758 todo_wine ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_SetProperty() should have returned %08x: %08x\n", DIERR_INVALIDPARAM, hr);
759 dip_gain_set.dwData = 0;
760 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
761 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
762 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
763 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
764 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
765 dip_gain_set.dwData = 10000;
766 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
767 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
768 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
769 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
770 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
771 /* WARNING: This call succeeds, on the contrary of what is stated on MSDN. */
772 dip_gain_set.dwData = 10001;
773 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
774 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
775 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
776 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
777 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
778
779 /* Test SendForceFeedbackCommand
780 * DISFFC_STOPALL - Should stop effects only
781 * DISFFC_RESET - Should stop effects and unload them (NOT release them)
782 * Tests for game Odallus (bug 41623) */
783 hr = IDirectInputDevice2_SendForceFeedbackCommand((IDirectInputDevice2A*)pJoystick, 0);
784 ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_SendForceFeedbackCommand() failed: %08x\n", hr);
785 hr = IDirectInputDevice2_SendForceFeedbackCommand((IDirectInputDevice2A*)pJoystick, 0xFF);
786 ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_SendForceFeedbackCommand() failed: %08x\n", hr);
787
789 ok(hr==DI_OK,"IDirectInputEffect_Download() failed: %08x\n", hr);
790
791 /* Send STOPALL and prove that the effect can still be started */
792 hr = IDirectInputDevice2_SendForceFeedbackCommand((IDirectInputDevice2A*)pJoystick, DISFFC_STOPALL);
793 ok(hr==DI_OK, "IDirectInputDevice_SendForceFeedbackCommand() failed: %08x\n", hr);
794 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
795 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
796 ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
797 hr = IDirectInputEffect_Start(effect, 1, 0);
798 ok(hr==DI_OK,"IDirectInputEffect_Start() failed: %08x\n", hr);
800 ok(hr==DI_OK,"IDirectInputEffect_GetEffectGuid() failed: %08x\n", hr);
801 ok(IsEqualGUID(&effect_data.guid, &guid), "Wrong guid returned\n");
802
803 /* Send RESET and prove that we can still manipulate the effect, thus not released */
804 hr = IDirectInputDevice2_SendForceFeedbackCommand((IDirectInputDevice2A*)pJoystick, DISFFC_RESET);
805 ok(hr==DI_OK, "IDirectInputDevice_SendForceFeedbackCommand() failed: %08x\n", hr);
806 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
807 ok(hr==DIERR_NOTDOWNLOADED,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
809 ok(hr==DI_OK,"IDirectInputEffect_Download() failed: %08x\n", hr);
810 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
811 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
812 ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
813 hr = IDirectInputEffect_Start(effect, 1, 0);
814 ok(hr==DI_OK,"IDirectInputEffect_Start() failed: %08x\n", hr);
816 ok(hr==DI_OK,"IDirectInputEffect_GetEffectGuid() failed: %08x\n", hr);
817 ok(IsEqualGUID(&effect_data.guid, &guid), "Wrong guid returned\n");
818
819 ref = IUnknown_Release(effect);
820 ok(ref == 0, "IDirectInputDevice_Release() reference count = %d\n", ref);
821 }
822 cnt1 = get_refcount((IUnknown*)pJoystick);
823 ok(cnt1 == cnt2, "Ref count is wrong %d != %d\n", cnt1, cnt2);
824 }
825 /* No force feedback support, CreateEffect is supposed to fail. Fairy Bloom Freesia
826 * calls CreateEffect without checking the DIDC_FORCEFEEDBACK. It expects the correct
827 * error return to determine if force feedback is unsupported. */
828 else
829 {
830 trace("No force feedback support\n");
831 ok(hr==DIERR_UNSUPPORTED, "IDirectInputDevice_CreateEffect() must fail with DIERR_UNSUPPORTED, got: %08x\n", hr);
832 ok(effect == NULL, "effect must be NULL, got %p\n", effect);
833 }
834
835 /* Before destroying the window, release joystick to revert to
836 * non-exclusive, background cooperative level. */
837 hr = IDirectInputDevice_Unacquire(pJoystick);
838 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
841 ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
842 DestroyWindow (real_hWnd);
843 hr = IDirectInputDevice_Acquire(pJoystick);
844 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
845
847 trace("You have 30 seconds to test all axes, sliders, POVs and buttons\n");
848 count = 300;
849 } else
850 count = 1;
851
852 trace("\n");
853 oldstate[0]='\0';
854 for (i = 0; i < count; i++) {
855 hr = IDirectInputDevice_GetDeviceState(pJoystick, sizeof(DIJOYSTATE2), &js);
856 ok(hr==DI_OK,"IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
857 if (hr != DI_OK)
858 break;
859 sprintf(curstate, "X%5d Y%5d Z%5d Rx%5d Ry%5d Rz%5d "
860 "S0%5d S1%5d POV0%5d POV1%5d POV2%5d POV3%5d "
861 "B %d %d %d %d %d %d %d %d %d %d %d %d\n",
862 js.lX, js.lY, js.lZ, js.lRx, js.lRy, js.lRz,
863 js.rglSlider[0], js.rglSlider[1],
864 js.rgdwPOV[0], js.rgdwPOV[1], js.rgdwPOV[2], js.rgdwPOV[3],
865 js.rgbButtons[0]>>7, js.rgbButtons[1]>>7, js.rgbButtons[2]>>7,
866 js.rgbButtons[3]>>7, js.rgbButtons[4]>>7, js.rgbButtons[5]>>7,
867 js.rgbButtons[6]>>7, js.rgbButtons[7]>>7, js.rgbButtons[8]>>7,
868 js.rgbButtons[9]>>7, js.rgbButtons[10]>>7, js.rgbButtons[11]>>7);
869 if (strcmp(oldstate, curstate) != 0)
870 {
871 trace("%s\n", curstate);
872 strcpy(oldstate, curstate);
873 }
874 Sleep(100);
875 }
876 trace("\n");
877
878 hr = IDirectInputDevice_Unacquire(pJoystick);
879 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
880
881RELEASE:
882 ref = IDirectInputDevice_Release(pJoystick);
883 ok(ref==0,"IDirectInputDevice_Release() reference count = %d\n", ref);
884
885DONE:
886 return DIENUM_CONTINUE;
887}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
HWND hWnd
Definition: settings.c:17
HINSTANCE hInstance
Definition: charmap.c:19
const DIDATAFORMAT c_dfDIJoystick2
Definition: data_formats.c:251
const DIDATAFORMAT c_dfDIJoystick
Definition: data_formats.c:75
#define DIEP_TYPESPECIFICPARAMS
Definition: dinput.h:1022
#define IDirectInputDevice_EnumObjects(p, a, b, c)
Definition: dinput.h:1605
#define DIPROP_GUIDANDPATH
Definition: dinput.h:908
#define IDirectInputDevice2_SetProperty(p, a, b)
Definition: dinput.h:1730
#define IDirectInputEffect_GetEffectStatus(p, a)
Definition: dinput.h:1517
#define IDirectInputDevice_Acquire(p)
Definition: dinput.h:1608
#define DIPROP_INSTANCENAME
Definition: dinput.h:910
#define DISCL_FOREGROUND
Definition: dinput.h:965
#define IDirectInputDevice_SetDataFormat(p, a)
Definition: dinput.h:1612
#define DIERR_INVALIDPARAM
Definition: dinput.h:152
#define IDirectInputDevice_SetCooperativeLevel(p, a, b)
Definition: dinput.h:1614
#define DIDEVTYPE_HID
Definition: dinput.h:201
#define DIPROP_FFGAIN
Definition: dinput.h:895
#define DIPROP_AUTOCENTER
Definition: dinput.h:897
#define DIPROP_JOYSTICKID
Definition: dinput.h:912
#define DIDFT_ALL
Definition: dinput.h:750
#define IDirectInputEffect_GetEffectGuid(p, a)
Definition: dinput.h:1512
#define DISCL_BACKGROUND
Definition: dinput.h:966
#define DIERR_NOTDOWNLOADED
Definition: dinput.h:177
#define DIEP_START
Definition: dinput.h:1026
#define DIEB_NOTRIGGER
Definition: dinput.h:1029
#define IDirectInputDevice2_CreateEffect(p, a, b, c, d)
Definition: dinput.h:1743
#define DIJOFS_X
Definition: dinput.h:1205
#define DIDC_FORCEFEEDBACK
Definition: dinput.h:949
#define IDirectInputEffect_Initialize(p, a, b, c)
Definition: dinput.h:1511
#define IDirectInputEffect_Start(p, a, b)
Definition: dinput.h:1515
#define DIPROP_PRODUCTNAME
Definition: dinput.h:911
#define DIEFF_OBJECTOFFSETS
Definition: dinput.h:1009
#define DIJOFS_Y
Definition: dinput.h:1206
#define IDirectInputDevice_GetCapabilities(p, a)
Definition: dinput.h:1604
#define DIPROPAUTOCENTER_ON
Definition: dinput.h:900
#define IDirectInputDevice_GetDeviceInfo(p, a)
Definition: dinput.h:1616
#define DISFFC_RESET
Definition: dinput.h:970
#define IDirectInputEffect_SetParameters(p, a, b)
Definition: dinput.h:1514
#define DIERR_UNSUPPORTED
Definition: dinput.h:156
#define IDirectInput_CreateDevice(p, a, b, c)
Definition: dinput.h:2296
#define IDirectInputDevice2_SendForceFeedbackCommand(p, a)
Definition: dinput.h:1747
#define IDirectInputDevice2_EnumEffects(p, a, b, c)
Definition: dinput.h:1744
#define DIEP_AXES
Definition: dinput.h:1019
#define DISFFC_STOPALL
Definition: dinput.h:971
#define DIEFT_ALL
Definition: dinput.h:991
struct IDirectInputEffect * LPDIRECTINPUTEFFECT
Definition: dinput.h:107
#define DIEP_GAIN
Definition: dinput.h:1016
#define IDirectInputDevice2_GetProperty(p, a, b)
Definition: dinput.h:1729
#define DIPROPAUTOCENTER_OFF
Definition: dinput.h:899
#define IDirectInputDevice_Unacquire(p)
Definition: dinput.h:1609
#define DISCL_NONEXCLUSIVE
Definition: dinput.h:964
#define IDirectInputDevice_Release(p)
Definition: dinput.h:1602
#define DIEFF_CARTESIAN
Definition: dinput.h:1010
#define IDirectInputEffect_Download(p)
Definition: dinput.h:1518
#define DIPH_DEVICE
Definition: dinput.h:835
#define IDirectInputDevice_GetDeviceState(p, a, b)
Definition: dinput.h:1610
#define DISCL_EXCLUSIVE
Definition: dinput.h:963
#define DIEP_DIRECTION
Definition: dinput.h:1020
#define CP_ACP
Definition: compat.h:109
#define MAX_PATH
Definition: compat.h:34
#define MultiByteToWideChar
Definition: compat.h:110
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define INFINITE
Definition: serial.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
#define RELEASE(_tag)
Definition: fxobject.hpp:50
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
_Check_return_ _CRTIMP int __cdecl swscanf(_In_z_ const wchar_t *_Src, _In_z_ _Scanf_format_string_ const wchar_t *_Format,...)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static BOOL CALLBACK EnumAxes(const DIDEVICEOBJECTINSTANCEA *pdidoi, void *pContext)
Definition: joystick.c:91
static HWND get_hwnd(void)
Definition: joystick.c:67
static int get_refcount(IUnknown *object)
Definition: joystick.c:85
static const HRESULT SetCoop_null_window[16]
Definition: joystick.c:261
static const DIDATAFORMAT c_dfDIJoystickTest
Definition: joystick.c:58
static const HRESULT SetCoop_real_window[16]
Definition: joystick.c:267
static BOOL CALLBACK EnumEffects(const DIEFFECTINFOA *lpef, void *ref)
Definition: joystick.c:194
#define todo_wine
Definition: custom.c:79
long LONG
Definition: pedump.c:60
#define DONE
Definition: rnr20lib.h:14
_CRTIMP wchar_t *__cdecl _wcslwr(_Inout_z_ wchar_t *_String)
int winetest_interactive
#define memset(x, y, z)
Definition: compat.h:39
DWORD dwAxes
Definition: dinput.h:935
DWORD dwButtons
Definition: dinput.h:936
DWORD dwPOVs
Definition: dinput.h:937
DWORD dwSize
Definition: dinput.h:932
DWORD dwFlags
Definition: dinput.h:933
LONG lRy
Definition: dinput.h:1177
LONG lRx
Definition: dinput.h:1176
LONG lZ
Definition: dinput.h:1175
DWORD rgdwPOV[4]
Definition: dinput.h:1180
LONG lRz
Definition: dinput.h:1178
LONG lX
Definition: dinput.h:1173
LONG rglSlider[2]
Definition: dinput.h:1179
BYTE rgbButtons[128]
Definition: dinput.h:1181
LONG lY
Definition: dinput.h:1174
WCHAR wszPath[MAX_PATH]
Definition: dinput.h:869
DIPROPHEADER diph
Definition: dinput.h:867
DIPROPHEADER diph
Definition: dinput.h:874
WCHAR wsz[MAX_PATH]
Definition: dinput.h:875
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
uint32_t ULONG
Definition: typedefs.h:59
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
#define S_FALSE
Definition: winerror.h:2357
#define E_POINTER
Definition: winerror.h:2365
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define SW_SHOW
Definition: winuser.h:774
BOOL WINAPI DestroyWindow(_In_ HWND)
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by joystick_tests().

◆ get_hwnd()

◆ get_refcount()

static int get_refcount ( IUnknown object)
static

Definition at line 85 of file joystick.c.

86{
87 IUnknown_AddRef( object );
88 return IUnknown_Release( object );
89}

Referenced by EnumJoysticks().

◆ joystick_tests()

static void joystick_tests ( DWORD  version)
static

Definition at line 889 of file joystick.c.

890{
891 HRESULT hr;
892 IDirectInputA *pDI;
893 ULONG ref;
895
896 trace("-- Testing Direct Input Version 0x%04x --\n", version);
898 ok(hr==DI_OK||hr==DIERR_OLDDIRECTINPUTVERSION, "DirectInputCreateA() failed: %08x\n", hr);
899 if (hr==DI_OK && pDI!=0) {
901 data.pDI = pDI;
902 data.version = version;
905 ok(hr==DI_OK,"IDirectInput_EnumDevices() failed: %08x\n", hr);
907 ok(ref==0,"IDirectInput_Release() reference count = %d\n", ref);
909 trace(" Version Not Supported\n");
910}
#define DIDEVTYPE_JOYSTICK
Definition: dinput.h:200
#define DIEDFL_ALLDEVICES
Definition: dinput.h:190
#define DIERR_OLDDIRECTINPUTVERSION
Definition: dinput.h:141
#define IDirectInput_EnumDevices(p, a, b, c, d)
Definition: dinput.h:2297
#define IDirectInput_Release(p)
Definition: dinput.h:2294
HRESULT WINAPI DECLSPEC_HOTPATCH DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
Definition: dinput_main.c:229
static const WCHAR version[]
Definition: asmname.c:66
static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
Definition: joystick.c:296

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( joystick  )

Definition at line 930 of file joystick.c.

931{
933
934 joystick_tests(0x0700);
935 joystick_tests(0x0500);
936 joystick_tests(0x0300);
937
939
941}
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
static void test_enum_feedback(void)
Definition: joystick.c:912
static void joystick_tests(DWORD version)
Definition: joystick.c:889

◆ test_enum_feedback()

static void test_enum_feedback ( void  )
static

Definition at line 912 of file joystick.c.

913{
914 HRESULT hr;
915 IDirectInputA *pDI;
916 ULONG ref;
918
919 hr = DirectInputCreateA(hInstance, 0x0700, &pDI, NULL);
920 ok(hr==DI_OK||hr==DIERR_OLDDIRECTINPUTVERSION, "DirectInputCreateA() failed: %08x\n", hr);
921 if (hr==DI_OK && pDI!=0) {
923 ok(hr==DI_OK,"IDirectInput_EnumDevices() failed: %08x\n", hr);
925 ok(ref==0,"IDirectInput_Release() reference count = %d\n", ref);
927 trace(" Version Not Supported\n");
928}
#define DIEDFL_ATTACHEDONLY
Definition: dinput.h:191
#define DIEDFL_FORCEFEEDBACK
Definition: dinput.h:192
static BOOL CALLBACK EnumAllFeedback(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
Definition: joystick.c:273

Referenced by START_TEST().

Variable Documentation

◆ c_dfDIJoystickTest

const DIDATAFORMAT c_dfDIJoystickTest
static
Initial value:
= {
sizeof(DIDATAFORMAT),
sizeof(DIJOYSTATE2),
}
struct _DIDATAFORMAT DIDATAFORMAT
struct _DIOBJECTDATAFORMAT * LPDIOBJECTDATAFORMAT
#define DIDF_ABSAXIS
Definition: dinput.h:775
static const DIOBJECTDATAFORMAT dfDIJoystickTest[]
Definition: joystick.c:38

Definition at line 58 of file joystick.c.

Referenced by EnumJoysticks().

◆ dfDIJoystickTest

const DIOBJECTDATAFORMAT dfDIJoystickTest[]
static
Initial value:
= {
}
#define DIDFT_AXIS
Definition: dinput.h:753
#define DIJOFS_RX
Definition: dinput.h:1208
#define DIDFT_OPTIONAL
Definition: dinput.h:771
#define DIJOFS_Z
Definition: dinput.h:1207
#define DIJOFS_BUTTON(n)
Definition: dinput.h:1215
#define DIDFT_ANYINSTANCE
Definition: dinput.h:760
#define DIJOFS_RZ
Definition: dinput.h:1210
#define DIJOFS_RY
Definition: dinput.h:1209
#define DIDFT_BUTTON
Definition: dinput.h:756

Definition at line 38 of file joystick.c.

◆ effect_conversion

const struct effect_id effect_conversion[]
static
Initial value:
= {
{&GUID_ConstantForce, DIEFT_CONSTANTFORCE, "Constant"},
{&GUID_RampForce, DIEFT_RAMPFORCE, "Ramp"},
{&GUID_Square, DIEFT_PERIODIC, "Square"},
{&GUID_Sine, DIEFT_PERIODIC, "Sine"},
{&GUID_Triangle, DIEFT_PERIODIC, "Triangle"},
{&GUID_SawtoothUp, DIEFT_PERIODIC, "Saw Tooth Up"},
{&GUID_SawtoothDown, DIEFT_PERIODIC, "Saw Tooth Down"},
{&GUID_Spring, DIEFT_CONDITION, "Spring"},
{&GUID_Damper, DIEFT_CONDITION, "Damper"},
{&GUID_Inertia, DIEFT_CONDITION, "Inertia"},
{&GUID_Friction, DIEFT_CONDITION, "Friction"},
{&GUID_CustomForce, DIEFT_CUSTOMFORCE, "Custom"}
}

Referenced by effect_from_guid().

◆ SetCoop_null_window

const HRESULT SetCoop_null_window[16]
static

◆ SetCoop_real_window