[NTVDM]: Implement mouse capture. There are still "bugs" remaining, namely, if somebo...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 7 Nov 2015 23:40:26 +0000 (23:40 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 7 Nov 2015 23:40:26 +0000 (23:40 +0000)
svn path=/trunk/; revision=69843

13 files changed:
reactos/subsystems/mvdm/ntvdm/console/console.c
reactos/subsystems/mvdm/ntvdm/lang/cs-CZ.rc
reactos/subsystems/mvdm/ntvdm/lang/de-DE.rc
reactos/subsystems/mvdm/ntvdm/lang/en-US.rc
reactos/subsystems/mvdm/ntvdm/lang/es-ES.rc
reactos/subsystems/mvdm/ntvdm/lang/fr-FR.rc
reactos/subsystems/mvdm/ntvdm/lang/it-IT.rc
reactos/subsystems/mvdm/ntvdm/lang/pl-PL.rc
reactos/subsystems/mvdm/ntvdm/lang/ro-RO.rc
reactos/subsystems/mvdm/ntvdm/lang/ru-RU.rc
reactos/subsystems/mvdm/ntvdm/lang/tr-TR.rc
reactos/subsystems/mvdm/ntvdm/lang/zh-CN.rc
reactos/subsystems/mvdm/ntvdm/resource.h

index 9884e44..72200a1 100644 (file)
@@ -18,9 +18,9 @@ static HANDLE ConsoleOutput = INVALID_HANDLE_VALUE;
 static DWORD  OrgConsoleInputMode, OrgConsoleOutputMode;
 
 HWND hConsoleWnd = NULL;
-static HMENU hConsoleMenu  = NULL;
-static INT   VdmMenuPos    = -1;
-static BOOLEAN ShowPointer = TRUE;
+static HMENU hConsoleMenu = NULL;
+static INT   VdmMenuPos   = -1;
+static BOOL  CaptureMouse = FALSE;
 
 /*
  * Those menu helpers were taken from the GUI frontend in winsrv.dll
@@ -48,8 +48,8 @@ static const VDM_MENUITEM VdmMenuItems[] =
 static const VDM_MENUITEM VdmMainMenuItems[] =
 {
     { -1, NULL, 0 },    /* Separator */
-    { IDS_HIDE_MOUSE,   NULL, ID_SHOWHIDE_MOUSE },  /* "Hide mouse"; can be renamed to "Show mouse" */
-    { IDS_VDM_MENU  ,   VdmMenuItems,         0 },  /* ReactOS VDM Menu */
+    { IDS_CAPTURE_MOUSE, NULL, ID_CAPTURE_MOUSE },  /* "Capture mouse"; can be renamed to "Release mouse" */
+    { IDS_VDM_MENU , VdmMenuItems, 0 },             /* ReactOS VDM Menu */
 
     { 0, NULL, 0 }      /* End of list */
 };
@@ -116,7 +116,7 @@ VdmMenuExists(HMENU hConsoleMenu)
     /* Check for the presence of one of the VDM menu items */
     for (i = 0; i <= MenuPos; i++)
     {
-        if (GetMenuItemID(hConsoleMenu, i) == ID_SHOWHIDE_MOUSE)
+        if (GetMenuItemID(hConsoleMenu, i) == ID_CAPTURE_MOUSE)
         {
             /* Set VdmMenuPos to the position of the existing menu */
             VdmMenuPos = i - 1;
@@ -131,14 +131,14 @@ UpdateVdmMenuMouse(VOID)
 {
     WCHAR szMenuString[256];
 
-    /* Update "Hide/Show mouse" menu item */
+    /* Update "Capture/Release mouse" menu item */
     if (LoadStringW(GetModuleHandle(NULL),
-                    (!ShowPointer ? IDS_SHOW_MOUSE : IDS_HIDE_MOUSE),
+                    (CaptureMouse ? IDS_RELEASE_MOUSE : IDS_CAPTURE_MOUSE),
                     szMenuString,
                     ARRAYSIZE(szMenuString)) > 0)
     {
-        ModifyMenuW(hConsoleMenu, ID_SHOWHIDE_MOUSE,
-                    MF_BYCOMMAND, ID_SHOWHIDE_MOUSE, szMenuString);
+        ModifyMenuW(hConsoleMenu, ID_CAPTURE_MOUSE,
+                    MF_BYCOMMAND, ID_CAPTURE_MOUSE, szMenuString);
     }
 }
 
@@ -210,7 +210,7 @@ CreateVdmMenu(HANDLE ConOutHandle)
     WCHAR szMenuString1[256], szMenuString2[256];
 
     hConsoleMenu = ConsoleMenuControl(ConOutHandle,
-                                      ID_SHOWHIDE_MOUSE,
+                                      ID_CAPTURE_MOUSE,
                                       ID_VDM_DRIVES + (2 * ARRAYSIZE(GlobalSettings.FloppyDisks)));
     if (hConsoleMenu == NULL) return;
 
@@ -285,17 +285,33 @@ DestroyVdmMenu(VOID)
     DrawMenuBar(hConsoleWnd);
 }
 
-static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr)
+static VOID CaptureMousePointer(HANDLE ConOutHandle, BOOLEAN Capture)
 {
-    if (ShowPtr)
+    static BOOL IsClipped = FALSE; // For debugging purposes
+    UNREFERENCED_PARAMETER(IsClipped);
+
+    if (Capture)
     {
-        /* Be sure the cursor will be shown */
-        while (ShowConsoleCursor(ConOutHandle, TRUE) < 0) ;
+        RECT rcClip;
+
+        // if (IsClipped) return;
+
+        /* Be sure the cursor will be hidden */
+        while (ShowConsoleCursor(ConOutHandle, FALSE) >= 0) ;
+
+        GetClientRect(hConsoleWnd, &rcClip);
+        MapWindowPoints(hConsoleWnd, HWND_DESKTOP /*NULL*/, (LPPOINT)&rcClip, 2 /* Magic value when the LPPOINT parameter is a RECT */);
+        IsClipped = ClipCursor(&rcClip);
     }
     else
     {
-        /* Be sure the cursor will be hidden */
-        while (ShowConsoleCursor(ConOutHandle, FALSE) >= 0) ;
+        // if (!IsClipped) return;
+
+        ClipCursor(NULL);
+        IsClipped = FALSE;
+
+        /* Be sure the cursor will be shown */
+        while (ShowConsoleCursor(ConOutHandle, TRUE) < 0) ;
     }
 }
 
@@ -373,7 +389,7 @@ static VOID
 ConsoleCleanupUI(VOID)
 {
     /* Display again properly the mouse pointer */
-    if (ShowPointer) ShowHideMousePointer(ConsoleOutput, ShowPointer);
+    if (CaptureMouse) CaptureMousePointer(ConsoleOutput, !CaptureMouse);
 
     DestroyVdmMenu();
 }
@@ -423,7 +439,7 @@ ConsoleReattach(HANDLE ConOutHandle)
     CreateVdmMenu(ConOutHandle);
 
     /* Synchronize mouse cursor display with console screenbuffer switches */
-    ShowHideMousePointer(CurrentConsoleOutput, ShowPointer);
+    CaptureMousePointer(CurrentConsoleOutput, CaptureMouse);
 }
 
 static BOOL
@@ -493,21 +509,25 @@ VOID MenuEventHandler(PMENU_EVENT_RECORD MenuEvent)
          */
 
         case WM_INITMENU:
-            DPRINT1("WM_INITMENU\n");
-            break;
-
         case WM_MENUSELECT:
-            DPRINT1("WM_MENUSELECT\n");
+        {
+            /*
+             * If the mouse is captured, release it or recapture it
+             * when the menu opens or closes, respectively.
+             */
+            if (!CaptureMouse) break;
+            CaptureMousePointer(CurrentConsoleOutput, MenuEvent->dwCommandId == WM_INITMENU ? FALSE : TRUE);
             break;
+        }
 
 
         /*
          * User-defined menu commands
          */
 
-        case ID_SHOWHIDE_MOUSE:
-            ShowPointer = !ShowPointer;
-            ShowHideMousePointer(CurrentConsoleOutput, ShowPointer);
+        case ID_CAPTURE_MOUSE:
+            CaptureMouse = !CaptureMouse;
+            CaptureMousePointer(CurrentConsoleOutput, CaptureMouse);
             UpdateVdmMenuMouse();
             break;
 
@@ -555,5 +575,10 @@ VOID MenuEventHandler(PMENU_EVENT_RECORD MenuEvent)
 
 VOID FocusEventHandler(PFOCUS_EVENT_RECORD FocusEvent)
 {
-    DPRINT1("Focus events not handled\n");
+    /*
+     * If the mouse is captured, release it or recapture it
+     * when we lose or regain focus, respectively.
+     */
+    if (!CaptureMouse) return;
+    CaptureMousePointer(CurrentConsoleOutput, FocusEvent->bSetFocus);
 }
index 2630fc7..c69b761 100644 (file)
@@ -8,9 +8,9 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "&Skrýt ukazatel myši"
-    IDS_SHOW_MOUSE, "&Zobrazit ukazatel myši"
-    IDS_VDM_MENU  , "ReactOS &VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index a516cce..ecf0579 100644 (file)
@@ -2,9 +2,9 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "Mauszeiger &verstecken"
-    IDS_SHOW_MOUSE, "Mauszeiger &anzeigen"
-    IDS_VDM_MENU  , "&ReactOS VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index db723cc..e90629a 100644 (file)
@@ -2,9 +2,9 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "&Hide Mouse Pointer"
-    IDS_SHOW_MOUSE, "&Display Mouse Pointer"
-    IDS_VDM_MENU  , "ReactOS &VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index 63fe3f0..c9154ac 100644 (file)
@@ -2,9 +2,9 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "&Ocultar puntero del ratón"
-    IDS_SHOW_MOUSE, "&Mostrar puntero del ratón"
-    IDS_VDM_MENU  , "ReactOS &VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index e796a03..2175ca3 100644 (file)
@@ -2,9 +2,9 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "Mas&quer le pointeur de la souris"
-    IDS_SHOW_MOUSE, "&Afficher le pointeur de la souris"
-    IDS_VDM_MENU  , "ReactOS &VDM"
+    IDS_CAPTURE_MOUSE, "&Capturer le pointeur de la souris"
+    IDS_RELEASE_MOUSE, "&Libérer le pointeur de la souris"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index 293fe38..18634a5 100644 (file)
@@ -2,9 +2,9 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "&Nascondi il mouse"
-    IDS_SHOW_MOUSE, "&Mostra il mouse"
-    IDS_VDM_MENU  , "ReactOS &VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index f46112e..a5df819 100644 (file)
@@ -4,9 +4,9 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "&Ukryj Wskaźnik Myszki"
-    IDS_SHOW_MOUSE, "&Pokaż Wskaźnik Myszki"
-    IDS_VDM_MENU  , "ReactOS &VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index 382c09e..a0a4f96 100644 (file)
@@ -3,9 +3,9 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "Asc&unde indicatorul șoricelului"
-    IDS_SHOW_MOUSE, "Afișea&ză indicatorul șoricelului"
-    IDS_VDM_MENU  , "ReactOS &VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index 0014996..0bfacdb 100644 (file)
@@ -2,9 +2,9 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "&Спрятать указатель мыши"
-    IDS_SHOW_MOUSE, "&Отобразить указатель мыши"
-    IDS_VDM_MENU  , "ReactOS &VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index d4b984b..fa39f4b 100644 (file)
@@ -4,9 +4,9 @@ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "&Fâre İmlecini Gizle"
-    IDS_SHOW_MOUSE, "Fâre &İmlecini Göster"
-    IDS_VDM_MENU  , "&ReactOS VDM"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS &VDM"
 END
 
 STRINGTABLE
index 9f8f83a..8155f9f 100644 (file)
@@ -4,9 +4,9 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 
 STRINGTABLE
 BEGIN
-    IDS_HIDE_MOUSE, "隐藏鼠标指针 (&H)"
-    IDS_SHOW_MOUSE, "显示鼠标指针 (&D)"
-    IDS_VDM_MENU  , "ReactOS DOS 虚拟机 (&V)"
+    IDS_CAPTURE_MOUSE, "&Capture Mouse Pointer"
+    IDS_RELEASE_MOUSE, "&Release Mouse Pointer"
+    IDS_VDM_MENU     , "ReactOS DOS 虚拟机 (&V)"
 END
 
 STRINGTABLE
index 1de5417..d2c5974 100644 (file)
@@ -1,7 +1,7 @@
 #pragma once
 
 /* Menu IDs */
-#define ID_SHOWHIDE_MOUSE   1000
+#define ID_CAPTURE_MOUSE    1000
 #define ID_VDM_DUMPMEM_TXT  1001
 #define ID_VDM_DUMPMEM_BIN  1002
 #define ID_VDM_QUIT         1003
@@ -10,9 +10,9 @@
 #define ID_VDM_DRIVES       1010
 
 /* String IDs */
-#define IDS_HIDE_MOUSE  100
-#define IDS_SHOW_MOUSE  101
-#define IDS_VDM_MENU    102
+#define IDS_CAPTURE_MOUSE   100
+#define IDS_RELEASE_MOUSE   101
+#define IDS_VDM_MENU        102
 
 #define IDS_VDM_DUMPMEM_TXT     200
 #define IDS_VDM_DUMPMEM_BIN     201