1 /* $Id: guiconsole.c,v 1.15 2004/07/03 17:17:05 hbirr Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: subsys/csrss/win32csr/guiconsole.c
6 * PURPOSE: Implementation of gui-mode consoles
9 /* INCLUDES ******************************************************************/
13 #include "guiconsole.h"
19 /* Not defined in any header file */
20 extern VOID STDCALL
PrivateCsrssManualGuiCheck(LONG Check
);
22 /* GLOBALS *******************************************************************/
24 typedef struct GUI_CONSOLE_DATA_TAG
32 CRITICAL_SECTION Lock
;
35 } GUI_CONSOLE_DATA
, *PGUI_CONSOLE_DATA
;
40 #define PM_CREATE_CONSOLE (WM_APP + 1)
41 #define PM_DESTROY_CONSOLE (WM_APP + 2)
43 #define CURSOR_BLINK_TIME 500
45 static BOOL Initialized
= FALSE
;
46 static HWND NotifyWnd
;
48 /* FUNCTIONS *****************************************************************/
51 GuiConsoleGetDataPointers(HWND hWnd
, PCSRSS_CONSOLE
*Console
, PGUI_CONSOLE_DATA
*GuiData
)
53 *Console
= (PCSRSS_CONSOLE
) GetWindowLongW(hWnd
, GWL_USERDATA
);
54 *GuiData
= (NULL
== *Console
? NULL
: (*Console
)->PrivateData
);
58 GuiConsoleHandleNcCreate(HWND hWnd
, CREATESTRUCTW
*Create
)
61 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Create
->lpCreateParams
;
62 PGUI_CONSOLE_DATA GuiData
;
67 GuiData
= HeapAlloc(Win32CsrApiHeap
, HEAP_ZERO_MEMORY
,
68 sizeof(GUI_CONSOLE_DATA
) +
69 (Console
->Size
.X
+ 1) * sizeof(WCHAR
));
72 DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
76 InitializeCriticalSection(&GuiData
->Lock
);
78 GuiData
->LineBuffer
= (PWCHAR
)(GuiData
+ 1);
80 GuiData
->Font
= CreateFontW(12, 0, 0, TA_BASELINE
, FW_NORMAL
,
81 FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
82 OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
,
83 DEFAULT_QUALITY
, FIXED_PITCH
| FF_DONTCARE
,
84 L
"Bitstream Vera Sans Mono");
85 if (NULL
== GuiData
->Font
)
87 DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
88 DeleteCriticalSection(&GuiData
->Lock
);
89 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
95 DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
96 DeleteObject(GuiData
->Font
);
97 DeleteCriticalSection(&GuiData
->Lock
);
98 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
101 OldFont
= SelectObject(Dc
, GuiData
->Font
);
104 DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
106 DeleteObject(GuiData
->Font
);
107 DeleteCriticalSection(&GuiData
->Lock
);
108 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
111 if (! GetTextMetricsW(Dc
, &Metrics
))
113 DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
114 SelectObject(Dc
, OldFont
);
116 DeleteObject(GuiData
->Font
);
117 DeleteCriticalSection(&GuiData
->Lock
);
118 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
121 GuiData
->CharWidth
= Metrics
.tmMaxCharWidth
;
122 GuiData
->CharHeight
= Metrics
.tmHeight
+ Metrics
.tmExternalLeading
;
123 SelectObject(Dc
, OldFont
);
125 GuiData
->MemoryDC
= CreateCompatibleDC(Dc
);
126 GuiData
->MemoryBitmap
= CreateCompatibleBitmap(Dc
,
127 Console
->Size
.X
* GuiData
->CharWidth
,
128 Console
->Size
.Y
* GuiData
->CharHeight
);
129 DeleteObject(SelectObject(GuiData
->MemoryDC
, GuiData
->MemoryBitmap
));
130 DeleteObject(SelectObject(GuiData
->MemoryDC
, GuiData
->Font
));
134 GuiData
->CursorBlinkOn
= TRUE
;
135 GuiData
->ForceCursorOff
= FALSE
;
137 Console
->PrivateData
= GuiData
;
138 SetWindowLongW(hWnd
, GWL_USERDATA
, (LONG
) Console
);
140 GetWindowRect(hWnd
, &Rect
);
141 Rect
.right
= Rect
.left
+ Console
->Size
.X
* GuiData
->CharWidth
+
142 2 * GetSystemMetrics(SM_CXFIXEDFRAME
);
143 Rect
.bottom
= Rect
.top
+ Console
->Size
.Y
* GuiData
->CharHeight
+
144 2 * GetSystemMetrics(SM_CYFIXEDFRAME
) + GetSystemMetrics(SM_CYCAPTION
);
145 MoveWindow(hWnd
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
,
146 Rect
.bottom
- Rect
.top
, FALSE
);
148 SetTimer(hWnd
, 1, CURSOR_BLINK_TIME
, NULL
);
150 return (BOOL
) DefWindowProcW(hWnd
, WM_NCCREATE
, 0, (LPARAM
) Create
);
153 static COLORREF FASTCALL
154 GuiConsoleRGBFromAttribute(BYTE Attribute
)
156 int Red
= (Attribute
& 0x04 ? (Attribute
& 0x08 ? 0xff : 0x80) : 0x00);
157 int Green
= (Attribute
& 0x02 ? (Attribute
& 0x08 ? 0xff : 0x80) : 0x00);
158 int Blue
= (Attribute
& 0x01 ? (Attribute
& 0x08 ? 0xff : 0x80) : 0x00);
160 return RGB(Red
, Green
, Blue
);
164 GuiConsoleSetTextColors(HDC Dc
, BYTE Attribute
)
166 SetTextColor(Dc
, GuiConsoleRGBFromAttribute(Attribute
& 0x0f));
167 SetBkColor(Dc
, GuiConsoleRGBFromAttribute((Attribute
& 0xf0) >> 4));
171 GuiConsoleGetLogicalCursorPos(PCSRSS_SCREEN_BUFFER Buff
, ULONG
*CursorX
, ULONG
*CursorY
)
173 *CursorX
= Buff
->CurrentX
;
174 if (Buff
->CurrentY
< Buff
->ShowY
)
176 *CursorY
= Buff
->MaxY
- Buff
->ShowY
+ Buff
->CurrentY
;
180 *CursorY
= Buff
->CurrentY
- Buff
->ShowY
;
185 GuiConsoleUpdateBitmap(HWND hWnd
, RECT rc
)
187 PCSRSS_CONSOLE Console
;
188 PGUI_CONSOLE_DATA GuiData
;
189 PCSRSS_SCREEN_BUFFER Buff
;
191 ULONG TopLine
, BottomLine
, LeftChar
, RightChar
;
192 ULONG Line
, Char
, Start
;
195 BYTE LastAttribute
, Attribute
;
196 ULONG CursorX
, CursorY
, CursorHeight
;
197 HBRUSH CursorBrush
, OldBrush
;
199 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
200 if (NULL
!= Console
&& NULL
!= GuiData
&& NULL
!= Console
->ActiveBuffer
)
202 Buff
= Console
->ActiveBuffer
;
203 EnterCriticalSection(&Buff
->Header
.Lock
);
205 if (rc
.right
<= rc
.left
|| rc
.bottom
<= rc
.top
)
208 LeaveCriticalSection(&Buff
->Header
.Lock
);
212 EnterCriticalSection(&GuiData
->Lock
);
214 TopLine
= rc
.top
/ GuiData
->CharHeight
;
215 BottomLine
= (rc
.bottom
+ (GuiData
->CharHeight
- 1)) / GuiData
->CharHeight
- 1;
216 LeftChar
= rc
.left
/ GuiData
->CharWidth
;
217 RightChar
= (rc
.right
+ (GuiData
->CharWidth
- 1)) / GuiData
->CharWidth
- 1;
218 LastAttribute
= Buff
->Buffer
[(TopLine
* Buff
->MaxX
+ LeftChar
) * 2 + 1];
219 GuiConsoleSetTextColors(GuiData
->MemoryDC
, LastAttribute
);
221 for (Line
= TopLine
; Line
<= BottomLine
; Line
++)
223 if (Line
+ Buff
->ShowY
< Buff
->MaxY
)
225 From
= Buff
->Buffer
+ ((Line
+ Buff
->ShowY
) * Buff
->MaxX
+ LeftChar
) * 2;
229 From
= Buff
->Buffer
+
230 ((Line
- (Buff
->MaxY
- Buff
->ShowY
)) * Buff
->MaxX
+ LeftChar
) * 2;
233 To
= GuiData
->LineBuffer
;
234 for (Char
= LeftChar
; Char
<= RightChar
; Char
++)
236 if (*(From
+ 1) != LastAttribute
)
238 TextOutW(GuiData
->MemoryDC
, Start
* GuiData
->CharWidth
, Line
* GuiData
->CharHeight
,
239 GuiData
->LineBuffer
, Char
- Start
);
241 To
= GuiData
->LineBuffer
;
242 Attribute
= *(From
+ 1);
243 if (Attribute
!= LastAttribute
)
245 GuiConsoleSetTextColors(GuiData
->MemoryDC
, Attribute
);
246 LastAttribute
= Attribute
;
249 *((PBYTE
) To
) = *From
;
250 *(((PBYTE
) To
) + 1) = '\0';
254 TextOutW(GuiData
->MemoryDC
, Start
* GuiData
->CharWidth
, Line
* GuiData
->CharHeight
,
255 GuiData
->LineBuffer
, RightChar
- Start
+ 1);
258 if (Buff
->CursorInfo
.bVisible
&& GuiData
->CursorBlinkOn
259 &&! GuiData
->ForceCursorOff
)
261 GuiConsoleGetLogicalCursorPos(Buff
, &CursorX
, &CursorY
);
262 if (LeftChar
<= CursorX
&& CursorX
<= RightChar
&&
263 TopLine
<= CursorY
&& CursorY
<= BottomLine
)
265 CursorHeight
= (GuiData
->CharHeight
* Buff
->CursorInfo
.dwSize
) / 100;
266 if (CursorHeight
< 1)
270 From
= Buff
->Buffer
+ (Buff
->CurrentY
* Buff
->MaxX
+ Buff
->CurrentX
) * 2 + 1;
271 CursorBrush
= CreateSolidBrush(GuiConsoleRGBFromAttribute(*From
));
272 OldBrush
= SelectObject(GuiData
->MemoryDC
, CursorBrush
);
273 PatBlt(GuiData
->MemoryDC
, CursorX
* GuiData
->CharWidth
,
274 CursorY
* GuiData
->CharHeight
+ (GuiData
->CharHeight
- CursorHeight
),
275 GuiData
->CharWidth
, CursorHeight
, PATCOPY
);
276 SelectObject(GuiData
->MemoryDC
, OldBrush
);
277 DeleteObject(CursorBrush
);
281 LeaveCriticalSection(&GuiData
->Lock
);
283 LeaveCriticalSection(&Buff
->Header
.Lock
);
284 InvalidateRect(hWnd
, &rc
, FALSE
);
290 GuiConsoleHandlePaint(HWND hWnd
)
294 PCSRSS_CONSOLE Console
;
295 PGUI_CONSOLE_DATA GuiData
;
297 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
298 if (NULL
!= Console
&& NULL
!= GuiData
)
300 EnterCriticalSection(&GuiData
->Lock
);
301 Dc
= BeginPaint (hWnd
, &Ps
);
302 BitBlt(Dc
, Ps
.rcPaint
.left
, Ps
.rcPaint
.top
,
303 Ps
.rcPaint
.right
- Ps
.rcPaint
.left
+ 1,
304 Ps
.rcPaint
.bottom
- Ps
.rcPaint
.top
+ 1, GuiData
->MemoryDC
,
305 Ps
.rcPaint
.left
, Ps
.rcPaint
.top
, SRCCOPY
);
306 EndPaint (hWnd
, &Ps
);
307 LeaveCriticalSection(&GuiData
->Lock
);
311 Dc
= BeginPaint (hWnd
, &Ps
);
312 EndPaint (hWnd
, &Ps
);
317 GuiConsoleHandleKey(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
319 PCSRSS_CONSOLE Console
;
320 PGUI_CONSOLE_DATA GuiData
;
323 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
325 Message
.message
= msg
;
326 Message
.wParam
= wParam
;
327 Message
.lParam
= lParam
;
329 ConioProcessKey(&Message
, Console
, FALSE
);
333 GuiIntDrawRegion(PGUI_CONSOLE_DATA GuiData
, HWND Wnd
, RECT
*Region
)
337 RegionRect
.left
= Region
->left
* GuiData
->CharWidth
;
338 RegionRect
.top
= Region
->top
* GuiData
->CharHeight
;
339 RegionRect
.right
= (Region
->right
+ 1) * GuiData
->CharWidth
;
340 RegionRect
.bottom
= (Region
->bottom
+ 1) * GuiData
->CharHeight
;
342 GuiConsoleUpdateBitmap(Wnd
, RegionRect
);
346 GuiDrawRegion(PCSRSS_CONSOLE Console
, RECT
*Region
)
348 PGUI_CONSOLE_DATA GuiData
= (PGUI_CONSOLE_DATA
) Console
->PrivateData
;
350 if (NULL
== Console
->hWindow
|| NULL
== GuiData
)
355 GuiIntDrawRegion(GuiData
, Console
->hWindow
, Region
);
359 GuiInvalidateCell(PGUI_CONSOLE_DATA GuiData
, HWND Wnd
, UINT x
, UINT y
)
368 GuiIntDrawRegion(GuiData
, Wnd
, &CellRect
);
372 GuiWriteStream(PCSRSS_CONSOLE Console
, RECT
*Region
, UINT CursorStartX
, UINT CursorStartY
,
373 UINT ScrolledLines
, CHAR
*Buffer
, UINT Length
)
375 PGUI_CONSOLE_DATA GuiData
= (PGUI_CONSOLE_DATA
) Console
->PrivateData
;
376 PCSRSS_SCREEN_BUFFER Buff
= Console
->ActiveBuffer
;
377 LONG CursorEndX
, CursorEndY
;
380 if (NULL
== Console
->hWindow
|| NULL
== GuiData
)
385 if (0 != ScrolledLines
)
388 Source
.top
= ScrolledLines
;
389 Source
.right
= Console
->Size
.X
- 1;
390 Source
.bottom
= ScrolledLines
+ Region
->top
- 1;
393 Dest
.right
= Console
->Size
.X
- 1;
394 Dest
.bottom
= Region
->top
- 1;
396 GuiConsoleCopyRegion(Console
->hWindow
, &Source
, &Dest
);
399 GuiIntDrawRegion(GuiData
, Console
->hWindow
, Region
);
401 if (CursorStartX
< Region
->left
|| Region
->right
< CursorStartX
402 || CursorStartY
< Region
->top
|| Region
->bottom
< CursorStartY
)
404 GuiInvalidateCell(GuiData
, Console
->hWindow
, CursorStartX
, CursorStartY
);
407 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
,
408 &CursorEndX
, &CursorEndY
);
409 if ((CursorEndX
< Region
->left
|| Region
->right
< CursorEndX
410 || CursorEndY
< Region
->top
|| Region
->bottom
< CursorEndY
)
411 && (CursorEndX
!= CursorStartX
|| CursorEndY
!= CursorStartY
))
413 GuiInvalidateCell(GuiData
, Console
->hWindow
, CursorEndX
, CursorEndY
);
418 GuiSetCursorInfo(PCSRSS_CONSOLE Console
, PCSRSS_SCREEN_BUFFER Buff
)
422 if (Console
->ActiveBuffer
== Buff
)
424 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
,
425 &UpdateRect
.left
, &UpdateRect
.top
);
426 UpdateRect
.right
= UpdateRect
.left
;
427 UpdateRect
.bottom
= UpdateRect
.top
;
428 ConioDrawRegion(Console
, &UpdateRect
);
435 GuiSetScreenInfo(PCSRSS_CONSOLE Console
, PCSRSS_SCREEN_BUFFER Buff
, UINT OldCursorX
, UINT OldCursorY
)
439 if (Console
->ActiveBuffer
== Buff
)
441 /* Redraw char at old position (removes cursor) */
442 UpdateRect
.left
= OldCursorX
;
443 UpdateRect
.top
= OldCursorY
;
444 UpdateRect
.right
= OldCursorX
;
445 UpdateRect
.bottom
= OldCursorY
;
446 ConioDrawRegion(Console
, &UpdateRect
);
447 /* Redraw char at new position (shows cursor) */
448 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
,
449 &(UpdateRect
.left
), &(UpdateRect
.top
));
450 UpdateRect
.right
= UpdateRect
.left
;
451 UpdateRect
.bottom
= UpdateRect
.top
;
452 ConioDrawRegion(Console
, &UpdateRect
);
459 GuiConsoleHandleTimer(HWND hWnd
)
461 PCSRSS_CONSOLE Console
;
462 PGUI_CONSOLE_DATA GuiData
;
464 ULONG CursorX
, CursorY
;
466 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
467 GuiData
->CursorBlinkOn
= ! GuiData
->CursorBlinkOn
;
469 GuiConsoleGetLogicalCursorPos(Console
->ActiveBuffer
, &CursorX
, &CursorY
);
470 CursorRect
.left
= CursorX
;
471 CursorRect
.top
= CursorY
;
472 CursorRect
.right
= CursorX
;
473 CursorRect
.bottom
= CursorY
;
474 GuiDrawRegion(Console
, &CursorRect
);
478 GuiConsoleHandleClose(HWND hWnd
)
480 PCSRSS_CONSOLE Console
;
481 PGUI_CONSOLE_DATA GuiData
;
482 PLIST_ENTRY current_entry
;
483 PCSRSS_PROCESS_DATA current
;
487 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
489 EnterCriticalSection(&Console
->Header
.Lock
);
491 current_entry
= Console
->ProcessList
.Flink
;
492 while (current_entry
!= &Console
->ProcessList
)
494 current
= CONTAINING_RECORD(current_entry
, CSRSS_PROCESS_DATA
, ProcessEntry
);
495 current_entry
= current_entry
->Flink
;
497 Process
= OpenProcess(PROCESS_DUP_HANDLE
, FALSE
, current
->ProcessId
);
500 DPRINT1("Failed for handle duplication\n");
503 Result
= TerminateProcess(Process
, 0);
504 CloseHandle(Process
);
507 DPRINT1("Failed to terminate process %d\n", current
->ProcessId
);
511 LeaveCriticalSection(&Console
->Header
.Lock
);
515 GuiConsoleHandleNcDestroy(HWND hWnd
)
517 PCSRSS_CONSOLE Console
;
518 PGUI_CONSOLE_DATA GuiData
;
520 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
522 Console
->PrivateData
= NULL
;
523 DeleteDC(GuiData
->MemoryDC
);
524 DeleteCriticalSection(&GuiData
->Lock
);
525 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
528 static LRESULT CALLBACK
529 GuiConsoleWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
536 Result
= (LRESULT
) GuiConsoleHandleNcCreate(hWnd
, (CREATESTRUCTW
*) lParam
);
539 GuiConsoleHandlePaint(hWnd
);
547 GuiConsoleHandleKey(hWnd
, msg
, wParam
, lParam
);
551 GuiConsoleHandleTimer(hWnd
);
555 GuiConsoleHandleClose(hWnd
);
559 GuiConsoleHandleNcDestroy(hWnd
);
563 Result
= DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
570 static LRESULT CALLBACK
571 GuiConsoleNotifyWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
575 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) lParam
;
580 SetWindowLongW(hWnd
, GWL_USERDATA
, 0);
582 case PM_CREATE_CONSOLE
:
583 NewWindow
= CreateWindowW(L
"Win32CsrConsole",
584 Console
->Title
.Buffer
,
585 WS_OVERLAPPED
| WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
,
592 (HINSTANCE
) GetModuleHandleW(NULL
),
594 Console
->hWindow
= NewWindow
;
595 if (NULL
!= NewWindow
)
597 SetWindowLongW(hWnd
, GWL_USERDATA
, GetWindowLongW(hWnd
, GWL_USERDATA
) + 1);
598 ShowWindow(NewWindow
, SW_SHOW
);
600 return (LRESULT
) NewWindow
;
601 case PM_DESTROY_CONSOLE
:
602 DestroyWindow(Console
->hWindow
);
603 Console
->hWindow
= NULL
;
604 WindowCount
= GetWindowLongW(hWnd
, GWL_USERDATA
);
606 SetWindowLongW(hWnd
, GWL_USERDATA
, WindowCount
);
607 if (0 == WindowCount
)
611 PrivateCsrssManualGuiCheck(-1);
616 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
621 GuiConsoleGuiThread(PVOID Data
)
624 PHANDLE GraphicsStartupEvent
= (PHANDLE
) Data
;
626 NotifyWnd
= CreateWindowW(L
"Win32CsrCreateNotify",
635 (HINSTANCE
) GetModuleHandleW(NULL
),
637 if (NULL
== NotifyWnd
)
639 PrivateCsrssManualGuiCheck(-1);
640 SetEvent(*GraphicsStartupEvent
);
644 SetEvent(*GraphicsStartupEvent
);
646 while(GetMessageW(&msg
, NULL
, 0, 0))
648 TranslateMessage(&msg
);
649 DispatchMessageW(&msg
);
662 Desktop
= OpenDesktopW(L
"Default", 0, FALSE
, GENERIC_ALL
);
665 DPRINT1("Failed to open desktop\n");
668 Status
= NtSetInformationProcess(NtCurrentProcess(),
672 if (!NT_SUCCESS(Status
))
674 DPRINT1("Cannot set default desktop.\n");
677 if (! SetThreadDesktop(Desktop
))
679 DPRINT1("Failed to set thread desktop\n");
683 if (NULL
== NotifyWnd
)
685 PrivateCsrssManualGuiCheck(+1);
688 wc
.cbSize
= sizeof(WNDCLASSEXW
);
689 wc
.lpszClassName
= L
"Win32CsrCreateNotify";
690 wc
.lpfnWndProc
= GuiConsoleNotifyWndProc
;
692 wc
.hInstance
= (HINSTANCE
) GetModuleHandleW(NULL
);
695 wc
.hbrBackground
= NULL
;
696 wc
.lpszMenuName
= NULL
;
700 if (RegisterClassExW(&wc
) == 0)
702 DPRINT1("Failed to register notify wndproc\n");
706 wc
.cbSize
= sizeof(WNDCLASSEXW
);
707 wc
.lpszClassName
= L
"Win32CsrConsole";
708 wc
.lpfnWndProc
= GuiConsoleWndProc
;
710 wc
.hInstance
= (HINSTANCE
) GetModuleHandleW(NULL
);
711 wc
.hIcon
= LoadIconW(Win32CsrDllHandle
, MAKEINTRESOURCEW(1));
712 wc
.hCursor
= LoadCursorW(NULL
, MAKEINTRESOURCEW(IDC_ARROW
));
713 wc
.hbrBackground
= NULL
;
714 wc
.lpszMenuName
= NULL
;
717 wc
.hIconSm
= LoadImageW(Win32CsrDllHandle
, MAKEINTRESOURCEW(1), IMAGE_ICON
,
718 GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
),
720 if (RegisterClassExW(&wc
) == 0)
722 DPRINT1("Failed to register console wndproc\n");
730 GuiInitScreenBuffer(PCSRSS_CONSOLE Console
, PCSRSS_SCREEN_BUFFER Buffer
)
732 Buffer
->DefaultAttrib
= 0x0f;
736 GuiChangeTitle(PCSRSS_CONSOLE Console
)
738 SendMessageW(Console
->hWindow
, WM_SETTEXT
, 0, (LPARAM
) Console
->Title
.Buffer
);
744 GuiChangeIcon(PCSRSS_CONSOLE Console
)
746 SendMessageW(Console
->hWindow
, WM_SETICON
, ICON_BIG
, (LPARAM
)Console
->hWindowIcon
);
747 SendMessageW(Console
->hWindow
, WM_SETICON
, ICON_SMALL
, (LPARAM
)Console
->hWindowIcon
);
753 GuiCleanupConsole(PCSRSS_CONSOLE Console
)
755 SendMessageW(NotifyWnd
, PM_DESTROY_CONSOLE
, 0, (LPARAM
) Console
);
758 static CSRSS_CONSOLE_VTBL GuiVtbl
=
771 GuiInitConsole(PCSRSS_CONSOLE Console
)
773 HANDLE GraphicsStartupEvent
;
782 return STATUS_UNSUCCESSFUL
;
786 Console
->Vtbl
= &GuiVtbl
;
787 Console
->Size
.X
= 80;
788 Console
->Size
.Y
= 25;
789 if (NULL
== NotifyWnd
)
791 GraphicsStartupEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
792 if (NULL
== GraphicsStartupEvent
)
794 return STATUS_UNSUCCESSFUL
;
797 ThreadHandle
= CreateThread(NULL
,
800 (PVOID
) &GraphicsStartupEvent
,
803 if (NULL
== ThreadHandle
)
805 NtClose(GraphicsStartupEvent
);
806 DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
807 return STATUS_UNSUCCESSFUL
;
809 SetThreadPriority(ThreadHandle
, THREAD_PRIORITY_HIGHEST
);
810 CloseHandle(ThreadHandle
);
812 WaitForSingleObject(GraphicsStartupEvent
, INFINITE
);
813 CloseHandle(GraphicsStartupEvent
);
815 if (NULL
== NotifyWnd
)
817 DPRINT1("Win32Csr: Failed to create notification window.\n");
818 return STATUS_UNSUCCESSFUL
;
822 PostMessageW(NotifyWnd
, PM_CREATE_CONSOLE
, 0, (LPARAM
) Console
);
824 return STATUS_SUCCESS
;
828 GuiConsoleCopyRegion(HWND hWnd
,
833 PGUI_CONSOLE_DATA GuiData
;
834 PCSRSS_CONSOLE Console
;
837 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
839 ScrollRect
.left
= Dest
->left
* GuiData
->CharWidth
;
840 ScrollRect
.right
= (Dest
->right
+ 1) * GuiData
->CharWidth
;
841 ScrollRect
.top
= Dest
->top
* GuiData
->CharHeight
;
842 ScrollRect
.bottom
= (Dest
->bottom
+ 1) * GuiData
->CharHeight
;
843 EnterCriticalSection(&GuiData
->Lock
);
844 BitBlt(GuiData
->MemoryDC
, ScrollRect
.left
, ScrollRect
.top
,
845 ScrollRect
.right
- ScrollRect
.left
, ScrollRect
.bottom
- ScrollRect
.top
,
846 GuiData
->MemoryDC
, Source
->left
* GuiData
->CharWidth
, Source
->top
* GuiData
->CharHeight
, SRCCOPY
);
848 LeaveCriticalSection(&GuiData
->Lock
);
850 InvalidateRect(hWnd
, &ScrollRect
, FALSE
);