mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-29 12:32:52 +00:00
Modify Allegro to use WM_MOUSEMOVE instead of DirectInput in the Windows mouse driver.
This commit is contained in:
parent
094f0b6e8f
commit
57b54ad050
@ -1,4 +1,6 @@
|
||||
This is a modified version of Allegro library (branch 4.4) specially
|
||||
patched for ASE.
|
||||
patched for ASE by David Capello.
|
||||
|
||||
- David Capello
|
||||
Changes:
|
||||
- Mouse driver for Windows was modified to use WM_MOUSEMOVE instead of
|
||||
DirectInput (like in Allegro 5).
|
||||
|
@ -127,11 +127,7 @@ AL_FUNC(int, key_dinput_unacquire, (void));
|
||||
|
||||
/* mouse routines */
|
||||
AL_VAR(HCURSOR, _win_hcursor);
|
||||
AL_FUNC(int, mouse_dinput_acquire, (void));
|
||||
AL_FUNC(int, mouse_dinput_unacquire, (void));
|
||||
AL_FUNC(int, mouse_dinput_grab, (void));
|
||||
AL_FUNC(int, mouse_set_syscursor, (void));
|
||||
AL_FUNC(int, mouse_set_sysmenu, (int state));
|
||||
|
||||
|
||||
/* thread routines */
|
||||
|
@ -84,13 +84,6 @@ AL_VAR(SYSTEM_DRIVER, system_directx);
|
||||
|
||||
|
||||
|
||||
/*******************************************/
|
||||
/************* mouse drivers ***************/
|
||||
/*******************************************/
|
||||
#define MOUSE_DIRECTX AL_ID('D','X',' ',' ')
|
||||
|
||||
|
||||
|
||||
/*******************************************/
|
||||
/*************** gfx drivers ***************/
|
||||
/*******************************************/
|
||||
|
@ -114,7 +114,6 @@ void _win_switch_in(void)
|
||||
_win_app_foreground = TRUE;
|
||||
|
||||
key_dinput_acquire();
|
||||
mouse_dinput_acquire();
|
||||
|
||||
if (win_gfx_driver && win_gfx_driver->switch_in)
|
||||
win_gfx_driver->switch_in();
|
||||
@ -147,7 +146,6 @@ void _win_switch_out(void)
|
||||
_win_app_foreground = FALSE;
|
||||
|
||||
key_dinput_unacquire();
|
||||
mouse_dinput_unacquire();
|
||||
|
||||
if (win_gfx_driver && win_gfx_driver->switch_out)
|
||||
win_gfx_driver->switch_out();
|
||||
|
@ -1,32 +1,15 @@
|
||||
/* ______ ___ ___
|
||||
* /\ _ \ /\_ \ /\_ \
|
||||
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
|
||||
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
|
||||
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
|
||||
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
|
||||
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
|
||||
* /\____/
|
||||
* \_/__/
|
||||
*
|
||||
* Windows mouse driver.
|
||||
*
|
||||
* By Stefan Schimanski.
|
||||
*
|
||||
* See readme.txt for copyright information.
|
||||
*/
|
||||
/*
|
||||
Mouse driver for ASE
|
||||
by David Capello
|
||||
|
||||
Based on code of Stefan Schimanski and Milan Mimica.
|
||||
*/
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0300
|
||||
|
||||
#include "allegro.h"
|
||||
#include "allegro/internal/aintern.h"
|
||||
#include "allegro/platform/aintwin.h"
|
||||
|
||||
#ifndef SCAN_DEPEND
|
||||
#include <process.h>
|
||||
#include <dinput.h>
|
||||
#endif
|
||||
|
||||
#ifndef ALLEGRO_WINDOWS
|
||||
#error something is wrong with the makefile
|
||||
#endif
|
||||
@ -36,73 +19,56 @@
|
||||
#define PREFIX_E "al-wmouse ERROR: "
|
||||
|
||||
|
||||
static MOUSE_DRIVER mouse_directx;
|
||||
static MOUSE_DRIVER mouse_winapi;
|
||||
|
||||
|
||||
#define MOUSE_WINAPI AL_ID('W','A','P','I')
|
||||
|
||||
|
||||
_DRIVER_INFO _mouse_driver_list[] =
|
||||
{
|
||||
{MOUSE_DIRECTX, &mouse_directx, TRUE},
|
||||
{MOUSE_WINAPI, &mouse_winapi, TRUE},
|
||||
{MOUSEDRV_NONE, &mousedrv_none, TRUE},
|
||||
{0, NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
static int mouse_directx_init(void);
|
||||
static void mouse_directx_exit(void);
|
||||
static void mouse_directx_position(int x, int y);
|
||||
static void mouse_directx_set_range(int x1, int y1, int x2, int y2);
|
||||
static void mouse_directx_set_speed(int xspeed, int yspeed);
|
||||
static void mouse_directx_get_mickeys(int *mickeyx, int *mickeyy);
|
||||
static void mouse_directx_enable_hardware_cursor(int mode);
|
||||
static int mouse_directx_select_system_cursor(int cursor);
|
||||
static int mouse_winapi_init(void);
|
||||
static void mouse_winapi_exit(void);
|
||||
static void mouse_winapi_position(int x, int y);
|
||||
static void mouse_winapi_set_range(int x1, int y1, int x2, int y2);
|
||||
static void mouse_winapi_set_speed(int xspeed, int yspeed);
|
||||
static void mouse_winapi_get_mickeys(int *mickeyx, int *mickeyy);
|
||||
static void mouse_winapi_enable_hardware_cursor(int mode);
|
||||
static int mouse_winapi_select_system_cursor(int cursor);
|
||||
|
||||
static MOUSE_DRIVER mouse_directx =
|
||||
|
||||
#define MOUSE_WINAPI AL_ID('W','A','P','I')
|
||||
|
||||
|
||||
static MOUSE_DRIVER mouse_winapi =
|
||||
{
|
||||
MOUSE_DIRECTX,
|
||||
MOUSE_WINAPI,
|
||||
empty_string,
|
||||
empty_string,
|
||||
"DirectInput mouse",
|
||||
mouse_directx_init,
|
||||
mouse_directx_exit,
|
||||
"WinAPI mouse",
|
||||
mouse_winapi_init,
|
||||
mouse_winapi_exit,
|
||||
NULL, // AL_METHOD(void, poll, (void));
|
||||
NULL, // AL_METHOD(void, timer_poll, (void));
|
||||
mouse_directx_position,
|
||||
mouse_directx_set_range,
|
||||
mouse_directx_set_speed,
|
||||
mouse_directx_get_mickeys,
|
||||
mouse_winapi_position,
|
||||
mouse_winapi_set_range,
|
||||
mouse_winapi_set_speed,
|
||||
mouse_winapi_get_mickeys,
|
||||
NULL, // AL_METHOD(int, analyse_data, (AL_CONST char *buffer, int size));
|
||||
mouse_directx_enable_hardware_cursor,
|
||||
mouse_directx_select_system_cursor
|
||||
mouse_winapi_enable_hardware_cursor,
|
||||
mouse_winapi_select_system_cursor
|
||||
};
|
||||
|
||||
|
||||
HCURSOR _win_hcursor = NULL; /* Hardware cursor to display */
|
||||
|
||||
|
||||
#define DINPUT_BUFFERSIZE 256
|
||||
static HANDLE mouse_input_event = NULL;
|
||||
static LPDIRECTINPUT mouse_dinput = NULL;
|
||||
static LPDIRECTINPUTDEVICE mouse_dinput_device = NULL;
|
||||
|
||||
static int dinput_buttons = 0;
|
||||
static int dinput_wheel = FALSE;
|
||||
|
||||
static int mouse_swap_button = FALSE; /* TRUE means buttons 1 and 2 are swapped */
|
||||
|
||||
static int dinput_x = 0; /* tracked dinput positon */
|
||||
static int dinput_y = 0;
|
||||
|
||||
static int mouse_mx = 0; /* internal position, in mickeys */
|
||||
static int mouse_my = 0;
|
||||
|
||||
static int mouse_sx = 2; /* mickey -> pixel scaling factor */
|
||||
static int mouse_sy = 2;
|
||||
|
||||
#define MAF_DEFAULT 1 /* mouse acceleration parameters */
|
||||
static int mouse_accel_fact = MAF_DEFAULT;
|
||||
static int mouse_accel_mult = MAF_DEFAULT;
|
||||
static int mouse_accel_thr1 = 5 * 5;
|
||||
static int mouse_accel_thr2 = 16 * 16;
|
||||
|
||||
static int mouse_minx = 0; /* mouse range */
|
||||
static int mouse_miny = 0;
|
||||
@ -114,12 +80,6 @@ static int mymickey_y = 0;
|
||||
static int mymickey_ox = 0;
|
||||
static int mymickey_oy = 0;
|
||||
|
||||
#define MICKEY_TO_COORD_X(n) ((n) / mouse_sx)
|
||||
#define MICKEY_TO_COORD_Y(n) ((n) / mouse_sy)
|
||||
|
||||
#define COORD_TO_MICKEY_X(n) ((n) * mouse_sx)
|
||||
#define COORD_TO_MICKEY_Y(n) ((n) * mouse_sy)
|
||||
|
||||
#define CLEAR_MICKEYS() \
|
||||
{ \
|
||||
if (gfx_driver && gfx_driver->windowed) { \
|
||||
@ -134,358 +94,11 @@ static int mymickey_oy = 0;
|
||||
mymickey_oy = p.y; \
|
||||
} \
|
||||
else { \
|
||||
dinput_x = 0; \
|
||||
dinput_y = 0; \
|
||||
mymickey_ox = 0; \
|
||||
mymickey_oy = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define READ_CURSOR_POS(p) \
|
||||
{ \
|
||||
GetCursorPos(&p); \
|
||||
\
|
||||
p.x -= wnd_x; \
|
||||
p.y -= wnd_y; \
|
||||
\
|
||||
if ((p.x < mouse_minx) || (p.x > mouse_maxx) || \
|
||||
(p.y < mouse_miny) || (p.y > mouse_maxy)) { \
|
||||
if (_mouse_on) { \
|
||||
_mouse_on = FALSE; \
|
||||
wnd_schedule_proc(mouse_set_syscursor); \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
if (!_mouse_on) { \
|
||||
_mouse_on = TRUE; \
|
||||
wnd_schedule_proc(mouse_set_syscursor); \
|
||||
} \
|
||||
_mouse_x = p.x; \
|
||||
_mouse_y = p.y; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* dinput_err_str:
|
||||
* Returns a DirectInput error string.
|
||||
*/
|
||||
#ifdef DEBUGMODE
|
||||
static char* dinput_err_str(long err)
|
||||
{
|
||||
static char err_str[64];
|
||||
|
||||
switch (err) {
|
||||
|
||||
case DIERR_ACQUIRED:
|
||||
_al_sane_strncpy(err_str, "the device is acquired", sizeof(err_str));
|
||||
break;
|
||||
|
||||
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 not granted", 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
|
||||
|
||||
|
||||
|
||||
/* mouse_dinput_handle_event: [input thread]
|
||||
* Handles a single event.
|
||||
*/
|
||||
static void mouse_dinput_handle_event(int ofs, int data)
|
||||
{
|
||||
static int last_data_x = 0;
|
||||
static int last_data_y = 0;
|
||||
static int last_was_x = 0;
|
||||
int mag;
|
||||
|
||||
switch (ofs) {
|
||||
|
||||
case DIMOFS_X:
|
||||
if (!gfx_driver || !gfx_driver->windowed) {
|
||||
if (last_was_x)
|
||||
last_data_y = 0;
|
||||
last_data_x = data;
|
||||
last_was_x = 1;
|
||||
if (mouse_accel_mult) {
|
||||
mag = last_data_x*last_data_x + last_data_y*last_data_y;
|
||||
if (mag >= mouse_accel_thr2)
|
||||
data *= (mouse_accel_mult<<1);
|
||||
else if (mag >= mouse_accel_thr1)
|
||||
data *= mouse_accel_mult;
|
||||
}
|
||||
|
||||
dinput_x += data;
|
||||
}
|
||||
break;
|
||||
|
||||
case DIMOFS_Y:
|
||||
if (!gfx_driver || !gfx_driver->windowed) {
|
||||
if (!last_was_x)
|
||||
last_data_x = 0;
|
||||
last_data_y = data;
|
||||
last_was_x = 0;
|
||||
if (mouse_accel_mult) {
|
||||
mag = last_data_x*last_data_x + last_data_y*last_data_y;
|
||||
if (mag >= mouse_accel_thr2)
|
||||
data *= (mouse_accel_mult<<1);
|
||||
else if (mag >= mouse_accel_thr1)
|
||||
data *= mouse_accel_mult;
|
||||
}
|
||||
|
||||
dinput_y += data;
|
||||
}
|
||||
break;
|
||||
|
||||
case DIMOFS_Z:
|
||||
if (dinput_wheel && _mouse_on)
|
||||
_mouse_z += data/120;
|
||||
break;
|
||||
|
||||
case DIMOFS_BUTTON0:
|
||||
if (data & 0x80) {
|
||||
if (_mouse_on)
|
||||
_mouse_b |= (mouse_swap_button ? 2 : 1);
|
||||
}
|
||||
else
|
||||
_mouse_b &= ~(mouse_swap_button ? 2 : 1);
|
||||
break;
|
||||
|
||||
case DIMOFS_BUTTON1:
|
||||
if (data & 0x80) {
|
||||
if (_mouse_on)
|
||||
_mouse_b |= (mouse_swap_button ? 1 : 2);
|
||||
}
|
||||
else
|
||||
_mouse_b &= ~(mouse_swap_button ? 1 : 2);
|
||||
break;
|
||||
|
||||
case DIMOFS_BUTTON2:
|
||||
if (data & 0x80) {
|
||||
if (_mouse_on)
|
||||
_mouse_b |= 4;
|
||||
}
|
||||
else
|
||||
_mouse_b &= ~4;
|
||||
break;
|
||||
|
||||
case DIMOFS_BUTTON3:
|
||||
if (data & 0x80) {
|
||||
if (_mouse_on)
|
||||
_mouse_b |= 8;
|
||||
}
|
||||
else
|
||||
_mouse_b &= ~8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_dinput_handle: [input thread]
|
||||
* Handles queued mouse input.
|
||||
*/
|
||||
static void mouse_dinput_handle(void)
|
||||
{
|
||||
static DIDEVICEOBJECTDATA message_buffer[DINPUT_BUFFERSIZE];
|
||||
unsigned long int waiting_messages;
|
||||
HRESULT hr;
|
||||
unsigned long 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 = CLAMP(mouse_minx, _mouse_x, mouse_maxx);
|
||||
_mouse_y = CLAMP(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_dinput_unacquire: [window thread]
|
||||
* Unacquires the mouse device.
|
||||
*/
|
||||
int mouse_dinput_unacquire(void)
|
||||
{
|
||||
if (mouse_dinput_device) {
|
||||
IDirectInputDevice_Unacquire(mouse_dinput_device);
|
||||
|
||||
_mouse_b = 0;
|
||||
_mouse_on = FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_set_syscursor: [window thread]
|
||||
@ -493,12 +106,8 @@ int mouse_dinput_grab(void)
|
||||
*/
|
||||
int mouse_set_syscursor(void)
|
||||
{
|
||||
HWND allegro_wnd = win_get_window();
|
||||
if ((mouse_dinput_device && _mouse_on) || (gfx_driver && !gfx_driver->windowed)) {
|
||||
if (_mouse_on || (gfx_driver && !gfx_driver->windowed))
|
||||
SetCursor(_win_hcursor);
|
||||
/* Make sure the cursor is removed by the system. */
|
||||
PostMessage(allegro_wnd, WM_MOUSEMOVE, 0, 0);
|
||||
}
|
||||
else
|
||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||
|
||||
@ -507,211 +116,32 @@ int mouse_set_syscursor(void)
|
||||
|
||||
|
||||
|
||||
/* mouse_set_sysmenu: [window thread]
|
||||
* Changes the state of the mouse when going to/from sysmenu mode.
|
||||
*/
|
||||
int mouse_set_sysmenu(int state)
|
||||
static int mouse_winapi_init(void)
|
||||
{
|
||||
POINT p;
|
||||
|
||||
if (mouse_dinput_device) {
|
||||
if (state == TRUE) {
|
||||
if (_mouse_on) {
|
||||
_mouse_on = FALSE;
|
||||
mouse_set_syscursor();
|
||||
}
|
||||
}
|
||||
else {
|
||||
READ_CURSOR_POS(p);
|
||||
}
|
||||
|
||||
_handle_mouse_input();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_enum_callback: [primary thread]
|
||||
* Helper function for finding out how many buttons we have.
|
||||
*/
|
||||
static BOOL CALLBACK mouse_enum_callback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
|
||||
{
|
||||
if (memcmp(&lpddoi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
|
||||
dinput_wheel = TRUE;
|
||||
else if (memcmp(&lpddoi->guidType, &GUID_Button, sizeof(GUID)) == 0)
|
||||
dinput_buttons++;
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_dinput_init: [primary thread]
|
||||
* Sets up the DirectInput mouse device.
|
||||
*/
|
||||
static int mouse_dinput_init(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
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, &mouse_dinput);
|
||||
if (FAILED(hr))
|
||||
goto Error;
|
||||
|
||||
hr = IDirectInput_Initialize(mouse_dinput, allegro_inst, DIRECTINPUT_VERSION);
|
||||
if (FAILED(hr))
|
||||
goto Error;
|
||||
|
||||
/* Create the mouse device */
|
||||
hr = IDirectInput_CreateDevice(mouse_dinput, &GUID_SysMouse, &mouse_dinput_device, NULL);
|
||||
if (FAILED(hr))
|
||||
goto Error;
|
||||
|
||||
/* Find how many buttons */
|
||||
dinput_buttons = 0;
|
||||
dinput_wheel = FALSE;
|
||||
|
||||
hr = IDirectInputDevice_EnumObjects(mouse_dinput_device, mouse_enum_callback, NULL, DIDFT_PSHBUTTON | DIDFT_AXIS);
|
||||
if (FAILED(hr))
|
||||
goto Error;
|
||||
|
||||
/* Check to see if the buttons are swapped (left-hand) */
|
||||
mouse_swap_button = GetSystemMetrics(SM_SWAPBUTTON);
|
||||
|
||||
/* Set data format */
|
||||
hr = IDirectInputDevice_SetDataFormat(mouse_dinput_device, &c_dfDIMouse);
|
||||
if (FAILED(hr))
|
||||
goto Error;
|
||||
|
||||
/* Set buffer size */
|
||||
hr = IDirectInputDevice_SetProperty(mouse_dinput_device, DIPROP_BUFFERSIZE, &property_buf_size.diph);
|
||||
if (FAILED(hr))
|
||||
goto Error;
|
||||
|
||||
/* Enable event notification */
|
||||
mouse_input_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
hr = IDirectInputDevice_SetEventNotification(mouse_dinput_device, mouse_input_event);
|
||||
if (FAILED(hr))
|
||||
goto Error;
|
||||
|
||||
/* Register event handler */
|
||||
if (_win_input_register_event(mouse_input_event, mouse_dinput_handle) != 0)
|
||||
goto Error;
|
||||
|
||||
/* Grab the device */
|
||||
_mouse_on = TRUE;
|
||||
wnd_call_proc(mouse_dinput_grab);
|
||||
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
mouse_dinput_exit();
|
||||
return -1;
|
||||
/* Returns the number of buttons available. */
|
||||
return GetSystemMetrics(SM_CMOUSEBUTTONS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_directx_init: [primary thread]
|
||||
*/
|
||||
static int mouse_directx_init(void)
|
||||
static void mouse_winapi_exit(void)
|
||||
{
|
||||
char tmp1[64], tmp2[128];
|
||||
|
||||
/* get user acceleration factor */
|
||||
mouse_accel_fact = get_config_int(uconvert_ascii("mouse", tmp1),
|
||||
uconvert_ascii("mouse_accel_factor", tmp2),
|
||||
MAF_DEFAULT);
|
||||
|
||||
if (mouse_dinput_init() != 0) {
|
||||
/* something has gone wrong */
|
||||
_TRACE(PREFIX_E "mouse handler init failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* the mouse handler has successfully set up */
|
||||
_TRACE(PREFIX_I "mouse handler starts\n");
|
||||
return dinput_buttons;
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_directx_exit: [primary thread]
|
||||
/* mouse_winapi_position: [primary thread]
|
||||
*/
|
||||
static void mouse_directx_exit(void)
|
||||
{
|
||||
if (mouse_dinput_device) {
|
||||
/* command mouse handler shutdown */
|
||||
_TRACE(PREFIX_I "mouse handler exits\n");
|
||||
mouse_dinput_exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_directx_position: [primary thread]
|
||||
*/
|
||||
static void mouse_directx_position(int x, int y)
|
||||
static void mouse_winapi_position(int x, int y)
|
||||
{
|
||||
_enter_critical();
|
||||
|
||||
_mouse_x = x;
|
||||
_mouse_y = y;
|
||||
|
||||
mouse_mx = COORD_TO_MICKEY_X(x);
|
||||
mouse_my = COORD_TO_MICKEY_Y(y);
|
||||
|
||||
if (gfx_driver && gfx_driver->windowed)
|
||||
SetCursorPos(x+wnd_x, y+wnd_y);
|
||||
|
||||
@ -719,17 +149,14 @@ static void mouse_directx_position(int x, int y)
|
||||
|
||||
mymickey_x = mymickey_y = 0;
|
||||
|
||||
/* force mouse update */
|
||||
SetEvent(mouse_input_event);
|
||||
|
||||
_exit_critical();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_directx_set_range: [primary thread]
|
||||
/* mouse_winapi_set_range: [primary thread]
|
||||
*/
|
||||
static void mouse_directx_set_range(int x1, int y1, int x2, int y2)
|
||||
static void mouse_winapi_set_range(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
mouse_minx = x1;
|
||||
mouse_miny = y1;
|
||||
@ -741,31 +168,19 @@ static void mouse_directx_set_range(int x1, int y1, int x2, int y2)
|
||||
_mouse_x = CLAMP(mouse_minx, _mouse_x, mouse_maxx);
|
||||
_mouse_y = CLAMP(mouse_miny, _mouse_y, mouse_maxy);
|
||||
|
||||
mouse_mx = COORD_TO_MICKEY_X(_mouse_x);
|
||||
mouse_my = COORD_TO_MICKEY_Y(_mouse_y);
|
||||
|
||||
CLEAR_MICKEYS();
|
||||
|
||||
_exit_critical();
|
||||
|
||||
/* scale up the acceleration multiplier to the range */
|
||||
mouse_accel_mult = mouse_accel_fact * MAX(x2-x1+1, y2-y1+1)/320;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_directx_set_speed: [primary thread]
|
||||
/* mouse_winapi_set_speed: [primary thread]
|
||||
*/
|
||||
static void mouse_directx_set_speed(int xspeed, int yspeed)
|
||||
static void mouse_winapi_set_speed(int xspeed, int yspeed)
|
||||
{
|
||||
_enter_critical();
|
||||
|
||||
mouse_sx = MAX(1, xspeed);
|
||||
mouse_sy = MAX(1, yspeed);
|
||||
|
||||
mouse_mx = COORD_TO_MICKEY_X(_mouse_x);
|
||||
mouse_my = COORD_TO_MICKEY_Y(_mouse_y);
|
||||
|
||||
CLEAR_MICKEYS();
|
||||
|
||||
_exit_critical();
|
||||
@ -773,9 +188,9 @@ static void mouse_directx_set_speed(int xspeed, int yspeed)
|
||||
|
||||
|
||||
|
||||
/* mouse_directx_get_mickeys: [primary thread]
|
||||
/* mouse_winapi_get_mickeys: [primary thread]
|
||||
*/
|
||||
static void mouse_directx_get_mickeys(int *mickeyx, int *mickeyy)
|
||||
static void mouse_winapi_get_mickeys(int *mickeyx, int *mickeyy)
|
||||
{
|
||||
int temp_x = mymickey_x;
|
||||
int temp_y = mymickey_y;
|
||||
@ -789,22 +204,21 @@ static void mouse_directx_get_mickeys(int *mickeyx, int *mickeyy)
|
||||
|
||||
|
||||
|
||||
/* mouse_directx_enable_hardware_cursor:
|
||||
/* mouse_winapi_enable_hardware_cursor:
|
||||
* enable the hardware cursor; actually a no-op in Windows, but we need to
|
||||
* put something in the vtable.
|
||||
*/
|
||||
static void mouse_directx_enable_hardware_cursor(int mode)
|
||||
static void mouse_winapi_enable_hardware_cursor(int mode)
|
||||
{
|
||||
/* Do nothing */
|
||||
(void)mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mouse_directx_select_system_cursor:
|
||||
/* mouse_winapi_select_system_cursor:
|
||||
* Select an OS native cursor
|
||||
*/
|
||||
static int mouse_directx_select_system_cursor (int cursor)
|
||||
static int mouse_winapi_select_system_cursor(int cursor)
|
||||
{
|
||||
HCURSOR wc;
|
||||
HWND allegro_wnd = win_get_window();
|
||||
@ -829,7 +243,55 @@ static int mouse_directx_select_system_cursor (int cursor)
|
||||
|
||||
_win_hcursor = wc;
|
||||
SetCursor(_win_hcursor);
|
||||
PostMessage(allegro_wnd, WM_MOUSEMOVE, 0, 0);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _al_win_mouse_handle_button(HWND hwnd, int button, BOOL down, int x, int y, BOOL abs)
|
||||
{
|
||||
_enter_critical();
|
||||
|
||||
if (down)
|
||||
_mouse_b |= (1 << (button-1));
|
||||
else
|
||||
_mouse_b &= ~(1 << (button-1));
|
||||
|
||||
_exit_critical();
|
||||
|
||||
_handle_mouse_input();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _al_win_mouse_handle_wheel(HWND hwnd, int z, BOOL abs)
|
||||
{
|
||||
_enter_critical();
|
||||
|
||||
_mouse_z += z;
|
||||
|
||||
_exit_critical();
|
||||
|
||||
_handle_mouse_input();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _al_win_mouse_handle_move(HWND hwnd, int x, int y)
|
||||
{
|
||||
_enter_critical();
|
||||
|
||||
_mouse_x = CLAMP(mouse_minx, x, mouse_maxx);
|
||||
_mouse_y = CLAMP(mouse_miny, y, mouse_maxy);
|
||||
|
||||
mymickey_x += x - mymickey_ox;
|
||||
mymickey_y += y - mymickey_oy;
|
||||
|
||||
mymickey_ox = x;
|
||||
mymickey_oy = y;
|
||||
|
||||
_exit_critical();
|
||||
|
||||
_handle_mouse_input();
|
||||
}
|
||||
|
@ -351,7 +351,6 @@ 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);
|
||||
|
||||
/* reset switch mode */
|
||||
_win_reset_switch_mode();
|
||||
|
@ -20,11 +20,12 @@
|
||||
#include "allegro/internal/aintern.h"
|
||||
#include "allegro/platform/aintwin.h"
|
||||
|
||||
#ifndef SCAN_DEPEND
|
||||
#include <string.h>
|
||||
#include <process.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <process.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef ALLEGRO_WINDOWS
|
||||
#error something is wrong with the makefile
|
||||
@ -89,6 +90,12 @@ typedef struct {
|
||||
#endif /* ifndef CCHILDREN_TITLEBAR */
|
||||
|
||||
|
||||
/* In wmouse.c */
|
||||
void _al_win_mouse_handle_button(HWND hwnd, int button, BOOL down, int x, int y, 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);
|
||||
|
||||
|
||||
|
||||
/* init_window_modules:
|
||||
* Initialises the modules that are specified by the WM argument.
|
||||
@ -211,8 +218,11 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
|
||||
|
||||
case WM_SETCURSOR:
|
||||
if (!user_wnd_proc || _mouse_installed) {
|
||||
mouse_set_syscursor();
|
||||
return 1; /* not TRUE */
|
||||
int hittest = LOWORD(lparam);
|
||||
if (hittest == HTCLIENT) {
|
||||
mouse_set_syscursor();
|
||||
return 1; /* not TRUE */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -306,7 +316,6 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
|
||||
|
||||
case WM_INITMENUPOPUP:
|
||||
wnd_sysmenu = TRUE;
|
||||
mouse_set_sysmenu(TRUE);
|
||||
|
||||
if (win_gfx_driver && win_gfx_driver->enter_sysmode)
|
||||
win_gfx_driver->enter_sysmode();
|
||||
@ -315,7 +324,6 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
|
||||
case WM_MENUSELECT:
|
||||
if ((HIWORD(wparam) == 0xFFFF) && (!lparam)) {
|
||||
wnd_sysmenu = FALSE;
|
||||
mouse_set_sysmenu(FALSE);
|
||||
|
||||
if (win_gfx_driver && win_gfx_driver->exit_sysmode)
|
||||
win_gfx_driver->exit_sysmode();
|
||||
@ -332,6 +340,59 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP: {
|
||||
int mx = GET_X_LPARAM(lparam);
|
||||
int my = GET_Y_LPARAM(lparam);
|
||||
BOOL down = (message == WM_LBUTTONDOWN);
|
||||
_al_win_mouse_handle_button(wnd, 1, down, mx, my, TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP: {
|
||||
int mx = GET_X_LPARAM(lparam);
|
||||
int my = GET_Y_LPARAM(lparam);
|
||||
BOOL down = (message == WM_MBUTTONDOWN);
|
||||
_al_win_mouse_handle_button(wnd, 3, down, mx, my, TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP: {
|
||||
int mx = GET_X_LPARAM(lparam);
|
||||
int my = GET_Y_LPARAM(lparam);
|
||||
BOOL down = (message == WM_RBUTTONDOWN);
|
||||
_al_win_mouse_handle_button(wnd, 2, down, mx, my, TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_XBUTTONUP: {
|
||||
int mx = GET_X_LPARAM(lparam);
|
||||
int my = GET_Y_LPARAM(lparam);
|
||||
int button = HIWORD(wparam);
|
||||
BOOL down = (message == WM_XBUTTONDOWN);
|
||||
if (button == XBUTTON1)
|
||||
_al_win_mouse_handle_button(wnd, 4, down, mx, my, TRUE);
|
||||
else if (button == XBUTTON2)
|
||||
_al_win_mouse_handle_button(wnd, 5, down, mx, my, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_MOUSEWHEEL: {
|
||||
int d = GET_WHEEL_DELTA_WPARAM(wparam);
|
||||
_al_win_mouse_handle_wheel(wnd, d / WHEEL_DELTA, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_MOUSEMOVE: {
|
||||
POINTS p = MAKEPOINTS(lparam);
|
||||
_al_win_mouse_handle_move(wnd, p.x, p.y);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* pass message to default window proc */
|
||||
@ -734,5 +795,4 @@ void win_set_wnd_create_proc(HWND (*proc)(WNDPROC))
|
||||
void win_grab_input(void)
|
||||
{
|
||||
wnd_schedule_proc(key_dinput_acquire);
|
||||
wnd_schedule_proc(mouse_dinput_grab);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user