/* key_dinput_acquire: [window thread] * Acquires the keyboard device. This must be called after a * window switch for example if the device is in foreground * cooperative level. */ int key_dinput_acquire(void) { HRESULT hr; BYTE keystate[256]; if (key_dinput_device) { /* Read the current Windows keyboard state */ GetKeyboardState(keystate); update_shifts(keystate); hr = IDirectInputDevice_Acquire(key_dinput_device); if (FAILED(hr)) { _TRACE(PREFIX_E "acquire keyboard failed: %s\n", dinput_err_str(hr)); return -1; } /* Initialize keyboard state */ SetEvent(key_input_event); return 0; } else return -1; }
/* joystick_dinput_acquire: [window thread] * Acquires the joystick devices. */ int joystick_dinput_acquire(void) { HRESULT hr; int i; if (joystick_dinput) { for (i=0; i<dinput_joy_num; i++) { hr = IDirectInputDevice2_Acquire(dinput_joystick[i].device); if (FAILED(hr)) _TRACE(PREFIX_E "acquire joystick %d failed: %s\n", i, dinput_err_str(hr)); } } return 0; }
/* _al_win_joystick_dinput_acquire: [window thread] * Acquires the joystick devices. */ static void joystick_dinput_acquire(void) { HRESULT hr; int i; if (!joystick_dinput) return; for (i=0; i < MAX_JOYSTICKS; i++) { if (joydx_joystick[i].device) { hr = IDirectInputDevice8_Acquire(joydx_joystick[i].device); if (FAILED(hr)) ALLEGRO_ERROR("acquire joystick %d failed: %s\n", i, dinput_err_str(hr)); } } }
/* mouse_dinput_grab: [window thread] * Grabs the mouse device. */ int mouse_dinput_grab(void) { HRESULT hr; DWORD level; HWND allegro_wnd = win_get_window(); if (mouse_dinput_device) { /* necessary in order to set the cooperative level */ mouse_dinput_unacquire(); if (gfx_driver && !gfx_driver->windowed) { level = DISCL_FOREGROUND | DISCL_EXCLUSIVE; _TRACE(PREFIX_I "foreground exclusive cooperative level requested for mouse\n"); } else { level = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; _TRACE(PREFIX_I "foreground non-exclusive cooperative level requested for mouse\n"); } /* set cooperative level */ hr = IDirectInputDevice_SetCooperativeLevel(mouse_dinput_device, allegro_wnd, level); if (FAILED(hr)) { _TRACE(PREFIX_E "set cooperative level failed: %s\n", dinput_err_str(hr)); return -1; } mouse_dinput_acquire(); /* update the system cursor */ mouse_set_syscursor(); return 0; } else { /* update the system cursor */ mouse_set_syscursor(); return -1; } }
static void joydx_merge(void) { unsigned i; HRESULT hr; config_needs_merging = false; joydx_num_joysticks = 0; for (i = 0; i < MAX_JOYSTICKS; i++) { ALLEGRO_JOYSTICK_DIRECTX *joy = &joydx_joystick[i]; switch (joy->config_state) { case STATE_UNUSED: break; case STATE_BORN: hr = IDirectInputDevice8_Acquire(joy->device); if (FAILED(hr)) { ALLEGRO_ERROR("acquire joystick %d failed: %s\n", i, dinput_err_str(hr)); } joy->config_state = STATE_ALIVE; /* fall through */ case STATE_ALIVE: JOYSTICK_WAKER(joydx_num_joysticks) = joy->waker_event; joydx_num_joysticks++; break; case STATE_DYING: joydx_inactivate_joy(joy); break; } } ALLEGRO_INFO("Merged, num joysticks=%d\n", joydx_num_joysticks); joystick_dinput_acquire(); }
/* mouse_dinput_acquire: [window thread] * Acquires the mouse device. */ int mouse_dinput_acquire(void) { HRESULT hr; if (mouse_dinput_device) { _mouse_b = 0; hr = IDirectInputDevice_Acquire(mouse_dinput_device); if (FAILED(hr)) { _TRACE(PREFIX_E "acquire mouse failed: %s\n", dinput_err_str(hr)); return -1; } /* The cursor may not be in the client area * so we don't set _mouse_on here. */ return 0; } else { return -1; } }
/* joystick_enum_callback: [primary thread] * Helper function to find out how many joysticks we have and set them up. * At the end joydx_num_joysticks and joydx_joystick[] will be initialised. */ static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { DIPROPRANGE property_range = { /* the header */ { sizeof(DIPROPRANGE), // diph.dwSize sizeof(DIPROPHEADER), // diph.dwHeaderSize 0, // diph.dwObj DIPH_DEVICE, // diph.dwHow }, /* the data */ -32767, // lMin +32767 // lMax }; DIPROPDWORD property_deadzone = { /* the header */ { sizeof(DIPROPDWORD), // diph.dwSize sizeof(DIPROPHEADER), // diph.dwHeaderSize 0, // diph.dwObj DIPH_DEVICE, // diph.dwHow }, /* the data */ 2000, // dwData }; DIPROPDWORD property_buffersize = { /* the header */ { sizeof(DIPROPDWORD), // diph.dwSize sizeof(DIPROPHEADER), // diph.dwHeaderSize 0, // diph.dwObj DIPH_DEVICE, // diph.dwHow }, /* the data */ DEVICE_BUFFER_SIZE // number of data items }; LPDIRECTINPUTDEVICE _dinput_device1; LPDIRECTINPUTDEVICE2 dinput_device = NULL; HRESULT hr; LPVOID temp; CAPS_AND_NAMES caps_and_names; ALLEGRO_JOYSTICK_DIRECTX *joy; int num; (void)pvRef; /* check if the joystick already existed before */ joy = joydx_by_guid(lpddi->guidInstance); if (joy) { ALLEGRO_DEBUG("Device %s still exists\n", joydx_guid_string(joy)); joy->marked = true; return DIENUM_CONTINUE; } /* create the DirectInput joystick device */ hr = IDirectInput8_CreateDevice(joystick_dinput, &lpddi->guidInstance, &_dinput_device1, NULL); if (FAILED(hr)) goto Error; /* query the DirectInputDevice2 interface needed for the poll() method */ hr = IDirectInputDevice8_QueryInterface(_dinput_device1, &__al_IID_IDirectInputDevice8A, &temp); IDirectInputDevice8_Release(_dinput_device1); if (FAILED(hr)) goto Error; dinput_device = temp; /* enumerate objects available on the device */ memset(&caps_and_names, 0, sizeof(caps_and_names)); hr = IDirectInputDevice8_EnumObjects(dinput_device, object_enum_callback, &caps_and_names, DIDFT_PSHBUTTON | DIDFT_AXIS | DIDFT_POV); if (FAILED(hr)) goto Error; /* set data format */ hr = IDirectInputDevice8_SetDataFormat(dinput_device, &__al_c_dfDIJoystick); if (FAILED(hr)) goto Error; /* set the range of axes */ hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_RANGE, &property_range.diph); if (FAILED(hr)) goto Error; /* set the dead zone of axes */ hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_DEADZONE, &property_deadzone.diph); if (FAILED(hr)) goto Error; /* set the buffer size */ hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_BUFFERSIZE, &property_buffersize.diph); if (FAILED(hr)) goto Error; /* set up the joystick structure */ joy = joydx_allocate_structure(&num); if (!joy) { ALLEGRO_ERROR("Joystick array full\n"); goto Error; } joy->config_state = STATE_BORN; joy->marked = true; joy->device = dinput_device; memcpy(&joy->guid, &lpddi->guidInstance, sizeof(GUID)); _al_sane_strncpy(joy->name, lpddi->tszInstanceName, sizeof(joy->name)); /* fill in the joystick structure */ fill_joystick_info_using_caps_and_names(joy, &caps_and_names); /* create a thread event for this joystick, unless it was already created */ joy->waker_event = CreateEvent(NULL, false, false, NULL); /* tell the joystick background thread to wake up when this joystick * device's state changes */ hr = IDirectInputDevice8_SetEventNotification(joy->device, joy->waker_event); if (FAILED(hr)) { ALLEGRO_ERROR("SetEventNotification failed for joystick %d: %s\n", num, dinput_err_str(hr)); goto Error; } if (hr == DI_POLLEDDEVICE) { /* This joystick device must be polled -- replace the Event with * a Waitable Timer object. * * Theoretically all polled devices could share a single * waitable timer object. But, really, how many such devices * are there going to be on a system? */ CloseHandle(joy->waker_event); joy->waker_event = CreateWaitableTimer(NULL, false, NULL); if (joy->waker_event == NULL) { ALLEGRO_ERROR("CreateWaitableTimer failed for polled device.\n"); goto Error; } { LARGE_INTEGER due_time; due_time.HighPart = 0; due_time.LowPart = 150; /* 15 ms (arbitrary) */ SetWaitableTimer(joy->waker_event, &due_time, true, /* periodic */ NULL, NULL, false); } } ALLEGRO_INFO("Joystick %d initialized, GUID: %s\n", num, joydx_guid_string(joy)); config_needs_merging = true; return DIENUM_CONTINUE; Error: if (dinput_device) IDirectInputDevice8_Release(dinput_device); if (joy) { joy->device = NULL; joydx_inactivate_joy(joy); } return DIENUM_CONTINUE; }
/* key_dinput_acquire: [window thread] * Acquires the keyboard device. This must be called after a * window switch for example if the device is in foreground * cooperative level. */ int key_dinput_acquire(void) { HRESULT hr; int mask, state; char key_state[256]; if (key_dinput_device) { mask = KB_SCROLOCK_FLAG | KB_NUMLOCK_FLAG | KB_CAPSLOCK_FLAG; state = 0; /* Read the current Windows keyboard state */ GetKeyboardState(key_state); if (key_state[VK_SCROLL] & 1) state |= KB_SCROLOCK_FLAG; if (key_state[VK_NUMLOCK] & 1) state |= KB_NUMLOCK_FLAG; if (key_state[VK_CAPITAL] & 1) state |= KB_CAPSLOCK_FLAG; _key_shifts = (_key_shifts & ~mask) | (state & mask); hr = IDirectInputDevice_Acquire(key_dinput_device); if (FAILED(hr)) { _TRACE(PREFIX_E "acquire keyboard failed: %s\n", dinput_err_str(hr)); return -1; } /* Initialize keyboard state */ SetEvent(key_input_event); return 0; } else return -1; }