-/* $Id: guiconsole.c,v 1.2 2003/12/03 21:50:49 gvg Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
- * FILE: subsys/csrss/win32csr/dllmain.c
- * PURPOSE: Initialization
+ * FILE: subsys/csrss/win32csr/guiconsole.c
+ * PURPOSE: Implementation of gui-mode consoles
*/
/* INCLUDES ******************************************************************/
-#include <windows.h>
-#include "conio.h"
-#include "guiconsole.h"
-#include "win32csr.h"
+#include "w32csr.h"
+
+#define NDEBUG
+#include <debug.h>
/* Not defined in any header file */
-extern VOID STDCALL PrivateCsrssGraphicsDone(VOID);
+extern VOID STDCALL PrivateCsrssManualGuiCheck(LONG Check);
/* GLOBALS *******************************************************************/
PWCHAR LineBuffer;
BOOL CursorBlinkOn;
BOOL ForceCursorOff;
+ CRITICAL_SECTION Lock;
+ RECT Selection;
+ POINT SelectionStart;
+ BOOL MouseDown;
} GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
#ifndef WM_APP
#define PM_CREATE_CONSOLE (WM_APP + 1)
#define PM_DESTROY_CONSOLE (WM_APP + 2)
-#define PM_COPY_REGION (WM_APP + 100)
-
#define CURSOR_BLINK_TIME 500
+static BOOL ConsInitialized = FALSE;
static HWND NotifyWnd;
/* FUNCTIONS *****************************************************************/
static VOID FASTCALL
GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData)
{
- *Console = (PCSRSS_CONSOLE) GetWindowLongW(hWnd, GWL_USERDATA);
- *GuiData = (NULL == *Console ? NULL : (*Console)->GuiConsoleData);
+ *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA);
+ *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
}
static BOOL FASTCALL
HFONT OldFont;
TEXTMETRICW Metrics;
- GuiData = HeapAlloc(Win32CsrApiHeap, 0,
+ GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
sizeof(GUI_CONSOLE_DATA) +
(Console->Size.X + 1) * sizeof(WCHAR));
if (NULL == GuiData)
{
- DbgPrint("GuiConsoleNcCreate: HeapAlloc failed\n");
+ DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
return FALSE;
}
+
+ InitializeCriticalSection(&GuiData->Lock);
+
GuiData->LineBuffer = (PWCHAR)(GuiData + 1);
GuiData->Font = CreateFontW(12, 0, 0, TA_BASELINE, FW_NORMAL,
- FALSE, FALSE, FALSE, ANSI_CHARSET,
+ FALSE, FALSE, FALSE, OEM_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE,
+ NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE,
L"Bitstream Vera Sans Mono");
if (NULL == GuiData->Font)
{
- DbgPrint("GuiConsoleNcCreate: CreateFont failed\n");
+ DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
+ DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
Dc = GetDC(hWnd);
if (NULL == Dc)
{
- DbgPrint("GuiConsoleNcCreate: GetDC failed\n");
+ DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
+ DeleteObject(GuiData->Font);
+ DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
OldFont = SelectObject(Dc, GuiData->Font);
if (NULL == OldFont)
{
- DbgPrint("GuiConsoleNcCreate: SelectObject failed\n");
+ DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
ReleaseDC(hWnd, Dc);
+ DeleteObject(GuiData->Font);
+ DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
if (! GetTextMetricsW(Dc, &Metrics))
{
- DbgPrint("GuiConsoleNcCreate: GetTextMetrics failed\n");
+ DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
SelectObject(Dc, OldFont);
ReleaseDC(hWnd, Dc);
+ DeleteObject(GuiData->Font);
+ DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
GuiData->CharWidth = Metrics.tmMaxCharWidth;
GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
SelectObject(Dc, OldFont);
+
ReleaseDC(hWnd, Dc);
GuiData->CursorBlinkOn = TRUE;
GuiData->ForceCursorOff = FALSE;
- Console->GuiConsoleData = GuiData;
- SetWindowLongW(hWnd, GWL_USERDATA, (LONG) Console);
+ GuiData->Selection.left = -1;
+
+ Console->PrivateData = GuiData;
+ SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console);
GetWindowRect(hWnd, &Rect);
Rect.right = Rect.left + Console->Size.X * GuiData->CharWidth +
}
}
+
static VOID FASTCALL
-GuiConsoleHandlePaint(HWND hWnd)
+GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData)
{
- PAINTSTRUCT Ps;
- HDC Dc;
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- PCSRSS_SCREEN_BUFFER Buff;
- unsigned TopLine, BottomLine, LeftChar, RightChar;
- unsigned Line, Char, Start;
- HFONT OldFont;
- PCHAR From;
- PWCHAR To;
- BYTE LastAttribute, Attribute;
- ULONG CursorX, CursorY, CursorHeight;
- HBRUSH CursorBrush, OldBrush;
+ RECT oldRect = GuiData->Selection;
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- if (NULL != Console && NULL != GuiData && NULL != Console->ActiveBuffer)
+ if(rc != NULL)
+ {
+ RECT changeRect = *rc;
+
+ GuiData->Selection = *rc;
+
+ changeRect.left *= GuiData->CharWidth;
+ changeRect.top *= GuiData->CharHeight;
+ changeRect.right *= GuiData->CharWidth;
+ changeRect.bottom *= GuiData->CharHeight;
+
+ if(rc->left != oldRect.left ||
+ rc->top != oldRect.top ||
+ rc->right != oldRect.right ||
+ rc->bottom != oldRect.bottom)
{
- Buff = Console->ActiveBuffer;
- EnterCriticalSection(&(Buff->Lock));
+ if(oldRect.left != -1)
+ {
+ HRGN rgn1, rgn2;
- Dc = BeginPaint(hWnd, &Ps);
- if (Ps.rcPaint.right <= Ps.rcPaint.left || Ps.rcPaint.bottom <= Ps.rcPaint.top)
- {
- EndPaint(hWnd, &Ps);
- LeaveCriticalSection(&(Buff->Lock));
- return;
- }
- OldFont = SelectObject(Dc, GuiData->Font);
-
- TopLine = Ps.rcPaint.top / GuiData->CharHeight;
- BottomLine = (Ps.rcPaint.bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1;
- LeftChar = Ps.rcPaint.left / GuiData->CharWidth;
- RightChar = (Ps.rcPaint.right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1;
- LastAttribute = Buff->Buffer[(TopLine * Buff->MaxX + LeftChar) * 2 + 1];
- GuiConsoleSetTextColors(Dc, LastAttribute);
- for (Line = TopLine; Line <= BottomLine; Line++)
+ oldRect.left *= GuiData->CharWidth;
+ oldRect.top *= GuiData->CharHeight;
+ oldRect.right *= GuiData->CharWidth;
+ oldRect.bottom *= GuiData->CharHeight;
+
+ /* calculate the region that needs to be updated */
+ if((rgn1 = CreateRectRgnIndirect(&oldRect)))
{
- if (Line + Buff->ShowY < Buff->MaxY)
+ if((rgn2 = CreateRectRgnIndirect(&changeRect)))
+ {
+ if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
{
- From = Buff->Buffer + ((Line + Buff->ShowY) * Buff->MaxX + LeftChar) * 2;
+ InvalidateRgn(hWnd, rgn1, FALSE);
}
- else
+
+ DeleteObject(rgn2);
+ }
+ DeleteObject(rgn1);
+ }
+ }
+ else
+ {
+ InvalidateRect(hWnd, &changeRect, FALSE);
+ }
+ }
+ }
+ else if(oldRect.left != -1)
+ {
+ /* clear the selection */
+ GuiData->Selection.left = -1;
+ oldRect.left *= GuiData->CharWidth;
+ oldRect.top *= GuiData->CharHeight;
+ oldRect.right *= GuiData->CharWidth;
+ oldRect.bottom *= GuiData->CharHeight;
+ InvalidateRect(hWnd, &oldRect, FALSE);
+ }
+}
+
+
+static VOID FASTCALL
+GuiConsolePaint(PCSRSS_CONSOLE Console,
+ PGUI_CONSOLE_DATA GuiData,
+ HDC hDC,
+ PRECT rc)
+{
+ PCSRSS_SCREEN_BUFFER Buff;
+ ULONG TopLine, BottomLine, LeftChar, RightChar;
+ ULONG Line, Char, Start;
+ PBYTE From;
+ PWCHAR To;
+ BYTE LastAttribute, Attribute;
+ ULONG CursorX, CursorY, CursorHeight;
+ HBRUSH CursorBrush, OldBrush;
+ HFONT OldFont;
+
+ Buff = Console->ActiveBuffer;
+
+ TopLine = rc->top / GuiData->CharHeight;
+ BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1;
+ LeftChar = rc->left / GuiData->CharWidth;
+ RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1;
+ LastAttribute = Buff->Buffer[(TopLine * Buff->MaxX + LeftChar) * 2 + 1];
+
+ GuiConsoleSetTextColors(hDC,
+ LastAttribute);
+
+ EnterCriticalSection(&Buff->Header.Lock);
+
+ OldFont = SelectObject(hDC,
+ GuiData->Font);
+
+ for (Line = TopLine; Line <= BottomLine; Line++)
+ {
+ if (Line + Buff->ShowY < Buff->MaxY)
+ {
+ From = Buff->Buffer + ((Line + Buff->ShowY) * Buff->MaxX + LeftChar) * 2;
+ }
+ else
+ {
+ From = Buff->Buffer +
+ ((Line - (Buff->MaxY - Buff->ShowY)) * Buff->MaxX + LeftChar) * 2;
+ }
+ Start = LeftChar;
+ To = GuiData->LineBuffer;
+
+ for (Char = LeftChar; Char <= RightChar; Char++)
+ {
+ if (*(From + 1) != LastAttribute)
{
- From = Buff->Buffer +
- ((Line - (Buff->MaxY - Buff->ShowY)) * Buff->MaxX + LeftChar) * 2;
+ TextOutW(hDC,
+ Start * GuiData->CharWidth,
+ Line * GuiData->CharHeight,
+ GuiData->LineBuffer,
+ Char - Start);
+ Start = Char;
+ To = GuiData->LineBuffer;
+ Attribute = *(From + 1);
+ if (Attribute != LastAttribute)
+ {
+ GuiConsoleSetTextColors(hDC,
+ Attribute);
+ LastAttribute = Attribute;
+ }
}
- Attribute = *(From + 1);
- Start = LeftChar;
- To = GuiData->LineBuffer;
- for (Char = LeftChar; Char <= RightChar; Char++)
+
+ MultiByteToWideChar(Console->OutputCodePage,
+ 0,
+ (PCHAR)From,
+ 1,
+ To,
+ 1);
+ To++;
+ From += 2;
+ }
+
+ TextOutW(hDC,
+ Start * GuiData->CharWidth,
+ Line * GuiData->CharHeight,
+ GuiData->LineBuffer,
+ RightChar - Start + 1);
+ }
+
+ if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn &&
+ !GuiData->ForceCursorOff)
+ {
+ GuiConsoleGetLogicalCursorPos(Buff,
+ &CursorX,
+ &CursorY);
+ if (LeftChar <= CursorX && CursorX <= RightChar &&
+ TopLine <= CursorY && CursorY <= BottomLine)
+ {
+ CursorHeight = (GuiData->CharHeight * Buff->CursorInfo.dwSize) / 100;
+ if (CursorHeight < 1)
{
- if (*(From + 1) != Attribute)
- {
- TextOutW(Dc, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
- GuiData->LineBuffer, Char - Start);
- Start = Char;
- Attribute = *(From + 1);
- if (Attribute != LastAttribute)
- {
- GuiConsoleSetTextColors(Dc, LastAttribute);
- }
- }
- *((PBYTE) To) = *From;
- *(((PBYTE) To) + 1) = '\0';
- To++;
- From += 2;
+ CursorHeight = 1;
}
- TextOutW(Dc, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
- GuiData->LineBuffer, RightChar - Start + 1);
+ From = Buff->Buffer + (Buff->CurrentY * Buff->MaxX + Buff->CurrentX) * 2 + 1;
+ CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From));
+ OldBrush = SelectObject(hDC,
+ CursorBrush);
+ PatBlt(hDC,
+ CursorX * GuiData->CharWidth,
+ CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
+ GuiData->CharWidth,
+ CursorHeight,
+ PATCOPY);
+ SelectObject(hDC,
+ OldBrush);
+ DeleteObject(CursorBrush);
}
+ }
- SelectObject(Dc, OldFont);
+ LeaveCriticalSection(&Buff->Header.Lock);
- if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn
- &&! GuiData->ForceCursorOff)
+ SelectObject(hDC,
+ OldFont);
+}
+
+static VOID FASTCALL
+GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
+{
+ HDC hDC;
+ PAINTSTRUCT ps;
+ PCSRSS_CONSOLE Console;
+ PGUI_CONSOLE_DATA GuiData;
+
+ hDC = BeginPaint(hWnd, &ps);
+ if (hDC != NULL &&
+ ps.rcPaint.left < ps.rcPaint.right &&
+ ps.rcPaint.top < ps.rcPaint.bottom)
+ {
+ GuiConsoleGetDataPointers(hWnd,
+ &Console,
+ &GuiData);
+ if (Console != NULL && GuiData != NULL &&
+ Console->ActiveBuffer != NULL)
{
- GuiConsoleGetLogicalCursorPos(Buff, &CursorX, &CursorY);
- if (LeftChar <= CursorX && CursorX <= RightChar &&
- TopLine <= CursorY && CursorY <= BottomLine)
+ EnterCriticalSection(&GuiData->Lock);
+
+ GuiConsolePaint(Console,
+ GuiData,
+ hDC,
+ &ps.rcPaint);
+
+ if (GuiData->Selection.left != -1)
{
- CursorHeight = (GuiData->CharHeight * Buff->CursorInfo.dwSize) / 100;
- if (CursorHeight < 1)
+ RECT rc = GuiData->Selection;
+
+ rc.left *= GuiData->CharWidth;
+ rc.top *= GuiData->CharHeight;
+ rc.right *= GuiData->CharWidth;
+ rc.bottom *= GuiData->CharHeight;
+
+ /* invert the selection */
+ if (IntersectRect(&rc,
+ &ps.rcPaint,
+ &rc))
{
- CursorHeight = 1;
+ PatBlt(hDC,
+ rc.left,
+ rc.top,
+ rc.right - rc.left,
+ rc.bottom - rc.top,
+ DSTINVERT);
}
- From = Buff->Buffer + (Buff->CurrentY * Buff->MaxX + Buff->CurrentX) * 2 + 1;
- CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From));
- OldBrush = SelectObject(Dc, CursorBrush);
- PatBlt(Dc, CursorX * GuiData->CharWidth,
- CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
- GuiData->CharWidth, CursorHeight, PATCOPY);
- SelectObject(Dc, OldBrush);
- DeleteObject(CursorBrush);
}
+
+ LeaveCriticalSection(&GuiData->Lock);
}
- EndPaint(hWnd, &Ps);
- LeaveCriticalSection(&(Buff->Lock));
- }
- else
- {
- Dc = BeginPaint(hWnd, &Ps);
- EndPaint(hWnd, &Ps);
+ EndPaint(hWnd, &ps);
}
}
Message.wParam = wParam;
Message.lParam = lParam;
- CsrProcessKey(&Message, Console);
+ if(msg == WM_CHAR || msg == WM_SYSKEYDOWN)
+ {
+ /* clear the selection */
+ GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
+ }
+
+ ConioProcessKey(&Message, Console, FALSE);
}
static VOID FASTCALL
-GuiConsoleHandleCopyRegion(HWND hWnd, PRECT Source, PRECT Dest)
+GuiIntDrawRegion(PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region)
{
- HDC Dc;
- int XDest, YDest, Width, Height, XSrc, YSrc;
- PCSRSS_CONSOLE Console;
- PGUI_CONSOLE_DATA GuiData;
- RECT CursorRect, UpdateRect;
- DWORD CursorX, CursorY;
- PCSRSS_SCREEN_BUFFER Buff;
+ RECT RegionRect;
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- Buff = Console->ActiveBuffer;
+ RegionRect.left = Region->left * GuiData->CharWidth;
+ RegionRect.top = Region->top * GuiData->CharHeight;
+ RegionRect.right = (Region->right + 1) * GuiData->CharWidth;
+ RegionRect.bottom = (Region->bottom + 1) * GuiData->CharHeight;
- /* Check if the cursor is in the source rectangle and if it is,
- * make sure it's invisible */
- GuiConsoleGetLogicalCursorPos(Buff, &CursorX, &CursorY);
- if (Source->left <= CursorX && CursorX <= Source->right &&
- Source->top <= CursorY && CursorY <= Source->bottom)
- {
- GuiData->ForceCursorOff = TRUE;
+ InvalidateRect(Wnd, &RegionRect, FALSE);
+}
- CursorRect.left = CursorX * GuiData->CharWidth;
- CursorRect.top = CursorY * GuiData->CharHeight;
- CursorRect.right = (CursorX + 1) * GuiData->CharWidth;
- CursorRect.bottom = (CursorY + 1) * GuiData->CharHeight;
+static VOID STDCALL
+GuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region)
+{
+ PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
- InvalidateRect(hWnd, &CursorRect, FALSE);
+ if (NULL != Console->hWindow && NULL != GuiData)
+ {
+ GuiIntDrawRegion(GuiData, Console->hWindow, Region);
}
+}
+
+static VOID FASTCALL
+GuiInvalidateCell(PGUI_CONSOLE_DATA GuiData, HWND Wnd, UINT x, UINT y)
+{
+ RECT CellRect;
+ CellRect.left = x;
+ CellRect.top = y;
+ CellRect.right = x;
+ CellRect.bottom = y;
- /* This is a bit tricky. We want to copy a source rectangle to
- * a destination rectangle, but there is no guarantee that the
- * contents of the source rectangle is valid. First let's try
- * to make it as valid as possible by painting all outstanding
- * updates. To do that we have to release the lock, otherwise
- * the paint code can't acquire it */
+ GuiIntDrawRegion(GuiData, Wnd, &CellRect);
+}
- UpdateWindow(hWnd);
+static VOID STDCALL
+GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY,
+ UINT ScrolledLines, CHAR *Buffer, UINT Length)
+{
+ PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
+ PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
+ LONG CursorEndX, CursorEndY;
+ RECT ScrollRect;
- Dc = GetDC(hWnd);
- if (NULL == Dc)
+ if (NULL == Console->hWindow || NULL == GuiData)
{
return;
}
- XSrc = Source->left * GuiData->CharWidth;
- YSrc = Source->top * GuiData->CharHeight;
- XDest = Dest->left * GuiData->CharWidth;
- YDest = Dest->top * GuiData->CharHeight;
- Width = (Dest->right - Dest->left + 1) * GuiData->CharWidth;
- Height = (Dest->bottom - Dest->top + 1) * GuiData->CharHeight;
-
- BitBlt(Dc, XDest, YDest, Width, Height, Dc, XSrc, YSrc, SRCCOPY);
+ if (0 != ScrolledLines)
+ {
+ ScrollRect.left = 0;
+ ScrollRect.top = 0;
+ ScrollRect.right = Console->Size.X * GuiData->CharWidth;
+ ScrollRect.bottom = Region->top * GuiData->CharHeight;
+
+ if (GuiData->Selection.left != -1)
+ {
+ /* scroll the selection */
+ if (GuiData->Selection.top > ScrolledLines)
+ {
+ GuiData->Selection.top -= ScrolledLines;
+ GuiData->Selection.bottom -= ScrolledLines;
+ }
+ else if (GuiData->Selection.bottom < ScrolledLines)
+ {
+ GuiData->Selection.left = -1;
+ }
+ else
+ {
+ GuiData->Selection.top = 0;
+ GuiData->Selection.bottom -= ScrolledLines;
+ }
+ }
+
+ ScrollWindowEx(Console->hWindow,
+ 0,
+ -(ScrolledLines * GuiData->CharHeight),
+ &ScrollRect,
+ NULL,
+ NULL,
+ NULL,
+ SW_INVALIDATE);
+ }
- ReleaseDC(hWnd, Dc);
+ GuiIntDrawRegion(GuiData, Console->hWindow, Region);
- /* Although we tried to make sure that the source rectangle was
- * up-to-date, this is not guaranteed. For example, the user could
- * have moved a window between the UpdateWindow() and the BitBlt()
- * above, invalidating part of the window. So, we're going to
- * check if the current update rect of the window overlaps with the
- * source rectangle. If it does, we invalidate the corresponding
- * part of the destination rectangle so it will eventually be
- * repainted. Note that this is probably doesn't happen all that
- * often and GetUpdateRect() below will usually return FALSE,
- * indicating that the whole window is valid */
-
- if (GetUpdateRect(hWnd, &UpdateRect, FALSE))
+ if (CursorStartX < Region->left || Region->right < CursorStartX
+ || CursorStartY < Region->top || Region->bottom < CursorStartY)
{
- UpdateRect.left = max(UpdateRect.left, XSrc);
- UpdateRect.top = max(UpdateRect.top, YSrc);
- UpdateRect.right = min(UpdateRect.right, XSrc + Width);
- UpdateRect.bottom = min(UpdateRect.bottom, YSrc + Height);
- if (UpdateRect.left < UpdateRect.right && UpdateRect.top < UpdateRect.bottom)
- {
- UpdateRect.left += XDest - XSrc;
- UpdateRect.top += YDest - YSrc;
- UpdateRect.right += XDest - XSrc;
- UpdateRect.bottom += YDest - YSrc;
+ GuiInvalidateCell(GuiData, Console->hWindow, CursorStartX, CursorStartY);
+ }
- InvalidateRect(Console->hWindow, &UpdateRect, FALSE);
- }
+ ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
+ &CursorEndX, &CursorEndY);
+ if ((CursorEndX < Region->left || Region->right < CursorEndX
+ || CursorEndY < Region->top || Region->bottom < CursorEndY)
+ && (CursorEndX != CursorStartX || CursorEndY != CursorStartY))
+ {
+ GuiInvalidateCell(GuiData, Console->hWindow, CursorEndX, CursorEndY);
}
+}
- /* Show cursor again if we made it invisible */
- if (GuiData->ForceCursorOff)
+static BOOL STDCALL
+GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
+{
+ RECT UpdateRect;
+
+ if (Console->ActiveBuffer == Buff)
{
- GuiData->ForceCursorOff = FALSE;
+ ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
+ &UpdateRect.left, &UpdateRect.top);
+ UpdateRect.right = UpdateRect.left;
+ UpdateRect.bottom = UpdateRect.top;
+ ConioDrawRegion(Console, &UpdateRect);
+ }
+
+ return TRUE;
+}
- InvalidateRect(hWnd, &CursorRect, FALSE);
+static BOOL STDCALL
+GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
+{
+ RECT UpdateRect;
+
+ if (Console->ActiveBuffer == Buff)
+ {
+ /* Redraw char at old position (removes cursor) */
+ UpdateRect.left = OldCursorX;
+ UpdateRect.top = OldCursorY;
+ UpdateRect.right = OldCursorX;
+ UpdateRect.bottom = OldCursorY;
+ ConioDrawRegion(Console, &UpdateRect);
+ /* Redraw char at new position (shows cursor) */
+ ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
+ &(UpdateRect.left), &(UpdateRect.top));
+ UpdateRect.right = UpdateRect.left;
+ UpdateRect.bottom = UpdateRect.top;
+ ConioDrawRegion(Console, &UpdateRect);
}
+
+ return TRUE;
}
static VOID FASTCALL
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
- SMALL_RECT CursorRect;
+ RECT CursorRect;
ULONG CursorX, CursorY;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn;
GuiConsoleGetLogicalCursorPos(Console->ActiveBuffer, &CursorX, &CursorY);
- CursorRect.Left = CursorX;
- CursorRect.Top = CursorY;
- CursorRect.Right = CursorX;
- CursorRect.Bottom = CursorY;
- GuiConsoleDrawRegion(Console, CursorRect);
+ CursorRect.left = CursorX;
+ CursorRect.top = CursorY;
+ CursorRect.right = CursorX;
+ CursorRect.bottom = CursorY;
+ GuiDrawRegion(Console, &CursorRect);
}
static VOID FASTCALL
GuiConsoleHandleClose(HWND hWnd)
{
- /* FIXME for now, just ignore close requests */
+ PCSRSS_CONSOLE Console;
+ PGUI_CONSOLE_DATA GuiData;
+ PLIST_ENTRY current_entry;
+ PCSRSS_PROCESS_DATA current;
+
+ GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+
+ EnterCriticalSection(&Console->Header.Lock);
+
+ current_entry = Console->ProcessList.Flink;
+ while (current_entry != &Console->ProcessList)
+ {
+ current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
+ current_entry = current_entry->Flink;
+
+ ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current);
+ }
+
+ LeaveCriticalSection(&Console->Header.Lock);
}
static VOID FASTCALL
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
KillTimer(hWnd, 1);
- Console->GuiConsoleData = NULL;
+ Console->PrivateData = NULL;
+ DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
}
+static VOID FASTCALL
+GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam)
+{
+ PCSRSS_CONSOLE Console;
+ PGUI_CONSOLE_DATA GuiData;
+ POINTS pt;
+ RECT rc;
+
+ GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+ if (Console == NULL || GuiData == NULL) return;
+
+ pt = MAKEPOINTS(lParam);
+
+ rc.left = pt.x / GuiData->CharWidth;
+ rc.top = pt.y / GuiData->CharHeight;
+ rc.right = rc.left + 1;
+ rc.bottom = rc.top + 1;
+
+ GuiData->SelectionStart.x = rc.left;
+ GuiData->SelectionStart.y = rc.top;
+
+ SetCapture(hWnd);
+
+ GuiData->MouseDown = TRUE;
+
+ GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
+}
+
+static VOID FASTCALL
+GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam)
+{
+ PCSRSS_CONSOLE Console;
+ PGUI_CONSOLE_DATA GuiData;
+ RECT rc;
+ POINTS pt;
+
+ GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+ if (Console == NULL || GuiData == NULL) return;
+ if (GuiData->Selection.left == -1 || !GuiData->MouseDown) return;
+
+ pt = MAKEPOINTS(lParam);
+
+ rc.left = GuiData->SelectionStart.x;
+ rc.top = GuiData->SelectionStart.y;
+ rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
+ rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
+
+ /* exchange left/top with right/bottom if required */
+ if(rc.left >= rc.right)
+ {
+ LONG tmp;
+ tmp = rc.left;
+ rc.left = max(rc.right - 1, 0);
+ rc.right = tmp + 1;
+ }
+ if(rc.top >= rc.bottom)
+ {
+ LONG tmp;
+ tmp = rc.top;
+ rc.top = max(rc.bottom - 1, 0);
+ rc.bottom = tmp + 1;
+ }
+
+ GuiData->MouseDown = FALSE;
+
+ GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
+
+ ReleaseCapture();
+}
+
+static VOID FASTCALL
+GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ PCSRSS_CONSOLE Console;
+ PGUI_CONSOLE_DATA GuiData;
+ RECT rc;
+ POINTS pt;
+
+ if (!(wParam & MK_LBUTTON)) return;
+
+ GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+ if (Console == NULL || GuiData == NULL || !GuiData->MouseDown) return;
+
+ pt = MAKEPOINTS(lParam);
+
+ rc.left = GuiData->SelectionStart.x;
+ rc.top = GuiData->SelectionStart.y;
+ rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
+ if (Console->Size.X < rc.right)
+ {
+ rc.right = Console->Size.X;
+ }
+ rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
+ if (Console->Size.Y < rc.bottom)
+ {
+ rc.bottom = Console->Size.Y;
+ }
+
+ /* exchange left/top with right/bottom if required */
+ if(rc.left >= rc.right)
+ {
+ LONG tmp;
+ tmp = rc.left;
+ rc.left = max(rc.right - 1, 0);
+ rc.right = tmp + 1;
+ }
+ if(rc.top >= rc.bottom)
+ {
+ LONG tmp;
+ tmp = rc.top;
+ rc.top = max(rc.bottom - 1, 0);
+ rc.bottom = tmp + 1;
+ }
+
+ GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
+}
+
+static VOID FASTCALL
+GuiConsoleRightMouseDown(HWND hWnd)
+{
+ PCSRSS_CONSOLE Console;
+ PGUI_CONSOLE_DATA GuiData;
+
+ GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+ if (Console == NULL || GuiData == NULL) return;
+
+ if (GuiData->Selection.left == -1)
+ {
+ /* FIXME - paste text from clipboard */
+ }
+ else
+ {
+ /* FIXME - copy selection to clipboard */
+
+ GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
+ }
+
+}
+
static LRESULT CALLBACK
GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
- LRESULT Result;
+ LRESULT Result = 0;
switch(msg)
{
Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam);
break;
case WM_PAINT:
- GuiConsoleHandlePaint(hWnd);
- Result = 0;
+ GuiConsoleHandlePaint(hWnd, (HDC)wParam);
break;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
case WM_CHAR:
GuiConsoleHandleKey(hWnd, msg, wParam, lParam);
- Result = 0;
break;
case WM_TIMER:
GuiConsoleHandleTimer(hWnd);
- Result = 0;
- break;
- case PM_COPY_REGION:
- GuiConsoleHandleCopyRegion(hWnd, (PRECT) wParam, (PRECT) lParam);
break;
case WM_CLOSE:
GuiConsoleHandleClose(hWnd);
- Result = 0;
break;
case WM_NCDESTROY:
GuiConsoleHandleNcDestroy(hWnd);
- Result = 0;
+ break;
+ case WM_LBUTTONDOWN:
+ GuiConsoleLeftMouseDown(hWnd, lParam);
+ break;
+ case WM_LBUTTONUP:
+ GuiConsoleLeftMouseUp(hWnd, lParam);
+ break;
+ case WM_RBUTTONDOWN:
+ GuiConsoleRightMouseDown(hWnd);
+ break;
+ case WM_MOUSEMOVE:
+ GuiConsoleMouseMove(hWnd, wParam, lParam);
break;
default:
Result = DefWindowProcW(hWnd, msg, wParam, lParam);
{
HWND NewWindow;
LONG WindowCount;
+ MSG Msg;
+ PWCHAR Buffer, Title;
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam;
switch(msg)
SetWindowLongW(hWnd, GWL_USERDATA, 0);
return 0;
case PM_CREATE_CONSOLE:
- NewWindow = CreateWindowW(L"Win32CsrConsole",
- Console->Title.Buffer,
+ Buffer = HeapAlloc(Win32CsrApiHeap, 0,
+ Console->Title.Length + sizeof(WCHAR));
+ if (NULL != Buffer)
+ {
+ memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
+ Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
+ Title = Buffer;
+ }
+ else
+ {
+ Title = L"";
+ }
+ NewWindow = CreateWindowW(L"ConsoleWindowClass",
+ Title,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
(HINSTANCE) GetModuleHandleW(NULL),
(PVOID) Console);
+ if (NULL != Buffer)
+ {
+ HeapFree(Win32CsrApiHeap, 0, Buffer);
+ }
+ Console->hWindow = NewWindow;
if (NULL != NewWindow)
{
SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
}
return (LRESULT) NewWindow;
case PM_DESTROY_CONSOLE:
+ /* Window creation is done using a PostMessage(), so it's possible that the
+ * window that we want to destroy doesn't exist yet. So first empty the message
+ * queue */
+ while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&Msg);
+ DispatchMessageW(&Msg);
+ }
DestroyWindow(Console->hWindow);
Console->hWindow = NULL;
WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
{
NotifyWnd = NULL;
DestroyWindow(hWnd);
- PrivateCsrssGraphicsDone();
+ PrivateCsrssManualGuiCheck(-1);
+ PostQuitMessage(0);
}
return 0;
default:
static DWORD STDCALL
GuiConsoleGuiThread(PVOID Data)
{
- WNDCLASSW wc;
MSG msg;
PHANDLE GraphicsStartupEvent = (PHANDLE) Data;
- wc.lpszClassName = L"Win32CsrCreateNotify";
- wc.lpfnWndProc = GuiConsoleNotifyWndProc;
- wc.style = 0;
- wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
- wc.hIcon = NULL;
- wc.hCursor = NULL;
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- if (RegisterClassW(&wc) == 0)
- {
- NtSetEvent(*GraphicsStartupEvent, 0);
- return 1;
- }
-
- wc.lpszClassName = L"Win32CsrConsole";
- wc.lpfnWndProc = GuiConsoleWndProc;
- wc.style = 0;
- wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
- wc.hIcon = LoadIconW(NULL, (LPCWSTR) IDI_APPLICATION);
- wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW);
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- if (RegisterClassW(&wc) == 0)
- {
- NtSetEvent(*GraphicsStartupEvent, 0);
- return 1;
- }
-
NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify",
L"",
WS_OVERLAPPEDWINDOW,
NULL);
if (NULL == NotifyWnd)
{
- NtSetEvent(*GraphicsStartupEvent, 0);
+ PrivateCsrssManualGuiCheck(-1);
+ SetEvent(*GraphicsStartupEvent);
return 1;
}
- NtSetEvent(*GraphicsStartupEvent, 0);
+ SetEvent(*GraphicsStartupEvent);
while(GetMessageW(&msg, NULL, 0, 0))
{
return 1;
}
-VOID FASTCALL
-GuiConsoleInitConsoleSupport(VOID)
+static BOOL FASTCALL
+GuiInit(VOID)
{
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE GraphicsStartupEvent;
- HWINSTA WindowStation;
- HDESK Desktop;
- HANDLE ThreadHandle;
+ WNDCLASSEXW wc;
- WindowStation = OpenWindowStationW(L"WinSta0", FALSE, GENERIC_ALL);
- if (NULL == WindowStation)
- {
- DbgPrint("Win32Csr: failed to open window station\n");
- return;
- }
- if (! SetProcessWindowStation(WindowStation))
- {
- DbgPrint("Win32Csr: failed to set process window station\n");
- return;
- }
- Desktop = OpenDesktopW(L"Default", 0, FALSE, GENERIC_ALL);
- if (NULL == Desktop)
+ if (NULL == NotifyWnd)
{
- DbgPrint("Win32Csr: failed to open desktop\n");
- return;
+ PrivateCsrssManualGuiCheck(+1);
}
- Status = NtSetInformationProcess(NtCurrentProcess(),
- ProcessDesktop,
- &Desktop,
- sizeof(Desktop));
- if (!NT_SUCCESS(Status))
+
+ wc.cbSize = sizeof(WNDCLASSEXW);
+ wc.lpszClassName = L"Win32CsrCreateNotify";
+ wc.lpfnWndProc = GuiConsoleNotifyWndProc;
+ wc.style = 0;
+ wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hIconSm = NULL;
+ if (RegisterClassExW(&wc) == 0)
{
- DbgPrint("Win32Csr: cannot set default desktop.\n");
- return;
+ DPRINT1("Failed to register notify wndproc\n");
+ return FALSE;
}
- if (! SetThreadDesktop(Desktop))
+
+ wc.cbSize = sizeof(WNDCLASSEXW);
+ wc.lpszClassName = L"ConsoleWindowClass";
+ wc.lpfnWndProc = GuiConsoleWndProc;
+ wc.style = 0;
+ wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
+ wc.hIcon = LoadIconW(Win32CsrDllHandle, MAKEINTRESOURCEW(1));
+ wc.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_ARROW));
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hIconSm = LoadImageW(Win32CsrDllHandle, MAKEINTRESOURCEW(1), IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
+ LR_SHARED);
+ if (RegisterClassExW(&wc) == 0)
{
- DbgPrint("Win32Csr: failed to set thread desktop\n");
- return;
+ DPRINT1("Failed to register console wndproc\n");
+ return FALSE;
}
- InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_INHERIT, NULL, NULL);
+ return TRUE;
+}
+
+static VOID STDCALL
+GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
+{
+ Buffer->DefaultAttrib = 0x0f;
+}
+
+static BOOL STDCALL
+GuiChangeTitle(PCSRSS_CONSOLE Console)
+{
+ PWCHAR Buffer, Title;
- Status = NtCreateEvent(&GraphicsStartupEvent, STANDARD_RIGHTS_ALL, &ObjectAttributes, FALSE, FALSE);
- if( !NT_SUCCESS(Status))
+ Buffer = HeapAlloc(Win32CsrApiHeap, 0,
+ Console->Title.Length + sizeof(WCHAR));
+ if (NULL != Buffer)
{
- return;
+ memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
+ Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
+ Title = Buffer;
}
-
- ThreadHandle = CreateThread(NULL,
- 0,
- GuiConsoleGuiThread,
- (PVOID) &GraphicsStartupEvent,
- 0,
- NULL);
- if (NULL == ThreadHandle)
+ else
{
- NtClose(GraphicsStartupEvent);
- DbgPrint("Win32Csr: Failed to create graphics console thread. Expect problems\n");
- return;
+ Title = L"";
}
- CloseHandle(ThreadHandle);
-
- NtWaitForSingleObject(GraphicsStartupEvent, FALSE, NULL);
- NtClose(GraphicsStartupEvent);
-
- if (NULL == NotifyWnd)
+ SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title);
+ if (NULL != Buffer)
{
- DbgPrint("Win32Csr: Failed to create notification window.\n");
- return;
+ HeapFree(Win32CsrApiHeap, 0, Buffer);
}
+
+ return TRUE;
}
-BOOL STDCALL
-GuiConsoleInitConsole(PCSRSS_CONSOLE Console)
+static BOOL STDCALL
+GuiChangeIcon(PCSRSS_CONSOLE Console)
{
- Console->Size.X = 80;
- Console->Size.Y = 25;
- Console->hWindow = (HWND) SendMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
+ SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)Console->hWindowIcon);
+ SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)Console->hWindowIcon);
- return NULL != Console->hWindow;
+ return TRUE;
}
-VOID STDCALL
-GuiConsoleDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT Region)
+static VOID STDCALL
+GuiCleanupConsole(PCSRSS_CONSOLE Console)
{
- PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->GuiConsoleData;
- RECT RegionRect;
+ SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console);
+}
- if (NULL == Console->hWindow || NULL == GuiData)
+static CSRSS_CONSOLE_VTBL GuiVtbl =
+{
+ GuiInitScreenBuffer,
+ GuiWriteStream,
+ GuiDrawRegion,
+ GuiSetCursorInfo,
+ GuiSetScreenInfo,
+ GuiChangeTitle,
+ GuiCleanupConsole,
+ GuiChangeIcon
+};
+
+NTSTATUS FASTCALL
+GuiInitConsole(PCSRSS_CONSOLE Console)
+{
+ HANDLE GraphicsStartupEvent;
+ HANDLE ThreadHandle;
+
+ if (! ConsInitialized)
{
- return;
+ ConsInitialized = TRUE;
+ if (! GuiInit())
+ {
+ ConsInitialized = FALSE;
+ return STATUS_UNSUCCESSFUL;
+ }
}
- RegionRect.left = Region.Left * GuiData->CharWidth;
- RegionRect.top = Region.Top * GuiData->CharHeight;
- RegionRect.right = (Region.Right + 1) * GuiData->CharWidth;
- RegionRect.bottom = (Region.Bottom + 1) * GuiData->CharHeight;
+ Console->Vtbl = &GuiVtbl;
+ Console->Size.X = 80;
+ Console->Size.Y = 25;
+ if (NULL == NotifyWnd)
+ {
+ GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ if (NULL == GraphicsStartupEvent)
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
- InvalidateRect(Console->hWindow, &RegionRect, FALSE);
-}
+ ThreadHandle = CreateThread(NULL,
+ 0,
+ GuiConsoleGuiThread,
+ (PVOID) &GraphicsStartupEvent,
+ 0,
+ NULL);
+ if (NULL == ThreadHandle)
+ {
+ NtClose(GraphicsStartupEvent);
+ DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+ SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
+ CloseHandle(ThreadHandle);
-VOID STDCALL
-GuiConsoleCopyRegion(PCSRSS_CONSOLE Console,
- RECT *Source,
- RECT *Dest)
-{
- LeaveCriticalSection(&(Console->ActiveBuffer->Lock));
- SendMessageW(Console->hWindow, PM_COPY_REGION, (WPARAM) Source, (LPARAM) Dest);
- EnterCriticalSection(&(Console->ActiveBuffer->Lock));
-}
+ WaitForSingleObject(GraphicsStartupEvent, INFINITE);
+ CloseHandle(GraphicsStartupEvent);
-VOID STDCALL
-GuiConsoleChangeTitle(PCSRSS_CONSOLE Console)
-{
- SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Console->Title.Buffer);
-}
+ if (NULL == NotifyWnd)
+ {
+ DPRINT1("Win32Csr: Failed to create notification window.\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
-VOID STDCALL
-GuiConsoleDeleteConsole(PCSRSS_CONSOLE Console)
-{
- SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console);
+ PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
+
+ return STATUS_SUCCESS;
}
/* EOF */