Changed mouse button mapping and check size of return buffer.

diff --git a/windows/dinput.c b/windows/dinput.c
index f7829a3..f975b89 100644
--- a/windows/dinput.c
+++ b/windows/dinput.c
@@ -1,6 +1,8 @@
 /*		DirectInput
  *
  * Copyright 1998 Marcus Meissner
+ *
+ * Additions (mouse support) Copyright 1998 Lionel Ulmer
  */
 /* Status:
  *
@@ -9,6 +11,8 @@
  * - WingCommander Prophecy Demo:
  *   Doesn't get Input Focus.
  * 
+ * - Fallout : works great in X and DGA mode
+ *
  * FIXME: The keyboard handling needs to (and will) be merged into keyboard.c
  *	  (The current implementation is currently only a proof of concept and
  *	   an utter mess.)
@@ -57,10 +61,47 @@
  *	IDirectInputA_EnumDevices
  */
 static HRESULT WINAPI IDirectInputA_EnumDevices(
-	LPDIRECTINPUT32A this,DWORD dwFlags,LPDIENUMDEVICESCALLBACK32A cb,
-	LPVOID context,DWORD x
+	LPDIRECTINPUT32A this, DWORD dwDevType, LPDIENUMDEVICESCALLBACK32A lpCallback,
+	LPVOID pvRef, DWORD dwFlags
 ) {
-	FIXME(dinput,"(this=%p,0x%08lx,%p,%p,0x%08lx): stub\n",this,dwFlags,cb,context,x);
+  DIDEVICEINSTANCE32A devInstance;
+  int ret;
+
+  TRACE(dinput, "(this=%p,0x%04lx,%p,%p,%04lx)\n", this, dwDevType, lpCallback, pvRef, dwFlags);
+
+#if 0 /* Not compiled for the moment as long as I do not find
+	 the needed constants */
+  /* Ignore this field for the moment */
+  if (dwDevType != 0) {
+    FIXME(dinput, "device filtering not supported.\n");
+  }
+    
+  devInstance.dwSize = sizeof(DIDEVICEINSTANCE32A);
+  
+  /* Return keyboard */
+  devInstance.guidInstance = GUID_SysKeyboard;
+  devInstance.guidProduct = GUID_SysKeyboard;
+  devInstance.dwDevType = 1; /* Constant unknown :-( */
+  strcpy(devInstance.tszInstanceName, "Keyboard");
+  strcpy(devInstance.tszProductName, "Wine Keyboard");
+  
+  ret = lpCallback(&devInstance, pvRef);
+  TRACE(dinput, "Keyboard registered (%d)\n", ret);
+  
+  if (!ret)
+    return 0;
+  
+  /* Return mouse */
+  devInstance.guidInstance = GUID_SysMouse;
+  devInstance.guidProduct = GUID_SysMouse;
+  devInstance.dwDevType = 2; /* Constant unknown :-( */
+  strcpy(devInstance.tszInstanceName, "Mouse");
+  strcpy(devInstance.tszProductName, "Wine Mouse");
+  
+  ret = lpCallback(&devInstance, pvRef);
+  TRACE(dinput, "Mouse registered (%d)\n", ret);
+#endif
+  
 	return 0;
 }
 
@@ -215,7 +256,8 @@
 	LPDIRECTINPUTDEVICE32A this,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
 	LPDWORD entries,DWORD flags
 ) {
-/*	TRACE(dinput,"IDirectInputDeviceA(%p)->GetDeviceData(%ld,%p,%p(0x%08lx),0x%08lx)\n",this,dodsize,dod,entries,*entries,flags);*/
+  TRACE(dinput,"IDirectInputDeviceA(%p)->GetDeviceData(%ld,%p,%p(0x%08lx),0x%08lx)\n",
+	this,dodsize,dod,entries,*entries,flags);
 	return 0;
 }
 
@@ -363,6 +405,14 @@
 /******************************************************************************
  *	SysMouseA (DInput Mouse support)
  */
+
+/******************************************************************************
+  *     SetDataFormat : the application can choose the format of the data
+  *   the device driver sends back with GetDeviceState.
+  *
+  *   For the moment, only the "standard" configuration (c_dfDIMouse) is supported
+  *   in absolute and relative mode.
+  */
 static HRESULT WINAPI SysMouseA_SetDataFormat(
 	LPDIRECTINPUTDEVICE32A this,LPCDIDATAFORMAT df
 ) {
@@ -384,12 +434,19 @@
       WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
     else
       strcpy(xbuf,"<no guid>");
-    TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
+    TRACE(dinput,"df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
     TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
     TRACE(dinput,"dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
     TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
   }
 
+  /* Check size of data format to prevent crashes if the applications
+     sends a smaller buffer */
+  if (df->dwDataSize != sizeof(struct DIMOUSESTATE)) {
+    FIXME(dinput, "non-standard mouse configuration not supported yet.");
+    return DIERR_INVALIDPARAM;
+  }
+  
   /* For the moment, ignore these fields and return always as if
      c_dfDIMouse was passed as format... */
   if (df->dwFlags == DIDF_ABSAXIS)
@@ -407,18 +464,19 @@
     TSXQueryPointer(display, rootWindow, &rw, &cr,
 		    &rx, &ry, &cx, &cy, &mask);
     /* Fill the initial mouse state structure */
-    mthis->prevpos.lX = rx;
-    mthis->prevpos.lY = ry;
-    mthis->prevpos.lZ = 0;
-    mthis->prevpos.rgbButtons[0] = (mask & Button1Mask ? 0xFF : 0x00);
-    mthis->prevpos.rgbButtons[1] = (mask & Button2Mask ? 0xFF : 0x00);
-    mthis->prevpos.rgbButtons[2] = (mask & Button3Mask ? 0xFF : 0x00);
-    mthis->prevpos.rgbButtons[3] = (mask & Button4Mask ? 0xFF : 0x00);
+    mthis->prevX = rx;
+    mthis->prevY = ry;
   }
   
   return 0;
 }
 
+/******************************************************************************
+  *     GetDeviceState : returns the "state" of the mouse.
+  *
+  *   For the moment, only the "standard" return structure (DIMOUSESTATE) is
+  *   supported.
+  */
 static HRESULT WINAPI SysMouseA_GetDeviceState(
 	LPDIRECTINPUTDEVICE32A this,DWORD len,LPVOID ptr
 ) {
@@ -430,6 +488,12 @@
   
   TRACE(dinput,"(this=%p,0x%08lx,%p): \n",this,len,ptr);
   
+  /* Check if the buffer is big enough */
+  if (len < sizeof(struct DIMOUSESTATE)) {
+    FIXME(dinput, "unsupported state structure.");
+    return DIERR_INVALIDPARAM;
+  }
+  
   /* Get the mouse position */
   TSXQueryPointer(display, rootWindow, &rw, &cr,
 		  &rx, &ry, &cx, &cy, &mask);
@@ -440,16 +504,16 @@
     mstate->lX = rx;
     mstate->lY = ry;
   } else {
-    mstate->lX = rx - mthis->prevpos.lX;
-    mstate->lY = ry - mthis->prevpos.lY;
-    /* Fill the previous position structure */
-    mthis->prevpos.lX = rx;
-    mthis->prevpos.lY = ry;
+    mstate->lX = rx - mthis->prevX;
+    mstate->lY = ry - mthis->prevY;
+    /* Fill the previous positions */
+    mthis->prevX = rx;
+    mthis->prevY = ry;
   }
   mstate->lZ = 0;
   mstate->rgbButtons[0] = (mask & Button1Mask ? 0xFF : 0x00);
-  mstate->rgbButtons[1] = (mask & Button2Mask ? 0xFF : 0x00);
-  mstate->rgbButtons[2] = (mask & Button3Mask ? 0xFF : 0x00);
+  mstate->rgbButtons[1] = (mask & Button3Mask ? 0xFF : 0x00); /* Windows button two is X button 3 */
+  mstate->rgbButtons[2] = (mask & Button2Mask ? 0xFF : 0x00);
   mstate->rgbButtons[3] = (mask & Button4Mask ? 0xFF : 0x00);
   
   return 0;