This is the mail archive of the cygwin-xfree@cygwin.com mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

3Button emulation (fwd)


Hi,

I've done some hacking and created a 3 button mouse emulation for 2 button
mice. The emulation can be switched on with "-emulate3" and the timeout
can be set via "-emu3timeout n" with an default of 50ms.

The patch is taken against Harolds source tarball from April 22. 

I will provide an binary on www.gotti.org [1]

bye
    ago

[1] http://www-usercgi.tu-chemnitz.de/~goal/xfree/XWin-emu3.exe.bz2
-- 
Alexander.Gottwald@informatik.tu-chemnitz.de
http://www.gotti.org
+49 3725 3498080

diff -U3 -r xwin.old/InitOutput.c xwin/InitOutput.c
--- xwin.old/InitOutput.c	Fri Apr 20 22:06:55 2001
+++ xwin/InitOutput.c	Mon Apr 30 15:18:37 2001
@@ -59,6 +59,7 @@
       g_winScreens[i].pixelBlack = WIN_DEFAULT_BLACKPIXEL;
       g_winScreens[i].pixelWhite = WIN_DEFAULT_WHITEPIXEL;
       g_winScreens[i].dwLineBias = WIN_DEFAULT_LINEBIAS;
+      g_winScreens[i].dwEmulate3Timeout = WIN_DEFAULT_EMULATE3_TIMEOUT;
       g_winScreens[i].pfb = NULL;
     }
   g_nNumScreens = 1;
@@ -132,6 +133,10 @@
 	  "\t\tDirectDraw4 blitter\t4\n");
   ErrorF ("-fullscreen\n"
 	  "\tRun the specified server engine in fullscreen mode\n");
+  ErrorF ("-emulate3\n"
+          "\tEmulate 3Button mouse\n");
+  ErrorF ("-emu3timeout\n"
+          "\ttimeout for 3Button emulation\n"); 
 }
 
 /* See Porting Layer Definition - p. 57 */
@@ -349,7 +354,65 @@
       /* Indicate that we have processed this argument */
       return 1;
     }
+  /* Look for the '-emulate3' argument */
+  if (strcmp(argv[i], "-emulate3") == 0)
+    {
+      /* Is this parameter attached to a screen or is it global? */
+      if (-1 == g_nLastScreen)
+	{
+	  int			i;
+
+	  /* Parameter is for all screens */
+	  for (i = 0; i < MAXSCREENS; i++)
+	    {
+	      g_winScreens[i].fEmulate3 = TRUE;
+	    }
+	}
+      else
+	{
+	  /* Parameter is for a single screen */
+	  g_winScreens[g_nLastScreen].fEmulate3 = TRUE;
+	}
+
+      /* Indicate that we have processed this argument */
+      return 1;
+    }
+
+  /* Look for the '-emu3timeout' argument */
+  if (strcmp(argv[i], "-emu3timeout") == 0)
+    {
+      DWORD dwTimeout = 0;
+      
+      /* Display the usage message if the argument is malformed */
+      if (++i >= argc)
+	{
+	  UseMsg ();
+	  return 0;
+	}
+
+      /* Grab the argument */
+      dwTimeout = atoi (argv[i]);
+      
+      /* Is this parameter attached to a screen or is it global? */
+      if (-1 == g_nLastScreen)
+	{
+	  int			i;
+
+	  /* Parameter is for all screens */
+	  for (i = 0; i < MAXSCREENS; i++)
+	    {
+	      g_winScreens[i].dwEmulate3Timeout = dwTimeout;
+	    }
+	}
+      else
+	{
+	  /* Parameter is for a single screen */
+	  g_winScreens[g_nLastScreen].dwEmulate3Timeout = dwTimeout;
+	}
 
+      /* Indicate that we have processed this argument */
+      return 1;
+    }
   return 0;
 }
 
diff -U3 -r xwin.old/win.h xwin/win.h
--- xwin.old/win.h	Sun Apr 22 03:17:55 2001
+++ xwin/win.h	Mon Apr 30 15:23:12 2001
@@ -92,6 +92,7 @@
 #define WIN_DEFAULT_WHITEPIXEL	255
 #define WIN_DEFAULT_BLACKPIXEL	0
 #define WIN_DEFAULT_LINEBIAS	0
+#define WIN_DEFAULT_EMULATE3_TIMEOUT 50
 
 #define WIN_FD_INVALID		-1
 
@@ -235,6 +236,8 @@
   DWORD			dwEnginePreferred;
   DWORD			dwEnginesSupported;
   Bool			fFullScreen;
+  Bool                  fEmulate3;
+  DWORD                 dwEmulate3Timeout;
 } winScreenInfo, *winScreenInfoPtr;
 
 typedef struct
@@ -256,7 +259,9 @@
   DWORD			dwBitsPerRGB;
 
   DWORD			dwModeKeyStates;
-
+  DWORD                 dwButtonStates;
+  LONG                  lButtonTimeout;
+  
   /* Privates used by shadow fb GDI server */
   HBITMAP		hbmpShadow;
   HDC			hdcScreen;
diff -U3 -r xwin.old/winwndproc.c xwin/winwndproc.c
--- xwin.old/winwndproc.c	Fri Apr  6 22:57:34 2001
+++ xwin/winwndproc.c	Mon Apr 30 15:27:27 2001
@@ -33,6 +33,7 @@
 
 #include "win.h"
 
+
 /* Called by the WakeupHandler
  * Processes and/or dispatches Windows messages
  */
@@ -231,45 +232,87 @@
 
     case WM_LBUTTONDBLCLK:
     case WM_LBUTTONDOWN:
-      xCurrentEvent.u.u.type = ButtonPress;
-      xCurrentEvent.u.u.detail = Button1;
-      xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
-      mieqEnqueue (&xCurrentEvent);
-      return 0;
-
-    case WM_LBUTTONUP:
-      xCurrentEvent.u.u.type = ButtonRelease;
-      xCurrentEvent.u.u.detail = Button1;
-      xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
-      mieqEnqueue (&xCurrentEvent);
-      return 0;
-
     case WM_MBUTTONDBLCLK:
     case WM_MBUTTONDOWN:
-      xCurrentEvent.u.u.type = ButtonPress;
-      xCurrentEvent.u.u.detail = Button2;
-      xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
-      mieqEnqueue (&xCurrentEvent);
-      return 0;
-
-    case WM_MBUTTONUP:
-      xCurrentEvent.u.u.type = ButtonRelease;
-      xCurrentEvent.u.u.detail = Button2;
-      xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
-      mieqEnqueue (&xCurrentEvent);
-      return 0;
-
     case WM_RBUTTONDBLCLK:
     case WM_RBUTTONDOWN:
+      switch (message) {
+          case WM_LBUTTONDBLCLK:
+          case WM_LBUTTONDOWN:
+              xCurrentEvent.u.u.detail = Button1;
+              break;
+          case WM_MBUTTONDBLCLK:
+          case WM_MBUTTONDOWN:
+              xCurrentEvent.u.u.detail = Button2;
+              break;
+          case WM_RBUTTONDBLCLK:
+          case WM_RBUTTONDOWN:
+              xCurrentEvent.u.u.detail = Button3;
+              break;
+      }
+      if ((wParam & (MK_LBUTTON|MK_RBUTTON)) == (MK_LBUTTON|MK_RBUTTON) 
+              && pScreenPriv->pScreenInfo->fEmulate3 &&
+              GetMessageTime() < pScreenPriv->lButtonTimeout) {
+          if (pScreenPriv->dwButtonStates && (1<<Button1)) {
+              xCurrentEvent.u.u.detail = Button1;
+              xCurrentEvent.u.u.type = ButtonRelease;
+              xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
+              mieqEnqueue (&xCurrentEvent);
+              pScreenPriv->dwButtonStates &= ~(1<<Button1);
+          }
+          if (pScreenPriv->dwButtonStates && (1<<Button3)) {
+              xCurrentEvent.u.u.detail = Button3;
+              xCurrentEvent.u.u.type = ButtonRelease;
+              xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
+              mieqEnqueue (&xCurrentEvent);
+              pScreenPriv->dwButtonStates &= ~(1<<Button3);
+          }
+          if (pScreenPriv->dwButtonStates && (1<<Button2)) {
+              xCurrentEvent.u.u.detail = Button2;
+              xCurrentEvent.u.u.type = ButtonRelease;
+              xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
+              mieqEnqueue (&xCurrentEvent);
+              pScreenPriv->dwButtonStates &= ~(1<<Button2);
+          }
+          xCurrentEvent.u.u.detail = Button2;
+      }
+      pScreenPriv->lButtonTimeout = GetMessageTime() + 
+          pScreenPriv->pScreenInfo->dwEmulate3Timeout; 
+      pScreenPriv->dwButtonStates |= (1<<xCurrentEvent.u.u.detail);
+      ErrorF("Button Press msg=0x%04x wparam=0x%08x button=0x%04x\n",
+              message,wParam,pScreenPriv->dwButtonStates);
       xCurrentEvent.u.u.type = ButtonPress;
-      xCurrentEvent.u.u.detail = Button3;
       xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
       mieqEnqueue (&xCurrentEvent);
       return 0;
 
+    case WM_LBUTTONUP:
+    case WM_MBUTTONUP:
     case WM_RBUTTONUP:
+      switch (message) {
+          case WM_LBUTTONUP:
+              xCurrentEvent.u.u.detail = Button1;
+              break;
+          case WM_MBUTTONUP:
+              xCurrentEvent.u.u.detail = Button2;
+              break;
+          case WM_RBUTTONUP:
+              xCurrentEvent.u.u.detail = Button3;
+              break;
+      }
+      if (( xCurrentEvent.u.u.detail == Button1 ||
+              xCurrentEvent.u.u.detail == Button3 ) &&
+              ( pScreenPriv->dwButtonStates & (1<<Button2))
+              && pScreenPriv->pScreenInfo->fEmulate3 ) {
+          if (!(pScreenPriv->dwButtonStates & (1<<xCurrentEvent.u.u.detail))) 
+              xCurrentEvent.u.u.detail = Button2;
+      }
+      if (!(pScreenPriv->dwButtonStates & (1<<xCurrentEvent.u.u.detail))) 
+          return 0;
+      pScreenPriv->dwButtonStates &= ~(1<<xCurrentEvent.u.u.detail);
+      ErrorF("Button Release msg=0x%04x wparam=0x%08x button=0x%04x\n",
+              message,wParam,pScreenPriv->dwButtonStates);
       xCurrentEvent.u.u.type = ButtonRelease;
-      xCurrentEvent.u.u.detail = Button3;
       xCurrentEvent.u.keyButtonPointer.time = GetTickCount ();
       mieqEnqueue (&xCurrentEvent);
       return 0;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]