reactos/subsys/csrss/win32csr
diff -u -r1.10 -r1.11
--- guiconsole.c 4 Feb 2004 00:05:46 -0000 1.10
+++ guiconsole.c 7 Mar 2004 21:00:11 -0000 1.11
@@ -1,4 +1,4 @@
-/* $Id: guiconsole.c,v 1.10 2004/02/04 00:05:46 gvg Exp $
+/* $Id: guiconsole.c,v 1.11 2004/03/07 21:00:11 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@@ -29,6 +29,9 @@
PWCHAR LineBuffer;
BOOL CursorBlinkOn;
BOOL ForceCursorOff;
+ CRITICAL_SECTION Lock;
+ HDC MemoryDC;
+ HBITMAP MemoryBitmap;
} GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
#ifndef WM_APP
@@ -37,8 +40,6 @@
#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;
@@ -62,8 +63,9 @@
HDC Dc;
HFONT OldFont;
TEXTMETRICW Metrics;
+ NTSTATUS Status;
- GuiData = HeapAlloc(Win32CsrApiHeap, 0,
+ GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
sizeof(GUI_CONSOLE_DATA) +
(Console->Size.X + 1) * sizeof(WCHAR));
if (NULL == GuiData)
@@ -71,6 +73,15 @@
DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
return FALSE;
}
+
+ Status = RtlInitializeCriticalSection(&GuiData->Lock);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlInitializeCriticalSection failed, Status=%x\n", Status);
+ HeapFree(Win32CsrApiHeap, 0, GuiData);
+ return FALSE;
+ }
+
GuiData->LineBuffer = (PWCHAR)(GuiData + 1);
GuiData->Font = CreateFontW(12, 0, 0, TA_BASELINE, FW_NORMAL,
@@ -81,6 +92,7 @@
if (NULL == GuiData->Font)
{
DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
+ RtlDeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
@@ -88,6 +100,8 @@
if (NULL == Dc)
{
DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
+ DeleteObject(GuiData->Font);
+ RtlDeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
@@ -96,6 +110,8 @@
{
DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
ReleaseDC(hWnd, Dc);
+ DeleteObject(GuiData->Font);
+ RtlDeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
@@ -104,12 +120,23 @@
DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
SelectObject(Dc, OldFont);
ReleaseDC(hWnd, Dc);
+ DeleteObject(GuiData->Font);
+ RtlDeleteCriticalSection(&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);
+ DeleteObject(SelectObject(GuiData->MemoryDC, GuiData->MemoryBitmap));
+ DeleteObject(SelectObject(GuiData->MemoryDC, GuiData->Font));
+
+
ReleaseDC(hWnd, Dc);
GuiData->CursorBlinkOn = TRUE;
GuiData->ForceCursorOff = FALSE;
@@ -161,17 +188,15 @@
}
}
-static VOID FASTCALL
-GuiConsoleHandlePaint(HWND hWnd)
+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;
@@ -182,23 +207,24 @@
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)
@@ -217,14 +243,14 @@
{
if (*(From + 1) != Attribute)
{
- 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;
}
}
@@ -233,12 +259,10 @@
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)
{
@@ -253,22 +277,47 @@
}
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);
+ EndPaint (hWnd, &Ps);
+ LeaveCriticalSection(&GuiData->Lock);
}
else
{
- Dc = BeginPaint(hWnd, &Ps);
- EndPaint(hWnd, &Ps);
+ Dc = BeginPaint (hWnd, &Ps);
+ EndPaint (hWnd, &Ps);
}
}
@@ -289,25 +338,6 @@
}
static VOID FASTCALL
-GuiConsoleHandleCopyRegion(HWND hWnd, PRECT Source, PRECT Dest)
-{
- RECT ClientRect, ScrollRect;
- PGUI_CONSOLE_DATA GuiData;
- PCSRSS_CONSOLE Console;
-
- 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);
-}
-
-static VOID FASTCALL
GuiIntDrawRegion(PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region)
{
RECT RegionRect;
@@ -317,7 +347,7 @@
RegionRect.right = (Region->right + 1) * GuiData->CharWidth;
RegionRect.bottom = (Region->bottom + 1) * GuiData->CharHeight;
- InvalidateRect(Wnd, &RegionRect, FALSE);
+ GuiConsoleUpdateBitmap(Wnd, RegionRect);
}
static VOID STDCALL
@@ -371,7 +401,7 @@
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);
@@ -467,6 +497,8 @@
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
KillTimer(hWnd, 1);
Console->PrivateData = NULL;
+ DeleteDC(GuiData->MemoryDC);
+ RtlDeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
}
@@ -496,9 +528,6 @@
GuiConsoleHandleTimer(hWnd);
Result = 0;
break;
- case PM_COPY_REGION:
- GuiConsoleHandleCopyRegion(hWnd, (PRECT) wParam, (PRECT) lParam);
- break;
case WM_CLOSE:
GuiConsoleHandleClose(hWnd);
Result = 0;
@@ -744,6 +773,7 @@
DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
return STATUS_UNSUCCESSFUL;
}
+ SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
CloseHandle(ThreadHandle);
WaitForSingleObject(GraphicsStartupEvent, INFINITE);
@@ -762,13 +792,29 @@
}
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 */