1Index: src/video/wincommon/SDL_lowvideo.h
2===================================================================
3--- src/video/wincommon/SDL_lowvideo.h	(revision 4067)
4+++ src/video/wincommon/SDL_lowvideo.h	(working copy)
5@@ -51,10 +51,13 @@
6 /* Hidden "this" pointer for the video functions */
7 #define _THIS	SDL_VideoDevice *this
8
9+#define FULLSCREEN() \
10+	((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
11+
12 #define WINDIB_FULLSCREEN()						\
13 (									\
14 	SDL_VideoSurface &&						\
15-	((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && \
16+	FULLSCREEN() && \
17 	(((SDL_VideoSurface->flags & SDL_OPENGL   ) == SDL_OPENGL    ) || \
18 	((SDL_strcmp(this->name, "windib") == 0) || \
19 	 (SDL_strcmp(this->name, "gapi") == 0))) \
20@@ -62,13 +65,19 @@
21 #define DDRAW_FULLSCREEN() 						\
22 (									\
23 	SDL_VideoSurface &&						\
24-	((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && \
25+	FULLSCREEN() && \
26 	((SDL_VideoSurface->flags & SDL_OPENGL    ) != SDL_OPENGL    ) && \
27 	(SDL_strcmp(this->name, "directx") == 0)				\
28 )
29
30-#define DINPUT_FULLSCREEN()	DDRAW_FULLSCREEN()
31+#define DINPUT_FULLSCREEN() 						\
32+(									\
33+	FULLSCREEN() && \
34+	(strcmp(this->name, "directx") == 0)				\
35+)
36
37+#define DINPUT() (strcmp(this->name, "directx") == 0)
38+
39 /* The main window -- and a function to set it for the audio */
40 #ifdef _WIN32_WCE
41 extern LPWSTR SDL_Appname;
42Index: src/video/wincommon/SDL_sysevents.c
43===================================================================
44--- src/video/wincommon/SDL_sysevents.c	(revision 4067)
45+++ src/video/wincommon/SDL_sysevents.c	(working copy)
46@@ -335,7 +335,6 @@
47 {
48 	SDL_VideoDevice *this = current_video;
49 	static int mouse_pressed = 0;
50-	static int in_window = 0;
51 #ifdef WMMSG_DEBUG
52 	fprintf(stderr, "Received windows message:  ");
53 	if ( msg > MAX_WMMSG ) {
54@@ -411,62 +410,41 @@
55 		break;
56
57 		case WM_MOUSEMOVE: {
58-
59-			/* Mouse is handled by DirectInput when fullscreen */
60-			if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
61-				Sint16 x, y;
62
63-				/* mouse has entered the window */
64-				if ( ! in_window ) {
65 #ifdef WM_MOUSELEAVE
66+			/* No need to handle SDL_APPMOUSEFOCUS when fullscreen */
67+			if ( SDL_VideoSurface && !FULLSCREEN() ) {
68+				/* mouse has entered the window */
69+
70+				if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
71 					TRACKMOUSEEVENT tme;
72
73 					tme.cbSize = sizeof(tme);
74 					tme.dwFlags = TME_LEAVE;
75 					tme.hwndTrack = SDL_Window;
76 					_TrackMouseEvent(&tme);
77+				}
78+			}
79 #endif /* WM_MOUSELEAVE */
80-					in_window = TRUE;
81
82-					posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
83-				}
84+			/* Mouse motion is handled in DIB_PumpEvents or
85+			 * DX5_PumpEvents, depending on the video driver
86+			 * in use */
87
88-				/* mouse has moved within the window */
89-				x = LOWORD(lParam);
90-				y = HIWORD(lParam);
91-				if ( mouse_relative ) {
92-					POINT center;
93-					center.x = (SDL_VideoSurface->w/2);
94-					center.y = (SDL_VideoSurface->h/2);
95-					x -= (Sint16)center.x;
96-					y -= (Sint16)center.y;
97-					if ( x || y ) {
98-						ClientToScreen(SDL_Window, &center);
99-						SetCursorPos(center.x, center.y);
100-						posted = SDL_PrivateMouseMotion(0, 1, x, y);
101-					}
102-				} else {
103-#ifdef _WIN32_WCE
104-					if (SDL_VideoSurface)
105-						GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y);
106-#endif
107-					posted = SDL_PrivateMouseMotion(0, 0, x, y);
108-				}
109-			}
110+			posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
111 		}
112 		return(0);
113
114 #ifdef WM_MOUSELEAVE
115 		case WM_MOUSELEAVE: {
116
117-			/* Mouse is handled by DirectInput when fullscreen */
118-			if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
119+			/* No need to handle SDL_APPMOUSEFOCUS when fullscreen */
120+			if ( SDL_VideoSurface && !FULLSCREEN() ) {
121 				/* mouse has left the window */
122 				/* or */
123 				/* Elvis has left the building! */
124 				posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
125 			}
126-			in_window = FALSE;
127 		}
128 		return(0);
129 #endif /* WM_MOUSELEAVE */
130@@ -480,7 +458,7 @@
131 		case WM_XBUTTONDOWN:
132 		case WM_XBUTTONUP: {
133 			/* Mouse is handled by DirectInput when fullscreen */
134-			if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
135+			if ( SDL_VideoSurface && ! DINPUT() ) {
136 				WORD xbuttonval = 0;
137 				Sint16 x, y;
138 				Uint8 button, state;
139@@ -544,20 +522,8 @@
140 						mouse_pressed = 0;
141 					}
142 				}
143-				if ( mouse_relative ) {
144-				/*	RJR: March 28, 2000
145-					report internal mouse position if in relative mode */
146-					x = 0; y = 0;
147-				} else {
148-					x = (Sint16)LOWORD(lParam);
149-					y = (Sint16)HIWORD(lParam);
150-#ifdef _WIN32_WCE
151-					if (SDL_VideoSurface)
152-						GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y);
153-#endif
154-				}
155 				posted = SDL_PrivateMouseButton(
156-							state, button, x, y);
157+							state, button, 0, 0);
158
159 				/*
160 				 * MSDN says:
161@@ -578,7 +544,7 @@
162
163 #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
164 		case WM_MOUSEWHEEL:
165-			if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
166+			if ( SDL_VideoSurface && ! DINPUT() ) {
167 				int move = (short)HIWORD(wParam);
168 				if ( move ) {
169 					Uint8 button;
170Index: src/video/wincommon/SDL_sysmouse.c
171===================================================================
172--- src/video/wincommon/SDL_sysmouse.c	(revision 4067)
173+++ src/video/wincommon/SDL_sysmouse.c	(working copy)
174@@ -188,8 +188,7 @@
175 {
176 	POINT mouse_pos;
177
178-	/* The fullscreen cursor must be done in software with DirectInput */
179-	if ( !this->screen || DDRAW_FULLSCREEN() ) {
180+	if ( !this->screen ) {
181 		return(0);
182 	}
183
184@@ -208,15 +207,20 @@
185
186 void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
187 {
188-	if ( DDRAW_FULLSCREEN() ) {
189-		SDL_PrivateMouseMotion(0, 0, x, y);
190-	} else if ( mouse_relative) {
191+	if ( mouse_relative) {
192 		/*	RJR: March 28, 2000
193 			leave physical cursor at center of screen if
194 			mouse hidden and grabbed */
195 		SDL_PrivateMouseMotion(0, 0, x, y);
196 	} else {
197 		POINT pt;
198+
199+		/* With DirectInput the position doesn't follow
200+		 * the cursor, so it is set manually */
201+		if ( DINPUT() ) {
202+			SDL_PrivateMouseMotion(0, 0, x, y);
203+		}
204+
205 		pt.x = x;
206 		pt.y = y;
207 		ClientToScreen(SDL_Window, &pt);
208@@ -227,20 +231,15 @@
209 /* Update the current mouse state and position */
210 void WIN_UpdateMouse(_THIS)
211 {
212-	RECT rect;
213 	POINT pt;
214
215-	if ( ! DDRAW_FULLSCREEN() ) {
216-		GetClientRect(SDL_Window, &rect);
217-		GetCursorPos(&pt);
218-		MapWindowPoints(NULL, SDL_Window, &pt, 1);
219-		if (PtInRect(&rect, pt) && (WindowFromPoint(pt) == SDL_Window)){
220-			SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
221-			SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y);
222-		} else {
223-			SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
224-		}
225-	}
226+	/* Always unset SDL_APPMOUSEFOCUS to give the WM_MOUSEMOVE event
227+	 * handler a chance to install a TRACKMOUSEEVENT */
228+	SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
229+
230+	GetCursorPos(&pt);
231+	ScreenToClient(SDL_Window, &pt);
232+	SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y);
233 }
234
235 /* Check to see if we need to enter or leave mouse relative mode */
236Index: src/video/windib/SDL_dibevents.c
237===================================================================
238--- src/video/windib/SDL_dibevents.c	(revision 4067)
239+++ src/video/windib/SDL_dibevents.c	(working copy)
240@@ -262,6 +262,36 @@
241 	return(DefWindowProc(hwnd, msg, wParam, lParam));
242 }
243
244+static void DIB_GenerateMouseMotionEvent(void)
245+{
246+	extern int mouse_relative;
247+	extern int posted;
248+
249+	POINT mouse;
250+	GetCursorPos( &mouse );
251+
252+	if ( mouse_relative ) {
253+		POINT center;
254+		center.x = (SDL_VideoSurface->w/2);
255+		center.y = (SDL_VideoSurface->h/2);
256+		ClientToScreen(SDL_Window, &center);
257+
258+		mouse.x -= (Sint16)center.x;
259+		mouse.y -= (Sint16)center.y;
260+		if ( mouse.x || mouse.y ) {
261+			SetCursorPos(center.x, center.y);
262+			posted = SDL_PrivateMouseMotion(0, 1, mouse.x, mouse.y);
263+		}
264+	} else if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
265+		ScreenToClient(SDL_Window, &mouse);
266+#ifdef _WIN32_WCE
267+		if (SDL_VideoSurface)
268+			GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &mouse.x, &mouse.y);
269+#endif
270+		posted = SDL_PrivateMouseMotion(0, 0, mouse.x, mouse.y);
271+	}
272+}
273+
274 void DIB_PumpEvents(_THIS)
275 {
276 	MSG msg;
277@@ -271,6 +301,10 @@
278 			DispatchMessage(&msg);
279 		}
280 	}
281+
282+	if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
283+		DIB_GenerateMouseMotionEvent( );
284+	}
285 }
286
287 static HKL hLayoutUS = NULL;
288@@ -494,7 +528,7 @@
289 		Uint16	wchars[2];
290
291 		GetKeyboardState(keystate);
292-		if (SDL_ToUnicode((UINT)vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) == 1)
293+		if (SDL_ToUnicode((UINT)vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
294 		{
295 			keysym->unicode = wchars[0];
296 		}
297Index: src/video/windx5/SDL_dx5events.c
298===================================================================
299--- src/video/windx5/SDL_dx5events.c	(revision 4067)
300+++ src/video/windx5/SDL_dx5events.c	(working copy)
301@@ -143,9 +143,14 @@
302 		(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
303 		(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard },
304 	{ "mouse",
305-		&GUID_SysMouse, &c_dfDIMouse,
306+		&GUID_SysMouse,
307+#if DIRECTINPUT_VERSION >= 0x700
308+		&c_dfDIMouse2,
309+#else
310+		&c_dfDIMouse,
311+#endif
312 		(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
313-		(DISCL_FOREGROUND|DISCL_EXCLUSIVE), handle_mouse },
314+		(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_mouse },
315 	{ NULL, NULL, NULL, 0, 0, NULL }
316 };
317
318@@ -285,6 +290,76 @@
319 		}
320 	}
321 }
322+
323+static void post_mouse_motion(int relative, Sint16 x, Sint16 y)
324+{
325+	extern int mouse_relative;
326+
327+	if ( SDL_GetAppState() & (SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS) ==
328+		(SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS) ) {
329+		posted = SDL_PrivateMouseMotion(
330+			0, relative, x, y);
331+
332+		if ( !mouse_relative ) {
333+			/* As DirectInput reads raw device coordinates, it has no notion of
334+			 * cursors or absolute position. We must assume responsibility for
335+			 * keeping track of this. */
336+			int current_x, current_y;
337+			POINT cursor;
338+			RECT trap;
339+			RECT window;
340+			int at_edge;
341+
342+			/* Get the current cursor position */
343+			SDL_GetMouseState(&current_x, &current_y);
344+			cursor.x = current_x;
345+			cursor.y = current_y;
346+			ClientToScreen(SDL_Window, &cursor);
347+
348+			/* Construct a 1 pixel square RECT that is used to confine the cursor
349+			 * pointer to a specific pixel using ClipCursor. This is used in
350+			 * preference to SetCursorPos as it avoids the cursor jumping around as
351+			 * both the OS and SDL attempt to move it simultaneously. */
352+			trap.left = cursor.x;
353+			trap.top = cursor.y;
354+			trap.right = cursor.x + 1;
355+			trap.bottom = cursor.y + 1;
356+
357+			GetClientRect(SDL_Window, &window);
358+			window.right -= window.left; window.left = 0;
359+			window.bottom -= window.top; window.top = 0;
360+
361+			/* As we're assuming control over the cursor, we need to know when to
362+			 * relinquish control of it back to the operating system. This is when
363+			 * the cursor reaches the edge of the window. */
364+			at_edge = (current_x == window.left) ||
365+				(current_x == (window.right - 1)) ||
366+				(current_y == window.top) ||
367+				(current_y == (window.bottom - 1));
368+
369+			if ( at_edge ) {
370+				ClipCursor(NULL);
371+			} else {
372+				ClipCursor(&trap);
373+			}
374+		} else {
375+			/* When in relative mode, warp the OS's idea of where the cursor is to
376+			 * the center of the screen. This isn't really necessary as DirectInput
377+			 * reads from the hardware itself, but in case things go wrong, the
378+			 * cursor will be left in a sensible place. */
379+			POINT center;
380+			center.x = (SDL_VideoSurface->w/2);
381+			center.y = (SDL_VideoSurface->h/2);
382+			ClientToScreen(SDL_Window, &center);
383+			SetCursorPos(center.x, center.y);
384+		}
385+	} else {
386+		/* No window or mouse focus, control is lost */
387+		mouse_lost = 1;
388+		ClipCursor(NULL);
389+	}
390+}
391+
392 static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
393 {
394 	int i;
395@@ -298,14 +373,8 @@
396 		return;
397 	}
398
399-	/* If we are in windowed mode, Windows is taking care of the mouse */
400-	if (  (SDL_PublicSurface->flags & SDL_OPENGL) ||
401-	     !(SDL_PublicSurface->flags & SDL_FULLSCREEN) ) {
402-		return;
403-	}
404-
405 	/* If the mouse was lost, regain some sense of mouse state */
406-	if ( mouse_lost ) {
407+	if ( mouse_lost && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
408 		POINT mouse_pos;
409 		Uint8 old_state;
410 		Uint8 new_state;
411@@ -313,14 +382,17 @@
412 		/* Set ourselves up with the current cursor position */
413 		GetCursorPos(&mouse_pos);
414 		ScreenToClient(SDL_Window, &mouse_pos);
415-		posted = SDL_PrivateMouseMotion(0, 0,
416-				(Sint16)mouse_pos.x, (Sint16)mouse_pos.y);
417+		post_mouse_motion( 0, (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);
418
419 		/* Check for mouse button changes */
420 		old_state = SDL_GetMouseState(NULL, NULL);
421 		new_state = 0;
422 		{ /* Get the new DirectInput button state for the mouse */
423+#if DIRECTINPUT_VERSION >= 0x700
424+			DIMOUSESTATE2 distate;
425+#else
426 			DIMOUSESTATE distate;
427+#endif
428 			HRESULT result;
429
430 			result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
431@@ -341,14 +413,13 @@
432 		for ( i=0; i<8; ++i ) {
433 			if ( (old_state&0x01) != (new_state&0x01) ) {
434 				button = (Uint8)(i+1);
435-				/* Button #2 on two button mice is button 3
436-				   (the middle button is button 2)
437-				 */
438-				if ( button == 2 ) {
439-					button = 3;
440-				} else
441-				if ( button == 3 ) {
442-					button = 2;
443+				/* Map DI button numbers to SDL */
444+				switch ( button ) {
445+					case 2: button = SDL_BUTTON_RIGHT; break;
446+					case 3: button = SDL_BUTTON_MIDDLE; break;
447+					case 4: button = SDL_BUTTON_X1; break;
448+					case 5: button = SDL_BUTTON_X2; break;
449+					default: break;
450 				}
451 				if ( new_state & 0x01 ) {
452 					/* Grab mouse so we get mouse-up */
453@@ -387,8 +458,7 @@
454 			case DIMOFS_X:
455 				if ( timestamp != ptrbuf[i].dwTimeStamp ) {
456 					if ( xrel || yrel ) {
457-						posted = SDL_PrivateMouseMotion(
458-								0, 1, xrel, yrel);
459+						post_mouse_motion(1, xrel, yrel);
460 						xrel = 0;
461 						yrel = 0;
462 					}
463@@ -399,8 +469,7 @@
464 			case DIMOFS_Y:
465 				if ( timestamp != ptrbuf[i].dwTimeStamp ) {
466 					if ( xrel || yrel ) {
467-						posted = SDL_PrivateMouseMotion(
468-								0, 1, xrel, yrel);
469+						post_mouse_motion(1, xrel, yrel);
470 						xrel = 0;
471 						yrel = 0;
472 					}
473@@ -410,8 +479,7 @@
474 				break;
475 			case DIMOFS_Z:
476 				if ( xrel || yrel ) {
477-					posted = SDL_PrivateMouseMotion(
478-							0, 1, xrel, yrel);
479+					post_mouse_motion(1, xrel, yrel);
480 					xrel = 0;
481 					yrel = 0;
482 				}
483@@ -429,22 +497,26 @@
484 			case DIMOFS_BUTTON1:
485 			case DIMOFS_BUTTON2:
486 			case DIMOFS_BUTTON3:
487+#if DIRECTINPUT_VERSION >= 0x700
488+			case DIMOFS_BUTTON4:
489+			case DIMOFS_BUTTON5:
490+			case DIMOFS_BUTTON6:
491+			case DIMOFS_BUTTON7:
492+#endif
493 				if ( xrel || yrel ) {
494-					posted = SDL_PrivateMouseMotion(
495-							0, 1, xrel, yrel);
496+					post_mouse_motion(1, xrel, yrel);
497 					xrel = 0;
498 					yrel = 0;
499 				}
500 				timestamp = 0;
501 				button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;
502-				/* Button #2 on two button mice is button 3
503-				   (the middle button is button 2)
504-				 */
505-				if ( button == 2 ) {
506-					button = 3;
507-				} else
508-				if ( button == 3 ) {
509-					button = 2;
510+				/* Map DI button numbers to SDL */
511+				switch ( button ) {
512+					case 2: button = SDL_BUTTON_RIGHT; break;
513+					case 3: button = SDL_BUTTON_MIDDLE; break;
514+					case 4: button = SDL_BUTTON_X1; break;
515+					case 5: button = SDL_BUTTON_X2; break;
516+					default: break;
517 				}
518 				if ( ptrbuf[i].dwData & 0x80 ) {
519 					/* Grab mouse so we get mouse-up */
520@@ -471,7 +543,7 @@
521 		}
522 	}
523 	if ( xrel || yrel ) {
524-		posted = SDL_PrivateMouseMotion( 0, 1, xrel, yrel);
525+		post_mouse_motion(1, xrel, yrel);
526 	}
527 }
528
529@@ -516,10 +588,7 @@
530
531 		/* The keyboard is handled via DirectInput */
532 		case WM_SYSKEYUP:
533-		case WM_SYSKEYDOWN: {
534-			/* Pass syskey to DefWindwoProc (ALT-F4, etc.) */
535-		}
536-		break;
537+		case WM_SYSKEYDOWN:
538 		case WM_KEYUP:
539 		case WM_KEYDOWN: {
540 			/* Ignore windows keyboard messages */;
541@@ -840,7 +909,7 @@
542 		keysym->unicode = vkey;
543 #else
544 		GetKeyboardState(keystate);
545-		if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) == 1)
546+		if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
547 		{
548 			keysym->unicode = wchars[0];
549 		}
550Index: src/video/windx5/directx.h
551===================================================================
552--- src/video/windx5/directx.h	(revision 4067)
553+++ src/video/windx5/directx.h	(working copy)
554@@ -72,7 +72,7 @@
555 /* We need these defines to mark what version of DirectX API we use */
556 #define DIRECTDRAW_VERSION  0x0700
557 #define DIRECTSOUND_VERSION 0x0500
558-#define DIRECTINPUT_VERSION 0x0500
559+#define DIRECTINPUT_VERSION 0x0700
560
561 #ifdef __GNUC__
562 #define NONAMELESSUNION
563@@ -81,4 +81,20 @@
564 #include <dsound.h>
565 #include <dinput.h>
566
567+#if DIRECTINPUT_VERSION >= 0x0700 && !defined(DIMOFS_BUTTON4)
568+typedef struct _DIMOUSESTATE2 {
569+    LONG    lX;
570+    LONG    lY;
571+    LONG    lZ;
572+    BYTE    rgbButtons[8];
573+} DIMOUSESTATE2, *LPDIMOUSESTATE2;
574+
575+#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4)
576+#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5)
577+#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6)
578+#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7)
579+
580+extern const DIDATAFORMAT c_dfDIMouse2;
581+#endif
582+
583 #endif /* _directx_h */
584Index: configure.in
585===================================================================
586--- configure.in	(revision 4067)
587+++ configure.in	(working copy)
588@@ -2442,7 +2442,7 @@
589         # Set up the system libraries we need
590         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm"
591         if test x$have_directx = xyes; then
592-            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldxguid"
593+            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldxguid -ldinput8"
594         fi
595         # The Win32 platform requires special setup
596         SOURCES="$SOURCES $srcdir/src/main/win32/*.rc"
597