diff --git a/src/win/win.h b/src/win/win.h
index f3045663f..959056ba9 100644
--- a/src/win/win.h
+++ b/src/win/win.h
@@ -112,6 +112,9 @@ extern void keyboard_handle(LPARAM lParam, int infocus);
extern void win_mouse_init(void);
extern void win_mouse_close(void);
+#ifndef USE_DINPUT
+extern void win_mouse_handle(LPARAM lParam, int infocus);
+#endif
extern LPARAM win_get_string(int id);
diff --git a/src/win/win_mouse_rawinput.cpp b/src/win/win_mouse_rawinput.cpp
new file mode 100644
index 000000000..7d1bbf2df
--- /dev/null
+++ b/src/win/win_mouse_rawinput.cpp
@@ -0,0 +1,139 @@
+/*
+ * 86Box A hypervisor and IBM PC system emulator that specializes in
+ * running old operating systems and software designed for IBM
+ * PC systems and compatibles from 1981 through fairly recent
+ * system designs based on the PCI bus.
+ *
+ * This file is part of the 86Box distribution.
+ *
+ * RawInput mouse interface.
+ *
+ * Version: @(#)win_mouse_rawinput.cpp 1.0.0 2019/3/19
+ *
+ * Authors: Sarah Walker,
+ * Miran Grca,
+ * GH Cao,
+ *
+ * Copyright 2008-2017 Sarah Walker.
+ * Copyright 2016,2017 Miran Grca.
+ * Copyright 2019 GH Cao.
+ */
+#include
+#include
+#include
+#include
+#include "../86box.h"
+#include "../mouse.h"
+#include "../plat.h"
+#include "win.h"
+
+int mouse_capture;
+
+typedef struct {
+ int buttons;
+ int dx;
+ int dy;
+} MOUSESTATE;
+
+MOUSESTATE mousestate;
+
+void
+win_mouse_init(void)
+{
+ atexit(win_mouse_close);
+
+ mouse_capture = 0;
+
+ /* Initialize the RawInput (mouse) module. */
+ RAWINPUTDEVICE ridev;
+ ridev.dwFlags = 0;
+ ridev.hwndTarget = NULL;
+ ridev.usUsagePage = 0x01;
+ ridev.usUsage = 0x02;
+ if (! RegisterRawInputDevices(&ridev, 1, sizeof(ridev)))
+ fatal("plat_mouse_init: RegisterRawInputDevices failed\n");
+
+ memset(&mousestate, 0, sizeof(MOUSESTATE));
+}
+
+void
+win_mouse_handle(LPARAM lParam, int infocus)
+{
+ uint32_t ri_size = 0;
+ UINT size;
+ RAWINPUT *raw;
+
+ if (! infocus) return;
+
+ GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL,
+ &size, sizeof(RAWINPUTHEADER));
+
+ raw = (RAWINPUT*)malloc(size);
+ if (raw == NULL) return;
+
+ /* Here we read the raw input data for the mouse */
+ ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT,
+ raw, &size, sizeof(RAWINPUTHEADER));
+ if (ri_size != size) return;
+
+ /* If the input is mouse, we process it */
+ if (raw->header.dwType == RIM_TYPEMOUSE) {
+ RAWMOUSE state = raw->data.mouse;
+
+ if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
+ mousestate.buttons |= 1;
+ else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
+ mousestate.buttons &= ~1;
+
+ if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
+ mousestate.buttons |= 4;
+ else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
+ mousestate.buttons &= ~4;
+
+ if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
+ mousestate.buttons |= 2;
+ else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
+ mousestate.buttons &= ~2;
+
+ static int x = 0, y = 0;
+ if (x != state.lLastX || y != state.lLastY) {
+ mousestate.dx += state.lLastX;
+ mousestate.dy += state.lLastY;
+ x = state.lLastX;
+ y = state.lLastY;
+ }
+ }
+ free(raw);
+}
+
+void
+win_mouse_close(void)
+{
+ RAWINPUTDEVICE ridev;
+ ridev.dwFlags = RIDEV_REMOVE;
+ ridev.hwndTarget = NULL;
+ ridev.usUsagePage = 0x01;
+ ridev.usUsage = 0x02;
+ RegisterRawInputDevices(&ridev, 1, sizeof(ridev));
+}
+
+void
+mouse_poll(void)
+{
+ static int b = 0;
+ if (mouse_capture || video_fullscreen) {
+ if (mousestate.dx != 0 || mousestate.dy != 0) {
+ mouse_x += mousestate.dx;
+ mouse_y += mousestate.dy;
+ mouse_z = 0;
+
+ mousestate.dx=0;
+ mousestate.dy=0;
+ }
+
+ if (b != mousestate.buttons) {
+ mouse_buttons = mousestate.buttons;
+ b = mousestate.buttons;
+ }
+ }
+}
diff --git a/src/win/win_ui.c b/src/win/win_ui.c
index 190535aac..fc7e2709e 100644
--- a/src/win/win_ui.c
+++ b/src/win/win_ui.c
@@ -1089,6 +1089,9 @@ input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message) {
case WM_INPUT:
keyboard_handle(lParam, infocus);
+#ifndef USE_DINPUT
+ win_mouse_handle(lParam, infocus);
+#endif
break;
case WM_SETFOCUS: