[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
This commit is contained in:
Hermès Bélusca-Maïto 2015-11-07 23:40:26 +00:00
parent 29d481611e
commit 45a54c5b12
13 changed files with 89 additions and 64 deletions

View 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);
}

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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