[NTVDM]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 3 Oct 2015 02:36:35 +0000 (02:36 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 3 Oct 2015 02:36:35 +0000 (02:36 +0000)
Usability fixes:
- Update the menu each time the user chooses to show or hide the mouse pointer.
- Keep the mouse show state across screenbuffer switches (text/graphics) (half-hackish at the moment; will be elegantly fixed later on).
- Update the floppy disk menu items each time the user mounts / ejects a disk; display the disk image file name currently mounted (CHAR strings used at the moment, WCHAR conversion will follow soon).

svn path=/trunk/; revision=69428

reactos/subsystems/mvdm/ntvdm/emulator.c
reactos/subsystems/mvdm/ntvdm/ntvdm.c
reactos/subsystems/mvdm/ntvdm/ntvdm.h

index bf23138..2f8d98e 100644 (file)
@@ -414,39 +414,69 @@ VOID MountFloppy(IN ULONG DiskNumber)
 #define  OFN_EX_NOPLACESBAR         0x00000001
 #endif // (_WIN32_WINNT >= 0x0500)
 
-    OPENFILENAMEA ofn;
-    CHAR szFile[MAX_PATH] = "";
+    OPENFILENAMEW ofn;
+    WCHAR szFile[MAX_PATH] = L"";
+    UNICODE_STRING ValueString;
+
+    ASSERT(DiskNumber < ARRAYSIZE(GlobalSettings.FloppyDisks));
 
     RtlZeroMemory(&ofn, sizeof(ofn));
     ofn.lStructSize  = sizeof(ofn);
     ofn.hwndOwner    = hConsoleWnd;
-    ofn.lpstrTitle   = "Select a virtual floppy image";
+    ofn.lpstrTitle   = L"Select a virtual floppy image";
     ofn.Flags        = OFN_EXPLORER | OFN_ENABLESIZING | OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
 //  ofn.FlagsEx      = OFN_EX_NOPLACESBAR;
-    ofn.lpstrFilter  = "Virtual floppy images (*.vfd;*.img;*.ima;*.dsk)\0*.vfd;*.img;*.ima;*.dsk\0All files (*.*)\0*.*\0\0";
-    ofn.lpstrDefExt  = "vfd";
+    ofn.lpstrFilter  = L"Virtual floppy images (*.vfd;*.img;*.ima;*.dsk)\0*.vfd;*.img;*.ima;*.dsk\0All files (*.*)\0*.*\0\0";
+    ofn.lpstrDefExt  = L"vfd";
     ofn.nFilterIndex = 0;
     ofn.lpstrFile    = szFile;
     ofn.nMaxFile     = ARRAYSIZE(szFile);
 
-    if (!GetOpenFileNameA(&ofn))
+    if (!GetOpenFileNameW(&ofn))
     {
         DPRINT1("CommDlgExtendedError = %d\n", CommDlgExtendedError());
         return;
     }
 
-    // TODO: Refresh the menu state
+    /* Free the old string */
+    if (GlobalSettings.FloppyDisks[DiskNumber].Buffer)
+        RtlFreeAnsiString(&GlobalSettings.FloppyDisks[DiskNumber]);
+
+    /* Convert the UNICODE string to ANSI and store it */
+    RtlInitEmptyUnicodeString(&ValueString, szFile, wcslen(szFile) * sizeof(WCHAR));
+    ValueString.Length = ValueString.MaximumLength;
+    RtlUnicodeStringToAnsiString(&GlobalSettings.FloppyDisks[DiskNumber], &ValueString, TRUE);
 
-    if (!MountDisk(FLOPPY_DISK, DiskNumber, szFile, !!(ofn.Flags & OFN_READONLY)))
+    /* Mount the disk */
+    if (!MountDisk(FLOPPY_DISK, DiskNumber, GlobalSettings.FloppyDisks[DiskNumber].Buffer, !!(ofn.Flags & OFN_READONLY)))
+    {
         DisplayMessage(L"An error happened when mounting disk %d", DiskNumber);
+        RtlFreeAnsiString(&GlobalSettings.FloppyDisks[DiskNumber]);
+        RtlInitEmptyAnsiString(&GlobalSettings.FloppyDisks[DiskNumber], NULL, 0);
+        return;
+    }
+
+    /* Refresh the menu state */
+    UpdateVdmMenuDisks();
 }
 
 VOID EjectFloppy(IN ULONG DiskNumber)
 {
-    // TODO: Refresh the menu state
+    ASSERT(DiskNumber < ARRAYSIZE(GlobalSettings.FloppyDisks));
 
+    /* Unmount the disk */
     if (!UnmountDisk(FLOPPY_DISK, DiskNumber))
         DisplayMessage(L"An error happened when ejecting disk %d", DiskNumber);
+
+    /* Free the old string */
+    if (GlobalSettings.FloppyDisks[DiskNumber].Buffer)
+    {
+        RtlFreeAnsiString(&GlobalSettings.FloppyDisks[DiskNumber]);
+        RtlInitEmptyAnsiString(&GlobalSettings.FloppyDisks[DiskNumber], NULL, 0);
+    }
+
+    /* Refresh the menu state */
+    UpdateVdmMenuDisks();
 }
 
 
@@ -560,7 +590,12 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
             GlobalSettings.FloppyDisks[i].Buffer      &&
             GlobalSettings.FloppyDisks[i].Buffer != '\0')
         {
-            MountDisk(FLOPPY_DISK, i, GlobalSettings.FloppyDisks[i].Buffer, FALSE);
+            if (!MountDisk(FLOPPY_DISK, i, GlobalSettings.FloppyDisks[i].Buffer, FALSE))
+            {
+                DPRINT1("Failed to mount floppy disk file '%Z'.\n", &GlobalSettings.FloppyDisks[i]);
+                RtlFreeAnsiString(&GlobalSettings.FloppyDisks[i]);
+                RtlInitEmptyAnsiString(&GlobalSettings.FloppyDisks[i], NULL, 0);
+            }
         }
     }
 
@@ -576,13 +611,16 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
         {
             if (!MountDisk(HARD_DISK, i, GlobalSettings.HardDisks[i].Buffer, FALSE))
             {
-                wprintf(L"FATAL: Failed to mount hard disk file '%Z'.\n", &GlobalSettings);
+                wprintf(L"FATAL: Failed to mount hard disk file '%Z'.\n", &GlobalSettings.HardDisks[i]);
                 EmulatorCleanup();
                 return FALSE;
             }
         }
     }
 
+    /* Refresh the menu state */
+    UpdateVdmMenuDisks();
+
     /* Initialize the software callback system and register the emulator BOPs */
     InitializeInt32();
     RegisterBop(BOP_DEBUGGER  , EmulatorDebugBreakBop);
index 29ecf73..d3ef093 100644 (file)
@@ -22,6 +22,8 @@
 
 /* VARIABLES ******************************************************************/
 
+static HANDLE CurrentConsoleOutput = INVALID_HANDLE_VALUE;
+
 static HANDLE ConsoleInput  = INVALID_HANDLE_VALUE;
 static HANDLE ConsoleOutput = INVALID_HANDLE_VALUE;
 static DWORD  OrgConsoleInputMode, OrgConsoleOutputMode;
@@ -35,7 +37,7 @@ WCHAR** NtVdmArgv;
 HWND hConsoleWnd = NULL;
 static HMENU hConsoleMenu  = NULL;
 static INT   VdmMenuPos    = -1;
-static BOOLEAN ShowPointer = FALSE;
+static BOOLEAN ShowPointer = TRUE;
 
 /*
  * Those menu helpers were taken from the GUI frontend in winsrv.dll
@@ -141,6 +143,97 @@ VdmMenuExists(HMENU hConsoleMenu)
     return FALSE;
 }
 
+static VOID
+UpdateVdmMenuMouse(VOID)
+{
+    WCHAR szMenuString[256];
+
+    /* Update "Hide/Show mouse" menu item */
+    if (LoadStringW(GetModuleHandle(NULL),
+                    (!ShowPointer ? IDS_SHOW_MOUSE : IDS_HIDE_MOUSE),
+                    szMenuString,
+                    ARRAYSIZE(szMenuString)) > 0)
+    {
+        ModifyMenuW(hConsoleMenu, ID_SHOWHIDE_MOUSE,
+                    MF_BYCOMMAND, ID_SHOWHIDE_MOUSE, szMenuString);
+    }
+}
+
+/*static*/ VOID
+UpdateVdmMenuDisks(VOID)
+{
+    UINT_PTR ItemID;
+    USHORT i;
+
+    CHAR szNoMedia[100];
+    CHAR szMenuString1[256], szMenuString2[256];
+
+    /* Update the disks menu items */
+
+    LoadStringA(GetModuleHandle(NULL),
+                IDS_NO_MEDIA,
+                szNoMedia,
+                ARRAYSIZE(szNoMedia));
+
+    LoadStringA(GetModuleHandle(NULL),
+                IDS_VDM_MOUNT_FLOPPY,
+                szMenuString1,
+                ARRAYSIZE(szMenuString1));
+
+    for (i = 0; i < ARRAYSIZE(GlobalSettings.FloppyDisks); ++i)
+    {
+        ItemID = ID_VDM_DRIVES + (2 * i);
+
+        if (GlobalSettings.FloppyDisks[i].Length != 0 &&
+            GlobalSettings.FloppyDisks[i].Buffer      &&
+            GlobalSettings.FloppyDisks[i].Buffer != '\0')
+        {
+            /* Update item text */
+            _snprintf(szMenuString2, ARRAYSIZE(szMenuString2), szMenuString1, i, GlobalSettings.FloppyDisks[i].Buffer);
+            szMenuString2[ARRAYSIZE(szMenuString2) - 1] = ANSI_NULL;
+            ModifyMenuA(hConsoleMenu, ItemID, MF_BYCOMMAND | MF_STRING, ItemID, szMenuString2);
+
+            /* Enable the eject item */
+            EnableMenuItem(hConsoleMenu, ItemID + 1, MF_BYCOMMAND | MF_ENABLED);
+        }
+        else
+        {
+            /* Update item text */
+            _snprintf(szMenuString2, ARRAYSIZE(szMenuString2), szMenuString1, i, szNoMedia);
+            szMenuString2[ARRAYSIZE(szMenuString2) - 1] = ANSI_NULL;
+            ModifyMenuA(hConsoleMenu, ItemID, MF_BYCOMMAND | MF_STRING, ItemID, szMenuString2);
+
+            /* Disable the eject item */
+            EnableMenuItem(hConsoleMenu, ItemID + 1, MF_BYCOMMAND | MF_GRAYED);
+        }
+    }
+}
+
+static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr)
+{
+    if (ShowPtr)
+    {
+        /* Be sure the cursor will be shown */
+        while (ShowConsoleCursor(ConOutHandle, TRUE) < 0) ;
+    }
+    else
+    {
+        /* Be sure the cursor will be hidden */
+        while (ShowConsoleCursor(ConOutHandle, FALSE) >= 0) ;
+    }
+}
+
+static VOID
+UpdateVdmMenu(VOID)
+{
+    // This is a temporary HACK until I find the most elegant way
+    // to synchronize mouse cursor display with console screenbuffer switches.
+    ShowHideMousePointer(CurrentConsoleOutput, ShowPointer);
+
+    UpdateVdmMenuMouse();
+    UpdateVdmMenuDisks();
+}
+
 /*static*/ VOID
 CreateVdmMenu(HANDLE ConOutHandle)
 {
@@ -155,6 +248,8 @@ CreateVdmMenu(HANDLE ConOutHandle)
                                       ID_VDM_DRIVES + 4);
     if (hConsoleMenu == NULL) return;
 
+    CurrentConsoleOutput = ConOutHandle;
+
     /* Get the position where we are going to insert our menu items */
     VdmMenuPos = GetMenuItemCount(hConsoleMenu);
 
@@ -203,9 +298,8 @@ CreateVdmMenu(HANDLE ConOutHandle)
         szMenuString2[ARRAYSIZE(szMenuString2) - 1] = UNICODE_NULL;
         InsertMenuW(hVdmSubMenu, Pos++, MF_STRING | MF_BYPOSITION, ItemID + 3, szMenuString2);
 
-        // TODO: Refresh the menu state
-
-        /* Refresh the menu */
+        /* Refresh the menu state */
+        UpdateVdmMenu();
         DrawMenuBar(hConsoleWnd);
     }
 }
@@ -223,31 +317,8 @@ DestroyVdmMenu(VOID)
     } while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].uCmdID == 0));
 
     DrawMenuBar(hConsoleWnd);
-}
 
-static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr)
-{
-    WCHAR szMenuString[256];
-
-    if (ShowPtr)
-    {
-        /* Be sure the cursor will be shown */
-        while (ShowConsoleCursor(ConOutHandle, TRUE) < 0) ;
-    }
-    else
-    {
-        /* Be sure the cursor will be hidden */
-        while (ShowConsoleCursor(ConOutHandle, FALSE) >= 0) ;
-    }
-
-    if (LoadStringW(GetModuleHandle(NULL),
-                    (!ShowPtr ? IDS_SHOW_MOUSE : IDS_HIDE_MOUSE),
-                    szMenuString,
-                    ARRAYSIZE(szMenuString)) > 0)
-    {
-        ModifyMenu(hConsoleMenu, ID_SHOWHIDE_MOUSE,
-                   MF_BYCOMMAND, ID_SHOWHIDE_MOUSE, szMenuString);
-    }
+    CurrentConsoleOutput = INVALID_HANDLE_VALUE;
 }
 
 static VOID EnableExtraHardware(HANDLE ConsoleInput)
@@ -859,8 +930,9 @@ VOID MenuEventHandler(PMENU_EVENT_RECORD MenuEvent)
     switch (MenuEvent->dwCommandId)
     {
         case ID_SHOWHIDE_MOUSE:
-            ShowHideMousePointer(ConsoleOutput, ShowPointer);
             ShowPointer = !ShowPointer;
+            ShowHideMousePointer(CurrentConsoleOutput, ShowPointer);
+            UpdateVdmMenuMouse();
             break;
 
         case ID_VDM_DUMPMEM_TXT:
index e1d48e4..42af547 100644 (file)
@@ -103,6 +103,8 @@ VOID PrintMessageAnsi(IN CHAR_PRINT CharPrint,
 CreateVdmMenu(HANDLE ConOutHandle);
 /*static*/ VOID
 DestroyVdmMenu(VOID);
+/*static*/ VOID
+UpdateVdmMenuDisks(VOID);
 
 BOOL ConsoleAttach(VOID);
 VOID ConsoleDetach(VOID);