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; }
/****************************************************************************** * 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; }
/****************************************************************************** * 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; }
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; }
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; }
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; }
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++); } }
* 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},
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"); }
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; }
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; }
#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 */
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; }
/****************************************************************************** * 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; }
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},
/* 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; }
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( ); }
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); }
/* 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); }
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 ); }
{ &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},
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; }
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++); } }
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); } } } }