ReactOS  0.4.14-dev-606-g14ebc0b
joystick.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-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 DIRECTINPUT_VERSION 0x0700
20 
21 #define COBJMACROS
22 #include <windows.h>
23 
24 #include <math.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 
28 #include "wine/test.h"
29 #include "windef.h"
30 #include "wingdi.h"
31 #include "dinput.h"
32 
33 typedef struct tagUserData {
34  IDirectInputA *pDI;
36 } UserData;
37 
56 };
57 
59  sizeof(DIDATAFORMAT),
60  sizeof(DIOBJECTDATAFORMAT),
62  sizeof(DIJOYSTATE2),
65 };
66 
67 static HWND get_hwnd(void)
68 {
70  if (!hwnd)
72  return hwnd;
73 }
74 
75 typedef struct tagJoystickInfo
76 {
77  IDirectInputDeviceA *pJoystick;
83 } JoystickInfo;
84 
85 static int get_refcount(IUnknown *object)
86 {
87  IUnknown_AddRef( object );
88  return IUnknown_Release( object );
89 }
90 
91 static BOOL CALLBACK EnumAxes(const DIDEVICEOBJECTINSTANCEA *pdidoi, void *pContext)
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 
117  hr = IDirectInputDevice_GetProperty(info->pJoystick, DIPROP_RANGE, &diprg.diph);
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 
129  hr = IDirectInputDevice_SetProperty(info->pJoystick, DIPROP_RANGE, &diprg.diph);
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 }
155 
156 static const struct effect_id
157 {
158  const GUID *guid;
159  int dieft;
160  const char *name;
161 } effect_conversion[] = {
162  {&GUID_ConstantForce, DIEFT_CONSTANTFORCE, "Constant"},
163  {&GUID_RampForce, DIEFT_RAMPFORCE, "Ramp"},
164  {&GUID_Square, DIEFT_PERIODIC, "Square"},
165  {&GUID_Sine, DIEFT_PERIODIC, "Sine"},
166  {&GUID_Triangle, DIEFT_PERIODIC, "Triangle"},
167  {&GUID_SawtoothUp, DIEFT_PERIODIC, "Saw Tooth Up"},
168  {&GUID_SawtoothDown, DIEFT_PERIODIC, "Saw Tooth Down"},
169  {&GUID_Spring, DIEFT_CONDITION, "Spring"},
170  {&GUID_Damper, DIEFT_CONDITION, "Damper"},
171  {&GUID_Inertia, DIEFT_CONDITION, "Inertia"},
172  {&GUID_Friction, DIEFT_CONDITION, "Friction"},
173  {&GUID_CustomForce, DIEFT_CUSTOMFORCE, "Custom"}
174 };
175 
176 static const struct effect_id* effect_from_guid(const GUID *guid)
177 {
178  unsigned int i;
179  for (i = 0; i < ARRAY_SIZE(effect_conversion); i++)
181  return &effect_conversion[i];
182  return NULL;
183 }
184 
186 {
190  const char *effect_name;
191 };
192 
193 /* The last enumerated effect will be used for force feedback testing */
194 static BOOL CALLBACK EnumEffects(const DIEFFECTINFOA *lpef, void *ref)
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;
234  case DIEFT_CONSTANTFORCE:
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 }
260 
261 static const HRESULT SetCoop_null_window[16] = {
266 
267 static const HRESULT SetCoop_real_window[16] = {
272 
273 static BOOL CALLBACK EnumAllFeedback(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
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,
286  wine_dbgstr_guid(&lpddi->guidProduct),
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 }
295 
296 static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
297 {
298  HRESULT hr;
299  UserData * data = pvRef;
300  IDirectInputDeviceA *pJoystick;
302  DIDEVCAPS caps;
303  DIJOYSTATE2 js;
305  int i, count;
306  ULONG ref;
307  DIDEVICEINSTANCEA inst;
308  DIDEVICEINSTANCE_DX3A inst3;
309  DIPROPDWORD dipw;
310  DIPROPSTRING dps;
311  DIPROPGUIDANDPATH dpg;
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,
355  wine_dbgstr_guid(&lpddi->guidProduct),
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",
417  count, wine_dbgstr_w(dpg.wszPath));
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",
420  wine_dbgstr_w(dpg.wszPath));
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);
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  {
576  static DICONSTANTFORCE constant;
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 
603  hr = IDirectInputEffect_Initialize(effect, hInstance, data->version,
604  &effect_data.guid);
605  ok(hr==DI_OK,"IDirectInputEffect_Initialize failed: %08x\n", hr);
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");
694  if (winetest_interactive) {
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");
705  if (winetest_interactive) {
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 
846  if (winetest_interactive) {
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 
881 RELEASE:
882  ref = IDirectInputDevice_Release(pJoystick);
883  ok(ref==0,"IDirectInputDevice_Release() reference count = %d\n", ref);
884 
885 DONE:
886  return DIENUM_CONTINUE;
887 }
888 
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) {
900  UserData data;
901  data.pDI = pDI;
902  data.version = version;
905  ok(hr==DI_OK,"IDirectInput_EnumDevices() failed: %08x\n", hr);
906  ref = IDirectInput_Release(pDI);
907  ok(ref==0,"IDirectInput_Release() reference count = %d\n", ref);
908  } else if (hr==DIERR_OLDDIRECTINPUTVERSION)
909  trace(" Version Not Supported\n");
910 }
911 
912 static void test_enum_feedback(void)
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);
924  ref = IDirectInput_Release(pDI);
925  ok(ref==0,"IDirectInput_Release() reference count = %d\n", ref);
926  } else if (hr==DIERR_OLDDIRECTINPUTVERSION)
927  trace(" Version Not Supported\n");
928 }
929 
930 START_TEST(joystick)
931 {
933 
934  joystick_tests(0x0700);
935  joystick_tests(0x0500);
936  joystick_tests(0x0300);
937 
939 
940  CoUninitialize();
941 }
DWORD cAxes
Definition: dinput.h:1112
#define DIEP_AXES
Definition: dinput.h:1019
LONG lRx
Definition: dinput.h:1176
GUID guidInstance
Definition: dinput.h:413
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define IDirectInputDevice2_SendForceFeedbackCommand(p, a)
Definition: dinput.h:1747
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
DWORD dwDuration
Definition: dinput.h:1107
#define IDirectInputEffect_GetEffectGuid(p, a)
Definition: dinput.h:1512
#define DIEFT_CONDITION
Definition: dinput.h:996
DWORD dwSize
Definition: dinput.h:828
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define DIDF_ABSAXIS
Definition: dinput.h:775
#define E_HANDLE
Definition: winerror.h:2850
static const DIDATAFORMAT c_dfDIJoystickTest
Definition: joystick.c:58
HRESULT hr
Definition: shlfolder.c:183
#define DIJOFS_RZ
Definition: dinput.h:1210
#define DIPH_BYID
Definition: dinput.h:837
#define DIPROP_PRODUCTNAME
Definition: dinput.h:911
#define IDirectInputDevice_SetCooperativeLevel(p, a, b)
Definition: dinput.h:1614
static BOOL CALLBACK EnumEffects(const DIEFFECTINFOA *lpef, void *ref)
Definition: joystick.c:194
#define IDirectInputDevice_EnumObjects(p, a, b, c)
Definition: dinput.h:1605
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
#define IDirectInput_CreateDevice(p, a, b, c)
Definition: dinput.h:2296
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define DIEFT_PERIODIC
Definition: dinput.h:995
static const struct effect_id effect_conversion[]
#define DIEP_GAIN
Definition: dinput.h:1016
struct DIPROPGUIDANDPATH DIPROPGUIDANDPATH
#define CALLBACK
Definition: compat.h:27
#define DIJOFS_BUTTON(n)
Definition: dinput.h:1215
HWND hWnd
Definition: settings.c:17
#define IDirectInputDevice_GetDeviceState(p, a, b)
Definition: dinput.h:1610
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
const char * wine_dbgstr_guid(const GUID *guid)
#define ZeroMemory
Definition: winbase.h:1642
const char * effect_name
Definition: joystick.c:190
DWORD dwGain
Definition: dinput.h:1109
LPVOID lpvTypeSpecificParams
Definition: dinput.h:1117
#define DIEDFL_FORCEFEEDBACK
Definition: dinput.h:192
#define DIPROP_RANGE
Definition: dinput.h:892
struct DIJOYSTATE2 DIJOYSTATE2
int winetest_interactive
static const BYTE ramp[17]
Definition: dib.c:2709
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
DWORD dwHow
Definition: dinput.h:831
#define IDirectInputDevice2_CreateEffect(p, a, b, c, d)
Definition: dinput.h:1743
BOOL WINAPI DestroyWindow(_In_ HWND)
#define IDirectInputDevice_GetProperty(p, a, b)
Definition: dinput.h:1606
Definition: send.c:47
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define DIPH_DEVICE
Definition: dinput.h:835
#define DIJOFS_X
Definition: dinput.h:1205
#define DIERR_UNSUPPORTED
Definition: dinput.h:156
#define DISCL_NONEXCLUSIVE
Definition: dinput.h:964
struct _test_info info[]
Definition: SetCursorPos.c:19
const DIDATAFORMAT c_dfDIJoystick
Definition: data_formats.c:75
struct _DIOBJECTDATAFORMAT * LPDIOBJECTDATAFORMAT
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define IDirectInputEffect_SetParameters(p, a, b)
Definition: dinput.h:1514
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
HINSTANCE hInstance
Definition: charmap.c:20
#define DIEP_TYPESPECIFICPARAMS
Definition: dinput.h:1022
DIPROPHEADER diph
Definition: dinput.h:843
const GUID * guid
WCHAR wszPath[MAX_PATH]
Definition: dinput.h:869
int dieft
Definition: joystick.c:159
struct DIPROPRANGE DIPROPRANGE
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define DIDFT_BUTTON
Definition: dinput.h:756
GUID guid
Definition: joystick.c:188
#define DIEFT_CUSTOMFORCE
Definition: dinput.h:997
#define DI_SECONDS
Definition: dinput.h:1039
const char * name
Definition: joystick.c:160
LONG lRy
Definition: dinput.h:1177
GLenum GLint ref
Definition: glext.h:6028
DWORD dwDevType
Definition: dinput.h:415
DWORD dwSize
Definition: dinput.h:1105
IDirectInputA * pDI
Definition: joystick.c:34
GLenum condition
Definition: glext.h:9255
#define S_FALSE
Definition: winerror.h:2357
struct _DIDATAFORMAT DIDATAFORMAT
DWORD dwFlags
Definition: dinput.h:933
#define E_INVALIDARG
Definition: ddrawi.h:101
GUID guidProduct
Definition: dinput.h:414
static const DIOBJECTDATAFORMAT dfDIJoystickTest[]
Definition: joystick.c:38
#define DIEP_DIRECTION
Definition: dinput.h:1020
const GUID * guid
Definition: joystick.c:158
smooth NULL
Definition: ftsmooth.c:416
static const HRESULT SetCoop_null_window[16]
Definition: joystick.c:261
static const HRESULT SetCoop_real_window[16]
Definition: joystick.c:267
static const WCHAR version[]
Definition: asmname.c:66
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:652
#define IDirectInputDevice_GetCapabilities(p, a)
Definition: dinput.h:1604
DIEFFECT eff
Definition: joystick.c:187
DWORD dwAxes
Definition: dinput.h:935
DWORD dwPOVs
Definition: dinput.h:937
#define IDirectInputDevice_Release(p)
Definition: dinput.h:1602
#define SW_SHOW
Definition: winuser.h:769
static int get_refcount(IUnknown *object)
Definition: joystick.c:85
static BOOL CALLBACK EnumAxes(const DIDEVICEOBJECTINSTANCEA *pdidoi, void *pContext)
Definition: joystick.c:91
static void test_enum_feedback(void)
Definition: joystick.c:912
#define DISFFC_RESET
Definition: dinput.h:970
struct DIPROPSTRING DIPROPSTRING
#define DIPROP_DEADZONE
Definition: dinput.h:893
#define DIJOFS_Y
Definition: dinput.h:1206
#define DIEDFL_ATTACHEDONLY
Definition: dinput.h:191
#define DIERR_INVALIDPARAM
Definition: dinput.h:152
#define DISCL_BACKGROUND
Definition: dinput.h:966
#define IDirectInputEffect_Start(p, a, b)
Definition: dinput.h:1515
LPDWORD rgdwAxes
Definition: dinput.h:1113
DIPROPHEADER diph
Definition: dinput.h:849
#define IDirectInput_Release(p)
Definition: dinput.h:2294
#define DIDFT_ANYINSTANCE
Definition: dinput.h:760
DIPROPHEADER diph
Definition: dinput.h:867
#define trace
Definition: atltest.h:70
DWORD dwSize
Definition: dinput.h:932
#define DIEFT_CONSTANTFORCE
Definition: dinput.h:993
LONG lX
Definition: dinput.h:1173
DWORD cbTypeSpecificParams
Definition: dinput.h:1116
#define DIERR_OLDDIRECTINPUTVERSION
Definition: dinput.h:141
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG lY
Definition: dinput.h:1174
#define DIDOI_ASPECTPOSITION
Definition: dinput.h:820
LONG HRESULT
Definition: typedefs.h:77
#define IDirectInputEffect_Initialize(p, a, b, c)
Definition: dinput.h:1511
DWORD dwButtons
Definition: dinput.h:936
struct tagUserData UserData
#define MAX_PATH
Definition: compat.h:26
START_TEST(joystick)
Definition: joystick.c:930
#define DIDFT_OPTIONAL
Definition: dinput.h:771
static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
Definition: joystick.c:296
#define DIJOFS_Z
Definition: dinput.h:1207
char * name
Definition: compiler.c:66
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD rgdwPOV[4]
Definition: dinput.h:1180
#define DIERR_NOTDOWNLOADED
Definition: dinput.h:177
WCHAR wsz[MAX_PATH]
Definition: dinput.h:875
#define DIPROP_FFGAIN
Definition: dinput.h:895
#define DIDEVTYPE_JOYSTICK
Definition: dinput.h:200
#define DISCL_FOREGROUND
Definition: dinput.h:965
struct IDirectInputEffect * LPDIRECTINPUTEFFECT
Definition: dinput.h:107
#define DIEP_START
Definition: dinput.h:1026
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LONG lRz
Definition: dinput.h:1178
#define DIEFF_CARTESIAN
Definition: dinput.h:1010
#define DIJOFS_RX
Definition: dinput.h:1208
#define DIEB_NOTRIGGER
Definition: dinput.h:1029
#define todo_wine
Definition: test.h:163
#define DIDFT_AXIS
Definition: dinput.h:753
#define DIEFF_OBJECTOFFSETS
Definition: dinput.h:1009
DWORD dwData
Definition: dinput.h:844
CHAR tszInstanceName[MAX_PATH]
Definition: dinput.h:416
#define DIPROP_JOYSTICKID
Definition: dinput.h:912
#define DIPROP_GUIDANDPATH
Definition: dinput.h:908
LPLONG rglDirection
Definition: dinput.h:1114
#define DIEDFL_ALLDEVICES
Definition: dinput.h:190
const DIDATAFORMAT c_dfDIJoystick2
Definition: data_formats.c:251
static HWND get_hwnd(void)
Definition: joystick.c:67
#define IDirectInputDevice_SetProperty(p, a, b)
Definition: dinput.h:1607
#define IDirectInputDevice_Acquire(p)
Definition: dinput.h:1608
struct DIPROPHEADER DIPROPHEADER
#define DIPROP_AUTOCENTER
Definition: dinput.h:897
_CRTIMP wchar_t *__cdecl _wcslwr(_Inout_z_ wchar_t *_String)
LONG rglSlider[2]
Definition: dinput.h:1179
#define S_OK
Definition: intsafe.h:59
#define DIPROPAUTOCENTER_ON
Definition: dinput.h:900
#define DIPROPAUTOCENTER_OFF
Definition: dinput.h:899
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define ARRAY_SIZE(a)
Definition: main.h:24
#define DIDEVTYPE_HID
Definition: dinput.h:201
#define IDirectInputDevice2_EnumEffects(p, a, b, c)
Definition: dinput.h:1744
#define ok(value,...)
Definition: atltest.h:57
LONG lZ
Definition: dinput.h:1175
#define IDirectInputEffect_Download(p)
Definition: dinput.h:1518
DWORD dwObj
Definition: dinput.h:830
IDirectInputDeviceA * pJoystick
Definition: joystick.c:77
#define IDirectInputDevice_SetDataFormat(p, a)
Definition: dinput.h:1612
#define IDirectInputDevice_GetDeviceInfo(p, a)
Definition: dinput.h:1616
DWORD dwTriggerButton
Definition: dinput.h:1110
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
#define IDirectInput_EnumDevices(p, a, b, c, d)
Definition: dinput.h:2297
#define MultiByteToWideChar
Definition: compat.h:100
#define IDirectInputDevice2_SetProperty(p, a, b)
Definition: dinput.h:1730
#define IDirectInputEffect_GetEffectStatus(p, a)
Definition: dinput.h:1517
DWORD version
Definition: joystick.c:35
#define DISFFC_STOPALL
Definition: dinput.h:971
DWORD dwEffType
Definition: dinput.h:1127
#define IDirectInputDevice2_GetProperty(p, a, b)
Definition: dinput.h:1729
CHAR tszProductName[MAX_PATH]
Definition: dinput.h:417
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
struct tagJoystickInfo JoystickInfo
int effect_count
Definition: joystick.c:189
LONG lMin
Definition: dinput.h:850
#define DI_OK
Definition: dinput.h:128
#define DIENUM_CONTINUE
Definition: dinput.h:188
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
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)
#define DIEFT_RAMPFORCE
Definition: dinput.h:994
#define IDirectInputDevice_Unacquire(p)
Definition: dinput.h:1609
DWORD dwHeaderSize
Definition: dinput.h:829
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:847
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define DIJOFS_RY
Definition: dinput.h:1209
#define DIEFT_ALL
Definition: dinput.h:991
DWORD dwFlags
Definition: dinput.h:1106
LONG lMax
Definition: dinput.h:851
#define DONE
Definition: rnr20lib.h:14
#define DIDFT_ALL
Definition: dinput.h:750
DWORD button
Definition: joystick.c:80
BYTE rgbButtons[128]
Definition: dinput.h:1181
#define DI_FFNOMINALMAX
Definition: dinput.h:1038
static BOOL CALLBACK EnumAllFeedback(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
Definition: joystick.c:273
#define DIDFT_GETTYPE(n)
Definition: dinput.h:763
static const struct effect_id * effect_from_guid(const GUID *guid)
Definition: joystick.c:176
#define E_POINTER
Definition: winerror.h:2365
#define INFINITE
Definition: serial.h:102
struct DIPROPDWORD DIPROPDWORD
#define memset(x, y, z)
Definition: compat.h:39
_Check_return_ _CRTIMP int __cdecl swscanf(_In_z_ const wchar_t *_Src, _In_z_ _Scanf_format_string_ const wchar_t *_Format,...)
#define DIDC_FORCEFEEDBACK
Definition: dinput.h:949
DIPROPHEADER diph
Definition: dinput.h:874
HRESULT WINAPI DECLSPEC_HOTPATCH DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
Definition: dinput_main.c:229
static void joystick_tests(DWORD version)
Definition: joystick.c:889
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define DISCL_EXCLUSIVE
Definition: dinput.h:963
#define SUCCEEDED(hr)
Definition: intsafe.h:57
#define DIPROP_INSTANCENAME
Definition: dinput.h:910