static void UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick) { int i; HRESULT result; DWORD numevents; DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE]; numevents = INPUT_QSIZE; result = IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA), evtbuf, &numevents, 0); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); result = IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA), evtbuf, &numevents, 0); } /* Handle the events or punt */ if (FAILED(result)) { joystick->hwdata->send_remove_event = SDL_TRUE; joystick->hwdata->removed = SDL_TRUE; return; } for (i = 0; i < (int)numevents; ++i) { int j; for (j = 0; j < joystick->hwdata->NumInputs; ++j) { const input_t *in = &joystick->hwdata->Inputs[j]; if (evtbuf[i].dwOfs != in->ofs) continue; switch (in->type) { case AXIS: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData); break; case BUTTON: SDL_PrivateJoystickButton(joystick, in->num, (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED)); break; case HAT: { Uint8 pos = TranslatePOV(evtbuf[i].dwData); SDL_PrivateJoystickHat(joystick, in->num, pos); } break; } } } }
static void test_device_input(IDirectInputDevice8A *lpdid, DWORD event_type, DWORD event, DWORD expected) { HRESULT hr; DIDEVICEOBJECTDATA obj_data; DWORD data_size = 1; int i; hr = IDirectInputDevice8_Acquire(lpdid); ok (SUCCEEDED(hr), "Failed to acquire device hr=%08x\n", hr); if (event_type == INPUT_KEYBOARD) keybd_event( event, DIK_SPACE, 0, 0); if (event_type == INPUT_MOUSE) mouse_event( event, 0, 0, 0, 0); flush_events(); IDirectInputDevice8_Poll(lpdid); hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0); if (data_size != 1) { win_skip("We're not able to inject input into Windows dinput8 with events\n"); IDirectInputDevice_Unacquire(lpdid); return; } ok (obj_data.uAppData == expected, "Retrieval of action failed uAppData=%lu expected=%d\n", obj_data.uAppData, expected); /* Check for buffer owerflow */ for (i = 0; i < 17; i++) if (event_type == INPUT_KEYBOARD) { keybd_event( VK_SPACE, DIK_SPACE, 0, 0); keybd_event( VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0); } else if (event_type == INPUT_MOUSE) { mouse_event(MOUSEEVENTF_LEFTDOWN, 1, 1, 0, 0); mouse_event(MOUSEEVENTF_LEFTUP, 1, 1, 0, 0); } flush_events(); IDirectInputDevice8_Poll(lpdid); data_size = 1; hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0); ok(hr == DI_BUFFEROVERFLOW, "GetDeviceData() failed: %08x\n", hr); data_size = 1; hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0); ok(hr == DI_OK && data_size == 1, "GetDeviceData() failed: %08x cnt:%d\n", hr, data_size); IDirectInputDevice_Unacquire(lpdid); }
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetDeviceData(JNIEnv *env, jclass unused, jlong address, jint flags, jobject queue, jobject queue_array, jint position, jint remaining) { LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; DWORD num_events = remaining; DIDEVICEOBJECTDATA *data; DIDEVICEOBJECTDATA *data_element; jmethodID set_method; HRESULT res; int i; jclass data_class; jclass queue_class; jmethodID position_method; data_class = (*env)->FindClass(env, "net/java/games/input/DIDeviceObjectData"); if (data_class == NULL) return -1; set_method = (*env)->GetMethodID(env, data_class, "set", "(IIII)V"); if (set_method == NULL) return -1; queue_class = (*env)->GetObjectClass(env, queue); if (queue_class == NULL) return -1; position_method = (*env)->GetMethodID(env, queue_class, "position", "(I)V"); if (position_method == NULL) return -1; data = (DIDEVICEOBJECTDATA *)malloc(num_events*sizeof(DIDEVICEOBJECTDATA)); if (data == NULL) return -1; res = IDirectInputDevice8_GetDeviceData(lpDevice, sizeof(DIDEVICEOBJECTDATA), data, &num_events, flags); if (res == DI_OK || res == DI_BUFFEROVERFLOW) { for (i = 0; i < num_events; i++) { jobject queue_element = (*env)->GetObjectArrayElement(env, queue_array, position + i); if (queue_element == NULL) { free(data); return -1; } data_element = data + i; (*env)->CallVoidMethod(env, queue_element, set_method, (jint)data_element->dwOfs, (jint)data_element->dwData, (jint)data_element->dwTimeStamp, (jint)data_element->dwSequence); if ((*env)->ExceptionOccurred(env)) { free(data); return -1; } } (*env)->CallVoidMethod(env, queue, position_method, position + num_events); } free(data); return res; }
/* update_joystick: [joystick thread] * Reads in data for a single DirectInput joystick device, updates * the internal ALLEGRO_JOYSTICK_STATE structure, and generates any Allegro * events required. */ static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy) { DIDEVICEOBJECTDATA buffer[DEVICE_BUFFER_SIZE]; DWORD num_items = DEVICE_BUFFER_SIZE; HRESULT hr; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); /* some devices require polling */ IDirectInputDevice8_Poll(joy->device); /* get device data into buffer */ hr = IDirectInputDevice8_GetDeviceData(joy->device, sizeof(DIDEVICEOBJECTDATA), buffer, &num_items, 0); if (hr != DI_OK && hr != DI_BUFFEROVERFLOW) { if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) { ALLEGRO_WARN("joystick device not acquired or lost\n"); } else { ALLEGRO_ERROR("unexpected error while polling the joystick\n"); } return; } /* don't bother locking the event source if there's no work to do */ /* this happens a lot for polled devices */ if (num_items == 0) return; _al_event_source_lock(es); { unsigned int i; for (i = 0; i < num_items; i++) { const DIDEVICEOBJECTDATA *item = &buffer[i]; const int dwOfs = item->dwOfs; const DWORD dwData = item->dwData; switch (dwOfs) { case DIJOFS_X: handle_axis_event(joy, &joy->x_mapping, dwData); break; case DIJOFS_Y: handle_axis_event(joy, &joy->y_mapping, dwData); break; case DIJOFS_Z: handle_axis_event(joy, &joy->z_mapping, dwData); break; case DIJOFS_RX: handle_axis_event(joy, &joy->rx_mapping, dwData); break; case DIJOFS_RY: handle_axis_event(joy, &joy->ry_mapping, dwData); break; case DIJOFS_RZ: handle_axis_event(joy, &joy->rz_mapping, dwData); break; case DIJOFS_SLIDER(0): handle_axis_event(joy, &joy->slider_mapping[0], dwData); break; case DIJOFS_SLIDER(1): handle_axis_event(joy, &joy->slider_mapping[1], dwData); break; case DIJOFS_POV(0): handle_pov_event(joy, joy->pov_mapping_stick[0], dwData); break; case DIJOFS_POV(1): handle_pov_event(joy, joy->pov_mapping_stick[1], dwData); break; case DIJOFS_POV(2): handle_pov_event(joy, joy->pov_mapping_stick[2], dwData); break; case DIJOFS_POV(3): handle_pov_event(joy, joy->pov_mapping_stick[3], dwData); break; default: /* buttons */ if ((dwOfs >= DIJOFS_BUTTON0) && (dwOfs < DIJOFS_BUTTON(joy->parent.info.num_buttons))) { int num = (dwOfs - DIJOFS_BUTTON0) / (DIJOFS_BUTTON1 - DIJOFS_BUTTON0); handle_button_event(joy, num, (dwData & 0x80)); } break; } } } _al_event_source_unlock(es); }
void PollKeys(void) { u32 i; DWORD i2; DWORD size=8; DIDEVICEOBJECTDATA didod[8]; HRESULT hr; for (i = 0; i < numpads; i++) { if (paddevice[i].lpDIDevice == NULL) continue; hr = IDirectInputDevice8_Poll(paddevice[i].lpDIDevice); if (FAILED(hr)) { if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { // Make sure device is acquired while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {} continue; } } size = 8; // Poll events if (FAILED(IDirectInputDevice8_GetDeviceData(paddevice[i].lpDIDevice, sizeof(DIDEVICEOBJECTDATA), didod, &size, 0))) { if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { // Make sure device is acquired while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {} continue; } } if (size == 0) continue; switch (paddevice[i].type) { case TYPE_KEYBOARD: // This probably could be optimized for (i2 = 0; i2 < size; i2++) { if (didod[i2].dwData & 0x80) PerKeyDown(didod[i2].dwOfs); else PerKeyUp(didod[i2].dwOfs); } break; case TYPE_JOYSTICK: { // This probably could be optimized for (i2 = 0; i2 < size; i2++) { // X Axis if (didod[i2].dwOfs == DIJOFS_X) { if (didod[i2].dwData < 0x3FFF) { PerKeyDown(PAD_DIR_AXISLEFT); PerKeyUp(PAD_DIR_AXISRIGHT); } else if (didod[i2].dwData > 0xBFFF) { PerKeyDown(PAD_DIR_AXISRIGHT); PerKeyUp(PAD_DIR_AXISLEFT); } else { PerKeyUp(PAD_DIR_AXISLEFT); PerKeyUp(PAD_DIR_AXISRIGHT); } } // Y Axis else if (didod[i2].dwOfs == DIJOFS_Y) { if (didod[i2].dwData < 0x3FFF) { PerKeyDown(PAD_DIR_AXISUP); PerKeyUp(PAD_DIR_AXISDOWN); } else if (didod[i2].dwData > 0xBFFF) { PerKeyDown(PAD_DIR_AXISDOWN); PerKeyUp(PAD_DIR_AXISUP); } else { PerKeyUp(PAD_DIR_AXISUP); PerKeyUp(PAD_DIR_AXISDOWN); } } else if (didod[i2].dwOfs == DIJOFS_POV(0)) { // POV Center if (LOWORD(didod[i2].dwData) == 0xFFFF) { PerKeyUp(PAD_DIR_POVUP); PerKeyUp(PAD_DIR_POVRIGHT); PerKeyUp(PAD_DIR_POVDOWN); PerKeyUp(PAD_DIR_POVLEFT); } // POV Up else if (didod[i2].dwData < 4500) { PerKeyDown(PAD_DIR_POVUP); PerKeyUp(PAD_DIR_POVRIGHT); PerKeyUp(PAD_DIR_POVLEFT); } // POV Up-right else if (didod[i2].dwData < 9000) { PerKeyDown(PAD_DIR_POVUP); PerKeyDown(PAD_DIR_POVRIGHT); } // POV Right else if (didod[i2].dwData < 13500) { PerKeyDown(PAD_DIR_POVRIGHT); PerKeyUp(PAD_DIR_POVDOWN); PerKeyUp(PAD_DIR_POVUP); } // POV Right-down else if (didod[i2].dwData < 18000) { PerKeyDown(PAD_DIR_POVRIGHT); PerKeyDown(PAD_DIR_POVDOWN); } // POV Down else if (didod[i2].dwData < 22500) { PerKeyDown(PAD_DIR_POVDOWN); PerKeyUp(PAD_DIR_POVLEFT); PerKeyUp(PAD_DIR_POVRIGHT); } // POV Down-left else if (didod[i2].dwData < 27000) { PerKeyDown(PAD_DIR_POVDOWN); PerKeyDown(PAD_DIR_POVLEFT); } // POV Left else if (didod[i2].dwData < 31500) { PerKeyDown(PAD_DIR_POVLEFT); PerKeyUp(PAD_DIR_POVUP); PerKeyUp(PAD_DIR_POVDOWN); } // POV Left-up else if (didod[i2].dwData < 36000) { PerKeyDown(PAD_DIR_POVLEFT); PerKeyDown(PAD_DIR_POVUP); } } else if (didod[i2].dwOfs >= DIJOFS_BUTTON(0) && didod[i2].dwOfs <= DIJOFS_BUTTON(127)) { if (didod[i2].dwData & 0x80) PerKeyDown(didod[i2].dwOfs); else PerKeyUp(didod[i2].dwOfs); } } break; } case TYPE_MOUSE: for (i2 = 0; i2 < size; i2++) { if (didod[i2].dwOfs == DIMOFS_X) // X Axis PerMouseMove((PerMouse_struct *)pad[i], (s32)didod[i2].dwData, 0); else if (didod[i2].dwOfs == DIMOFS_Y) // Y Axis PerMouseMove((PerMouse_struct *)pad[i], 0, 0-(s32)didod[i2].dwData); else if (didod[i2].dwOfs >= DIMOFS_BUTTON0 && didod[i2].dwOfs <= DIMOFS_BUTTON7) { // Mouse Buttons if (didod[i2].dwData & 0x80) PerKeyDown(didod[i2].dwOfs-DIMOFS_BUTTON0); else PerKeyUp(didod[i2].dwOfs-DIMOFS_BUTTON0); } } break; default: break; } } }
LRESULT CALLBACK ButtonConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static LPDIRECTINPUTDEVICE8 lpDIDevicetemp; DIPROPDWORD dipdw; HRESULT hr; DWORD size; DIDEVICEOBJECTDATA didod[8]; DWORD i; DIDEVCAPS didc; switch (uMsg) { case WM_INITDIALOG: { lpDIDevicetemp = (LPDIRECTINPUTDEVICE8)lParam; if (FAILED(IDirectInputDevice8_SetCooperativeLevel(lpDIDevicetemp, hDlg, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY))) return FALSE; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = 8; // should be enough // Setup Buffered input if (FAILED((hr = IDirectInputDevice8_SetProperty(lpDIDevicetemp, DIPROP_BUFFERSIZE, &dipdw.diph)))) return FALSE; if (!SetTimer(hDlg, 1, 100, NULL)) return FALSE; PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, IDC_WAITINPUT), TRUE); hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHook, GetModuleHandle(NULL), GetCurrentThreadId()); return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_CUSTOMCANCEL: { EndDialog(hDlg, FALSE); return TRUE; } default: break; } break; } case WM_TIMER: { size = 8; if (wParam == 1) { memset(&didod, 0, sizeof(DIDEVICEOBJECTDATA) * 8); // Let's see if there's any data waiting hr = IDirectInputDevice8_Poll(lpDIDevicetemp); if (FAILED(hr)) { if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { // Make sure device is acquired while(IDirectInputDevice8_Acquire(lpDIDevicetemp) == DIERR_INPUTLOST) {} return TRUE; } } // Poll events if (FAILED(IDirectInputDevice8_GetDeviceData(lpDIDevicetemp, sizeof(DIDEVICEOBJECTDATA), didod, &size, 0))) { if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) { // Make sure device is acquired while(IDirectInputDevice8_Acquire(lpDIDevicetemp) == DIERR_INPUTLOST) {} return TRUE; } } didc.dwSize = sizeof(DIDEVCAPS); if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc))) return TRUE; if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) { for (i = 0; i < size; i++) { if (didod[i].dwData & 0x80) { // We're done. time to bail EndDialog(hDlg, TRUE); memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); break; } } } else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) { for (i = 0; i < size; i++) { if (didod[i].dwOfs == 0 || didod[i].dwOfs == 4) { if (didod[i].dwData <= 0x1000 || didod[i].dwData >= 0xF000) { // We're done. time to bail EndDialog(hDlg, TRUE); memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); break; } } else if (didod[i].dwOfs == 0x20) { if (((int)didod[i].dwData) >= 0) { // We're done. time to bail EndDialog(hDlg, TRUE); memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); } } else if (didod[i].dwOfs >= 0x30) { if (didod[i].dwData & 0x80) { // We're done. time to bail EndDialog(hDlg, TRUE); memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); break; } } } } else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) { for (i = 0; i < size; i++) { // Make sure it's a button press if (didod[i].dwOfs >= DIMOFS_BUTTON0 && didod[i].dwOfs <= DIMOFS_BUTTON7) { if (didod[i].dwData & 0x80) { EndDialog(hDlg, TRUE); memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); break; } } } } return TRUE; } return FALSE; } case WM_DESTROY: { KillTimer(hDlg, 1); UnhookWindowsHookEx(hook); break; } } return FALSE; }