[CONSRV]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 13 Oct 2013 00:11:38 +0000 (00:11 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 13 Oct 2013 00:11:38 +0000 (00:11 +0000)
Implement a basic full-screen mode for the console. Still Work-In-Progress. See r59099 for more details.

svn path=/trunk/; revision=60635

reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c
reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h
reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c
reactos/win32ss/user/winsrv/consrv/include/conio.h

index 6dac933..c579fb5 100644 (file)
@@ -19,6 +19,7 @@
 
 
 VOID GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData);
+VOID SwitchFullScreen(PGUI_CONSOLE_DATA GuiData, BOOL FullScreen);
 
 /* FUNCTIONS ******************************************************************/
 
@@ -507,8 +508,10 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
             /*
              * Apply full-screen mode.
              */
-            GuiData->GuiInfo.FullScreen = GuiInfo->FullScreen;
-            // TODO: Apply it really
+            if (GuiInfo->FullScreen != GuiData->GuiInfo.FullScreen)
+            {
+                SwitchFullScreen(GuiData, GuiInfo->FullScreen);
+            }
         }
 
         /*
index 2a3c616..9e7627f 100644 (file)
@@ -49,6 +49,9 @@ typedef struct _GUI_CONSOLE_DATA
     HICON hIcon;                /* Handle to the console's icon (big)   */
     HICON hIconSm;              /* Handle to the console's icon (small) */
 
+    LONG_PTR WndStyle;
+    LONG_PTR WndStyleEx;
+
     HPALETTE hSysPalette;       /* Handle to the original system palette */
 
 /*** The following may be put per-screen-buffer !! ***/
index fc2a711..8587d98 100644 (file)
@@ -12,7 +12,6 @@
 /* INCLUDES *******************************************************************/
 
 #define COBJMACROS
-#define NONAMELESSUNION
 
 #include "consrv.h"
 #include "include/conio.h"
@@ -468,46 +467,147 @@ GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData)
     // to: InvalidateRect(GuiData->hWindow, NULL, TRUE);
 }
 
+
+
+static BOOL
+EnterFullScreen(PGUI_CONSOLE_DATA GuiData)
+{
+    DEVMODEW DevMode;
+
+    ZeroMemory(&DevMode, sizeof(DevMode));
+    DevMode.dmSize = sizeof(DevMode);
+
+    // DevMode.dmDisplayFixedOutput = DMDFO_CENTER; // DMDFO_STRETCH // DMDFO_DEFAULT
+    // DevMode.dmDisplayFlags = DMDISPLAYFLAGS_TEXTMODE;
+    DevMode.dmPelsWidth  = 640; // GuiData->ActiveBuffer->ViewSize.X * GuiData->CharWidth;
+    DevMode.dmPelsHeight = 480; // GuiData->ActiveBuffer->ViewSize.Y * GuiData->CharHeight;
+    // DevMode.dmBitsPerPel = 32;
+    DevMode.dmFields     = /* DM_DISPLAYFIXEDOUTPUT | DM_DISPLAYFLAGS | DM_BITSPERPEL | */ DM_PELSWIDTH | DM_PELSHEIGHT;
+
+    return (ChangeDisplaySettingsW(&DevMode, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
+}
+
+static BOOL
+LeaveFullScreen(PGUI_CONSOLE_DATA GuiData)
+{
+    return (ChangeDisplaySettingsW(NULL, CDS_RESET) == DISP_CHANGE_SUCCESSFUL);
+}
+
 static VOID
-GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData)
+GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam);
+
+VOID
+SwitchFullScreen(PGUI_CONSOLE_DATA GuiData, BOOL FullScreen)
 {
     PCONSOLE Console = GuiData->Console;
-    // DEVMODE dmScreenSettings;
 
-    if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
+    /*
+     * See:
+     * http://stackoverflow.com/questions/2382464/win32-full-screen-and-hiding-taskbar
+     * http://stackoverflow.com/questions/3549148/fullscreen-management-with-winapi
+     * http://blogs.msdn.com/b/oldnewthing/archive/2010/04/12/9994016.aspx
+     * http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx
+     * http://stackoverflow.com/questions/1400654/how-do-i-put-my-opengl-app-into-fullscreen-mode
+     * http://nehe.gamedev.net/tutorial/creating_an_opengl_window_win32/13001/
+     * http://www.reocities.com/pcgpe/dibs.html
+     */
 
-    /* Switch to full-screen or to windowed mode */
-    GuiData->GuiInfo.FullScreen = !GuiData->GuiInfo.FullScreen;
-    DPRINT1("GuiConsoleSwitchFullScreen - Switch to %s ...\n",
-            (GuiData->GuiInfo.FullScreen ? "full-screen" : "windowed mode"));
-
-    // TODO: Change window appearance.
-    // See:
-    // http://stackoverflow.com/questions/2382464/win32-full-screen-and-hiding-taskbar
-    // http://stackoverflow.com/questions/3549148/fullscreen-management-with-NTAPI
-    // http://blogs.msdn.com/b/oldnewthing/archive/2010/04/12/9994016.aspx
-    // http://stackoverflow.com/questions/1400654/how-do-i-put-my-opengl-app-into-fullscreen-mode
-    // http://nehe.gamedev.net/tutorial/creating_an_opengl_window_win32/13001/
-#if 0
-    if (GuiData->GuiInfo.FullScreen)
+    if (FullScreen)
     {
-        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
-        dmScreenSettings.dmSize       = sizeof(dmScreenSettings);
-        dmScreenSettings.dmDisplayFixedOutput = DMDFO_CENTER; // DMDFO_STRETCH // DMDFO_DEFAULT
-        dmScreenSettings.dmPelsWidth  = 640; // GuiData->ActiveBuffer->ViewSize.X * GuiData->CharWidth;
-        dmScreenSettings.dmPelsHeight = 480; // GuiData->ActiveBuffer->ViewSize.Y * GuiData->CharHeight;
-        dmScreenSettings.dmBitsPerPel = 32;
-        dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-        ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
+        SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+
+        /* Switch to full screen */
+        if (EnterFullScreen(GuiData))
+        {
+            /* Save the new state */
+            GuiData->GuiInfo.FullScreen = TRUE;
+            Console->FixedSize = TRUE;
+
+            GuiData->ActiveBuffer->OldViewSize = GuiData->ActiveBuffer->ViewSize;
+            // GuiData->ActiveBuffer->OldScreenBufferSize = GuiData->ActiveBuffer->ScreenBufferSize;
+
+            /* Save the old window styles */
+            GuiData->WndStyle   = GetWindowLongPtr(GuiData->hWindow, GWL_STYLE  );
+            GuiData->WndStyleEx = GetWindowLongPtr(GuiData->hWindow, GWL_EXSTYLE);
+
+            /* Change the window styles */
+            SetWindowLongPtr(GuiData->hWindow, GWL_STYLE,
+                             WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
+            SetWindowLongPtr(GuiData->hWindow, GWL_EXSTYLE,
+                             WS_EX_APPWINDOW);
+
+            /* Reposition the window to the upper-left corner */
+            SetWindowPos(GuiData->hWindow,
+                         HWND_TOPMOST,
+                         0, 0,
+                         0, 0,
+                         SWP_NOSIZE | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
+            /* Make it the foreground window */
+            SetForegroundWindow(GuiData->hWindow);
+            /* Resize it */
+            // GuiConsoleResizeWindow(GuiData);
+            GuiConsoleResize(GuiData, SIZE_RESTORED, MAKELPARAM(640, 480));
+
+            PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+        }
+        else
+        {
+            PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
+        }
     }
     else
     {
+        SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+
+        /* Restore windowing mode */
+        if (LeaveFullScreen(GuiData))
+        {
+            /* Save the new state */
+            GuiData->GuiInfo.FullScreen = FALSE;
+            Console->FixedSize = FALSE;
+
+            /*
+             * Restore possible saved dimensions
+             * of the active screen buffer view.
+             */
+            GuiData->ActiveBuffer->ViewSize = GuiData->ActiveBuffer->OldViewSize;
+            // GuiData->ActiveBuffer->ScreenBufferSize = GuiData->ActiveBuffer->OldScreenBufferSize;
+
+            /* Restore the window styles */
+            SetWindowLongPtr(GuiData->hWindow, GWL_STYLE,
+                             GuiData->WndStyle);
+            SetWindowLongPtr(GuiData->hWindow, GWL_EXSTYLE,
+                             GuiData->WndStyleEx);
+
+            /* Resize it */
+            GuiConsoleResizeWindow(GuiData);
+
+            // PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
+        }
+        PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
     }
-#endif
+}
+
+static VOID
+GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData)
+{
+    PCONSOLE Console = GuiData->Console;
+    BOOL FullScreen;
+
+    if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
+
+    /* Switch to full-screen or to windowed mode */
+    FullScreen = !GuiData->GuiInfo.FullScreen;
+    DPRINT1("GuiConsoleSwitchFullScreen - Switch to %s ...\n",
+            (FullScreen ? "full-screen" : "windowed mode"));
+
+    SwitchFullScreen(GuiData, FullScreen);
 
     LeaveCriticalSection(&Console->Lock);
 }
 
+
+
 static BOOL
 GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
 {
@@ -1688,7 +1788,31 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
     {
         case WM_ACTIVATE:
         {
-            if (LOWORD(wParam) == WA_CLICKACTIVE) GuiData->IgnoreNextMouseSignal = TRUE;
+            WORD ActivationState = LOWORD(wParam);
+
+            if ( ActivationState == WA_ACTIVE ||
+                 ActivationState == WA_CLICKACTIVE )
+            {
+                if (GuiData->GuiInfo.FullScreen)
+                {
+                    EnterFullScreen(GuiData);
+                    // // PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
+                    // SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
+                }
+            }
+            else // if (ActivationState == WA_INACTIVE)
+            {
+                if (GuiData->GuiInfo.FullScreen)
+                {
+                    SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+                    LeaveFullScreen(GuiData);
+                    // // PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+                    // SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+                }
+            }
+
+            if (ActivationState == WA_CLICKACTIVE) GuiData->IgnoreNextMouseSignal = TRUE;
+
             break;
         }
 
@@ -2043,6 +2167,8 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
                                         (PVOID)GuiData);
             if (NULL != NewWindow)
             {
+                ASSERT(NewWindow == GuiData->hWindow);
+
                 WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
                 WindowCount++;
                 SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
@@ -2068,6 +2194,9 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
                 GuiConsoleResizeWindow(GuiData);
                 GuiData->WindowSizeLock = FALSE;
 
+                /* Switch to full-screen mode if necessary */
+                if (GuiData->GuiInfo.FullScreen) SwitchFullScreen(GuiData, TRUE);
+
                 // ShowWindow(NewWindow, (int)wParam);
                 ShowWindowAsync(NewWindow, (int)wParam);
                 DPRINT("Window showed\n");
@@ -2080,6 +2209,9 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
         {
             PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
 
+            /* Exit the full screen mode if it was already set */
+            // LeaveFullScreen(GuiData);
+
             /*
              * Window creation is done using a PostMessage(), so it's possible
              * that the window that we want to destroy doesn't exist yet.
index 76d4aa2..0e8bbc4 100644 (file)
@@ -66,7 +66,7 @@ struct _CONSOLE_SCREEN_BUFFER
 
     // PVOID Data;                         /* Private data for the frontend to use */
 
-    COORD   ScreenBufferSize;           /* Size of this screen buffer. (Rows, Columns) for text-mode and (Width, Height) for graphics */
+    COORD   ScreenBufferSize;           /* Size of this screen buffer. (Rows, Columns) for text-mode and (Width, Height) for graphics-mode */
     COORD   ViewSize;                   /* Associated "view" (i.e. console) size */
 
     COORD   OldScreenBufferSize;        /* Old size of this screen buffer */