mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-04 05:50:15 +00:00
Modify Allegro to use WM_KEYUP/DOWN messages instead of DirectInput.
This commit is contained in:
parent
57b54ad050
commit
a877d52048
@ -4,3 +4,5 @@ patched for ASE by David Capello.
|
|||||||
Changes:
|
Changes:
|
||||||
- Mouse driver for Windows was modified to use WM_MOUSEMOVE instead of
|
- Mouse driver for Windows was modified to use WM_MOUSEMOVE instead of
|
||||||
DirectInput (like in Allegro 5).
|
DirectInput (like in Allegro 5).
|
||||||
|
- Keyboard driver for Windows was modified to use WM_KEYDOWN/UP messages
|
||||||
|
instead of DirectInput (like in Allegro 5).
|
||||||
|
@ -120,10 +120,6 @@ AL_FUNC(int, _win_input_register_event, (HANDLE event_id, void (*event_handler)(
|
|||||||
AL_FUNC(void, _win_input_unregister_event, (HANDLE event_id));
|
AL_FUNC(void, _win_input_unregister_event, (HANDLE event_id));
|
||||||
|
|
||||||
|
|
||||||
/* keyboard routines */
|
|
||||||
AL_FUNC(int, key_dinput_acquire, (void));
|
|
||||||
AL_FUNC(int, key_dinput_unacquire, (void));
|
|
||||||
|
|
||||||
|
|
||||||
/* mouse routines */
|
/* mouse routines */
|
||||||
AL_VAR(HCURSOR, _win_hcursor);
|
AL_VAR(HCURSOR, _win_hcursor);
|
||||||
|
@ -77,12 +77,6 @@ AL_VAR(SYSTEM_DRIVER, system_directx);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************/
|
|
||||||
/************ keyboard drivers *************/
|
|
||||||
/*******************************************/
|
|
||||||
#define KEYBOARD_DIRECTX AL_ID('D','X',' ',' ')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
/*************** gfx drivers ***************/
|
/*************** gfx drivers ***************/
|
||||||
|
@ -82,8 +82,6 @@ typedef struct WIN_GFX_DRIVER {
|
|||||||
|
|
||||||
AL_VAR(WIN_GFX_DRIVER *, win_gfx_driver);
|
AL_VAR(WIN_GFX_DRIVER *, win_gfx_driver);
|
||||||
|
|
||||||
AL_FUNC(void, win_grab_input, (void));
|
|
||||||
|
|
||||||
|
|
||||||
/* external window support */
|
/* external window support */
|
||||||
AL_FUNC(HWND, win_get_window, (void));
|
AL_FUNC(HWND, win_get_window, (void));
|
||||||
|
@ -237,9 +237,6 @@ static void finalize_fullscreen_init(void)
|
|||||||
|
|
||||||
/* set the default switching policy */
|
/* set the default switching policy */
|
||||||
set_display_switch_mode(SWITCH_AMNESIA);
|
set_display_switch_mode(SWITCH_AMNESIA);
|
||||||
|
|
||||||
/* grab input devices */
|
|
||||||
win_grab_input();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -404,9 +404,6 @@ static struct BITMAP *init_directx_ovl(int w, int h, int v_w, int v_h, int color
|
|||||||
/* set default switching policy */
|
/* set default switching policy */
|
||||||
set_display_switch_mode(SWITCH_PAUSE);
|
set_display_switch_mode(SWITCH_PAUSE);
|
||||||
|
|
||||||
/* grab input devices */
|
|
||||||
win_grab_input();
|
|
||||||
|
|
||||||
_exit_critical();
|
_exit_critical();
|
||||||
|
|
||||||
return gfx_directx_forefront_bitmap;
|
return gfx_directx_forefront_bitmap;
|
||||||
|
@ -772,9 +772,6 @@ static struct BITMAP *init_directx_win(int w, int h, int v_w, int v_h, int color
|
|||||||
/* set default switching policy */
|
/* set default switching policy */
|
||||||
set_display_switch_mode(SWITCH_PAUSE);
|
set_display_switch_mode(SWITCH_PAUSE);
|
||||||
|
|
||||||
/* grab input devices */
|
|
||||||
win_grab_input();
|
|
||||||
|
|
||||||
_exit_critical();
|
_exit_critical();
|
||||||
|
|
||||||
return gfx_directx_forefront_bitmap;
|
return gfx_directx_forefront_bitmap;
|
||||||
|
@ -113,8 +113,6 @@ void _win_switch_in(void)
|
|||||||
|
|
||||||
_win_app_foreground = TRUE;
|
_win_app_foreground = TRUE;
|
||||||
|
|
||||||
key_dinput_acquire();
|
|
||||||
|
|
||||||
if (win_gfx_driver && win_gfx_driver->switch_in)
|
if (win_gfx_driver && win_gfx_driver->switch_in)
|
||||||
win_gfx_driver->switch_in();
|
win_gfx_driver->switch_in();
|
||||||
|
|
||||||
@ -145,8 +143,6 @@ void _win_switch_out(void)
|
|||||||
|
|
||||||
_win_app_foreground = FALSE;
|
_win_app_foreground = FALSE;
|
||||||
|
|
||||||
key_dinput_unacquire();
|
|
||||||
|
|
||||||
if (win_gfx_driver && win_gfx_driver->switch_out)
|
if (win_gfx_driver && win_gfx_driver->switch_out)
|
||||||
win_gfx_driver->switch_out();
|
win_gfx_driver->switch_out();
|
||||||
|
|
||||||
|
@ -513,9 +513,6 @@ static struct BITMAP *gfx_gdi_init(int w, int h, int v_w, int v_h, int color_dep
|
|||||||
/* set the default switching policy */
|
/* set the default switching policy */
|
||||||
set_display_switch_mode(SWITCH_PAUSE);
|
set_display_switch_mode(SWITCH_PAUSE);
|
||||||
|
|
||||||
/* grab input devices */
|
|
||||||
win_grab_input();
|
|
||||||
|
|
||||||
_exit_critical();
|
_exit_critical();
|
||||||
|
|
||||||
return gdi_screen;
|
return gdi_screen;
|
||||||
|
@ -1,32 +1,15 @@
|
|||||||
/* ______ ___ ___
|
/*
|
||||||
* /\ _ \ /\_ \ /\_ \
|
Mouse driver for ASE
|
||||||
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
|
by David Capello
|
||||||
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
|
|
||||||
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
|
|
||||||
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
|
|
||||||
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
|
|
||||||
* /\____/
|
|
||||||
* \_/__/
|
|
||||||
*
|
|
||||||
* Windows keyboard driver.
|
|
||||||
*
|
|
||||||
* By Stefan Schimanski, hacked up by Peter Wang and Elias Pschernig.
|
|
||||||
*
|
|
||||||
* See readme.txt for copyright information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
Based on code of Stefan Schimanski, Peter Wang, Elias Pschernig,
|
||||||
#define DIRECTINPUT_VERSION 0x0300
|
and Milan Mimica.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "allegro.h"
|
#include "allegro.h"
|
||||||
#include "allegro/internal/aintern.h"
|
#include "allegro/internal/aintern.h"
|
||||||
#include "allegro/platform/aintwin.h"
|
#include "allegro/platform/aintwin.h"
|
||||||
|
|
||||||
#ifndef SCAN_DEPEND
|
|
||||||
#include <process.h>
|
|
||||||
#include <dinput.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ALLEGRO_WINDOWS
|
#ifndef ALLEGRO_WINDOWS
|
||||||
#error something is wrong with the makefile
|
#error something is wrong with the makefile
|
||||||
#endif
|
#endif
|
||||||
@ -36,130 +19,86 @@
|
|||||||
#define PREFIX_E "al-wkey ERROR: "
|
#define PREFIX_E "al-wkey ERROR: "
|
||||||
|
|
||||||
|
|
||||||
#define DINPUT_BUFFERSIZE 256
|
|
||||||
static HANDLE key_input_event = NULL;
|
#define KEY_UNKNOWN KEY_MAX
|
||||||
static HANDLE key_input_processed_event = NULL;
|
|
||||||
static LPDIRECTINPUT key_dinput = NULL;
|
|
||||||
static LPDIRECTINPUTDEVICE key_dinput_device = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
/* lookup table for converting DIK_* scancodes into Allegro KEY_* codes */
|
/* lookup table for converting virtualkey VK_* codes into Allegro KEY_* codes */
|
||||||
/* this table was from pckeys.c */
|
/* Last unknown key sequence: 39*/
|
||||||
static const unsigned char hw_to_mycode[256] = {
|
static const unsigned char hw_to_mycode[256] =
|
||||||
/* 0x00 */ 0, KEY_ESC, KEY_1, KEY_2,
|
|
||||||
/* 0x04 */ KEY_3, KEY_4, KEY_5, KEY_6,
|
|
||||||
/* 0x08 */ KEY_7, KEY_8, KEY_9, KEY_0,
|
|
||||||
/* 0x0C */ KEY_MINUS, KEY_EQUALS, KEY_BACKSPACE, KEY_TAB,
|
|
||||||
/* 0x10 */ KEY_Q, KEY_W, KEY_E, KEY_R,
|
|
||||||
/* 0x14 */ KEY_T, KEY_Y, KEY_U, KEY_I,
|
|
||||||
/* 0x18 */ KEY_O, KEY_P, KEY_OPENBRACE, KEY_CLOSEBRACE,
|
|
||||||
/* 0x1C */ KEY_ENTER, KEY_LCONTROL, KEY_A, KEY_S,
|
|
||||||
/* 0x20 */ KEY_D, KEY_F, KEY_G, KEY_H,
|
|
||||||
/* 0x24 */ KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
|
|
||||||
/* 0x28 */ KEY_QUOTE, KEY_TILDE, KEY_LSHIFT, KEY_BACKSLASH,
|
|
||||||
/* 0x2C */ KEY_Z, KEY_X, KEY_C, KEY_V,
|
|
||||||
/* 0x30 */ KEY_B, KEY_N, KEY_M, KEY_COMMA,
|
|
||||||
/* 0x34 */ KEY_STOP, KEY_SLASH, KEY_RSHIFT, KEY_ASTERISK,
|
|
||||||
/* 0x38 */ KEY_ALT, KEY_SPACE, KEY_CAPSLOCK, KEY_F1,
|
|
||||||
/* 0x3C */ KEY_F2, KEY_F3, KEY_F4, KEY_F5,
|
|
||||||
/* 0x40 */ KEY_F6, KEY_F7, KEY_F8, KEY_F9,
|
|
||||||
/* 0x44 */ KEY_F10, KEY_NUMLOCK, KEY_SCRLOCK, KEY_7_PAD,
|
|
||||||
/* 0x48 */ KEY_8_PAD, KEY_9_PAD, KEY_MINUS_PAD, KEY_4_PAD,
|
|
||||||
/* 0x4C */ KEY_5_PAD, KEY_6_PAD, KEY_PLUS_PAD, KEY_1_PAD,
|
|
||||||
/* 0x50 */ KEY_2_PAD, KEY_3_PAD, KEY_0_PAD, KEY_DEL_PAD,
|
|
||||||
/* 0x54 */ KEY_PRTSCR, 0, KEY_BACKSLASH2, KEY_F11,
|
|
||||||
/* 0x58 */ KEY_F12, 0, 0, KEY_LWIN,
|
|
||||||
/* 0x5C */ KEY_RWIN, KEY_MENU, 0, 0,
|
|
||||||
/* 0x60 */ 0, 0, 0, 0,
|
|
||||||
/* 0x64 */ 0, 0, 0, 0,
|
|
||||||
/* 0x68 */ 0, 0, 0, 0,
|
|
||||||
/* 0x6C */ 0, 0, 0, 0,
|
|
||||||
/* 0x70 */ KEY_KANA, 0, 0, KEY_ABNT_C1,
|
|
||||||
/* 0x74 */ 0, 0, 0, 0,
|
|
||||||
/* 0x78 */ 0, KEY_CONVERT, 0, KEY_NOCONVERT,
|
|
||||||
/* 0x7C */ 0, KEY_YEN, 0, 0,
|
|
||||||
/* 0x80 */ 0, 0, 0, 0,
|
|
||||||
/* 0x84 */ 0, 0, 0, 0,
|
|
||||||
/* 0x88 */ 0, 0, 0, 0,
|
|
||||||
/* 0x8C */ 0, 0, 0, 0,
|
|
||||||
/* 0x90 */ 0, KEY_AT, KEY_COLON2, 0,
|
|
||||||
/* 0x94 */ KEY_KANJI, 0, 0, 0,
|
|
||||||
/* 0x98 */ 0, 0, 0, 0,
|
|
||||||
/* 0x9C */ KEY_ENTER_PAD, KEY_RCONTROL, 0, 0,
|
|
||||||
/* 0xA0 */ 0, 0, 0, 0,
|
|
||||||
/* 0xA4 */ 0, 0, 0, 0,
|
|
||||||
/* 0xA8 */ 0, 0, 0, 0,
|
|
||||||
/* 0xAC */ 0, 0, 0, 0,
|
|
||||||
/* 0xB0 */ 0, 0, 0, 0,
|
|
||||||
/* 0xB4 */ 0, KEY_SLASH_PAD, 0, KEY_PRTSCR,
|
|
||||||
/* 0xB8 */ KEY_ALTGR, 0, 0, 0,
|
|
||||||
/* 0xBC */ 0, 0, 0, 0,
|
|
||||||
/* 0xC0 */ 0, 0, 0, 0,
|
|
||||||
/* 0xC4 */ 0, KEY_PAUSE, 0, KEY_HOME,
|
|
||||||
/* 0xC8 */ KEY_UP, KEY_PGUP, 0, KEY_LEFT,
|
|
||||||
/* 0xCC */ 0, KEY_RIGHT, 0, KEY_END,
|
|
||||||
/* 0xD0 */ KEY_DOWN, KEY_PGDN, KEY_INSERT, KEY_DEL,
|
|
||||||
/* 0xD4 */ 0, 0, 0, 0,
|
|
||||||
/* 0xD8 */ 0, 0, 0, KEY_LWIN,
|
|
||||||
/* 0xDC */ KEY_RWIN, KEY_MENU, 0, 0,
|
|
||||||
/* 0xE0 */ 0, 0, 0, 0,
|
|
||||||
/* 0xE4 */ 0, 0, 0, 0,
|
|
||||||
/* 0xE8 */ 0, 0, 0, 0,
|
|
||||||
/* 0xEC */ 0, 0, 0, 0,
|
|
||||||
/* 0xF0 */ 0, 0, 0, 0,
|
|
||||||
/* 0xF4 */ 0, 0, 0, 0,
|
|
||||||
/* 0xF8 */ 0, 0, 0, 0,
|
|
||||||
/* 0xFC */ 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Used in scancode_to_name. */
|
|
||||||
static LONG reverse_mapping[KEY_MAX];
|
|
||||||
|
|
||||||
|
|
||||||
/* dinput_err_str:
|
|
||||||
* Returns a DirectInput error string.
|
|
||||||
*/
|
|
||||||
#ifdef DEBUGMODE
|
|
||||||
static char* dinput_err_str(long err)
|
|
||||||
{
|
{
|
||||||
static char err_str[64];
|
/* 0x00 */ 0, KEY_UNKNOWN+0, KEY_UNKNOWN+1, KEY_UNKNOWN+2,
|
||||||
|
/* 0x04 */ KEY_UNKNOWN+3, KEY_UNKNOWN+4, KEY_UNKNOWN+5, 0,
|
||||||
|
/* 0x08 */ KEY_BACKSPACE, KEY_TAB, 0, 0,
|
||||||
|
/* 0x0C */ KEY_UNKNOWN+39, KEY_ENTER, 0, 0,
|
||||||
|
/* 0x10 */ 0/*L or R shift*/, 0/*L or R ctrl*/, 0/*L or R alt*/, KEY_PAUSE,
|
||||||
|
/* 0x14 */ KEY_CAPSLOCK, KEY_KANA, 0, KEY_UNKNOWN+6,
|
||||||
|
/* 0x18 */ KEY_UNKNOWN+7, KEY_KANJI, 0, KEY_ESC,
|
||||||
|
/* 0x1C */ KEY_CONVERT, KEY_NOCONVERT, KEY_UNKNOWN+8, KEY_UNKNOWN+9,
|
||||||
|
/* 0x20 */ KEY_SPACE, KEY_PGUP, KEY_PGDN, KEY_END,
|
||||||
|
/* 0x24 */ KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT,
|
||||||
|
/* 0x28 */ KEY_DOWN, KEY_UNKNOWN+10, KEY_UNKNOWN+11, KEY_UNKNOWN+12,
|
||||||
|
/* 0x2C */ KEY_PRTSCR, KEY_INSERT, KEY_DEL, KEY_UNKNOWN+13,
|
||||||
|
/* 0x30 */ KEY_0, KEY_1, KEY_2, KEY_3,
|
||||||
|
/* 0x34 */ KEY_4, KEY_5, KEY_6, KEY_7,
|
||||||
|
/* 0x38 */ KEY_8, KEY_9, 0, 0,
|
||||||
|
/* 0x3C */ 0, 0, 0, 0,
|
||||||
|
/* 0x40 */ 0, KEY_A, KEY_B, KEY_C,
|
||||||
|
/* 0x44 */ KEY_D, KEY_E, KEY_F, KEY_G,
|
||||||
|
/* 0x48 */ KEY_H, KEY_I, KEY_J, KEY_K,
|
||||||
|
/* 0x4C */ KEY_L, KEY_M, KEY_N, KEY_O,
|
||||||
|
/* 0x50 */ KEY_P, KEY_Q, KEY_R, KEY_S,
|
||||||
|
/* 0x54 */ KEY_T, KEY_U, KEY_V, KEY_W,
|
||||||
|
/* 0x58 */ KEY_X, KEY_Y, KEY_Z, KEY_LWIN,
|
||||||
|
/* 0x5C */ KEY_RWIN, KEY_UNKNOWN+14, 0, 0,
|
||||||
|
/* 0x60 */ KEY_0_PAD, KEY_1_PAD, KEY_2_PAD, KEY_3_PAD,
|
||||||
|
/* 0x64 */ KEY_4_PAD, KEY_5_PAD, KEY_6_PAD, KEY_7_PAD,
|
||||||
|
/* 0x68 */ KEY_8_PAD, KEY_9_PAD, KEY_ASTERISK, KEY_PLUS_PAD,
|
||||||
|
/* 0x6C */ KEY_UNKNOWN+15, KEY_MINUS_PAD, KEY_UNKNOWN+16, KEY_SLASH_PAD,
|
||||||
|
/* 0x70 */ KEY_F1, KEY_F2, KEY_F3, KEY_F4,
|
||||||
|
/* 0x74 */ KEY_F5, KEY_F6, KEY_F7, KEY_F8,
|
||||||
|
/* 0x78 */ KEY_F9, KEY_F10, KEY_F11, KEY_F12,
|
||||||
|
/* 0x7C */ KEY_UNKNOWN+17, KEY_UNKNOWN+18, KEY_UNKNOWN+19, KEY_UNKNOWN+20,
|
||||||
|
/* 0x80 */ KEY_UNKNOWN+21, KEY_UNKNOWN+22, KEY_UNKNOWN+23, KEY_UNKNOWN+24,
|
||||||
|
/* 0x84 */ KEY_UNKNOWN+25, KEY_UNKNOWN+26, KEY_UNKNOWN+27, KEY_UNKNOWN+28,
|
||||||
|
/* 0x88 */ 0, 0, 0, 0,
|
||||||
|
/* 0x8C */ 0, 0, 0, 0,
|
||||||
|
/* 0x90 */ KEY_NUMLOCK, KEY_SCRLOCK, 0, 0,
|
||||||
|
/* 0x94 */ 0, 0, 0, 0,
|
||||||
|
/* 0x98 */ 0, 0, 0, 0,
|
||||||
|
/* 0x9C */ 0, 0, 0, 0,
|
||||||
|
/* 0xA0 */ KEY_LSHIFT, KEY_RSHIFT, KEY_LCONTROL, KEY_RCONTROL,
|
||||||
|
/* 0xA4 */ KEY_ALT, KEY_ALTGR, 0, 0,
|
||||||
|
/* 0xA8 */ 0, 0, 0, 0,
|
||||||
|
/* 0xAC */ 0, 0, 0, 0,
|
||||||
|
/* 0xB0 */ 0, 0, 0, 0,
|
||||||
|
/* 0xB4 */ 0, 0, 0, 0,
|
||||||
|
/* 0xB8 */ 0, 0, KEY_SEMICOLON, KEY_EQUALS,
|
||||||
|
/* 0xBC */ KEY_COMMA, KEY_MINUS, KEY_STOP, KEY_SLASH,
|
||||||
|
/* 0xC0 */ KEY_TILDE, 0, 0, 0,
|
||||||
|
/* 0xC4 */ 0, 0, 0, 0,
|
||||||
|
/* 0xC8 */ 0, 0, 0, 0,
|
||||||
|
/* 0xCC */ 0, 0, 0, 0,
|
||||||
|
/* 0xD0 */ 0, 0, 0, 0,
|
||||||
|
/* 0xD4 */ 0, 0, 0, 0,
|
||||||
|
/* 0xD8 */ 0, 0, 0, KEY_OPENBRACE,
|
||||||
|
/* 0xDC */ KEY_BACKSLASH, KEY_CLOSEBRACE, KEY_QUOTE, 0,
|
||||||
|
/* 0xE0 */ 0, 0, KEY_BACKSLASH2, 0,
|
||||||
|
/* 0xE4 */ 0, KEY_UNKNOWN+29, 0, 0,
|
||||||
|
/* 0xE8 */ 0, 0, 0, 0,
|
||||||
|
/* 0xEC */ 0, 0, 0, 0,
|
||||||
|
/* 0xF0 */ 0, 0, 0, 0,
|
||||||
|
/* 0xF4 */ 0, 0, KEY_UNKNOWN+30, KEY_UNKNOWN+31,
|
||||||
|
/* 0xF8 */ KEY_UNKNOWN+32, KEY_UNKNOWN+33, KEY_UNKNOWN+34, KEY_UNKNOWN+35,
|
||||||
|
/* 0xFC */ KEY_UNKNOWN+36, KEY_UNKNOWN+37, KEY_UNKNOWN+38, 0
|
||||||
|
};
|
||||||
|
|
||||||
switch (err) {
|
|
||||||
|
|
||||||
case DIERR_NOTACQUIRED:
|
|
||||||
_al_sane_strncpy(err_str, "the device is not acquired", sizeof(err_str));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DIERR_INPUTLOST:
|
|
||||||
_al_sane_strncpy(err_str, "access to the device was lost", sizeof(err_str));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DIERR_INVALIDPARAM:
|
|
||||||
_al_sane_strncpy(err_str, "the device does not have a selected data format", sizeof(err_str));
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef DIERR_OTHERAPPHASPRIO
|
|
||||||
/* this is not a legacy DirectX 3 error code */
|
|
||||||
case DIERR_OTHERAPPHASPRIO:
|
|
||||||
_al_sane_strncpy(err_str, "can't acquire the device in background", sizeof(err_str));
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
_al_sane_strncpy(err_str, "unknown error", sizeof(err_str));
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_str;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define dinput_err_str(hr) "\0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Update the key_shifts.
|
/* Update the key_shifts.
|
||||||
*/
|
*/
|
||||||
static void update_shifts(BYTE * keystate)
|
static void update_shifts(BYTE* keystate)
|
||||||
{
|
{
|
||||||
/* TODO: There must be a more efficient way to maintain key_modifiers? */
|
/* TODO: There must be a more efficient way to maintain key_modifiers? */
|
||||||
/* Can't we just deprecate key_shifts, now that pckeys.c is gone? EP */
|
/* Can't we just deprecate key_shifts, now that pckeys.c is gone? EP */
|
||||||
@ -180,654 +119,147 @@ static void update_shifts(BYTE * keystate)
|
|||||||
modifiers |= KB_CAPSLOCK_FLAG;
|
modifiers |= KB_CAPSLOCK_FLAG;
|
||||||
|
|
||||||
_key_shifts = modifiers;
|
_key_shifts = modifiers;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* handle_key_press: [input thread]
|
/* _al_win_kbd_handle_key_press:
|
||||||
* Does stuff when a key is pressed.
|
* Does stuff when a key is pressed.
|
||||||
*/
|
*/
|
||||||
static void handle_key_press(unsigned char scancode)
|
void _al_win_kbd_handle_key_press(int scode, int vcode, BOOL repeated)
|
||||||
{
|
{
|
||||||
int mycode;
|
int my_code;
|
||||||
int unicode;
|
int ccode;
|
||||||
int n;
|
BYTE ks[256];
|
||||||
UINT vkey;
|
WCHAR buf[8];
|
||||||
BYTE keystate[256];
|
|
||||||
WCHAR chars[16];
|
|
||||||
|
|
||||||
vkey = MapVirtualKey(scancode, 1);
|
if (!GetKeyboardState(&ks[0]))
|
||||||
|
ccode = 0; /* shound't really happen */
|
||||||
GetKeyboardState(keystate);
|
else if (ToUnicode(vcode, scode, ks, buf, 8, 0) == 1)
|
||||||
update_shifts(keystate);
|
ccode = buf[0];
|
||||||
|
|
||||||
/* TODO: shouldn't we base the mapping on vkey? */
|
|
||||||
mycode = hw_to_mycode[scancode];
|
|
||||||
if (mycode == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* MapVirtualKey always returns the arrow key VKEY, so adjust
|
|
||||||
it if num lock is on */
|
|
||||||
if (keystate[VK_NUMLOCK]) {
|
|
||||||
switch (scancode) {
|
|
||||||
case DIK_NUMPAD0:
|
|
||||||
vkey = VK_NUMPAD0;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD1:
|
|
||||||
vkey = VK_NUMPAD1;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD2:
|
|
||||||
vkey = VK_NUMPAD2;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD3:
|
|
||||||
vkey = VK_NUMPAD3;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD4:
|
|
||||||
vkey = VK_NUMPAD4;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD5:
|
|
||||||
vkey = VK_NUMPAD5;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD6:
|
|
||||||
vkey = VK_NUMPAD6;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD7:
|
|
||||||
vkey = VK_NUMPAD7;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD8:
|
|
||||||
vkey = VK_NUMPAD8;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPAD9:
|
|
||||||
vkey = VK_NUMPAD9;
|
|
||||||
break;
|
|
||||||
case DIK_DECIMAL:
|
|
||||||
vkey = VK_DECIMAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* what's life without a few special cases */
|
|
||||||
switch (scancode) {
|
|
||||||
case DIK_DIVIDE:
|
|
||||||
vkey = VK_DIVIDE;
|
|
||||||
break;
|
|
||||||
case DIK_MULTIPLY:
|
|
||||||
vkey = VK_MULTIPLY;
|
|
||||||
break;
|
|
||||||
case DIK_SUBTRACT:
|
|
||||||
vkey = VK_SUBTRACT;
|
|
||||||
break;
|
|
||||||
case DIK_ADD:
|
|
||||||
vkey = VK_ADD;
|
|
||||||
break;
|
|
||||||
case DIK_NUMPADENTER:
|
|
||||||
vkey = VK_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: is there an advantage using ToUnicode? maybe it would allow
|
|
||||||
* Chinese and so on characters? For now, always ToAscii is used. */
|
|
||||||
//n = ToUnicode(vkey, scancode, keystate, chars, 16, 0);
|
|
||||||
n = ToAscii(vkey, scancode, keystate, (WORD *)chars, 0);
|
|
||||||
if (n == 1)
|
|
||||||
{
|
|
||||||
WCHAR wstr[2];
|
|
||||||
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)chars, n, wstr, 2);
|
|
||||||
unicode = wstr[0];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
ccode = 0;
|
||||||
/* Don't generate key presses for modifier keys or dead keys */
|
|
||||||
if (mycode >= KEY_MODIFIERS || n != 0)
|
/* Windows doesn't differentiate between the left and right versions
|
||||||
unicode = -1;
|
of the modifiers. To compensate we read the current keyboard state
|
||||||
|
and use that information to determine which key was actually
|
||||||
|
pressed. We check the last known state of the modifier in question
|
||||||
|
and if it is not down we know that is the key that was pressed. */
|
||||||
|
if (vcode == VK_SHIFT || vcode == VK_CONTROL || vcode == VK_MENU) {
|
||||||
|
if ((ks[VK_LCONTROL] & 0x80) && !key[KEY_LCONTROL])
|
||||||
|
vcode = VK_LCONTROL;
|
||||||
|
else if ((ks[VK_RCONTROL] & 0x80) && !key[KEY_RCONTROL])
|
||||||
|
vcode = VK_RCONTROL;
|
||||||
|
else if ((ks[VK_LSHIFT] & 0x80) && !key[KEY_LSHIFT])
|
||||||
|
vcode = VK_LSHIFT;
|
||||||
|
else if ((ks[VK_RSHIFT] & 0x80) && !key[KEY_RSHIFT])
|
||||||
|
vcode = VK_RSHIFT;
|
||||||
|
else if ((ks[VK_LMENU] & 0x80) && !key[KEY_ALT])
|
||||||
|
vcode = VK_LMENU;
|
||||||
|
else if ((ks[VK_RMENU] & 0x80) && !key[KEY_ALTGR])
|
||||||
|
vcode = VK_RMENU;
|
||||||
else
|
else
|
||||||
unicode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* When alt key is pressed, any key always must return ASCII 0 in Allegro. */
|
|
||||||
if (unicode > 0 && (keystate[VK_LMENU] & 0x80)) {
|
|
||||||
unicode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_handle_key_press(unicode, mycode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* handle_key_release: [input thread]
|
|
||||||
* Does stuff when a key is released. The keyboard event source
|
|
||||||
* should be locked.
|
|
||||||
*/
|
|
||||||
static void handle_key_release(unsigned char scancode)
|
|
||||||
{
|
|
||||||
int mycode = hw_to_mycode[scancode];
|
|
||||||
if (mycode == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
{
|
|
||||||
BYTE keystate[256];
|
|
||||||
GetKeyboardState(keystate);
|
|
||||||
update_shifts(keystate);
|
|
||||||
}
|
|
||||||
|
|
||||||
_handle_key_release(mycode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_dinput_handle_scancode: [input thread]
|
|
||||||
* Handles a single scancode.
|
|
||||||
*/
|
|
||||||
static void key_dinput_handle_scancode(unsigned char scancode, int pressed)
|
|
||||||
{
|
|
||||||
HWND allegro_wnd = win_get_window();
|
|
||||||
static int ignore_three_finger_flag = FALSE;
|
|
||||||
/* ignore special Windows keys (alt+tab, alt+space, (ctrl|alt)+esc) */
|
|
||||||
if (((scancode == DIK_TAB) && (_key_shifts & KB_ALT_FLAG))
|
|
||||||
|| ((scancode == DIK_SPACE) && (_key_shifts & KB_ALT_FLAG))
|
|
||||||
|| ((scancode == DIK_ESCAPE) && (_key_shifts & (KB_CTRL_FLAG | KB_ALT_FLAG))))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* alt+F4 triggers a WM_CLOSE under Windows */
|
|
||||||
if ((scancode == DIK_F4) && (_key_shifts & KB_ALT_FLAG)) {
|
|
||||||
if (pressed)
|
|
||||||
PostMessage(allegro_wnd, WM_CLOSE, 0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special case KEY_PAUSE as flip-flop key. */
|
|
||||||
if (scancode == DIK_PAUSE) {
|
|
||||||
if (!pressed)
|
|
||||||
return;
|
return;
|
||||||
if (key[KEY_PAUSE])
|
|
||||||
pressed = 0;
|
|
||||||
else
|
|
||||||
pressed = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if not foreground, filter out press codes and handle only release codes */
|
/* Ignore repeats for Caps Lock */
|
||||||
if (!wnd_sysmenu || !pressed) {
|
if (vcode == VK_CAPITAL && repeated && key[KEY_CAPSLOCK])
|
||||||
/* three-finger salute for killing the program */
|
return;
|
||||||
if (three_finger_flag && (_key_shifts & KB_CTRL_FLAG) && (_key_shifts & KB_ALT_FLAG)) {
|
|
||||||
if (scancode == 0x00) {
|
|
||||||
/* when pressing CTRL-ALT-DEL, Windows launches CTRL-ALT-EVERYTHING */
|
|
||||||
ignore_three_finger_flag = TRUE;
|
|
||||||
}
|
|
||||||
else if (!ignore_three_finger_flag && (scancode == DIK_END || scancode == DIK_NUMPAD1)) {
|
|
||||||
/* we can now safely assume the user hit CTRL-ALT-END as opposed to CTRL-ALT-DEL */
|
|
||||||
_TRACE(PREFIX_I "Terminating application\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
else if (ignore_three_finger_flag && scancode == 0xff) {
|
|
||||||
/* Windows is finished with CTRL-ALT-EVERYTHING - lets return to normality */
|
|
||||||
ignore_three_finger_flag = FALSE;
|
|
||||||
_key_shifts = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pressed)
|
my_code = hw_to_mycode[vcode];
|
||||||
handle_key_press(scancode);
|
update_shifts(ks);
|
||||||
else
|
|
||||||
handle_key_release(scancode);
|
_handle_key_press(ccode, my_code);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_dinput_handle: [input thread]
|
|
||||||
* Handles queued keyboard input.
|
/* _al_win_kbd_handle_key_release:
|
||||||
|
* Does stuff when a key is released.
|
||||||
*/
|
*/
|
||||||
static void key_dinput_handle(void)
|
void _al_win_kbd_handle_key_release(int vcode)
|
||||||
{
|
{
|
||||||
static DIDEVICEOBJECTDATA scancode_buffer[DINPUT_BUFFERSIZE];
|
int my_code;
|
||||||
unsigned long int waiting_scancodes;
|
BYTE ks[256];
|
||||||
HRESULT hr;
|
|
||||||
unsigned long int i;
|
|
||||||
|
|
||||||
/* the whole buffer is free */
|
/* We need to read the latest key states so we can tell which
|
||||||
waiting_scancodes = DINPUT_BUFFERSIZE;
|
modifier was released. */
|
||||||
|
GetKeyboardState(&ks[0]);
|
||||||
|
|
||||||
/* fill the buffer */
|
if (vcode == VK_SHIFT && key[KEY_LSHIFT] && !(ks[VK_LSHIFT] & 0x80))
|
||||||
hr = IDirectInputDevice_GetDeviceData(key_dinput_device,
|
vcode = VK_LSHIFT;
|
||||||
sizeof(DIDEVICEOBJECTDATA),
|
else if (vcode == VK_SHIFT && key[KEY_RSHIFT] && !(ks[VK_RSHIFT] & 0x80))
|
||||||
scancode_buffer,
|
vcode = VK_RSHIFT;
|
||||||
&waiting_scancodes,
|
else if (vcode == VK_CONTROL && key[KEY_LCONTROL] && !(ks[VK_LCONTROL] & 0x80))
|
||||||
0);
|
vcode = VK_LCONTROL;
|
||||||
|
else if (vcode == VK_CONTROL && key[KEY_RCONTROL] && !(ks[VK_RCONTROL] & 0x80))
|
||||||
|
vcode = VK_RCONTROL;
|
||||||
|
else if (vcode == VK_MENU && key[KEY_ALT] && !(ks[VK_LMENU] & 0x80))
|
||||||
|
vcode = VK_LMENU;
|
||||||
|
else if (vcode == VK_MENU && key[KEY_ALTGR] && !(ks[VK_RMENU] & 0x80))
|
||||||
|
vcode = VK_RMENU;
|
||||||
|
else if(vcode == VK_MENU)
|
||||||
|
return;
|
||||||
|
|
||||||
/* was device lost ? */
|
my_code = hw_to_mycode[vcode];
|
||||||
if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) {
|
update_shifts(ks);
|
||||||
/* 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);
|
_handle_key_release(my_code);
|
||||||
|
|
||||||
|
/* Windows only sends a WM_KEYUP message for the Shift keys when
|
||||||
|
both have been released. If one of the Shift keys is still reported
|
||||||
|
as down, we need to release it as well. */
|
||||||
|
if (my_code == KEY_LSHIFT && key[KEY_RSHIFT])
|
||||||
|
_al_win_kbd_handle_key_release(VK_RSHIFT);
|
||||||
|
else if (my_code == KEY_RSHIFT && key[KEY_LSHIFT])
|
||||||
|
_al_win_kbd_handle_key_release(VK_LSHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_dinput_acquire: [window thread]
|
static int key_winapi_init(void)
|
||||||
* 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 ks[256];
|
||||||
BYTE keystate[256];
|
GetKeyboardState(&ks[0]);
|
||||||
|
update_shifts(ks);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_dinput_unacquire: [window thread]
|
|
||||||
* Unacquires the keyboard device.
|
|
||||||
*/
|
|
||||||
int key_dinput_unacquire(void)
|
|
||||||
{
|
|
||||||
int key;
|
|
||||||
|
|
||||||
if (key_dinput_device) {
|
|
||||||
IDirectInputDevice_Unacquire(key_dinput_device);
|
|
||||||
|
|
||||||
/* release all keys */
|
|
||||||
for (key=0; key<256; key++)
|
|
||||||
if (key != KEY_PAUSE)
|
|
||||||
key_dinput_handle_scancode((unsigned char) key, FALSE);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_dinput_exit: [primary thread]
|
|
||||||
* Shuts down the DirectInput keyboard device.
|
|
||||||
*/
|
|
||||||
static int key_dinput_exit(void)
|
|
||||||
{
|
|
||||||
if (key_dinput_device) {
|
|
||||||
/* unregister event handler first */
|
|
||||||
_win_input_unregister_event(key_input_event);
|
|
||||||
|
|
||||||
/* unacquire device */
|
|
||||||
wnd_call_proc(key_dinput_unacquire);
|
|
||||||
|
|
||||||
/* now it can be released */
|
|
||||||
IDirectInputDevice_Release(key_dinput_device);
|
|
||||||
key_dinput_device = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* release DirectInput interface */
|
|
||||||
if (key_dinput) {
|
|
||||||
IDirectInput_Release(key_dinput);
|
|
||||||
key_dinput = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* close event handle */
|
|
||||||
if (key_input_event) {
|
|
||||||
CloseHandle(key_input_event);
|
|
||||||
key_input_event = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* get_reverse_mapping:
|
static void key_winapi_exit(void)
|
||||||
* Build a table that maps Allegro "scancodes" to arguments to
|
|
||||||
* GetKeyNameText() that will return the name of the key.
|
|
||||||
* The format of the argument is given in the MSDN library, e.g. the
|
|
||||||
* `lparam' argument for the WM_KEYDOWN message. Most importantly:
|
|
||||||
* bits 16-23:
|
|
||||||
* Specifies the scan code.
|
|
||||||
* bit 24:
|
|
||||||
* Specifies whether the key is an extended key, such as the right-hand
|
|
||||||
* ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard.
|
|
||||||
* The value is 1 if it is an extended key; otherwise, it is 0.
|
|
||||||
*
|
|
||||||
* We used to attempt to derive this table from `hw_to_mycode' but it is not
|
|
||||||
* straight forward. For example to get the name of the right Ctrl key we
|
|
||||||
* need to pass the same scancode as for the left Ctrl key, but with the
|
|
||||||
* extended key flag set. The values below come from printing out the
|
|
||||||
* value of the `lparam' argument for each WM_KEYDOWN message received.
|
|
||||||
* There is code in wwnd.c to help someone else do this for more keys.
|
|
||||||
*/
|
|
||||||
static void get_reverse_mapping(void)
|
|
||||||
{
|
{
|
||||||
#define REV reverse_mapping
|
/* Do nothing. */
|
||||||
|
|
||||||
REV[KEY_A] = 0x01E0000;
|
|
||||||
REV[KEY_B] = 0x0300000;
|
|
||||||
REV[KEY_C] = 0x02E0000;
|
|
||||||
REV[KEY_D] = 0x0200000;
|
|
||||||
REV[KEY_E] = 0x0120000;
|
|
||||||
REV[KEY_F] = 0x0210000;
|
|
||||||
REV[KEY_G] = 0x0220000;
|
|
||||||
REV[KEY_H] = 0x0230000;
|
|
||||||
REV[KEY_I] = 0x0170000;
|
|
||||||
REV[KEY_J] = 0x0240000;
|
|
||||||
REV[KEY_K] = 0x0250000;
|
|
||||||
REV[KEY_L] = 0x0260000;
|
|
||||||
REV[KEY_M] = 0x0320000;
|
|
||||||
REV[KEY_N] = 0x0310000;
|
|
||||||
REV[KEY_O] = 0x0180000;
|
|
||||||
REV[KEY_P] = 0x0190000;
|
|
||||||
REV[KEY_Q] = 0x0100000;
|
|
||||||
REV[KEY_R] = 0x0130000;
|
|
||||||
REV[KEY_S] = 0x01F0000;
|
|
||||||
REV[KEY_T] = 0x0140000;
|
|
||||||
REV[KEY_U] = 0x0160000;
|
|
||||||
REV[KEY_V] = 0x02F0000;
|
|
||||||
REV[KEY_W] = 0x0110000;
|
|
||||||
REV[KEY_X] = 0x02D0000;
|
|
||||||
REV[KEY_Y] = 0x0150000;
|
|
||||||
REV[KEY_Z] = 0x02C0000;
|
|
||||||
REV[KEY_0] = 0x00B0000;
|
|
||||||
REV[KEY_1] = 0x0020000;
|
|
||||||
REV[KEY_2] = 0x0030000;
|
|
||||||
REV[KEY_3] = 0x0040000;
|
|
||||||
REV[KEY_4] = 0x0050000;
|
|
||||||
REV[KEY_5] = 0x0060000;
|
|
||||||
REV[KEY_6] = 0x0070000;
|
|
||||||
REV[KEY_7] = 0x0080000;
|
|
||||||
REV[KEY_8] = 0x0090000;
|
|
||||||
REV[KEY_9] = 0x00A0000;
|
|
||||||
REV[KEY_0_PAD] = 0x0520000;
|
|
||||||
REV[KEY_1_PAD] = 0x04F0000;
|
|
||||||
REV[KEY_2_PAD] = 0x0500000;
|
|
||||||
REV[KEY_3_PAD] = 0x0510000;
|
|
||||||
REV[KEY_4_PAD] = 0x04B0000;
|
|
||||||
REV[KEY_5_PAD] = 0x04C0000;
|
|
||||||
REV[KEY_6_PAD] = 0x04D0000;
|
|
||||||
REV[KEY_7_PAD] = 0x0470000;
|
|
||||||
REV[KEY_8_PAD] = 0x0480000;
|
|
||||||
REV[KEY_9_PAD] = 0x0490000;
|
|
||||||
REV[KEY_F1] = 0x03B0000;
|
|
||||||
REV[KEY_F2] = 0x03C0000;
|
|
||||||
REV[KEY_F3] = 0x03D0000;
|
|
||||||
REV[KEY_F4] = 0x03E0000;
|
|
||||||
REV[KEY_F5] = 0x03F0000;
|
|
||||||
REV[KEY_F6] = 0x0400000;
|
|
||||||
REV[KEY_F7] = 0x0410000;
|
|
||||||
REV[KEY_F8] = 0x0420000;
|
|
||||||
REV[KEY_F9] = 0x0430000;
|
|
||||||
REV[KEY_F10] = 0x0440000;
|
|
||||||
REV[KEY_F11] = 0x0570000;
|
|
||||||
REV[KEY_F12] = 0x0580000;
|
|
||||||
REV[KEY_ESC] = 0x0010000;
|
|
||||||
REV[KEY_TILDE] = 0x0290000;
|
|
||||||
REV[KEY_MINUS] = 0x00C0000;
|
|
||||||
REV[KEY_EQUALS] = 0x00D0000;
|
|
||||||
REV[KEY_BACKSPACE] = 0x00E0000;
|
|
||||||
REV[KEY_TAB] = 0x00F0000;
|
|
||||||
REV[KEY_OPENBRACE] = 0x01A0000;
|
|
||||||
REV[KEY_CLOSEBRACE] = 0x01B0000;
|
|
||||||
REV[KEY_ENTER] = 0x01C0000;
|
|
||||||
REV[KEY_COLON] = 0x0270000;
|
|
||||||
REV[KEY_QUOTE] = 0x0280000;
|
|
||||||
REV[KEY_BACKSLASH] = 0x02B0000;
|
|
||||||
/* KEY_BACKSLASH2 */
|
|
||||||
REV[KEY_COMMA] = 0x0330000;
|
|
||||||
REV[KEY_STOP] = 0x0340000;
|
|
||||||
REV[KEY_SLASH] = 0x0350000;
|
|
||||||
REV[KEY_SPACE] = 0x0390000;
|
|
||||||
REV[KEY_INSERT] = 0x1520000;
|
|
||||||
REV[KEY_DEL] = 0x1530000;
|
|
||||||
REV[KEY_HOME] = 0x1470000;
|
|
||||||
REV[KEY_END] = 0x14F0000;
|
|
||||||
REV[KEY_PGUP] = 0x1490000;
|
|
||||||
REV[KEY_PGDN] = 0x1510000;
|
|
||||||
REV[KEY_LEFT] = 0x14B0000;
|
|
||||||
REV[KEY_RIGHT] = 0x14D0000;
|
|
||||||
REV[KEY_UP] = 0x1480000;
|
|
||||||
REV[KEY_DOWN] = 0x1500000;
|
|
||||||
REV[KEY_SLASH_PAD] = 0x1350000;
|
|
||||||
REV[KEY_ASTERISK] = 0x0370000;
|
|
||||||
REV[KEY_MINUS_PAD] = 0x04A0000;
|
|
||||||
REV[KEY_PLUS_PAD] = 0x04E0000;
|
|
||||||
REV[KEY_DEL_PAD] = 0x0530000;
|
|
||||||
REV[KEY_ENTER_PAD] = 0x11C0000;
|
|
||||||
/* XXX doesn't work
|
|
||||||
REV[KEY_PRTSCR] = 0x570000;
|
|
||||||
*/
|
|
||||||
REV[KEY_PAUSE] = 0x0450000;
|
|
||||||
/* XXX Japanese keys missing
|
|
||||||
REV[KEY_ABNT_C1] =
|
|
||||||
REV[KEY_YEN] =
|
|
||||||
REV[KEY_KANA] =
|
|
||||||
REV[KEY_CONVERT] =
|
|
||||||
REV[KEY_NOCONVERT] =
|
|
||||||
REV[KEY_AT] =
|
|
||||||
REV[KEY_CIRCUMFLEX] =
|
|
||||||
REV[KEY_COLON2] =
|
|
||||||
REV[KEY_KANJI] =
|
|
||||||
*/
|
|
||||||
|
|
||||||
REV[KEY_LSHIFT] = 0x02A0000;
|
|
||||||
REV[KEY_RSHIFT] = 0x0360000;
|
|
||||||
REV[KEY_LCONTROL] = 0x01D0000;
|
|
||||||
REV[KEY_RCONTROL] = 0x11D0000;
|
|
||||||
REV[KEY_ALT] = 0x0380000;
|
|
||||||
REV[KEY_ALTGR] = 0x1380000;
|
|
||||||
REV[KEY_LWIN] = 0x15B0000;
|
|
||||||
REV[KEY_RWIN] = 0x15C0000;
|
|
||||||
REV[KEY_MENU] = 0x15D0000;
|
|
||||||
REV[KEY_SCRLOCK] = 0x0460000;
|
|
||||||
REV[KEY_NUMLOCK] = 0x1450000;
|
|
||||||
REV[KEY_CAPSLOCK] = 0x03A0000;
|
|
||||||
|
|
||||||
#undef REV
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_dinput_init: [primary thread]
|
#define KEYBOARD_WINAPI AL_ID('W','A','P','I')
|
||||||
* Sets up the DirectInput keyboard device.
|
|
||||||
*/
|
static KEYBOARD_DRIVER keyboard_winapi =
|
||||||
static int key_dinput_init(void)
|
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
KEYBOARD_WINAPI,
|
||||||
HWND allegro_wnd = win_get_window();
|
|
||||||
DIPROPDWORD property_buf_size =
|
|
||||||
{
|
|
||||||
/* the header */
|
|
||||||
{
|
|
||||||
sizeof(DIPROPDWORD), // diph.dwSize
|
|
||||||
sizeof(DIPROPHEADER), // diph.dwHeaderSize
|
|
||||||
0, // diph.dwObj
|
|
||||||
DIPH_DEVICE, // diph.dwHow
|
|
||||||
},
|
|
||||||
|
|
||||||
/* the data */
|
|
||||||
DINPUT_BUFFERSIZE, // dwData
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Get DirectInput interface */
|
|
||||||
hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput, &key_dinput);
|
|
||||||
if (FAILED(hr))
|
|
||||||
goto Error;
|
|
||||||
|
|
||||||
hr = IDirectInput_Initialize(key_dinput, allegro_inst, DIRECTINPUT_VERSION);
|
|
||||||
if (FAILED(hr))
|
|
||||||
goto Error;
|
|
||||||
|
|
||||||
/* Create the keyboard device */
|
|
||||||
hr = IDirectInput_CreateDevice(key_dinput, &GUID_SysKeyboard, &key_dinput_device, NULL);
|
|
||||||
if (FAILED(hr))
|
|
||||||
goto Error;
|
|
||||||
|
|
||||||
/* Set data format */
|
|
||||||
hr = IDirectInputDevice_SetDataFormat(key_dinput_device, &c_dfDIKeyboard);
|
|
||||||
if (FAILED(hr))
|
|
||||||
goto Error;
|
|
||||||
|
|
||||||
/* Set buffer size */
|
|
||||||
hr = IDirectInputDevice_SetProperty(key_dinput_device, DIPROP_BUFFERSIZE, &property_buf_size.diph);
|
|
||||||
if (FAILED(hr))
|
|
||||||
goto Error;
|
|
||||||
|
|
||||||
/* Set cooperative level */
|
|
||||||
hr = IDirectInputDevice_SetCooperativeLevel(key_dinput_device, allegro_wnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
|
||||||
if (FAILED(hr))
|
|
||||||
goto Error;
|
|
||||||
|
|
||||||
/* Enable event notification */
|
|
||||||
key_input_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
||||||
hr = IDirectInputDevice_SetEventNotification(key_dinput_device, key_input_event);
|
|
||||||
if (FAILED(hr))
|
|
||||||
goto Error;
|
|
||||||
|
|
||||||
/* Register event handler */
|
|
||||||
if (_win_input_register_event(key_input_event, key_dinput_handle) != 0)
|
|
||||||
goto Error;
|
|
||||||
|
|
||||||
get_reverse_mapping();
|
|
||||||
|
|
||||||
/* Acquire the device */
|
|
||||||
wnd_call_proc(key_dinput_acquire);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Error:
|
|
||||||
key_dinput_exit();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_directx_init: [primary thread]
|
|
||||||
*/
|
|
||||||
static int key_directx_init(void)
|
|
||||||
{
|
|
||||||
/* keyboard input is handled by the window thread */
|
|
||||||
key_input_processed_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
||||||
|
|
||||||
if (key_dinput_init() != 0) {
|
|
||||||
/* something has gone wrong */
|
|
||||||
_TRACE(PREFIX_E "keyboard handler init failed\n");
|
|
||||||
CloseHandle(key_input_processed_event);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the keyboard handler has successfully set up */
|
|
||||||
_TRACE(PREFIX_I "keyboard handler starts\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_directx_exit: [primary thread]
|
|
||||||
*/
|
|
||||||
static void key_directx_exit(void)
|
|
||||||
{
|
|
||||||
if (key_dinput_device) {
|
|
||||||
/* command keyboard handler shutdown */
|
|
||||||
_TRACE(PREFIX_I "keyboard handler exits\n");
|
|
||||||
key_dinput_exit();
|
|
||||||
|
|
||||||
/* now we can free all resources */
|
|
||||||
CloseHandle(key_input_processed_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* key_directx_wait_for_input: [primary thread]
|
|
||||||
*/
|
|
||||||
static void key_directx_wait_for_input(void)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(key_input_processed_event, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* static void key_directx_stop_wait: [primary thread]
|
|
||||||
*/
|
|
||||||
static void key_directx_stop_wait(void)
|
|
||||||
{
|
|
||||||
SetEvent(key_input_processed_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* scancode_to_name:
|
|
||||||
* Converts the given scancode to a description of the key.
|
|
||||||
*/
|
|
||||||
static AL_CONST char *key_directx_scancode_to_name(const int scancode)
|
|
||||||
{
|
|
||||||
static char name[256];
|
|
||||||
TCHAR str[256];
|
|
||||||
WCHAR wstr[256];
|
|
||||||
|
|
||||||
ASSERT(scancode >= 0 && scancode < KEY_MAX);
|
|
||||||
|
|
||||||
if (GetKeyNameText(reverse_mapping[scancode], str, sizeof str)) {
|
|
||||||
/* let Windows translate from the current encoding into UTF16 */
|
|
||||||
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, sizeof wstr);
|
|
||||||
/* translate from utf16 to Allegro's current encoding */
|
|
||||||
uconvert((char *)wstr, U_UNICODE, name, U_CURRENT, sizeof name);
|
|
||||||
/* why oh why doesn't everybody just use UTF8/16 */
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return _keyboard_common_names[scancode];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static KEYBOARD_DRIVER keyboard_directx =
|
|
||||||
{
|
|
||||||
KEYBOARD_DIRECTX,
|
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"DirectInput keyboard",
|
"WinAPI keyboard",
|
||||||
1,
|
1,
|
||||||
key_directx_init,
|
key_winapi_init,
|
||||||
key_directx_exit,
|
key_winapi_exit,
|
||||||
NULL, NULL, NULL,
|
|
||||||
key_directx_wait_for_input,
|
|
||||||
key_directx_stop_wait,
|
|
||||||
NULL,
|
NULL,
|
||||||
key_directx_scancode_to_name
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_DRIVER_INFO _keyboard_driver_list[] =
|
_DRIVER_INFO _keyboard_driver_list[] =
|
||||||
{
|
{
|
||||||
{KEYBOARD_DIRECTX, &keyboard_directx, TRUE},
|
{KEYBOARD_WINAPI, &keyboard_winapi, TRUE},
|
||||||
{0, NULL, 0}
|
{0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
@ -349,8 +349,6 @@ static void sys_directx_save_console_state(void)
|
|||||||
static void sys_directx_restore_console_state(void)
|
static void sys_directx_restore_console_state(void)
|
||||||
{
|
{
|
||||||
HWND allegro_wnd = win_get_window();
|
HWND allegro_wnd = win_get_window();
|
||||||
/* unacquire input devices */
|
|
||||||
wnd_schedule_proc(key_dinput_unacquire);
|
|
||||||
|
|
||||||
/* reset switch mode */
|
/* reset switch mode */
|
||||||
_win_reset_switch_mode();
|
_win_reset_switch_mode();
|
||||||
|
@ -95,6 +95,9 @@ void _al_win_mouse_handle_button(HWND hwnd, int button, BOOL down, int x, int y,
|
|||||||
void _al_win_mouse_handle_wheel(HWND hwnd, int z, BOOL abs);
|
void _al_win_mouse_handle_wheel(HWND hwnd, int z, BOOL abs);
|
||||||
void _al_win_mouse_handle_move(HWND hwnd, int x, int y);
|
void _al_win_mouse_handle_move(HWND hwnd, int x, int y);
|
||||||
|
|
||||||
|
/* In wkeybd.c */
|
||||||
|
void _al_win_kbd_handle_key_press(int scode, int vcode, BOOL repeated);
|
||||||
|
void _al_win_kbd_handle_key_release(int vcode);
|
||||||
|
|
||||||
|
|
||||||
/* init_window_modules:
|
/* init_window_modules:
|
||||||
@ -185,18 +188,6 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See get_reverse_mapping() in wkeybd.c to see what this is for. */
|
|
||||||
if (FALSE && (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)) {
|
|
||||||
static char name[256];
|
|
||||||
TCHAR str[256];
|
|
||||||
WCHAR wstr[256];
|
|
||||||
|
|
||||||
GetKeyNameText(lparam, str, sizeof str);
|
|
||||||
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, sizeof wstr);
|
|
||||||
uconvert((char *)wstr, U_UNICODE, name, U_CURRENT, sizeof name);
|
|
||||||
_TRACE(PREFIX_I" key[%s] = 0x%08lx;\n", name, lparam & 0x1ff0000);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
|
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
@ -294,17 +285,6 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_KEYDOWN:
|
|
||||||
case WM_KEYUP:
|
|
||||||
case WM_SYSKEYDOWN:
|
|
||||||
case WM_SYSKEYUP:
|
|
||||||
/* Disable the default message-based key handler
|
|
||||||
* in order to prevent conflicts on NT kernels.
|
|
||||||
*/
|
|
||||||
if (!user_wnd_proc || _keyboard_installed)
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_SYSCOMMAND:
|
case WM_SYSCOMMAND:
|
||||||
if (wparam == SC_MONITORPOWER || wparam == SC_SCREENSAVE) {
|
if (wparam == SC_MONITORPOWER || wparam == SC_SCREENSAVE) {
|
||||||
if (_screensaver_policy == ALWAYS_DISABLED
|
if (_screensaver_policy == ALWAYS_DISABLED
|
||||||
@ -393,6 +373,30 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_SYSKEYDOWN: {
|
||||||
|
int vcode = wparam;
|
||||||
|
BOOL repeated = (lparam >> 30) & 0x1;
|
||||||
|
_al_win_kbd_handle_key_press(0, vcode, repeated);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_KEYDOWN: {
|
||||||
|
int vcode = wparam;
|
||||||
|
int scode = (lparam >> 16) & 0xff;
|
||||||
|
BOOL repeated = (lparam >> 30) & 0x1;
|
||||||
|
/* We can't use TranslateMessage() because we don't know if it will
|
||||||
|
produce a WM_CHAR or not. */
|
||||||
|
_al_win_kbd_handle_key_press(scode, vcode, repeated);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_SYSKEYUP:
|
||||||
|
case WM_KEYUP: {
|
||||||
|
int vcode = wparam;
|
||||||
|
_al_win_kbd_handle_key_release(vcode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pass message to default window proc */
|
/* pass message to default window proc */
|
||||||
@ -786,13 +790,3 @@ void win_set_wnd_create_proc(HWND (*proc)(WNDPROC))
|
|||||||
{
|
{
|
||||||
wnd_create_proc = proc;
|
wnd_create_proc = proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* win_grab_input:
|
|
||||||
* Grabs the input devices.
|
|
||||||
*/
|
|
||||||
void win_grab_input(void)
|
|
||||||
{
|
|
||||||
wnd_schedule_proc(key_dinput_acquire);
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user