diff --git a/src/allegro/README.txt b/src/allegro/README.txt
index 8b7022b29..b10decca3 100644
--- a/src/allegro/README.txt
+++ b/src/allegro/README.txt
@@ -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).
diff --git a/src/allegro/include/allegro/platform/aintwin.h b/src/allegro/include/allegro/platform/aintwin.h
index ccdb064c5..904109875 100644
--- a/src/allegro/include/allegro/platform/aintwin.h
+++ b/src/allegro/include/allegro/platform/aintwin.h
@@ -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 */
diff --git a/src/allegro/include/allegro/platform/alwin.h b/src/allegro/include/allegro/platform/alwin.h
index 7344c2a19..743d756fc 100644
--- a/src/allegro/include/allegro/platform/alwin.h
+++ b/src/allegro/include/allegro/platform/alwin.h
@@ -84,13 +84,6 @@ AL_VAR(SYSTEM_DRIVER, system_directx);
 
 
 
-/*******************************************/
-/************* mouse drivers ***************/
-/*******************************************/
-#define MOUSE_DIRECTX            AL_ID('D','X',' ',' ')
-
-
-
 /*******************************************/
 /*************** gfx drivers ***************/
 /*******************************************/
diff --git a/src/allegro/src/win/wdispsw.c b/src/allegro/src/win/wdispsw.c
index a0232b772..981c3175c 100644
--- a/src/allegro/src/win/wdispsw.c
+++ b/src/allegro/src/win/wdispsw.c
@@ -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();
diff --git a/src/allegro/src/win/wmouse.c b/src/allegro/src/win/wmouse.c
index 02e9090e8..bf46fc83e 100644
--- a/src/allegro/src/win/wmouse.c
+++ b/src/allegro/src/win/wmouse.c
@@ -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();
+}
diff --git a/src/allegro/src/win/wsystem.c b/src/allegro/src/win/wsystem.c
index f9e976f58..4da893dec 100644
--- a/src/allegro/src/win/wsystem.c
+++ b/src/allegro/src/win/wsystem.c
@@ -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();
diff --git a/src/allegro/src/win/wwnd.c b/src/allegro/src/win/wwnd.c
index d421e9e43..de7355c72 100644
--- a/src/allegro/src/win/wwnd.c
+++ b/src/allegro/src/win/wwnd.c
@@ -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);
 }