Mouse in DOS console mode

Jukka Heinonen jhei at iki.fi
Sun Mar 17 10:38:52 CST 2002


Changelog:
  Console mode DOS programs now receive mouse events.
  Replaced GetMessage with PeekMessage, since
  MsgWaitForMultipleObjects is allowed to return spontaneously.



Index: wine/dlls/winedos/dosexe.h 
=================================================================== 
RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v 
retrieving revision 1.3 
diff -u -r1.3 dosexe.h 
--- wine/dlls/winedos/dosexe.h  9 Mar 2002 23:44:32 -0000       1.3 
+++ wine/dlls/winedos/dosexe.h  17 Mar 2002 16:22:40 -0000 
@@ -24,6 +24,7 @@ 
 #include "wine/windef16.h" 
 #include "winbase.h"   /* for LPSTARTUPINFO32A */ 
 #include "winnt.h"     /* for PCONTEXT */ 
+#include "wincon.h"    /* for MOUSE_EVENT_RECORD */ 
  
 struct _DOSEVENT; 
  
@@ -105,6 +106,7 @@ 
 /* int33.c */ 
 extern void WINAPI DOSVM_Int33Handler(CONTEXT86*); 
 extern void WINAPI DOSVM_Int33Message(UINT,WPARAM,LPARAM); 
+extern void WINAPI DOSVM_Int33Console(MOUSE_EVENT_RECORD*); 
  
 /* int67.c */ 
 extern void WINAPI DOSVM_Int67Handler(CONTEXT86*); 




Index: wine/dlls/winedos/dosvm.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosvm.c,v
retrieving revision 1.13
diff -u -r1.13 dosvm.c
--- wine/dlls/winedos/dosvm.c   9 Mar 2002 23:44:32 -0000       1.13
+++ wine/dlls/winedos/dosvm.c   17 Mar 2002 16:34:35 -0000
@@ -245,8 +245,20 @@
       }
       DOSVM_Int09SendScan(scan,msg.Event.KeyEvent.uChar.AsciiChar);
       break;
+    case MOUSE_EVENT:
+      DOSVM_Int33Console(&msg.Event.MouseEvent);
+      break;
+    case WINDOW_BUFFER_SIZE_EVENT:
+      FIXME("unhandled WINDOW_BUFFER_SIZE_EVENT.\n");
+      break;
+    case MENU_EVENT:
+      FIXME("unhandled MENU_EVENT.\n");
+      break;
+    case FOCUS_EVENT:
+      FIXME("unhandled FOCUS_EVENT.\n");
+      break;
     default:
-      FIXME("unhandled console event: %d\n", msg.EventType);
+      FIXME("unknown console event: %d\n", msg.EventType);
     }
   }
 }
@@ -362,36 +374,37 @@
     waitret = MsgWaitForMultipleObjects(1, &obj, FALSE, INFINITE, QS_ALLINPUT);
     if (waitret == WAIT_OBJECT_0) {
       DOSVM_ProcessConsole();
-    }
-    else if (waitret == WAIT_OBJECT_0 + 1) {
-      GetMessageA(&msg, 0, 0, 0);
-      if (msg.hwnd) {
-       /* it's a window message */
-       DOSVM_ProcessMessage(&msg);
-       DispatchMessageA(&msg);
-      } else {
-       /* it's a thread message */
-       switch (msg.message) {
-       case WM_QUIT:
-         /* stop this madness!! */
-         return 0;
-       case WM_USER:
-         /* run passed procedure in this thread */
-         /* (sort of like APC, but we signal the completion) */
-         {
-           DOS_SPC *spc = (DOS_SPC *)msg.lParam;
-           TRACE_(int)("calling %p with arg %08x\n", spc->proc, spc->arg);
-           (spc->proc)(spc->arg);
-           TRACE_(int)("done, signalling event %d\n", msg.wParam);
-           SetEvent(msg.wParam);
+    } else if (waitret == WAIT_OBJECT_0 + 1) {
+      while (PeekMessageA(&msg,0,0,0,PM_REMOVE)) {
+       if (msg.hwnd) {
+         /* it's a window message */
+         DOSVM_ProcessMessage(&msg);
+         DispatchMessageA(&msg);
+       } else {
+         /* it's a thread message */
+         switch (msg.message) {
+         case WM_QUIT:
+           /* stop this madness!! */
+           return 0;
+         case WM_USER:
+           /* run passed procedure in this thread */
+           /* (sort of like APC, but we signal the completion) */
+           {
+             DOS_SPC *spc = (DOS_SPC *)msg.lParam;
+             TRACE_(int)("calling %p with arg %08x\n", spc->proc, spc->arg);
+             (spc->proc)(spc->arg);
+             TRACE_(int)("done, signalling event %d\n", msg.wParam);
+             SetEvent(msg.wParam);
+           }
+           break;
          }
-         break;
        }
       }
+    } else {
+      ERR_(int)("MsgWaitForMultipleObjects returned unexpected value.\n");
+      return 0;
     }
-    else break;
   }
-  return 0;
 }
 
 static WINE_EXCEPTION_FILTER(exception_handler)




Index: wine/dlls/winedos/int33.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int33.c,v
retrieving revision 1.4
diff -u -r1.4 int33.c
--- wine/dlls/winedos/int33.c   9 Mar 2002 23:44:32 -0000       1.4
+++ wine/dlls/winedos/int33.c   17 Mar 2002 16:28:27 -0000
@@ -65,7 +65,8 @@
     FIXME("Hide mouse cursor\n");
     break;
   case 0x03:
-    TRACE("Return mouse position and button status\n");
+    TRACE("Return mouse position and button status: (%d,%d) and %d\n",
+         mouse_info.x, mouse_info.y, mouse_info.but);
     BX_reg(context) = mouse_info.but;
     CX_reg(context) = mouse_info.x;
     DX_reg(context) = mouse_info.y;
@@ -148,6 +149,58 @@
   DPMI_CallRMProc(&ctx, NULL, 0, 0);
 }

+static void QueueMouseRelay(DWORD mx, DWORD my, WORD mask)
+{
+  mouse_info.x = mx;
+  mouse_info.y = my;
+
+  /* Left button down */
+  if(mask & 0x02) {
+    mouse_info.but |= 0x01;
+    mouse_info.llastx = mx;
+    mouse_info.llasty = my;
+    mouse_info.lbcount++;
+  }
+
+  /* Left button up */
+  if(mask & 0x04) {
+    mouse_info.but &= ~0x01;
+  }
+
+  /* Right button down */
+  if(mask & 0x08) {
+    mouse_info.but |= 0x02;
+    mouse_info.rlastx = mx;
+    mouse_info.rlasty = my;
+    mouse_info.rbcount++;
+  }
+
+  /* Right button up */
+  if(mask & 0x10) {
+    mouse_info.but &= ~0x02;
+  }
+
+  /* Middle button down */
+  if(mask & 0x20) {
+    mouse_info.but |= 0x04;
+  }
+
+  /* Middle button up */
+  if(mask & 0x40) {
+    mouse_info.but &= ~0x04;
+  }
+
+  if ((mask & mouse_info.callmask) && mouse_info.callback) {
+    MCALLDATA *data = calloc(1,sizeof(MCALLDATA));
+    data->proc = mouse_info.callback;
+    data->mask = mask & mouse_info.callmask;
+    data->but = mouse_info.but;
+    data->x = mouse_info.x;
+    data->y = mouse_info.y;
+    DOSVM_QueueEvent(-1, DOS_PRIORITY_MOUSE, MouseRelay, data);
+  }
+}
+
 void WINAPI DOSVM_Int33Message(UINT message,WPARAM wParam,LPARAM lParam)
 {
   WORD mask = 0;
@@ -159,54 +212,68 @@
       SX = 640/Width;
     if (!SX) SX=1;
   }
-  mouse_info.x = LOWORD(lParam) * SX;
-  mouse_info.y = HIWORD(lParam) * SY;
+
   switch (message) {
   case WM_MOUSEMOVE:
     mask |= 0x01;
     break;
   case WM_LBUTTONDOWN:
   case WM_LBUTTONDBLCLK:
-    mouse_info.but |= 0x01;
     mask |= 0x02;
-    mouse_info.llastx = mouse_info.x;
-    mouse_info.llasty = mouse_info.y;
-    mouse_info.lbcount++;
     break;
   case WM_LBUTTONUP:
-    mouse_info.but &= ~0x01;
     mask |= 0x04;
     break;
   case WM_RBUTTONDOWN:
   case WM_RBUTTONDBLCLK:
-    mouse_info.but |= 0x02;
     mask |= 0x08;
-    mouse_info.rlastx = mouse_info.x;
-    mouse_info.rlasty = mouse_info.y;
-    mouse_info.rbcount++;
     break;
   case WM_RBUTTONUP:
-    mouse_info.but &= ~0x02;
     mask |= 0x10;
     break;
   case WM_MBUTTONDOWN:
   case WM_MBUTTONDBLCLK:
-    mouse_info.but |= 0x04;
     mask |= 0x20;
     break;
   case WM_MBUTTONUP:
-    mouse_info.but &= ~0x04;
     mask |= 0x40;
     break;
   }
 
-  if ((mask & mouse_info.callmask) && mouse_info.callback) {
-    MCALLDATA *data = calloc(1,sizeof(MCALLDATA));
-    data->proc = mouse_info.callback;
-    data->mask = mask & mouse_info.callmask;
-    data->but = mouse_info.but;
-    data->x = mouse_info.x;
-    data->y = mouse_info.y;
-    DOSVM_QueueEvent(-1, DOS_PRIORITY_MOUSE, MouseRelay, data);
-  }
+  QueueMouseRelay(LOWORD(lParam) * SX,
+                 HIWORD(lParam) * SY,
+                 mask);
+}
+
+void WINAPI DOSVM_Int33Console(MOUSE_EVENT_RECORD *record)
+{
+  unsigned Height, Width;
+  WORD mask = 0;
+  BOOL newLeftButton = record->dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED;
+  BOOL oldLeftButton = mouse_info.but & 0x01;
+  BOOL newRightButton = record->dwButtonState & RIGHTMOST_BUTTON_PRESSED;
+  BOOL oldRightButton = mouse_info.but & 0x02;
+  BOOL newMiddleButton = record->dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED;
+  BOOL oldMiddleButton = mouse_info.but & 0x04;
+
+  if(newLeftButton && !oldLeftButton)
+    mask |= 0x02;
+  else if(!newLeftButton && oldLeftButton)
+    mask |= 0x04;
+
+  if(newRightButton && !oldRightButton)
+    mask |= 0x08;
+  else if(!newRightButton && oldRightButton)
+    mask |= 0x10;
+
+  if(newMiddleButton && !oldMiddleButton)
+    mask |= 0x20;
+  else if(!newMiddleButton && oldMiddleButton)
+    mask |= 0x40;
+ 
+  VGA_GetAlphaMode(&Width, &Height);
+
+  QueueMouseRelay(640 / Width * record->dwMousePosition.X,
+                 200 / Height * record->dwMousePosition.Y,
+                 mask);
 }


-- 
Jukka Heinonen <http://www.iki.fi/jhei/>



More information about the wine-patches mailing list