Example #1
0
static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
{
    SysMouseImpl* newDevice;
    LPDIDATAFORMAT df = NULL;
    unsigned i;
    char buffer[20];
    HKEY hkey, appkey;

    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseImpl));
    if (!newDevice) return NULL;
    newDevice->base.IDirectInputDevice8A_iface.lpVtbl = &SysMouseAvt;
    newDevice->base.IDirectInputDevice8W_iface.lpVtbl = &SysMouseWvt;
    newDevice->base.ref = 1;
    newDevice->base.dwCoopLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND;
    newDevice->base.guid = *rguid;
    InitializeCriticalSection(&newDevice->base.crit);
    newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysMouseImpl*->base.crit");
    newDevice->base.dinput = dinput;
    newDevice->base.event_proc = dinput_mouse_hook;

    get_app_key(&hkey, &appkey);
    if (!get_config_key(hkey, appkey, "MouseWarpOverride", buffer, sizeof(buffer)))
    {
        if (!strcasecmp(buffer, "disable"))
            newDevice->warp_override = WARP_DISABLE;
        else if (!strcasecmp(buffer, "force"))
            newDevice->warp_override = WARP_FORCE_ON;
    }
    if (appkey) RegCloseKey(appkey);
    if (hkey) RegCloseKey(hkey);

    /* Create copy of default data format */
    if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIMouse2.dwSize))) goto failed;
    memcpy(df, &c_dfDIMouse2, c_dfDIMouse2.dwSize);
    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;
    memcpy(df->rgodf, c_dfDIMouse2.rgodf, df->dwNumObjs * df->dwObjSize);

    /* Because we don't do any detection yet just modify instance and type */
    for (i = 0; i < df->dwNumObjs; i++)
        if (DIDFT_GETTYPE(df->rgodf[i].dwType) & DIDFT_AXIS)
            df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_RELAXIS;
        else
            df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;

    newDevice->base.data_format.wine_df = df;
    IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);

    EnterCriticalSection(&dinput->crit);
    list_add_tail(&dinput->devices_list, &newDevice->base.entry);
    LeaveCriticalSection(&dinput->crit);

    return newDevice;

failed:
    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
    HeapFree(GetProcessHeap(), 0, df);
    HeapFree(GetProcessHeap(), 0, newDevice);
    return NULL;
}
Example #2
0
/******************************************************************************
  *     GetProperty : get input device properties
  */
static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
						REFGUID rguid,
						LPDIPROPHEADER pdiph)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    TRACE("(this=%p,%s,%p)\n",
	  iface, debugstr_guid(rguid), pdiph);
    
    if (TRACE_ON(dinput))
	_dump_DIPROPHEADER(pdiph);
    
    if (!HIWORD(rguid)) {
	switch (LOWORD(rguid)) {
	    case (DWORD) DIPROP_BUFFERSIZE: {
		LPDIPROPDWORD	pd = (LPDIPROPDWORD)pdiph;
		
		TRACE(" return buffersize = %d\n",This->queue_len);
		pd->dwData = This->queue_len;
		break;
	    }
	      
	    case (DWORD) DIPROP_GRANULARITY: {
		LPDIPROPDWORD pr = (LPDIPROPDWORD) pdiph;
		
		/* We'll just assume that the app asks about the Z axis */
		pr->dwData = WHEEL_DELTA;
		
		break;
	    }
	      
	    case (DWORD) DIPROP_RANGE: {
		LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
		
		if ((pdiph->dwHow == DIPH_BYID) &&
		    ((pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS)) ||
		     (pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS)))) {
		    /* Querying the range of either the X or the Y axis.  As I do
		       not know the range, do as if the range were
		       unrestricted...*/
		    pr->lMin = DIPROPRANGE_NOMIN;
		    pr->lMax = DIPROPRANGE_NOMAX;
		}
		
		break;
	    }
	      
	    default:
	      FIXME("Unknown type %p (%s)\n",rguid,debugstr_guid(rguid));
	      break;
	  }
      }
    
    return DI_OK;
}
Example #3
0
/******************************************************************************
  *     GetProperty : get input device properties
  */
static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
						REFGUID rguid,
						LPDIPROPHEADER pdiph)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    
    TRACE("(%p) %s,%p\n", This, debugstr_guid(rguid), pdiph);
    _dump_DIPROPHEADER(pdiph);
    
    if (!HIWORD(rguid)) {
	switch (LOWORD(rguid)) {
	    case (DWORD) DIPROP_GRANULARITY: {
		LPDIPROPDWORD pr = (LPDIPROPDWORD) pdiph;
		
		/* We'll just assume that the app asks about the Z axis */
		pr->dwData = WHEEL_DELTA;
		
		break;
	    }
	      
	    case (DWORD) DIPROP_RANGE: {
		LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
		
		if ((pdiph->dwHow == DIPH_BYID) &&
		    ((pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS)) ||
		     (pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS)))) {
		    /* Querying the range of either the X or the Y axis.  As I do
		       not know the range, do as if the range were
		       unrestricted...*/
		    pr->lMin = DIPROPRANGE_NOMIN;
		    pr->lMax = DIPROPRANGE_NOMAX;
		}
		
		break;
	    }

	    default:
                return IDirectInputDevice2AImpl_GetProperty(iface, rguid, pdiph);
        }
    }
    
    return DI_OK;
}
Example #4
0
static SysMouseImpl *alloc_device(REFGUID rguid, const void *mvt, IDirectInputImpl *dinput)
{
    SysMouseImpl* newDevice;
    LPDIDATAFORMAT df = NULL;
    unsigned i;

    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseImpl));
    if (!newDevice) return NULL;
    newDevice->base.lpVtbl = mvt;
    newDevice->base.ref = 1;
    newDevice->base.dwCoopLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND;
    newDevice->base.guid = *rguid;
    InitializeCriticalSection(&newDevice->base.crit);
    newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysMouseImpl*->base.crit");
    newDevice->base.dinput = dinput;
    newDevice->base.event_proc = dinput_mouse_hook;

    /* Create copy of default data format */
    if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIMouse2.dwSize))) goto failed;
    memcpy(df, &c_dfDIMouse2, c_dfDIMouse2.dwSize);
    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;
    memcpy(df->rgodf, c_dfDIMouse2.rgodf, df->dwNumObjs * df->dwObjSize);

    /* Because we don't do any detection yet just modify instance and type */
    for (i = 0; i < df->dwNumObjs; i++)
        if (DIDFT_GETTYPE(df->rgodf[i].dwType) & DIDFT_AXIS)
            df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_RELAXIS;
        else
            df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;

    newDevice->base.data_format.wine_df = df;
    IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->base.dinput);
    return newDevice;

failed:
    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
    HeapFree(GetProcessHeap(), 0, df);
    HeapFree(GetProcessHeap(), 0, newDevice);
    return NULL;
}
Example #5
0
static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
{
    SysKeyboardImpl* newDevice;
    LPDIDATAFORMAT df = NULL;
    int i, idx = 0;

    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardImpl));
    newDevice->base.IDirectInputDevice8A_iface.lpVtbl = &SysKeyboardAvt;
    newDevice->base.IDirectInputDevice8W_iface.lpVtbl = &SysKeyboardWvt;
    newDevice->base.ref = 1;
    memcpy(&newDevice->base.guid, rguid, sizeof(*rguid));
    newDevice->base.dinput = dinput;
    newDevice->base.event_proc = KeyboardCallback;
    InitializeCriticalSection(&newDevice->base.crit);
    newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");

    /* Create copy of default data format */
    if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIKeyboard.dwSize))) goto failed;
    memcpy(df, &c_dfDIKeyboard, c_dfDIKeyboard.dwSize);
    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;

    for (i = 0; i < df->dwNumObjs; i++)
    {
        char buf[MAX_PATH];

        if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf)))
            continue;

        memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[i], df->dwObjSize);
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
    }
    df->dwNumObjs = idx;

    newDevice->base.data_format.wine_df = df;
    IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);

    EnterCriticalSection(&dinput->crit);
    list_add_tail(&dinput->devices_list, &newDevice->base.entry);
    LeaveCriticalSection(&dinput->crit);

    return newDevice;

failed:
    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
    HeapFree(GetProcessHeap(), 0, df);
    HeapFree(GetProcessHeap(), 0, newDevice);
    return NULL;
}
Example #6
0
static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
{
    SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface);
    int dik_code, ret = This->base.dwCoopLevel & DISCL_EXCLUSIVE;
    KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
    BYTE new_diks;

    if (wparam != WM_KEYDOWN && wparam != WM_KEYUP &&
            wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP)
        return 0;

    TRACE("(%p) %ld,%ld\n", iface, wparam, lparam);

    switch (hook->vkCode)
    {
    /* R-Shift is special - it is an extended key with separate scan code */
    case VK_RSHIFT  :
        dik_code = DIK_RSHIFT;
        break;
    case VK_PAUSE   :
        dik_code = DIK_PAUSE;
        break;
    case VK_NUMLOCK :
        dik_code = DIK_NUMLOCK;
        break;
    case VK_SUBTRACT:
        dik_code = DIK_SUBTRACT;
        break;
    default:
        dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode);
        if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
    }
    new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;

    /* returns now if key event already known */
    if (new_diks == This->DInputKeyState[dik_code])
        return ret;

    This->DInputKeyState[dik_code] = new_diks;
    TRACE(" setting %02X to %02X\n", dik_code, This->DInputKeyState[dik_code]);

    EnterCriticalSection(&This->base.crit);
    queue_event(iface, DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON,
                new_diks, hook->time, This->base.dinput->evsequence++);
    LeaveCriticalSection(&This->base.crit);

    return ret;
}
Example #7
0
static gboolean
dx_dinput_setup_events (ControllerDXDInput *controller,
                        GError            **error)
{
  HRESULT         hresult;
  DIPROPDWORD     dword;
  gint            i, k;
  DXDInputSource *source;

  if ((controller->event = CreateEvent (NULL, TRUE, FALSE, NULL)) == NULL)
    {
      g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED,
                   "CreateEvent failed: %s",
                   g_win32_error_message (GetLastError ()));
      return FALSE;
    }

  controller->format = g_new (DIDATAFORMAT, 1);
  controller->format->dwSize = sizeof (DIDATAFORMAT);
  controller->format->dwObjSize = sizeof (DIOBJECTDATAFORMAT);

  dword.diph.dwSize = sizeof (DIPROPDWORD);
  dword.diph.dwHeaderSize = sizeof (DIPROPHEADER);
  dword.diph.dwObj = 0;
  dword.diph.dwHow = DIPH_DEVICE;

  /* Get the axis mode so we can use the same in the format */
  if (FAILED ((hresult = IDirectInputDevice8_GetProperty (controller->didevice8,
                                                          DIPROP_AXISMODE,
                                                          &dword.diph))))
    {
      g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED,
                   "IDirectInputDevice8::GetParameters failed: %s",
                   g_win32_error_message (hresult));
      goto fail0;
    }

  controller->format->dwFlags = dword.dwData + 1;

  controller->format->dwNumObjs =
    controller->num_buttons +
    controller->num_axes +
    controller->num_sliders +
    controller->num_povs;

  controller->format->rgodf = g_new (DIOBJECTDATAFORMAT, controller->format->dwNumObjs);

  k = 0;
  controller->format->dwDataSize = 0;

  for (i = 0; i < controller->num_buttons; i++)
    {
      controller->format->rgodf[k].pguid = NULL;
      controller->format->rgodf[k].dwOfs = controller->format->dwDataSize;
      controller->format->rgodf[k].dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE (i);
      controller->format->rgodf[k].dwFlags = 0;
      controller->format->dwDataSize += 1;
      k++;
    }

  controller->format->dwDataSize = 4*((controller->format->dwDataSize + 3)/4);

  for (i = 0; i < controller->num_axes; i++)
    {
      controller->format->rgodf[k].pguid = NULL;
      controller->format->rgodf[k].dwOfs = controller->format->dwDataSize;
      controller->format->rgodf[k].dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE (i);
      controller->format->rgodf[k].dwFlags = DIDOI_ASPECTPOSITION;
      controller->format->dwDataSize += 4;
      k++;
    }

  for (i = 0; i < controller->num_sliders; i++)
    {
      controller->format->rgodf[k].pguid = NULL;
      controller->format->rgodf[k].dwOfs = controller->format->dwDataSize;
      controller->format->rgodf[k].dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE (i);
      controller->format->rgodf[k].dwFlags = DIDOI_ASPECTPOSITION;
      controller->format->dwDataSize += 4;
      k++;
    }

  for (i = 0; i < controller->num_povs; i++)
    {
      controller->format->rgodf[k].pguid = NULL;
      controller->format->rgodf[k].dwOfs = controller->format->dwDataSize;
      controller->format->rgodf[k].dwType = DIDFT_POV | DIDFT_MAKEINSTANCE (i);
      controller->format->rgodf[k].dwFlags = 0;
      controller->format->dwDataSize += 4;
      k++;
    }

  g_assert (k == controller->format->dwNumObjs);

  controller->format->dwDataSize = 4*((controller->format->dwDataSize + 3)/4);
  controller->prevdata = g_malloc (controller->format->dwDataSize);

  dump_data_format (controller->format);

  if (FAILED ((hresult = IDirectInputDevice8_SetDataFormat (controller->didevice8,
                                                            controller->format))))
    {
      g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED,
                   "IDirectInputDevice8::SetDataFormat failed: %s",
                   g_win32_error_message (hresult));
      goto fail1;
    }

  if (FAILED ((hresult = IDirectInputDevice8_SetEventNotification (controller->didevice8,
                                                                   controller->event))))
    {
      g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED,
                   "IDirectInputDevice8::SetEventNotification failed: %s",
                   g_win32_error_message (hresult));
      goto fail2;
    }

  if (FAILED ((hresult = IDirectInputDevice8_Acquire (controller->didevice8))))
    {
      g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED,
                   "IDirectInputDevice8::Acquire failed: %s",
                   g_win32_error_message (hresult));
      goto fail2;
    }

  if (FAILED ((hresult = IDirectInputDevice8_GetDeviceState (controller->didevice8,
                                                             controller->format->dwDataSize,
                                                             controller->prevdata))))
    {
      g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED,
                   "IDirectInputDevice8::GetDeviceState failed: %s",
                   g_win32_error_message (hresult));
      goto fail2;
    }

  source = (DXDInputSource *) g_source_new (&dx_dinput_event_funcs,
                                            sizeof (DXDInputSource));
  source->controller = controller;
  controller->source = (GSource *) source;

  controller->pollfd = g_new (GPollFD, 1);

  controller->pollfd->fd = (int) controller->event;
  controller->pollfd->events = G_IO_IN;

  g_source_add_poll (&source->source, controller->pollfd);
  g_source_attach (&source->source, NULL);

  return TRUE;

 fail2:
  IDirectInputDevice8_SetEventNotification (controller->didevice8, NULL);
 fail1:
  g_free (controller->format->rgodf);
  g_free (controller->format);
  controller->format = NULL;
  g_free (controller->prevdata);
  controller->prevdata = NULL;
 fail0:
  CloseHandle (controller->event);
  controller->event = 0;

  return FALSE;
}
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nSetDataFormat(JNIEnv *env, jclass unused, jlong address, jint flags, jobjectArray objects) {
    LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address;
	DIDATAFORMAT data_format;
	jsize num_objects = (*env)->GetArrayLength(env, objects);
	/*
	 * Data size must be a multiple of 4, but since sizeof(jint) is
	 * 4, we're safe
	 */
	DWORD data_size = num_objects*sizeof(jint);
	GUID *guids;
	DIOBJECTDATAFORMAT *object_formats;
	int i;
	HRESULT res;
	jclass clazz;
	jmethodID getGUID_method;
	jmethodID getFlags_method;
	jmethodID getType_method;
	jmethodID getInstance_method;
	jobject object;
	jint type;
	jint object_flags;
	jint instance;
	jobject guid_array;
	DWORD composite_type;
	DWORD flags_masked;
	LPDIOBJECTDATAFORMAT object_format;
	
	data_format.dwSize = sizeof(DIDATAFORMAT);
	data_format.dwObjSize = sizeof(DIOBJECTDATAFORMAT);
	data_format.dwFlags = flags;
	data_format.dwDataSize = data_size;
	data_format.dwNumObjs = num_objects;

	clazz = (*env)->FindClass(env, "net/java/games/input/DIDeviceObject");
	if (clazz == NULL)
		return -1;
	getGUID_method = (*env)->GetMethodID(env, clazz, "getGUID", "()[B");
	if (getGUID_method == NULL)
		return -1;
	getFlags_method = (*env)->GetMethodID(env, clazz, "getFlags", "()I");
	if (getFlags_method == NULL)
		return -1;
	getType_method = (*env)->GetMethodID(env, clazz, "getType", "()I");
	if (getType_method == NULL)
		return -1;
	getInstance_method = (*env)->GetMethodID(env, clazz, "getInstance", "()I");
	if (getInstance_method == NULL)
		return -1;

	guids = (GUID *)malloc(num_objects*sizeof(GUID));
	if (guids == NULL) {
		throwIOException(env, "Failed to allocate GUIDs");
		return -1;
	}
	object_formats = (DIOBJECTDATAFORMAT *)malloc(num_objects*sizeof(DIOBJECTDATAFORMAT));
	if (object_formats == NULL) {
		free(guids);
		throwIOException(env, "Failed to allocate data format");
		return -1;
	}
	for (i = 0; i < num_objects; i++) {
		object = (*env)->GetObjectArrayElement(env, objects, i);
		if ((*env)->ExceptionOccurred(env)) {
			free(guids);
			free(object_formats);
			return -1;
		}
		guid_array = (*env)->CallObjectMethod(env, object, getGUID_method);
		if ((*env)->ExceptionOccurred(env)) {
			free(guids);
			free(object_formats);
			return -1;
		}
		unwrapGUID(env, guid_array, guids + i);
		if ((*env)->ExceptionOccurred(env)) {
			free(guids);
			free(object_formats);
			return -1;
		}
		type = (*env)->CallIntMethod(env, object, getType_method);
		if ((*env)->ExceptionOccurred(env)) {
			free(guids);
			free(object_formats);
			return -1;
		}
		object_flags = (*env)->CallIntMethod(env, object, getFlags_method);
		if ((*env)->ExceptionOccurred(env)) {
			free(guids);
			free(object_formats);
			return -1;
		}
		instance = (*env)->CallIntMethod(env, object, getInstance_method);
		if ((*env)->ExceptionOccurred(env)) {
			free(guids);
			free(object_formats);
			return -1;
		}
		(*env)->DeleteLocalRef(env, object);
		composite_type = type | DIDFT_MAKEINSTANCE(instance);
		flags_masked = flags & (DIDOI_ASPECTACCEL | DIDOI_ASPECTFORCE | DIDOI_ASPECTPOSITION | DIDOI_ASPECTVELOCITY);		
		object_format = object_formats + i;
		object_format->pguid = guids + i;
		object_format->dwType = composite_type;
		object_format->dwFlags = flags_masked;
		// dwOfs must be multiple of 4, but sizeof(jint) is 4, so we're safe
		object_format->dwOfs = i*sizeof(jint);
	}
	data_format.rgodf = object_formats;
	res = IDirectInputDevice8_SetDataFormat(lpDevice, &data_format);
	free(guids);
	free(object_formats);
	return res;
}
static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput, unsigned short index)
{
    JoystickImpl* newDevice;
    LPDIDATAFORMAT df = NULL;
    int i, idx = 0;
    char buffer[MAX_PATH+16];
    HKEY hkey, appkey;
    LONG def_deadzone = 0;

    newDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(JoystickImpl));
    if (!newDevice) return NULL;

    newDevice->base.lpVtbl = jvt;
    newDevice->base.ref    = 1;
    newDevice->base.guid   = *rguid;
    newDevice->base.dinput = dinput;
    newDevice->joyfd       = -1;
    newDevice->joydev      = &joydevs[index];
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
    newDevice->ff_state    = FF_STATUS_STOPPED;
#endif
    InitializeCriticalSection(&newDevice->base.crit);
    newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->base.crit");

    /* get options */
    get_app_key(&hkey, &appkey);

    if (!get_config_key(hkey, appkey, "DefaultDeadZone", buffer, MAX_PATH))
    {
        def_deadzone = atoi(buffer);
        TRACE("setting default deadzone to: %d\n", def_deadzone);
    }
    if (appkey) RegCloseKey(appkey);
    if (hkey) RegCloseKey(hkey);

    /* Create copy of default data format */
    if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto failed;
    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;

    /* Supported Axis & POVs should map 1-to-1 */
    for (i = 0; i < WINE_JOYSTICK_MAX_AXES; i++)
    {
        if (!test_bit(newDevice->joydev->absbits, i)) {
            newDevice->axes[i] = -1;
            continue;
        }

        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i], df->dwObjSize);
        newDevice->axes[i] = idx;
        newDevice->props[idx].lDevMin = newDevice->joydev->axes[i].minimum;
        newDevice->props[idx].lDevMax = newDevice->joydev->axes[i].maximum;
        newDevice->props[idx].lMin    = 0;
        newDevice->props[idx].lMax    = 0xffff;
        newDevice->props[idx].lSaturation = 0;
        newDevice->props[idx].lDeadZone = def_deadzone;

        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(newDevice->numAxes++) | DIDFT_ABSAXIS;
    }

    for (i = 0; i < WINE_JOYSTICK_MAX_POVS; i++)
    {
        if (!test_bit(newDevice->joydev->absbits, ABS_HAT0X + i * 2) ||
            !test_bit(newDevice->joydev->absbits, ABS_HAT0Y + i * 2)) {
            newDevice->axes[ABS_HAT0X + i * 2] = newDevice->axes[ABS_HAT0Y + i * 2] = -1;
            continue;
        }

        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + WINE_JOYSTICK_MAX_AXES], df->dwObjSize);
        newDevice->axes[ABS_HAT0X + i * 2] = newDevice->axes[ABS_HAT0Y + i * 2] = i;
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(newDevice->numPOVs++) | DIDFT_POV;
    }

    /* Buttons can be anywhere, so check all */
    for (i = 0; i < KEY_MAX && newDevice->numButtons < WINE_JOYSTICK_MAX_BUTTONS; i++)
    {
        if (!test_bit(newDevice->joydev->keybits, i)) continue;

        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[newDevice->numButtons + WINE_JOYSTICK_MAX_AXES + WINE_JOYSTICK_MAX_POVS], df->dwObjSize);
	newDevice->buttons[i] = 0x80 | newDevice->numButtons;
        df->rgodf[idx  ].pguid = &GUID_Button;
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(newDevice->numButtons++) | DIDFT_PSHBUTTON;
    }
    df->dwNumObjs = idx;

    fake_current_js_state(newDevice);

    newDevice->base.data_format.wine_df = df;
    IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->base.dinput);
    return newDevice;

failed:
    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
    HeapFree(GetProcessHeap(), 0, df);
    HeapFree(GetProcessHeap(), 0, newDevice);
    return NULL;
}
/* convert wine format offset to user format object index */
static void joy_polldev(JoystickImpl *This)
{
    struct pollfd plfd;
    struct input_event ie;

    if (This->joyfd==-1)
	return;

    while (1)
    {
        LONG value = 0;
        int inst_id = -1;

	plfd.fd = This->joyfd;
	plfd.events = POLLIN;

	if (poll(&plfd,1,0) != 1)
	    return;

	/* we have one event, so we can read */
	if (sizeof(ie)!=read(This->joyfd,&ie,sizeof(ie)))
	    return;

	TRACE("input_event: type %d, code %d, value %d\n",ie.type,ie.code,ie.value);
	switch (ie.type) {
	case EV_KEY:	/* button */
        {
            int btn = This->buttons[ie.code];

            TRACE("(%p) %d -> %d\n", This, ie.code, btn);
            if (btn & 0x80)
            {
                btn &= 0x7F;
                inst_id = DIDFT_MAKEINSTANCE(btn) | DIDFT_PSHBUTTON;
                This->js.rgbButtons[btn] = value = ie.value ? 0x80 : 0x00;
            }
            break;
        }
	case EV_ABS:
        {
            int axis = This->axes[ie.code];
            if (axis==-1) {
                break;
            }
            inst_id = DIDFT_MAKEINSTANCE(axis) | (ie.code < ABS_HAT0X ? DIDFT_ABSAXIS : DIDFT_POV);
            value = joystick_map_axis(&This->props[id_to_object(This->base.data_format.wine_df, inst_id)], ie.value);

	    switch (ie.code) {
            case ABS_X:         This->js.lX  = value; break;
            case ABS_Y:         This->js.lY  = value; break;
            case ABS_Z:         This->js.lZ  = value; break;
            case ABS_RX:        This->js.lRx = value; break;
            case ABS_RY:        This->js.lRy = value; break;
            case ABS_RZ:        This->js.lRz = value; break;
            case ABS_THROTTLE:  This->js.rglSlider[0] = value; break;
            case ABS_RUDDER:    This->js.rglSlider[1] = value; break;
            case ABS_HAT0X: case ABS_HAT0Y: case ABS_HAT1X: case ABS_HAT1Y:
            case ABS_HAT2X: case ABS_HAT2Y: case ABS_HAT3X: case ABS_HAT3Y:
            {
                int idx = (ie.code - ABS_HAT0X) / 2;

                if (ie.code % 2)
                    This->povs[idx].y = ie.value;
                else
                    This->povs[idx].x = ie.value;

                This->js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]);
                break;
            }
	    default:
		FIXME("unhandled joystick axis event (code %d, value %d)\n",ie.code,ie.value);
	    }
	    break;
        }
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
	case EV_FF_STATUS:
	    This->ff_state = ie.value;
	    break;
#endif
#ifdef EV_SYN
	case EV_SYN:
	    /* there is nothing to do */
	    break;
#endif
	default:
	    FIXME("joystick cannot handle type %d event (code %d)\n",ie.type,ie.code);
	    break;
	}
        if (inst_id >= 0)
            queue_event((LPDIRECTINPUTDEVICE8A)This,
                        id_to_offset(&This->base.data_format, inst_id),
                        value, ie.time.tv_usec, This->base.dinput->evsequence++);
    }
}
Example #11
0
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define DIRECTINPUT_VERSION 0x0700

#define COBJMACROS
#include <windows.h>

#include "wine/test.h"
#include "windef.h"
#include "dinput.h"

static const DIOBJECTDATAFORMAT obj_data_format[] = {
  { &GUID_YAxis, 16, DIDFT_OPTIONAL|DIDFT_AXIS  |DIDFT_MAKEINSTANCE(1), 0},
  { &GUID_Button,15, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(3), 0},
  { &GUID_Key,    0, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(16),0},
  { &GUID_Key,    1, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(17),0},
  { &GUID_Key,    2, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(18),0},
  { &GUID_Key,    3, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(19),0},
  { &GUID_Key,    4, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(20),0},
  { &GUID_Key,    5, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(21),0},
  { &GUID_Key,    6, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(22),0},
  { &GUID_Key,    7, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(23),0},
  { &GUID_Key,    8, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(24),0},
  { &GUID_Key,    9, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(25),0},
  { &GUID_Key,   10, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(26),0},
  { &GUID_Key,   11, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(27),0},
  { &GUID_Key,   12, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(28),0},
  { NULL,        13, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(5),0},
Example #12
0
static void test_save_settings(void)
{
    HRESULT hr;
    HINSTANCE hinst = GetModuleHandleA(NULL);
    IDirectInput8A *pDI = NULL;
    DIACTIONFORMATA af;
    IDirectInputDevice8A *pKey;

    static const GUID mapping_guid = { 0xcafecafe, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
    static const GUID other_guid = { 0xcafe, 0xcafe, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };

    static DIACTIONA actions[] = {
        { 0, DIKEYBOARD_A , 0, { "Blam" } },
        { 1, DIKEYBOARD_B , 0, { "Kapow"} }
    };
    static const DWORD results[] = {
        DIDFT_MAKEINSTANCE(DIK_A) | DIDFT_PSHBUTTON,
        DIDFT_MAKEINSTANCE(DIK_B) | DIDFT_PSHBUTTON
    };
    static const DWORD other_results[] = {
        DIDFT_MAKEINSTANCE(DIK_C) | DIDFT_PSHBUTTON,
        DIDFT_MAKEINSTANCE(DIK_D) | DIDFT_PSHBUTTON
    };

    hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI);
    if (hr == DIERR_OLDDIRECTINPUTVERSION ||
        hr == DIERR_BETADIRECTINPUTVERSION ||
        hr == REGDB_E_CLASSNOTREG)
    {
        win_skip("ActionMapping requires dinput8\n");
        return;
    }
    ok (SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr);
    if (FAILED(hr)) return;

    hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION);
    if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
    {
        win_skip("ActionMapping requires dinput8\n");
        return;
    }
    ok (SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%08x\n", hr);
    if (FAILED(hr)) return;

    hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKey, NULL);
    ok (SUCCEEDED(hr), "IDirectInput_Create device failed hr: 0x%08x\n", hr);
    if (FAILED(hr)) return;

    memset (&af, 0, sizeof(af));
    af.dwSize = sizeof(af);
    af.dwActionSize = sizeof(DIACTIONA);
    af.dwDataSize = 4 * ARRAY_SIZE(actions);
    af.dwNumActions = ARRAY_SIZE(actions);
    af.rgoAction = actions;
    af.guidActionMap = mapping_guid;
    af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
    af.dwBufferSize = 32;

    /* Easy case. Ask for default mapping, save, ask for previous map and read it back */
    hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, DIDBAM_HWDEFAULTS);
    ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);

    ok (results[0] == af.rgoAction[0].dwObjID,
        "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);

    ok (results[1] == af.rgoAction[1].dwObjID,
        "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);

    hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE);
    ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);

    if (hr == DI_SETTINGSNOTSAVED)
    {
        skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n");
        return;
    }

    af.rgoAction[0].dwObjID = 0;
    af.rgoAction[1].dwObjID = 0;
    memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
    memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));

    hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
    ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);

    ok (results[0] == af.rgoAction[0].dwObjID,
        "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);
    ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");

    ok (results[1] == af.rgoAction[1].dwObjID,
        "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);
    ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");

    /* Test that a different action map with no pre-stored settings, in spite of the flags,
       does not try to load mappings and instead applies the default mapping */
    af.guidActionMap = other_guid;

    af.rgoAction[0].dwObjID = 0;
    af.rgoAction[1].dwObjID = 0;
    memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
    memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));

    hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
    ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);

    ok (results[0] == af.rgoAction[0].dwObjID,
        "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID);
    ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");

    ok (results[1] == af.rgoAction[1].dwObjID,
        "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID);
    ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");

    af.guidActionMap = mapping_guid;
    /* Hard case. Customized mapping, save, ask for previous map and read it back */
    af.rgoAction[0].dwObjID = other_results[0];
    af.rgoAction[0].dwHow = DIAH_USERCONFIG;
    af.rgoAction[0].guidInstance = GUID_SysKeyboard;
    af.rgoAction[1].dwObjID = other_results[1];
    af.rgoAction[1].dwHow = DIAH_USERCONFIG;
    af.rgoAction[1].guidInstance = GUID_SysKeyboard;

    hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE);
    ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);

    if (hr == DI_SETTINGSNOTSAVED)
    {
        skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n");
        return;
    }

    af.rgoAction[0].dwObjID = 0;
    af.rgoAction[1].dwObjID = 0;
    memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID));
    memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID));

    hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0);
    ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr);

    ok (other_results[0] == af.rgoAction[0].dwObjID,
        "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[0], af.rgoAction[0].dwObjID);
    ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n");

    ok (other_results[1] == af.rgoAction[1].dwObjID,
        "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[1], af.rgoAction[1].dwObjID);
    ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n");
}
Example #13
0
static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput,
    LPDIRECTINPUTDEVICEA* pdev, unsigned short index)
{
    DWORD i;
    JoystickImpl* newDevice;
    char name[MAX_PATH];
    HRESULT hr;
    LPDIDATAFORMAT df = NULL;
    int idx = 0;

    TRACE("%s %p %p %p %hu\n", debugstr_guid(rguid), jvt, dinput, pdev, index);

    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
    if (newDevice == 0) {
        WARN("out of memory\n");
        *pdev = 0;
        return DIERR_OUTOFMEMORY;
    }

    if (!lstrcpynA(newDevice->dev, joystick_devices[index], sizeof(newDevice->dev)) ||
        (newDevice->joyfd = open(newDevice->dev, O_RDONLY)) < 0)
    {
        WARN("open(%s, O_RDONLY) failed: %s\n", newDevice->dev, strerror(errno));
        HeapFree(GetProcessHeap(), 0, newDevice);
        return DIERR_DEVICENOTREG;
    }

    /* get the device name */
#if defined(JSIOCGNAME)
    if (ioctl(newDevice->joyfd,JSIOCGNAME(MAX_PATH),name) < 0) {
        WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", newDevice->dev, strerror(errno));
        strcpy(name, "Wine Joystick");
    }
#else
    strcpy(name, "Wine Joystick");
#endif

    /* copy the device name */
    newDevice->name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1);
    strcpy(newDevice->name, name);

#ifdef JSIOCGAXES
    if (ioctl(newDevice->joyfd,JSIOCGAXES,&newDevice->axes) < 0) {
        WARN("ioctl(%s,JSIOCGAXES) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno));
        newDevice->axes = 2;
    }
#endif
#ifdef JSIOCGBUTTONS
    if (ioctl(newDevice->joyfd, JSIOCGBUTTONS, &newDevice->devcaps.dwButtons) < 0) {
        WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno));
        newDevice->devcaps.dwButtons = 2;
    }
#endif

    if (newDevice->devcaps.dwButtons > 128)
    {
        WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->devcaps.dwButtons);
        newDevice->devcaps.dwButtons = 128;
    }

    newDevice->base.lpVtbl = jvt;
    newDevice->base.ref = 1;
    newDevice->base.dinput = dinput;
    newDevice->base.guid = *rguid;
    InitializeCriticalSection(&newDevice->base.crit);
    newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->base.crit");

    /* setup_dinput_options may change these */
    newDevice->deadzone = 0;

    /* do any user specified configuration */
    hr = setup_dinput_options(newDevice);
    if (hr != DI_OK)
        goto FAILED1;

    /* Create copy of default data format */
    if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);

    df->dwNumObjs = newDevice->devcaps.dwAxes + newDevice->devcaps.dwPOVs + newDevice->devcaps.dwButtons;
    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;

    for (i = 0; i < newDevice->axes; i++)
    {
        int wine_obj = newDevice->axis_map[i];

        if (wine_obj < 0) continue;

        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
        if (wine_obj < 8)
            df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
        else
        {
            df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj - 8) | DIDFT_POV;
            i++; /* POV takes 2 axes */
        }
    }
    for (i = 0; i < newDevice->devcaps.dwButtons; i++)
    {
        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
        df->rgodf[idx  ].pguid = &GUID_Button;
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
    }
    newDevice->base.data_format.wine_df = df;

    /* create default properties */
    newDevice->props = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwNumObjs*sizeof(ObjProps));
    if (newDevice->props == 0)
        goto FAILED;

    /* initialize default properties */
    for (i = 0; i < c_dfDIJoystick2.dwNumObjs; i++) {
        newDevice->props[i].lDevMin = -32767;
        newDevice->props[i].lDevMax = +32767;
        newDevice->props[i].lMin = 0;
        newDevice->props[i].lMax = 0xffff;
        newDevice->props[i].lDeadZone = newDevice->deadzone;	/* % * 1000 */
        newDevice->props[i].lSaturation = 0;
    }

    IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->base.dinput);

    newDevice->devcaps.dwSize = sizeof(newDevice->devcaps);
    newDevice->devcaps.dwFlags = DIDC_ATTACHED;
    if (newDevice->base.dinput->dwVersion >= 0x0800)
        newDevice->devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
    else
        newDevice->devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
    newDevice->devcaps.dwFFSamplePeriod = 0;
    newDevice->devcaps.dwFFMinTimeResolution = 0;
    newDevice->devcaps.dwFirmwareRevision = 0;
    newDevice->devcaps.dwHardwareRevision = 0;
    newDevice->devcaps.dwFFDriverVersion = 0;

    if (TRACE_ON(dinput)) {
        _dump_DIDATAFORMAT(newDevice->base.data_format.wine_df);
       for (i = 0; i < (newDevice->axes); i++)
           TRACE("axis_map[%d] = %d\n", i, newDevice->axis_map[i]);
        _dump_DIDEVCAPS(&newDevice->devcaps);
    }

    *pdev = (LPDIRECTINPUTDEVICEA)newDevice;

    return DI_OK;

FAILED:
    hr = DIERR_OUTOFMEMORY;
FAILED1:
    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
    HeapFree(GetProcessHeap(), 0, df);
    release_DataFormat(&newDevice->base.data_format);
    HeapFree(GetProcessHeap(),0,newDevice->axis_map);
    HeapFree(GetProcessHeap(),0,newDevice->name);
    HeapFree(GetProcessHeap(),0,newDevice->props);
    HeapFree(GetProcessHeap(),0,newDevice);
    *pdev = 0;

    return hr;
}
Example #14
0
static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
                            JoystickImpl **pdev, unsigned short index)
{
    DWORD i;
    IOHIDDeviceRef device;
    JoystickImpl* newDevice;
    char name[MAX_PATH];
    HRESULT hr;
    LPDIDATAFORMAT df = NULL;
    int idx = 0;
    int axis_map[8]; /* max axes */
    int slider_count = 0;
    FFCAPABILITIES ffcaps;

    TRACE("%s %p %p %hu\n", debugstr_guid(rguid), dinput, pdev, index);

    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
    if (newDevice == 0) {
        WARN("out of memory\n");
        *pdev = 0;
        return DIERR_OUTOFMEMORY;
    }

    newDevice->id = index;

    newDevice->generic.guidInstance = DInput_Wine_OsX_Joystick_GUID;
    newDevice->generic.guidInstance.Data3 = index;
    newDevice->generic.guidProduct = DInput_Wine_OsX_Joystick_GUID;
    newDevice->generic.joy_polldev = poll_osx_device_state;

    /* get the device name */
    get_osx_device_name(index, name, MAX_PATH);
    TRACE("Name %s\n",name);

    /* copy the device name */
    newDevice->generic.name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1);
    strcpy(newDevice->generic.name, name);

    list_init(&newDevice->effects);
    device = get_device_ref(index);
    if(get_ff(device, &newDevice->ff) == S_OK) {
        newDevice->generic.devcaps.dwFlags |= DIDC_FORCEFEEDBACK;

        hr = FFDeviceGetForceFeedbackCapabilities(newDevice->ff, &ffcaps);
        if(SUCCEEDED(hr)) {
            TRACE("FF Capabilities:\n");
            TRACE("\tsupportedEffects: 0x%x\n", (unsigned int)ffcaps.supportedEffects);
            TRACE("\temulatedEffects: 0x%x\n", (unsigned int)ffcaps.emulatedEffects);
            TRACE("\tsubType: 0x%x\n", (unsigned int)ffcaps.subType);
            TRACE("\tnumFfAxes: %u\n", (unsigned int)ffcaps.numFfAxes);
            TRACE("\tffAxes: [");
            for(i = 0; i < ffcaps.numFfAxes; ++i) {
                TRACE("%s", osx_ff_axis_name(ffcaps.ffAxes[i]));
                if(i < ffcaps.numFfAxes - 1)
                    TRACE(", ");
            }
            TRACE("]\n");
            TRACE("\tstorageCapacity: %u\n", (unsigned int)ffcaps.storageCapacity);
            TRACE("\tplaybackCapacity: %u\n", (unsigned int)ffcaps.playbackCapacity);
        }

        hr = FFDeviceSendForceFeedbackCommand(newDevice->ff, FFSFFC_RESET);
        if(FAILED(hr))
            WARN("FFDeviceSendForceFeedbackCommand(FFSFFC_RESET) failed: %08x\n", hr);

        hr = FFDeviceSendForceFeedbackCommand(newDevice->ff, FFSFFC_SETACTUATORSON);
        if(FAILED(hr))
            WARN("FFDeviceSendForceFeedbackCommand(FFSFFC_SETACTUATORSON) failed: %08x\n", hr);
    }

    memset(axis_map, 0, sizeof(axis_map));
    get_osx_device_elements(newDevice, axis_map);

    TRACE("%i axes %i buttons %i povs\n",newDevice->generic.devcaps.dwAxes,newDevice->generic.devcaps.dwButtons,newDevice->generic.devcaps.dwPOVs);

    if (newDevice->generic.devcaps.dwButtons > 128)
    {
        WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons);
        newDevice->generic.devcaps.dwButtons = 128;
    }

    newDevice->generic.base.IDirectInputDevice8A_iface.lpVtbl = &JoystickAvt;
    newDevice->generic.base.IDirectInputDevice8W_iface.lpVtbl = &JoystickWvt;
    newDevice->generic.base.ref = 1;
    newDevice->generic.base.dinput = dinput;
    newDevice->generic.base.guid = *rguid;
    InitializeCriticalSection(&newDevice->generic.base.crit);
    newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");

    /* Create copy of default data format */
    if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);

    df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons;
    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;

    for (i = 0; i < newDevice->generic.devcaps.dwAxes; i++)
    {
        int wine_obj = -1;
        BOOL has_ff  = FALSE;
        switch (axis_map[i])
        {
        case kHIDUsage_GD_X:
            wine_obj = 0;
            has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_X);
            break;
        case kHIDUsage_GD_Y:
            wine_obj = 1;
            has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_Y);
            break;
        case kHIDUsage_GD_Z:
            wine_obj = 2;
            has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_Z);
            break;
        case kHIDUsage_GD_Rx:
            wine_obj = 3;
            has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RX);
            break;
        case kHIDUsage_GD_Ry:
            wine_obj = 4;
            has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RY);
            break;
        case kHIDUsage_GD_Rz:
            wine_obj = 5;
            has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_RZ);
            break;
        case kHIDUsage_GD_Slider:
            wine_obj = 6 + slider_count;
            has_ff = (newDevice->ff != 0) && osx_axis_has_ff(&ffcaps, FFJOFS_SLIDER(slider_count));
            slider_count++;
            break;
        }
        if (wine_obj < 0 ) continue;

        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
        df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
        if(has_ff)
            df->rgodf[idx].dwFlags |= DIDOI_FFACTUATOR;
        ++idx;
    }

    for (i = 0; i < newDevice->generic.devcaps.dwPOVs; i++)
    {
        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 8], df->dwObjSize);
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_POV;
    }

    for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++)
    {
        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
        df->rgodf[idx  ].pguid = &GUID_Button;
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
    }
    newDevice->generic.base.data_format.wine_df = df;

    /* initialize default properties */
    get_osx_device_elements_props(newDevice);

    IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);

    EnterCriticalSection(&dinput->crit);
    list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
    LeaveCriticalSection(&dinput->crit);

    newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
    newDevice->generic.devcaps.dwFlags |= DIDC_ATTACHED;
    if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
        newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
    else
        newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
    newDevice->generic.devcaps.dwFFSamplePeriod = 0;
    newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
    newDevice->generic.devcaps.dwFirmwareRevision = 0;
    newDevice->generic.devcaps.dwHardwareRevision = 0;
    newDevice->generic.devcaps.dwFFDriverVersion = 0;

    if (TRACE_ON(dinput)) {
        _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df);
        _dump_DIDEVCAPS(&newDevice->generic.devcaps);
    }

    *pdev = newDevice;

    return DI_OK;

FAILED:
    hr = DIERR_OUTOFMEMORY;
    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
    HeapFree(GetProcessHeap(), 0, df);
    release_DataFormat(&newDevice->generic.base.data_format);
    HeapFree(GetProcessHeap(),0,newDevice->generic.name);
    HeapFree(GetProcessHeap(),0,newDevice);
    *pdev = 0;

    return hr;
}
Example #15
0
#define WINE_MOUSE_L_POSITION 3
#define WINE_MOUSE_R_POSITION 4
#define WINE_MOUSE_M_POSITION 5

typedef struct {
    LONG lX;
    LONG lY;
    LONG lZ;
    BYTE rgbButtons[4];
} Wine_InternalMouseData;

#define WINE_INTERNALMOUSE_NUM_OBJS 6

static const DIOBJECTDATAFORMAT Wine_InternalMouseObjectFormat[WINE_INTERNALMOUSE_NUM_OBJS] = {
    { &GUID_XAxis,   FIELD_OFFSET(Wine_InternalMouseData, lX),
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
    { &GUID_YAxis,   FIELD_OFFSET(Wine_InternalMouseData, lY),
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
    { &GUID_ZAxis,   FIELD_OFFSET(Wine_InternalMouseData, lZ),
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
    { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 0,
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 },
    { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 1,
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 },
    { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 2,
	  DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 }
};

static const DIDATAFORMAT Wine_InternalMouseFormat = {
    0, /* dwSize - unused */
    0, /* dwObjsize - unused */
Example #16
0
static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
                            JoystickImpl **pdev, unsigned short index)
{
    DWORD i;
    JoystickImpl* newDevice;
    HRESULT hr;
    LPDIDATAFORMAT df = NULL;
    int idx = 0;

    TRACE("%s %p %p %hu\n", debugstr_guid(rguid), dinput, pdev, index);

    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
    if (newDevice == 0) {
        WARN("out of memory\n");
        *pdev = 0;
        return DIERR_OUTOFMEMORY;
    }

    newDevice->joydev = &joystick_devices[index];
    newDevice->joyfd = -1;
    newDevice->generic.guidInstance = DInput_Wine_Joystick_GUID;
    newDevice->generic.guidInstance.Data3 = index;
    newDevice->generic.guidProduct = DInput_Wine_Joystick_GUID;
    newDevice->generic.joy_polldev = joy_polldev;
    newDevice->generic.name        = newDevice->joydev->name;
    newDevice->generic.device_axis_count = newDevice->joydev->axis_count;
    newDevice->generic.devcaps.dwButtons = newDevice->joydev->button_count;

    if (newDevice->generic.devcaps.dwButtons > 128)
    {
        WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons);
        newDevice->generic.devcaps.dwButtons = 128;
    }

    newDevice->generic.base.IDirectInputDevice8A_iface.lpVtbl = &JoystickAvt;
    newDevice->generic.base.IDirectInputDevice8W_iface.lpVtbl = &JoystickWvt;
    newDevice->generic.base.ref = 1;
    newDevice->generic.base.dinput = dinput;
    newDevice->generic.base.guid = *rguid;
    InitializeCriticalSection(&newDevice->generic.base.crit);
    newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");

    /* setup_dinput_options may change these */
    newDevice->generic.deadzone = 0;

    /* do any user specified configuration */
    hr = setup_dinput_options(&newDevice->generic, newDevice->joydev->dev_axes_map);
    if (hr != DI_OK)
        goto FAILED1;

    /* Create copy of default data format */
    if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);

    df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons;
    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;

    for (i = 0; i < newDevice->generic.device_axis_count; i++)
    {
        int wine_obj = newDevice->generic.axis_map[i];

        if (wine_obj < 0) continue;

        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
        if (wine_obj < 8)
            df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
        else
        {
            df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj - 8) | DIDFT_POV;
            i++; /* POV takes 2 axes */
        }
    }
    for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++)
    {
        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
        df->rgodf[idx  ].pguid = &GUID_Button;
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
    }
    newDevice->generic.base.data_format.wine_df = df;

    /* initialize default properties */
    for (i = 0; i < c_dfDIJoystick2.dwNumObjs; i++) {
        newDevice->generic.props[i].lDevMin = -32767;
        newDevice->generic.props[i].lDevMax = +32767;
        newDevice->generic.props[i].lMin = 0;
        newDevice->generic.props[i].lMax = 0xffff;
        newDevice->generic.props[i].lDeadZone = newDevice->generic.deadzone; /* % * 1000 */
        newDevice->generic.props[i].lSaturation = 0;
    }

    IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);

    EnterCriticalSection(&dinput->crit);
    list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
    LeaveCriticalSection(&dinput->crit);

    newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
    newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
    if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
        newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
    else
        newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
    newDevice->generic.devcaps.dwFFSamplePeriod = 0;
    newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
    newDevice->generic.devcaps.dwFirmwareRevision = 0;
    newDevice->generic.devcaps.dwHardwareRevision = 0;
    newDevice->generic.devcaps.dwFFDriverVersion = 0;

    if (TRACE_ON(dinput)) {
        _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df);
       for (i = 0; i < (newDevice->generic.device_axis_count); i++)
           TRACE("axis_map[%d] = %d\n", i, newDevice->generic.axis_map[i]);
        _dump_DIDEVCAPS(&newDevice->generic.devcaps);
    }

    *pdev = newDevice;

    return DI_OK;

FAILED:
    hr = DIERR_OUTOFMEMORY;
FAILED1:
    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
    HeapFree(GetProcessHeap(), 0, df);
    release_DataFormat(&newDevice->generic.base.data_format);
    HeapFree(GetProcessHeap(),0,newDevice->generic.axis_map);
    HeapFree(GetProcessHeap(),0,newDevice);
    *pdev = 0;

    return hr;
}
Example #17
0
/******************************************************************************
  *     EnumObjects : enumerate the different buttons and axis...
  */
static HRESULT WINAPI SysMouseAImpl_EnumObjects(
	LPDIRECTINPUTDEVICE8A iface,
	LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
	LPVOID lpvRef,
	DWORD dwFlags)
{
    SysMouseImpl *This = (SysMouseImpl *)iface;
    DIDEVICEOBJECTINSTANCEA ddoi;
    
    TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags);
    if (TRACE_ON(dinput)) {
	TRACE("  - flags = ");
	_dump_EnumObjects_flags(dwFlags);
	TRACE("\n");
    }
    
    /* Only the fields till dwFFMaxForce are relevant */
    memset(&ddoi, 0, sizeof(ddoi));
    ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce);
    
    /* In a mouse, we have : two relative axis and three buttons */
    if ((dwFlags == DIDFT_ALL) ||
	(dwFlags & DIDFT_AXIS)) {
	/* X axis */
	ddoi.guidType = GUID_XAxis;
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_X_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS;
	strcpy(ddoi.tszName, "X-Axis");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
	
	/* Y axis */
	ddoi.guidType = GUID_YAxis;
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_Y_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS;
	strcpy(ddoi.tszName, "Y-Axis");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
	
	/* Z axis */
	ddoi.guidType = GUID_ZAxis;
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_Z_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS;
	strcpy(ddoi.tszName, "Z-Axis");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
    }

    if ((dwFlags == DIDFT_ALL) ||
	(dwFlags & DIDFT_BUTTON)) {
	ddoi.guidType = GUID_Button;
	
	/* Left button */
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_L_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON;
	strcpy(ddoi.tszName, "Left-Button");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
	
	/* Right button */
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_R_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON;
	strcpy(ddoi.tszName, "Right-Button");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
	
	/* Middle button */
	ddoi.dwOfs = This->offset_array[WINE_MOUSE_M_POSITION];
	ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON;
	strcpy(ddoi.tszName, "Middle-Button");
	_dump_OBJECTINSTANCEA(&ddoi);
	if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
    }
    
    return DI_OK;
}
Example #18
0
	dinput_kbd.c - DirectInput Keyboard DATAFORMAT

	Written by Filip Navara <*****@*****.**>

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

*/

#include "dinput_private.h"

static DIOBJECTDATAFORMAT ATTRIBUTE_TEXT_SECTION c_rgodfDIKeyboard[] =
{
	{&GUID_Key,0x0,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x0)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x1,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x1)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x2,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x2)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x3,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x3)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x4,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x4)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x5,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x5)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x6,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x6)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x7,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x7)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x8,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x8)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0x9,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0x9)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0xa,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0xa)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0xb,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0xb)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0xc,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0xc)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0xd,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0xd)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0xe,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0xe)|DIDFT_OPTIONAL,0x0},
	{&GUID_Key,0xf,DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0xf)|DIDFT_OPTIONAL,0x0},
Example #19
0
/* low-level mouse hook */
static int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
{
    MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
    SysMouseImpl* This = impl_from_IDirectInputDevice8A(iface);
    int wdata = 0, inst_id = -1, ret = 0;

    TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y);

    EnterCriticalSection(&This->base.crit);

    switch(wparam) {
        case WM_MOUSEMOVE:
        {
            POINT pt, pt1;

            GetCursorPos(&pt);
            This->m_state.lX += pt.x = hook->pt.x - pt.x;
            This->m_state.lY += pt.y = hook->pt.y - pt.y;

            if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
            {
                pt1.x = This->m_state.lX;
                pt1.y = This->m_state.lY;
            } else
                pt1 = pt;

            if (pt.x)
            {
                inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS;
                wdata = pt1.x;
            }
            if (pt.y)
            {
                /* Already have X, need to queue it */
                if (inst_id != -1)
                    queue_event(iface, inst_id,
                                wdata, GetCurrentTime(), This->base.dinput->evsequence);
                inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS;
                wdata = pt1.y;
            }

            if (pt.x || pt.y)
            {
                if ((This->warp_override == WARP_FORCE_ON) ||
                    (This->warp_override != WARP_DISABLE && (This->base.dwCoopLevel & DISCL_EXCLUSIVE)))
                    This->need_warp = TRUE;
            }
            break;
        }
        case WM_MOUSEWHEEL:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS;
            This->m_state.lZ += wdata = (short)HIWORD(hook->mouseData);
            /* FarCry crashes if it gets a mouse wheel message */
            /* FIXME: should probably filter out other messages too */
            ret = This->clipped;
            break;
        case WM_LBUTTONDOWN:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[0] = wdata = 0x80;
	    break;
	case WM_LBUTTONUP:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[0] = wdata = 0x00;
	    break;
	case WM_RBUTTONDOWN:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[1] = wdata = 0x80;
	    break;
	case WM_RBUTTONUP:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[1] = wdata = 0x00;
	    break;
	case WM_MBUTTONDOWN:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[2] = wdata = 0x80;
	    break;
	case WM_MBUTTONUP:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[2] = wdata = 0x00;
	    break;
        case WM_XBUTTONDOWN:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x80;
            break;
        case WM_XBUTTONUP:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x00;
            break;
    }


    if (inst_id != -1)
    {
        _dump_mouse_state(&This->m_state);
        queue_event(iface, inst_id,
                    wdata, GetCurrentTime(), This->base.dinput->evsequence++);
    }

    LeaveCriticalSection(&This->base.crit);
    return ret;
}
Example #20
0
DI_HID_DeviceBase::DI_HID_DeviceBase( ) {

	this->refCount = 0;
	this->diDevice = NULL;
	this->seqNumber = 0;
	this->exclusiveMode = false;
	this->foregroundMode = false;
	this->captureDisabled = true;
	this->isAcquired = false;
	this->absoluteAxis = false;
	memset( &this->windowRect, 0, sizeof( RECT ) );

	DI_HID_Object obj;

	obj.guidType = GUID_DI_XAxis;
	obj.dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE( 0 );
	obj.dwOfs = DIMOFS_X;
	strcpy( obj.tszName, "X-Axis" );
	obj.SetSize( 4 );
	obj.SetType( type_axis_x );
	objects.push_back( obj );

	obj.guidType = GUID_DI_YAxis;
	obj.dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE( 1 );
	obj.dwOfs = DIMOFS_Y;
	strcpy( obj.tszName, "Y-Axis" );
	obj.SetSize( 4 );
	obj.SetType( type_axis_y );
	objects.push_back( obj );

	obj.guidType = GUID_DI_ZAxis;
	obj.dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE( 2 );
	obj.dwOfs = DIMOFS_Z;
	strcpy( obj.tszName, "Z-Axis" );
	obj.SetSize( 4 );
	obj.SetType( type_axis_z );
	objects.push_back( obj );

	obj.guidType = GUID_DI_Button;
	obj.dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE( 0 );
	obj.dwOfs = DIMOFS_BUTTON0;
	strcpy( obj.tszName, "Left Button" );
	obj.SetSize( 1 );
	obj.SetType( type_button_1 );
	objects.push_back( obj );

	obj.guidType = GUID_DI_Button;
	obj.dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE( 1 );
	obj.dwOfs = DIMOFS_BUTTON1;
	strcpy( obj.tszName, "Right Button" );
	obj.SetSize( 1 );
	obj.SetType( type_button_2 );
	objects.push_back( obj );

	obj.guidType = GUID_DI_Button;
	obj.dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE( 2 );
	obj.dwOfs = DIMOFS_BUTTON2;
	strcpy( obj.tszName, "Middle Button" );
	obj.SetSize( 1 );
	obj.SetType( type_button_3 );
	objects.push_back( obj );

	obj.guidType = GUID_DI_Button;
	obj.dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE( 3 );
	obj.dwOfs = DIMOFS_BUTTON3;
	strcpy( obj.tszName, "Button 4" );
	obj.SetSize( 1 );
	obj.SetType( type_button_4 );
	objects.push_back( obj );

	obj.guidType = GUID_DI_Button;
	obj.dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE( 4 );
	obj.dwOfs = DIMOFS_BUTTON4;
	strcpy( obj.tszName, "Button 5" );
	obj.SetSize( 1 );
	obj.SetType( type_button_5 );
	objects.push_back( obj );

	obj.guidType = GUID_DI_Button;
	obj.dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE( 5 );
	obj.dwOfs = DIMOFS_BUTTON5;
	strcpy( obj.tszName, "Wheel Left" );
	obj.SetSize( 1 );
	obj.SetType( type_button_6 );
	objects.push_back( obj );

	obj.guidType = GUID_DI_Button;
	obj.dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE( 6 );
	obj.dwOfs = DIMOFS_BUTTON6;
	strcpy( obj.tszName, "Wheel Right" );
	obj.SetSize( 1 );
	obj.SetType( type_button_7 );
	objects.push_back( obj );

	initTime = GetTickCount( );
}
Example #21
0
static void acquire_tests(IDirectInputA *pDI, HWND hwnd)
{
    HRESULT hr;
    IDirectInputDeviceA *pKeyboard;
    BYTE kbd_state[256];
    LONG custom_state[6];
    int i;
    DIOBJECTDATAFORMAT dodf[] =
        {
            { &GUID_Key, sizeof(LONG) * 0, DIDFT_MAKEINSTANCE(DIK_Q)|DIDFT_BUTTON, 0 },
            { &GUID_Key, sizeof(LONG) * 1, DIDFT_MAKEINSTANCE(DIK_W)|DIDFT_BUTTON, 0 },
            { &GUID_Key, sizeof(LONG) * 2, DIDFT_MAKEINSTANCE(DIK_E)|DIDFT_BUTTON, 0 },
            { &GUID_Key, sizeof(LONG) * 4, DIDFT_MAKEINSTANCE(DIK_R)|DIDFT_BUTTON, 0 },
        };

    DIDATAFORMAT df;
    df.dwSize = sizeof( df );
    df.dwObjSize = sizeof( DIOBJECTDATAFORMAT );
    df.dwFlags = DIDF_RELAXIS;
    df.dwDataSize = sizeof( custom_state );
    df.dwNumObjs = sizeof( dodf )/sizeof( dodf[0] );
    df.rgodf = dodf;

    hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKeyboard, NULL);
    ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
    if (FAILED(hr)) return;

    hr = IDirectInputDevice_SetDataFormat(pKeyboard, &c_dfDIKeyboard);
    ok(SUCCEEDED(hr), "IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
    hr = IDirectInputDevice_SetCooperativeLevel(pKeyboard, NULL, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
    ok(SUCCEEDED(hr), "IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
    hr = IDirectInputDevice_GetDeviceState(pKeyboard, 10, kbd_state);
    ok(hr == DIERR_NOTACQUIRED, "IDirectInputDevice_GetDeviceState(10,) should have failed: %08x\n", hr);
    hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(kbd_state), kbd_state);
    ok(hr == DIERR_NOTACQUIRED, "IDirectInputDevice_GetDeviceState() should have failed: %08x\n", hr);
    hr = IDirectInputDevice_Unacquire(pKeyboard);
    ok(hr == S_FALSE, "IDirectInputDevice_Unacquire() should have failed: %08x\n", hr);
    hr = IDirectInputDevice_Acquire(pKeyboard);
    ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
    hr = IDirectInputDevice_Acquire(pKeyboard);
    ok(hr == S_FALSE, "IDirectInputDevice_Acquire() should have failed: %08x\n", hr);
    hr = IDirectInputDevice_GetDeviceState(pKeyboard, 10, kbd_state);
    ok(hr == DIERR_INVALIDPARAM, "IDirectInputDevice_GetDeviceState(10,) should have failed: %08x\n", hr);
    hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(kbd_state), kbd_state);
    ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
    hr = IDirectInputDevice_Unacquire(pKeyboard);
    ok(SUCCEEDED(hr), "IDirectInputDevice_Uncquire() failed: %08x\n", hr);
    hr = IDirectInputDevice_SetDataFormat( pKeyboard , &df );
    ok(SUCCEEDED(hr), "IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
    hr = IDirectInputDevice_Acquire(pKeyboard);
    ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
    hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
    ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState(4,) failed: %08x\n", hr);
    hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(kbd_state), kbd_state);
    ok(hr == DIERR_INVALIDPARAM, "IDirectInputDevice_GetDeviceState(256,) should have failed: %08x\n", hr);

    memset(custom_state, 0x56, sizeof(custom_state));
    IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
    for (i = 0; i < sizeof(custom_state) / sizeof(custom_state[0]); i++)
        ok(custom_state[i] == 0, "Should be zeroed, got 0x%08x\n", custom_state[i]);

    /* simulate some keyboard input */
    SetFocus(hwnd);
    keybd_event('Q', 0, 0, 0);
    hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
    ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
    if (!custom_state[0])
        win_skip("Keyboard event not processed, skipping test\n");
    else
    {
        /* unacquiring should reset the device state */
        hr = IDirectInputDevice_Unacquire(pKeyboard);
        ok(SUCCEEDED(hr), "IDirectInputDevice_Unacquire() failed: %08x\n", hr);
        hr = IDirectInputDevice_Acquire(pKeyboard);
        ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
        hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
        ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState failed: %08x\n", hr);
        for (i = 0; i < sizeof(custom_state) / sizeof(custom_state[0]); i++)
            ok(custom_state[i] == 0, "Should be zeroed, got 0x%08x\n", custom_state[i]);
    }
    keybd_event('Q', 0, KEYEVENTF_KEYUP, 0);

    if (pKeyboard) IUnknown_Release(pKeyboard);
}
Example #22
0
/* low-level mouse hook */
static void dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
{
    MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
    SysMouseImpl* This = (SysMouseImpl*) iface;
    DWORD dwCoop;
    int wdata = 0, inst_id = -1;

    TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y);

    EnterCriticalSection(&This->base.crit);
    dwCoop = This->base.dwCoopLevel;

    switch(wparam) {
        case WM_MOUSEMOVE:
        {
            POINT pt, pt1;

            GetCursorPos(&pt);
            This->m_state.lX += pt.x = hook->pt.x - pt.x;
            This->m_state.lY += pt.y = hook->pt.y - pt.y;

            if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
            {
                pt1.x = This->m_state.lX;
                pt1.y = This->m_state.lY;
            } else
                pt1 = pt;

            if (pt.x)
            {
                inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS;
                wdata = pt1.x;
            }
            if (pt.y)
            {
                /* Already have X, need to queue it */
                if (inst_id != -1)
                    queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id),
                                wdata, GetCurrentTime(), This->base.dinput->evsequence);
                inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS;
                wdata = pt1.y;
            }

            This->need_warp = (pt.x || pt.y) && dwCoop & DISCL_EXCLUSIVE;
            break;
        }
        case WM_MOUSEWHEEL:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS;
            This->m_state.lZ += wdata = (short)HIWORD(hook->mouseData);
            break;
        case WM_LBUTTONDOWN:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[0] = wdata = 0x80;
	    break;
	case WM_LBUTTONUP:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[0] = wdata = 0x00;
	    break;
	case WM_RBUTTONDOWN:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[1] = wdata = 0x80;
	    break;
	case WM_RBUTTONUP:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[1] = wdata = 0x00;
	    break;
	case WM_MBUTTONDOWN:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[2] = wdata = 0x80;
	    break;
	case WM_MBUTTONUP:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[2] = wdata = 0x00;
	    break;
        case WM_XBUTTONDOWN:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x80;
            break;
        case WM_XBUTTONUP:
            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
            This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x00;
            break;
    }


    if (inst_id != -1)
    {
        _dump_mouse_state(&This->m_state);
        queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id),
                    wdata, GetCurrentTime(), This->base.dinput->evsequence++);
    }

    LeaveCriticalSection(&This->base.crit);
}
Example #23
0
File: mouse.c Project: Jactry/wine
static void test_acquire(IDirectInputA *pDI, HWND hwnd)
{
    HRESULT hr;
    IDirectInputDeviceA *pMouse = NULL;
    DIMOUSESTATE m_state;
    HWND hwnd2;
    DIPROPDWORD di_op;
    DIDEVICEOBJECTDATA mouse_state;
    DWORD cnt;
    int i;

    if (! SetForegroundWindow(hwnd))
    {
        skip("Not running as foreground app, skipping acquire tests\n");
        return;
    }

    hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, &pMouse, NULL);
    ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
    if (FAILED(hr)) return;

    hr = IDirectInputDevice_SetCooperativeLevel(pMouse, hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
    ok(hr == S_OK, "SetCooperativeLevel: %08x\n", hr);

    memset(&di_op, 0, sizeof(di_op));
    di_op.dwData = 5;
    di_op.diph.dwHow = DIPH_DEVICE;
    di_op.diph.dwSize = sizeof(DIPROPDWORD);
    di_op.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    hr = IDirectInputDevice_SetProperty(pMouse, DIPROP_BUFFERSIZE, (LPCDIPROPHEADER)&di_op);
    ok(hr == S_OK, "SetProperty() failed: %08x\n", hr);

    hr = IDirectInputDevice_SetDataFormat(pMouse, &c_dfDIMouse);
    ok(SUCCEEDED(hr), "IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
    hr = IDirectInputDevice_Unacquire(pMouse);
    ok(hr == S_FALSE, "IDirectInputDevice_Unacquire() should have failed: %08x\n", hr);
    hr = IDirectInputDevice_Acquire(pMouse);
    ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
    hr = IDirectInputDevice_Acquire(pMouse);
    ok(hr == S_FALSE, "IDirectInputDevice_Acquire() should have failed: %08x\n", hr);

    /* Foreground coop level requires window to have focus */
    /* Create a temporary window, this should make dinput
     * lose mouse input */
    hwnd2 = CreateWindowA("static", "Temporary", WS_VISIBLE, 10, 210, 200, 200, NULL, NULL, NULL,
                          NULL);
    ok(hwnd2 != NULL, "CreateWindowA failed with %u\n", GetLastError());

    hr = IDirectInputDevice_GetDeviceState(pMouse, sizeof(m_state), &m_state);
    ok(hr == DIERR_NOTACQUIRED, "GetDeviceState() should have failed: %08x\n", hr);

    hr = IDirectInputDevice_Acquire(pMouse);
    ok(hr == DIERR_OTHERAPPHASPRIO, "Acquire() should have failed: %08x\n", hr);

    SetActiveWindow( hwnd );
    hr = IDirectInputDevice_Acquire(pMouse);
    ok(hr == S_OK, "Acquire() failed: %08x\n", hr);

    mouse_event(MOUSEEVENTF_MOVE, 10, 10, 0, 0);
    cnt = 1;
    hr = IDirectInputDevice_GetDeviceData(pMouse, sizeof(mouse_state), &mouse_state, &cnt, 0);
    ok(hr == S_OK && cnt > 0, "GetDeviceData() failed: %08x cnt:%d\n", hr, cnt);

    mouse_event(MOUSEEVENTF_MOVE, 10, 10, 0, 0);
    IDirectInputDevice_Unacquire(pMouse);
    cnt = 1;
    hr = IDirectInputDevice_GetDeviceData(pMouse, sizeof(mouse_state), &mouse_state, &cnt, 0);
    ok(hr == S_OK && cnt > 0, "GetDeviceData() failed: %08x cnt:%d\n", hr, cnt);

    IDirectInputDevice_Acquire(pMouse);
    mouse_event(MOUSEEVENTF_MOVE, 10, 10, 0, 0);
    IDirectInputDevice_Unacquire(pMouse);
    IDirectInputDevice_Acquire(pMouse);
    cnt = 1;
    hr = IDirectInputDevice_GetDeviceData(pMouse, sizeof(mouse_state), &mouse_state, &cnt, 0);
    ok(hr == S_OK && cnt > 0, "GetDeviceData() failed: %08x cnt:%d\n", hr, cnt);

    /* Check for buffer overflow */
    for (i = 0; i < 6; i++)
        mouse_event(MOUSEEVENTF_MOVE, 10 + i, 10 + i, 0, 0);

    cnt = 1;
    hr = IDirectInputDevice_GetDeviceData(pMouse, sizeof(mouse_state), &mouse_state, &cnt, 0);
    ok(hr == DI_OK, "GetDeviceData() failed: %08x cnt:%d\n", hr, cnt);
    cnt = 1;
    hr = IDirectInputDevice_GetDeviceData(pMouse, sizeof(mouse_state), &mouse_state, &cnt, 0);
    ok(hr == DI_OK && cnt == 1, "GetDeviceData() failed: %08x cnt:%d\n", hr, cnt);

    /* Check for granularity property using BYOFFSET */
    memset(&di_op, 0, sizeof(di_op));
    di_op.diph.dwHow = DIPH_BYOFFSET;
    di_op.diph.dwObj = DIMOFS_Y;
    di_op.diph.dwSize = sizeof(DIPROPDWORD);
    di_op.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    hr = IDirectInputDevice_GetProperty(pMouse, DIPROP_GRANULARITY, &di_op.diph);
    /* Granularity of Y axis should be 1! */
    ok(hr == S_OK && di_op.dwData == 1, "GetProperty(): %08x, dwData: %i but should be 1.\n", hr, di_op.dwData);

    /* Check for granularity property using BYID */
    memset(&di_op, 0, sizeof(di_op));
    di_op.diph.dwHow = DIPH_BYID;
    /* WINE_MOUSE_Y_AXIS_INSTANCE := 1 */
    di_op.diph.dwObj = (DIDFT_MAKEINSTANCE(1) | DIDFT_RELAXIS);
    di_op.diph.dwSize = sizeof(DIPROPDWORD);
    di_op.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    hr = IDirectInputDevice_GetProperty(pMouse, DIPROP_GRANULARITY, &di_op.diph);
    /* Granularity of Y axis should be 1! */
    ok(hr == S_OK && di_op.dwData == 1, "GetProperty(): %08x, dwData: %i but should be 1.\n", hr, di_op.dwData);

    if (pMouse) IUnknown_Release(pMouse);

    DestroyWindow( hwnd2 );
}
Example #24
0
  { &GUID_Button, DIMOFS_BUTTON5, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
  { &GUID_Button, DIMOFS_BUTTON6, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
  { &GUID_Button, DIMOFS_BUTTON7, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 }
};

const DIDATAFORMAT c_dfDIMouse2 = {
    sizeof(DIDATAFORMAT),
    sizeof(DIOBJECTDATAFORMAT),
    DIDF_RELAXIS,
    sizeof(DIMOUSESTATE2),
    numObjects(dfDIMouse2),
    (LPDIOBJECTDATAFORMAT)dfDIMouse2
};

static const DIOBJECTDATAFORMAT dfDIKeyboard[] = {
  { &GUID_Key,0,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(0),0},
  { &GUID_Key,1,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(1),0},
  { &GUID_Key,2,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(2),0},
  { &GUID_Key,3,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(3),0},
  { &GUID_Key,4,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(4),0},
  { &GUID_Key,5,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(5),0},
  { &GUID_Key,6,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(6),0},
  { &GUID_Key,7,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(7),0},
  { &GUID_Key,8,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(8),0},
  { &GUID_Key,9,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(9),0},
  { &GUID_Key,10,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(10),0},
  { &GUID_Key,11,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(11),0},
  { &GUID_Key,12,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(12),0},
  { &GUID_Key,13,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(13),0},
  { &GUID_Key,14,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(14),0},
  { &GUID_Key,15,DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(15),0},
Example #25
0
static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput,
    LPDIRECTINPUTDEVICEA* pdev, unsigned short index)
{
    DWORD i;
    JoystickImpl* newDevice;
    char name[MAX_PATH];
    HRESULT hr;
    LPDIDATAFORMAT df = NULL;
    int idx = 0;
    int axis_map[8]; /* max axes */
    int slider_count = 0;

    TRACE("%s %p %p %p %hu\n", debugstr_guid(rguid), jvt, dinput, pdev, index);

    newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
    if (newDevice == 0) {
        WARN("out of memory\n");
        *pdev = 0;
        return DIERR_OUTOFMEMORY;
    }

    newDevice->id = index;

    newDevice->generic.guidInstance = DInput_Wine_OsX_Joystick_GUID;
    newDevice->generic.guidInstance.Data3 = index;
    newDevice->generic.guidProduct = DInput_Wine_OsX_Joystick_GUID;
    newDevice->generic.joy_polldev = poll_osx_device_state;

    /* get the device name */
    get_osx_device_name(index, name, MAX_PATH);
    TRACE("Name %s\n",name);

    /* copy the device name */
    newDevice->generic.name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1);
    strcpy(newDevice->generic.name, name);

    memset(axis_map, 0, sizeof(axis_map));
    get_osx_device_elements(newDevice, axis_map);

    TRACE("%i axes %i buttons %i povs\n",newDevice->generic.devcaps.dwAxes,newDevice->generic.devcaps.dwButtons,newDevice->generic.devcaps.dwPOVs);

    if (newDevice->generic.devcaps.dwButtons > 128)
    {
        WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons);
        newDevice->generic.devcaps.dwButtons = 128;
    }

    newDevice->generic.base.lpVtbl = jvt;
    newDevice->generic.base.ref = 1;
    newDevice->generic.base.dinput = dinput;
    newDevice->generic.base.guid = *rguid;
    InitializeCriticalSection(&newDevice->generic.base.crit);
    newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");

    /* Create copy of default data format */
    if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);

    df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons;
    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;

    for (i = 0; i < newDevice->generic.devcaps.dwAxes; i++)
    {
        int wine_obj = -1;
        switch (axis_map[i])
        {
            case kHIDUsage_GD_X: wine_obj = 0; break;
            case kHIDUsage_GD_Y: wine_obj = 1; break;
            case kHIDUsage_GD_Z: wine_obj = 2; break;
            case kHIDUsage_GD_Rx: wine_obj = 3; break;
            case kHIDUsage_GD_Ry: wine_obj = 4; break;
            case kHIDUsage_GD_Rz: wine_obj = 5; break;
            case kHIDUsage_GD_Slider:
                wine_obj = 6 + slider_count;
                slider_count++;
                break;
        }
        if (wine_obj < 0 ) continue;

        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
    }

    for (i = 0; i < newDevice->generic.devcaps.dwPOVs; i++)
    {
        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 8], df->dwObjSize);
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_POV;
    }

    for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++)
    {
        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
        df->rgodf[idx  ].pguid = &GUID_Button;
        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
    }
    newDevice->generic.base.data_format.wine_df = df;

    /* initialize default properties */
    get_osx_device_elements_props(newDevice);

    IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->generic.base.dinput);

    newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
    newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
    if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
        newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
    else
        newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
    newDevice->generic.devcaps.dwFFSamplePeriod = 0;
    newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
    newDevice->generic.devcaps.dwFirmwareRevision = 0;
    newDevice->generic.devcaps.dwHardwareRevision = 0;
    newDevice->generic.devcaps.dwFFDriverVersion = 0;

    if (TRACE_ON(dinput)) {
        _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df);
        _dump_DIDEVCAPS(&newDevice->generic.devcaps);
    }

    *pdev = (LPDIRECTINPUTDEVICEA)newDevice;

    return DI_OK;

FAILED:
    hr = DIERR_OUTOFMEMORY;
    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
    HeapFree(GetProcessHeap(), 0, df);
    release_DataFormat(&newDevice->generic.base.data_format);
    HeapFree(GetProcessHeap(),0,newDevice->generic.name);
    HeapFree(GetProcessHeap(),0,newDevice);
    *pdev = 0;

    return hr;
}
Example #26
0
static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
{
    struct pollfd plfd;
    struct js_event jse;
    JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);

    TRACE("(%p)\n", This);

    if (This->joyfd==-1) {
        WARN("no device\n");
        return;
    }
    while (1)
    {
        LONG value;
        int inst_id = -1;

	plfd.fd = This->joyfd;
	plfd.events = POLLIN;
	if (poll(&plfd,1,0) != 1)
	    return;
	/* we have one event, so we can read */
	if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
	    return;
	}
        TRACE("js_event: type 0x%x, number %d, value %d\n",
              jse.type,jse.number,jse.value);
        if (jse.type & JS_EVENT_BUTTON)
        {
            if (jse.number >= This->generic.devcaps.dwButtons) return;

            inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON;
            This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00;
        }
        else if (jse.type & JS_EVENT_AXIS)
        {
            int number = This->generic.axis_map[jse.number];	/* wine format object index */

            if (number < 0) return;
            inst_id = number < 8 ?  DIDFT_MAKEINSTANCE(number) | DIDFT_ABSAXIS :
                                    DIDFT_MAKEINSTANCE(number - 8) | DIDFT_POV;
            value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], jse.value);

            TRACE("changing axis %d => %d\n", jse.number, number);
            switch (number)
            {
                case 0: This->generic.js.lX  = value; break;
                case 1: This->generic.js.lY  = value; break;
                case 2: This->generic.js.lZ  = value; break;
                case 3: This->generic.js.lRx = value; break;
                case 4: This->generic.js.lRy = value; break;
                case 5: This->generic.js.lRz = value; break;
                case 6: This->generic.js.rglSlider[0] = value; break;
                case 7: This->generic.js.rglSlider[1] = value; break;
                case 8: case 9: case 10: case 11:
                {
                    int idx = number - 8;

                    if (jse.number % 2)
                        This->povs[idx].y = jse.value;
                    else
                        This->povs[idx].x = jse.value;

                    This->generic.js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]);
                    break;
                }
                default:
                    WARN("axis %d not supported\n", number);
            }
        }
        if (inst_id >= 0)
            queue_event(iface, inst_id,
                        value, jse.time, This->generic.base.dinput->evsequence++);
    }
}
Example #27
0
static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface)
{
    JoystickImpl *device = impl_from_IDirectInputDevice8A(iface);
    IOHIDElementRef tIOHIDTopElementRef;
    IOHIDDeviceRef tIOHIDDeviceRef;
    CFArrayRef gElementCFArrayRef = device->elementCFArrayRef;

    TRACE("polling device %i\n",device->id);

    if (!gCollections)
        return;

    tIOHIDTopElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(gCollections, device->id);
    tIOHIDDeviceRef = IOHIDElementGetDevice(tIOHIDTopElementRef);

    if (!tIOHIDDeviceRef)
        return;

    if (gElementCFArrayRef)
    {
        int button_idx = 0;
        int pov_idx = 0;
        int slider_idx = 0;
        int inst_id;
        CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef );

        for ( idx = 0; idx < cnt; idx++ )
        {
            IOHIDValueRef valueRef;
            int val, oldVal, newVal;
            IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx );
            int eleType = IOHIDElementGetType( tIOHIDElementRef );

            switch(eleType)
            {
            case kIOHIDElementTypeInput_Button:
                if(button_idx < 128)
                {
                    IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef);
                    val = IOHIDValueGetIntegerValue(valueRef);
                    newVal = val ? 0x80 : 0x0;
                    oldVal = device->generic.js.rgbButtons[button_idx];
                    device->generic.js.rgbButtons[button_idx] = newVal;
                    if (oldVal != newVal)
                    {
                        inst_id = DIDFT_MAKEINSTANCE(button_idx) | DIDFT_PSHBUTTON;
                        queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++);
                    }
                    button_idx ++;
                }
                break;
            case kIOHIDElementTypeInput_Misc:
            {
                uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef );
                switch(usage)
                {
                case kHIDUsage_GD_Hatswitch:
                {
                    IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef);
                    val = IOHIDValueGetIntegerValue(valueRef);
                    oldVal = device->generic.js.rgdwPOV[pov_idx];
                    if (val >= 8)
                        newVal = -1;
                    else
                        newVal = val * 4500;
                    device->generic.js.rgdwPOV[pov_idx] = newVal;
                    if (oldVal != newVal)
                    {
                        inst_id = DIDFT_MAKEINSTANCE(pov_idx) | DIDFT_POV;
                        queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++);
                    }
                    pov_idx ++;
                    break;
                }
                case kHIDUsage_GD_X:
                case kHIDUsage_GD_Y:
                case kHIDUsage_GD_Z:
                case kHIDUsage_GD_Rx:
                case kHIDUsage_GD_Ry:
                case kHIDUsage_GD_Rz:
                case kHIDUsage_GD_Slider:
                {
                    int wine_obj = -1;

                    IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef);
                    val = IOHIDValueGetIntegerValue(valueRef);
                    newVal = joystick_map_axis(&device->generic.props[idx], val);
                    switch (usage)
                    {
                    case kHIDUsage_GD_X:
                        wine_obj = 0;
                        oldVal = device->generic.js.lX;
                        device->generic.js.lX = newVal;
                        break;
                    case kHIDUsage_GD_Y:
                        wine_obj = 1;
                        oldVal = device->generic.js.lY;
                        device->generic.js.lY = newVal;
                        break;
                    case kHIDUsage_GD_Z:
                        wine_obj = 2;
                        oldVal = device->generic.js.lZ;
                        device->generic.js.lZ = newVal;
                        break;
                    case kHIDUsage_GD_Rx:
                        wine_obj = 3;
                        oldVal = device->generic.js.lRx;
                        device->generic.js.lRx = newVal;
                        break;
                    case kHIDUsage_GD_Ry:
                        wine_obj = 4;
                        oldVal = device->generic.js.lRy;
                        device->generic.js.lRy = newVal;
                        break;
                    case kHIDUsage_GD_Rz:
                        wine_obj = 5;
                        oldVal = device->generic.js.lRz;
                        device->generic.js.lRz = newVal;
                        break;
                    case kHIDUsage_GD_Slider:
                        wine_obj = 6 + slider_idx;
                        oldVal = device->generic.js.rglSlider[slider_idx];
                        device->generic.js.rglSlider[slider_idx] = newVal;
                        slider_idx ++;
                        break;
                    }
                    if ((wine_obj != -1) &&
                            (oldVal != newVal))
                    {
                        inst_id = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
                        queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++);
                    }

                    break;
                }
                default:
                    FIXME("unhandled usage %i\n",usage);
                }
                break;
            }
            default:
                FIXME("Unhandled type %i\n",eleType);
            }
        }
    }
}