1 /* $Id: guiconsole.c,v 1.8 2004/01/19 20:14:28 gvg 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 } GUI_CONSOLE_DATA
, *PGUI_CONSOLE_DATA
;
37 #define PM_CREATE_CONSOLE (WM_APP + 1)
38 #define PM_DESTROY_CONSOLE (WM_APP + 2)
40 #define PM_COPY_REGION (WM_APP + 100)
42 #define CURSOR_BLINK_TIME 500
44 static BOOL Initialized
= FALSE
;
45 static HWND NotifyWnd
;
47 /* FUNCTIONS *****************************************************************/
50 GuiConsoleGetDataPointers(HWND hWnd
, PCSRSS_CONSOLE
*Console
, PGUI_CONSOLE_DATA
*GuiData
)
52 *Console
= (PCSRSS_CONSOLE
) GetWindowLongW(hWnd
, GWL_USERDATA
);
53 *GuiData
= (NULL
== *Console
? NULL
: (*Console
)->PrivateData
);
57 GuiConsoleHandleNcCreate(HWND hWnd
, CREATESTRUCTW
*Create
)
60 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Create
->lpCreateParams
;
61 PGUI_CONSOLE_DATA GuiData
;
66 GuiData
= HeapAlloc(Win32CsrApiHeap
, 0,
67 sizeof(GUI_CONSOLE_DATA
) +
68 (Console
->Size
.X
+ 1) * sizeof(WCHAR
));
71 DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
74 GuiData
->LineBuffer
= (PWCHAR
)(GuiData
+ 1);
76 GuiData
->Font
= CreateFontW(12, 0, 0, TA_BASELINE
, FW_NORMAL
,
77 FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
78 OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
,
79 DEFAULT_QUALITY
, FIXED_PITCH
| FF_DONTCARE
,
80 L
"Bitstream Vera Sans Mono");
81 if (NULL
== GuiData
->Font
)
83 DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
84 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
90 DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
91 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
94 OldFont
= SelectObject(Dc
, GuiData
->Font
);
97 DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
99 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
102 if (! GetTextMetricsW(Dc
, &Metrics
))
104 DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
105 SelectObject(Dc
, OldFont
);
107 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
110 GuiData
->CharWidth
= Metrics
.tmMaxCharWidth
;
111 GuiData
->CharHeight
= Metrics
.tmHeight
+ Metrics
.tmExternalLeading
;
112 SelectObject(Dc
, OldFont
);
114 GuiData
->CursorBlinkOn
= TRUE
;
115 GuiData
->ForceCursorOff
= FALSE
;
117 Console
->PrivateData
= GuiData
;
118 SetWindowLongW(hWnd
, GWL_USERDATA
, (LONG
) Console
);
120 GetWindowRect(hWnd
, &Rect
);
121 Rect
.right
= Rect
.left
+ Console
->Size
.X
* GuiData
->CharWidth
+
122 2 * GetSystemMetrics(SM_CXFIXEDFRAME
);
123 Rect
.bottom
= Rect
.top
+ Console
->Size
.Y
* GuiData
->CharHeight
+
124 2 * GetSystemMetrics(SM_CYFIXEDFRAME
) + GetSystemMetrics(SM_CYCAPTION
);
125 MoveWindow(hWnd
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
,
126 Rect
.bottom
- Rect
.top
, FALSE
);
128 SetTimer(hWnd
, 1, CURSOR_BLINK_TIME
, NULL
);
130 return (BOOL
) DefWindowProcW(hWnd
, WM_NCCREATE
, 0, (LPARAM
) Create
);
133 static COLORREF FASTCALL
134 GuiConsoleRGBFromAttribute(BYTE Attribute
)
136 int Red
= (Attribute
& 0x04 ? (Attribute
& 0x08 ? 0xff : 0x80) : 0x00);
137 int Green
= (Attribute
& 0x02 ? (Attribute
& 0x08 ? 0xff : 0x80) : 0x00);
138 int Blue
= (Attribute
& 0x01 ? (Attribute
& 0x08 ? 0xff : 0x80) : 0x00);
140 return RGB(Red
, Green
, Blue
);
144 GuiConsoleSetTextColors(HDC Dc
, BYTE Attribute
)
146 SetTextColor(Dc
, GuiConsoleRGBFromAttribute(Attribute
& 0x0f));
147 SetBkColor(Dc
, GuiConsoleRGBFromAttribute((Attribute
& 0xf0) >> 4));
151 GuiConsoleGetLogicalCursorPos(PCSRSS_SCREEN_BUFFER Buff
, ULONG
*CursorX
, ULONG
*CursorY
)
153 *CursorX
= Buff
->CurrentX
;
154 if (Buff
->CurrentY
< Buff
->ShowY
)
156 *CursorY
= Buff
->MaxY
- Buff
->ShowY
+ Buff
->CurrentY
;
160 *CursorY
= Buff
->CurrentY
- Buff
->ShowY
;
165 GuiConsoleHandlePaint(HWND hWnd
)
169 PCSRSS_CONSOLE Console
;
170 PGUI_CONSOLE_DATA GuiData
;
171 PCSRSS_SCREEN_BUFFER Buff
;
172 unsigned TopLine
, BottomLine
, LeftChar
, RightChar
;
173 unsigned Line
, Char
, Start
;
177 BYTE LastAttribute
, Attribute
;
178 ULONG CursorX
, CursorY
, CursorHeight
;
179 HBRUSH CursorBrush
, OldBrush
;
181 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
182 if (NULL
!= Console
&& NULL
!= GuiData
&& NULL
!= Console
->ActiveBuffer
)
184 Buff
= Console
->ActiveBuffer
;
185 EnterCriticalSection(&(Buff
->Header
.Lock
));
187 Dc
= BeginPaint(hWnd
, &Ps
);
188 if (Ps
.rcPaint
.right
<= Ps
.rcPaint
.left
|| Ps
.rcPaint
.bottom
<= Ps
.rcPaint
.top
)
191 LeaveCriticalSection(&(Buff
->Header
.Lock
));
194 OldFont
= SelectObject(Dc
, GuiData
->Font
);
196 TopLine
= Ps
.rcPaint
.top
/ GuiData
->CharHeight
;
197 BottomLine
= (Ps
.rcPaint
.bottom
+ (GuiData
->CharHeight
- 1)) / GuiData
->CharHeight
- 1;
198 LeftChar
= Ps
.rcPaint
.left
/ GuiData
->CharWidth
;
199 RightChar
= (Ps
.rcPaint
.right
+ (GuiData
->CharWidth
- 1)) / GuiData
->CharWidth
- 1;
200 LastAttribute
= Buff
->Buffer
[(TopLine
* Buff
->MaxX
+ LeftChar
) * 2 + 1];
201 GuiConsoleSetTextColors(Dc
, LastAttribute
);
202 for (Line
= TopLine
; Line
<= BottomLine
; Line
++)
204 if (Line
+ Buff
->ShowY
< Buff
->MaxY
)
206 From
= Buff
->Buffer
+ ((Line
+ Buff
->ShowY
) * Buff
->MaxX
+ LeftChar
) * 2;
210 From
= Buff
->Buffer
+
211 ((Line
- (Buff
->MaxY
- Buff
->ShowY
)) * Buff
->MaxX
+ LeftChar
) * 2;
213 Attribute
= *(From
+ 1);
215 To
= GuiData
->LineBuffer
;
216 for (Char
= LeftChar
; Char
<= RightChar
; Char
++)
218 if (*(From
+ 1) != Attribute
)
220 TextOutW(Dc
, Start
* GuiData
->CharWidth
, Line
* GuiData
->CharHeight
,
221 GuiData
->LineBuffer
, Char
- Start
);
223 To
= GuiData
->LineBuffer
;
224 Attribute
= *(From
+ 1);
225 if (Attribute
!= LastAttribute
)
227 GuiConsoleSetTextColors(Dc
, Attribute
);
228 LastAttribute
= Attribute
;
231 *((PBYTE
) To
) = *From
;
232 *(((PBYTE
) To
) + 1) = '\0';
236 TextOutW(Dc
, Start
* GuiData
->CharWidth
, Line
* GuiData
->CharHeight
,
237 GuiData
->LineBuffer
, RightChar
- Start
+ 1);
240 SelectObject(Dc
, OldFont
);
242 if (Buff
->CursorInfo
.bVisible
&& GuiData
->CursorBlinkOn
243 &&! GuiData
->ForceCursorOff
)
245 GuiConsoleGetLogicalCursorPos(Buff
, &CursorX
, &CursorY
);
246 if (LeftChar
<= CursorX
&& CursorX
<= RightChar
&&
247 TopLine
<= CursorY
&& CursorY
<= BottomLine
)
249 CursorHeight
= (GuiData
->CharHeight
* Buff
->CursorInfo
.dwSize
) / 100;
250 if (CursorHeight
< 1)
254 From
= Buff
->Buffer
+ (Buff
->CurrentY
* Buff
->MaxX
+ Buff
->CurrentX
) * 2 + 1;
255 CursorBrush
= CreateSolidBrush(GuiConsoleRGBFromAttribute(*From
));
256 OldBrush
= SelectObject(Dc
, CursorBrush
);
257 PatBlt(Dc
, CursorX
* GuiData
->CharWidth
,
258 CursorY
* GuiData
->CharHeight
+ (GuiData
->CharHeight
- CursorHeight
),
259 GuiData
->CharWidth
, CursorHeight
, PATCOPY
);
260 SelectObject(Dc
, OldBrush
);
261 DeleteObject(CursorBrush
);
266 LeaveCriticalSection(&(Buff
->Header
.Lock
));
270 Dc
= BeginPaint(hWnd
, &Ps
);
276 GuiConsoleHandleKey(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
278 PCSRSS_CONSOLE Console
;
279 PGUI_CONSOLE_DATA GuiData
;
282 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
284 Message
.message
= msg
;
285 Message
.wParam
= wParam
;
286 Message
.lParam
= lParam
;
288 ConioProcessKey(&Message
, Console
, FALSE
);
292 GuiConsoleHandleCopyRegion(HWND hWnd
, PRECT Source
, PRECT Dest
)
295 int XDest
, YDest
, Width
, Height
, XSrc
, YSrc
;
296 PCSRSS_CONSOLE Console
;
297 PGUI_CONSOLE_DATA GuiData
;
298 RECT CursorRect
, UpdateRect
;
299 DWORD CursorX
, CursorY
;
300 PCSRSS_SCREEN_BUFFER Buff
;
302 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
303 Buff
= Console
->ActiveBuffer
;
305 /* Check if the cursor is in the source rectangle and if it is,
306 * make sure it's invisible */
307 GuiConsoleGetLogicalCursorPos(Buff
, &CursorX
, &CursorY
);
308 if (Source
->left
<= CursorX
&& CursorX
<= Source
->right
&&
309 Source
->top
<= CursorY
&& CursorY
<= Source
->bottom
)
311 GuiData
->ForceCursorOff
= TRUE
;
313 CursorRect
.left
= CursorX
* GuiData
->CharWidth
;
314 CursorRect
.top
= CursorY
* GuiData
->CharHeight
;
315 CursorRect
.right
= (CursorX
+ 1) * GuiData
->CharWidth
;
316 CursorRect
.bottom
= (CursorY
+ 1) * GuiData
->CharHeight
;
318 InvalidateRect(hWnd
, &CursorRect
, FALSE
);
322 /* This is a bit tricky. We want to copy a source rectangle to
323 * a destination rectangle, but there is no guarantee that the
324 * contents of the source rectangle is valid. First let's try
325 * to make it as valid as possible by painting all outstanding
326 * updates. To do that we have to release the lock, otherwise
327 * the paint code can't acquire it */
337 XSrc
= Source
->left
* GuiData
->CharWidth
;
338 YSrc
= Source
->top
* GuiData
->CharHeight
;
339 XDest
= Dest
->left
* GuiData
->CharWidth
;
340 YDest
= Dest
->top
* GuiData
->CharHeight
;
341 Width
= (Dest
->right
- Dest
->left
+ 1) * GuiData
->CharWidth
;
342 Height
= (Dest
->bottom
- Dest
->top
+ 1) * GuiData
->CharHeight
;
344 BitBlt(Dc
, XDest
, YDest
, Width
, Height
, Dc
, XSrc
, YSrc
, SRCCOPY
);
348 /* Although we tried to make sure that the source rectangle was
349 * up-to-date, this is not guaranteed. For example, the user could
350 * have moved a window between the UpdateWindow() and the BitBlt()
351 * above, invalidating part of the window. So, we're going to
352 * check if the current update rect of the window overlaps with the
353 * source rectangle. If it does, we invalidate the corresponding
354 * part of the destination rectangle so it will eventually be
355 * repainted. Note that this is probably doesn't happen all that
356 * often and GetUpdateRect() below will usually return FALSE,
357 * indicating that the whole window is valid */
359 if (GetUpdateRect(hWnd
, &UpdateRect
, FALSE
))
361 UpdateRect
.left
= max(UpdateRect
.left
, XSrc
);
362 UpdateRect
.top
= max(UpdateRect
.top
, YSrc
);
363 UpdateRect
.right
= min(UpdateRect
.right
, XSrc
+ Width
);
364 UpdateRect
.bottom
= min(UpdateRect
.bottom
, YSrc
+ Height
);
365 if (UpdateRect
.left
< UpdateRect
.right
&& UpdateRect
.top
< UpdateRect
.bottom
)
367 UpdateRect
.left
+= XDest
- XSrc
;
368 UpdateRect
.top
+= YDest
- YSrc
;
369 UpdateRect
.right
+= XDest
- XSrc
;
370 UpdateRect
.bottom
+= YDest
- YSrc
;
372 InvalidateRect(Console
->hWindow
, &UpdateRect
, FALSE
);
376 /* Show cursor again if we made it invisible */
377 if (GuiData
->ForceCursorOff
)
379 GuiData
->ForceCursorOff
= FALSE
;
381 InvalidateRect(hWnd
, &CursorRect
, FALSE
);
386 GuiIntDrawRegion(PGUI_CONSOLE_DATA GuiData
, HWND Wnd
, RECT
*Region
)
390 RegionRect
.left
= Region
->left
* GuiData
->CharWidth
;
391 RegionRect
.top
= Region
->top
* GuiData
->CharHeight
;
392 RegionRect
.right
= (Region
->right
+ 1) * GuiData
->CharWidth
;
393 RegionRect
.bottom
= (Region
->bottom
+ 1) * GuiData
->CharHeight
;
395 InvalidateRect(Wnd
, &RegionRect
, FALSE
);
399 GuiDrawRegion(PCSRSS_CONSOLE Console
, RECT
*Region
)
401 PGUI_CONSOLE_DATA GuiData
= (PGUI_CONSOLE_DATA
) Console
->PrivateData
;
403 if (NULL
== Console
->hWindow
|| NULL
== GuiData
)
408 GuiIntDrawRegion(GuiData
, Console
->hWindow
, Region
);
412 GuiInvalidateCell(PGUI_CONSOLE_DATA GuiData
, HWND Wnd
, UINT x
, UINT y
)
421 GuiIntDrawRegion(GuiData
, Wnd
, &CellRect
);
425 GuiWriteStream(PCSRSS_CONSOLE Console
, RECT
*Region
, UINT CursorStartX
, UINT CursorStartY
,
426 UINT ScrolledLines
, CHAR
*Buffer
, UINT Length
)
428 PGUI_CONSOLE_DATA GuiData
= (PGUI_CONSOLE_DATA
) Console
->PrivateData
;
429 PCSRSS_SCREEN_BUFFER Buff
= Console
->ActiveBuffer
;
430 LONG CursorEndX
, CursorEndY
;
433 if (NULL
== Console
->hWindow
|| NULL
== GuiData
)
438 if (0 != ScrolledLines
)
441 Source
.top
= ScrolledLines
;
442 Source
.right
= Console
->Size
.X
- 1;
443 Source
.bottom
= ScrolledLines
+ Region
->top
- 1;
446 Dest
.right
= Console
->Size
.X
- 1;
447 Dest
.bottom
= Region
->top
- 1;
449 GuiConsoleCopyRegion(Console
, &Source
, &Dest
);
452 GuiIntDrawRegion(GuiData
, Console
->hWindow
, Region
);
454 if (CursorStartX
< Region
->left
|| Region
->right
< CursorStartX
455 || CursorStartY
< Region
->top
|| Region
->bottom
< CursorStartY
)
457 GuiInvalidateCell(GuiData
, Console
->hWindow
, CursorStartX
, CursorStartY
);
460 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
,
461 &CursorEndX
, &CursorEndY
);
462 if ((CursorEndX
< Region
->left
|| Region
->right
< CursorEndX
463 || CursorEndY
< Region
->top
|| Region
->bottom
< CursorEndY
)
464 && (CursorEndX
!= CursorStartX
|| CursorEndY
!= CursorStartY
))
466 GuiInvalidateCell(GuiData
, Console
->hWindow
, CursorEndX
, CursorEndY
);
471 GuiSetCursorInfo(PCSRSS_CONSOLE Console
, PCSRSS_SCREEN_BUFFER Buff
)
475 if (Console
->ActiveBuffer
== Buff
)
477 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
,
478 &UpdateRect
.left
, &UpdateRect
.top
);
479 UpdateRect
.right
= UpdateRect
.left
;
480 UpdateRect
.bottom
= UpdateRect
.top
;
481 ConioDrawRegion(Console
, &UpdateRect
);
488 GuiSetScreenInfo(PCSRSS_CONSOLE Console
, PCSRSS_SCREEN_BUFFER Buff
, UINT OldCursorX
, UINT OldCursorY
)
492 if (Console
->ActiveBuffer
== Buff
)
494 /* Redraw char at old position (removes cursor) */
495 UpdateRect
.left
= OldCursorX
;
496 UpdateRect
.top
= OldCursorY
;
497 UpdateRect
.right
= OldCursorX
;
498 UpdateRect
.bottom
= OldCursorY
;
499 ConioDrawRegion(Console
, &UpdateRect
);
500 /* Redraw char at new position (shows cursor) */
501 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
,
502 &(UpdateRect
.left
), &(UpdateRect
.top
));
503 UpdateRect
.right
= UpdateRect
.left
;
504 UpdateRect
.bottom
= UpdateRect
.top
;
505 ConioDrawRegion(Console
, &UpdateRect
);
512 GuiConsoleHandleTimer(HWND hWnd
)
514 PCSRSS_CONSOLE Console
;
515 PGUI_CONSOLE_DATA GuiData
;
517 ULONG CursorX
, CursorY
;
519 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
520 GuiData
->CursorBlinkOn
= ! GuiData
->CursorBlinkOn
;
522 GuiConsoleGetLogicalCursorPos(Console
->ActiveBuffer
, &CursorX
, &CursorY
);
523 CursorRect
.left
= CursorX
;
524 CursorRect
.top
= CursorY
;
525 CursorRect
.right
= CursorX
;
526 CursorRect
.bottom
= CursorY
;
527 GuiDrawRegion(Console
, &CursorRect
);
531 GuiConsoleHandleClose(HWND hWnd
)
533 /* FIXME for now, just ignore close requests */
537 GuiConsoleHandleNcDestroy(HWND hWnd
)
539 PCSRSS_CONSOLE Console
;
540 PGUI_CONSOLE_DATA GuiData
;
542 GuiConsoleGetDataPointers(hWnd
, &Console
, &GuiData
);
544 Console
->PrivateData
= NULL
;
545 HeapFree(Win32CsrApiHeap
, 0, GuiData
);
548 static LRESULT CALLBACK
549 GuiConsoleWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
556 Result
= (LRESULT
) GuiConsoleHandleNcCreate(hWnd
, (CREATESTRUCTW
*) lParam
);
559 GuiConsoleHandlePaint(hWnd
);
567 GuiConsoleHandleKey(hWnd
, msg
, wParam
, lParam
);
571 GuiConsoleHandleTimer(hWnd
);
575 GuiConsoleHandleCopyRegion(hWnd
, (PRECT
) wParam
, (PRECT
) lParam
);
578 GuiConsoleHandleClose(hWnd
);
582 GuiConsoleHandleNcDestroy(hWnd
);
586 Result
= DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
593 static LRESULT CALLBACK
594 GuiConsoleNotifyWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
598 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) lParam
;
603 SetWindowLongW(hWnd
, GWL_USERDATA
, 0);
605 case PM_CREATE_CONSOLE
:
606 NewWindow
= CreateWindowW(L
"Win32CsrConsole",
607 Console
->Title
.Buffer
,
608 WS_OVERLAPPED
| WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
,
615 (HINSTANCE
) GetModuleHandleW(NULL
),
617 Console
->hWindow
= NewWindow
;
618 if (NULL
!= NewWindow
)
620 SetWindowLongW(hWnd
, GWL_USERDATA
, GetWindowLongW(hWnd
, GWL_USERDATA
) + 1);
621 ShowWindow(NewWindow
, SW_SHOW
);
623 return (LRESULT
) NewWindow
;
624 case PM_DESTROY_CONSOLE
:
625 DestroyWindow(Console
->hWindow
);
626 Console
->hWindow
= NULL
;
627 WindowCount
= GetWindowLongW(hWnd
, GWL_USERDATA
);
629 SetWindowLongW(hWnd
, GWL_USERDATA
, WindowCount
);
630 if (0 == WindowCount
)
634 PrivateCsrssManualGuiCheck(-1);
639 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
644 GuiConsoleGuiThread(PVOID Data
)
647 PHANDLE GraphicsStartupEvent
= (PHANDLE
) Data
;
649 PrivateCsrssManualGuiCheck(+1);
651 NotifyWnd
= CreateWindowW(L
"Win32CsrCreateNotify",
660 (HINSTANCE
) GetModuleHandleW(NULL
),
662 if (NULL
== NotifyWnd
)
664 PrivateCsrssManualGuiCheck(-1);
665 SetEvent(*GraphicsStartupEvent
);
669 SetEvent(*GraphicsStartupEvent
);
671 while(GetMessageW(&msg
, NULL
, 0, 0))
673 TranslateMessage(&msg
);
674 DispatchMessageW(&msg
);
687 Desktop
= OpenDesktopW(L
"Default", 0, FALSE
, GENERIC_ALL
);
690 DPRINT1("Failed to open desktop\n");
693 Status
= NtSetInformationProcess(NtCurrentProcess(),
697 if (!NT_SUCCESS(Status
))
699 DPRINT1("Cannot set default desktop.\n");
702 if (! SetThreadDesktop(Desktop
))
704 DPRINT1("Failed to set thread desktop\n");
708 wc
.cbSize
= sizeof(WNDCLASSEXW
);
709 wc
.lpszClassName
= L
"Win32CsrCreateNotify";
710 wc
.lpfnWndProc
= GuiConsoleNotifyWndProc
;
712 wc
.hInstance
= (HINSTANCE
) GetModuleHandleW(NULL
);
715 wc
.hbrBackground
= NULL
;
716 wc
.lpszMenuName
= NULL
;
720 if (RegisterClassExW(&wc
) == 0)
722 DPRINT1("Failed to register notify wndproc\n");
726 wc
.cbSize
= sizeof(WNDCLASSEXW
);
727 wc
.lpszClassName
= L
"Win32CsrConsole";
728 wc
.lpfnWndProc
= GuiConsoleWndProc
;
730 wc
.hInstance
= (HINSTANCE
) GetModuleHandleW(NULL
);
731 wc
.hIcon
= LoadIconW(Win32CsrDllHandle
, MAKEINTRESOURCEW(1));
732 wc
.hCursor
= LoadCursorW(NULL
, MAKEINTRESOURCEW(IDC_ARROW
));
733 wc
.hbrBackground
= NULL
;
734 wc
.lpszMenuName
= NULL
;
737 wc
.hIconSm
= LoadImageW(Win32CsrDllHandle
, MAKEINTRESOURCEW(1), IMAGE_ICON
,
738 GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
),
740 if (RegisterClassExW(&wc
) == 0)
742 DPRINT1("Failed to register console wndproc\n");
750 GuiInitScreenBuffer(PCSRSS_CONSOLE Console
, PCSRSS_SCREEN_BUFFER Buffer
)
752 Buffer
->DefaultAttrib
= 0x0f;
756 GuiChangeTitle(PCSRSS_CONSOLE Console
)
758 SendMessageW(Console
->hWindow
, WM_SETTEXT
, 0, (LPARAM
) Console
->Title
.Buffer
);
764 GuiCleanupConsole(PCSRSS_CONSOLE Console
)
766 SendMessageW(NotifyWnd
, PM_DESTROY_CONSOLE
, 0, (LPARAM
) Console
);
769 static CSRSS_CONSOLE_VTBL GuiVtbl
=
781 GuiInitConsole(PCSRSS_CONSOLE Console
)
783 HANDLE GraphicsStartupEvent
;
792 return STATUS_UNSUCCESSFUL
;
796 Console
->Vtbl
= &GuiVtbl
;
797 Console
->Size
.X
= 80;
798 Console
->Size
.Y
= 25;
799 if (NULL
== NotifyWnd
)
801 GraphicsStartupEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
802 if (NULL
== GraphicsStartupEvent
)
804 return STATUS_UNSUCCESSFUL
;
807 ThreadHandle
= CreateThread(NULL
,
810 (PVOID
) &GraphicsStartupEvent
,
813 if (NULL
== ThreadHandle
)
815 NtClose(GraphicsStartupEvent
);
816 DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
817 return STATUS_UNSUCCESSFUL
;
819 CloseHandle(ThreadHandle
);
821 WaitForSingleObject(GraphicsStartupEvent
, INFINITE
);
822 CloseHandle(GraphicsStartupEvent
);
824 if (NULL
== NotifyWnd
)
826 DPRINT1("Win32Csr: Failed to create notification window.\n");
827 return STATUS_UNSUCCESSFUL
;
831 PostMessageW(NotifyWnd
, PM_CREATE_CONSOLE
, 0, (LPARAM
) Console
);
833 return STATUS_SUCCESS
;
837 GuiConsoleCopyRegion(PCSRSS_CONSOLE Console
,
841 LeaveCriticalSection(&(Console
->ActiveBuffer
->Header
.Lock
));
842 SendMessageW(Console
->hWindow
, PM_COPY_REGION
, (WPARAM
) Source
, (LPARAM
) Dest
);
843 EnterCriticalSection(&(Console
->ActiveBuffer
->Header
.Lock
));