/* INCLUDES *******************************************************************/
#define COBJMACROS
-#define NONAMELESSUNION
#include "consrv.h"
#include "include/conio.h"
/* Not defined in any header file */
-extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check);
+extern VOID NTAPI PrivateCsrssManualGuiCheck(LONG Check);
// See winsrv/usersrv/init.c line 234
#define GWLP_CONSOLE_LEADER_PID 0
#define GWLP_CONSOLE_LEADER_TID 4
-#define SetConsoleWndConsoleLeaderCID(GuiData) \
-do { \
- PCONSOLE_PROCESS_DATA ProcessData; \
- CLIENT_ID ConsoleLeaderCID; \
+#define SetConsoleWndConsoleLeaderCID(GuiData) \
+do { \
+ PCONSOLE_PROCESS_DATA ProcessData; \
+ CLIENT_ID ConsoleLeaderCID; \
ProcessData = CONTAINING_RECORD((GuiData)->Console->ProcessList.Blink, \
CONSOLE_PROCESS_DATA, \
ConsoleLink); \
ConsoleLeaderCID = ProcessData->Process->ClientId; \
- SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_PID, (LONG_PTR)(ConsoleLeaderCID.UniqueProcess)); \
- SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_TID, (LONG_PTR)(ConsoleLeaderCID.UniqueThread )); \
+ SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_PID, \
+ (LONG_PTR)(ConsoleLeaderCID.UniqueProcess)); \
+ SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_TID, \
+ (LONG_PTR)(ConsoleLeaderCID.UniqueThread )); \
} while (0)
/**************************************************************/
GuiConsolePaste(PGUI_CONSOLE_DATA GuiData);
static VOID
GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord);
-static VOID WINAPI
+static VOID NTAPI
GuiDrawRegion(IN OUT PFRONTEND This, SMALL_RECT* Region);
static VOID
-GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData);
+GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData, DWORD WidthUnit, DWORD HeightUnit);
static LRESULT
Ret = FALSE;
goto Quit;
}
- ActiveBuffer = ConDrvGetActiveScreenBuffer(Console);
+ ActiveBuffer = GuiData->ActiveBuffer;
/*
* In case the selected menu item belongs to the user-reserved menu id range,
LPWSTR WindowTitle = NULL;
SIZE_T Length = 0;
+ /*
+ * The selection area extends to the whole screen buffer's width.
+ */
Console->Selection.dwSelectionAnchor.X = 0;
Console->Selection.dwSelectionAnchor.Y = 0;
- Console->dwSelectionCursor.X = ActiveBuffer->ViewSize.X - 1;
- Console->dwSelectionCursor.Y = ActiveBuffer->ViewSize.Y - 1;
+ Console->dwSelectionCursor.X = ActiveBuffer->ScreenBufferSize.X - 1;
+
+ /*
+ * Determine whether the selection must extend to just some part
+ * (for text-mode screen buffers) or to all of the screen buffer's
+ * height (for graphics ones).
+ */
+ if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
+ {
+ /*
+ * We select all the characters from the first line
+ * to the line where the cursor is positioned.
+ */
+ Console->dwSelectionCursor.Y = ActiveBuffer->CursorPosition.Y;
+ }
+ else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */
+ {
+ /*
+ * We select all the screen buffer area.
+ */
+ Console->dwSelectionCursor.Y = ActiveBuffer->ScreenBufferSize.Y - 1;
+ }
+
Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION;
GuiConsoleUpdateSelection(Console, &Console->dwSelectionCursor);
}
static VOID
-GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData)
+GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData, DWORD WidthUnit, DWORD HeightUnit)
{
- PCONSOLE Console = GuiData->Console;
- PCONSOLE_SCREEN_BUFFER Buff = ConDrvGetActiveScreenBuffer(Console);
+ PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer;
SCROLLINFO sInfo;
DWORD Width, Height;
- UINT WidthUnit, HeightUnit;
-
- GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit);
Width = Buff->ViewSize.X * WidthUnit +
2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
// to: InvalidateRect(GuiData->hWindow, NULL, TRUE);
}
-static VOID
-GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData)
-{
- PCONSOLE Console = GuiData->Console;
- // DEVMODE dmScreenSettings;
-
- if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
-
- /* 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-winapi
- // 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)
- {
- memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
- dmScreenSettings.dmSize = sizeof(dmScreenSettings);
- dmScreenSettings.dmDisplayFixedOutput = DMDFO_CENTER; // DMDFO_STRETCH // DMDFO_DEFAULT
- dmScreenSettings.dmPelsWidth = 640; // Console->ActiveBuffer->ViewSize.X * GuiData->CharWidth;
- dmScreenSettings.dmPelsHeight = 480; // Console->ActiveBuffer->ViewSize.Y * GuiData->CharHeight;
- dmScreenSettings.dmBitsPerPel = 32;
- dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
- }
- else
- {
- }
-#endif
-
- LeaveCriticalSection(&Console->Lock);
-}
-
static BOOL
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;
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);
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);
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);
+
+ /* Initialize the terminal framebuffer */
+ GuiData->hMemDC = CreateCompatibleDC(NULL);
+ GuiData->hBitmap = NULL;
+ GuiData->hSysPalette = NULL; /* Original system palette */
// FIXME: Keep these instructions here ? ///////////////////////////////////
Console->ActiveBuffer->CursorBlinkOn = TRUE;
static VOID
SmallRectToRect(PGUI_CONSOLE_DATA GuiData, PRECT Rect, PSMALL_RECT SmallRect)
{
- PCONSOLE Console = GuiData->Console;
- PCONSOLE_SCREEN_BUFFER Buffer = ConDrvGetActiveScreenBuffer(Console);
+ PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer;
UINT WidthUnit, HeightUnit;
GetScreenBufferSizeUnits(Buffer, GuiData, &WidthUnit, &HeightUnit);
VOID
GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData,
- HDC hDC,
- PRECT rc);
+ PRECT rcView,
+ PRECT rcFramebuffer);
VOID
GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData,
- HDC hDC,
- PRECT rc);
+ PRECT rcView,
+ PRECT rcFramebuffer);
static VOID
GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData)
BOOL Success = TRUE;
PCONSOLE Console = GuiData->Console;
PCONSOLE_SCREEN_BUFFER ActiveBuffer;
- HDC hDC;
PAINTSTRUCT ps;
+ RECT rcPaint;
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
{
Success = FALSE;
goto Quit;
}
- ActiveBuffer = ConDrvGetActiveScreenBuffer(Console);
+ ActiveBuffer = GuiData->ActiveBuffer;
- hDC = BeginPaint(GuiData->hWindow, &ps);
- if (hDC != NULL &&
+ BeginPaint(GuiData->hWindow, &ps);
+ if (ps.hdc != NULL &&
ps.rcPaint.left < ps.rcPaint.right &&
ps.rcPaint.top < ps.rcPaint.bottom)
{
EnterCriticalSection(&GuiData->Lock);
+ /* Compose the current screen-buffer on-memory */
if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
{
GuiPaintTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)ActiveBuffer,
- GuiData, hDC, &ps.rcPaint);
+ GuiData, &ps.rcPaint, &rcPaint);
}
else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */
{
GuiPaintGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)ActiveBuffer,
- GuiData, hDC, &ps.rcPaint);
+ GuiData, &ps.rcPaint, &rcPaint);
}
+ /* Send it to screen */
+ BitBlt(ps.hdc,
+ ps.rcPaint.left,
+ ps.rcPaint.top,
+ rcPaint.right - rcPaint.left,
+ rcPaint.bottom - rcPaint.top,
+ GuiData->hMemDC,
+ rcPaint.left,
+ rcPaint.top,
+ SRCCOPY);
+
if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
{
- RECT rc;
- SmallRectToRect(GuiData, &rc, &Console->Selection.srSelection);
+ SmallRectToRect(GuiData, &rcPaint, &Console->Selection.srSelection);
- /* invert the selection */
- if (IntersectRect(&rc, &ps.rcPaint, &rc))
+ /* Invert the selection */
+ if (IntersectRect(&rcPaint, &ps.rcPaint, &rcPaint))
{
- PatBlt(hDC,
- rc.left,
- rc.top,
- rc.right - rc.left,
- rc.bottom - rc.top,
- DSTINVERT);
+ InvertRect(ps.hdc, &rcPaint);
}
}
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
- ActiveBuffer = ConDrvGetActiveScreenBuffer(Console);
+ ActiveBuffer = GuiData->ActiveBuffer;
if (Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS)
{
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
- Buff = ConDrvGetActiveScreenBuffer(Console);
+ Buff = GuiData->ActiveBuffer;
if (GetType(Buff) == TEXTMODE_BUFFER)
{
GuiInvalidateCell(&Console->TermIFace, Buff->CursorPosition.X, Buff->CursorPosition.Y);
Buff->CursorBlinkOn = !Buff->CursorBlinkOn;
- if ((GuiData->OldCursor.x != Buff->CursorPosition.X) || (GuiData->OldCursor.y != Buff->CursorPosition.Y))
+ if ((GuiData->OldCursor.x != Buff->CursorPosition.X) ||
+ (GuiData->OldCursor.y != Buff->CursorPosition.Y))
{
SCROLLINFO xScroll;
int OldScrollX = -1, OldScrollY = -1;
// If we successfully got the info for the horizontal scrollbar
if (OldScrollX >= 0)
{
- if ((Buff->CursorPosition.X < Buff->ViewOrigin.X) || (Buff->CursorPosition.X >= (Buff->ViewOrigin.X + Buff->ViewSize.X)))
+ if ((Buff->CursorPosition.X < Buff->ViewOrigin.X) ||
+ (Buff->CursorPosition.X >= (Buff->ViewOrigin.X + Buff->ViewSize.X)))
{
// Handle the horizontal scroll bar
- if (Buff->CursorPosition.X >= Buff->ViewSize.X) NewScrollX = Buff->CursorPosition.X - Buff->ViewSize.X + 1;
- else NewScrollX = 0;
+ if (Buff->CursorPosition.X >= Buff->ViewSize.X)
+ NewScrollX = Buff->CursorPosition.X - Buff->ViewSize.X + 1;
+ else
+ NewScrollX = 0;
}
else
{
// If we successfully got the info for the vertical scrollbar
if (OldScrollY >= 0)
{
- if ((Buff->CursorPosition.Y < Buff->ViewOrigin.Y) || (Buff->CursorPosition.Y >= (Buff->ViewOrigin.Y + Buff->ViewSize.Y)))
+ if ((Buff->CursorPosition.Y < Buff->ViewOrigin.Y) ||
+ (Buff->CursorPosition.Y >= (Buff->ViewOrigin.Y + Buff->ViewSize.Y)))
{
// Handle the vertical scroll bar
- if (Buff->CursorPosition.Y >= Buff->ViewSize.Y) NewScrollY = Buff->CursorPosition.Y - Buff->ViewSize.Y + 1;
- else NewScrollY = 0;
+ if (Buff->CursorPosition.Y >= Buff->ViewSize.Y)
+ NewScrollY = Buff->CursorPosition.Y - Buff->ViewSize.Y + 1;
+ else
+ NewScrollY = 0;
}
else
{
SetScrollInfo(GuiData->hWindow, SB_VERT, &xScroll, TRUE);
}
UpdateWindow(GuiData->hWindow);
+ // InvalidateRect(GuiData->hWindow, NULL, FALSE);
GuiData->OldCursor.x = Buff->CursorPosition.X;
GuiData->OldCursor.y = Buff->CursorPosition.Y;
}
static LRESULT
GuiConsoleHandleNcDestroy(HWND hWnd)
{
+ PGUI_CONSOLE_DATA GuiData = GuiGetGuiData(hWnd);
+
KillTimer(hWnd, CONGUI_UPDATE_TIMER);
GetSystemMenu(hWnd, TRUE);
+ if (GuiData)
+ {
+ /* Free the terminal framebuffer */
+ if (GuiData->hMemDC ) DeleteDC(GuiData->hMemDC);
+ if (GuiData->hBitmap) DeleteObject(GuiData->hBitmap);
+ // if (GuiData->hSysPalette) DeleteObject(GuiData->hSysPalette);
+ if (GuiData->Font) DeleteObject(GuiData->Font);
+ }
+
/* Free the GuiData registration */
SetWindowLongPtrW(hWnd, GWLP_USERDATA, (DWORD_PTR)NULL);
static COORD
PointToCoord(PGUI_CONSOLE_DATA GuiData, LPARAM lParam)
{
- PCONSOLE Console = GuiData->Console;
- PCONSOLE_SCREEN_BUFFER Buffer = ConDrvGetActiveScreenBuffer(Console);
+ PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer;
COORD Coord;
UINT WidthUnit, HeightUnit;
if (OpenClipboard(GuiData->hWindow) == TRUE)
{
PCONSOLE Console = GuiData->Console;
- PCONSOLE_SCREEN_BUFFER Buffer = ConDrvGetActiveScreenBuffer(Console);
+ PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer;
if (GetType(Buffer) == TEXTMODE_BUFFER)
{
{
if (OpenClipboard(GuiData->hWindow) == TRUE)
{
- PCONSOLE Console = GuiData->Console;
- PCONSOLE_SCREEN_BUFFER Buffer = ConDrvGetActiveScreenBuffer(Console);
+ PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer;
if (GetType(Buffer) == TEXTMODE_BUFFER)
{
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
- ActiveBuffer = ConDrvGetActiveScreenBuffer(Console);
+ ActiveBuffer = GuiData->ActiveBuffer;
GetScreenBufferSizeUnits(ActiveBuffer, GuiData, &WidthUnit, &HeightUnit);
if ((GuiData->WindowSizeLock == FALSE) &&
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED))
{
- PCONSOLE_SCREEN_BUFFER Buff = ConDrvGetActiveScreenBuffer(Console);
+ PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer;
DWORD windx, windy, charx, chary;
UINT WidthUnit, HeightUnit;
Buff->ViewSize.Y = (chary <= Buff->ScreenBufferSize.Y) ? chary : Buff->ScreenBufferSize.Y;
}
- GuiConsoleResizeWindow(GuiData);
+ GuiConsoleResizeWindow(GuiData, WidthUnit, HeightUnit);
// Adjust the start of the visible area if we are attempting to show nonexistent areas
if ((Buff->ScreenBufferSize.X - Buff->ViewOrigin.X) < Buff->ViewSize.X) Buff->ViewOrigin.X = Buff->ScreenBufferSize.X - Buff->ViewSize.X;
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return 0;
- Buff = ConDrvGetActiveScreenBuffer(Console);
+ Buff = GuiData->ActiveBuffer;
if (uMsg == WM_HSCROLL)
{
SetScrollInfo(GuiData->hWindow, fnBar, &sInfo, TRUE);
UpdateWindow(GuiData->hWindow);
+ // InvalidateRect(GuiData->hWindow, NULL, FALSE);
}
Quit:
return 0;
}
+
+BOOL
+EnterFullScreen(PGUI_CONSOLE_DATA GuiData);
+VOID
+LeaveFullScreen(PGUI_CONSOLE_DATA GuiData);
+VOID
+SwitchFullScreen(PGUI_CONSOLE_DATA GuiData, BOOL FullScreen);
+VOID
+GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData);
+
static LRESULT CALLBACK
GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
GuiData = GuiGetGuiData(hWnd);
if (GuiData == NULL) return DefWindowProcW(hWnd, msg, wParam, lParam);
+ // TEMPORARY HACK until all of the functions can deal with a NULL GuiData->ActiveBuffer ...
+ if (GuiData->ActiveBuffer == NULL) return DefWindowProcW(hWnd, msg, wParam, lParam);
+
/*
* Just retrieve a pointer to the console in case somebody needs it.
* It is not NULL because it was checked in GuiGetGuiData.
{
case WM_ACTIVATE:
{
- if (LOWORD(wParam) == WA_CLICKACTIVE) GuiData->IgnoreNextMouseSignal = TRUE;
+ WORD ActivationState = LOWORD(wParam);
+
+ DPRINT1("WM_ACTIVATE - ActivationState = %d\n");
+
+ 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;
}
GuiConsoleHandlePaint(GuiData);
break;
+ case WM_PALETTECHANGED:
+ {
+ PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
+
+ 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)
+ {
+ DPRINT1("WM_PALETTECHANGED changing palette\n");
+
+ /* Specify the use of the system palette for the framebuffer */
+ SetSystemPaletteUse(GuiData->hMemDC, ActiveBuffer->PaletteUsage);
+
+ /* Realize the (logical) palette */
+ RealizePalette(GuiData->hMemDC);
+ }
+
+ DPRINT1("WM_PALETTECHANGED quit\n");
+
+ break;
+ }
+
case WM_KEYDOWN:
case WM_KEYUP:
case WM_CHAR:
if (msg == WM_SYSKEYDOWN && (HIWORD(lParam) & KF_ALTDOWN) && wParam == VK_RETURN)
{
/* Switch only at first Alt-Enter press, and ignore subsequent key repetitions */
- if ((HIWORD(lParam) & (KF_UP | KF_REPEAT)) != KF_REPEAT) GuiConsoleSwitchFullScreen(GuiData);
+ if ((HIWORD(lParam) & (KF_UP | KF_REPEAT)) != KF_REPEAT)
+ GuiConsoleSwitchFullScreen(GuiData);
+
break;
}
* 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:
{
if (ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
{
+ BOOL SetFocus = (msg == WM_SETFOCUS);
INPUT_RECORD er;
+
er.EventType = FOCUS_EVENT;
- er.Event.FocusEvent.bSetFocus = (msg == WM_SETFOCUS);
+ er.Event.FocusEvent.bSetFocus = SetFocus;
ConioProcessInputEvent(Console, &er);
- if (msg == WM_SETFOCUS)
+ if (SetFocus)
DPRINT1("TODO: Create console caret\n");
- else // if (msg == WM_KILLFOCUS)
+ else
DPRINT1("TODO: Destroy console caret\n");
LeaveCriticalSection(&Console->Lock);
case PM_RESIZE_TERMINAL:
{
+ PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer;
+ HDC hDC;
+ HBITMAP hnew, hold;
+
+ DWORD Width, Height;
+ UINT WidthUnit, HeightUnit;
+
+ GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit);
+
+ Width = Buff->ScreenBufferSize.X * WidthUnit ;
+ Height = Buff->ScreenBufferSize.Y * HeightUnit;
+
+ /* Recreate the framebuffer */
+ hDC = GetDC(GuiData->hWindow);
+ hnew = CreateCompatibleBitmap(hDC, Width, Height);
+ ReleaseDC(GuiData->hWindow, hDC);
+ hold = SelectObject(GuiData->hMemDC, hnew);
+ if (GuiData->hBitmap)
+ {
+ if (hold == GuiData->hBitmap) DeleteObject(GuiData->hBitmap);
+ }
+ GuiData->hBitmap = hnew;
+
/* Resize the window to the user's values */
GuiData->WindowSizeLock = TRUE;
- GuiConsoleResizeWindow(GuiData);
+ GuiConsoleResizeWindow(GuiData, WidthUnit, HeightUnit);
GuiData->WindowSizeLock = FALSE;
break;
}
(PVOID)GuiData);
if (NULL != NewWindow)
{
+ ASSERT(NewWindow == GuiData->hWindow);
+
WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
WindowCount++;
SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
/* Move and resize the window to the user's values */
/* CAN WE DEADLOCK ?? */
GuiConsoleMoveWindow(GuiData);
- GuiData->WindowSizeLock = TRUE;
- GuiConsoleResizeWindow(GuiData);
- GuiData->WindowSizeLock = FALSE;
+ SendMessageW(GuiData->hWindow, PM_RESIZE_TERMINAL, 0, 0);
+
+ /* Switch to full-screen mode if necessary */
+ if (GuiData->GuiInfo.FullScreen) SwitchFullScreen(GuiData, TRUE);
// ShowWindow(NewWindow, (int)wParam);
ShowWindowAsync(NewWindow, (int)wParam);
{
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.
}
}
-static DWORD WINAPI
+static DWORD NTAPI
GuiConsoleGuiThread(PVOID Data)
{
MSG msg;
* GUI Console Driver *
******************************************************************************/
-static VOID WINAPI
+static VOID NTAPI
GuiDeinitFrontEnd(IN OUT PFRONTEND This);
NTSTATUS NTAPI
return STATUS_UNSUCCESSFUL;
}
/* HACK */ Console->TermIFace.Data = (PVOID)GuiData; /* HACK */
- GuiData->Console = Console;
+ GuiData->Console = Console;
+ GuiData->ActiveBuffer = Console->ActiveBuffer;
GuiData->hWindow = NULL;
/* The console can be resized */
*/
if (ConsoleStartInfo->dwStartupFlags & STARTF_USESHOWWINDOW)
{
- TermInfo.ShowWindow = ConsoleStartInfo->ShowWindow;
+ TermInfo.ShowWindow = ConsoleStartInfo->wShowWindow;
}
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEPOSITION)
{
TermInfo.AutoPosition = FALSE;
- TermInfo.WindowOrigin = ConsoleStartInfo->ConsoleWindowOrigin;
+ TermInfo.WindowOrigin.x = ConsoleStartInfo->dwWindowOrigin.X;
+ TermInfo.WindowOrigin.y = ConsoleStartInfo->dwWindowOrigin.Y;
}
if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN)
{
return STATUS_SUCCESS;
}
-static VOID WINAPI
+static VOID NTAPI
GuiDeinitFrontEnd(IN OUT PFRONTEND This)
{
PGUI_CONSOLE_DATA GuiData = This->Data;
DPRINT("Quit GuiDeinitFrontEnd\n");
}
-static VOID WINAPI
+static VOID NTAPI
GuiDrawRegion(IN OUT PFRONTEND This,
SMALL_RECT* Region)
{
SmallRectToRect(GuiData, &RegionRect, Region);
/* Do not erase the background: it speeds up redrawing and reduce flickering */
InvalidateRect(GuiData->hWindow, &RegionRect, FALSE);
+ /**UpdateWindow(GuiData->hWindow);**/
}
-static VOID WINAPI
+static VOID NTAPI
GuiWriteStream(IN OUT PFRONTEND This,
SMALL_RECT* Region,
SHORT CursorStartX,
if (NULL == GuiData || NULL == GuiData->hWindow) return;
- Buff = ConDrvGetActiveScreenBuffer(GuiData->Console);
+ Buff = GuiData->ActiveBuffer;
if (GetType(Buff) != TEXTMODE_BUFFER) return;
if (0 != ScrolledLines)
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
}
-static BOOL WINAPI
+static BOOL NTAPI
GuiSetCursorInfo(IN OUT PFRONTEND This,
PCONSOLE_SCREEN_BUFFER Buff)
{
PGUI_CONSOLE_DATA GuiData = This->Data;
- if (ConDrvGetActiveScreenBuffer(GuiData->Console) == Buff)
+ if (GuiData->ActiveBuffer == Buff)
{
GuiInvalidateCell(This, Buff->CursorPosition.X, Buff->CursorPosition.Y);
}
return TRUE;
}
-static BOOL WINAPI
+static BOOL NTAPI
GuiSetScreenInfo(IN OUT PFRONTEND This,
PCONSOLE_SCREEN_BUFFER Buff,
SHORT OldCursorX,
{
PGUI_CONSOLE_DATA GuiData = This->Data;
- if (ConDrvGetActiveScreenBuffer(GuiData->Console) == Buff)
+ if (GuiData->ActiveBuffer == Buff)
{
/* Redraw char at old position (remove cursor) */
GuiInvalidateCell(This, OldCursorX, OldCursorY);
return TRUE;
}
-static VOID WINAPI
+static VOID NTAPI
GuiResizeTerminal(IN OUT PFRONTEND This)
{
PGUI_CONSOLE_DATA GuiData = This->Data;
/* Resize the window to the user's values */
- // GuiData->WindowSizeLock = TRUE;
- // GuiConsoleResizeWindow(GuiData);
- // GuiData->WindowSizeLock = FALSE;
- // NOTE: This code ^^ causes deadlocks...
-
PostMessageW(GuiData->hWindow, PM_RESIZE_TERMINAL, 0, 0);
}
-static BOOL WINAPI
+static VOID NTAPI
+GuiSetActiveScreenBuffer(IN OUT PFRONTEND This)
+{
+ PGUI_CONSOLE_DATA GuiData = This->Data;
+ PCONSOLE_SCREEN_BUFFER ActiveBuffer;
+ HPALETTE hPalette;
+
+ EnterCriticalSection(&GuiData->Lock);
+ GuiData->WindowSizeLock = TRUE;
+
+ InterlockedExchangePointer(&GuiData->ActiveBuffer,
+ ConDrvGetActiveScreenBuffer(GuiData->Console));
+
+ 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);
+
+ /* Set the new palette for the framebuffer */
+ SelectPalette(GuiData->hMemDC, hPalette, FALSE);
+
+ /* Specify the use of the system palette for the framebuffer */
+ SetSystemPaletteUse(GuiData->hMemDC, ActiveBuffer->PaletteUsage);
+
+ /* Realize the (logical) palette */
+ RealizePalette(GuiData->hMemDC);
+
+ GuiResizeTerminal(This);
+ // ConioDrawConsole(Console);
+}
+
+static VOID NTAPI
+GuiReleaseScreenBuffer(IN OUT PFRONTEND This,
+ IN PCONSOLE_SCREEN_BUFFER ScreenBuffer)
+{
+ PGUI_CONSOLE_DATA GuiData = This->Data;
+
+ /*
+ * If we were notified to release a screen buffer that is not actually
+ * ours, then just ignore the notification...
+ */
+ if (ScreenBuffer != GuiData->ActiveBuffer) return;
+
+ /*
+ * ... else, we must release our active buffer. Two cases are present:
+ * - If ScreenBuffer (== GuiData->ActiveBuffer) IS NOT the console
+ * active screen buffer, then we can safely switch to it.
+ * - If ScreenBuffer IS the console active screen buffer, we must release
+ * it ONLY.
+ */
+
+ /* Release the old active palette and set the default one */
+ if (GetCurrentObject(GuiData->hMemDC, OBJ_PAL) == ScreenBuffer->PaletteHandle)
+ {
+ /* Set the new palette */
+ SelectPalette(GuiData->hMemDC, GuiData->hSysPalette, FALSE);
+ }
+
+ /* Set the adequate active screen buffer */
+ if (ScreenBuffer != GuiData->Console->ActiveBuffer)
+ {
+ GuiSetActiveScreenBuffer(This);
+ }
+ else
+ {
+ EnterCriticalSection(&GuiData->Lock);
+ GuiData->WindowSizeLock = TRUE;
+
+ InterlockedExchangePointer(&GuiData->ActiveBuffer, NULL);
+
+ GuiData->WindowSizeLock = FALSE;
+ LeaveCriticalSection(&GuiData->Lock);
+ }
+}
+
+static BOOL NTAPI
GuiProcessKeyCallback(IN OUT PFRONTEND This,
MSG* msg,
BYTE KeyStateMenu,
return FALSE;
}
-static BOOL WINAPI
+static BOOL NTAPI
GuiSetMouseCursor(IN OUT PFRONTEND This,
HCURSOR hCursor);
-static VOID WINAPI
+static VOID NTAPI
GuiRefreshInternalInfo(IN OUT PFRONTEND This)
{
PGUI_CONSOLE_DATA GuiData = This->Data;
GuiSetMouseCursor(This, NULL);
}
-static VOID WINAPI
+static VOID NTAPI
GuiChangeTitle(IN OUT PFRONTEND This)
{
PGUI_CONSOLE_DATA GuiData = This->Data;
SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer);
}
-static BOOL WINAPI
+static BOOL NTAPI
GuiChangeIcon(IN OUT PFRONTEND This,
HICON hWindowIcon)
{
return TRUE;
}
-static HWND WINAPI
+static HWND NTAPI
GuiGetConsoleWindowHandle(IN OUT PFRONTEND This)
{
PGUI_CONSOLE_DATA GuiData = This->Data;
return GuiData->hWindow;
}
-static VOID WINAPI
+static VOID NTAPI
GuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This,
PCOORD pSize)
{
return;
}
- ActiveBuffer = ConDrvGetActiveScreenBuffer(GuiData->Console);
+ ActiveBuffer = GuiData->ActiveBuffer;
if (ActiveBuffer)
{
GetScreenBufferSizeUnits(ActiveBuffer, GuiData, &WidthUnit, &HeightUnit);
pSize->Y = (SHORT)(height / (int)HeightUnit) /* HACK */ + 1;
}
-static ULONG WINAPI
+static BOOL NTAPI
+GuiSetPalette(IN OUT PFRONTEND This,
+ HPALETTE PaletteHandle,
+ UINT PaletteUsage)
+{
+ PGUI_CONSOLE_DATA GuiData = This->Data;
+ HPALETTE OldPalette;
+
+ // if (GetType(GuiData->ActiveBuffer) != GRAPHICS_BUFFER) return FALSE;
+ if (PaletteHandle == NULL) return FALSE;
+
+ /* Set the new palette for the framebuffer */
+ OldPalette = SelectPalette(GuiData->hMemDC, PaletteHandle, FALSE);
+ if (OldPalette == NULL) return FALSE;
+
+ /* Specify the use of the system palette for the framebuffer */
+ SetSystemPaletteUse(GuiData->hMemDC, PaletteUsage);
+
+ /* Realize the (logical) palette */
+ RealizePalette(GuiData->hMemDC);
+
+ /* Save the original system palette handle */
+ if (GuiData->hSysPalette == NULL) GuiData->hSysPalette = OldPalette;
+
+ return TRUE;
+}
+
+static ULONG NTAPI
GuiGetDisplayMode(IN OUT PFRONTEND This)
{
PGUI_CONSOLE_DATA GuiData = This->Data;
return DisplayMode;
}
-static BOOL WINAPI
+static BOOL NTAPI
GuiSetDisplayMode(IN OUT PFRONTEND This,
ULONG NewMode)
{
PGUI_CONSOLE_DATA GuiData = This->Data;
+ BOOL FullScreen;
if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE))
return FALSE;
- GuiData->GuiInfo.FullScreen = (NewMode & CONSOLE_FULLSCREEN_MODE);
- // TODO: Change the display mode
+ FullScreen = ((NewMode & CONSOLE_FULLSCREEN_MODE) != 0);
+
+ if (FullScreen != GuiData->GuiInfo.FullScreen)
+ {
+ SwitchFullScreen(GuiData, FullScreen);
+ }
+
return TRUE;
}
-static INT WINAPI
+static INT NTAPI
GuiShowMouseCursor(IN OUT PFRONTEND This,
BOOL Show)
{
return GuiData->MouseCursorRefCount;
}
-static BOOL WINAPI
+static BOOL NTAPI
GuiSetMouseCursor(IN OUT PFRONTEND This,
HCURSOR hCursor)
{
return TRUE;
}
-static HMENU WINAPI
+static HMENU NTAPI
GuiMenuControl(IN OUT PFRONTEND This,
UINT cmdIdLow,
UINT cmdIdHigh)
return GetSystemMenu(GuiData->hWindow, FALSE);
}
-static BOOL WINAPI
+static BOOL NTAPI
GuiSetMenuClose(IN OUT PFRONTEND This,
BOOL Enable)
{
GuiSetCursorInfo,
GuiSetScreenInfo,
GuiResizeTerminal,
+ GuiSetActiveScreenBuffer,
+ GuiReleaseScreenBuffer,
GuiProcessKeyCallback,
GuiRefreshInternalInfo,
GuiChangeTitle,
GuiChangeIcon,
GuiGetConsoleWindowHandle,
GuiGetLargestConsoleWindowSize,
+ GuiSetPalette,
GuiGetDisplayMode,
GuiSetDisplayMode,
GuiShowMouseCursor,
/* Get the window showing command */
hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd);
- if (SUCCEEDED(hRes)) ConsoleStartInfo->ShowWindow = (WORD)ShowCmd;
+ if (SUCCEEDED(hRes)) ConsoleStartInfo->wShowWindow = (WORD)ShowCmd;
/* Get the hotkey */
// hRes = pshl->GetHotkey(&ShowCmd);