Index: src/win/wwindow.c
===================================================================
--- src/win/wwindow.c	(revision 14659)
+++ src/win/wwindow.c	(working copy)
@@ -28,6 +28,11 @@
 #define WM_MOUSEHWHEEL 0x020E
 #endif
 
+/* Missing from MSVC 2005 headers. */
+#ifndef MAPVK_VSC_TO_VK_EX
+#define MAPVK_VSC_TO_VK_EX 3
+#endif
+
 #include <allegro5/allegro.h>
 #include <process.h>
 
@@ -435,67 +440,84 @@
    switch (message) {
       case WM_INPUT:
       {
-         /* RAW Input is currently unused. */
+         /* Raw input is currently used for keyboard, but not enabled for mouse. */
           UINT dwSize;
           LPBYTE lpb;
           RAWINPUT* raw;
+          UINT r;
 
-          /* We can't uninstall WM_INPUT mesages. */
-          if (!al_is_mouse_installed())
-             break;
-
-          GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize,
+          r = GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize,
                           sizeof(RAWINPUTHEADER));
+          ASSERT(r == 0);
           lpb = al_malloc(sizeof(BYTE)*dwSize);
           if (lpb == NULL)
               break;
 
           GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
+          ASSERT(r != -1);
           raw = (RAWINPUT*)lpb;
 
-          if (raw->header.dwType != RIM_TYPEMOUSE) {
-             al_free(lpb);
-             break;
+         if (raw->header.dwType == RIM_TYPEMOUSE && al_is_mouse_installed()) {
+            RAWMOUSE *rm = &raw->data.mouse;
+            int x = raw->data.mouse.lLastX;
+            int y = raw->data.mouse.lLastY;
+            bool abs = rm->usFlags & (MOUSE_MOVE_ABSOLUTE || MOUSE_VIRTUAL_DESKTOP);
+            if (abs || x || y)
+               _al_win_mouse_handle_move(x, y, abs, win_display);
+
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_DOWN)
+               _al_win_mouse_handle_button(1, true, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_UP)
+               _al_win_mouse_handle_button(1, false, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_DOWN)
+               _al_win_mouse_handle_button(2, true, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_UP)
+               _al_win_mouse_handle_button(2, false, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_DOWN)
+               _al_win_mouse_handle_button(3, true, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_UP)
+               _al_win_mouse_handle_button(3, false, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN)
+               _al_win_mouse_handle_button(4, true, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_UP)
+               _al_win_mouse_handle_button(4, false, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN)
+               _al_win_mouse_handle_button(5, true, x, y, abs, win_display);
+            if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_UP)
+               _al_win_mouse_handle_button(5, false, x, y, abs, win_display);
+
+            if (rm->usButtonFlags & RI_MOUSE_WHEEL) {
+               SHORT z = (SHORT)rm->usButtonData;
+               _al_win_mouse_handle_wheel(z / WHEEL_DELTA, false, win_display);
+            }
           }
+         else if (raw->header.dwType == RIM_TYPEKEYBOARD) {
+            int vcode = raw->data.keyboard.VKey;
+            int scode = raw->data.keyboard.MakeCode & 0xff;
+            bool extended = (raw->data.keyboard.Flags >> 1) & 1;
 
-       {
-          RAWMOUSE *rm = &raw->data.mouse;
-          int x = raw->data.mouse.lLastX;
-          int y = raw->data.mouse.lLastY;
-          bool abs = rm->usFlags & (MOUSE_MOVE_ABSOLUTE
-                                 || MOUSE_VIRTUAL_DESKTOP);
-          if (abs || x || y)
-             _al_win_mouse_handle_move(x, y, abs, win_display);
+            /* Ignore invalid key codes. */
+            if (vcode == 0xff)
+               break;
 
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_DOWN)
-             _al_win_mouse_handle_button(1, true, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_UP)
-             _al_win_mouse_handle_button(1, false, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_DOWN)
-             _al_win_mouse_handle_button(2, true, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_UP)
-             _al_win_mouse_handle_button(2, false, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_DOWN)
-             _al_win_mouse_handle_button(3, true, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_UP)
-             _al_win_mouse_handle_button(3, false, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN)
-             _al_win_mouse_handle_button(4, true, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_UP)
-             _al_win_mouse_handle_button(4, false, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN)
-             _al_win_mouse_handle_button(5, true, x, y, abs, win_display);
-          if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_UP)
-             _al_win_mouse_handle_button(5, false, x, y, abs, win_display);
+            if (vcode == VK_CONTROL)
+               vcode = (extended ? VK_RCONTROL : VK_LCONTROL);
+            else if (vcode == VK_MENU)
+               vcode = (extended ? VK_RMENU : VK_LMENU);
+            else if (vcode == VK_SHIFT)
+               vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX);
 
-          if (rm->usButtonFlags & RI_MOUSE_WHEEL) {
-             SHORT z = (SHORT)rm->usButtonData;
-             _al_win_mouse_handle_wheel(z / WHEEL_DELTA, false, win_display);
-          }
-       }
+            if (raw->data.keyboard.Flags & 1) {
+               _al_win_kbd_handle_key_release(scode, vcode, extended, win_display);
+            }
+            else {
+               bool repeated = (GetKeyState(vcode) >> 15) & 1;
+               _al_win_kbd_handle_key_press(scode, vcode, extended, repeated, win_display);
+            }
+         }
 
-          al_free(lpb);
-          break;
+         al_free(lpb);
+         break;
       }
       case WM_LBUTTONDOWN:
       case WM_LBUTTONUP: {
@@ -658,31 +680,6 @@
          }
          break;
       }
-      case WM_SYSKEYDOWN: {
-         int vcode = wParam;
-         bool extended = (lParam >> 24) & 0x1;
-         bool repeated  = (lParam >> 30) & 0x1;
-         _al_win_kbd_handle_key_press(0, vcode, extended, repeated, win_display);
-         break;
-      }
-      case WM_KEYDOWN: {
-         int vcode = wParam;
-         int scode = (lParam >> 16) & 0xff;
-         bool extended = (lParam >> 24) & 0x1;
-         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, extended, repeated, win_display);
-         break;
-      }
-      case WM_SYSKEYUP:
-      case WM_KEYUP: {
-         int vcode = wParam;
-         int scode = (lParam >> 16) & 0xff;
-         bool extended = (lParam >> 24) & 0x1;
-         _al_win_kbd_handle_key_release(scode, vcode, extended, win_display);
-         break;
-      }
       case WM_SYSCOMMAND: {
          if (_al_win_disable_screensaver &&
                ((wParam & 0xfff0) == SC_MONITORPOWER || (wParam & 0xfff0) == SC_SCREENSAVE)) {
Index: src/win/wkeyboard.c
===================================================================
--- src/win/wkeyboard.c	(revision 14659)
+++ src/win/wkeyboard.c	(working copy)
@@ -22,11 +22,6 @@
 #include "allegro5/internal/aintern_keyboard.h"
 #include "allegro5/platform/aintwin.h"
 
-/* Missing from MSVC 2005 headers. */
-#ifndef MAPVK_VSC_TO_VK_EX
-   #define MAPVK_VSC_TO_VK_EX 3
-#endif
-
 static bool installed = false;
 static ALLEGRO_KEYBOARD the_keyboard;
 static ALLEGRO_KEYBOARD_STATE the_state;
@@ -59,7 +54,7 @@
    /* 0x50 */    ALLEGRO_KEY_P,           ALLEGRO_KEY_Q,             ALLEGRO_KEY_R,              ALLEGRO_KEY_S,
    /* 0x54 */    ALLEGRO_KEY_T,           ALLEGRO_KEY_U,             ALLEGRO_KEY_V,              ALLEGRO_KEY_W,
    /* 0x58 */    ALLEGRO_KEY_X,           ALLEGRO_KEY_Y,             ALLEGRO_KEY_Z,              ALLEGRO_KEY_LWIN,
-   /* 0x5C */    ALLEGRO_KEY_RWIN,        ALLEGRO_KEY_UNKNOWN+14,    0,                          0,
+   /* 0x5C */    ALLEGRO_KEY_RWIN,        ALLEGRO_KEY_MENU,          0,                          0,
    /* 0x60 */    ALLEGRO_KEY_PAD_0,       ALLEGRO_KEY_PAD_1,         ALLEGRO_KEY_PAD_2,          ALLEGRO_KEY_PAD_3,
    /* 0x64 */    ALLEGRO_KEY_PAD_4,       ALLEGRO_KEY_PAD_5,         ALLEGRO_KEY_PAD_6,          ALLEGRO_KEY_PAD_7,
    /* 0x68 */    ALLEGRO_KEY_PAD_8,       ALLEGRO_KEY_PAD_9,         ALLEGRO_KEY_PAD_ASTERISK,   ALLEGRO_KEY_PAD_PLUS,
@@ -142,14 +137,23 @@
  */
 static bool init_keyboard(void)
 {
+   RAWINPUTDEVICE rid;
+
    memset(&the_keyboard, 0, sizeof the_keyboard);
    memset(&the_state, 0, sizeof the_state);
 
-   /* Initialise the keyboard object for use as an event source. */
-   _al_event_source_init(&the_keyboard.es);
-
-   installed = true;
-   return true;
+   /* Using raw input (WM_INPUT messages). */
+   rid.usUsagePage = 1;
+   rid.usUsage = 6;
+   rid.dwFlags = 0;
+   rid.hwndTarget = NULL;
+   if (RegisterRawInputDevices(&rid, 1, sizeof(rid))) {
+      /* Initialise the keyboard object for use as an event source. */
+      _al_event_source_init(&the_keyboard.es);
+      installed = true;
+      return true;
+   }
+   return false;
 }
 
 
@@ -270,26 +274,18 @@
    if (!installed)
       return;
 
-   /* Using MapVirtualKey for Ctrl and Alt doesn't work, since the right hand versions have
-      two-byte scan codes. On the other hand, none of the Shift keys are 'extended' keys. */
-   if (vcode == VK_CONTROL)
-      vcode = extended ? VK_RCONTROL : VK_LCONTROL;
-   else if (vcode == VK_MENU)
-      vcode = extended ? VK_RMENU : VK_LMENU;
-   else if (vcode == VK_SHIFT)
-      vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX);
-
-   /* Ignore repeats for Caps Lock */
-   if (vcode == VK_CAPITAL && repeated && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_CAPSLOCK))
-      return;
-
    my_code = hw_to_mycode[vcode];
    /* No VK_* code for numpad Enter, need to special case it. */
-   if (extended && my_code == ALLEGRO_KEY_ENTER) {
-      my_code = ALLEGRO_KEY_PAD_ENTER;
+   if (my_code == ALLEGRO_KEY_ENTER) {
+      if (extended)
+         my_code = ALLEGRO_KEY_PAD_ENTER;
+      if (repeated && !_AL_KEYBOARD_STATE_KEY_DOWN(the_state, my_code))
+         repeated = false;
    }
-   update_modifiers(my_code, true);   
+   update_modifiers(my_code, true);
 
+   _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, my_code);
+
    if (!_al_event_source_needs_to_generate_event(&the_keyboard.es))
       return;
 
@@ -303,10 +299,9 @@
 
    _al_event_source_lock(&the_keyboard.es);
 
-   if (my_code > 0 && !(repeated && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, my_code))) {
+   if (my_code > 0 && !repeated) {
       _al_event_source_emit_event(&the_keyboard.es, &event);
-   }
-   _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, my_code);
+   }   
 
    /* Send char events, but not for modifier keys or dead keys. */
    if (my_code < ALLEGRO_KEY_MODIFIERS) {
@@ -353,13 +348,6 @@
    if (!installed)
      return;
 
-   if (vcode == VK_CONTROL)
-      vcode = extended ? VK_RCONTROL : VK_LCONTROL;
-   else if (vcode == VK_MENU)
-      vcode = extended ? VK_RMENU : VK_LMENU;
-   else if (vcode == VK_SHIFT)
-      vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX);
-
    my_code = hw_to_mycode[vcode];
    if (extended && my_code == ALLEGRO_KEY_ENTER) {
       my_code = ALLEGRO_KEY_PAD_ENTER;
@@ -367,15 +355,7 @@
    update_modifiers(my_code, false);
 
    _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, 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 == ALLEGRO_KEY_LSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_RSHIFT))
-      _al_win_kbd_handle_key_release(scode, VK_RSHIFT, extended, win_disp);
-   else if (my_code == ALLEGRO_KEY_RSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_LSHIFT))
-      _al_win_kbd_handle_key_release(scode, VK_LSHIFT, extended, win_disp);
-   
+
    if (!_al_event_source_needs_to_generate_event(&the_keyboard.es))
       return;
 
