/* mouse_dinput_exit: [primary thread] * Shuts down the DirectInput mouse device. */ static int mouse_dinput_exit(void) { if (mouse_dinput_device) { /* unregister event handler first */ _win_input_unregister_event(mouse_input_event); /* unacquire device */ wnd_call_proc(mouse_dinput_unacquire); /* now it can be released */ IDirectInputDevice_Release(mouse_dinput_device); mouse_dinput_device = NULL; } /* release DirectInput interface */ if (mouse_dinput) { IDirectInput_Release(mouse_dinput); mouse_dinput = NULL; } /* close event handle */ if (mouse_input_event) { CloseHandle(mouse_input_event); mouse_input_event = NULL; } /* update the system cursor */ wnd_schedule_proc(mouse_set_syscursor); return 0; }
/* sys_directx_restore_console_state: * Restores console window size and position. */ static void sys_directx_restore_console_state(void) { HWND allegro_wnd = win_get_window(); /* unacquire input devices */ wnd_schedule_proc(key_dinput_unacquire); wnd_schedule_proc(mouse_dinput_unacquire); wnd_schedule_proc(joystick_dinput_unacquire); /* reset switch mode */ _win_reset_switch_mode(); /* re-size and hide window */ SetWindowPos(allegro_wnd, HWND_TOP, wnd_rect.left, wnd_rect.top, wnd_rect.right - wnd_rect.left, wnd_rect.bottom - wnd_rect.top, SWP_NOCOPYBITS); ShowWindow(allegro_wnd, SW_SHOW); }
/* key_dinput_handle: [input thread] * Handles queued keyboard input. */ static void key_dinput_handle(void) { static DIDEVICEOBJECTDATA scancode_buffer[DINPUT_BUFFERSIZE]; long int waiting_scancodes; HRESULT hr; int i; /* the whole buffer is free */ waiting_scancodes = DINPUT_BUFFERSIZE; /* fill the buffer */ hr = IDirectInputDevice_GetDeviceData(key_dinput_device, sizeof(DIDEVICEOBJECTDATA), scancode_buffer, &waiting_scancodes, 0); /* was device lost ? */ if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) { /* reacquire device */ _TRACE(PREFIX_W "keyboard device not acquired or lost\n"); wnd_schedule_proc(key_dinput_acquire); } else if (FAILED(hr)) { /* other error? */ _TRACE(PREFIX_E "unexpected error while filling keyboard scancode buffer\n"); } else { /* normally only this case should happen */ for (i = 0; i < waiting_scancodes; i++) { key_dinput_handle_scancode((unsigned char) scancode_buffer[i].dwOfs, scancode_buffer[i].dwData & 0x80); } } SetEvent(key_input_processed_event); }
/* win_grab_input: * Grabs the input devices. */ void win_grab_input(void) { wnd_schedule_proc(key_dinput_acquire); wnd_schedule_proc(mouse_dinput_grab); wnd_schedule_proc(joystick_dinput_acquire); }
/* joystick_dinput_poll: [primary thread] * Polls the DirectInput joystick devices. */ static int joystick_dinput_poll(void) { int n_joy, n_axis, n_but; DIJOYSTATE js; HRESULT hr; for (n_joy = 0; n_joy < dinput_joy_num; n_joy++) { /* poll the device */ IDirectInputDevice2_Poll(dinput_joystick[n_joy].device); hr = IDirectInputDevice2_GetDeviceState(dinput_joystick[n_joy].device, sizeof(DIJOYSTATE), &js); if (hr == DI_OK) { /* axes */ dinput_joystick[n_joy].axis[0] = js.lX; dinput_joystick[n_joy].axis[1] = js.lY; n_axis = 2; if (dinput_joystick[n_joy].caps & JOYCAPS_HASZ) { dinput_joystick[n_joy].axis[n_axis] = js.lZ; n_axis++; } if (dinput_joystick[n_joy].caps & JOYCAPS_HASR) { dinput_joystick[n_joy].axis[n_axis] = js.lRz; n_axis++; } /* In versions of the DirectInput joystick API earlier than 8.00, slider * data is to be found in the Z axis data member, although the object was * reported as a slider during enumeration. * * Very few locations seem to describe this "feature". Here is one: * http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dx81_vb/directx_vb/Input/VB_Ref/Types/dijoystate2.asp * * The interesting part is the note at the bottom of the page: * " Note: Under Microsoft DirectX 7, sliders on some joysticks could be assigned * to the Z axis, with subsequent code retrieving data from that member. * Using DirectX 8, those same sliders will be assigned to the slider array. * This should be taken into account when porting applications to DirectX 8. * Make any necessary alterations to ensure that slider data is retrieved from * the slider array. " */ /* For U axis (slider 0), get data from Z axis member if API < 0x0800 * and if a real Z axis is not present. Otherwise get it from slider 0 member. */ if (dinput_joystick[n_joy].caps & JOYCAPS_HASU) { #if DIRECTINPUT_VERSION < 0x0800 if (dinput_joystick[n_joy].caps & JOYCAPS_HASZ) dinput_joystick[n_joy].axis[n_axis] = js.rglSlider[0]; else dinput_joystick[n_joy].axis[n_axis] = js.lZ; #else dinput_joystick[n_joy].axis[n_axis] = js.rglSlider[0]; #endif n_axis++; } /* For V axis (slider 1), get data from slider 0 member if API < 0x0800 * and if a real Z axis is not present. Otherwise get it from slider 1 member. */ if (dinput_joystick[n_joy].caps & JOYCAPS_HASV) { #if DIRECTINPUT_VERSION < 0x0800 if (dinput_joystick[n_joy].caps & JOYCAPS_HASZ) dinput_joystick[n_joy].axis[n_axis] = js.rglSlider[1]; else dinput_joystick[n_joy].axis[n_axis] = js.rglSlider[0]; #else dinput_joystick[n_joy].axis[n_axis] = js.rglSlider[1]; #endif n_axis++; } /* hat */ if (dinput_joystick[n_joy].caps & JOYCAPS_HASPOV) dinput_joystick[n_joy].hat = js.rgdwPOV[0]; /* buttons */ for (n_but = 0; n_but < dinput_joystick[n_joy].num_buttons; n_but++) dinput_joystick[n_joy].button[n_but] = ((js.rgbButtons[n_but] & 0x80) != 0); win_update_joystick_status(n_joy, (WINDOWS_JOYSTICK_INFO *)&dinput_joystick[n_joy]); } else { if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) { /* reacquire device */ _TRACE(PREFIX_W "joystick device not acquired or lost\n"); wnd_schedule_proc(joystick_dinput_acquire); } else { _TRACE(PREFIX_E "unexpected error while polling the joystick\n"); } } } return 0; }
/* mouse_dinput_handle: [input thread] * Handles queued mouse input. */ static void mouse_dinput_handle(void) { static DIDEVICEOBJECTDATA message_buffer[DINPUT_BUFFERSIZE]; long int waiting_messages; HRESULT hr; int i; /* the whole buffer is free */ waiting_messages = DINPUT_BUFFERSIZE; /* fill the buffer */ hr = IDirectInputDevice_GetDeviceData(mouse_dinput_device, sizeof(DIDEVICEOBJECTDATA), message_buffer, &waiting_messages, 0); /* was device lost ? */ if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) { /* reacquire device */ _TRACE(PREFIX_W "mouse device not acquired or lost\n"); wnd_schedule_proc(mouse_dinput_acquire); } else if (FAILED(hr)) { /* other error? */ _TRACE(PREFIX_E "unexpected error while filling mouse message buffer\n"); } else { /* normally only this case should happen */ for (i = 0; i < waiting_messages; i++) { mouse_dinput_handle_event(message_buffer[i].dwOfs, message_buffer[i].dwData); } if (gfx_driver && gfx_driver->windowed) { /* windowed input mode */ if (!wnd_sysmenu) { POINT p; READ_CURSOR_POS(p); mymickey_x += p.x - mymickey_ox; mymickey_y += p.y - mymickey_oy; mymickey_ox = p.x; mymickey_oy = p.y; _handle_mouse_input(); } } else { /* fullscreen input mode */ mymickey_x += dinput_x - mymickey_ox; mymickey_y += dinput_y - mymickey_oy; mymickey_ox = dinput_x; mymickey_oy = dinput_y; _mouse_x = MICKEY_TO_COORD_X(mouse_mx + dinput_x); _mouse_y = MICKEY_TO_COORD_Y(mouse_my + dinput_y); if ((_mouse_x < mouse_minx) || (_mouse_x > mouse_maxx) || (_mouse_y < mouse_miny) || (_mouse_y > mouse_maxy)) { _mouse_x = MID(mouse_minx, _mouse_x, mouse_maxx); _mouse_y = MID(mouse_miny, _mouse_y, mouse_maxy); mouse_mx = COORD_TO_MICKEY_X(_mouse_x); mouse_my = COORD_TO_MICKEY_Y(_mouse_y); CLEAR_MICKEYS(); } if (!_mouse_on) { _mouse_on = TRUE; wnd_schedule_proc(mouse_set_syscursor); } _handle_mouse_input(); } } }