[NTVDM]
[reactos.git] / subsystems / ntvdm / vga.c
index bfff763..a535048 100644 (file)
@@ -265,11 +265,15 @@ static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
 
 static VOID VgaLeaveGraphicsMode(VOID)
 {
+    /* Release the console framebuffer mutex if needed */
+    ReleaseMutex(ConsoleMutex);
+
     /* Switch back to the text buffer */
     SetConsoleActiveScreenBuffer(TextConsoleBuffer);
 
     /* Cleanup the video data */
     CloseHandle(ConsoleMutex);
+    ConsoleMutex = NULL;
     CloseHandle(GraphicsConsoleBuffer);
     GraphicsConsoleBuffer = NULL;
 }
@@ -350,17 +354,22 @@ static VOID VgaUpdateFramebuffer(VOID)
     DWORD Address = (VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG] << 8)
                     + VgaCrtcRegisters[VGA_CRTC_START_ADDR_LOW_REG];
     DWORD ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
-    PCHAR_INFO CharBuffer = (PCHAR_INFO)ConsoleFramebuffer;
-    PBYTE GraphicsBuffer = (PBYTE)ConsoleFramebuffer;
 
-    /* Loop through the scanlines */
-    for (i = 0; i < Resolution.Y; i++)
+    /* Check if this is text mode or graphics mode */
+    if (VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA)
     {
-        /* Check if this is text mode or graphics mode */
-        if (VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA)
-        {
-            /* Graphics mode */
+        /* Graphics mode */
+        PBYTE GraphicsBuffer = (PBYTE)ConsoleFramebuffer;
+
+        /*
+         * Synchronize access to the graphics framebuffer
+         * with the console framebuffer mutex.
+         */
+        WaitForSingleObject(ConsoleMutex, INFINITE);
 
+        /* Loop through the scanlines */
+        for (i = 0; i < Resolution.Y; i++)
+        {
             /* Loop through the pixels */
             for (j = 0; j < Resolution.X; j++)
             {
@@ -460,11 +469,25 @@ static VOID VgaUpdateFramebuffer(VOID)
                     VgaMarkForUpdate(i, j);
                 }
             }
+
+            /* Move to the next scanline */
+            Address += ScanlineSize;
         }
-        else
-        {
-            /* Text mode */
 
+        /*
+         * Release the console framebuffer mutex
+         * so that we allow for repainting.
+         */
+        ReleaseMutex(ConsoleMutex);
+    }
+    else
+    {
+        /* Text mode */
+        PCHAR_INFO CharBuffer = (PCHAR_INFO)ConsoleFramebuffer;
+
+        /* Loop through the scanlines */
+        for (i = 0; i < Resolution.Y; i++)
+        {
             /* Loop through the characters */
             for (j = 0; j < Resolution.X; j++)
             {
@@ -488,10 +511,10 @@ static VOID VgaUpdateFramebuffer(VOID)
                     VgaMarkForUpdate(i, j);
                 }
             }
-        }
 
-        /* Move to the next scanline */
-        Address += ScanlineSize;
+            /* Move to the next scanline */
+            Address += ScanlineSize;
+        }
     }
 }
 
@@ -546,6 +569,7 @@ DWORD VgaGetVideoLimitAddress(VOID)
 COORD VgaGetDisplayResolution(VOID)
 {
     COORD Resolution;
+    BYTE TextSize = 1 + (VgaCrtcRegisters[VGA_CRTC_MAX_SCAN_LINE_REG] & 0x1F);
 
     /* The low 8 bits are in the display registers */
     Resolution.X = VgaCrtcRegisters[VGA_CRTC_END_HORZ_DISP_REG];
@@ -580,7 +604,7 @@ COORD VgaGetDisplayResolution(VOID)
     else
     {
         /* Divide the number of scanlines by the font size */
-        Resolution.Y /= 16;
+        Resolution.Y /= TextSize;
     }
 
     /* Return the resolution */