From: Hermès Bélusca-Maïto Date: Sat, 7 Nov 2015 23:40:26 +0000 (+0000) Subject: [NTVDM]: Implement mouse capture. There are still "bugs" remaining, namely, if somebo... X-Git-Tag: ReactOS-0.4.0~215 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=45a54c5b12994a7a2779cb57b5c75573da446c4d [NTVDM]: Implement mouse capture. There are still "bugs" remaining, namely, if somebody moves the NTVDM console window, or, if resolution changes, the mouse clip rectangle is not recomputed. This is left as an exercice for the programmer (or, if I don't find patches in Jira soon, I or somebody else will fix it). svn path=/trunk/; revision=69843 --- diff --git a/reactos/subsystems/mvdm/ntvdm/console/console.c b/reactos/subsystems/mvdm/ntvdm/console/console.c index 9884e446adc..72200a103a2 100644 --- a/reactos/subsystems/mvdm/ntvdm/console/console.c +++ b/reactos/subsystems/mvdm/ntvdm/console/console.c @@ -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); } diff --git a/reactos/subsystems/mvdm/ntvdm/lang/cs-CZ.rc b/reactos/subsystems/mvdm/ntvdm/lang/cs-CZ.rc index 2630fc7406c..c69b7619273 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/cs-CZ.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/cs-CZ.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/de-DE.rc b/reactos/subsystems/mvdm/ntvdm/lang/de-DE.rc index a516cce5bb1..ecf05791a13 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/de-DE.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/de-DE.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/en-US.rc b/reactos/subsystems/mvdm/ntvdm/lang/en-US.rc index db723cc225a..e90629ac62f 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/en-US.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/en-US.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/es-ES.rc b/reactos/subsystems/mvdm/ntvdm/lang/es-ES.rc index 63fe3f0aab9..c9154ac02db 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/es-ES.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/es-ES.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/fr-FR.rc b/reactos/subsystems/mvdm/ntvdm/lang/fr-FR.rc index e796a0333e9..2175ca3076c 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/fr-FR.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/fr-FR.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/it-IT.rc b/reactos/subsystems/mvdm/ntvdm/lang/it-IT.rc index 293fe38d5d7..18634a5d44f 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/it-IT.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/it-IT.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/pl-PL.rc b/reactos/subsystems/mvdm/ntvdm/lang/pl-PL.rc index f46112edbb1..a5df819b0cc 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/pl-PL.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/pl-PL.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/ro-RO.rc b/reactos/subsystems/mvdm/ntvdm/lang/ro-RO.rc index 382c09ecc15..a0a4f965277 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/ro-RO.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/ro-RO.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/ru-RU.rc b/reactos/subsystems/mvdm/ntvdm/lang/ru-RU.rc index 00149965224..0bfacdb36d4 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/ru-RU.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/ru-RU.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/tr-TR.rc b/reactos/subsystems/mvdm/ntvdm/lang/tr-TR.rc index d4b984bbfb1..fa39f4b6477 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/tr-TR.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/tr-TR.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/lang/zh-CN.rc b/reactos/subsystems/mvdm/ntvdm/lang/zh-CN.rc index 9f8f83a3873..8155f9fdb7f 100644 --- a/reactos/subsystems/mvdm/ntvdm/lang/zh-CN.rc +++ b/reactos/subsystems/mvdm/ntvdm/lang/zh-CN.rc @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/resource.h b/reactos/subsystems/mvdm/ntvdm/resource.h index 1de54171192..d2c59746dca 100644 --- a/reactos/subsystems/mvdm/ntvdm/resource.h +++ b/reactos/subsystems/mvdm/ntvdm/resource.h @@ -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