Modify Allegro to use WM_MOUSEMOVE instead of DirectInput in the Windows mouse driver.

This commit is contained in:
David Capello 2010-10-17 20:04:26 -03:00
parent 094f0b6e8f
commit 57b54ad050
7 changed files with 174 additions and 664 deletions

View File

@ -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).

View File

@ -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 */

View File

@ -84,13 +84,6 @@ AL_VAR(SYSTEM_DRIVER, system_directx);
/*******************************************/
/************* mouse drivers ***************/
/*******************************************/
#define MOUSE_DIRECTX AL_ID('D','X',' ',' ')
/*******************************************/
/*************** gfx drivers ***************/
/*******************************************/

View File

@ -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();

View File

@ -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();
}

View File

@ -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();

View File

@ -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);
}