-/* $Id: guiconsole.c,v 1.9 2004/02/03 17:53:54 navaraf Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
/* INCLUDES ******************************************************************/
-#include <windows.h>
-#include "conio.h"
-#include "guiconsole.h"
-#include "win32csr.h"
+#include "w32csr.h"
#define NDEBUG
#include <debug.h>
PWCHAR LineBuffer;
BOOL CursorBlinkOn;
BOOL ForceCursorOff;
+ CRITICAL_SECTION Lock;
+ HDC MemoryDC;
+ HBITMAP MemoryBitmap;
+ 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 Initialized = FALSE;
+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);
+ *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA);
*GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
}
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)
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)
{
DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
+ DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
if (NULL == Dc)
{
DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
+ DeleteObject(GuiData->Font);
+ DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
{
DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
ReleaseDC(hWnd, Dc);
+ DeleteObject(GuiData->Font);
+ DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
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);
+
+ GuiData->MemoryDC = CreateCompatibleDC(Dc);
+ GuiData->MemoryBitmap = CreateCompatibleBitmap(Dc,
+ Console->Size.X * GuiData->CharWidth,
+ Console->Size.Y * GuiData->CharHeight);
+ /* NOTE: Don't delete the "first bitmap", it's done in DeleteDC. */
+ SelectObject(GuiData->MemoryDC, GuiData->MemoryBitmap);
+ /* NOTE: Don't delete stock font. */
+ SelectObject(GuiData->MemoryDC, GuiData->Font);
+
ReleaseDC(hWnd, Dc);
GuiData->CursorBlinkOn = TRUE;
GuiData->ForceCursorOff = FALSE;
+ GuiData->Selection.left = -1;
+
Console->PrivateData = GuiData;
- SetWindowLongW(hWnd, GWL_USERDATA, (LONG) Console);
+ 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)
+{
+ RECT oldRect = GuiData->Selection;
+
+ 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)
+ {
+ if(oldRect.left != -1)
+ {
+ HRGN rgn1, rgn2;
+
+ 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((rgn2 = CreateRectRgnIndirect(&changeRect)))
+ {
+ if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
+ {
+ InvalidateRgn(hWnd, rgn1, FALSE);
+ }
+
+ 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);
+ }
+}
+
+
+VOID FASTCALL
+GuiConsoleUpdateBitmap(HWND hWnd, RECT rc)
{
- 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;
+ HDC Dc;
+ ULONG TopLine, BottomLine, LeftChar, RightChar;
+ ULONG Line, Char, Start;
PBYTE From;
PWCHAR To;
BYTE LastAttribute, Attribute;
if (NULL != Console && NULL != GuiData && NULL != Console->ActiveBuffer)
{
Buff = Console->ActiveBuffer;
- EnterCriticalSection(&(Buff->Header.Lock));
-
- Dc = BeginPaint(hWnd, &Ps);
- if (Ps.rcPaint.right <= Ps.rcPaint.left || Ps.rcPaint.bottom <= Ps.rcPaint.top)
+ EnterCriticalSection(&Buff->Header.Lock);
+ Dc = GetDC(hWnd);
+ if (rc.right <= rc.left || rc.bottom <= rc.top)
{
- EndPaint(hWnd, &Ps);
- LeaveCriticalSection(&(Buff->Header.Lock));
+ ReleaseDC(hWnd, Dc);
+ LeaveCriticalSection(&Buff->Header.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;
+ EnterCriticalSection(&GuiData->Lock);
+
+ 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(Dc, LastAttribute);
+ GuiConsoleSetTextColors(GuiData->MemoryDC, LastAttribute);
+
for (Line = TopLine; Line <= BottomLine; Line++)
{
if (Line + Buff->ShowY < Buff->MaxY)
From = Buff->Buffer +
((Line - (Buff->MaxY - Buff->ShowY)) * Buff->MaxX + LeftChar) * 2;
}
- Attribute = *(From + 1);
Start = LeftChar;
To = GuiData->LineBuffer;
for (Char = LeftChar; Char <= RightChar; Char++)
{
- if (*(From + 1) != Attribute)
+ if (*(From + 1) != LastAttribute)
{
- TextOutW(Dc, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
+ TextOutW(GuiData->MemoryDC, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
GuiData->LineBuffer, Char - Start);
Start = Char;
To = GuiData->LineBuffer;
Attribute = *(From + 1);
if (Attribute != LastAttribute)
{
- GuiConsoleSetTextColors(Dc, Attribute);
+ GuiConsoleSetTextColors(GuiData->MemoryDC, Attribute);
LastAttribute = Attribute;
}
- }
- *((PBYTE) To) = *From;
- *(((PBYTE) To) + 1) = '\0';
+ }
+ MultiByteToWideChar(Console->OutputCodePage, 0, (PCHAR)From, 1, To, 1);
To++;
From += 2;
}
- TextOutW(Dc, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
+ TextOutW(GuiData->MemoryDC, Start * GuiData->CharWidth, Line * GuiData->CharHeight,
GuiData->LineBuffer, RightChar - Start + 1);
}
- SelectObject(Dc, OldFont);
-
if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn
&&! GuiData->ForceCursorOff)
{
}
From = Buff->Buffer + (Buff->CurrentY * Buff->MaxX + Buff->CurrentX) * 2 + 1;
CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From));
- OldBrush = SelectObject(Dc, CursorBrush);
- PatBlt(Dc, CursorX * GuiData->CharWidth,
+ OldBrush = SelectObject(GuiData->MemoryDC, CursorBrush);
+ PatBlt(GuiData->MemoryDC, CursorX * GuiData->CharWidth,
CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth, CursorHeight, PATCOPY);
- SelectObject(Dc, OldBrush);
+ SelectObject(GuiData->MemoryDC, OldBrush);
DeleteObject(CursorBrush);
}
}
- EndPaint(hWnd, &Ps);
- LeaveCriticalSection(&(Buff->Header.Lock));
+ LeaveCriticalSection(&GuiData->Lock);
+ ReleaseDC(hWnd, Dc);
+ LeaveCriticalSection(&Buff->Header.Lock);
+ InvalidateRect(hWnd, &rc, FALSE);
+ }
+}
+
+VOID FASTCALL
+GuiConsoleHandlePaint(HWND hWnd)
+{
+ PAINTSTRUCT Ps;
+ HDC Dc;
+ PCSRSS_CONSOLE Console;
+ PGUI_CONSOLE_DATA GuiData;
+
+ GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+ if (NULL != Console && NULL != GuiData)
+ {
+ EnterCriticalSection(&GuiData->Lock);
+ Dc = BeginPaint (hWnd, &Ps);
+ BitBlt(Dc, Ps.rcPaint.left, Ps.rcPaint.top,
+ Ps.rcPaint.right - Ps.rcPaint.left + 1,
+ Ps.rcPaint.bottom - Ps.rcPaint.top + 1, GuiData->MemoryDC,
+ Ps.rcPaint.left, Ps.rcPaint.top, SRCCOPY);
+
+ if (GuiData->Selection.left != -1)
+ {
+ RECT rc = GuiData->Selection;
+
+ rc.left *= GuiData->CharWidth;
+ rc.top *= GuiData->CharHeight;
+ rc.right *= GuiData->CharWidth;
+ rc.bottom *= GuiData->CharHeight;
+
+ if (IntersectRect(&rc, &Ps.rcPaint, &rc))
+ {
+ PatBlt(Dc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, DSTINVERT);
+ }
+ }
+
+ EndPaint (hWnd, &Ps);
+ LeaveCriticalSection(&GuiData->Lock);
}
else
{
- Dc = BeginPaint(hWnd, &Ps);
- EndPaint(hWnd, &Ps);
+ Dc = BeginPaint (hWnd, &Ps);
+ EndPaint (hWnd, &Ps);
}
}
Message.wParam = wParam;
Message.lParam = lParam;
- ConioProcessKey(&Message, Console, FALSE);
-}
-
-static VOID FASTCALL
-GuiConsoleHandleCopyRegion(HWND hWnd, PRECT Source, PRECT Dest)
-{
- RECT ClientRect, ScrollRect;
- PGUI_CONSOLE_DATA GuiData;
- PCSRSS_CONSOLE Console;
+ if(msg == WM_CHAR || msg == WM_SYSKEYDOWN)
+ {
+ /* clear the selection */
+ GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
+ }
- GetClientRect(hWnd, &ClientRect);
- GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- ScrollRect.left = min(Source->left, Dest->left) * GuiData->CharWidth;
- ScrollRect.top = min(Source->top, Dest->top) * GuiData->CharHeight;
- ScrollRect.right = max(Source->right, Dest->right) * GuiData->CharWidth;
- ScrollRect.bottom = max(Source->bottom, Dest->bottom) * GuiData->CharHeight;
- ScrollWindow(hWnd,
- (Dest->left - Source->left) * GuiData->CharWidth,
- (Dest->top - Source->top) * GuiData->CharHeight,
- &ScrollRect, &ClientRect);
+ ConioProcessKey(&Message, Console, FALSE);
}
static VOID FASTCALL
RegionRect.right = (Region->right + 1) * GuiData->CharWidth;
RegionRect.bottom = (Region->bottom + 1) * GuiData->CharHeight;
- InvalidateRect(Wnd, &RegionRect, FALSE);
+ GuiConsoleUpdateBitmap(Wnd, RegionRect);
}
static VOID STDCALL
}
static VOID STDCALL
-GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, UINT CursorStartX, UINT CursorStartY,
+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;
Dest.right = Console->Size.X - 1;
Dest.bottom = Region->top - 1;
- GuiConsoleCopyRegion(Console, &Source, &Dest);
+ GuiConsoleCopyRegion(Console->hWindow, &Source, &Dest);
}
GuiIntDrawRegion(GuiData, Console->hWindow, Region);
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->PrivateData = NULL;
+ DeleteDC(GuiData->MemoryDC);
+ 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);
+ 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;
+ }
+
+ 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)
{
break;
case WM_PAINT:
GuiConsoleHandlePaint(hWnd);
- Result = 0;
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)
{
}
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);
MSG msg;
PHANDLE GraphicsStartupEvent = (PHANDLE) Data;
- PrivateCsrssManualGuiCheck(+1);
-
NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify",
L"",
WS_OVERLAPPEDWINDOW,
static BOOL FASTCALL
GuiInit(VOID)
{
- HDESK Desktop;
- NTSTATUS Status;
WNDCLASSEXW wc;
- Desktop = OpenDesktopW(L"Default", 0, FALSE, GENERIC_ALL);
- if (NULL == Desktop)
- {
- DPRINT1("Failed to open desktop\n");
- return FALSE;
- }
- Status = NtSetInformationProcess(NtCurrentProcess(),
- ProcessDesktop,
- &Desktop,
- sizeof(Desktop));
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Cannot set default desktop.\n");
- return FALSE;
- }
- if (! SetThreadDesktop(Desktop))
+ if (NULL == NotifyWnd)
{
- DPRINT1("Failed to set thread desktop\n");
- return FALSE;
+ PrivateCsrssManualGuiCheck(+1);
}
wc.cbSize = sizeof(WNDCLASSEXW);
}
wc.cbSize = sizeof(WNDCLASSEXW);
- wc.lpszClassName = L"Win32CsrConsole";
+ wc.lpszClassName = L"ConsoleWindowClass";
wc.lpfnWndProc = GuiConsoleWndProc;
wc.style = 0;
wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
Buffer->DefaultAttrib = 0x0f;
}
-STATIC BOOL STDCALL
+static BOOL STDCALL
GuiChangeTitle(PCSRSS_CONSOLE Console)
{
- SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Console->Title.Buffer);
+ PWCHAR Buffer, Title;
+
+ 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"";
+ }
+ SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title);
+ if (NULL != Buffer)
+ {
+ HeapFree(Win32CsrApiHeap, 0, Buffer);
+ }
+
+ return TRUE;
+}
+
+static BOOL STDCALL
+GuiChangeIcon(PCSRSS_CONSOLE Console)
+{
+ SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)Console->hWindowIcon);
+ SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)Console->hWindowIcon);
return TRUE;
}
GuiSetCursorInfo,
GuiSetScreenInfo,
GuiChangeTitle,
- GuiCleanupConsole
+ GuiCleanupConsole,
+ GuiChangeIcon
};
NTSTATUS FASTCALL
HANDLE GraphicsStartupEvent;
HANDLE ThreadHandle;
- if (! Initialized)
+ if (! ConsInitialized)
{
- Initialized = TRUE;
+ ConsInitialized = TRUE;
if (! GuiInit())
{
- Initialized = FALSE;
+ ConsInitialized = FALSE;
return STATUS_UNSUCCESSFUL;
}
}
DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
return STATUS_UNSUCCESSFUL;
}
+ SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
CloseHandle(ThreadHandle);
WaitForSingleObject(GraphicsStartupEvent, INFINITE);
}
VOID STDCALL
-GuiConsoleCopyRegion(PCSRSS_CONSOLE Console,
+GuiConsoleCopyRegion(HWND hWnd,
RECT *Source,
RECT *Dest)
{
- LeaveCriticalSection(&(Console->ActiveBuffer->Header.Lock));
- SendMessageW(Console->hWindow, PM_COPY_REGION, (WPARAM) Source, (LPARAM) Dest);
- EnterCriticalSection(&(Console->ActiveBuffer->Header.Lock));
+ RECT ScrollRect;
+ PGUI_CONSOLE_DATA GuiData;
+ PCSRSS_CONSOLE Console;
+
+
+ GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+
+ ScrollRect.left = Dest->left * GuiData->CharWidth;
+ ScrollRect.right = (Dest->right + 1) * GuiData->CharWidth;
+ ScrollRect.top = Dest->top * GuiData->CharHeight;
+ ScrollRect.bottom = (Dest->bottom + 1) * GuiData->CharHeight;
+ EnterCriticalSection(&GuiData->Lock);
+ BitBlt(GuiData->MemoryDC, ScrollRect.left, ScrollRect.top,
+ ScrollRect.right - ScrollRect.left, ScrollRect.bottom - ScrollRect.top,
+ GuiData->MemoryDC, Source->left * GuiData->CharWidth, Source->top * GuiData->CharHeight, SRCCOPY);
+
+ LeaveCriticalSection(&GuiData->Lock);
+
+ InvalidateRect(hWnd, &ScrollRect, FALSE);
}
/* EOF */