Skip to content

Commit

Permalink
[NTVDM]
Browse files Browse the repository at this point in the history
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
  • Loading branch information
HBelusca committed Oct 3, 2015
1 parent 7fe1394 commit a2871b3
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 40 deletions.
60 changes: 49 additions & 11 deletions reactos/subsystems/mvdm/ntvdm/emulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}


Expand Down Expand Up @@ -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);
}
}
}

Expand All @@ -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);
Expand Down
130 changes: 101 additions & 29 deletions reactos/subsystems/mvdm/ntvdm/ntvdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);

Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions reactos/subsystems/mvdm/ntvdm/ntvdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit a2871b3

Please sign in to comment.