Author: aandrejevic
Date: Fri May  2 21:17:05 2014
New Revision: 63119

URL: http://svn.reactos.org/svn/reactos?rev=63119&view=rev
Log:
[NTVDM]
Restore the console to normal size while no DOS task is running and keep track
of the cursor position.
Adapted from a patch by Hermès Bélusca-Maïto.


Modified:
    branches/ntvdm/subsystems/ntvdm/dos/dem.c
    branches/ntvdm/subsystems/ntvdm/hardware/vga.c
    branches/ntvdm/subsystems/ntvdm/hardware/vga.h
    branches/ntvdm/subsystems/ntvdm/ntvdm.c

Modified: branches/ntvdm/subsystems/ntvdm/dos/dem.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos/dem.c?rev=63119&r1=63118&r2=63119&view=diff
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos/dem.c   [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos/dem.c   [iso-8859-1] Fri May  2 
21:17:05 2014
@@ -20,6 +20,9 @@
 #include "dem.h"
 #include "bop.h"
 
+#include "bios/bios.h"
+#include "hardware/vga.h"
+
 /* Extra PSDK/NDK Headers */
 #include <ndk/obtypes.h>
 
@@ -117,7 +120,7 @@
             STARTUPINFOA StartupInfo;
             PROCESS_INFORMATION ProcessInformation;
 
-            /* Remove return carriage character */
+            /* NULL-terminate the command by removing the return carriage 
character */
             while (*CmdPtr != '\r') CmdPtr++;
             *CmdPtr = '\0';
 
@@ -135,7 +138,8 @@
 
             StartupInfo.cb = sizeof(StartupInfo);
 
-            DosPrintCharacter('\n');
+            VgaRefreshDisplay();
+            VgaDetachFromConsole(FALSE);
 
             Result = CreateProcessA(NULL,
                                     CommandLine,
@@ -166,8 +170,10 @@
                 DPRINT1("Failed when launched command '%s'\n");
                 dwExitCode = GetLastError();
             }
-            
-            DosPrintCharacter('\n');
+
+            VgaAttachToConsole();
+            VgaRefreshDisplay();
+            VidBiosSyncCursorPosition();
 
             setAL((UCHAR)dwExitCode);
 

Modified: branches/ntvdm/subsystems/ntvdm/hardware/vga.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/hardware/vga.c?rev=63119&r1=63118&r2=63119&view=diff
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/hardware/vga.c      [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/hardware/vga.c      [iso-8859-1] Fri May  2 
21:17:05 2014
@@ -12,6 +12,7 @@
 
 #include "emulator.h"
 #include "vga.h"
+#include "../bios/vidbios.h"
 
 #include "io.h"
 
@@ -189,6 +190,10 @@
 static HANDLE EndEvent   = NULL;
 static HANDLE AnotherEvent = NULL;
 
+static CONSOLE_CURSOR_INFO         OrgConsoleCursorInfo;
+static CONSOLE_SCREEN_BUFFER_INFO  OrgConsoleBufferInfo;
+
+
 /*
  * Text mode -- we always keep a valid text mode framebuffer
  * even if we are in graphics mode. This is needed in order to
@@ -403,8 +408,24 @@
 /* PRIVATE FUNCTIONS 
**********************************************************/
 
 static inline DWORD VgaGetAddressSize(VOID);
-
-static BOOL VgaAttachToConsole(PCOORD Resolution)
+static VOID VgaUpdateTextCursor(VOID);
+
+static VOID VgaUpdateCursorPosition(VOID)
+{
+    /*
+     * Update the cursor position in the VGA registers.
+     */
+    WORD Offset = ConsoleInfo.dwCursorPosition.Y * TextResolution.X +
+                  ConsoleInfo.dwCursorPosition.X;
+
+    VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_LOW_REG]  = LOBYTE(Offset);
+    VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG] = HIBYTE(Offset);
+
+    VidBiosSyncCursorPosition();
+    VgaUpdateTextCursor();
+}
+
+static BOOL VgaAttachToConsoleInternal(PCOORD Resolution)
 {
     BOOL Success;
     ULONG Length = 0;
@@ -414,12 +435,10 @@
     DWORD AddressSize, ScanlineSize;
     DWORD Address = 0;
     DWORD CurrentAddr;
-    SMALL_RECT ScreenRect; // ConRect;
+    SMALL_RECT ConRect;
     COORD Origin = { 0, 0 };
 
     ASSERT(TextFramebuffer == NULL);
-
-    // ResetEvent(AnotherEvent);
 
     TextResolution = *Resolution;
 
@@ -454,504 +473,9 @@
         return FALSE;
     }
 
-    /* Copy console data into VGA memory */
-
-    /* Get the data */
-    AddressSize = VgaGetAddressSize();
-    ScreenRect.Left = ScreenRect.Top = 0;
-    ScreenRect.Right  = TextResolution.X;
-    ScreenRect.Bottom = TextResolution.Y;
-
-    // ConRect.Left   = 0;
-    // ConRect.Top    = ConsoleSize->Y - BufferSize.Y;
-    // ConRect.Right  = ConRect.Left + BufferSize.X - 1;
-    // ConRect.Bottom = ConRect.Top  + BufferSize.Y - 1;
-
-    ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
-
-    /* Read the data from the console into the framebuffer... */
-    ReadConsoleOutputA(TextConsoleBuffer,
-                       CharBuff,
-                       TextResolution,
-                       Origin,
-                       &ScreenRect); // &ConRect);
-
-    /* ... and copy the framebuffer into the VGA memory */
-
-    /* Loop through the scanlines */
-    for (i = 0; i < TextResolution.Y; i++)
-    {
-        /* Loop through the characters */
-        for (j = 0; j < TextResolution.X; j++)
-        {
-            CurrentAddr = LOWORD((Address + j) * AddressSize);
-
-            /* Store the character in plane 0 */
-            VgaMemory[CurrentAddr] = CharBuff[i * TextResolution.X + 
j].Char.AsciiChar;
-
-            /* Store the attribute in plane 1 */
-            VgaMemory[CurrentAddr + VGA_BANK_SIZE] = (BYTE)CharBuff[i * 
TextResolution.X + j].Attributes;
-        }
-
-        /* Move to the next scanline */
-        Address += ScanlineSize;
-    }
-
-    return TRUE;
-}
-
-static VOID VgaDetachFromConsole(VOID)
-{
-    ULONG dummyLength;
-    PVOID dummyPtr;
-    COORD dummySize = {0};
-
-    __RegisterConsoleVDM(0,
-                         NULL,
-                         NULL,
-                         NULL,
-                         0,
-                         &dummyLength,
-                         &dummyPtr,
-                         NULL,
-                         0,
-                         dummySize,
-                         (PCHAR*)&dummyPtr);
-
-    TextFramebuffer = NULL;
-}
-
-static BOOL IsConsoleHandle(HANDLE hHandle)
-{
-    DWORD dwMode;
-
-    /* Check whether the handle may be that of a console... */
-    if ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR)
-        return FALSE;
-
     /*
-     * It may be. Perform another test... The idea comes from the
-     * MSDN description of the WriteConsole API:
-     *
-     * "WriteConsole fails if it is used with a standard handle
-     *  that is redirected to a file. If an application processes
-     *  multilingual output that can be redirected, determine whether
-     *  the output handle is a console handle (one method is to call
-     *  the GetConsoleMode function and check whether it succeeds).
-     *  If the handle is a console handle, call WriteConsole. If the
-     *  handle is not a console handle, the output is redirected and
-     *  you should call WriteFile to perform the I/O."
+     * Resize the console
      */
-    return GetConsoleMode(hHandle, &dwMode);
-}
-
-static inline DWORD VgaGetAddressSize(VOID)
-{
-    if (VgaCrtcRegisters[VGA_CRTC_UNDERLINE_REG] & VGA_CRTC_UNDERLINE_DWORD)
-    {
-        /* Double-word addressing */
-        return 4; // sizeof(DWORD)
-    }
-    else if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] & 
VGA_CRTC_MODE_CONTROL_BYTE)
-    {
-        /* Byte addressing */
-        return 1; // sizeof(BYTE)
-    }
-    else
-    {
-        /* Word addressing */
-        return 2; // sizeof(WORD)
-    }
-}
-
-static inline DWORD VgaTranslateReadAddress(DWORD Address)
-{
-    DWORD Offset = Address - VgaGetVideoBaseAddress();
-    BYTE Plane;
-
-    /* Check for chain-4 and odd-even mode */
-    if (VgaSeqRegisters[VGA_SEQ_MEM_REG] & VGA_SEQ_MEM_C4)
-    {
-        /* The lowest two bits are the plane number */
-        Plane = Offset & 3;
-        Offset >>= 2;
-    }
-    else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_OE)
-    {
-        /* The LSB is the plane number */
-        Plane = Offset & 1;
-        Offset >>= 1;
-    }
-    else
-    {
-        /* Use the read mode */
-        Plane = VgaGcRegisters[VGA_GC_READ_MAP_SEL_REG] & 0x03;
-    }
-
-    /* Multiply the offset by the address size */
-    Offset *= VgaGetAddressSize();
-    
-    return Offset + Plane * VGA_BANK_SIZE;
-}
-
-static inline DWORD VgaTranslateWriteAddress(DWORD Address)
-{
-    DWORD Offset = Address - VgaGetVideoBaseAddress();
-
-    /* Check for chain-4 and odd-even mode */
-    if (VgaSeqRegisters[VGA_SEQ_MEM_REG] & VGA_SEQ_MEM_C4)
-    {
-        /* Shift the offset to the right by 2 */
-        Offset >>= 2;
-    }
-    else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_OE)
-    {
-        /* Shift the offset to the right by 1 */
-        Offset >>= 1;
-    }
-
-    /* Multiply the offset by the address size */
-    Offset *= VgaGetAddressSize();
-
-    /* Return the offset on plane 0 */
-    return Offset;
-}
-
-static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane)
-{
-    BYTE WriteMode = VgaGcRegisters[VGA_GC_MODE_REG] & 3;
-    BYTE BitMask = VgaGcRegisters[VGA_GC_BITMASK_REG];
-
-    if (WriteMode == 1)
-    {
-        /* In write mode 1 just return the latch register */
-        return VgaLatchRegisters[Plane];
-    }
-
-    if (WriteMode != 2)
-    {
-        /* Write modes 0 and 3 rotate the data to the right first */
-        BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7;
-        Data = LOBYTE(((DWORD)Data >> RotateCount) | ((DWORD)Data << (8 - 
RotateCount)));
-    }
-    else
-    {
-        /* Write mode 2 expands the appropriate bit to all 8 bits */
-        Data = (Data & (1 << Plane)) ? 0xFF : 0x00;
-    }
-
-    if (WriteMode == 0)
-    {
-        /*
-         * In write mode 0, the enable set/reset register decides if the
-         * set/reset bit should be expanded to all 8 bits.
-         */
-        if (VgaGcRegisters[VGA_GC_ENABLE_RESET_REG] & (1 << Plane))
-        {
-            /* Copy the bit from the set/reset register to all 8 bits */
-            Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF : 
0x00;
-        }
-    }
-
-    if (WriteMode != 3)
-    {
-        /* Write modes 0 and 2 then perform a logical operation on the data 
and latch */
-        BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3;
-
-        if (LogicalOperation == 1) Data &= VgaLatchRegisters[Plane];
-        else if (LogicalOperation == 2) Data |= VgaLatchRegisters[Plane];
-        else if (LogicalOperation == 3) Data ^= VgaLatchRegisters[Plane];
-    }
-    else
-    {
-        /* For write mode 3, we AND the bitmask with the data, which is used 
as the new bitmask */
-        BitMask &= Data;
-
-        /* Then we expand the bit in the set/reset field */
-        Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF : 0x00;
-    }
-
-    /* Bits cleared in the bitmask are replaced with latch register bits */
-    Data = (Data & BitMask) | (VgaLatchRegisters[Plane] & (~BitMask));
-
-    /* Return the byte */
-    return Data;
-}
-
-static inline VOID VgaMarkForUpdate(SHORT Row, SHORT Column)
-{
-    /* Check if this is the first time the rectangle is updated */
-    if (!NeedsUpdate)
-    {
-        UpdateRectangle.Left = UpdateRectangle.Top = MAXSHORT;
-        UpdateRectangle.Right = UpdateRectangle.Bottom = MINSHORT;
-    }
-
-    /* Expand the rectangle to include the point */
-    UpdateRectangle.Left = min(UpdateRectangle.Left, Column);
-    UpdateRectangle.Right = max(UpdateRectangle.Right, Column);
-    UpdateRectangle.Top = min(UpdateRectangle.Top, Row);
-    UpdateRectangle.Bottom = max(UpdateRectangle.Bottom, Row);
-
-    /* Set the update request flag */
-    NeedsUpdate = TRUE;
-}
-
-static VOID VgaWriteSequencer(BYTE Data)
-{
-    ASSERT(VgaSeqIndex < VGA_SEQ_MAX_REG);
-
-    /* Save the value */
-    VgaSeqRegisters[VgaSeqIndex] = Data;
-}
-
-static VOID VgaWriteGc(BYTE Data)
-{
-    ASSERT(VgaGcIndex < VGA_GC_MAX_REG);
-
-    /* Save the value */
-    VgaGcRegisters[VgaGcIndex] = Data;
-
-    /* Check the index */
-    switch (VgaGcIndex)
-    {
-        case VGA_GC_MISC_REG:
-        {
-            /* The GC misc register decides if it's text or graphics mode */
-            ModeChanged = TRUE;
-            break;
-        }
-    }
-}
-
-static VOID VgaWriteCrtc(BYTE Data)
-{
-    ASSERT(VgaGcIndex < VGA_CRTC_MAX_REG);
-
-    /* Save the value */
-    VgaCrtcRegisters[VgaCrtcIndex] = Data;
-
-    /* Check the index */
-    switch (VgaCrtcIndex)
-    {
-        case VGA_CRTC_END_HORZ_DISP_REG:
-        case VGA_CRTC_VERT_DISP_END_REG:
-        case VGA_CRTC_OVERFLOW_REG:
-        {
-            /* The video mode has changed */
-            ModeChanged = TRUE;
-            break;
-        }
-
-        case VGA_CRTC_CURSOR_LOC_LOW_REG:
-        case VGA_CRTC_CURSOR_LOC_HIGH_REG:
-        case VGA_CRTC_CURSOR_START_REG:
-        case VGA_CRTC_CURSOR_END_REG:
-        {
-            /* Set the cursor moved flag */
-            CursorMoved = TRUE;
-            break;
-        }
-    }
-}
-
-static VOID VgaWriteDac(BYTE Data)
-{
-    INT PaletteIndex;
-    PALETTEENTRY Entry;
-
-    /* Set the value */
-    VgaDacRegisters[VgaDacIndex] = Data;
-
-    /* Find the palette index */
-    PaletteIndex = VgaDacIndex / 3;
-
-    /* Fill the entry structure */
-    Entry.peRed = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3]);
-    Entry.peGreen = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 1]);
-    Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 2]);
-    Entry.peFlags = 0;
-
-    /* Update the palette entry and set the palette change flag */
-    SetPaletteEntries(PaletteHandle, PaletteIndex, 1, &Entry);
-    PaletteChanged = TRUE;
-
-    /* Update the index */
-    VgaDacIndex++;
-    VgaDacIndex %= VGA_PALETTE_SIZE;
-}
-
-static VOID VgaWriteAc(BYTE Data)
-{
-    ASSERT(VgaAcIndex < VGA_AC_MAX_REG);
-
-    /* Save the value */
-    if (VgaAcIndex <= VGA_AC_PAL_F_REG)
-    {
-        if (VgaAcPalDisable) return;
-
-        // DbgPrint("    AC Palette Writing %d to index %d\n", Data, 
VgaAcIndex);
-        if (VgaAcRegisters[VgaAcIndex] != Data)
-        {
-            /* Update the AC register and set the palette change flag */
-            VgaAcRegisters[VgaAcIndex] = Data;
-            PaletteChanged = TRUE;
-        }
-    }
-    else
-    {
-        VgaAcRegisters[VgaAcIndex] = Data;
-    }
-}
-
-static VOID VgaRestoreDefaultPalette(PPALETTEENTRY Entries, USHORT 
NumOfEntries)
-{
-    USHORT i;
-
-    /* Copy the colors of the default palette to the DAC and console palette */
-    for (i = 0; i < NumOfEntries; i++)
-    {
-        /* Set the palette entries */
-        Entries[i].peRed   = GetRValue(VgaDefaultPalette[i]);
-        Entries[i].peGreen = GetGValue(VgaDefaultPalette[i]);
-        Entries[i].peBlue  = GetBValue(VgaDefaultPalette[i]);
-        Entries[i].peFlags = 0;
-
-        /* Set the DAC registers */
-        VgaDacRegisters[i * 3]     = 
VGA_COLOR_TO_DAC(GetRValue(VgaDefaultPalette[i]));
-        VgaDacRegisters[i * 3 + 1] = 
VGA_COLOR_TO_DAC(GetGValue(VgaDefaultPalette[i]));
-        VgaDacRegisters[i * 3 + 2] = 
VGA_COLOR_TO_DAC(GetBValue(VgaDefaultPalette[i]));
-    }
-}
-
-static BOOLEAN VgaInitializePalette(VOID)
-{
-    LPLOGPALETTE Palette;
-
-    /* Allocate storage space for the palette */
-    Palette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
-                                      HEAP_ZERO_MEMORY,
-                                      sizeof(LOGPALETTE) +
-                                        VGA_MAX_COLORS * sizeof(PALETTEENTRY));
-    if (Palette == NULL) return FALSE;
-
-    /* Initialize the palette */
-    Palette->palVersion = 0x0300;
-    Palette->palNumEntries = VGA_MAX_COLORS;
-
-    /* Restore the default palette */
-    VgaRestoreDefaultPalette(Palette->palPalEntry, Palette->palNumEntries);
-
-    /* Create the palette */
-    PaletteHandle = CreatePalette(Palette);
-
-    /* Free the palette */
-    HeapFree(GetProcessHeap(), 0, Palette);
-
-    /* Fail if the palette wasn't successfully created... */
-    if (PaletteHandle == NULL) return FALSE;
-
-    /* ... otherwise return success */
-    return TRUE;
-}
-
-static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
-{
-    DWORD i;
-    CONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo;
-    BYTE BitmapInfoBuffer[VGA_BITMAP_INFO_SIZE];
-    LPBITMAPINFO BitmapInfo = (LPBITMAPINFO)BitmapInfoBuffer;
-    LPWORD PaletteIndex = (LPWORD)(BitmapInfo->bmiColors);
-
-    LONG Width  = Resolution->X;
-    LONG Height = Resolution->Y;
-
-    /* Use DoubleVision mode if the resolution is too small */
-    if (Width < VGA_MINIMUM_WIDTH && Height < VGA_MINIMUM_HEIGHT)
-    {
-        DoubleVision = TRUE;
-        Width  *= 2;
-        Height *= 2;
-    }
-    else
-    {
-        DoubleVision = FALSE;
-    }
-
-    /* Fill the bitmap info header */
-    ZeroMemory(&BitmapInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
-    BitmapInfo->bmiHeader.biSize   = sizeof(BITMAPINFOHEADER);
-    BitmapInfo->bmiHeader.biWidth  = Width;
-    BitmapInfo->bmiHeader.biHeight = Height;
-    BitmapInfo->bmiHeader.biBitCount = 8;
-    BitmapInfo->bmiHeader.biPlanes   = 1;
-    BitmapInfo->bmiHeader.biCompression = BI_RGB;
-    BitmapInfo->bmiHeader.biSizeImage   = Width * Height /* * 1 == biBitCount 
/ 8 */;
-
-    /* Fill the palette data */
-    for (i = 0; i < (VGA_PALETTE_SIZE / 3); i++) PaletteIndex[i] = (WORD)i;
-
-    /* Fill the console graphics buffer info */
-    GraphicsBufferInfo.dwBitMapInfoLength = VGA_BITMAP_INFO_SIZE;
-    GraphicsBufferInfo.lpBitMapInfo = BitmapInfo;
-    GraphicsBufferInfo.dwUsage = DIB_PAL_COLORS;
-
-    /* Create the buffer */
-    GraphicsConsoleBuffer = CreateConsoleScreenBuffer(GENERIC_READ | 
GENERIC_WRITE,
-                                                      FILE_SHARE_READ | 
FILE_SHARE_WRITE,
-                                                      NULL,
-                                                      CONSOLE_GRAPHICS_BUFFER,
-                                                      &GraphicsBufferInfo);
-    if (GraphicsConsoleBuffer == INVALID_HANDLE_VALUE) return FALSE;
-
-    /* Save the framebuffer address and mutex */
-    ConsoleFramebuffer = GraphicsBufferInfo.lpBitMap;
-    ConsoleMutex = GraphicsBufferInfo.hMutex;
-
-    /* Clear the framebuffer */
-    ZeroMemory(ConsoleFramebuffer, BitmapInfo->bmiHeader.biSizeImage);
-
-    /* Set the active buffer */
-    SetConsoleActiveScreenBuffer(GraphicsConsoleBuffer);
-
-    /* Set the graphics mode palette */
-    SetConsolePalette(GraphicsConsoleBuffer,
-                      PaletteHandle,
-                      SYSPAL_NOSTATIC256);
-
-    /* Set the screen mode flag */
-    ScreenMode = GRAPHICS_MODE;
-
-    return TRUE;
-}
-
-static VOID VgaLeaveGraphicsMode(VOID)
-{
-    /* Release the console framebuffer mutex */
-    ReleaseMutex(ConsoleMutex);
-
-    /* Switch back to the default console text buffer */
-    // SetConsoleActiveScreenBuffer(TextConsoleBuffer);
-
-    /* Cleanup the video data */
-    CloseHandle(ConsoleMutex);
-    ConsoleMutex = NULL;
-    ConsoleFramebuffer = NULL;
-    CloseHandle(GraphicsConsoleBuffer);
-    GraphicsConsoleBuffer = NULL;
-    DoubleVision = FALSE;
-}
-
-static BOOL VgaEnterTextMode(PCOORD Resolution)
-{
-    SMALL_RECT ConRect;
-
-    DPRINT1("VgaEnterTextMode\n");
-
-    /* Switch to the text buffer */
-    SetConsoleActiveScreenBuffer(TextConsoleBuffer);
-
-    /* Resize the console */
     ConRect.Left   = 0;
     ConRect.Top    = ConsoleInfo.srWindow.Top;
     ConRect.Right  = ConRect.Left + Resolution->X - 1;
@@ -970,30 +494,551 @@
     /* Update the saved console information */
     GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo);
 
-    /* Adjust the text framebuffer if we changed resolution */
+    /*
+     * Copy console data into VGA memory
+     */
+
+    /* Get the data */
+    AddressSize = VgaGetAddressSize();
+    ConRect.Left   = ConRect.Top = 0;
+    ConRect.Right  = TextResolution.X;
+    ConRect.Bottom = TextResolution.Y;
+    ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
+
+    /* Read the data from the console into the framebuffer... */
+    ReadConsoleOutputA(TextConsoleBuffer,
+                       CharBuff,
+                       TextResolution,
+                       Origin,
+                       &ConRect);
+
+    /* ... and copy the framebuffer into the VGA memory */
+
+    /* Loop through the scanlines */
+    for (i = 0; i < TextResolution.Y; i++)
+    {
+        /* Loop through the characters */
+        for (j = 0; j < TextResolution.X; j++)
+        {
+            CurrentAddr = LOWORD((Address + j) * AddressSize);
+
+            /* Store the character in plane 0 */
+            VgaMemory[CurrentAddr] = CharBuff[i * TextResolution.X + 
j].Char.AsciiChar;
+
+            /* Store the attribute in plane 1 */
+            VgaMemory[CurrentAddr + VGA_BANK_SIZE] = (BYTE)CharBuff[i * 
TextResolution.X + j].Attributes;
+        }
+
+        /* Move to the next scanline */
+        Address += ScanlineSize;
+    }
+
+    VgaUpdateCursorPosition();
+
+    return TRUE;
+}
+
+BOOL VgaAttachToConsole(VOID)
+{
+    if (TextResolution.X == 0 || TextResolution.Y == 0)
+        DPRINT1("VgaAttachToConsole -- TextResolution uninitialized\n");
+
+    if (TextResolution.X == 0) TextResolution.X = 80;
+    if (TextResolution.Y == 0) TextResolution.Y = 25;
+
+    return VgaAttachToConsoleInternal(&TextResolution);
+}
+
+VOID VgaDetachFromConsole(BOOL ChangingMode)
+{
+    ULONG dummyLength;
+    PVOID dummyPtr;
+    COORD dummySize = {0};
+
+    __RegisterConsoleVDM(0,
+                         NULL,
+                         NULL,
+                         NULL,
+                         0,
+                         &dummyLength,
+                         &dummyPtr,
+                         NULL,
+                         0,
+                         dummySize,
+                         (PCHAR*)&dummyPtr);
+
+    TextFramebuffer = NULL;
+
+    if (!ChangingMode)
+    {
+        SMALL_RECT ConRect;
+
+        /* Restore the old screen buffer */
+        SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+
+        /* Restore the original console size */
+        ConRect.Left   = 0;
+        ConRect.Top    = 0;
+        ConRect.Right  = ConRect.Left + OrgConsoleBufferInfo.srWindow.Right  - 
OrgConsoleBufferInfo.srWindow.Left;
+        ConRect.Bottom = ConRect.Top  + OrgConsoleBufferInfo.srWindow.Bottom - 
OrgConsoleBufferInfo.srWindow.Top ;
+        /*
+         * See the following trick explanation in VgaAttachToConsoleInternal.
+         */
+        SetConsoleScreenBufferSize(TextConsoleBuffer, 
OrgConsoleBufferInfo.dwSize);
+        SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect);
+        SetConsoleScreenBufferSize(TextConsoleBuffer, 
OrgConsoleBufferInfo.dwSize);
+
+        /* Restore the original cursor shape */
+        SetConsoleCursorInfo(TextConsoleBuffer, &OrgConsoleCursorInfo);
+    }
+}
+
+static BOOL IsConsoleHandle(HANDLE hHandle)
+{
+    DWORD dwMode;
+
+    /* Check whether the handle may be that of a console... */
+    if ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR)
+        return FALSE;
+
+    /*
+     * It may be. Perform another test... The idea comes from the
+     * MSDN description of the WriteConsole API:
+     *
+     * "WriteConsole fails if it is used with a standard handle
+     *  that is redirected to a file. If an application processes
+     *  multilingual output that can be redirected, determine whether
+     *  the output handle is a console handle (one method is to call
+     *  the GetConsoleMode function and check whether it succeeds).
+     *  If the handle is a console handle, call WriteConsole. If the
+     *  handle is not a console handle, the output is redirected and
+     *  you should call WriteFile to perform the I/O."
+     */
+    return GetConsoleMode(hHandle, &dwMode);
+}
+
+static inline DWORD VgaGetAddressSize(VOID)
+{
+    if (VgaCrtcRegisters[VGA_CRTC_UNDERLINE_REG] & VGA_CRTC_UNDERLINE_DWORD)
+    {
+        /* Double-word addressing */
+        return 4; // sizeof(DWORD)
+    }
+    else if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] & 
VGA_CRTC_MODE_CONTROL_BYTE)
+    {
+        /* Byte addressing */
+        return 1; // sizeof(BYTE)
+    }
+    else
+    {
+        /* Word addressing */
+        return 2; // sizeof(WORD)
+    }
+}
+
+static inline DWORD VgaTranslateReadAddress(DWORD Address)
+{
+    DWORD Offset = Address - VgaGetVideoBaseAddress();
+    BYTE Plane;
+
+    /* Check for chain-4 and odd-even mode */
+    if (VgaSeqRegisters[VGA_SEQ_MEM_REG] & VGA_SEQ_MEM_C4)
+    {
+        /* The lowest two bits are the plane number */
+        Plane = Offset & 3;
+        Offset >>= 2;
+    }
+    else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_OE)
+    {
+        /* The LSB is the plane number */
+        Plane = Offset & 1;
+        Offset >>= 1;
+    }
+    else
+    {
+        /* Use the read mode */
+        Plane = VgaGcRegisters[VGA_GC_READ_MAP_SEL_REG] & 0x03;
+    }
+
+    /* Multiply the offset by the address size */
+    Offset *= VgaGetAddressSize();
+    
+    return Offset + Plane * VGA_BANK_SIZE;
+}
+
+static inline DWORD VgaTranslateWriteAddress(DWORD Address)
+{
+    DWORD Offset = Address - VgaGetVideoBaseAddress();
+
+    /* Check for chain-4 and odd-even mode */
+    if (VgaSeqRegisters[VGA_SEQ_MEM_REG] & VGA_SEQ_MEM_C4)
+    {
+        /* Shift the offset to the right by 2 */
+        Offset >>= 2;
+    }
+    else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_OE)
+    {
+        /* Shift the offset to the right by 1 */
+        Offset >>= 1;
+    }
+
+    /* Multiply the offset by the address size */
+    Offset *= VgaGetAddressSize();
+
+    /* Return the offset on plane 0 */
+    return Offset;
+}
+
+static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane)
+{
+    BYTE WriteMode = VgaGcRegisters[VGA_GC_MODE_REG] & 3;
+    BYTE BitMask = VgaGcRegisters[VGA_GC_BITMASK_REG];
+
+    if (WriteMode == 1)
+    {
+        /* In write mode 1 just return the latch register */
+        return VgaLatchRegisters[Plane];
+    }
+
+    if (WriteMode != 2)
+    {
+        /* Write modes 0 and 3 rotate the data to the right first */
+        BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7;
+        Data = LOBYTE(((DWORD)Data >> RotateCount) | ((DWORD)Data << (8 - 
RotateCount)));
+    }
+    else
+    {
+        /* Write mode 2 expands the appropriate bit to all 8 bits */
+        Data = (Data & (1 << Plane)) ? 0xFF : 0x00;
+    }
+
+    if (WriteMode == 0)
+    {
+        /*
+         * In write mode 0, the enable set/reset register decides if the
+         * set/reset bit should be expanded to all 8 bits.
+         */
+        if (VgaGcRegisters[VGA_GC_ENABLE_RESET_REG] & (1 << Plane))
+        {
+            /* Copy the bit from the set/reset register to all 8 bits */
+            Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF : 
0x00;
+        }
+    }
+
+    if (WriteMode != 3)
+    {
+        /* Write modes 0 and 2 then perform a logical operation on the data 
and latch */
+        BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3;
+
+        if (LogicalOperation == 1) Data &= VgaLatchRegisters[Plane];
+        else if (LogicalOperation == 2) Data |= VgaLatchRegisters[Plane];
+        else if (LogicalOperation == 3) Data ^= VgaLatchRegisters[Plane];
+    }
+    else
+    {
+        /* For write mode 3, we AND the bitmask with the data, which is used 
as the new bitmask */
+        BitMask &= Data;
+
+        /* Then we expand the bit in the set/reset field */
+        Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF : 0x00;
+    }
+
+    /* Bits cleared in the bitmask are replaced with latch register bits */
+    Data = (Data & BitMask) | (VgaLatchRegisters[Plane] & (~BitMask));
+
+    /* Return the byte */
+    return Data;
+}
+
+static inline VOID VgaMarkForUpdate(SHORT Row, SHORT Column)
+{
+    /* Check if this is the first time the rectangle is updated */
+    if (!NeedsUpdate)
+    {
+        UpdateRectangle.Left = UpdateRectangle.Top = MAXSHORT;
+        UpdateRectangle.Right = UpdateRectangle.Bottom = MINSHORT;
+    }
+
+    /* Expand the rectangle to include the point */
+    UpdateRectangle.Left = min(UpdateRectangle.Left, Column);
+    UpdateRectangle.Right = max(UpdateRectangle.Right, Column);
+    UpdateRectangle.Top = min(UpdateRectangle.Top, Row);
+    UpdateRectangle.Bottom = max(UpdateRectangle.Bottom, Row);
+
+    /* Set the update request flag */
+    NeedsUpdate = TRUE;
+}
+
+static VOID VgaWriteSequencer(BYTE Data)
+{
+    ASSERT(VgaSeqIndex < VGA_SEQ_MAX_REG);
+
+    /* Save the value */
+    VgaSeqRegisters[VgaSeqIndex] = Data;
+}
+
+static VOID VgaWriteGc(BYTE Data)
+{
+    ASSERT(VgaGcIndex < VGA_GC_MAX_REG);
+
+    /* Save the value */
+    VgaGcRegisters[VgaGcIndex] = Data;
+
+    /* Check the index */
+    switch (VgaGcIndex)
+    {
+        case VGA_GC_MISC_REG:
+        {
+            /* The GC misc register decides if it's text or graphics mode */
+            ModeChanged = TRUE;
+            break;
+        }
+    }
+}
+
+static VOID VgaWriteCrtc(BYTE Data)
+{
+    ASSERT(VgaGcIndex < VGA_CRTC_MAX_REG);
+
+    /* Save the value */
+    VgaCrtcRegisters[VgaCrtcIndex] = Data;
+
+    /* Check the index */
+    switch (VgaCrtcIndex)
+    {
+        case VGA_CRTC_END_HORZ_DISP_REG:
+        case VGA_CRTC_VERT_DISP_END_REG:
+        case VGA_CRTC_OVERFLOW_REG:
+        {
+            /* The video mode has changed */
+            ModeChanged = TRUE;
+            break;
+        }
+
+        case VGA_CRTC_CURSOR_LOC_LOW_REG:
+        case VGA_CRTC_CURSOR_LOC_HIGH_REG:
+        case VGA_CRTC_CURSOR_START_REG:
+        case VGA_CRTC_CURSOR_END_REG:
+        {
+            /* Set the cursor moved flag */
+            CursorMoved = TRUE;
+            break;
+        }
+    }
+}
+
+static VOID VgaWriteDac(BYTE Data)
+{
+    INT PaletteIndex;
+    PALETTEENTRY Entry;
+
+    /* Set the value */
+    VgaDacRegisters[VgaDacIndex] = Data;
+
+    /* Find the palette index */
+    PaletteIndex = VgaDacIndex / 3;
+
+    /* Fill the entry structure */
+    Entry.peRed = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3]);
+    Entry.peGreen = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 1]);
+    Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 2]);
+    Entry.peFlags = 0;
+
+    /* Update the palette entry and set the palette change flag */
+    SetPaletteEntries(PaletteHandle, PaletteIndex, 1, &Entry);
+    PaletteChanged = TRUE;
+
+    /* Update the index */
+    VgaDacIndex++;
+    VgaDacIndex %= VGA_PALETTE_SIZE;
+}
+
+static VOID VgaWriteAc(BYTE Data)
+{
+    ASSERT(VgaAcIndex < VGA_AC_MAX_REG);
+
+    /* Save the value */
+    if (VgaAcIndex <= VGA_AC_PAL_F_REG)
+    {
+        if (VgaAcPalDisable) return;
+
+        // DbgPrint("    AC Palette Writing %d to index %d\n", Data, 
VgaAcIndex);
+        if (VgaAcRegisters[VgaAcIndex] != Data)
+        {
+            /* Update the AC register and set the palette change flag */
+            VgaAcRegisters[VgaAcIndex] = Data;
+            PaletteChanged = TRUE;
+        }
+    }
+    else
+    {
+        VgaAcRegisters[VgaAcIndex] = Data;
+    }
+}
+
+static VOID VgaRestoreDefaultPalette(PPALETTEENTRY Entries, USHORT 
NumOfEntries)
+{
+    USHORT i;
+
+    /* Copy the colors of the default palette to the DAC and console palette */
+    for (i = 0; i < NumOfEntries; i++)
+    {
+        /* Set the palette entries */
+        Entries[i].peRed   = GetRValue(VgaDefaultPalette[i]);
+        Entries[i].peGreen = GetGValue(VgaDefaultPalette[i]);
+        Entries[i].peBlue  = GetBValue(VgaDefaultPalette[i]);
+        Entries[i].peFlags = 0;
+
+        /* Set the DAC registers */
+        VgaDacRegisters[i * 3]     = 
VGA_COLOR_TO_DAC(GetRValue(VgaDefaultPalette[i]));
+        VgaDacRegisters[i * 3 + 1] = 
VGA_COLOR_TO_DAC(GetGValue(VgaDefaultPalette[i]));
+        VgaDacRegisters[i * 3 + 2] = 
VGA_COLOR_TO_DAC(GetBValue(VgaDefaultPalette[i]));
+    }
+}
+
+static BOOLEAN VgaInitializePalette(VOID)
+{
+    LPLOGPALETTE Palette;
+
+    /* Allocate storage space for the palette */
+    Palette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
+                                      HEAP_ZERO_MEMORY,
+                                      sizeof(LOGPALETTE) +
+                                        VGA_MAX_COLORS * sizeof(PALETTEENTRY));
+    if (Palette == NULL) return FALSE;
+
+    /* Initialize the palette */
+    Palette->palVersion = 0x0300;
+    Palette->palNumEntries = VGA_MAX_COLORS;
+
+    /* Restore the default palette */
+    VgaRestoreDefaultPalette(Palette->palPalEntry, Palette->palNumEntries);
+
+    /* Create the palette */
+    PaletteHandle = CreatePalette(Palette);
+
+    /* Free the palette */
+    HeapFree(GetProcessHeap(), 0, Palette);
+
+    /* Fail if the palette wasn't successfully created... */
+    if (PaletteHandle == NULL) return FALSE;
+
+    /* ... otherwise return success */
+    return TRUE;
+}
+
+static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
+{
+    DWORD i;
+    CONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo;
+    BYTE BitmapInfoBuffer[VGA_BITMAP_INFO_SIZE];
+    LPBITMAPINFO BitmapInfo = (LPBITMAPINFO)BitmapInfoBuffer;
+    LPWORD PaletteIndex = (LPWORD)(BitmapInfo->bmiColors);
+
+    LONG Width  = Resolution->X;
+    LONG Height = Resolution->Y;
+
+    /* Use DoubleVision mode if the resolution is too small */
+    if (Width < VGA_MINIMUM_WIDTH && Height < VGA_MINIMUM_HEIGHT)
+    {
+        DoubleVision = TRUE;
+        Width  *= 2;
+        Height *= 2;
+    }
+    else
+    {
+        DoubleVision = FALSE;
+    }
+
+    /* Fill the bitmap info header */
+    ZeroMemory(&BitmapInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
+    BitmapInfo->bmiHeader.biSize   = sizeof(BITMAPINFOHEADER);
+    BitmapInfo->bmiHeader.biWidth  = Width;
+    BitmapInfo->bmiHeader.biHeight = Height;
+    BitmapInfo->bmiHeader.biBitCount = 8;
+    BitmapInfo->bmiHeader.biPlanes   = 1;
+    BitmapInfo->bmiHeader.biCompression = BI_RGB;
+    BitmapInfo->bmiHeader.biSizeImage   = Width * Height /* * 1 == biBitCount 
/ 8 */;
+
+    /* Fill the palette data */
+    for (i = 0; i < (VGA_PALETTE_SIZE / 3); i++) PaletteIndex[i] = (WORD)i;
+
+    /* Fill the console graphics buffer info */
+    GraphicsBufferInfo.dwBitMapInfoLength = VGA_BITMAP_INFO_SIZE;
+    GraphicsBufferInfo.lpBitMapInfo = BitmapInfo;
+    GraphicsBufferInfo.dwUsage = DIB_PAL_COLORS;
+
+    /* Create the buffer */
+    GraphicsConsoleBuffer = CreateConsoleScreenBuffer(GENERIC_READ | 
GENERIC_WRITE,
+                                                      FILE_SHARE_READ | 
FILE_SHARE_WRITE,
+                                                      NULL,
+                                                      CONSOLE_GRAPHICS_BUFFER,
+                                                      &GraphicsBufferInfo);
+    if (GraphicsConsoleBuffer == INVALID_HANDLE_VALUE) return FALSE;
+
+    /* Save the framebuffer address and mutex */
+    ConsoleFramebuffer = GraphicsBufferInfo.lpBitMap;
+    ConsoleMutex = GraphicsBufferInfo.hMutex;
+
+    /* Clear the framebuffer */
+    ZeroMemory(ConsoleFramebuffer, BitmapInfo->bmiHeader.biSizeImage);
+
+    /* Set the active buffer */
+    SetConsoleActiveScreenBuffer(GraphicsConsoleBuffer);
+
+    /* Set the graphics mode palette */
+    SetConsolePalette(GraphicsConsoleBuffer,
+                      PaletteHandle,
+                      SYSPAL_NOSTATIC256);
+
+    /* Set the screen mode flag */
+    ScreenMode = GRAPHICS_MODE;
+
+    return TRUE;
+}
+
+static VOID VgaLeaveGraphicsMode(VOID)
+{
+    /* Release the console framebuffer mutex */
+    ReleaseMutex(ConsoleMutex);
+
+    /* Switch back to the default console text buffer */
+    // SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+
+    /* Cleanup the video data */
+    CloseHandle(ConsoleMutex);
+    ConsoleMutex = NULL;
+    ConsoleFramebuffer = NULL;
+    CloseHandle(GraphicsConsoleBuffer);
+    GraphicsConsoleBuffer = NULL;
+    DoubleVision = FALSE;
+}
+
+static BOOL VgaEnterTextMode(PCOORD Resolution)
+{
+    DPRINT1("VgaEnterTextMode\n");
+
+    /* Switch to the text buffer */
+    SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+
+    /* Adjust the text framebuffer if we changed the resolution */
     if (TextResolution.X != Resolution->X ||
         TextResolution.Y != Resolution->Y)
     {
-        WORD Offset;
-
-        VgaDetachFromConsole();
-
-        /* VgaAttachToConsole sets TextResolution to the new resolution */
-        if (!VgaAttachToConsole(Resolution))
+        VgaDetachFromConsole(TRUE);
+
+        /*
+         * VgaAttachToConsoleInternal sets TextResolution to the
+         * new resolution and updates ConsoleInfo.
+         */
+        if (!VgaAttachToConsoleInternal(Resolution))
         {
             DisplayMessage(L"An unexpected error occurred!\n");
             EmulatorTerminate();
             return FALSE;
         }
-
-        /* Update the cursor position in the registers */
-        Offset = ConsoleInfo.dwCursorPosition.Y * Resolution->X +
-                 ConsoleInfo.dwCursorPosition.X;
-        DPRINT1("X = %d ; Y = %d\n", ConsoleInfo.dwCursorPosition.X, 
ConsoleInfo.dwCursorPosition.Y);
-        VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_LOW_REG]  = LOBYTE(Offset);
-        VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG] = HIBYTE(Offset);
-        CursorMoved = TRUE;
-    }
+    }
+    else VgaUpdateCursorPosition();
 
     /* The active framebuffer is now the text framebuffer */
     ConsoleFramebuffer = TextFramebuffer;
@@ -1825,11 +1870,13 @@
     if (!IsConsoleHandle(TextHandle)) return FALSE;
     TextConsoleBuffer = TextHandle;
 
-    /* Save the console information */
-    if (!GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo))
+    /* Save the original cursor and console screen buffer information */
+    if (!GetConsoleCursorInfo(TextConsoleBuffer, &OrgConsoleCursorInfo) ||
+        !GetConsoleScreenBufferInfo(TextConsoleBuffer, &OrgConsoleBufferInfo))
     {
         return FALSE;
     }
+    ConsoleInfo = OrgConsoleBufferInfo;
 
     /* Initialize the VGA palette and fail if it isn't successfully created */
     if (!VgaInitializePalette()) return FALSE;
@@ -1873,7 +1920,7 @@
         VgaLeaveTextMode();
     }
 
-    VgaDetachFromConsole();
+    VgaDetachFromConsole(FALSE);
 
     CloseHandle(AnotherEvent);
     CloseHandle(EndEvent);

Modified: branches/ntvdm/subsystems/ntvdm/hardware/vga.h
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/hardware/vga.h?rev=63119&r1=63118&r2=63119&view=diff
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/hardware/vga.h      [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/hardware/vga.h      [iso-8859-1] Fri May  2 
21:17:05 2014
@@ -250,6 +250,9 @@
 
 /* FUNCTIONS 
******************************************************************/
 
+BOOL VgaAttachToConsole(VOID);
+VOID VgaDetachFromConsole(BOOL ChangeMode);
+
 DWORD VgaGetVideoBaseAddress(VOID);
 DWORD VgaGetVideoLimitAddress(VOID);
 COORD VgaGetDisplayResolution(VOID);

Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?rev=63119&r1=63118&r2=63119&view=diff
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.c     [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.c     [iso-8859-1] Fri May  2 
21:17:05 2014
@@ -32,8 +32,6 @@
 static HANDLE ConsoleInput  = INVALID_HANDLE_VALUE;
 static HANDLE ConsoleOutput = INVALID_HANDLE_VALUE;
 static DWORD  OrgConsoleInputMode, OrgConsoleOutputMode;
-static CONSOLE_CURSOR_INFO         OrgConsoleCursorInfo;
-static CONSOLE_SCREEN_BUFFER_INFO  OrgConsoleBufferInfo;
 static BOOLEAN AcceptCommands = TRUE;
 static HANDLE CommandThread = NULL;
 
@@ -344,16 +342,6 @@
         return FALSE;
     }
 
-    /* Save the original cursor and console screen buffer information */
-    if (!GetConsoleCursorInfo(ConsoleOutput, &OrgConsoleCursorInfo) ||
-        !GetConsoleScreenBufferInfo(ConsoleOutput, &OrgConsoleBufferInfo))
-    {
-        CloseHandle(ConsoleOutput);
-        CloseHandle(ConsoleInput);
-        wprintf(L"FATAL: Cannot save console cursor/screen-buffer info\n");
-        return FALSE;
-    }
-
     /* Initialize the UI */
     ConsoleInitUI();
 
@@ -362,26 +350,6 @@
 
 VOID ConsoleCleanup(VOID)
 {
-    SMALL_RECT ConRect;
-
-    /* Restore the old screen buffer */
-    SetConsoleActiveScreenBuffer(ConsoleOutput);
-
-    /* Restore the original console size */
-    ConRect.Left   = 0;
-    ConRect.Top    = 0;
-    ConRect.Right  = ConRect.Left + OrgConsoleBufferInfo.srWindow.Right  - 
OrgConsoleBufferInfo.srWindow.Left;
-    ConRect.Bottom = ConRect.Top  + OrgConsoleBufferInfo.srWindow.Bottom - 
OrgConsoleBufferInfo.srWindow.Top ;
-    /*
-     * See the following trick explanation in vga.c:VgaEnterTextMode() .
-     */
-    SetConsoleScreenBufferSize(ConsoleOutput, OrgConsoleBufferInfo.dwSize);
-    SetConsoleWindowInfo(ConsoleOutput, TRUE, &ConRect);
-    SetConsoleScreenBufferSize(ConsoleOutput, OrgConsoleBufferInfo.dwSize);
-
-    /* Restore the original cursor shape */
-    SetConsoleCursorInfo(ConsoleOutput, &OrgConsoleCursorInfo);
-
     /* Restore the original input and output console modes */
     SetConsoleMode(ConsoleOutput, OrgConsoleOutputMode);
     SetConsoleMode(ConsoleInput , OrgConsoleInputMode );
@@ -428,11 +396,7 @@
         CommandInfo.Env = Env;
         CommandInfo.EnvLen = sizeof(Env);
 
-        if (First)
-        {
-            CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
-            First = FALSE;
-        }
+        if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
 
         /* Wait for the next available VDM */
         if (!GetNextVDMCommand(&CommandInfo)) break;
@@ -446,6 +410,12 @@
             DisplayMessage(L"Could not start '%S'. Error: %u", AppName, 
Result);
             break;
         }
+
+        /* Attach to the console */
+        if (!First) VgaAttachToConsole();
+
+        /* Perform a screen refresh */
+        VgaRefreshDisplay();
 
         /* Start simulation */
         SetEvent(VdmTaskEvent);
@@ -453,6 +423,11 @@
 
         /* Perform another screen refresh */
         VgaRefreshDisplay();
+
+        /* Detach from the console */
+        VgaDetachFromConsole(FALSE);
+
+        First = FALSE;
     }
 
     return 0;


Reply via email to