[CONSRV]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 12 Oct 2013 15:37:50 +0000 (15:37 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 12 Oct 2013 15:37:50 +0000 (15:37 +0000)
Implement SetConsolePalette (see r59711 for more details), but it is still WIP:
- the helper function ConDrvSetConsolePalette uses a hardcoded palette for testing purposes,
- lots of DPRINT1 are displayed when using this function or when swapping active screen buffers,
- lot of code redundancy which will be put in some helper functions when this code will work correctly,
- and I get some WIN32K warnings:
WARNING:  IntGdiRealizePalette at ../../win32ss/gdi/ntgdi/palette.c:777 is UNIMPLEMENTED!
It would be great if a win32k guy can have a look at this!! And I suspect that's because of this that the changed palette is not used...

Also, deactivate the WM_NCRBUTTONDOWN/WM_NCRBUTTONUP hack I introduced in revision 58632, because James worked on this in revisions 60622 and 60626 (see CORE-7054 too).

svn path=/trunk/; revision=60629

reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c
reactos/win32ss/user/winsrv/consrv/condrv/dummyfrontend.c
reactos/win32ss/user/winsrv/consrv/conoutput.c
reactos/win32ss/user/winsrv/consrv/frontendctl.c
reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h
reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c
reactos/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
reactos/win32ss/user/winsrv/consrv/include/conio.h
reactos/win32ss/user/winsrv/consrv/include/term.h

index 8aa6203..aa73210 100644 (file)
@@ -58,11 +58,23 @@ VOID
 CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
 {
     if (Buffer->Header.Type == TEXTMODE_BUFFER)
+    {
         TEXTMODE_BUFFER_Destroy(Buffer);
+    }
     else if (Buffer->Header.Type == GRAPHICS_BUFFER)
+    {
         GRAPHICS_BUFFER_Destroy(Buffer);
+    }
     else if (Buffer->Header.Type == SCREEN_BUFFER)
+    {
+        // TODO: Free Buffer->Data
+
+        /* Free the palette handle */
+        if (Buffer->PaletteHandle != NULL) DeleteObject(Buffer->PaletteHandle);
+
+        /* Free the screen buffer memory */
         ConsoleFreeHeap(Buffer);
+    }
     // else
     //     do_nothing;
 }
@@ -218,12 +230,125 @@ ConDrvInvalidateBitMapRect(IN PCONSOLE Console,
 
 NTSTATUS NTAPI
 ConDrvSetConsolePalette(IN PCONSOLE Console,
-                        IN PGRAPHICS_SCREEN_BUFFER Buffer,
+                        // IN PGRAPHICS_SCREEN_BUFFER Buffer,
+                        IN PCONSOLE_SCREEN_BUFFER Buffer,
                         IN HPALETTE PaletteHandle,
-                        IN UINT Usage)
+                        IN UINT PaletteUsage)
 {
-    DPRINT1("ConDrvSetConsolePalette is UNIMPLEMENTED but returns STATUS_SUCCESS\n");
-    return STATUS_SUCCESS;
+    BOOL Success;
+
+/******************************************************************************\
+|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************|
+\******************************************************************************/
+
+#define PALETTESIZE 256
+
+    UINT i;
+    LPLOGPALETTE LogPalette;                  /* Pointer to logical palette */
+
+PALETTEENTRY MyPalette[] =
+{ {0,   0,   0x80,0} ,       // 1
+  {0,   0x80,0,   0} ,       // 2
+  {0,   0,   0,   0} ,       // 0
+  {0,   0x80,0x80,0} ,       // 3
+  {0x80,0,   0,   0} ,       // 4
+  {0x80,0,   0x80,0} ,       // 5
+  {0x80,0x80,0,   0} ,       // 6
+  {0xC0,0xC0,0xC0,0} ,       // 7
+  {0x80,0x80,0x80,0} ,       // 8
+  {0,   0,   0xFF,0} ,       // 9
+  {0,   0xFF,0,   0} ,       // 10
+  {0,   0xFF,0xFF,0} ,       // 11
+  {0xFF,0,   0,   0} ,       // 12
+  {0xFF,0,   0xFF,0} ,       // 13
+  {0xFF,0xFF,0,   0} ,       // 14
+  {0xFF,0xFF,0xFF,0} };      // 15
+
+/******************************************************************************\
+|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************|
+\******************************************************************************/
+
+    DPRINT1("ConDrvSetConsolePalette checkpt 0\n");
+
+    if (Console == NULL || Buffer == NULL)
+        return STATUS_INVALID_PARAMETER;
+
+    DPRINT1("ConDrvSetConsolePalette checkpt 1\n");
+
+    // FIXME: Is it useful ?
+    if ( PaletteUsage != SYSPAL_STATIC   &&
+         PaletteUsage != SYSPAL_NOSTATIC &&
+         PaletteUsage != SYSPAL_NOSTATIC256 )
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    DPRINT1("ConDrvSetConsolePalette checkpt 2\n");
+
+    /* Validity check */
+    ASSERT(Console == Buffer->Header.Console);
+
+
+
+/******************************************************************************\
+|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************|
+\******************************************************************************/
+
+    DPRINT1("HACK: FIXME: ConDrvSetConsolePalette - Use hacked palette for testing purposes!!\n");
+
+    LogPalette = (LPLOGPALETTE)ConsoleAllocHeap(HEAP_ZERO_MEMORY,
+                                                (sizeof(LOGPALETTE) +
+                                                (sizeof(PALETTEENTRY) * PALETTESIZE)));
+
+    if (LogPalette)
+    {
+        LogPalette->palVersion = 0x300;
+        LogPalette->palNumEntries = PALETTESIZE;
+
+        for(i=0; i < PALETTESIZE;i++)
+        {
+            LogPalette->palPalEntry[i] = MyPalette[i % sizeof(MyPalette)/sizeof(MyPalette[0])];
+        }
+
+        PaletteHandle = CreatePalette(LogPalette);
+        PaletteUsage = SYSPAL_NOSTATIC256;
+        ConsoleFreeHeap(LogPalette);
+    }
+    else
+    {
+        DPRINT1("ConDrvSetConsolePalette - Hacked LogPalette is NULL\n");
+    }
+
+/******************************************************************************\
+|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************|
+\******************************************************************************/
+
+
+
+
+    /* Change the palette */
+    DPRINT1("ConDrvSetConsolePalette calling TermSetPalette\n");
+    Success = TermSetPalette(Console, PaletteHandle, PaletteUsage);
+    if (Success)
+    {
+        DPRINT1("TermSetPalette succeeded\n");
+        /* Free the old palette handle if there was already one set */
+        if ( Buffer->PaletteHandle != NULL &&
+             Buffer->PaletteHandle != PaletteHandle )
+        {
+            DeleteObject(Buffer->PaletteHandle);
+        }
+
+        /* Save the new palette in the screen buffer */
+        Buffer->PaletteHandle = PaletteHandle;
+        Buffer->PaletteUsage  = PaletteUsage;
+    }
+    else
+    {
+        DPRINT1("TermSetPalette failed\n");
+    }
+
+    return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
 }
 
 NTSTATUS NTAPI
index 38e563d..1cf7dd4 100644 (file)
@@ -118,6 +118,14 @@ DummyGetLargestConsoleWindowSize(IN OUT PFRONTEND This,
 {
 }
 
+static BOOL NTAPI
+DummySetPalette(IN OUT PFRONTEND This,
+                HPALETTE PaletteHandle,
+                UINT PaletteUsage)
+{
+    return TRUE;
+}
+
 static ULONG NTAPI
 DummyGetDisplayMode(IN OUT PFRONTEND This)
 {
@@ -177,6 +185,7 @@ static FRONTEND_VTBL DummyVtbl =
     DummyChangeIcon,
     DummyGetConsoleWindowHandle,
     DummyGetLargestConsoleWindowSize,
+    DummySetPalette,
     DummyGetDisplayMode,
     DummySetDisplayMode,
     DummyShowMouseCursor,
index 3076965..9265958 100644 (file)
@@ -52,30 +52,43 @@ CSR_API(SrvInvalidateBitMapRect)
 
 NTSTATUS NTAPI
 ConDrvSetConsolePalette(IN PCONSOLE Console,
-                        IN PGRAPHICS_SCREEN_BUFFER Buffer,
+                        // IN PGRAPHICS_SCREEN_BUFFER Buffer,
+                        IN PCONSOLE_SCREEN_BUFFER Buffer,
                         IN HPALETTE PaletteHandle,
-                        IN UINT Usage);
+                        IN UINT PaletteUsage);
 CSR_API(SrvSetConsolePalette)
 {
     NTSTATUS Status;
     PCONSOLE_SETPALETTE SetPaletteRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetPaletteRequest;
-    // PCONSOLE_SCREEN_BUFFER Buffer;
-    PGRAPHICS_SCREEN_BUFFER Buffer;
+    // PGRAPHICS_SCREEN_BUFFER Buffer;
+    PCONSOLE_SCREEN_BUFFER Buffer;
 
-    DPRINT("SrvSetConsolePalette\n");
+    DPRINT1("SrvSetConsolePalette\n");
 
     // NOTE: Tests show that this function is used only for graphics screen buffers
-    // and otherwise it returns false + sets last error to invalid handle.
+    // and otherwise it returns FALSE + sets last error to invalid handle.
+    // I think it's ridiculous, because if you are in text mode, simulating
+    // a change of VGA palette via DAC registers (done by a call to SetConsolePalette)
+    // cannot be done... So I allow it in ReactOS !
+    /*
     Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
                                      SetPaletteRequest->OutputHandle,
                                      &Buffer, GENERIC_WRITE, TRUE);
+    */
+    Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
+                                   SetPaletteRequest->OutputHandle,
+                                   &Buffer, GENERIC_WRITE, TRUE);
     if (!NT_SUCCESS(Status)) return Status;
 
+    DPRINT1("ConDrvSetConsolePalette calling...\n");
+
     Status = ConDrvSetConsolePalette(Buffer->Header.Console,
                                      Buffer,
                                      SetPaletteRequest->PaletteHandle,
                                      SetPaletteRequest->Usage);
 
+    DPRINT1("ConDrvSetConsolePalette returned Status 0x%08lx\n", Status);
+
     ConSrvReleaseScreenBuffer(Buffer, TRUE);
     return Status;
 }
index b6a6d95..ea52cce 100644 (file)
@@ -220,7 +220,7 @@ CSR_API(SrvSetConsoleCursor)
     PCONSOLE_SCREEN_BUFFER Buff;
 
     // FIXME: Tests show that this function is used only for graphics screen buffers
-    // and otherwise it returns false + sets last error to invalid handle.
+    // and otherwise it returns FALSE + sets last error to invalid handle.
     // NOTE: I find that behaviour is ridiculous but ok, let's accept that at the moment...
     Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
                                      SetCursorRequest->OutputHandle,
index 2e62fbe..2a3c616 100644 (file)
@@ -40,14 +40,18 @@ typedef struct _GUI_CONSOLE_INFO
 typedef struct _GUI_CONSOLE_DATA
 {
     CRITICAL_SECTION Lock;
-    HANDLE hGuiInitEvent;
     BOOL WindowSizeLock;
+
+    HANDLE hGuiInitEvent;
     POINT OldCursor;
 
     HWND hWindow;               /* Handle to the console's window       */
     HICON hIcon;                /* Handle to the console's icon (big)   */
     HICON hIconSm;              /* Handle to the console's icon (small) */
 
+    HPALETTE hSysPalette;       /* Handle to the original system palette */
+
+/*** The following may be put per-screen-buffer !! ***/
     HCURSOR hCursor;            /* Handle to the mouse cursor */
     INT  MouseCursorRefCount;   /* The reference counter associated with the mouse cursor. >= 0 and the cursor is shown; < 0 and the cursor is hidden. */
     BOOL IgnoreNextMouseSignal; /* Used in cases where we don't want to treat a mouse signal */
@@ -63,9 +67,11 @@ typedef struct _GUI_CONSOLE_DATA
     HFONT Font;
     UINT CharWidth;
     UINT CharHeight;
+/*****************************************************/
 
     PCONSOLE Console;           /* Pointer to the owned console */
     PCONSOLE_SCREEN_BUFFER ActiveBuffer;    /* Pointer to the active screen buffer (then maybe the previous Console member is redundant?? Or not...) */
+
     GUI_CONSOLE_INFO GuiInfo;   /* GUI terminal settings */
 } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
 
index 0a4d1a0..4869f38 100644 (file)
@@ -513,7 +513,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
 {
     PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Create->lpCreateParams;
     PCONSOLE Console;
-    HDC Dc;
+    HDC hDC;
     HFONT OldFont;
     TEXTMETRICW Metrics;
     SIZE CharSize;
@@ -552,8 +552,8 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
         SetEvent(GuiData->hGuiInitEvent);
         return FALSE;
     }
-    Dc = GetDC(GuiData->hWindow);
-    if (NULL == Dc)
+    hDC = GetDC(GuiData->hWindow);
+    if (NULL == hDC)
     {
         DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
         DeleteObject(GuiData->Font);
@@ -561,21 +561,21 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
         SetEvent(GuiData->hGuiInitEvent);
         return FALSE;
     }
-    OldFont = SelectObject(Dc, GuiData->Font);
+    OldFont = SelectObject(hDC, GuiData->Font);
     if (NULL == OldFont)
     {
         DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
-        ReleaseDC(GuiData->hWindow, Dc);
+        ReleaseDC(GuiData->hWindow, hDC);
         DeleteObject(GuiData->Font);
         GuiData->hWindow = NULL;
         SetEvent(GuiData->hGuiInitEvent);
         return FALSE;
     }
-    if (!GetTextMetricsW(Dc, &Metrics))
+    if (!GetTextMetricsW(hDC, &Metrics))
     {
         DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
-        SelectObject(Dc, OldFont);
-        ReleaseDC(GuiData->hWindow, Dc);
+        SelectObject(hDC, OldFont);
+        ReleaseDC(GuiData->hWindow, hDC);
         DeleteObject(GuiData->Font);
         GuiData->hWindow = NULL;
         SetEvent(GuiData->hGuiInitEvent);
@@ -585,12 +585,12 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
     GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
 
     /* Measure real char width more precisely if possible. */
-    if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize))
+    if (GetTextExtentPoint32W(hDC, L"R", 1, &CharSize))
         GuiData->CharWidth = CharSize.cx;
 
-    SelectObject(Dc, OldFont);
+    SelectObject(hDC, OldFont);
 
-    ReleaseDC(GuiData->hWindow, Dc);
+    ReleaseDC(GuiData->hWindow, hDC);
 
     // FIXME: Keep these instructions here ? ///////////////////////////////////
     Console->ActiveBuffer->CursorBlinkOn = TRUE;
@@ -1700,6 +1700,52 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
             GuiConsoleHandlePaint(GuiData);
             break;
 
+        case WM_PALETTECHANGED:
+        {
+            PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console);
+
+            DPRINT1("WM_PALETTECHANGED called\n");
+
+            /*
+             * Protects against infinite loops:
+             * "... A window that receives this message must not realize
+             * its palette, unless it determines that wParam does not contain
+             * its own window handle." (WM_PALETTECHANGED description - MSDN)
+             *
+             * This message is sent to all windows, including the one that
+             * changed the system palette and caused this message to be sent.
+             * The wParam of this message contains the handle of the window
+             * that caused the system palette to change. To avoid an infinite
+             * loop, care must be taken to check that the wParam of this message
+             * does not match the window's handle.
+             */
+            if ((HWND)wParam == hWnd) break;
+
+            DPRINT1("WM_PALETTECHANGED ok\n");
+
+            // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
+            if (ActiveBuffer->PaletteHandle)
+            {
+                /* Get the Device Context of the console window */
+                HDC hDC = GetDC(GuiData->hWindow);
+
+                DPRINT1("WM_PALETTECHANGED changing palette\n");
+
+                /* Specify the use of the system palette */
+                SetSystemPaletteUse(hDC, ActiveBuffer->PaletteUsage);
+
+                /* Realize the (logical) palette */
+                RealizePalette(hDC);
+
+                /* Release the Device Context and return */
+                ReleaseDC(GuiData->hWindow, hDC);
+            }
+
+            DPRINT1("WM_PALETTECHANGED quit\n");
+
+            break;
+        }
+
         case WM_KEYDOWN:
         case WM_KEYUP:
         case WM_CHAR:
@@ -1805,14 +1851,16 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
              * call after that DefWindowProc, on ReactOS, right-clicks on the
              * (non-client) application title-bar does not display the system
              * menu and does not trigger a WM_NCRBUTTONUP message too.
-             * See: http://git.reactos.org/?p=reactos.git;a=blob;f=reactos/win32ss/user/user32/windows/defwnd.c;hb=HEAD#l1103
+             * See: http://git.reactos.org/?p=reactos.git;a=blob;f=reactos/win32ss/user/user32/windows/defwnd.c;hb=332bc8f482f40fd05ab510f78276576719fbfba8#l1103
              * and line 1135 too.
              */
+#if 0
             if (DefWindowProcW(hWnd, WM_NCHITTEST, 0, lParam) == HTCAPTION)
             {
                 /* Call DefWindowProcW with the WM_CONTEXTMENU message */
                 msg = WM_CONTEXTMENU;
             }
+#endif
             goto Default;
         }
         // case WM_NCRBUTTONUP:
@@ -2370,6 +2418,9 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
         }
     }
 
+    /* Original system palette */
+    GuiData->hSysPalette = NULL;
+
     /* Mouse is shown by default with its default cursor shape */
     GuiData->hCursor = ghDefaultCursor;
     GuiData->MouseCursorRefCount = 0;
@@ -2567,6 +2618,9 @@ static VOID WINAPI
 GuiSetActiveScreenBuffer(IN OUT PFRONTEND This)
 {
     PGUI_CONSOLE_DATA GuiData = This->Data;
+    PCONSOLE_SCREEN_BUFFER ActiveBuffer; // = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console);
+    HDC hDC;
+    HPALETTE hPalette;
 
     EnterCriticalSection(&GuiData->Lock);
     GuiData->WindowSizeLock = TRUE;
@@ -2577,10 +2631,37 @@ GuiSetActiveScreenBuffer(IN OUT PFRONTEND This)
     GuiData->WindowSizeLock = FALSE;
     LeaveCriticalSection(&GuiData->Lock);
 
+    ActiveBuffer = GuiData->ActiveBuffer;
+
+    /* Change the current palette */
+    if (ActiveBuffer->PaletteHandle == NULL)
+    {
+        hPalette = GuiData->hSysPalette;
+    }
+    else
+    {
+        hPalette = ActiveBuffer->PaletteHandle;
+    }
+
+    DPRINT1("GuiSetActiveScreenBuffer using palette 0x%p\n", hPalette);
+
+    /* Get the Device Context of the console window */
+    hDC = GetDC(GuiData->hWindow);
+
+    /* Set the new palette */
+    SelectPalette(hDC, hPalette, FALSE);
+
+    /* Specify the use of the system palette */
+    SetSystemPaletteUse(hDC, ActiveBuffer->PaletteUsage);
+
+    /* Realize the (logical) palette */
+    RealizePalette(hDC);
+
+    /* Release the Device Context */
+    ReleaseDC(GuiData->hWindow, hDC);
+
     GuiResizeTerminal(This);
     // ConioDrawConsole(Console);
-
-    // FIXME: Change the palette.
 }
 
 static VOID WINAPI
@@ -2588,6 +2669,7 @@ GuiReleaseScreenBuffer(IN OUT PFRONTEND This,
                        IN PCONSOLE_SCREEN_BUFFER ScreenBuffer)
 {
     PGUI_CONSOLE_DATA GuiData = This->Data;
+    HDC hDC;
 
     /*
      * If we were notified to release a screen buffer that is not actually
@@ -2603,6 +2685,20 @@ GuiReleaseScreenBuffer(IN OUT PFRONTEND This,
      *   it ONLY.
      */
 
+    /* Get the Device Context of the console window */
+    hDC = GetDC(GuiData->hWindow);
+
+    /* Release the old active palette and set the default one */
+    if (GetCurrentObject(hDC, OBJ_PAL) == ScreenBuffer->PaletteHandle)
+    {
+        /* Set the new palette */
+        SelectPalette(hDC, GuiData->hSysPalette, FALSE);
+    }
+
+    /* Release the Device Context */
+    ReleaseDC(GuiData->hWindow, hDC);
+
+    /* Set the adequate active screen buffer */
     if (ScreenBuffer != GuiData->Console->ActiveBuffer)
     {
         GuiSetActiveScreenBuffer(This);
@@ -2767,6 +2863,61 @@ GuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This,
     pSize->Y = (SHORT)(height / (int)HeightUnit) /* HACK */ + 1;
 }
 
+static BOOL WINAPI
+GuiSetPalette(IN OUT PFRONTEND This,
+              HPALETTE PaletteHandle,
+              UINT PaletteUsage)
+{
+    BOOL Success = TRUE;
+    PGUI_CONSOLE_DATA GuiData = This->Data;
+    // PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console);
+    HDC hDC;
+    HPALETTE OldPalette;
+
+    DPRINT1("GuiSetPalette checkpt 0\n");
+
+    // if (GetType(ActiveBuffer) != GRAPHICS_BUFFER) return FALSE;
+    if (PaletteHandle == NULL) return FALSE;
+
+    DPRINT1("GuiSetPalette checkpt 1\n");
+
+    /* Get the Device Context of the console window */
+    hDC = GetDC(GuiData->hWindow);
+
+    DPRINT1("GuiSetPalette calling SelectPalette(0x%p, 0x%p, FALSE)\n", hDC, PaletteHandle);
+
+    /* Set the new palette */
+    OldPalette = SelectPalette(hDC, PaletteHandle, FALSE);
+    DPRINT1("OldPalette = 0x%p\n", OldPalette);
+    if (OldPalette == NULL)
+    {
+        DPRINT1("SelectPalette failed\n");
+        Success = FALSE;
+        goto Quit;
+    }
+
+    DPRINT1("GuiSetPalette checkpt 2\n");
+
+    /* Specify the use of the system palette */
+    SetSystemPaletteUse(hDC, PaletteUsage);
+
+    /* Realize the (logical) palette */
+    RealizePalette(hDC);
+
+    DPRINT1("GuiData->hSysPalette before == 0x%p\n", GuiData->hSysPalette);
+
+    /* Save the original system palette handle */
+    if (GuiData->hSysPalette == NULL) GuiData->hSysPalette = OldPalette;
+
+    DPRINT1("GuiData->hSysPalette after == 0x%p\n", GuiData->hSysPalette);
+
+Quit:
+    DPRINT1("GuiSetPalette Quit\n");
+    /* Release the Device Context and return */
+    ReleaseDC(GuiData->hWindow, hDC);
+    return Success;
+}
+
 static ULONG WINAPI
 GuiGetDisplayMode(IN OUT PFRONTEND This)
 {
@@ -2880,6 +3031,7 @@ static FRONTEND_VTBL GuiVtbl =
     GuiChangeIcon,
     GuiGetConsoleWindowHandle,
     GuiGetLargestConsoleWindowSize,
+    GuiSetPalette,
     GuiGetDisplayMode,
     GuiSetDisplayMode,
     GuiShowMouseCursor,
index d7c55ae..d27d10e 100644 (file)
@@ -746,6 +746,14 @@ TuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This,
     *pSize = PhysicalConsoleSize;
 }
 
+static BOOL WINAPI
+TuiSetPalette(IN OUT PFRONTEND This,
+              HPALETTE PaletteHandle,
+              UINT PaletteUsage)
+{
+    return TRUE;
+}
+
 static ULONG WINAPI
 TuiGetDisplayMode(IN OUT PFRONTEND This)
 {
@@ -805,6 +813,7 @@ static FRONTEND_VTBL TuiVtbl =
     TuiChangeIcon,
     TuiGetConsoleWindowHandle,
     TuiGetLargestConsoleWindowSize,
+    TuiSetPalette,
     TuiGetDisplayMode,
     TuiSetDisplayMode,
     TuiShowMouseCursor,
index 154373f..97a646f 100644 (file)
@@ -64,6 +64,8 @@ struct _CONSOLE_SCREEN_BUFFER
 
     LIST_ENTRY ListEntry;               /* Entry in console's list of buffers */
 
+    // 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   ViewSize;                   /* Associated "view" (i.e. console) size */
 
@@ -82,6 +84,9 @@ struct _CONSOLE_SCREEN_BUFFER
     CONSOLE_CURSOR_INFO CursorInfo; // FIXME: Keep this member or not ??
 /*********************************************/
 
+    HPALETTE PaletteHandle;             /* Handle to the color palette associated to this buffer */
+    UINT     PaletteUsage;              /* The new use of the system palette. See SetSystemPaletteUse 'uUsage' parameter */
+
 //  WORD   ScreenDefaultAttrib;         /* Default screen char attribute */
 //  WORD   PopupDefaultAttrib;          /* Default popup char attribute */
     USHORT Mode;                        /* Output buffer modes */
@@ -223,6 +228,9 @@ typedef struct _FRONTEND_VTBL
     HWND (WINAPI *GetConsoleWindowHandle)(IN OUT PFRONTEND This);
     VOID (WINAPI *GetLargestConsoleWindowSize)(IN OUT PFRONTEND This,
                                                PCOORD pSize);
+    BOOL (WINAPI *SetPalette)(IN OUT PFRONTEND This,
+                              HPALETTE PaletteHandle,
+                              UINT PaletteUsage);
     ULONG (WINAPI *GetDisplayMode)(IN OUT PFRONTEND This);
     BOOL  (WINAPI *SetDisplayMode)(IN OUT PFRONTEND This,
                                    ULONG NewMode);
index 3e1b1a5..f82025f 100644 (file)
@@ -38,6 +38,8 @@
     (Console)->TermIFace.Vtbl->GetConsoleWindowHandle(&(Console)->TermIFace)
 #define TermGetLargestConsoleWindowSize(Console, pSize) \
     (Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
+#define TermSetPalette(Console, PaletteHandle, PaletteUsage) \
+    (Console)->TermIFace.Vtbl->SetPalette(&(Console)->TermIFace, (PaletteHandle), (PaletteUsage))
 #define TermGetDisplayMode(Console) \
     (Console)->TermIFace.Vtbl->GetDisplayMode(&(Console)->TermIFace)
 #define TermSetDisplayMode(Console, NewMode) \