00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
#include "precomp.h"
00051
#pragma hdrstop
00052
00053
00054
00055
00056
00057
#ifdef PROFILE_GDI
00058
LONG ScrollDCCount;
00059 LONG ExtTextOutCount;
00060 LONG TextColor=1;
00061
00062
#define SCROLLDC_CALL ScrollDCCount++
00063
#define TEXTOUT_CALL ExtTextOutCount++
00064
#define TEXTCOLOR_CALL TextColor++
00065
#else
00066 #define SCROLLDC_CALL
00067 #define TEXTOUT_CALL
00068 #define TEXTCOLOR_CALL
00069
#endif
00070
00071 #define ITEM_MAX_SIZE 256
00072
00073
00074 typedef struct _PMIconData {
00075 DWORD dwResSize;
00076 DWORD dwVer;
00077 BYTE iResource;
00078 }
PMICONDATA, *
LPPMICONDATA;
00079
00080
00081
00082
00083
00084 int ConsoleFullScreenX;
00085 int ConsoleFullScreenY;
00086 int ConsoleCaptionY;
00087 int MinimumWidthX;
00088 SHORT VerticalScrollSize;
00089 SHORT HorizontalScrollSize;
00090
00091 SHORT VerticalClientToWindow;
00092 SHORT HorizontalClientToWindow;
00093
00094 PCHAR_INFO
ScrollBuffer;
00095 ULONG
ScrollBufferSize;
00096 CRITICAL_SECTION
ScrollBufferLock;
00097
00098
00099
00100
00101
00102 LONG
gnConsoleWindows;
00103
00104 BOOL gfInitSystemMetrics;
00105
00106 BOOL UsePolyTextOut;
00107
00108 HRGN
ghrgnScroll;
00109 LPRGNDATA
gprgnData;
00110
00111 ULONG
gucWheelScrollLines;
00112
00113 UINT guCaretBlinkTime;
00114
00115 #define GRGNDATASIZE (sizeof(RGNDATAHEADER) + (6 * sizeof(RECTL)))
00116
00117
00118 #define CharSizeOf(x) (sizeof(x) / sizeof(*x))
00119 #define LockScrollBuffer() RtlEnterCriticalSection(&ScrollBufferLock)
00120 #define UnlockScrollBuffer() RtlLeaveCriticalSection(&ScrollBufferLock)
00121
00122 #define SetWindowConsole(hWnd, Console) SetWindowLongPtr((hWnd), GWLP_USERDATA, (LONG_PTR)(Console))
00123
00124
#ifdef LATER
00125
#ifndef IS_IME_KBDLAYOUT
00126
#define IS_IME_KBDLAYOUT(hkl) ((((ULONG_PTR)(hkl)) & 0xf0000000) == 0xe0000000)
00127
#endif
00128
#endif
00129
00130
00131
void GetNonBiDiKeyboardLayout(HKL * phklActive);
00132
00133
VOID FreeConsoleBitmap(IN
PSCREEN_INFORMATION ScreenInfo);
00134
00135
VOID
00136
ScrollIfNecessary(
00137 IN
PCONSOLE_INFORMATION Console,
00138 IN
PSCREEN_INFORMATION ScreenInfo
00139 );
00140
00141
VOID
00142
ProcessResizeWindow(
00143 IN
PSCREEN_INFORMATION ScreenInfo,
00144 IN
PCONSOLE_INFORMATION Console,
00145 IN LPWINDOWPOS WindowPos
00146 );
00147
00148
NTSTATUS
00149
AllocateScrollBuffer(
00150 DWORD Size
00151 );
00152
00153
VOID FreeScrollBuffer ( VOID );
00154
00155
VOID
00156
InternalUpdateScrollBars(
00157 IN
PSCREEN_INFORMATION ScreenInfo
00158 );
00159
00160
#if defined(FE_SB)
00161
BOOL
00162 SB_PolyTextOutCandidate(
00163 IN
PSCREEN_INFORMATION ScreenInfo,
00164 IN PSMALL_RECT Region
00165 );
00166
00167
VOID
00168 SB_ConsolePolyTextOut(
00169 IN
PSCREEN_INFORMATION ScreenInfo,
00170 IN PSMALL_RECT Region
00171 );
00172
#endif
00173
00174
00175
00176
VOID
00177 InitializeSystemMetrics( VOID )
00178 {
00179 RECT WindowSize;
00180
00181
gfInitSystemMetrics =
FALSE;
00182
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &
gucWheelScrollLines,
FALSE);
00183
ConsoleFullScreenX =
GetSystemMetrics(SM_CXFULLSCREEN);
00184
ConsoleFullScreenY =
GetSystemMetrics(SM_CYFULLSCREEN);
00185
ConsoleCaptionY =
GetSystemMetrics(SM_CYCAPTION);
00186
VerticalScrollSize = (
SHORT)
GetSystemMetrics(SM_CXVSCROLL);
00187
HorizontalScrollSize = (
SHORT)
GetSystemMetrics(SM_CYHSCROLL);
00188 WindowSize.left = WindowSize.top = 0;
00189 WindowSize.right = WindowSize.bottom = 50;
00190
AdjustWindowRectEx(&WindowSize,
00191
CONSOLE_WINDOW_FLAGS,
00192
FALSE,
00193
CONSOLE_WINDOW_EX_FLAGS
00194 );
00195
VerticalClientToWindow = (
SHORT)(WindowSize.right-WindowSize.left-50);
00196
HorizontalClientToWindow = (
SHORT)(WindowSize.bottom-WindowSize.top-50);
00197
00198
#ifdef LATER
00199
gfIsIMEEnabled = !!
GetSystemMetrics(SM_IMMENABLED);
00200 RIPMSG1(RIP_VERBOSE,
"InitializeSystemMetrics: gfIsIMEEnabled=%d", gfIsIMEEnabled);
00201
#endif
00202
00203
guCaretBlinkTime = GetCaretBlinkTime();
00204 }
00205
00206
VOID
00207 GetWindowLimits(
00208 IN
PSCREEN_INFORMATION ScreenInfo,
00209 OUT
PWINDOW_LIMITS WindowLimits
00210 )
00211 {
00212 HMONITOR hMonitor;
00213 MONITORINFO MonitorInfo = {
sizeof(MonitorInfo)};
00214 COORD FontSize;
00215
00216
00217
00218
00219
00220
00221
if (
gfInitSystemMetrics ||
gnConsoleWindows == 0) {
00222
InitializeSystemMetrics();
00223 }
00224
00225
if (ScreenInfo->Console &&
00226 (ScreenInfo->Console->hWnd || !(ScreenInfo->Console->Flags &
CONSOLE_AUTO_POSITION)) &&
00227 ((hMonitor =
MonitorFromRect(&ScreenInfo->Console->WindowRect, MONITOR_DEFAULTTOPRIMARY)) !=
NULL) &&
00228
GetMonitorInfo(hMonitor, &MonitorInfo)) {
00229 WindowLimits->FullScreenSize.X = (
SHORT)(MonitorInfo.rcWork.right - MonitorInfo.rcWork.left);
00230 WindowLimits->FullScreenSize.Y = (
SHORT)(MonitorInfo.rcWork.bottom - MonitorInfo.rcWork.top -
ConsoleCaptionY);
00231 }
else {
00232 WindowLimits->FullScreenSize.X = (
SHORT)
ConsoleFullScreenX;
00233 WindowLimits->FullScreenSize.Y = (
SHORT)
ConsoleFullScreenY;
00234 }
00235
00236
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
00237 FontSize =
SCR_FONTSIZE(ScreenInfo);
00238 }
else {
00239 FontSize.X = 1;
00240 FontSize.Y = 1;
00241 }
00242
00243 WindowLimits->MinimumWindowSize.X = ((
MinimumWidthX -
VerticalClientToWindow + FontSize.X - 1) / FontSize.X);
00244 WindowLimits->MinimumWindowSize.Y = 1;
00245 WindowLimits->MaximumWindowSize.X =
min(WindowLimits->FullScreenSize.X/FontSize.X, ScreenInfo->ScreenBufferSize.X);
00246 WindowLimits->MaximumWindowSize.X =
max(WindowLimits->MaximumWindowSize.X, WindowLimits->MinimumWindowSize.X);
00247 WindowLimits->MaximumWindowSize.Y =
min(WindowLimits->FullScreenSize.Y/FontSize.Y, ScreenInfo->ScreenBufferSize.Y);
00248 WindowLimits->MaxWindow.X = WindowLimits->MaximumWindowSize.X*FontSize.X +
VerticalClientToWindow;
00249 WindowLimits->MaxWindow.Y = WindowLimits->MaximumWindowSize.Y*FontSize.Y +
HorizontalClientToWindow;
00250 }
00251
00252
VOID
00253 InitializeScreenInfo( VOID )
00254 {
00255 HDC hDC;
00256
00257
InitializeMouseButtons();
00258
MinimumWidthX =
GetSystemMetrics(SM_CXMIN);
00259
00260
InitializeSystemMetrics();
00261
00262 hDC = CreateDCW(
L"DISPLAY",
NULL,
NULL,
NULL);
00263
if (hDC !=
NULL) {
00264
UsePolyTextOut = GetDeviceCaps(hDC,TEXTCAPS) & TC_SCROLLBLT;
00265 DeleteDC(hDC);
00266 }
00267 }
00268
00269
NTSTATUS
00270 DoCreateScreenBuffer(
00271 IN
PCONSOLE_INFORMATION Console,
00272 IN
PCONSOLE_INFO ConsoleInfo
00273 )
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 {
00284 CHAR_INFO Fill,PopupFill;
00285 COORD dwScreenBufferSize, dwWindowSize;
00286
NTSTATUS Status;
00287
int FontIndexWant;
00288
00289
if (ConsoleInfo->dwStartupFlags & STARTF_USESHOWWINDOW) {
00290 Console->wShowWindow = ConsoleInfo->wShowWindow;
00291 }
else {
00292 Console->wShowWindow = SW_SHOWNORMAL;
00293 }
00294
00295
#if 0
00296
{
00297
00298
INT i;
00299
00300
DbgPrint(
"[Link Server Properties for %ws]\n", ConsoleTitle );
00301
DbgPrint(
" wFillAttribute = 0x%04X\n", ConsoleInfo->wFillAttribute );
00302
DbgPrint(
" wPopupFillAttribute = 0x%04X\n", ConsoleInfo->wPopupFillAttribute );
00303
DbgPrint(
" dwScreenBufferSize = (%d , %d)\n", ConsoleInfo->dwScreenBufferSize.X, ConsoleInfo->dwScreenBufferSize.Y );
00304
DbgPrint(
" dwWindowSize = (%d , %d)\n", ConsoleInfo->dwWindowSize.X, ConsoleInfo->dwWindowSize.Y );
00305
DbgPrint(
" dwWindowOrigin = (%d , %d)\n", ConsoleInfo->dwWindowOrigin.X, ConsoleInfo->dwWindowOrigin.Y );
00306
DbgPrint(
" nFont = %d\n", ConsoleInfo->nFont );
00307
DbgPrint(
" nInputBufferSize = %d\n", ConsoleInfo->nInputBufferSize );
00308
DbgPrint(
" dwFontSize = (%d , %d)\n", ConsoleInfo->dwFontSize.X, ConsoleInfo->dwFontSize.Y );
00309
DbgPrint(
" uFontFamily = 0x%08X\n", ConsoleInfo->uFontFamily );
00310
DbgPrint(
" uFontWeight = 0x%08X\n", ConsoleInfo->uFontWeight );
00311
DbgPrint(
" FaceName = %ws\n", ConsoleInfo->FaceName );
00312
DbgPrint(
" uCursorSize = %d\n", ConsoleInfo->uCursorSize );
00313
DbgPrint(
" bFullScreen = %s\n", ConsoleInfo->bFullScreen ?
"TRUE" :
"FALSE" );
00314
DbgPrint(
" bQuickEdit = %s\n", ConsoleInfo->bQuickEdit ?
"TRUE" :
"FALSE" );
00315
DbgPrint(
" bInsertMode = %s\n", ConsoleInfo->bInsertMode ?
"TRUE" :
"FALSE" );
00316
DbgPrint(
" bAutoPosition = %s\n", ConsoleInfo->bAutoPosition ?
"TRUE" :
"FALSE" );
00317
DbgPrint(
" uHistoryBufferSize = %d\n", ConsoleInfo->uHistoryBufferSize );
00318
DbgPrint(
" uNumHistoryBuffers = %d\n", ConsoleInfo->uNumberOfHistoryBuffers );
00319
DbgPrint(
" bHistoryNoDup = %s\n", ConsoleInfo->bHistoryNoDup ?
"TRUE" :
"FALSE" );
00320
DbgPrint(
" ColorTable = [" );
00321 i=0;
00322
while( i < 16 )
00323 {
00324
DbgPrint(
"\n ");
00325
DbgPrint(
"0x%08X ", ConsoleInfo->ColorTable[i++]);
00326
DbgPrint(
"0x%08X ", ConsoleInfo->ColorTable[i++]);
00327
DbgPrint(
"0x%08X ", ConsoleInfo->ColorTable[i++]);
00328
DbgPrint(
"0x%08X ", ConsoleInfo->ColorTable[i++]);
00329 }
00330
DbgPrint(
"]\n\n" );
00331 }
00332
#endif
00333
00334
00335
00336
00337
00338 Fill.Attributes = ConsoleInfo->wFillAttribute;
00339 Fill.Char.UnicodeChar = (WCHAR)
' ';
00340 PopupFill.Attributes = ConsoleInfo->wPopupFillAttribute;
00341 PopupFill.Char.UnicodeChar = (WCHAR)
' ';
00342
00343 dwScreenBufferSize = ConsoleInfo->dwScreenBufferSize;
00344
if (!(ConsoleInfo->dwStartupFlags & STARTF_USECOUNTCHARS)) {
00345
if (Console->Flags &
CONSOLE_NO_WINDOW) {
00346 dwScreenBufferSize.X =
min(dwScreenBufferSize.X, 80);
00347 dwScreenBufferSize.Y =
min(dwScreenBufferSize.Y, 25);
00348 }
00349 }
00350
if (dwScreenBufferSize.X == 0)
00351 dwScreenBufferSize.X = 1;
00352
if (dwScreenBufferSize.Y == 0)
00353 dwScreenBufferSize.Y = 1;
00354
00355
00356
00357
00358
#if defined(FE_SB)
00359
FontIndexWant =
FindCreateFont(ConsoleInfo->uFontFamily,
00360 ConsoleInfo->FaceName,
00361 ConsoleInfo->dwFontSize,
00362 ConsoleInfo->uFontWeight,
00363 ConsoleInfo->uCodePage
00364 );
00365
#else
00366
FontIndexWant =
FindCreateFont(ConsoleInfo->uFontFamily,
00367 ConsoleInfo->FaceName,
00368 ConsoleInfo->dwFontSize,
00369 ConsoleInfo->uFontWeight);
00370
#endif
00371
00372
00373
00374
00375
00376 dwWindowSize = ConsoleInfo->dwWindowSize;
00377
if (ConsoleInfo->dwStartupFlags & STARTF_USESIZE) {
00378 dwWindowSize.X /=
FontInfo[FontIndexWant].
Size.X;
00379 dwWindowSize.Y /=
FontInfo[FontIndexWant].
Size.Y;
00380 }
else if (Console->Flags &
CONSOLE_NO_WINDOW) {
00381 dwWindowSize.X =
min(dwWindowSize.X, 80);
00382 dwWindowSize.Y =
min(dwWindowSize.Y, 25);
00383 }
00384
if (dwWindowSize.X == 0)
00385 dwWindowSize.X = 1;
00386
if (dwWindowSize.Y == 0)
00387 dwWindowSize.Y = 1;
00388
00389
if (dwScreenBufferSize.X < dwWindowSize.X)
00390 dwScreenBufferSize.X = dwWindowSize.X;
00391
if (dwScreenBufferSize.Y < dwWindowSize.Y)
00392 dwScreenBufferSize.Y = dwWindowSize.Y;
00393
00394 Console->dwWindowOriginX = ConsoleInfo->dwWindowOrigin.X;
00395 Console->dwWindowOriginY = ConsoleInfo->dwWindowOrigin.Y;
00396
00397
if (ConsoleInfo->bAutoPosition) {
00398 Console->Flags |=
CONSOLE_AUTO_POSITION;
00399 Console->dwWindowOriginX = CW_USEDEFAULT;
00400 }
else {
00401 Console->WindowRect.left = Console->dwWindowOriginX;
00402 Console->WindowRect.top = Console->dwWindowOriginY;
00403 Console->WindowRect.right = Console->dwWindowOriginX + dwWindowSize.X *
FontInfo[FontIndexWant].
Size.X;
00404 Console->WindowRect.bottom = Console->dwWindowOriginY + dwWindowSize.Y *
FontInfo[FontIndexWant].
Size.Y;
00405 }
00406
00407
#ifdef i386
00408
if (
FullScreenInitialized) {
00409
if (ConsoleInfo->bFullScreen) {
00410 Console->FullScreenFlags = CONSOLE_FULLSCREEN;
00411 }
00412 }
00413
#endif
00414
if (ConsoleInfo->bQuickEdit) {
00415 Console->Flags |=
CONSOLE_QUICK_EDIT_MODE;
00416 }
00417 Console->Flags |=
CONSOLE_USE_PRIVATE_FLAGS;
00418
00419 Console->InsertMode = (ConsoleInfo->bInsertMode !=
FALSE);
00420 Console->CommandHistorySize = (
SHORT)ConsoleInfo->uHistoryBufferSize;
00421 Console->MaxCommandHistories = (
SHORT)ConsoleInfo->uNumberOfHistoryBuffers;
00422
if (ConsoleInfo->bHistoryNoDup) {
00423 Console->Flags |=
CONSOLE_HISTORY_NODUP;
00424 }
else {
00425 Console->Flags &= ~
CONSOLE_HISTORY_NODUP;
00426 }
00427 RtlCopyMemory(Console->ColorTable, ConsoleInfo->ColorTable,
sizeof( Console->ColorTable ));
00428
00429
#if defined(FE_SB)
00430
00431
00432
00433 Console->CP = ConsoleInfo->uCodePage;
00434 Console->OutputCP = ConsoleInfo->uCodePage;
00435
#if 0
00436
if (
CONSOLE_IS_DBCS_ENABLED()){
00437 Console->fIsDBCSCP = !!
IsAvailableFarEastCodePage(Console->CP);
00438 Console->fIsDBCSOutputCP = !!
IsAvailableFarEastCodePage(Console->OutputCP);
00439 }
00440
else {
00441 Console->fIsDBCSCP =
FALSE;
00442 Console->fIsDBCSOutputCP =
FALSE;
00443 }
00444
#else
00445
Console->fIsDBCSCP =
CONSOLE_IS_DBCS_ENABLED() &&
IsAvailableFarEastCodePage(Console->CP);
00446 Console->fIsDBCSOutputCP =
CONSOLE_IS_DBCS_ENABLED() &&
IsAvailableFarEastCodePage(Console->OutputCP);
00447
#endif
00448
#endif
00449
#if defined(FE_IME)
00450
Console->ConsoleIme.ScrollWaitTimeout =
guCaretBlinkTime * 2;
00451
#endif
00452
TryNewSize:
00453
Status =
CreateScreenBuffer(&Console->ScreenBuffers,
00454 dwWindowSize,
00455 FontIndexWant,
00456 dwScreenBufferSize,
00457 Fill,
00458 PopupFill,
00459 Console,
00460
CONSOLE_TEXTMODE_BUFFER,
00461
NULL,
00462
NULL,
00463
NULL,
00464 ConsoleInfo->uCursorSize,
00465 ConsoleInfo->FaceName
00466 );
00467
if (
Status == STATUS_NO_MEMORY) {
00468
00469
00470
00471
if (dwScreenBufferSize.X > 80 || dwScreenBufferSize.Y > 50) {
00472 dwScreenBufferSize.X =
min(dwScreenBufferSize.X, 80);
00473 dwScreenBufferSize.Y =
min(dwScreenBufferSize.Y, 50);
00474 dwWindowSize.X =
min(dwWindowSize.X, dwScreenBufferSize.X);
00475 dwWindowSize.Y =
min(dwWindowSize.Y, dwScreenBufferSize.Y);
00476 Console->Flags |=
CONSOLE_DEFAULT_BUFFER_SIZE;
00477
goto TryNewSize;
00478 }
00479 }
00480
00481
return Status;
00482 }
00483
00484
NTSTATUS
00485 CreateScreenBuffer(
00486 OUT
PSCREEN_INFORMATION *ScreenInformation,
00487 IN COORD dwWindowSize,
00488 IN DWORD nFont,
00489 IN COORD dwScreenBufferSize,
00490 IN CHAR_INFO Fill,
00491 IN CHAR_INFO PopupFill,
00492 IN
PCONSOLE_INFORMATION Console,
00493 IN DWORD Flags,
00494 IN PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo OPTIONAL,
00495 OUT PVOID *lpBitmap OPTIONAL,
00496 OUT HANDLE *hMutex OPTIONAL,
00497 IN UINT CursorSize,
00498 IN LPWSTR FaceName
00499 )
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 {
00524 LONG i,j;
00525
PSCREEN_INFORMATION ScreenInfo;
00526
NTSTATUS Status;
00527 PWCHAR TextRowPtr;
00528
#if defined(FE_SB)
00529
PBYTE AttrRowPtr;
00530
#endif
00531
WINDOW_LIMITS WindowLimits;
00532
00533
DBGPRINT((
"CreateScreenBuffer(\n"
00534
" OUT PSCREEN_INFORMATION = %lx\n"
00535
" dwWindowSize = (%d,%d)\n"
00536
" nFont = %x\n"
00537
" dwScreenBufferSize = (%d,%d)\n"
00538
" Fill\n"
00539
" PopupFill\n",
00540 ScreenInformation,
00541 dwWindowSize.X, dwWindowSize.Y,
00542 nFont,
00543 dwScreenBufferSize.X, dwScreenBufferSize.Y
00544
00545
00546 ));
00547
DBGPRINT((
" PCONSOLE_INFORMATION = %lx\n"
00548
" Flags = %lx\n"
00549
" GraphicsBufferInfo\n"
00550
" lpBitmap\n"
00551
" *hMutex\n"
00552
" ConsoleTitle \"%ls\"\n",
00553 Console,
00554 Flags,
00555
00556
00557
00558 Console->Title));
00559
00560
00561
00562
00563
ASSERT(nFont <
NumberOfFonts);
00564
if (
NumberOfFonts == 0) {
00565
return STATUS_UNSUCCESSFUL;
00566 }
00567
00568
00569
00570
00571
00572 ScreenInfo = (
PSCREEN_INFORMATION)
ConsoleHeapAlloc(
MAKE_TAG(
SCREEN_TAG ),
sizeof(
SCREEN_INFORMATION));
00573
if (ScreenInfo ==
NULL) {
00574
return STATUS_NO_MEMORY;
00575 }
00576 ScreenInfo->
Console = Console;
00577
if ((ScreenInfo->
Flags = Flags) &
CONSOLE_TEXTMODE_BUFFER) {
00578
00579
ASSERT(
FontInfo[nFont].FaceName !=
NULL);
00580
00581 ScreenInfo->
BufferInfo.TextInfo.ListOfTextBufferFont =
NULL;
00582
00583
Status =
StoreTextBufferFontInfo(ScreenInfo,
00584 nFont,
00585
FontInfo[nFont].
Size,
00586
FontInfo[nFont].Family,
00587
FontInfo[nFont].Weight,
00588 FaceName ? FaceName :
FontInfo[nFont].FaceName,
00589 Console->OutputCP);
00590
if (!
NT_SUCCESS(
Status)) {
00591
ConsoleHeapFree(ScreenInfo);
00592
return((ULONG)
Status);
00593 }
00594
00595
DBGFONTS((
"DoCreateScreenBuffer sets FontSize(%d,%d), FontNumber=%x, Family=%x\n",
00596
SCR_FONTSIZE(ScreenInfo).X,
00597
SCR_FONTSIZE(ScreenInfo).Y,
00598
SCR_FONTNUMBER(ScreenInfo),
00599
SCR_FAMILY(ScreenInfo)));
00600
00601
if (
TM_IS_TT_FONT(
FontInfo[nFont].Family)) {
00602 ScreenInfo->
Flags &= ~
CONSOLE_OEMFONT_DISPLAY;
00603 }
else {
00604 ScreenInfo->
Flags |=
CONSOLE_OEMFONT_DISPLAY;
00605 }
00606
00607 ScreenInfo->
ScreenBufferSize = dwScreenBufferSize;
00608
GetWindowLimits(ScreenInfo, &WindowLimits);
00609 dwScreenBufferSize.X =
max(dwScreenBufferSize.X, WindowLimits.
MinimumWindowSize.X);
00610 dwWindowSize.X =
max(dwWindowSize.X, WindowLimits.
MinimumWindowSize.X);
00611
00612 ScreenInfo->
BufferInfo.TextInfo.ModeIndex = (ULONG)-1;
00613
#ifdef i386
00614
if (Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
00615 COORD WindowSize;
00616 ScreenInfo->
BufferInfo.TextInfo.WindowedWindowSize = dwWindowSize;
00617 ScreenInfo->
BufferInfo.TextInfo.WindowedScreenSize = dwScreenBufferSize;
00618 ScreenInfo->
BufferInfo.TextInfo.ModeIndex = MatchWindowSize(Console->OutputCP,dwWindowSize,&WindowSize);
00619 }
00620
#endif
00621
ScreenInfo->
BufferInfo.TextInfo.FirstRow = 0;
00622 ScreenInfo->
BufferInfo.TextInfo.Rows = (
PROW)
ConsoleHeapAlloc(
MAKE_TAG(
SCREEN_TAG ),dwScreenBufferSize.Y *
sizeof(
ROW));
00623
if (ScreenInfo->
BufferInfo.TextInfo.Rows ==
NULL) {
00624
RemoveTextBufferFontInfo(ScreenInfo);
00625
ConsoleHeapFree(ScreenInfo);
00626
return STATUS_NO_MEMORY;
00627 }
00628 ScreenInfo->
BufferInfo.TextInfo.TextRows = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
SCREEN_TAG ),dwScreenBufferSize.X*dwScreenBufferSize.Y*
sizeof(WCHAR));
00629
if (ScreenInfo->
BufferInfo.TextInfo.TextRows ==
NULL) {
00630
ConsoleHeapFree(ScreenInfo->
BufferInfo.TextInfo.Rows);
00631
RemoveTextBufferFontInfo(ScreenInfo);
00632
ConsoleHeapFree(ScreenInfo);
00633
return STATUS_NO_MEMORY;
00634 }
00635
#if defined(FE_SB)
00636
if (!
CreateDbcsScreenBuffer(Console, dwScreenBufferSize,&ScreenInfo->
BufferInfo.TextInfo.DbcsScreenBuffer))
00637 {
00638
ConsoleHeapFree(ScreenInfo->
BufferInfo.TextInfo.TextRows);
00639
ConsoleHeapFree(ScreenInfo->
BufferInfo.TextInfo.Rows);
00640
RemoveTextBufferFontInfo(ScreenInfo);
00641
ConsoleHeapFree(ScreenInfo);
00642
return STATUS_NO_MEMORY;
00643 }
00644
00645 AttrRowPtr=ScreenInfo->
BufferInfo.TextInfo.DbcsScreenBuffer.KAttrRows;
00646
#endif
00647
for (i=0,TextRowPtr=ScreenInfo->
BufferInfo.TextInfo.TextRows;
00648 i<dwScreenBufferSize.Y;
00649 i++,TextRowPtr+=dwScreenBufferSize.X)
00650 {
00651 ScreenInfo->
BufferInfo.TextInfo.Rows[i].CharRow.Left = dwScreenBufferSize.X;
00652 ScreenInfo->
BufferInfo.TextInfo.Rows[i].CharRow.OldLeft =
INVALID_OLD_LENGTH;
00653 ScreenInfo->
BufferInfo.TextInfo.Rows[i].CharRow.Right = 0;
00654 ScreenInfo->
BufferInfo.TextInfo.Rows[i].CharRow.OldRight =
INVALID_OLD_LENGTH;
00655 ScreenInfo->
BufferInfo.TextInfo.Rows[i].CharRow.Chars = TextRowPtr;
00656
#if defined(FE_SB)
00657
ScreenInfo->
BufferInfo.TextInfo.Rows[i].CharRow.KAttrs = AttrRowPtr;
00658
#endif
00659
for (j=0;j<dwScreenBufferSize.X;j++) {
00660 TextRowPtr[j] = (WCHAR)
' ';
00661 }
00662
#if defined(FE_SB)
00663
if (AttrRowPtr) {
00664 RtlZeroMemory(AttrRowPtr, dwScreenBufferSize.X);
00665 AttrRowPtr+=dwScreenBufferSize.X;
00666 }
00667
#endif
00668
ScreenInfo->
BufferInfo.TextInfo.Rows[i].AttrRow.Length = 1;
00669 ScreenInfo->
BufferInfo.TextInfo.Rows[i].AttrRow.AttrPair.Length = dwScreenBufferSize.X;
00670 ScreenInfo->
BufferInfo.TextInfo.Rows[i].AttrRow.AttrPair.Attr = Fill.Attributes;
00671 ScreenInfo->
BufferInfo.TextInfo.Rows[i].AttrRow.Attrs = &ScreenInfo->
BufferInfo.TextInfo.Rows[i].AttrRow.AttrPair;
00672
00673 }
00674 ScreenInfo->
BufferInfo.TextInfo.CursorSize = CursorSize;
00675 ScreenInfo->
BufferInfo.TextInfo.CursorPosition.X = 0;
00676 ScreenInfo->
BufferInfo.TextInfo.CursorPosition.Y = 0;
00677 ScreenInfo->
BufferInfo.TextInfo.CursorMoved =
FALSE;
00678 ScreenInfo->
BufferInfo.TextInfo.CursorVisible =
TRUE;
00679 ScreenInfo->
BufferInfo.TextInfo.CursorOn =
FALSE;
00680 ScreenInfo->
BufferInfo.TextInfo.CursorYSize = (WORD)
CURSOR_SIZE_IN_PIXELS(
SCR_FONTSIZE(ScreenInfo).Y,ScreenInfo->
BufferInfo.TextInfo.CursorSize);
00681 ScreenInfo->
BufferInfo.TextInfo.UpdatingScreen = 0;
00682 ScreenInfo->
BufferInfo.TextInfo.DoubleCursor =
FALSE;
00683 ScreenInfo->
BufferInfo.TextInfo.DelayCursor =
FALSE;
00684 ScreenInfo->
BufferInfo.TextInfo.Flags =
SINGLE_ATTRIBUTES_PER_LINE;
00685 ScreenInfo->
ScreenBufferSize = dwScreenBufferSize;
00686 ScreenInfo->
Window.Left = 0;
00687 ScreenInfo->
Window.Top = 0;
00688 ScreenInfo->
Window.Right = dwWindowSize.X - 1;
00689 ScreenInfo->
Window.Bottom = dwWindowSize.Y - 1;
00690
if (ScreenInfo->
Window.Right >= WindowLimits.
MaximumWindowSize.X) {
00691 ScreenInfo->
Window.Right = WindowLimits.
MaximumWindowSize.X-1;
00692 dwWindowSize.X =
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
00693 }
00694
if (ScreenInfo->
Window.Bottom >= WindowLimits.
MaximumWindowSize.Y) {
00695 ScreenInfo->
Window.Bottom = WindowLimits.
MaximumWindowSize.Y-1;
00696 dwWindowSize.Y =
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
00697 }
00698 ScreenInfo->
WindowMaximizedX = (dwWindowSize.X == dwScreenBufferSize.X);
00699 ScreenInfo->
WindowMaximizedY = (dwWindowSize.Y == dwScreenBufferSize.Y);
00700
#if defined(FE_SB)
00701
#if defined(_X86_)
00702
ScreenInfo->
BufferInfo.TextInfo.MousePosition.X = 0;
00703 ScreenInfo->
BufferInfo.TextInfo.MousePosition.Y = 0;
00704
#endif // i386
00705
00706 ScreenInfo->
BufferInfo.TextInfo.CursorBlink =
TRUE;
00707 ScreenInfo->
BufferInfo.TextInfo.CursorDBEnable =
TRUE;
00708
#endif
00709
00710 }
00711
else {
00712
Status =
CreateConsoleBitmap(GraphicsBufferInfo,
00713 ScreenInfo,
00714 lpBitmap,
00715 hMutex
00716 );
00717
if (!
NT_SUCCESS(
Status)) {
00718
ConsoleHeapFree(ScreenInfo);
00719
return Status;
00720 }
00721 ScreenInfo->
WindowMaximizedX =
TRUE;
00722 ScreenInfo->
WindowMaximizedY =
TRUE;
00723 }
00724
00725 ScreenInfo->
WindowMaximized =
FALSE;
00726 ScreenInfo->
RefCount = 0;
00727 ScreenInfo->
ShareAccess.
OpenCount = 0;
00728 ScreenInfo->
ShareAccess.
Readers = 0;
00729 ScreenInfo->
ShareAccess.
Writers = 0;
00730 ScreenInfo->
ShareAccess.
SharedRead = 0;
00731 ScreenInfo->
ShareAccess.
SharedWrite = 0;
00732 ScreenInfo->
CursorHandle =
ghNormalCursor;
00733 ScreenInfo->
CursorDisplayCount = 0;
00734 ScreenInfo->
CommandIdLow = (
UINT)-1;
00735 ScreenInfo->
CommandIdHigh = (
UINT)-1;
00736 ScreenInfo->
dwUsage = SYSPAL_STATIC;
00737 ScreenInfo->
hPalette =
NULL;
00738
00739 ScreenInfo->
OutputMode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
00740
00741
00742 ScreenInfo->
ResizingWindow = 0;
00743 ScreenInfo->
Next =
NULL;
00744 ScreenInfo->
Attributes = Fill.Attributes;
00745 ScreenInfo->
PopupAttributes = PopupFill.Attributes;
00746
00747 ScreenInfo->
WheelDelta = 0;
00748
00749
#if defined(FE_SB)
00750
ScreenInfo->WriteConsoleDbcsLeadByte[0] = 0;
00751 ScreenInfo->BisectFlag = 0;
00752
if (Flags &
CONSOLE_TEXTMODE_BUFFER) {
00753
SetLineChar(ScreenInfo);
00754 }
00755 ScreenInfo->FillOutDbcsLeadChar = 0;
00756 ScreenInfo->ConvScreenInfo =
NULL;
00757
#endif
00758
00759 *ScreenInformation = ScreenInfo;
00760
DBGOUTPUT((
"SCREEN at %lx\n", ScreenInfo));
00761
return STATUS_SUCCESS;
00762 }
00763
00764
VOID
00765 PositionConsoleWindow(
00766 IN
PCONSOLE_INFORMATION Console,
00767 IN BOOL Initialize
00768 )
00769 {
00770
GetWindowRect(Console->hWnd, &Console->WindowRect);
00771
00772
00773
00774
00775
00776
00777
if (Initialize && (Console->Flags &
CONSOLE_AUTO_POSITION)) {
00778 RECT ClientRect;
00779 LONG dx = 0;
00780 LONG dy = 0;
00781 HMONITOR hMonitor;
00782 MONITORINFO MonitorInfo = {
sizeof(MonitorInfo)};
00783
00784 hMonitor =
MonitorFromRect(&Console->WindowRect, MONITOR_DEFAULTTONULL);
00785
if (hMonitor &&
GetMonitorInfo(hMonitor, &MonitorInfo)) {
00786
GetClientRect(Console->hWnd, &ClientRect);
00787
ClientToScreen(Console->hWnd, (LPPOINT)&ClientRect.left);
00788
ClientToScreen(Console->hWnd, (LPPOINT)&ClientRect.right);
00789
if (Console->WindowRect.right > MonitorInfo.rcWork.right) {
00790 dx =
max(
min((Console->WindowRect.right - MonitorInfo.rcWork.right),
00791 (Console->WindowRect.left - MonitorInfo.rcWork.left)),
00792
min((ClientRect.right - MonitorInfo.rcWork.right),
00793 (ClientRect.left - MonitorInfo.rcWork.left)));
00794 }
00795
if (Console->WindowRect.bottom > MonitorInfo.rcWork.bottom) {
00796 dy =
max(
min((Console->WindowRect.bottom - MonitorInfo.rcWork.bottom),
00797 (Console->WindowRect.top - MonitorInfo.rcWork.top)),
00798
min((ClientRect.bottom - MonitorInfo.rcWork.bottom),
00799 (ClientRect.top - MonitorInfo.rcWork.top)));
00800 }
00801
if (dx || dy) {
00802
SetWindowPos(Console->hWnd,
00803
NULL,
00804 Console->WindowRect.left - dx,
00805 Console->WindowRect.top - dy,
00806 0,
00807 0,
00808 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
00809 }
00810 }
00811 }
00812 }
00813
00814
00815
00816
00817
00818
00819
00820
NTSTATUS
00821 ConsoleSetActiveWindow(
00822 IN
PCONSOLE_INFORMATION Console
00823 )
00824 {
00825 HWND
hWnd = Console->hWnd;
00826 HANDLE ConsoleHandle = Console->ConsoleHandle;
00827
00828
UnlockConsole(Console);
00829 SetActiveWindow(
hWnd);
00830
return RevalidateConsole(ConsoleHandle, &Console);
00831 }
00832
00833
NTSTATUS
00834 CreateWindowsWindow(
00835 IN
PCONSOLE_INFORMATION Console
00836 )
00837 {
00838
PSCREEN_INFORMATION ScreenInfo;
00839 SIZE WindowSize;
00840
DWORD Style;
00841 THREAD_BASIC_INFORMATION ThreadInfo;
00842 HWND
hWnd;
00843
00844 ScreenInfo = Console->ScreenBuffers;
00845
00846
00847
00848
00849
00850
00851
ASSERT(ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER);
00852 WindowSize.cx =
CONSOLE_WINDOW_SIZE_X(ScreenInfo)*
SCR_FONTSIZE(ScreenInfo).X +
VerticalClientToWindow;
00853 WindowSize.cy =
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)*
SCR_FONTSIZE(ScreenInfo).Y +
HorizontalClientToWindow;
00854 Style =
CONSOLE_WINDOW_FLAGS & ~WS_VISIBLE;
00855
if (!ScreenInfo->
WindowMaximizedX) {
00856 WindowSize.cy +=
HorizontalScrollSize;
00857 }
else {
00858 Style &= ~WS_HSCROLL;
00859 }
00860
if (!ScreenInfo->
WindowMaximizedY) {
00861 WindowSize.cx +=
VerticalScrollSize;
00862 }
else {
00863 Style &= ~WS_VSCROLL;
00864 }
00865
#ifdef THERESES_DEBUG
00866
DbgPrint(
"creating window with char size %d %d\n",
CONSOLE_WINDOW_SIZE_X(ScreenInfo),
CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
00867
DbgPrint(
" pixel size %d %d\n",WindowSize.cx,WindowSize.cy);
00868
#endif
00869
00870
00871
00872
00873
00874 Console->WindowRect.left = Console->dwWindowOriginX;
00875 Console->WindowRect.top = Console->dwWindowOriginY;
00876 Console->WindowRect.right = WindowSize.cx + Console->dwWindowOriginX;
00877 Console->WindowRect.bottom = WindowSize.cy + Console->dwWindowOriginY;
00878
hWnd =
CreateWindowEx(
CONSOLE_WINDOW_EX_FLAGS,
00879
CONSOLE_WINDOW_CLASS,
00880 Console->Title,
00881 Style,
00882 Console->dwWindowOriginX,
00883 Console->dwWindowOriginY,
00884 WindowSize.cx,
00885 WindowSize.cy,
00886 (Console->Flags &
CONSOLE_NO_WINDOW) ? HWND_MESSAGE : HWND_DESKTOP,
00887
NULL,
00888
ghInstance,
00889
NULL);
00890
if (
hWnd ==
NULL) {
00891
NtSetEvent(Console->InitEvents[
INITIALIZATION_FAILED],
NULL);
00892
return STATUS_NO_MEMORY;
00893 }
00894 Console->hWnd =
hWnd;
00895
00896
SetWindowConsole(
hWnd, Console);
00897
00898
00899
00900
00901
00902
if (
NT_SUCCESS(
NtQueryInformationThread(Console->ClientThreadHandle,
00903 ThreadBasicInformation, &ThreadInfo,
00904
sizeof(ThreadInfo),
NULL))) {
00905
00906
SetConsolePid(Console->hWnd, HandleToUlong(ThreadInfo.ClientId.UniqueProcess));
00907
SetConsoleTid(Console->hWnd, HandleToUlong(ThreadInfo.ClientId.UniqueThread));
00908 }
00909
00910
00911
00912
00913
00914 Console->hDC =
GetDC(Console->hWnd);
00915
00916
if (Console->hDC ==
NULL) {
00917
NtSetEvent(Console->InitEvents[
INITIALIZATION_FAILED],
NULL);
00918
DestroyWindow(Console->hWnd);
00919 Console->hWnd =
NULL;
00920
return STATUS_NO_MEMORY;
00921 }
00922 Console->hMenu = GetSystemMenu(Console->hWnd,
FALSE);
00923
00924
00925
00926
00927
00928
InitSystemMenu(Console);
00929
00930
gnConsoleWindows++;
00931 Console->InputThreadInfo->WindowCount++;
00932
00933
#if defined(FE_IME)
00934
SetUndetermineAttribute(Console);
00935
#endif
00936
#if defined(FE_SB)
00937
RegisterKeisenOfTTFont(ScreenInfo);
00938
#endif
00939
00940
00941
00942
00943
if ((Console->dwHotKey != 0) && !(Console->Flags &
CONSOLE_NO_WINDOW)) {
00944
SendMessage(Console->hWnd, WM_SETHOTKEY, Console->dwHotKey, 0
L);
00945 }
00946
00947
00948
00949
00950
00951
if (Console->iIconId) {
00952
00953
00954
00955
PostMessage(HWND_BROADCAST,
00956
ProgmanHandleMessage,
00957 (WPARAM)Console->hWnd,
00958 1);
00959 }
00960
if (Console->hIcon ==
NULL) {
00961 Console->hIcon =
ghDefaultIcon;
00962 Console->hSmIcon =
ghDefaultSmIcon;
00963 }
else if (Console->hIcon !=
ghDefaultIcon) {
00964
SendMessage(Console->hWnd, WM_SETICON, ICON_BIG, (LPARAM)Console->hIcon);
00965
SendMessage(Console->hWnd, WM_SETICON, ICON_SMALL, (LPARAM)Console->hSmIcon);
00966 }
00967
00968 SetBkMode(Console->hDC,OPAQUE);
00969
SetFont(ScreenInfo);
00970 SelectObject(Console->hDC, GetStockObject(DC_BRUSH));
00971
SetScreenColors(ScreenInfo, ScreenInfo->
Attributes,
00972 ScreenInfo->
PopupAttributes,
FALSE);
00973
if (Console->Flags &
CONSOLE_NO_WINDOW) {
00974 ShowWindowAsync(Console->hWnd, SW_HIDE);
00975
#ifdef i386
00976
}
else if (Console->FullScreenFlags != 0) {
00977
if (Console->wShowWindow == SW_SHOWMINNOACTIVE) {
00978 ShowWindowAsync(Console->hWnd, Console->wShowWindow);
00979 Console->FullScreenFlags = 0;
00980 Console->Flags |=
CONSOLE_IS_ICONIC;
00981 }
else {
00982
ConvertToFullScreen(Console);
00983
if (!
NT_SUCCESS(
ConsoleSetActiveWindow(Console))) {
00984
return STATUS_INVALID_HANDLE;
00985 }
00986
00987
ChangeDispSettings(Console, Console->hWnd,CDS_FULLSCREEN);
00988 }
00989
#endif
00990
}
else {
00991
if (Console->wShowWindow != SW_SHOWNOACTIVATE &&
00992 Console->wShowWindow != SW_SHOWMINNOACTIVE &&
00993 Console->wShowWindow != SW_HIDE) {
00994
if (!
NT_SUCCESS(
ConsoleSetActiveWindow(Console))) {
00995
return STATUS_INVALID_HANDLE;
00996 }
00997 }
else if (Console->wShowWindow == SW_SHOWMINNOACTIVE) {
00998 Console->Flags |=
CONSOLE_IS_ICONIC;
00999 }
01000 ShowWindowAsync(Console->hWnd, Console->wShowWindow);
01001 }
01002
01003
01004
InternalUpdateScrollBars(ScreenInfo);
01005
if (!(Console->Flags &
CONSOLE_IS_ICONIC) &&
01006 (Console->FullScreenFlags == 0) ) {
01007
01008
PositionConsoleWindow(Console,
TRUE);
01009 }
01010
01011
#if defined(FE_IME)
01012
if (
CONSOLE_IS_IME_ENABLED() && !(Console->Flags &
CONSOLE_NO_WINDOW)) {
01013
SetTimer(Console->hWnd, SCROLL_WAIT_TIMER,
guCaretBlinkTime,
NULL);
01014 }
01015
#endif
01016
NtSetEvent(Console->InitEvents[
INITIALIZATION_SUCCEEDED],
NULL);
01017
return STATUS_SUCCESS;
01018 }
01019
01020
NTSTATUS
01021 FreeScreenBuffer(
01022 IN
PSCREEN_INFORMATION ScreenInfo
01023 )
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 {
01042
SHORT i;
01043
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
01044
01045
ASSERT(ScreenInfo->RefCount == 0);
01046
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
01047
for (i=0;i<ScreenInfo->ScreenBufferSize.Y;i++) {
01048
if (ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Length > 1) {
01049
ConsoleHeapFree(ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs);
01050 }
01051 }
01052
ConsoleHeapFree(ScreenInfo->BufferInfo.TextInfo.TextRows);
01053
ConsoleHeapFree(ScreenInfo->BufferInfo.TextInfo.Rows);
01054
#if defined(FE_SB)
01055
DeleteDbcsScreenBuffer(&ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer);
01056
#endif
01057
RemoveTextBufferFontInfo(ScreenInfo);
01058 }
else {
01059
if (ScreenInfo->hPalette !=
NULL) {
01060
if (GetCurrentObject(Console->
hDC, OBJ_PAL) == ScreenInfo->hPalette) {
01061
SelectPalette(Console->
hDC, Console->
hSysPalette,
FALSE);
01062 }
01063 DeleteObject(ScreenInfo->hPalette);
01064 }
01065
FreeConsoleBitmap(ScreenInfo);
01066 }
01067
ConsoleHeapFree(ScreenInfo);
01068
return STATUS_SUCCESS;
01069 }
01070
01071
VOID
01072 FindAttrIndex(
01073 IN
PATTR_PAIR String,
01074 IN SHORT Index,
01075 OUT
PATTR_PAIR *IndexedAttr,
01076 OUT PSHORT CountOfAttr
01077 )
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103 {
01104
SHORT i;
01105
01106
for (i=0;i<
Index;) {
01107 i +=
String->Length;
01108
String++;
01109 }
01110
01111
if (i>
Index) {
01112
String--;
01113 *CountOfAttr = i-
Index;
01114 }
01115
else {
01116 *CountOfAttr =
String->Length;
01117 }
01118 *IndexedAttr =
String;
01119 }
01120
01121
01122
01123
NTSTATUS
01124 MergeAttrStrings(
01125 IN
PATTR_PAIR Source,
01126 IN WORD SourceLength,
01127 IN
PATTR_PAIR Merge,
01128 IN WORD MergeLength,
01129 OUT
PATTR_PAIR *Target,
01130 OUT LPWORD TargetLength,
01131 IN SHORT StartIndex,
01132 IN SHORT EndIndex,
01133 IN
PROW Row,
01134 IN
PSCREEN_INFORMATION ScreenInfo
01135 )
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173 {
01174
PATTR_PAIR SrcAttr,TargetAttr,SrcEnd;
01175
PATTR_PAIR NewString;
01176
SHORT i;
01177
#if THERESES_DEBUG2
01178
#if DBG
01179
WORD AllocLength;
01180
01181 AllocLength = MergeLength + SourceLength + 1;
01182
#endif
01183
#endif
01184
01185
01186
01187
01188
01189
if (MergeLength == 1 && Row->AttrRow.Length == 1) {
01190
if (Row->AttrRow.Attrs->Attr ==
Merge->Attr) {
01191 *TargetLength = 1;
01192 *Target = &Row->AttrRow.AttrPair;
01193
return STATUS_SUCCESS;
01194 }
01195
if (StartIndex == 0 && EndIndex == (
SHORT)(ScreenInfo->ScreenBufferSize.X-1)) {
01196 NewString = &Row->AttrRow.AttrPair;
01197 NewString->
Attr =
Merge->Attr;
01198 *TargetLength = 1;
01199 *Target = NewString;
01200
return STATUS_SUCCESS;
01201 }
01202 }
01203
01204 NewString = (
PATTR_PAIR)
ConsoleHeapAlloc(
MAKE_TAG(
SCREEN_TAG ),(SourceLength+MergeLength+1)*
sizeof(
ATTR_PAIR));
01205
if (NewString ==
NULL) {
01206
return STATUS_NO_MEMORY;
01207 }
01208
01209
01210
01211
01212
01213 SrcAttr = Source;
01214 SrcEnd = Source + SourceLength;
01215 TargetAttr = NewString;
01216 i=0;
01217
if (StartIndex != 0) {
01218
while (i<StartIndex) {
01219 i += SrcAttr->
Length;
01220 *TargetAttr++ = *SrcAttr++;
01221 }
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232 TargetAttr--;
01233
if (i>StartIndex) {
01234 TargetAttr->
Length -= i-StartIndex;
01235 }
01236
if (
Merge->Attr == TargetAttr->
Attr) {
01237 TargetAttr->
Length +=
Merge->Length;
01238 MergeLength-=1;
01239
Merge++;
01240 }
01241 TargetAttr++;
01242 }
01243
01244
01245
01246
01247
01248 RtlCopyMemory(TargetAttr,
Merge,MergeLength*
sizeof(
ATTR_PAIR));
01249 TargetAttr += MergeLength;
01250
01251
01252
01253
01254
01255
while (i<=EndIndex) {
01256
ASSERT(SrcAttr != SrcEnd);
01257 i += SrcAttr->
Length;
01258 SrcAttr++;
01259 }
01260
01261
01262
01263
01264
01265
if (SrcAttr != SrcEnd || i!=(
SHORT)(EndIndex+1)) {
01266
01267
01268
01269
01270
01271
01272 TargetAttr--;
01273
if (i>(
SHORT)(EndIndex+1)) {
01274 SrcAttr--;
01275
if (TargetAttr->
Attr == SrcAttr->
Attr) {
01276 TargetAttr->
Length += i-(EndIndex+1);
01277 }
else {
01278 TargetAttr++;
01279 TargetAttr->
Attr = SrcAttr->
Attr;
01280 TargetAttr->
Length = (
SHORT)(i-(EndIndex+1));
01281 }
01282 SrcAttr++;
01283 }
01284
01285
01286
01287
01288
01289
else if (TargetAttr->
Attr == SrcAttr->
Attr) {
01290 TargetAttr->
Length += SrcAttr->
Length;
01291 i += SrcAttr->
Length;
01292 SrcAttr++;
01293 }
01294 TargetAttr++;
01295
01296
01297
01298
01299
01300
if (SrcAttr < SrcEnd) {
01301 RtlCopyMemory(TargetAttr,SrcAttr,(SrcEnd-SrcAttr)*
sizeof(
ATTR_PAIR));
01302 TargetAttr += SrcEnd - SrcAttr;
01303 }
01304 }
01305
01306 *TargetLength = (WORD)(TargetAttr - NewString);
01307
#if THERESES_DEBUG2
01308
#if DBG
01309
{
SHORT j;
01310 WORD i;
01311
PATTR_PAIR NewAttr;
01312 PULONG Foo;
01313 j=0;
01314 NewAttr = NewString;
01315
for (i=0;i<*TargetLength;i++) {
01316 j+=NewAttr->
Length;
01317 NewAttr++;
01318 }
01319
ASSERT (j == ScreenInfo->ScreenBufferSize.X);
01320
if (j != ScreenInfo->ScreenBufferSize.X) {
01321
DbgPrint(
"new length is %d\n",*TargetLength);
01322
DbgPrint(
"address of new attr string is %lx\n",NewString);
01323 }
01324
ASSERT (*TargetLength <= AllocLength);
01325 Foo = (PULONG)(NewString-4);
01326
ASSERT (*Foo & 1);
01327 Foo = (PULONG)(NewString-3);
01328
ASSERT (*Foo >= (*TargetLength *
sizeof(
ATTR_PAIR)) + 16);
01329 }
01330
#endif
01331
#endif
01332
*Target = NewString;
01333
if (*TargetLength == 1) {
01334 *Target = &Row->AttrRow.AttrPair;
01335 **Target = *NewString;
01336
ConsoleHeapFree(NewString);
01337 }
01338
return STATUS_SUCCESS;
01339 }
01340
01341
VOID
01342 ResetTextFlags(
01343 IN
PSCREEN_INFORMATION ScreenInfo,
01344 IN SHORT StartY,
01345 IN SHORT EndY
01346 )
01347
01348
01349
01350
01351
01352
01353
01354
01355 {
01356
SHORT RowIndex;
01357
PROW Row;
01358
SHORT i;
01359
01360
01361
01362
01363
01364
01365
01366 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+StartY) % ScreenInfo->ScreenBufferSize.Y;
01367
for (i=StartY;i<=EndY;i++) {
01368 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01369
if (Row->
AttrRow.
Length != 1) {
01370 ScreenInfo->BufferInfo.TextInfo.Flags &= ~
SINGLE_ATTRIBUTES_PER_LINE;
01371
return;
01372 }
01373
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01374 RowIndex = 0;
01375 }
01376 }
01377
01378
01379
01380
if (ScreenInfo->BufferInfo.TextInfo.Flags &
SINGLE_ATTRIBUTES_PER_LINE) {
01381
return;
01382 }
01383
01384
if (StartY == 0 && EndY == (ScreenInfo->ScreenBufferSize.Y-1)) {
01385 ScreenInfo->BufferInfo.TextInfo.Flags |=
SINGLE_ATTRIBUTES_PER_LINE;
01386
return;
01387 }
01388
01389 RowIndex = ScreenInfo->BufferInfo.TextInfo.FirstRow;
01390
for (i=0;i<StartY;i++) {
01391 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01392
if (Row->
AttrRow.
Length != 1) {
01393
return;
01394 }
01395
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01396 RowIndex = 0;
01397 }
01398 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01399 }
01400 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+EndY+1) % ScreenInfo->ScreenBufferSize.Y;
01401
for (i=EndY+1;i<ScreenInfo->ScreenBufferSize.Y;i++) {
01402 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01403
if (Row->
AttrRow.
Length != 1) {
01404
return;
01405 }
01406
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01407 RowIndex = 0;
01408 }
01409 }
01410 ScreenInfo->BufferInfo.TextInfo.Flags |=
SINGLE_ATTRIBUTES_PER_LINE;
01411 }
01412
01413
01414
VOID
01415 ReadRectFromScreenBuffer(
01416 IN
PSCREEN_INFORMATION ScreenInfo,
01417 IN COORD SourcePoint,
01418 IN PCHAR_INFO Target,
01419 IN COORD TargetSize,
01420 IN PSMALL_RECT TargetRect
01421 )
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448 {
01449
01450 PCHAR_INFO TargetPtr;
01451
SHORT i,j,k;
01452
SHORT XSize,YSize;
01453 BOOLEAN WholeTarget;
01454
SHORT RowIndex;
01455
PROW Row;
01456 PWCHAR Char;
01457
PATTR_PAIR Attr;
01458
SHORT CountOfAttr;
01459
01460
DBGOUTPUT((
"ReadRectFromScreenBuffer\n"));
01461
01462 XSize = (
SHORT)(TargetRect->Right - TargetRect->Left + 1);
01463 YSize = (
SHORT)(TargetRect->Bottom - TargetRect->Top + 1);
01464
01465 TargetPtr = Target;
01466 WholeTarget =
FALSE;
01467
if (XSize == TargetSize.X) {
01468
ASSERT (TargetRect->Left == 0);
01469
if (TargetRect->Top != 0) {
01470 TargetPtr = (PCHAR_INFO)
01471 ((
PBYTE)Target +
SCREEN_BUFFER_POINTER(TargetRect->Left,
01472 TargetRect->Top,
01473 TargetSize.X,
01474
sizeof(CHAR_INFO)));
01475 }
01476 WholeTarget =
TRUE;
01477 }
01478 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+SourcePoint.Y) % ScreenInfo->ScreenBufferSize.Y;
01479
for (i=0;i<YSize;i++) {
01480
if (!WholeTarget) {
01481 TargetPtr = (PCHAR_INFO)
01482 ((
PBYTE)Target +
SCREEN_BUFFER_POINTER(TargetRect->Left,
01483 TargetRect->Top+i,
01484 TargetSize.X,
01485
sizeof(CHAR_INFO)));
01486 }
01487
01488
01489
01490
01491
01492 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01493 Char = &Row->
CharRow.
Chars[SourcePoint.X];
01494
FindAttrIndex(Row->
AttrRow.
Attrs,
01495 SourcePoint.X,
01496 &Attr,
01497 &CountOfAttr
01498 );
01499 k=0;
01500
#if defined(FE_SB)
01501
if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console)) {
01502
PBYTE AttrP = &Row->
CharRow.KAttrs[SourcePoint.X];
01503
for (j=0;j<XSize;TargetPtr++) {
01504
BYTE AttrR;
01505 AttrR = *AttrP++;
01506
if (j==0 && AttrR & ATTR_TRAILING_BYTE)
01507 {
01508 TargetPtr->Char.UnicodeChar =
UNICODE_SPACE;
01509 AttrR = 0;
01510 }
01511
else if (j+1 >= XSize && AttrR & ATTR_LEADING_BYTE)
01512 {
01513 TargetPtr->Char.UnicodeChar =
UNICODE_SPACE;
01514 AttrR = 0;
01515 }
01516
else
01517 TargetPtr->Char.UnicodeChar = *Char;
01518 Char++;
01519 TargetPtr->Attributes = Attr->
Attr | (WCHAR)(AttrR & ATTR_DBCSSBCS_BYTE) << 8;
01520 j+=1;
01521
if (++k==CountOfAttr && j<XSize) {
01522 Attr++;
01523 k=0;
01524 CountOfAttr = Attr->
Length;
01525 }
01526 }
01527 }
01528
else{
01529
#endif
01530
for (j=0;j<XSize;TargetPtr++) {
01531 TargetPtr->Char.UnicodeChar = *Char++;
01532 TargetPtr->Attributes = Attr->
Attr;
01533 j+=1;
01534
if (++k==CountOfAttr && j<XSize) {
01535 Attr++;
01536 k=0;
01537 CountOfAttr = Attr->
Length;
01538 }
01539 }
01540
#if defined(FE_SB)
01541
}
01542
#endif
01543
01544
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01545 RowIndex = 0;
01546 }
01547 }
01548 }
01549
01550
VOID
01551 CopyRectangle(
01552 IN
PSCREEN_INFORMATION ScreenInfo,
01553 IN PSMALL_RECT SourceRect,
01554 IN COORD TargetPoint
01555 )
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578 {
01579 SMALL_RECT Target;
01580 COORD SourcePoint;
01581 COORD
Size;
01582
DBGOUTPUT((
"CopyRectangle\n"));
01583
01584
01585
LockScrollBuffer();
01586
01587 SourcePoint.X = SourceRect->Left;
01588 SourcePoint.Y = SourceRect->Top;
01589 Target.Left = 0;
01590 Target.Top = 0;
01591 Target.Right =
Size.X = SourceRect->Right - SourceRect->Left;
01592 Target.Bottom =
Size.Y = SourceRect->Bottom - SourceRect->Top;
01593
Size.X++;
01594
Size.Y++;
01595
01596
if (
ScrollBufferSize < (
Size.X *
Size.Y *
sizeof(CHAR_INFO))) {
01597
FreeScrollBuffer();
01598
if (!
NT_SUCCESS(
AllocateScrollBuffer(
Size.X *
Size.Y *
sizeof(CHAR_INFO)))) {
01599
UnlockScrollBuffer();
01600
return;
01601 }
01602 }
01603
01604
ReadRectFromScreenBuffer(ScreenInfo,
01605 SourcePoint,
01606
ScrollBuffer,
01607
Size,
01608 &Target
01609 );
01610
01611
WriteRectToScreenBuffer((
PBYTE)
ScrollBuffer,
01612
Size,
01613 &Target,
01614 ScreenInfo,
01615 TargetPoint,
01616 0xFFFFFFFF
01617 );
01618
UnlockScrollBuffer();
01619 }
01620
01621
01622
NTSTATUS
01623 ReadScreenBuffer(
01624 IN
PSCREEN_INFORMATION ScreenInformation,
01625 OUT PCHAR_INFO Buffer,
01626 IN OUT PSMALL_RECT ReadRegion
01627 )
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649 {
01650 COORD TargetSize;
01651 COORD TargetPoint,SourcePoint;
01652 SMALL_RECT Target;
01653
01654
DBGOUTPUT((
"ReadScreenBuffer\n"));
01655
01656
01657
01658
01659
01660 TargetSize.X = (
SHORT)(ReadRegion->Right - ReadRegion->Left + 1);
01661 TargetSize.Y = (
SHORT)(ReadRegion->Bottom - ReadRegion->Top + 1);
01662
01663
if (TargetSize.X <= 0 || TargetSize.Y <= 0) {
01664
return STATUS_SUCCESS;
01665 }
01666
01667
01668
01669
if (ReadRegion->Right > (
SHORT)(ScreenInformation->ScreenBufferSize.X-1)) {
01670 ReadRegion->Right = (
SHORT)(ScreenInformation->ScreenBufferSize.X-1);
01671 }
01672
if (ReadRegion->Bottom > (
SHORT)(ScreenInformation->ScreenBufferSize.Y-1)) {
01673 ReadRegion->Bottom = (
SHORT)(ScreenInformation->ScreenBufferSize.Y-1);
01674 }
01675
if (ReadRegion->Left < 0) {
01676 TargetPoint.X = -ReadRegion->Left;
01677 ReadRegion->Left = 0;
01678 }
01679
else {
01680 TargetPoint.X = 0;
01681 }
01682
if (ReadRegion->Top < 0) {
01683 TargetPoint.Y = -ReadRegion->Top;
01684 ReadRegion->Top = 0;
01685 }
01686
else {
01687 TargetPoint.Y = 0;
01688 }
01689
01690 SourcePoint.X = ReadRegion->Left;
01691 SourcePoint.Y = ReadRegion->Top;
01692 Target.Left = TargetPoint.X;
01693 Target.Top = TargetPoint.Y;
01694 Target.Right = TargetPoint.X + (ReadRegion->Right - ReadRegion->Left);
01695 Target.Bottom = TargetPoint.Y + (ReadRegion->Bottom - ReadRegion->Top);
01696
ReadRectFromScreenBuffer(ScreenInformation,
01697 SourcePoint,
01698
Buffer,
01699 TargetSize,
01700 &Target
01701 );
01702
return STATUS_SUCCESS;
01703 }
01704
01705
NTSTATUS
01706 WriteScreenBuffer(
01707 IN
PSCREEN_INFORMATION ScreenInformation,
01708 IN PCHAR_INFO Buffer,
01709 IN OUT PSMALL_RECT WriteRegion
01710 )
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734 {
01735 COORD SourceSize;
01736 COORD TargetPoint;
01737 SMALL_RECT SourceRect;
01738
01739
DBGOUTPUT((
"WriteScreenBuffer\n"));
01740
01741
01742
01743
01744
01745 SourceSize.X = (
SHORT)(WriteRegion->Right - WriteRegion->Left + 1);
01746 SourceSize.Y = (
SHORT)(WriteRegion->Bottom - WriteRegion->Top + 1);
01747
if (SourceSize.X <= 0 || SourceSize.Y <= 0) {
01748
return STATUS_SUCCESS;
01749 }
01750
01751
01752
01753
if (WriteRegion->Left >= ScreenInformation->ScreenBufferSize.X ||
01754 WriteRegion->Top >= ScreenInformation->ScreenBufferSize.Y) {
01755
return STATUS_SUCCESS;
01756 }
01757
01758
if (WriteRegion->Right > (
SHORT)(ScreenInformation->ScreenBufferSize.X-1))
01759 WriteRegion->Right = (
SHORT)(ScreenInformation->ScreenBufferSize.X-1);
01760 SourceRect.Right = WriteRegion->Right - WriteRegion->Left;
01761
if (WriteRegion->Bottom > (
SHORT)(ScreenInformation->ScreenBufferSize.Y-1))
01762 WriteRegion->Bottom = (
SHORT)(ScreenInformation->ScreenBufferSize.Y-1);
01763 SourceRect.Bottom = WriteRegion->Bottom - WriteRegion->Top;
01764
if (WriteRegion->Left < 0) {
01765 SourceRect.Left = -WriteRegion->Left;
01766 WriteRegion->Left = 0;
01767 }
01768
else {
01769 SourceRect.Left = 0;
01770 }
01771
if (WriteRegion->Top < 0) {
01772 SourceRect.Top = -WriteRegion->Top;
01773 WriteRegion->Top = 0;
01774 }
01775
else {
01776 SourceRect.Top = 0;
01777 }
01778
01779 TargetPoint.X = WriteRegion->Left;
01780 TargetPoint.Y = WriteRegion->Top;
01781
WriteRectToScreenBuffer((
PBYTE)
Buffer,
01782 SourceSize,
01783 &SourceRect,
01784 ScreenInformation,
01785 TargetPoint,
01786 0xFFFFFFFF
01787 );
01788
return STATUS_SUCCESS;
01789 }
01790
01791
01792
01793
01794
NTSTATUS
01795 ReadOutputString(
01796 IN
PSCREEN_INFORMATION ScreenInfo,
01797 OUT PVOID Buffer,
01798 IN COORD ReadCoord,
01799 IN ULONG StringType,
01800 IN OUT PULONG NumRecords
01801 )
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833 {
01834 ULONG NumRead;
01835
SHORT X,Y;
01836
SHORT RowIndex;
01837
SHORT CountOfAttr;
01838
PATTR_PAIR Attr;
01839
PROW Row;
01840 PWCHAR Char;
01841
SHORT j,k;
01842 PWCHAR TransBuffer =
NULL;
01843 PWCHAR BufPtr;
01844
#if defined(FE_SB)
01845
PBYTE AttrP;
01846
PBYTE TransBufferA,BufPtrA;
01847
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
01848
#endif
01849
01850
DBGOUTPUT((
"ReadOutputString\n"));
01851
if (*NumRecords == 0)
01852
return STATUS_SUCCESS;
01853 NumRead = 0;
01854 X=ReadCoord.X;
01855 Y=ReadCoord.Y;
01856
if (X>=ScreenInfo->ScreenBufferSize.X ||
01857 X<0 ||
01858 Y>=ScreenInfo->ScreenBufferSize.Y ||
01859 Y<0) {
01860 *NumRecords = 0;
01861
return STATUS_SUCCESS;
01862 }
01863
01864 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+ReadCoord.Y) % ScreenInfo->ScreenBufferSize.Y;
01865
01866
if (StringType ==
CONSOLE_ASCII) {
01867 TransBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),*NumRecords *
sizeof(WCHAR));
01868
if (TransBuffer ==
NULL) {
01869
return STATUS_NO_MEMORY;
01870 }
01871 BufPtr = TransBuffer;
01872 }
else {
01873 BufPtr =
Buffer;
01874 }
01875
01876
#if defined(FE_SB)
01877
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
01878 {
01879 TransBufferA = (
PBYTE)
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),*NumRecords *
sizeof(
BYTE));
01880
if (TransBufferA ==
NULL) {
01881
if (TransBuffer !=
NULL)
01882
ConsoleHeapFree(TransBuffer);
01883
return STATUS_NO_MEMORY;
01884 }
01885 BufPtrA = TransBufferA;
01886 }
01887
#endif
01888
if ((StringType ==
CONSOLE_ASCII) ||
01889 (StringType ==
CONSOLE_REAL_UNICODE) ||
01890 (StringType ==
CONSOLE_FALSE_UNICODE)) {
01891
while (NumRead < *NumRecords) {
01892
01893
01894
01895
01896
01897 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01898 Char = &Row->
CharRow.
Chars[X];
01899
#if defined(FE_SB)
01900
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
01901 AttrP = &Row->
CharRow.KAttrs[X];
01902
#endif
01903
if ((ULONG)(ScreenInfo->ScreenBufferSize.X - X) > (*NumRecords - NumRead)) {
01904 RtlCopyMemory(BufPtr,Char,(*NumRecords - NumRead) *
sizeof(WCHAR));
01905
#if defined(FE_SB)
01906
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
01907 RtlCopyMemory(BufPtrA,AttrP,(*NumRecords - NumRead) *
sizeof(
CHAR));
01908
#endif
01909
NumRead += *NumRecords - NumRead;
01910
break;
01911 }
01912 RtlCopyMemory(BufPtr,Char,(ScreenInfo->ScreenBufferSize.X - X) *
sizeof(WCHAR));
01913 BufPtr = (PVOID)((
PBYTE)BufPtr + ((ScreenInfo->ScreenBufferSize.X - X) *
sizeof(WCHAR)));
01914
#if defined(FE_SB)
01915
if (CONSOLE_IS_DBCS_OUTPUTCP(Console)) {
01916 RtlCopyMemory(BufPtrA,AttrP,(ScreenInfo->ScreenBufferSize.X - X) *
sizeof(
CHAR));
01917 BufPtrA = (PVOID)((
PBYTE)BufPtrA + ((ScreenInfo->ScreenBufferSize.X - X) *
sizeof(
CHAR)));
01918 }
01919
#endif
01920
NumRead += ScreenInfo->ScreenBufferSize.X - X;
01921
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01922 RowIndex = 0;
01923 }
01924 X = 0;
01925 Y++;
01926
if (Y>=ScreenInfo->ScreenBufferSize.Y) {
01927
break;
01928 }
01929 }
01930
#if defined(FE_SB)
01931
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) && (NumRead)) {
01932
if (StringType ==
CONSOLE_ASCII) {
01933 Char = BufPtr = TransBuffer;
01934 }
else {
01935 Char = BufPtr =
Buffer;
01936 }
01937 AttrP = BufPtrA = TransBufferA;
01938
01939
if (*BufPtrA & ATTR_TRAILING_BYTE)
01940 {
01941 j = k = (
SHORT)(NumRead - 1);
01942 BufPtr++;
01943 *Char++ =
UNICODE_SPACE;
01944 BufPtrA++;
01945 NumRead = 1;
01946 }
01947
else {
01948 j = k = (
SHORT)NumRead;
01949 NumRead = 0;
01950 }
01951
while (j--) {
01952
if (!(*BufPtrA & ATTR_TRAILING_BYTE)) {
01953 *Char++ = *BufPtr;
01954 NumRead++;
01955 }
01956 BufPtr++;
01957 BufPtrA++;
01958 }
01959
if (k && *(BufPtrA-1) & ATTR_LEADING_BYTE)
01960 {
01961 *(Char-1) =
UNICODE_SPACE;
01962 }
01963 }
01964
#endif
01965
}
else if (StringType ==
CONSOLE_ATTRIBUTE) {
01966 PWORD TargetPtr=BufPtr;
01967
while (NumRead < *NumRecords) {
01968
01969
01970
01971
01972
01973 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01974
#if defined(FE_SB)
01975
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
01976 AttrP = &Row->
CharRow.KAttrs[X];
01977
#endif
01978
FindAttrIndex(Row->
AttrRow.
Attrs,
01979 X,
01980 &Attr,
01981 &CountOfAttr
01982 );
01983 k=0;
01984
for (j=X;j<ScreenInfo->ScreenBufferSize.X;TargetPtr++) {
01985
#if defined(FE_SB)
01986
if (!CONSOLE_IS_DBCS_OUTPUTCP(Console) )
01987 *TargetPtr = Attr->
Attr;
01988
else if ((j == X) && (*AttrP & ATTR_TRAILING_BYTE))
01989 *TargetPtr = Attr->
Attr;
01990
else if (*AttrP & ATTR_LEADING_BYTE){
01991
if ((NumRead == *NumRecords-1)||(j == ScreenInfo->ScreenBufferSize.X-1))
01992 *TargetPtr = Attr->
Attr;
01993
else
01994 *TargetPtr = Attr->
Attr | (WCHAR)(*AttrP & ATTR_DBCSSBCS_BYTE) << 8;
01995 }
01996
else
01997 *TargetPtr = Attr->
Attr | (WCHAR)(*AttrP & ATTR_DBCSSBCS_BYTE) << 8;
01998
#else
01999
*TargetPtr = Attr->
Attr;
02000
#endif
02001
NumRead++;
02002 j+=1;
02003
if (++k==CountOfAttr && j<ScreenInfo->ScreenBufferSize.X) {
02004 Attr++;
02005 k=0;
02006 CountOfAttr = Attr->
Length;
02007 }
02008
if (NumRead == *NumRecords) {
02009
#if defined(FE_SB)
02010
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
02011
ConsoleHeapFree(TransBufferA);
02012
#endif
02013
return STATUS_SUCCESS;
02014 }
02015
#if defined(FE_SB)
02016
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
02017 AttrP++;
02018
#endif
02019
}
02020
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
02021 RowIndex = 0;
02022 }
02023 X = 0;
02024 Y++;
02025
if (Y>=ScreenInfo->ScreenBufferSize.Y) {
02026
break;
02027 }
02028 }
02029 }
else {
02030 *NumRecords = 0;
02031
#if defined(FE_SB)
02032
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
02033
ConsoleHeapFree(TransBufferA);
02034
#endif
02035
return STATUS_INVALID_PARAMETER;
02036 }
02037
02038
if (StringType ==
CONSOLE_ASCII) {
02039
UINT Codepage;
02040
#if defined(FE_SB)
02041
if ((ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
02042 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
02043
if (ScreenInfo->Console->OutputCP !=
WINDOWSCP)
02044 Codepage =
USACP;
02045
else
02046 Codepage =
WINDOWSCP;
02047 }
else {
02048 Codepage = ScreenInfo->Console->OutputCP;
02049 }
02050
#else
02051
if ((ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
02052 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
02053 Codepage =
WINDOWSCP;
02054 }
else {
02055 Codepage = ScreenInfo->Console->OutputCP;
02056 }
02057
#endif
02058
#if defined(FE_SB)
02059
if ((NumRead == 1) && !CONSOLE_IS_DBCS_OUTPUTCP(Console))
02060
#else
02061
if (NumRead == 1)
02062
#endif
02063
{
02064 *((
PBYTE)
Buffer) =
WcharToChar(Codepage, *TransBuffer);
02065 }
else {
02066 NumRead =
ConvertOutputToOem(Codepage, TransBuffer, NumRead,
Buffer, *NumRecords);
02067 }
02068
ConsoleHeapFree(TransBuffer);
02069 }
else if (StringType ==
CONSOLE_REAL_UNICODE &&
02070 (ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
02071 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
02072
02073
02074
02075
02076
FalseUnicodeToRealUnicode(
Buffer,
02077 NumRead,
02078 ScreenInfo->Console->OutputCP
02079 );
02080 }
02081
02082
#if defined(FE_SB)
02083
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
02084
ConsoleHeapFree(TransBufferA);
02085
#endif
02086
*NumRecords = NumRead;
02087
return STATUS_SUCCESS;
02088 }
02089
02090
02091
02092
NTSTATUS
02093 GetScreenBufferInformation(
02094 IN
PSCREEN_INFORMATION ScreenInfo,
02095 OUT PCOORD Size,
02096 OUT PCOORD CursorPosition,
02097 OUT PCOORD ScrollPosition,
02098 OUT PWORD Attributes,
02099 OUT PCOORD CurrentWindowSize,
02100 OUT PCOORD MaximumWindowSize
02101 )
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129 {
02130
WINDOW_LIMITS WindowLimits;
02131
02132 *
Size = ScreenInfo->ScreenBufferSize;
02133 *CursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
02134 ScrollPosition->X = ScreenInfo->Window.Left;
02135 ScrollPosition->Y = ScreenInfo->Window.Top;
02136 *Attributes = ScreenInfo->Attributes;
02137 CurrentWindowSize->X = (
SHORT)
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
02138 CurrentWindowSize->Y = (
SHORT)
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
02139
if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
02140 MaximumWindowSize->X =
min(80,ScreenInfo->ScreenBufferSize.X);
02141
#if defined(FE_SB)
02142
if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console))
02143 {
02144 MaximumWindowSize->Y =
min(25,ScreenInfo->ScreenBufferSize.Y);
02145 }
02146
else
02147 {
02148 MaximumWindowSize->Y =
min(50,ScreenInfo->ScreenBufferSize.Y);
02149 }
02150
#else
02151
MaximumWindowSize->Y =
min(50,ScreenInfo->ScreenBufferSize.Y);
02152
#endif
02153
}
else {
02154
GetWindowLimits(ScreenInfo, &WindowLimits);
02155 *MaximumWindowSize = WindowLimits.
MaximumWindowSize;
02156 }
02157
return STATUS_SUCCESS;
02158 }
02159
02160
02161
VOID
02162 UpdateScrollBars(
02163 IN
PSCREEN_INFORMATION ScreenInfo
02164 )
02165 {
02166
if (!
ACTIVE_SCREEN_BUFFER(ScreenInfo)) {
02167
return;
02168 }
02169
02170
if (ScreenInfo->Console->Flags &
CONSOLE_UPDATING_SCROLL_BARS)
02171
return;
02172 ScreenInfo->Console->Flags |=
CONSOLE_UPDATING_SCROLL_BARS;
02173
PostMessage(ScreenInfo->Console->hWnd,
02174
CM_UPDATE_SCROLL_BARS,
02175 (WPARAM)ScreenInfo,
02176 0
02177 );
02178 }
02179
02180
VOID
02181 InternalUpdateScrollBars(
02182 IN
PSCREEN_INFORMATION ScreenInfo
02183 )
02184 {
02185 SCROLLINFO si;
02186
02187 ScreenInfo->Console->Flags &= ~
CONSOLE_UPDATING_SCROLL_BARS;
02188
if (!
ACTIVE_SCREEN_BUFFER(ScreenInfo)) {
02189
return;
02190 }
02191
02192 ScreenInfo->ResizingWindow++;
02193
02194 si.cbSize =
sizeof(si);
02195 si.fMask = SIF_ALL;
02196 si.nPage =
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
02197 si.nMin = 0;
02198 si.nMax = ScreenInfo->ScreenBufferSize.Y - 1;
02199 si.nPos = ScreenInfo->Window.Top;
02200 SetScrollInfo(ScreenInfo->Console->hWnd, SB_VERT, &si,
TRUE);
02201
02202 si.cbSize =
sizeof(si);
02203 si.fMask = SIF_ALL;
02204 si.nPage =
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
02205 si.nMin = 0;
02206 si.nMax = ScreenInfo->ScreenBufferSize.X - 1;
02207 si.nPos = ScreenInfo->Window.Left;
02208 SetScrollInfo(ScreenInfo->Console->hWnd, SB_HORZ, &si,
TRUE);
02209
02210 ScreenInfo->ResizingWindow--;
02211 }
02212
02213
VOID
02214 ScreenBufferSizeChange(
02215 IN
PSCREEN_INFORMATION ScreenInfo,
02216 IN COORD NewSize
02217 )
02218 {
02219 INPUT_RECORD InputEvent;
02220
02221 InputEvent.EventType = WINDOW_BUFFER_SIZE_EVENT;
02222 InputEvent.Event.WindowBufferSizeEvent.dwSize = NewSize;
02223
WriteInputBuffer(ScreenInfo->Console,
02224 &ScreenInfo->Console->InputBuffer,
02225 &InputEvent,
02226 1
02227 );
02228 }
02229
02230
NTSTATUS
02231 ResizeScreenBuffer(
02232 IN
PSCREEN_INFORMATION ScreenInfo,
02233 IN COORD NewScreenSize,
02234 IN BOOL DoScrollBarUpdate
02235 )
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253 {
02254
SHORT i,j;
02255 BOOLEAN WindowMaximizedX,WindowMaximizedY;
02256
SHORT LimitX,LimitY;
02257 PWCHAR TextRows,TextRowPtr;
02258
BOOL UpdateWindow;
02259
SHORT TopRow,TopRowIndex;
02260 COORD CursorPosition;
02261
#if defined(FE_SB)
02262
DBCS_SCREEN_BUFFER NewDbcsScreenBuffer;
02263
PBYTE TextRowPtrA;
02264
#endif
02265
02266
02267
02268
02269
02270
if (!(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER)) {
02271
return STATUS_UNSUCCESSFUL;
02272 }
02273
02274 TextRows = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
SCREEN_TAG ),NewScreenSize.X*NewScreenSize.Y*
sizeof(WCHAR));
02275
if (TextRows ==
NULL) {
02276
return STATUS_NO_MEMORY;
02277 }
02278
#if defined(FE_SB)
02279
if (!
CreateDbcsScreenBuffer(ScreenInfo->Console,NewScreenSize,&NewDbcsScreenBuffer))
02280 {
02281
ConsoleHeapFree(TextRows);
02282
return STATUS_NO_MEMORY;
02283 }
02284
#endif
02285
LimitX = (NewScreenSize.X < ScreenInfo->ScreenBufferSize.X) ?
02286 NewScreenSize.X : ScreenInfo->ScreenBufferSize.X;
02287 LimitY = (NewScreenSize.Y < ScreenInfo->ScreenBufferSize.Y) ?
02288 NewScreenSize.Y : ScreenInfo->ScreenBufferSize.Y;
02289 TopRow = 0;
02290
if (NewScreenSize.Y <= ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y) {
02291 TopRow += ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y - NewScreenSize.Y + 1;
02292 }
02293 TopRowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TopRow) % ScreenInfo->ScreenBufferSize.Y;
02294
if (NewScreenSize.Y != ScreenInfo->ScreenBufferSize.Y) {
02295
PROW Temp;
02296
SHORT NumToCopy,NumToCopy2;
02297
02298
02299
02300
02301
02302
02303
02304 Temp = (
PROW)
ConsoleHeapAlloc(
MAKE_TAG(
SCREEN_TAG ),NewScreenSize.Y*
sizeof(
ROW));
02305
if (Temp ==
NULL) {
02306
ConsoleHeapFree(TextRows);
02307
#if defined(FE_SB)
02308
DeleteDbcsScreenBuffer(&NewDbcsScreenBuffer);
02309
#endif
02310
return STATUS_NO_MEMORY;
02311 }
02312 NumToCopy = ScreenInfo->ScreenBufferSize.Y-TopRowIndex;
02313
if (NumToCopy > NewScreenSize.Y)
02314 NumToCopy = NewScreenSize.Y;
02315 RtlCopyMemory(Temp,&ScreenInfo->BufferInfo.TextInfo.Rows[TopRowIndex],NumToCopy*
sizeof(
ROW));
02316
if (TopRowIndex!=0 && NumToCopy != NewScreenSize.Y) {
02317 NumToCopy2 = TopRowIndex;
02318
if (NumToCopy2 > (NewScreenSize.Y-NumToCopy))
02319 NumToCopy2 = NewScreenSize.Y-NumToCopy;
02320 RtlCopyMemory(&Temp[NumToCopy],
02321 ScreenInfo->BufferInfo.TextInfo.Rows,
02322 NumToCopy2*
sizeof(
ROW)
02323 );
02324 }
02325
for (i=0;i<LimitY;i++) {
02326
if (Temp[i].
AttrRow.
Length == 1) {
02327 Temp[i].
AttrRow.
Attrs = &Temp[i].
AttrRow.
AttrPair;
02328 }
02329 }
02330
02331
02332
02333
02334
02335
02336
02337
if (NewScreenSize.Y < ScreenInfo->ScreenBufferSize.Y) {
02338 i = (TopRowIndex+NewScreenSize.Y) % ScreenInfo->ScreenBufferSize.Y;
02339
for (j=NewScreenSize.Y;j<ScreenInfo->ScreenBufferSize.Y;j++) {
02340
if (ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Length > 1) {
02341
ConsoleHeapFree(ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs);
02342 }
02343
if (++i == ScreenInfo->ScreenBufferSize.Y) {
02344 i = 0;
02345 }
02346 }
02347 }
else if (NewScreenSize.Y > ScreenInfo->ScreenBufferSize.Y) {
02348
for (i=ScreenInfo->ScreenBufferSize.Y;i<NewScreenSize.Y;i++) {
02349 Temp[i].
AttrRow.
Length = 1;
02350 Temp[i].
AttrRow.
AttrPair.
Length = NewScreenSize.X;
02351 Temp[i].
AttrRow.
AttrPair.
Attr = ScreenInfo->Attributes;
02352 Temp[i].
AttrRow.
Attrs = &Temp[i].
AttrRow.
AttrPair;
02353 }
02354 }
02355 ScreenInfo->BufferInfo.TextInfo.FirstRow = 0;
02356
ConsoleHeapFree(ScreenInfo->BufferInfo.TextInfo.Rows);
02357 ScreenInfo->BufferInfo.TextInfo.Rows = Temp;
02358 }
02359
02360
02361
02362
02363
02364
#if defined(FE_SB)
02365
TextRowPtrA=NewDbcsScreenBuffer.KAttrRows;
02366
#endif
02367
for (i=0,TextRowPtr=TextRows;i<LimitY;i++,TextRowPtr+=NewScreenSize.X)
02368 {
02369 RtlCopyMemory(TextRowPtr,
02370 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.Chars,
02371 LimitX*
sizeof(WCHAR));
02372
#if defined(FE_SB)
02373
if (TextRowPtrA) {
02374 RtlCopyMemory(TextRowPtrA,
02375 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.KAttrs,
02376 LimitX*
sizeof(
CHAR));
02377 }
02378
#endif
02379
for (j=ScreenInfo->ScreenBufferSize.X;j<NewScreenSize.X;j++) {
02380 TextRowPtr[j] = (WCHAR)
' ';
02381 }
02382
02383
if (ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.Right > NewScreenSize.X) {
02384 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.OldRight =
INVALID_OLD_LENGTH;
02385 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.Right = NewScreenSize.X;
02386 }
02387 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.Chars = TextRowPtr;
02388
#if defined(FE_SB)
02389
ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.KAttrs = TextRowPtrA;
02390
if (TextRowPtrA) {
02391
if (NewScreenSize.X > ScreenInfo->ScreenBufferSize.X)
02392 RtlZeroMemory(TextRowPtrA+ScreenInfo->ScreenBufferSize.X,
02393 NewScreenSize.X-ScreenInfo->ScreenBufferSize.X);
02394 TextRowPtrA+=NewScreenSize.X;
02395 }
02396
#endif
02397
}
02398
for (;i<NewScreenSize.Y;i++,TextRowPtr+=NewScreenSize.X)
02399 {
02400
for (j=0;j<NewScreenSize.X;j++) {
02401 TextRowPtr[j] = (WCHAR)
' ';
02402 }
02403
#if defined(FE_SB)
02404
if (TextRowPtrA) {
02405 RtlZeroMemory(TextRowPtrA, NewScreenSize.X);
02406 }
02407
#endif
02408
ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.Chars = TextRowPtr;
02409 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.OldLeft =
INVALID_OLD_LENGTH;
02410 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.OldRight =
INVALID_OLD_LENGTH;
02411 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.Left = NewScreenSize.X;
02412 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.Right = 0;
02413
#if defined(FE_SB)
02414
ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.KAttrs = TextRowPtrA;
02415
if (TextRowPtrA) {
02416 TextRowPtrA+=NewScreenSize.X;
02417 }
02418
#endif
02419
}
02420
ConsoleHeapFree(ScreenInfo->BufferInfo.TextInfo.TextRows);
02421 ScreenInfo->BufferInfo.TextInfo.TextRows = TextRows;
02422
#if defined(FE_SB)
02423
DeleteDbcsScreenBuffer(&ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer);
02424 ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer = NewDbcsScreenBuffer;
02425
#endif
02426
02427
if (NewScreenSize.X != ScreenInfo->ScreenBufferSize.X) {
02428
for (i=0;i<LimitY;i++) {
02429
PATTR_PAIR IndexedAttr;
02430
SHORT CountOfAttr;
02431
02432
if (NewScreenSize.X > ScreenInfo->ScreenBufferSize.X) {
02433
FindAttrIndex(ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs,
02434 (
SHORT)(ScreenInfo->ScreenBufferSize.X-1),
02435 &IndexedAttr,
02436 &CountOfAttr
02437 );
02438
ASSERT (IndexedAttr <=
02439 &ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs[ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.
Length-1]);
02440 IndexedAttr->
Length += NewScreenSize.X - ScreenInfo->ScreenBufferSize.X;
02441 }
02442
else {
02443
02444
FindAttrIndex(ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs,
02445 (
SHORT)(NewScreenSize.X-1),
02446 &IndexedAttr,
02447 &CountOfAttr
02448 );
02449 IndexedAttr->
Length -= CountOfAttr-1;
02450
if (ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Length != 1) {
02451 ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Length = (
SHORT)(IndexedAttr - ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs + 1);
02452
if (ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Length != 1) {
02453 ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs = (
PATTR_PAIR)
ConsoleHeapReAlloc(
MAKE_TAG(
SCREEN_TAG ),ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs,
02454 ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Length *
sizeof(
ATTR_PAIR));
02455 }
02456
else {
02457 ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.AttrPair = *IndexedAttr;
02458
ConsoleHeapFree(ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs);
02459 ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.Attrs = &ScreenInfo->BufferInfo.TextInfo.Rows[i].AttrRow.AttrPair;
02460 }
02461 }
02462 }
02463 }
02464 }
02465
02466
02467
02468
02469
02470
#ifdef i386
02471
if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
02472
if (NewScreenSize.X < ScreenInfo->BufferInfo.TextInfo.WindowedWindowSize.X) {
02473 ScreenInfo->BufferInfo.TextInfo.WindowedWindowSize.X = NewScreenSize.X;
02474 }
02475
if (NewScreenSize.Y < ScreenInfo->BufferInfo.TextInfo.WindowedWindowSize.Y) {
02476 ScreenInfo->BufferInfo.TextInfo.WindowedWindowSize.Y = NewScreenSize.Y;
02477 }
02478 ScreenInfo->BufferInfo.TextInfo.WindowedScreenSize = NewScreenSize;
02479 }
02480
#endif
02481
02482
UpdateWindow =
FALSE;
02483
02484
02485
02486
02487
02488
02489
if (NewScreenSize.X >
CONSOLE_WINDOW_SIZE_X(ScreenInfo)) {
02490
if (ScreenInfo->Window.Right >= NewScreenSize.X) {
02491 ScreenInfo->Window.Left -= ScreenInfo->Window.Right - NewScreenSize.X + 1;
02492 ScreenInfo->Window.Right -= ScreenInfo->Window.Right - NewScreenSize.X + 1;
02493
UpdateWindow =
TRUE;
02494 }
02495 }
else {
02496 ScreenInfo->Window.Left = 0;
02497 ScreenInfo->Window.Right = NewScreenSize.X - 1;
02498
UpdateWindow =
TRUE;
02499 }
02500
if (NewScreenSize.Y >
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) {
02501
if (ScreenInfo->Window.Bottom >= NewScreenSize.Y) {
02502 ScreenInfo->Window.Top -= ScreenInfo->Window.Bottom - NewScreenSize.Y + 1;
02503 ScreenInfo->Window.Bottom -= ScreenInfo->Window.Bottom - NewScreenSize.Y + 1;
02504
UpdateWindow =
TRUE;
02505 }
02506 }
else {
02507 ScreenInfo->Window.Top = 0;
02508 ScreenInfo->Window.Bottom = NewScreenSize.Y - 1;
02509
UpdateWindow =
TRUE;
02510 }
02511
02512
#if defined(FE_SB)
02513
02514
02515
02516
02517
02518 ScreenInfo->ScreenBufferSize = NewScreenSize;
02519
#endif
02520
02521
02522
02523
02524
02525 CursorPosition=ScreenInfo->BufferInfo.TextInfo.CursorPosition;
02526
if (CursorPosition.X >= NewScreenSize.X) {
02527
if (ScreenInfo->OutputMode & ENABLE_WRAP_AT_EOL_OUTPUT) {
02528 CursorPosition.X = 0;
02529 CursorPosition.Y += 1;
02530 }
else {
02531 CursorPosition.X = NewScreenSize.X-1;
02532 }
02533 }
02534
if (CursorPosition.Y >= NewScreenSize.Y) {
02535 CursorPosition.Y = NewScreenSize.Y-1;
02536 }
02537
#if defined(FE_SB)
02538
02539
02540
02541
if (ScreenInfo->Console->InputBuffer.ImeMode.Open && CursorPosition.Y < 0) {
02542 CursorPosition.Y = 0;
02543 }
02544
#endif
02545
if (CursorPosition.X != ScreenInfo->BufferInfo.TextInfo.CursorPosition.X ||
02546 CursorPosition.Y != ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y) {
02547
SetCursorPosition(ScreenInfo,
02548 CursorPosition,
02549
FALSE
02550 );
02551 }
02552
02553
ASSERT (ScreenInfo->Window.Left >= 0);
02554
ASSERT (ScreenInfo->Window.Right < NewScreenSize.X);
02555
ASSERT (ScreenInfo->Window.Top >= 0);
02556
ASSERT (ScreenInfo->Window.Bottom < NewScreenSize.Y);
02557
02558 ScreenInfo->ScreenBufferSize = NewScreenSize;
02559
ResetTextFlags(ScreenInfo,0,(
SHORT)(ScreenInfo->ScreenBufferSize.Y-1));
02560 WindowMaximizedX = (
CONSOLE_WINDOW_SIZE_X(ScreenInfo) ==
02561 ScreenInfo->ScreenBufferSize.X);
02562 WindowMaximizedY = (
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) ==
02563 ScreenInfo->ScreenBufferSize.Y);
02564
02565
#if defined(FE_IME)
02566
if (
CONSOLE_IS_IME_ENABLED()) {
02567
if (!
NT_SUCCESS(ConsoleImeMessagePump(ScreenInfo->Console,
02568
CONIME_NOTIFY_SCREENBUFFERSIZE,
02569 (WPARAM)ScreenInfo->Console->ConsoleHandle,
02570 (LPARAM)MAKELPARAM(NewScreenSize.X, NewScreenSize.Y)
02571 ))) {
02572
return STATUS_INVALID_HANDLE;
02573 }
02574 }
02575
02576
if ( (! ScreenInfo->ConvScreenInfo) &&
02577 (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console)))
02578 {
02579
if (!
NT_SUCCESS(ConsoleImeResizeModeSystemScreenBuffer(ScreenInfo->Console,NewScreenSize)) ||
02580 !
NT_SUCCESS(ConsoleImeResizeCompStrScreenBuffer(ScreenInfo->Console,NewScreenSize))) {
02581
02582
02583
02584
return STATUS_INVALID_HANDLE;
02585 }
02586 }
02587
#endif // FE_IME
02588
if (ScreenInfo->WindowMaximizedX != WindowMaximizedX ||
02589 ScreenInfo->WindowMaximizedY != WindowMaximizedY) {
02590 ScreenInfo->WindowMaximizedX = WindowMaximizedX;
02591 ScreenInfo->WindowMaximizedY = WindowMaximizedY;
02592
UpdateWindow =
TRUE;
02593 }
02594
if (
UpdateWindow) {
02595
SetWindowSize(ScreenInfo);
02596 }
02597
02598
if (DoScrollBarUpdate) {
02599
UpdateScrollBars(ScreenInfo);
02600 }
02601
if (ScreenInfo->Console->InputBuffer.InputMode & ENABLE_WINDOW_INPUT) {
02602
ScreenBufferSizeChange(ScreenInfo,ScreenInfo->ScreenBufferSize);
02603 }
02604
02605
return STATUS_SUCCESS;
02606 }
02607
02608
NTSTATUS
02609 AllocateScrollBuffer(
02610 DWORD Size
02611 )
02612 {
02613
ScrollBuffer = (PCHAR_INFO)
ConsoleHeapAlloc(
MAKE_TAG(
SCREEN_TAG ),
Size);
02614
if (
ScrollBuffer ==
NULL) {
02615
ScrollBufferSize = 0;
02616
return STATUS_NO_MEMORY;
02617 }
02618
ScrollBufferSize =
Size;
02619
return STATUS_SUCCESS;
02620 }
02621
02622
VOID
02623 FreeScrollBuffer( VOID )
02624 {
02625
ConsoleHeapFree(
ScrollBuffer);
02626
ScrollBuffer =
NULL;
02627
ScrollBufferSize = 0;
02628 }
02629
02630
NTSTATUS
02631 InitializeScrollBuffer( VOID )
02632 {
02633
NTSTATUS Status;
02634
02635
ghrgnScroll = CreateRectRgn(0,0,1,1);
02636
if (
ghrgnScroll ==
NULL) {
02637 RIPMSG0(RIP_WARNING,
"InitializeScrollBuffer: cannot allocate ghrgnScroll.");
02638
return STATUS_UNSUCCESSFUL;
02639 }
02640
gprgnData = (LPRGNDATA)
ConsoleHeapAlloc(
MAKE_TAG(
SCREEN_TAG ),
GRGNDATASIZE);
02641
if (
gprgnData ==
NULL) {
02642 RIPMSG0(RIP_WARNING,
"InitializeScrollBuffer: allocate gprgnData.");
02643
Status = STATUS_NO_MEMORY;
02644
goto error;
02645 }
02646
02647
Status =
AllocateScrollBuffer(
DefaultRegInfo.
ScreenBufferSize.X *
02648
DefaultRegInfo.
ScreenBufferSize.Y *
02649
sizeof(CHAR_INFO));
02650
if (!
NT_SUCCESS(
Status)) {
02651
goto error;
02652 }
02653
02654
Status =
RtlInitializeCriticalSectionAndSpinCount(&
ScrollBufferLock,
02655 0x80000000);
02656
02657 error:
02658
if (!
NT_SUCCESS(
Status)) {
02659 RIPMSG0(RIP_WARNING,
"InitializeScrollBuffer failed, cleaning up");
02660
if (
ghrgnScroll) {
02661 DeleteObject(
ghrgnScroll);
02662
ghrgnScroll =
NULL;
02663 }
02664
if (
gprgnData) {
02665
ConsoleHeapFree(
gprgnData);
02666
gprgnData =
NULL;
02667 }
02668 }
02669
02670
return Status;
02671 }
02672
02673
VOID
02674 UpdateComplexRegion(
02675 IN
PSCREEN_INFORMATION ScreenInfo,
02676 IN COORD FontSize
02677 )
02678 {
02679
int iSize,i;
02680 LPRECT pRect;
02681 SMALL_RECT UpdateRegion;
02682 LPRGNDATA pRgnData;
02683
02684
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
02685 ScreenInfo->BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
02686 }
02687 pRgnData =
gprgnData;
02688
02689
02690
02691
02692 iSize = GetRegionData(
ghrgnScroll, 0,
NULL);
02693
if (iSize >
GRGNDATASIZE) {
02694 pRgnData = (LPRGNDATA)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),iSize);
02695
if (pRgnData ==
NULL)
02696
return;
02697 }
02698
02699
if (!GetRegionData(
ghrgnScroll, iSize, pRgnData)) {
02700
ASSERT(
FALSE);
02701
if (pRgnData !=
gprgnData) {
02702
ConsoleHeapFree(pRgnData);
02703 }
02704
return;
02705 }
02706
02707 pRect = (PRECT)&pRgnData->Buffer;
02708
02709
02710
02711
02712
for(i=0;i<(
int)pRgnData->rdh.nCount;i++,pRect++) {
02713
02714
02715
02716
02717
02718 UpdateRegion.Left = (
SHORT)((pRect->left/FontSize.X)+ \
02719 ScreenInfo->Window.Left);
02720 UpdateRegion.Right = (
SHORT)(((pRect->right-1)/FontSize.X)+ \
02721 ScreenInfo->Window.Left);
02722 UpdateRegion.Top = (
SHORT)((pRect->top/FontSize.Y)+ \
02723 ScreenInfo->Window.Top);
02724 UpdateRegion.Bottom = (
SHORT)(((pRect->bottom-1)/FontSize.Y)+ \
02725 ScreenInfo->Window.Top);
02726
02727
02728
02729
WriteToScreen(ScreenInfo, &UpdateRegion);
02730 }
02731
if (pRgnData !=
gprgnData) {
02732
ConsoleHeapFree(pRgnData);
02733 }
02734 }
02735
02736
VOID
02737 ScrollScreen(
02738 IN
PSCREEN_INFORMATION ScreenInfo,
02739 IN PSMALL_RECT ScrollRect,
02740 IN PSMALL_RECT MergeRect,
02741 IN COORD TargetPoint
02742 )
02743 {
02744 RECT ScrollRectGdi;
02745 SMALL_RECT UpdateRegion;
02746 COORD FontSize;
02747
BOOL Success;
02748 RECT BoundingBox;
02749
#if defined(FE_SB)
02750
BYTE fBisect = 0;
02751 SMALL_RECT UpdateRect;
02752 SMALL_RECT TmpBisect;
02753
#endif
02754
02755
DBGOUTPUT((
"ScrollScreen\n"));
02756
if (!
ACTIVE_SCREEN_BUFFER(ScreenInfo)) {
02757
return;
02758 }
02759
if (ScreenInfo->Console->FullScreenFlags == 0 &&
02760 !(ScreenInfo->Console->Flags & (
CONSOLE_IS_ICONIC |
CONSOLE_NO_WINDOW))) {
02761
#if defined(FE_SB)
02762
if (ScreenInfo->BisectFlag){
02763 SMALL_RECT RedrawRect;
02764
if (ScrollRect->Top < TargetPoint.Y){
02765 RedrawRect.Top = ScrollRect->Top;
02766 RedrawRect.Bottom = TargetPoint.Y+(ScrollRect->Bottom-ScrollRect->Top);
02767 }
02768
else{
02769 RedrawRect.Top = TargetPoint.Y;
02770 RedrawRect.Bottom = ScrollRect->Bottom;
02771 }
02772
if (ScrollRect->Left < TargetPoint.X){
02773 RedrawRect.Left = ScrollRect->Left;
02774 RedrawRect.Right = TargetPoint.X+(ScrollRect->Right-ScrollRect->Left);
02775 }
02776
else{
02777 RedrawRect.Left = TargetPoint.X;
02778 RedrawRect.Right = ScrollRect->Right;
02779 }
02780
WriteToScreen(ScreenInfo,&RedrawRect);
02781 }
02782
else{
02783
#endif
02784
ScrollRectGdi.left = ScrollRect->Left-ScreenInfo->Window.Left;
02785 ScrollRectGdi.right = (ScrollRect->Right-ScreenInfo->Window.Left+1);
02786 ScrollRectGdi.top = ScrollRect->Top-ScreenInfo->Window.Top;
02787 ScrollRectGdi.bottom = (ScrollRect->Bottom-ScreenInfo->Window.Top+1);
02788
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
02789 FontSize =
SCR_FONTSIZE(ScreenInfo);
02790 ScrollRectGdi.left *= FontSize.X;
02791 ScrollRectGdi.right *= FontSize.X;
02792 ScrollRectGdi.top *= FontSize.Y;
02793 ScrollRectGdi.bottom *= FontSize.Y;
02794
ASSERT (ScreenInfo->BufferInfo.TextInfo.UpdatingScreen>0);
02795 }
else {
02796 FontSize.X = 1;
02797 FontSize.Y = 1;
02798 }
02799
SCROLLDC_CALL;
02800
LockScrollBuffer();
02801 Success = (
int)
ScrollDC(ScreenInfo->Console->hDC,
02802 (TargetPoint.X-ScrollRect->Left)*FontSize.X,
02803 (TargetPoint.Y-ScrollRect->Top)*FontSize.Y,
02804 &ScrollRectGdi,
02805
NULL,
02806
ghrgnScroll,
02807
NULL);
02808
if (Success) {
02809
02810
02811
02812
02813
02814
02815
switch (GetRgnBox(
ghrgnScroll, &BoundingBox)) {
02816
case SIMPLEREGION:
02817 UpdateRegion.Left = (
SHORT)((BoundingBox.left / FontSize.X) + \
02818 ScreenInfo->Window.Left);
02819 UpdateRegion.Right = (
SHORT)(((BoundingBox.right-1) / FontSize.X) + \
02820 ScreenInfo->Window.Left);
02821 UpdateRegion.Top = (
SHORT)((BoundingBox.top / FontSize.Y) + \
02822 ScreenInfo->Window.Top);
02823 UpdateRegion.Bottom = (
SHORT)(((BoundingBox.bottom-1) / FontSize.Y) + \
02824 ScreenInfo->Window.Top);
02825
#if defined(FE_SB)
02826
fBisect = ScreenInfo->BisectFlag;
02827
#endif
02828
WriteToScreen(ScreenInfo, &UpdateRegion);
02829
break;
02830
case COMPLEXREGION:
02831
UpdateComplexRegion(ScreenInfo, FontSize);
02832
break;
02833 }
02834
02835
if (MergeRect) {
02836
#if defined(FE_SB)
02837
if (fBisect)
02838 ScreenInfo->BisectFlag = fBisect;
02839
else
02840 fBisect = ScreenInfo->BisectFlag;
02841
#endif
02842
WriteToScreen(ScreenInfo, MergeRect);
02843 }
02844
#if defined(FE_SB)
02845
if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console)) {
02846 UpdateRect.Left = TargetPoint.X;
02847 UpdateRect.Right = ScrollRect->Right + (TargetPoint.X-ScrollRect->Left);
02848 UpdateRect.Top = TargetPoint.Y;
02849 UpdateRect.Bottom = ScrollRect->Bottom + (TargetPoint.Y-ScrollRect->Top);
02850
if (UpdateRect.Left &&
02851 UpdateRect.Right+1 < ScreenInfo->ScreenBufferSize.X &&
02852 UpdateRect.Right-UpdateRect.Left <= 2) {
02853 TmpBisect.Left = UpdateRect.Left-1;
02854 TmpBisect.Right = UpdateRect.Right+1;
02855 TmpBisect.Top = UpdateRect.Top;
02856 TmpBisect.Bottom = UpdateRect.Bottom;
02857
WriteToScreen(ScreenInfo, &TmpBisect);
02858 }
02859
else {
02860
if (UpdateRect.Left) {
02861 TmpBisect.Left = UpdateRect.Left-1;
02862 TmpBisect.Right = UpdateRect.Left;
02863 TmpBisect.Top = UpdateRect.Top;
02864 TmpBisect.Bottom = UpdateRect.Bottom;
02865
WriteToScreen(ScreenInfo, &TmpBisect);
02866 }
02867
if (UpdateRect.Right+1 < ScreenInfo->ScreenBufferSize.X) {
02868 TmpBisect.Left = UpdateRect.Right;
02869 TmpBisect.Right = UpdateRect.Right+1;
02870 TmpBisect.Top = UpdateRect.Top;
02871 TmpBisect.Bottom = UpdateRect.Bottom;
02872
WriteToScreen(ScreenInfo, &TmpBisect);
02873 }
02874 }
02875 }
02876
#endif
02877
}
else {
02878
#if defined(FE_SB)
02879
if (fBisect)
02880 ScreenInfo->BisectFlag = fBisect;
02881
else
02882 fBisect = ScreenInfo->BisectFlag;
02883
#endif
02884
WriteToScreen(ScreenInfo, &ScreenInfo->Window);
02885 }
02886
UnlockScrollBuffer();
02887
#if defined(FE_SB)
02888
}
02889
#endif
02890
}
02891
#ifdef i386
02892
else if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
02893
#if defined(FE_SB)
02894
if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console)) {
02895
if (! ScreenInfo->ConvScreenInfo) {
02896
if (ScreenInfo->Console->CurrentScreenBuffer == ScreenInfo) {
02897 ScrollHW(ScreenInfo,
02898 ScrollRect,
02899 MergeRect,
02900 TargetPoint
02901 );
02902 }
02903 }
02904
else if (ScreenInfo->Console->CurrentScreenBuffer->Flags &
CONSOLE_TEXTMODE_BUFFER) {
02905 ScrollHW(ScreenInfo,
02906 ScrollRect,
02907 MergeRect,
02908 TargetPoint
02909 );
02910 }
02911 }
02912
else
02913
#endif
02914
ScrollHW(ScreenInfo,
02915 ScrollRect,
02916 MergeRect,
02917 TargetPoint
02918 );
02919 }
02920
#endif
02921
}
02922
02923
02924 void CopyRow(
02925
PROW Row,
02926
PROW PrevRow)
02927 {
02928
if (PrevRow->
AttrRow.
Length != 1 ||
02929 Row->
AttrRow.
Length != 1 ||
02930 PrevRow->
AttrRow.
Attrs->
Attr != Row->
AttrRow.
Attrs->
Attr) {
02931 Row->
CharRow.
OldRight =
INVALID_OLD_LENGTH;
02932 Row->
CharRow.
OldLeft =
INVALID_OLD_LENGTH;
02933 }
else {
02934 Row->
CharRow.
OldRight = PrevRow->
CharRow.
Right;
02935 Row->
CharRow.
OldLeft = PrevRow->
CharRow.
Left;
02936 }
02937 }
02938
02939
SHORT
02940 ScrollEntireScreen(
02941 IN
PSCREEN_INFORMATION ScreenInfo,
02942 IN SHORT ScrollValue,
02943 IN BOOL UpdateRowIndex
02944 )
02945
02946
02953 {
02954
SHORT RowIndex;
02955
int i;
02956
int new;
02957
int old;
02958
02959 ScreenInfo->BufferInfo.TextInfo.Flags |=
TEXT_VALID_HINT;
02960
02961
02962
02963
02964
02965 RowIndex = ScreenInfo->BufferInfo.TextInfo.FirstRow;
02966
02967
02968
02969
02970
02971
new = (RowIndex + ScreenInfo->Window.Bottom + ScrollValue) %
02972 ScreenInfo->ScreenBufferSize.Y;
02973 old = (RowIndex + ScreenInfo->Window.Bottom) %
02974 ScreenInfo->ScreenBufferSize.Y;
02975
for (i =
WINDOW_SIZE_Y(&ScreenInfo->Window) - 1; i >= 0; i--) {
02976
CopyRow(
02977 &ScreenInfo->BufferInfo.TextInfo.Rows[
new],
02978 &ScreenInfo->BufferInfo.TextInfo.Rows[old]);
02979
if (--
new < 0)
02980
new = ScreenInfo->ScreenBufferSize.Y - 1;
02981
if (--old < 0)
02982 old = ScreenInfo->ScreenBufferSize.Y - 1;
02983 }
02984
02985
02986
02987
02988
02989
if (UpdateRowIndex) {
02990 ScreenInfo->BufferInfo.TextInfo.FirstRow =
02991 (
SHORT)((RowIndex + ScrollValue) % ScreenInfo->ScreenBufferSize.Y);
02992 }
02993
02994
return RowIndex;
02995 }
02996
02997
VOID
02998 StreamScrollRegion(
02999 IN
PSCREEN_INFORMATION ScreenInfo
03000 )
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017 {
03018
SHORT RowIndex;
03019
PROW Row;
03020 PWCHAR Char;
03021 RECT
Rect;
03022 RECT BoundingBox;
03023
int ScreenWidth,ScrollHeight,ScreenHeight;
03024 COORD FontSize;
03025 SMALL_RECT UpdateRegion;
03026
BOOL Success;
03027
int i;
03028
#if defined(FE_SB)
03029
PBYTE AttrP;
03030
#endif
03031
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
03032
03033 RowIndex =
ScrollEntireScreen(ScreenInfo,1,
TRUE);
03034
03035 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
03036
03037
03038
03039
03040
03041 Char = &Row->
CharRow.
Chars[Row->
CharRow.
Left];
03042
for (i=Row->
CharRow.
Left;i<Row->
CharRow.
Right;i++) {
03043 *Char = (WCHAR)
' ';
03044 Char++;
03045 }
03046
#if defined(FE_SB)
03047
if (CONSOLE_IS_DBCS_OUTPUTCP(Console)){
03048
int LineWidth = Row->
CharRow.
Right - Row->
CharRow.
Left;
03049 AttrP = &Row->
CharRow.KAttrs[Row->
CharRow.
Left];
03050
if ( LineWidth > 0 )
03051 RtlZeroMemory(AttrP, LineWidth);
03052 AttrP += LineWidth;
03053 Row->
CharRow.
OldRight =
INVALID_OLD_LENGTH;
03054 Row->
CharRow.
OldLeft =
INVALID_OLD_LENGTH;
03055 Console->ConsoleIme.ScrollWaitCountDown = Console->ConsoleIme.ScrollWaitTimeout;
03056 }
03057
#endif
03058
Row->
CharRow.
Right = 0;
03059 Row->
CharRow.
Left = ScreenInfo->ScreenBufferSize.X;
03060
03061
03062
03063
03064
03065
if (Row->
AttrRow.
Length != 1) {
03066
ConsoleHeapFree(Row->
AttrRow.
Attrs);
03067 Row->
AttrRow.
Attrs = &Row->
AttrRow.
AttrPair;
03068 Row->
AttrRow.
AttrPair.
Length = ScreenInfo->ScreenBufferSize.X;
03069 Row->
AttrRow.
Length = 1;
03070 }
03071 Row->
AttrRow.
AttrPair.
Attr = ScreenInfo->Attributes;
03072
03073
03074
03075
03076
03077
if (
ACTIVE_SCREEN_BUFFER(ScreenInfo) &&
03078 Console->
FullScreenFlags == 0 &&
03079 !(Console->
Flags & (
CONSOLE_IS_ICONIC |
CONSOLE_NO_WINDOW))) {
03080
03081
ConsoleHideCursor(ScreenInfo);
03082
if (
UsePolyTextOut) {
03083
WriteRegionToScreen(ScreenInfo, &ScreenInfo->Window);
03084 }
else {
03085 FontSize =
SCR_FONTSIZE(ScreenInfo);
03086 ScreenWidth =
WINDOW_SIZE_X(&ScreenInfo->Window) * FontSize.X;
03087 ScreenHeight =
WINDOW_SIZE_Y(&ScreenInfo->Window) * FontSize.Y;
03088 ScrollHeight = ScreenHeight - FontSize.Y;
03089
03090
Rect.
left = 0;
03091
Rect.
right = ScreenWidth;
03092
Rect.
top = FontSize.Y;
03093
Rect.
bottom = ScreenHeight;
03094
03095
03096
03097
03098
03099
if (ScreenInfo->BufferInfo.TextInfo.Flags &
TEXT_VALID_HINT) {
03100
SHORT MinLeft,MaxRight;
03101 MinLeft = ScreenInfo->ScreenBufferSize.X;
03102 MaxRight = 0;
03103 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+ScreenInfo->Window.Top) % ScreenInfo->ScreenBufferSize.Y;
03104
for (i=ScreenInfo->Window.Top+1;i<=ScreenInfo->Window.Bottom;i++) {
03105 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
03106
if (Row->
CharRow.
OldLeft ==
INVALID_OLD_LENGTH) {
03107 MinLeft = 0;
03108 }
else {
03109
if (MinLeft >
min(Row->
CharRow.
Left,Row->
CharRow.
OldLeft)) {
03110 MinLeft =
min(Row->
CharRow.
Left,Row->
CharRow.
OldLeft);
03111 }
03112 }
03113
if (Row->
CharRow.
OldRight ==
INVALID_OLD_LENGTH) {
03114 MaxRight = ScreenInfo->ScreenBufferSize.X-1;
03115 }
else {
03116
if (MaxRight <
max(Row->
CharRow.
Right,Row->
CharRow.
OldRight)) {
03117 MaxRight =
max(Row->
CharRow.
Right,Row->
CharRow.
OldRight);
03118 }
03119 }
03120
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
03121 RowIndex = 0;
03122 }
03123 }
03124
Rect.
left = MinLeft*FontSize.X;
03125
Rect.
right = (MaxRight+1)*FontSize.X;
03126 }
03127
03128
LockScrollBuffer();
03129
ASSERT (ScreenInfo->BufferInfo.TextInfo.UpdatingScreen>0);
03130 Success = (
int)
ScrollDC(Console->
hDC,
03131 0,
03132 -FontSize.Y,
03133 &
Rect,
03134
NULL,
03135
ghrgnScroll,
03136
NULL
03137 );
03138
if (Success && ScreenInfo->Window.Top!=ScreenInfo->Window.Bottom) {
03139
#if defined(FE_SB)
03140
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) &&
03141 ScreenInfo->Attributes & (COMMON_LVB_GRID_HORIZONTAL +
03142 COMMON_LVB_GRID_LVERTICAL +
03143 COMMON_LVB_GRID_RVERTICAL +
03144 COMMON_LVB_REVERSE_VIDEO +
03145 COMMON_LVB_UNDERSCORE )){
03146 UpdateRegion = ScreenInfo->Window;
03147 UpdateRegion.Top = UpdateRegion.Bottom;
03148 ScreenInfo->BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
03149
WriteToScreen(ScreenInfo,&UpdateRegion);
03150 }
03151
else{
03152
#endif
03153
switch (GetRgnBox(
ghrgnScroll, &BoundingBox)) {
03154
case SIMPLEREGION:
03155
if (BoundingBox.left == 0 &&
03156 BoundingBox.right == ScreenWidth &&
03157 BoundingBox.top == ScrollHeight &&
03158 BoundingBox.bottom == ScreenHeight) {
03159
03160 PatBlt(Console->
hDC,0,ScrollHeight,ScreenWidth,FontSize.Y,PATCOPY);
03161 GdiFlush();
03162 }
else {
03163 UpdateRegion.Left = (
SHORT)((BoundingBox.left/FontSize.X)+ScreenInfo->Window.Left);
03164 UpdateRegion.Right = (
SHORT)(((BoundingBox.right-1)/FontSize.X)+ScreenInfo->Window.Left);
03165 UpdateRegion.Top = (
SHORT)((BoundingBox.top/FontSize.Y)+ScreenInfo->Window.Top);
03166 UpdateRegion.Bottom = (
SHORT)(((BoundingBox.bottom-1)/FontSize.Y)+ScreenInfo->Window.Top);
03167
WriteToScreen(ScreenInfo,&UpdateRegion);
03168 }
03169
break;
03170
case COMPLEXREGION:
03171
UpdateComplexRegion(ScreenInfo,FontSize);
03172
break;
03173 }
03174
#if defined(FE_SB)
03175
}
03176
#endif
03177
}
else {
03178
WriteToScreen(ScreenInfo,&ScreenInfo->Window);
03179 }
03180
UnlockScrollBuffer();
03181 }
03182
ConsoleShowCursor(ScreenInfo);
03183 }
03184
#ifdef i386
03185
else if (Console->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
03186 SMALL_RECT ScrollRect;
03187 COORD TargetPoint;
03188
03189 ScrollRect = ScreenInfo->Window;
03190 TargetPoint.Y = ScrollRect.Top;
03191 ScrollRect.Top += 1;
03192 TargetPoint.X = 0;
03193
#if defined(FE_SB)
03194
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) ) {
03195
if (! ScreenInfo->ConvScreenInfo) {
03196
if (ScreenInfo->Console->CurrentScreenBuffer == ScreenInfo) {
03197 ScrollHW(ScreenInfo,
03198 &ScrollRect,
03199
NULL,
03200 TargetPoint
03201 );
03202 }
03203 }
03204
else if (ScreenInfo->Console->CurrentScreenBuffer->Flags &
CONSOLE_TEXTMODE_BUFFER) {
03205 ScrollHW(ScreenInfo,
03206 &ScrollRect,
03207
NULL,
03208 TargetPoint
03209 );
03210 }
03211 }
03212
else
03213
#endif
03214
ScrollHW(ScreenInfo,
03215 &ScrollRect,
03216
NULL,
03217 TargetPoint
03218 );
03219 ScrollRect.Top = ScrollRect.Bottom - 1;
03220 WriteRegionToScreenHW(ScreenInfo,&ScrollRect);
03221 }
03222
#endif
03223
}
03224
03225
NTSTATUS
03226 ScrollRegion(
03227 IN
PSCREEN_INFORMATION ScreenInfo,
03228 IN OUT PSMALL_RECT ScrollRectangle,
03229 IN PSMALL_RECT ClipRectangle OPTIONAL,
03230 IN COORD DestinationOrigin,
03231 IN CHAR_INFO Fill
03232 )
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259 {
03260 SMALL_RECT TargetRectangle, SourceRectangle;
03261 COORD TargetPoint;
03262 COORD
Size;
03263 SMALL_RECT OurClipRectangle;
03264 SMALL_RECT ScrollRectangle2,ScrollRectangle3;
03265
NTSTATUS Status;
03266
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
if (Fill.Char.UnicodeChar ==
'\0' && Fill.Attributes == 0) {
03280 Fill.Char.UnicodeChar = (WCHAR)
' ';
03281 Fill.Attributes = ScreenInfo->Attributes;
03282 }
03283
03284
03285
03286
03287
03288
if (ScrollRectangle->Left < 0) {
03289 DestinationOrigin.X += -ScrollRectangle->Left;
03290 ScrollRectangle->Left = 0;
03291 }
03292
if (ScrollRectangle->Top < 0) {
03293 DestinationOrigin.Y += -ScrollRectangle->Top;
03294 ScrollRectangle->Top = 0;
03295 }
03296
if (ScrollRectangle->Right >= ScreenInfo->ScreenBufferSize.X) {
03297 ScrollRectangle->Right = (
SHORT)(ScreenInfo->ScreenBufferSize.X-1);
03298 }
03299
if (ScrollRectangle->Bottom >= ScreenInfo->ScreenBufferSize.Y) {
03300 ScrollRectangle->Bottom = (
SHORT)(ScreenInfo->ScreenBufferSize.Y-1);
03301 }
03302
03303
03304
03305
03306
03307
if (ScrollRectangle->Bottom < ScrollRectangle->Top ||
03308 ScrollRectangle->Right < ScrollRectangle->Left) {
03309
return STATUS_SUCCESS;
03310 }
03311
03312
03313
03314
03315
03316
03317
03318
if (ClipRectangle) {
03319
03320
03321
03322
03323
03324
if (ClipRectangle->Left < 0) {
03325 ClipRectangle->Left = 0;
03326 }
03327
if (ClipRectangle->Top < 0) {
03328 ClipRectangle->Top = 0;
03329 }
03330
if (ClipRectangle->Right >= ScreenInfo->ScreenBufferSize.X) {
03331 ClipRectangle->Right = (
SHORT)(ScreenInfo->ScreenBufferSize.X-1);
03332 }
03333
if (ClipRectangle->Bottom >= ScreenInfo->ScreenBufferSize.Y) {
03334 ClipRectangle->Bottom = (
SHORT)(ScreenInfo->ScreenBufferSize.Y-1);
03335 }
03336 }
03337
else {
03338 OurClipRectangle.Left = 0;
03339 OurClipRectangle.Top = 0;
03340 OurClipRectangle.Right = (
SHORT)(ScreenInfo->ScreenBufferSize.X-1);
03341 OurClipRectangle.Bottom = (
SHORT)(ScreenInfo->ScreenBufferSize.Y-1);
03342 ClipRectangle = &OurClipRectangle;
03343 }
03344
03345
03346
03347
03348
03349
03350
03351 ScrollRectangle2 = *ScrollRectangle;
03352 TargetRectangle.Left = DestinationOrigin.X;
03353 TargetRectangle.Top = DestinationOrigin.Y;
03354 TargetRectangle.Right = (
SHORT)(DestinationOrigin.X + (ScrollRectangle2.Right - ScrollRectangle2.Left + 1) - 1);
03355 TargetRectangle.Bottom = (
SHORT)(DestinationOrigin.Y + (ScrollRectangle2.Bottom - ScrollRectangle2.Top + 1) - 1);
03356
03357
if (TargetRectangle.Left < ClipRectangle->Left) {
03358 ScrollRectangle2.Left += ClipRectangle->Left - TargetRectangle.Left;
03359 TargetRectangle.Left = ClipRectangle->Left;
03360 }
03361
if (TargetRectangle.Top < ClipRectangle->Top) {
03362 ScrollRectangle2.Top += ClipRectangle->Top - TargetRectangle.Top;
03363 TargetRectangle.Top = ClipRectangle->Top;
03364 }
03365
if (TargetRectangle.Right > ClipRectangle->Right) {
03366 ScrollRectangle2.Right -= TargetRectangle.Right - ClipRectangle->Right;
03367 TargetRectangle.Right = ClipRectangle->Right;
03368 }
03369
if (TargetRectangle.Bottom > ClipRectangle->Bottom) {
03370 ScrollRectangle2.Bottom -= TargetRectangle.Bottom - ClipRectangle->Bottom;
03371 TargetRectangle.Bottom = ClipRectangle->Bottom;
03372 }
03373
03374
03375
03376
03377
03378 ScrollRectangle3 = *ScrollRectangle;
03379
if (ScrollRectangle3.Left < ClipRectangle->Left) {
03380 ScrollRectangle3.Left = ClipRectangle->Left;
03381 }
03382
if (ScrollRectangle3.Top < ClipRectangle->Top) {
03383 ScrollRectangle3.Top = ClipRectangle->Top;
03384 }
03385
if (ScrollRectangle3.Right > ClipRectangle->Right) {
03386 ScrollRectangle3.Right = ClipRectangle->Right;
03387 }
03388
if (ScrollRectangle3.Bottom > ClipRectangle->Bottom) {
03389 ScrollRectangle3.Bottom = ClipRectangle->Bottom;
03390 }
03391
03392
03393
03394
03395
03396
if (ScrollRectangle3.Bottom < ScrollRectangle3.Top ||
03397 ScrollRectangle3.Right < ScrollRectangle3.Left) {
03398
return STATUS_SUCCESS;
03399 }
03400
03401
ConsoleHideCursor(ScreenInfo);
03402
03403
#if defined(FE_IME)
03404
Console->ConsoleIme.ScrollWaitCountDown = Console->ConsoleIme.ScrollWaitTimeout;
03405
#endif // FE_IME
03406
03407
03408
03409
03410
03411
if (!(TargetRectangle.Bottom < TargetRectangle.Top ||
03412 TargetRectangle.Right < TargetRectangle.Left)) {
03413
03414
03415
03416
03417
03418
03419
03420
03421
if (ScrollRectangle2.Right == TargetRectangle.Right &&
03422 ScrollRectangle2.Left == TargetRectangle.Left &&
03423 ScrollRectangle2.Top > TargetRectangle.Top &&
03424 ScrollRectangle2.Top < TargetRectangle.Bottom) {
03425
03426 SMALL_RECT
FillRect;
03427
SHORT LastRowIndex,OldRight,OldLeft;
03428
PROW Row;
03429
03430 TargetPoint.X = TargetRectangle.Left;
03431 TargetPoint.Y = TargetRectangle.Top;
03432
if (ScrollRectangle2.Right == (
SHORT)(ScreenInfo->ScreenBufferSize.X-1) &&
03433 ScrollRectangle2.Left == 0 &&
03434 ScrollRectangle2.Bottom == (
SHORT)(ScreenInfo->ScreenBufferSize.Y-1) &&
03435 ScrollRectangle2.Top == 1 ) {
03436 LastRowIndex =
ScrollEntireScreen(ScreenInfo,(
SHORT)(ScrollRectangle2.Top-TargetRectangle.Top),
TRUE);
03437 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[LastRowIndex];
03438 OldRight = Row->
CharRow.
OldRight;
03439 OldLeft = Row->
CharRow.
OldLeft;
03440 }
else {
03441 LastRowIndex = -1;
03442
CopyRectangle(ScreenInfo,
03443 &ScrollRectangle2,
03444 TargetPoint
03445 );
03446 }
03447
FillRect.Left = TargetRectangle.Left;
03448
FillRect.Right = TargetRectangle.Right;
03449
FillRect.Top = (
SHORT)(TargetRectangle.Bottom+1);
03450
FillRect.Bottom = ScrollRectangle->Bottom;
03451
if (
FillRect.Top < ClipRectangle->Top) {
03452
FillRect.Top = ClipRectangle->Top;
03453 }
03454
if (
FillRect.Bottom > ClipRectangle->Bottom) {
03455
FillRect.Bottom = ClipRectangle->Bottom;
03456 }
03457
FillRectangle(Fill,
03458 ScreenInfo,
03459 &
FillRect
03460 );
03461
03462
03463
03464
03465
03466
03467
03468
03469
if (LastRowIndex != -1) {
03470 Row->
CharRow.
OldRight = OldRight;
03471 Row->
CharRow.
OldLeft = OldLeft;
03472 }
03473
03474
03475
03476
03477
03478
03479
if (!(Console->
Flags &
CONSOLE_IS_ICONIC) ||
03480 Console->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
03481
ScrollScreen(ScreenInfo,
03482 &ScrollRectangle2,
03483 &
FillRect,
03484 TargetPoint
03485 );
03486 }
03487 }
03488
03489
03490
03491
03492
03493
else if (ScrollRectangle3.Right < TargetRectangle.Left ||
03494 ScrollRectangle3.Left > TargetRectangle.Right ||
03495 ScrollRectangle3.Top > TargetRectangle.Bottom ||
03496 ScrollRectangle3.Bottom < TargetRectangle.Top) {
03497 TargetPoint.X = TargetRectangle.Left;
03498 TargetPoint.Y = TargetRectangle.Top;
03499
CopyRectangle(ScreenInfo,
03500 &ScrollRectangle2,
03501 TargetPoint
03502 );
03503
FillRectangle(Fill,
03504 ScreenInfo,
03505 &ScrollRectangle3
03506 );
03507
03508
03509
03510
03511
03512
03513
if (!(Console->
Flags &
CONSOLE_IS_ICONIC) ||
03514 Console->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
03515
ScrollScreen(ScreenInfo,
03516 &ScrollRectangle2,
03517 &ScrollRectangle3,
03518 TargetPoint
03519 );
03520 }
03521 }
03522
03523
03524
03525
03526
03527
03528
else {
03529 SMALL_RECT TargetRect;
03530 COORD SourcePoint;
03531
03532
LockScrollBuffer();
03533
Size.X = (
SHORT)(ScrollRectangle2.Right - ScrollRectangle2.Left + 1);
03534
Size.Y = (
SHORT)(ScrollRectangle2.Bottom - ScrollRectangle2.Top + 1);
03535
if (
ScrollBufferSize < (
Size.X *
Size.Y *
sizeof(CHAR_INFO))) {
03536
FreeScrollBuffer();
03537
Status =
AllocateScrollBuffer(
Size.X *
Size.Y *
sizeof(CHAR_INFO));
03538
if (!
NT_SUCCESS(
Status)) {
03539
UnlockScrollBuffer();
03540
ConsoleShowCursor(ScreenInfo);
03541
return Status;
03542 }
03543 }
03544
03545 TargetRect.Left = 0;
03546 TargetRect.Top = 0;
03547 TargetRect.Right = ScrollRectangle2.Right - ScrollRectangle2.Left;
03548 TargetRect.Bottom = ScrollRectangle2.Bottom - ScrollRectangle2.Top;
03549 SourcePoint.X = ScrollRectangle2.Left;
03550 SourcePoint.Y = ScrollRectangle2.Top;
03551
ReadRectFromScreenBuffer(ScreenInfo,
03552 SourcePoint,
03553
ScrollBuffer,
03554
Size,
03555 &TargetRect
03556 );
03557
03558
FillRectangle(Fill,
03559 ScreenInfo,
03560 &ScrollRectangle3
03561 );
03562
03563 SourceRectangle.Top = 0;
03564 SourceRectangle.Left = 0;
03565 SourceRectangle.Right = (
SHORT)(
Size.X-1);
03566 SourceRectangle.Bottom = (
SHORT)(
Size.Y-1);
03567 TargetPoint.X = TargetRectangle.Left;
03568 TargetPoint.Y = TargetRectangle.Top;
03569
WriteRectToScreenBuffer((
PBYTE)
ScrollBuffer,
03570
Size,
03571 &SourceRectangle,
03572 ScreenInfo,
03573 TargetPoint,
03574 0xFFFFFFFF
03575 );
03576
UnlockScrollBuffer();
03577
03578
03579
03580
03581
03582
03583
if (!(Console->
Flags &
CONSOLE_IS_ICONIC) ||
03584 Console->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
03585
03586
03587
03588
03589
03590
ScrollScreen(ScreenInfo,
03591 &ScrollRectangle2,
03592 &ScrollRectangle3,
03593 TargetPoint
03594 );
03595 }
03596 }
03597 }
03598
else {
03599
03600
03601
03602
03603
03604
FillRectangle(Fill,
03605 ScreenInfo,
03606 &ScrollRectangle3
03607 );
03608
03609
03610
03611
03612
03613
03614
if (
ACTIVE_SCREEN_BUFFER(ScreenInfo) &&
03615 !(Console->
Flags &
CONSOLE_IS_ICONIC) ||
03616 Console->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
03617
WriteToScreen(ScreenInfo,&ScrollRectangle3);
03618 }
03619 }
03620
ConsoleShowCursor(ScreenInfo);
03621
return STATUS_SUCCESS;
03622 }
03623
03624
03625
NTSTATUS
03626 SetWindowOrigin(
03627 IN
PSCREEN_INFORMATION ScreenInfo,
03628 IN BOOLEAN Absolute,
03629 IN COORD WindowOrigin
03630 )
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652 {
03653 SMALL_RECT NewWindow;
03654 COORD WindowSize;
03655 RECT BoundingBox;
03656
BOOL Success;
03657 RECT ScrollRect;
03658 SMALL_RECT UpdateRegion;
03659 COORD FontSize;
03660
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
03661
03662
03663
03664
03665
03666 WindowSize.X = (
SHORT)
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
03667 WindowSize.Y = (
SHORT)
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
03668
03669
03670
03671
03672
03673
if (!Absolute) {
03674
if (WindowOrigin.X == 0 && WindowOrigin.Y == 0) {
03675
return STATUS_SUCCESS;
03676 }
03677 NewWindow.Left = ScreenInfo->Window.Left + WindowOrigin.X;
03678 NewWindow.Top = ScreenInfo->Window.Top + WindowOrigin.Y;
03679 }
03680
else {
03681
if (WindowOrigin.X == ScreenInfo->Window.Left &&
03682 WindowOrigin.Y == ScreenInfo->Window.Top) {
03683
return STATUS_SUCCESS;
03684 }
03685 NewWindow.Left = WindowOrigin.X;
03686 NewWindow.Top = WindowOrigin.Y;
03687 }
03688 NewWindow.Right = (
SHORT)(NewWindow.Left + WindowSize.X - 1);
03689 NewWindow.Bottom = (
SHORT)(NewWindow.Top + WindowSize.Y - 1);
03690
03691
03692
03693
03694
03695
03696
if (NewWindow.Left < 0 || NewWindow.Top < 0 ||
03697 NewWindow.Right < 0 || NewWindow.Bottom < 0 ||
03698 NewWindow.Right >= ScreenInfo->ScreenBufferSize.X ||
03699 NewWindow.Bottom >= ScreenInfo->ScreenBufferSize.Y) {
03700
return STATUS_INVALID_PARAMETER;
03701 }
03702
03703
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
03704 FontSize =
SCR_FONTSIZE(ScreenInfo);
03705 ScreenInfo->BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
03706 }
else {
03707 FontSize.X = 1;
03708 FontSize.Y = 1;
03709 }
03710
ConsoleHideCursor(ScreenInfo);
03711
if (
ACTIVE_SCREEN_BUFFER(ScreenInfo) &&
03712 Console->
FullScreenFlags == 0 &&
03713 !(Console->
Flags & (
CONSOLE_IS_ICONIC |
CONSOLE_NO_WINDOW))) {
03714
03715
InvertSelection(Console,
TRUE);
03716
#if defined(FE_SB)
03717
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) &&
03718 !(Console->ConsoleIme.ScrollFlag & HIDE_FOR_SCROLL)) {
03719 ConsoleImeBottomLineUse(ScreenInfo,0);
03720 }
03721
#endif
03722
if ( ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER
03723 &&
UsePolyTextOut
03724 && NewWindow.Left == ScreenInfo->Window.Left
03725 ) {
03726
ScrollEntireScreen(ScreenInfo,
03727 (
SHORT)(NewWindow.Top - ScreenInfo->Window.Top),
03728
FALSE);
03729 ScreenInfo->Window = NewWindow;
03730
WriteRegionToScreen(ScreenInfo, &NewWindow);
03731 }
else {
03732
#if defined(FE_SB)
03733
RECT ClipRect;
03734
#endif
03735
ScrollRect.left = 0;
03736 ScrollRect.right =
CONSOLE_WINDOW_SIZE_X(ScreenInfo)*FontSize.X;
03737 ScrollRect.top = 0;
03738
#if defined(FE_SB)
03739
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) &&
03740 Console->
InputBuffer.ImeMode.Open )
03741 {
03742
if (ScreenInfo->Window.Top <= NewWindow.Top)
03743 ScrollRect.bottom = (
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-1)*FontSize.Y;
03744
else
03745 ScrollRect.bottom = (
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-2)*FontSize.Y;
03746 ClipRect = ScrollRect;
03747 ClipRect.bottom = (
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-1)*FontSize.Y;
03748 }
03749
else
03750
#endif
03751
ScrollRect.bottom =
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)*FontSize.Y;
03752
03753
#if defined(FE_SB)
03754
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) &&
03755 ScrollRect.bottom == 0) {
03756 UpdateRegion.Left = 0;
03757 UpdateRegion.Top = 0;
03758 UpdateRegion.Right =
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
03759 UpdateRegion.Bottom = 0;
03760
WriteToScreen(ScreenInfo,&UpdateRegion);
03761 }
03762
else {
03763
#endif
03764
SCROLLDC_CALL;
03765
#if defined(FE_SB)
03766
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) &&
03767 Console->
InputBuffer.ImeMode.Open )
03768 {
03769 Success =
ScrollDC(Console->
hDC,
03770 (ScreenInfo->Window.Left-NewWindow.Left)*FontSize.X,
03771 (ScreenInfo->Window.Top-NewWindow.Top)*FontSize.Y,
03772 &ScrollRect,
03773 &ClipRect,
03774
NULL,
03775 &BoundingBox
03776 );
03777 }
03778
else
03779
#endif
03780
Success =
ScrollDC(Console->
hDC,
03781 (ScreenInfo->Window.Left-NewWindow.Left)*FontSize.X,
03782 (ScreenInfo->Window.Top-NewWindow.Top)*FontSize.Y,
03783 &ScrollRect,
03784
NULL,
03785
NULL,
03786 &BoundingBox
03787 );
03788
03789
if (Success) {
03790 UpdateRegion.Left = (
SHORT)((BoundingBox.left/FontSize.X)+NewWindow.Left);
03791 UpdateRegion.Right = (
SHORT)(((BoundingBox.right-1)/FontSize.X)+NewWindow.Left);
03792 UpdateRegion.Top = (
SHORT)((BoundingBox.top/FontSize.Y)+NewWindow.Top);
03793 UpdateRegion.Bottom = (
SHORT)(((BoundingBox.bottom-1)/FontSize.Y)+NewWindow.Top);
03794 }
03795
else {
03796 UpdateRegion = NewWindow;
03797 }
03798
03799
03800
03801
03802
03803 ScreenInfo->Window = NewWindow;
03804
03805
WriteToScreen(ScreenInfo,&UpdateRegion);
03806
#if defined(FE_SB)
03807
}
03808
#endif
03809
}
03810
InvertSelection(Console,
FALSE);
03811 }
03812
#ifdef i386
03813
else if (Console->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE &&
03814 ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
03815
03816
03817
03818
03819
03820
03821
if (ScreenInfo->BufferInfo.TextInfo.MousePosition.X < NewWindow.Left) {
03822 ScreenInfo->BufferInfo.TextInfo.MousePosition.X = NewWindow.Left;
03823 }
else if (ScreenInfo->BufferInfo.TextInfo.MousePosition.X > NewWindow.Right) {
03824 ScreenInfo->BufferInfo.TextInfo.MousePosition.X = NewWindow.Right;
03825 }
03826
03827
if (ScreenInfo->BufferInfo.TextInfo.MousePosition.Y < NewWindow.Top) {
03828 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y = NewWindow.Top;
03829 }
else if (ScreenInfo->BufferInfo.TextInfo.MousePosition.Y > NewWindow.Bottom) {
03830 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y = NewWindow.Bottom;
03831 }
03832 ScreenInfo->Window = NewWindow;
03833
WriteToScreen(ScreenInfo,&ScreenInfo->Window);
03834 }
03835
#endif
03836
else {
03837
03838 ScreenInfo->Window = NewWindow;
03839 }
03840
03841
#if defined(FE_SB)
03842
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) ) {
03843 ConsoleImeResizeModeSystemView(Console,ScreenInfo->Window);
03844 ConsoleImeResizeCompStrView(Console,ScreenInfo->Window);
03845 }
03846
#endif
03847
ConsoleShowCursor(ScreenInfo);
03848
03849
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
03850 ScreenInfo->BufferInfo.TextInfo.Flags |=
TEXT_VALID_HINT;
03851 }
03852
03853
UpdateScrollBars(ScreenInfo);
03854
return STATUS_SUCCESS;
03855 }
03856
03857
NTSTATUS
03858 ResizeWindow(
03859 IN
PSCREEN_INFORMATION ScreenInfo,
03860 IN PSMALL_RECT WindowDimensions,
03861 IN BOOL DoScrollBarUpdate
03862 )
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887 {
03888
03889
03890
03891
03892
if (RtlEqualMemory(&ScreenInfo->Window, WindowDimensions,
sizeof(SMALL_RECT))) {
03893
return STATUS_SUCCESS;
03894 }
03895
03896
if (WindowDimensions->Left < 0) {
03897 WindowDimensions->Right -= WindowDimensions->Left;
03898 WindowDimensions->Left = 0;
03899 }
03900
if (WindowDimensions->Top < 0) {
03901 WindowDimensions->Bottom -= WindowDimensions->Top;
03902 WindowDimensions->Top = 0;
03903 }
03904
03905
if (WindowDimensions->Right >= ScreenInfo->ScreenBufferSize.X) {
03906 WindowDimensions->Right = ScreenInfo->ScreenBufferSize.X;
03907 }
03908
if (WindowDimensions->Bottom >= ScreenInfo->ScreenBufferSize.Y) {
03909 WindowDimensions->Bottom = ScreenInfo->ScreenBufferSize.Y;
03910 }
03911
03912 ScreenInfo->Window = *WindowDimensions;
03913 ScreenInfo->WindowMaximizedX = (
CONSOLE_WINDOW_SIZE_X(ScreenInfo) == ScreenInfo->ScreenBufferSize.X);
03914 ScreenInfo->WindowMaximizedY = (
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) == ScreenInfo->ScreenBufferSize.Y);
03915
03916
if (DoScrollBarUpdate) {
03917
UpdateScrollBars(ScreenInfo);
03918 }
03919
03920
if (!(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER)) {
03921
return STATUS_SUCCESS;
03922 }
03923
03924
if (
ACTIVE_SCREEN_BUFFER(ScreenInfo)) {
03925 ScreenInfo->BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
03926 }
03927
03928
#ifdef i386
03929
if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
03930
03931
03932
03933
03934
03935
if (ScreenInfo->BufferInfo.TextInfo.MousePosition.X < WindowDimensions->Left) {
03936 ScreenInfo->BufferInfo.TextInfo.MousePosition.X = WindowDimensions->Left;
03937 }
else if (ScreenInfo->BufferInfo.TextInfo.MousePosition.X > WindowDimensions->Right) {
03938 ScreenInfo->BufferInfo.TextInfo.MousePosition.X = WindowDimensions->Right;
03939 }
03940
03941
if (ScreenInfo->BufferInfo.TextInfo.MousePosition.Y < WindowDimensions->Top) {
03942 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y = WindowDimensions->Top;
03943 }
else if (ScreenInfo->BufferInfo.TextInfo.MousePosition.Y > WindowDimensions->Bottom) {
03944 ScreenInfo->BufferInfo.TextInfo.MousePosition.Y = WindowDimensions->Bottom;
03945 }
03946 }
03947
#endif
03948
03949
return(STATUS_SUCCESS);
03950 }
03951
03952
VOID
03953 SetWindowSize(
03954 IN
PSCREEN_INFORMATION ScreenInfo
03955 )
03956 {
03957
#if defined(FE_IME)
03958
if (ScreenInfo->ConvScreenInfo !=
NULL)
03959
return;
03960
#endif
03961
if (ScreenInfo->Console->Flags &
CONSOLE_SETTING_WINDOW_SIZE)
03962
return;
03963 ScreenInfo->Console->Flags |=
CONSOLE_SETTING_WINDOW_SIZE;
03964
PostMessage(ScreenInfo->Console->hWnd,
03965
CM_SET_WINDOW_SIZE,
03966 (WPARAM)ScreenInfo,
03967 0x47474747
03968 );
03969 }
03970
03971
VOID
03972 UpdateWindowSize(
03973 IN
PCONSOLE_INFORMATION Console,
03974 IN
PSCREEN_INFORMATION ScreenInfo
03975 )
03976 {
03977 LONG WindowStyle;
03978
03979
if (!(Console->Flags &
CONSOLE_IS_ICONIC)) {
03980
InternalUpdateScrollBars(ScreenInfo);
03981
03982 WindowStyle = GetWindowLong(Console->hWnd, GWL_STYLE);
03983
if (ScreenInfo->WindowMaximized) {
03984 WindowStyle |= WS_MAXIMIZE;
03985 }
else {
03986 WindowStyle &= ~WS_MAXIMIZE;
03987 }
03988 SetWindowLong(Console->hWnd, GWL_STYLE, WindowStyle);
03989
03990
SetWindowPos(Console->hWnd,
NULL,
03991 0,
03992 0,
03993 Console->WindowRect.right-Console->WindowRect.left,
03994 Console->WindowRect.bottom-Console->WindowRect.top,
03995 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DRAWFRAME
03996 );
03997 Console->ResizeFlags &= ~
SCREEN_BUFFER_CHANGE;
03998 }
else {
03999 Console->ResizeFlags |=
SCREEN_BUFFER_CHANGE;
04000 }
04001 }
04002
04003
NTSTATUS
04004 InternalSetWindowSize(
04005 IN
PCONSOLE_INFORMATION Console,
04006 IN
PSCREEN_INFORMATION ScreenInfo,
04007 IN PSMALL_RECT Window
04008 )
04009 {
04010 SIZE WindowSize;
04011 WORD WindowSizeX, WindowSizeY;
04012
04013 Console->Flags &= ~
CONSOLE_SETTING_WINDOW_SIZE;
04014
if (Console->CurrentScreenBuffer == ScreenInfo) {
04015
if (Console->FullScreenFlags == 0) {
04016
04017
04018
04019
04020
if (
gfInitSystemMetrics) {
04021
InitializeSystemMetrics();
04022 }
04023
04024
04025
04026
04027
04028
04029 ScreenInfo->ResizingWindow++;
04030 WindowSizeX =
WINDOW_SIZE_X(Window);
04031 WindowSizeY =
WINDOW_SIZE_Y(Window);
04032
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
04033 WindowSize.cx = WindowSizeX*
SCR_FONTSIZE(ScreenInfo).X;
04034 WindowSize.cy = WindowSizeY*
SCR_FONTSIZE(ScreenInfo).Y;
04035 }
else {
04036 WindowSize.cx = WindowSizeX;
04037 WindowSize.cy = WindowSizeY;
04038 }
04039 WindowSize.cx +=
VerticalClientToWindow;
04040 WindowSize.cy +=
HorizontalClientToWindow;
04041
04042
if (WindowSizeY != 0) {
04043
if (!ScreenInfo->WindowMaximizedX) {
04044 WindowSize.cy +=
HorizontalScrollSize;
04045 }
04046
if (!ScreenInfo->WindowMaximizedY) {
04047 WindowSize.cx +=
VerticalScrollSize;
04048 }
04049 }
04050
04051 Console->WindowRect.right = Console->WindowRect.left + WindowSize.cx;
04052 Console->WindowRect.bottom = Console->WindowRect.top + WindowSize.cy;
04053
04054
UpdateWindowSize(Console,ScreenInfo);
04055 ScreenInfo->ResizingWindow--;
04056 }
else if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
04057
WriteToScreen(ScreenInfo,&ScreenInfo->Window);
04058 }
04059
#if defined(FE_IME)
04060
if ( (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) &&
04061 (CONSOLE_IS_DBCS_OUTPUTCP(Console)))
04062 {
04063 ConsoleImeResizeModeSystemView(Console,Console->CurrentScreenBuffer->Window);
04064 ConsoleImeResizeCompStrView(Console,Console->CurrentScreenBuffer->Window);
04065 }
04066
#endif // FE_IME
04067
}
04068
return STATUS_SUCCESS;
04069 }
04070
04071
NTSTATUS
04072 SetActiveScreenBuffer(
04073 IN
PSCREEN_INFORMATION ScreenInfo
04074 )
04075 {
04076
PSCREEN_INFORMATION OldScreenInfo;
04077
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
04078
04079 OldScreenInfo = Console->
CurrentScreenBuffer;
04080
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
04081
04082
#if !defined(_X86_)
04083
if (Console->
FullScreenFlags & CONSOLE_FULLSCREEN) {
04084
return STATUS_INVALID_PARAMETER;
04085 }
04086
#endif
04087
Console->
CurrentScreenBuffer = ScreenInfo;
04088
04089
if (Console->
FullScreenFlags == 0) {
04090
04091
04092
04093
04094
04095 ScreenInfo->
BufferInfo.TextInfo.CursorOn =
FALSE;
04096
04097
04098
04099
04100
04101
SetFont(ScreenInfo);
04102 }
04103
#if defined(_X86_)
04104
else if (Console->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
04105
04106
if (!(Console->
Flags &
CONSOLE_VDM_REGISTERED)) {
04107
04108
if ( (!(OldScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER)) ||
04109 (OldScreenInfo->
BufferInfo.TextInfo.ModeIndex!=ScreenInfo->BufferInfo.TextInfo.ModeIndex)) {
04110
04111
04112 SetVideoMode(ScreenInfo);
04113 }
04114
04115
04116
04117 SetCursorInformationHW(ScreenInfo,
04118 ScreenInfo->BufferInfo.TextInfo.CursorSize,
04119 ScreenInfo->BufferInfo.TextInfo.CursorVisible);
04120 SetCursorPositionHW(ScreenInfo,
04121 ScreenInfo->BufferInfo.TextInfo.CursorPosition);
04122 }
04123
04124 }
04125
#endif
04126
}
04127
else {
04128 Console->
CurrentScreenBuffer = ScreenInfo;
04129 }
04130
04131
04132
04133
04134
04135
FlushAllButKeys(&Console->
InputBuffer);
04136
04137
if (Console->
FullScreenFlags == 0) {
04138
04139
SetScreenColors(ScreenInfo, ScreenInfo->Attributes,
04140 ScreenInfo->PopupAttributes,
FALSE);
04141
04142
04143
04144
04145
04146
SetWindowSize(ScreenInfo);
04147
04148
04149
04150
04151
04152
if (!(Console->
Flags &
CONSOLE_IS_ICONIC) &&
04153 Console->
FullScreenFlags == 0) {
04154
if (ScreenInfo->hPalette !=
NULL || OldScreenInfo->
hPalette !=
NULL) {
04155 HPALETTE hPalette;
04156
BOOL bReset =
FALSE;
04157 USERTHREAD_USEDESKTOPINFO utudi;
04158
04159
if (GetCurrentThreadId() != Console->
InputThreadInfo->
ThreadId) {
04160 bReset =
TRUE;
04161 utudi.hThread = Console->
InputThreadInfo->
ThreadHandle;
04162 utudi.drdRestore.pdeskRestore =
NULL;
04163
NtUserSetInformationThread(NtCurrentThread(),
04164 UserThreadUseDesktop,
04165 &utudi,
sizeof(utudi));
04166 }
04167
04168
if (ScreenInfo->hPalette ==
NULL) {
04169 hPalette = Console->
hSysPalette;
04170 }
else {
04171 hPalette = ScreenInfo->hPalette;
04172 }
04173
SelectPalette(Console->
hDC,
04174 hPalette,
04175
FALSE);
04176
SetActivePalette(ScreenInfo);
04177
04178
if (bReset ==
TRUE) {
04179 utudi.hThread =
NULL;
04180
NtUserSetInformationThread(NtCurrentThread(),
04181 UserThreadUseDesktop, &utudi,
sizeof(utudi));
04182 }
04183 }
04184 }
04185 }
04186
04187
#if defined(FE_IME)
04188
SetUndetermineAttribute(Console);
04189
#endif
04190
04191
04192
04193
04194 ScreenInfo->BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
04195
WriteToScreen(ScreenInfo,&ScreenInfo->Window);
04196
return STATUS_SUCCESS;
04197 }
04198
04199
VOID
04200 SetProcessFocus(
04201 IN PCSR_PROCESS Process,
04202 IN BOOL Foreground
04203 )
04204 {
04205
if (Foreground) {
04206 CsrSetForegroundPriority(Process);
04207 }
else {
04208 CsrSetBackgroundPriority(Process);
04209 }
04210 }
04211
04212
VOID
04213 SetProcessForegroundRights(
04214 IN PCSR_PROCESS Process,
04215 IN BOOL Foreground
04216 )
04217 {
04218 USERTHREAD_FLAGS Flags;
04219
04220 Flags.dwMask = (
W32PF_ALLOWSETFOREGROUND |
W32PF_CONSOLEHASFOCUS);
04221 Flags.dwFlags = (Foreground ? (
W32PF_ALLOWSETFOREGROUND |
W32PF_CONSOLEHASFOCUS) : 0);
04222
04223
NtUserSetInformationProcess(Process->ProcessHandle, UserProcessFlags, &Flags,
sizeof(Flags));
04224 }
04225
04226
VOID
04227 ModifyConsoleProcessFocus(
04228 IN
PCONSOLE_INFORMATION Console,
04229 IN BOOL Foreground
04230 )
04231 {
04232
PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
04233 PLIST_ENTRY ListHead, ListNext;
04234
04235 ListHead = &Console->ProcessHandleList;
04236 ListNext = ListHead->Flink;
04237
while (ListNext != ListHead) {
04238 ProcessHandleRecord = CONTAINING_RECORD( ListNext,
CONSOLE_PROCESS_HANDLE, ListLink );
04239 ListNext = ListNext->Flink;
04240 {
04241
SetProcessFocus(ProcessHandleRecord->
Process, Foreground);
04242
SetProcessForegroundRights(ProcessHandleRecord->
Process, Foreground);
04243 }
04244 }
04245 }
04246
04247
VOID
04248 TrimConsoleWorkingSet(
04249 IN
PCONSOLE_INFORMATION Console
04250 )
04251 {
04252
PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
04253 PLIST_ENTRY ListHead, ListNext;
04254
04255 ListHead = &Console->ProcessHandleList;
04256 ListNext = ListHead->Flink;
04257
while (ListNext != ListHead) {
04258 ProcessHandleRecord = CONTAINING_RECORD( ListNext,
CONSOLE_PROCESS_HANDLE, ListLink );
04259 ListNext = ListNext->Flink;
04260 {
04261 SetProcessWorkingSetSize(ProcessHandleRecord->
Process->ProcessHandle,(SIZE_T)-1,(SIZE_T)-1);
04262 }
04263 }
04264 }
04265
04266
NTSTATUS
04267 QueueConsoleMessage(
04268
PCONSOLE_INFORMATION Console,
04269 UINT Message,
04270 WPARAM wParam,
04271 LPARAM lParam
04272 )
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297 {
04298
PCONSOLE_MSG pConMsg;
04299
04300
ASSERT(
ConsoleLocked(Console));
04301
04302 pConMsg = (
PCONSOLE_MSG)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),
sizeof(
CONSOLE_MSG));
04303
if (pConMsg ==
NULL) {
04304
return STATUS_NO_MEMORY;
04305 }
04306
04307 pConMsg->
Message = Message;
04308 pConMsg->
wParam = wParam;
04309 pConMsg->
lParam = lParam;
04310
04311 InsertHeadList(&Console->
MessageQueue, &pConMsg->
ListLink);
04312
04313
if (!
PostMessage(Console->
hWnd,
CM_CONSOLE_MSG, 0, 0)) {
04314 RemoveEntryList(&pConMsg->
ListLink);
04315
ConsoleHeapFree(pConMsg);
04316
return STATUS_UNSUCCESSFUL;
04317 }
04318
04319
return STATUS_SUCCESS;
04320 }
04321
04322
BOOL
04323 UnqueueConsoleMessage(
04324
PCONSOLE_INFORMATION Console,
04325 UINT *pMessage,
04326 WPARAM *pwParam,
04327 LPARAM *plParam
04328 )
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351
04352 {
04353 PLIST_ENTRY pEntry;
04354
PCONSOLE_MSG pConMsg =
NULL;
04355
04356
ASSERT(
ConsoleLocked(Console));
04357
04358
if (IsListEmpty(&Console->
MessageQueue)) {
04359
return FALSE;
04360 }
04361
04362 pEntry = RemoveTailList(&Console->
MessageQueue);
04363 pConMsg = CONTAINING_RECORD(pEntry,
CONSOLE_MSG, ListLink);
04364
04365 *pMessage = pConMsg->
Message;
04366 *pwParam = pConMsg->
wParam;
04367 *plParam = pConMsg->
lParam;
04368
04369
ConsoleHeapFree(pConMsg);
04370
04371
return TRUE;
04372 }
04373
04374
VOID
04375 CleanupConsoleMessages(
04376
PCONSOLE_INFORMATION Console
04377 )
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395 {
04396
UINT Message;
04397 WPARAM wParam;
04398 LPARAM lParam;
04399
04400
while (
UnqueueConsoleMessage(Console, &Message, &wParam, &lParam)) {
04401
switch (Message) {
04402
case CM_MODE_TRANSITION:
04403
NtSetEvent((HANDLE)lParam,
NULL);
04404
NtClose((HANDLE)lParam);
04405
break;
04406
case CM_SET_IME_CODEPAGE:
04407
case CM_SET_NLSMODE:
04408
case CM_GET_NLSMODE:
04409
if (wParam) {
04410
NtSetEvent((HANDLE)wParam,
NULL);
04411
NtClose((HANDLE)wParam);
04412 }
04413
break;
04414
default:
04415 KdPrint((
"CONSRV: CleanupConsoleMessages - unknown message %x\n", Message));
04416
ASSERT(
FALSE);
04417
break;
04418 }
04419 }
04420 }
04421
04422
VOID
04423 AbortCreateConsole(
04424 IN
PCONSOLE_INFORMATION Console
04425 )
04426 {
04427
04428
04429
04430
04431
NtSetEvent(Console->InitEvents[
INITIALIZATION_FAILED],
NULL);
04432
04433
04434
04435
04436
04437 CloseHandle(Console->ClientThreadHandle);
04438
FreeInputBuffer(&Console->InputBuffer);
04439
ConsoleHeapFree(Console->Title);
04440
ConsoleHeapFree(Console->OriginalTitle);
04441
NtClose(Console->InitEvents[
INITIALIZATION_SUCCEEDED]);
04442
NtClose(Console->InitEvents[
INITIALIZATION_FAILED]);
04443
NtClose(Console->TerminationEvent);
04444
FreeAliasBuffers(Console);
04445
FreeCommandHistoryBuffers(Console);
04446
#if defined(FE_SB)
04447
FreeLocalEUDC(Console);
04448
DestroyFontCache(Console->FontCacheInformation);
04449
#endif
04450
DestroyConsole(Console);
04451 }
04452
04453
VOID
04454 DestroyWindowsWindow(
04455 IN
PCONSOLE_INFORMATION Console
04456 )
04457 {
04458
PSCREEN_INFORMATION Cur,Next;
04459 HWND
hWnd = Console->hWnd;
04460
04461
gnConsoleWindows--;
04462 Console->InputThreadInfo->WindowCount--;
04463
04464
SetWindowConsole(
hWnd,
NULL);
04465
04466 KillTimer(Console->hWnd,
CURSOR_TIMER);
04467
04468
if (Console->hWndProperties) {
04469
SendMessage(Console->hWndProperties, WM_CLOSE, 0, 0);
04470 }
04471
04472
04473
if (Console->FonthDC) {
04474
ReleaseDC(
NULL, Console->FonthDC);
04475 DeleteObject(Console->hBitmap);
04476 }
04477
DeleteEUDC(Console);
04478
04479
04480
if (
CONSOLE_IS_IME_ENABLED()) {
04481
if (!(Console->Flags &
CONSOLE_NO_WINDOW)) {
04482
04483 KillTimer(Console->hWnd, SCROLL_WAIT_TIMER);
04484 }
04485 ConsoleImeMessagePump(Console,
04486
CONIME_DESTROY,
04487 (WPARAM)Console->ConsoleHandle,
04488 (LPARAM)
NULL
04489 );
04490 }
04491
04492
04493
04494
CleanupConsoleMessages(Console);
04495
04496
ReleaseDC(
NULL, Console->hDC);
04497 Console->hDC =
NULL;
04498
04499
DestroyWindow(Console->hWnd);
04500 Console->hWnd =
NULL;
04501
04502
04503
04504
04505
04506
ReplyMessage(0);
04507
04508
04509
04510
04511
04512
ClearKeyInfo(
hWnd);
04513
04514
if (Console->hIcon !=
NULL && Console->hIcon !=
ghDefaultIcon) {
04515
DestroyIcon(Console->hIcon);
04516 }
04517
if (Console->hSmIcon !=
NULL && Console->hSmIcon !=
ghDefaultSmIcon) {
04518
DestroyIcon(Console->hSmIcon);
04519 }
04520
04521
04522
04523
04524
04525
04526 CloseHandle(Console->ClientThreadHandle);
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
for (Cur=Console->ScreenBuffers;Cur!=
NULL;Cur=Next) {
04539 Next = Cur->
Next;
04540
FreeScreenBuffer(Cur);
04541 }
04542
04543
FreeAliasBuffers(Console);
04544
FreeCommandHistoryBuffers(Console);
04545
04546
04547
04548
04549
04550
FreeInputBuffer(&Console->InputBuffer);
04551
ConsoleHeapFree(Console->Title);
04552
ConsoleHeapFree(Console->OriginalTitle);
04553
NtClose(Console->InitEvents[
INITIALIZATION_SUCCEEDED]);
04554
NtClose(Console->InitEvents[
INITIALIZATION_FAILED]);
04555
NtClose(Console->TerminationEvent);
04556
if (Console->hWinSta !=
NULL) {
04557 CloseDesktop(Console->hDesk);
04558
CloseWindowStation(Console->hWinSta);
04559 }
04560
if (Console->VDMProcessHandle)
04561 CloseHandle(Console->VDMProcessHandle);
04562
ASSERT(!(Console->Flags &
CONSOLE_VDM_REGISTERED));
04563
04564
04565
04566
04567
#if defined(FE_SB)
04568
FreeLocalEUDC(Console);
04569
DestroyFontCache(Console->FontCacheInformation);
04570
#endif
04571
DestroyConsole(Console);
04572 }
04573
04574
VOID
04575 VerticalScroll(
04576 IN
PCONSOLE_INFORMATION Console,
04577 IN
PSCREEN_INFORMATION ScreenInfo,
04578 IN WORD ScrollCommand,
04579 IN WORD AbsoluteChange
04580 )
04581 {
04582 COORD NewOrigin;
04583
04584 NewOrigin.X = ScreenInfo->Window.Left;
04585 NewOrigin.Y = ScreenInfo->Window.Top;
04586
switch (ScrollCommand) {
04587
case SB_LINEUP:
04588 NewOrigin.Y--;
04589
break;
04590
case SB_LINEDOWN:
04591 NewOrigin.Y++;
04592
break;
04593
case SB_PAGEUP:
04594
#if defined(FE_IME)
04595
04596
04597
if ( ScreenInfo->Console->InputBuffer.ImeMode.Open )
04598 {
04599
ASSERT(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER);
04600
if (!(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER)) {
04601
return;
04602 }
04603 NewOrigin.Y-=
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-2;
04604 ScreenInfo->BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
04605 ScreenInfo->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
04606 }
04607
else
04608
#endif // FE_IME
04609
NewOrigin.Y-=
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-1;
04610
break;
04611
case SB_PAGEDOWN:
04612
#if defined(FE_IME)
04613
04614
04615
if ( ScreenInfo->Console->InputBuffer.ImeMode.Open )
04616 {
04617 NewOrigin.Y+=
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-2;
04618 ScreenInfo->BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
04619 ScreenInfo->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
04620 }
04621
else
04622
#endif // FE_IME
04623
NewOrigin.Y+=
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-1;
04624
break;
04625
case SB_THUMBTRACK:
04626 Console->Flags |=
CONSOLE_SCROLLBAR_TRACKING;
04627 NewOrigin.Y= AbsoluteChange;
04628
break;
04629
case SB_THUMBPOSITION:
04630
UnblockWriteConsole(Console,
CONSOLE_SCROLLBAR_TRACKING);
04631 NewOrigin.Y= AbsoluteChange;
04632
break;
04633
case SB_TOP:
04634 NewOrigin.Y=0;
04635
break;
04636
case SB_BOTTOM:
04637 NewOrigin.Y=(WORD)(ScreenInfo->ScreenBufferSize.Y-
CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
04638
break;
04639
04640
default:
04641
return;
04642 }
04643
04644 NewOrigin.Y = (WORD)(
max(0,
min((
SHORT)NewOrigin.Y,
04645 (
SHORT)ScreenInfo->ScreenBufferSize.Y-(
SHORT)
CONSOLE_WINDOW_SIZE_Y(ScreenInfo))));
04646
SetWindowOrigin(ScreenInfo,
04647 (BOOLEAN)
TRUE,
04648 NewOrigin
04649 );
04650 }
04651
04652
VOID
04653 HorizontalScroll(
04654 IN
PSCREEN_INFORMATION ScreenInfo,
04655 IN WORD ScrollCommand,
04656 IN WORD AbsoluteChange
04657 )
04658 {
04659 COORD NewOrigin;
04660
04661 NewOrigin.X = ScreenInfo->Window.Left;
04662 NewOrigin.Y = ScreenInfo->Window.Top;
04663
switch (ScrollCommand) {
04664
case SB_LINEUP:
04665 NewOrigin.X--;
04666
break;
04667
case SB_LINEDOWN:
04668 NewOrigin.X++;
04669
break;
04670
case SB_PAGEUP:
04671 NewOrigin.X-=
CONSOLE_WINDOW_SIZE_X(ScreenInfo)-1;
04672
break;
04673
case SB_PAGEDOWN:
04674 NewOrigin.X+=
CONSOLE_WINDOW_SIZE_X(ScreenInfo)-1;
04675
break;
04676
case SB_THUMBTRACK:
04677
case SB_THUMBPOSITION:
04678 NewOrigin.X= AbsoluteChange;
04679
break;
04680
case SB_TOP:
04681 NewOrigin.X=0;
04682
break;
04683
case SB_BOTTOM:
04684 NewOrigin.X=(WORD)(ScreenInfo->ScreenBufferSize.X-
CONSOLE_WINDOW_SIZE_X(ScreenInfo));
04685
break;
04686
04687
default:
04688
return;
04689 }
04690
04691 NewOrigin.X = (WORD)(
max(0,
min((
SHORT)NewOrigin.X,
04692 (
SHORT)ScreenInfo->ScreenBufferSize.X-(
SHORT)
CONSOLE_WINDOW_SIZE_X(ScreenInfo))));
04693
SetWindowOrigin(ScreenInfo,
04694 (BOOLEAN)
TRUE,
04695 NewOrigin
04696 );
04697 }
04698
04699 LRESULT
APIENTRY
04700 ConsoleWindowProc(
04701 HWND hWnd,
04702 UINT Message,
04703 WPARAM wParam,
04704 LPARAM lParam
04705 )
04706 {
04707 HDC hDC;
04708 PAINTSTRUCT ps;
04709
PCONSOLE_INFORMATION Console;
04710
PSCREEN_INFORMATION ScreenInfo;
04711 SMALL_RECT
PaintRect;
04712 LRESULT
Status;
04713
04714 Console =
GetWindowConsole(
hWnd);
04715
if (Console !=
NULL) {
04716
04717
04718
04719
04720
04721
04722 CSR_SERVER_QUERYCLIENTTHREAD()->ThreadHandle =
04723 Console->
ClientThreadHandle;
04724
04725
04726
04727
04728
04729
if (Console->
Flags &
CONSOLE_TERMINATING) {
04730
LockConsole(Console);
04731
DestroyWindowsWindow(Console);
04732
return 0;
04733 }
04734
04735
04736
04737
04738
ASSERT(
NT_SUCCESS(
ValidateConsole(Console)));
04739
04740
LockConsole(Console);
04741
04742 ScreenInfo = Console->
CurrentScreenBuffer;
04743 }
04744
try {
04745
if (Console ==
NULL || ScreenInfo ==
NULL) {
04746
switch (Message) {
04747
case WM_GETMINMAXINFO:
04748 {
04749
04750
04751
04752
04753
04754
04755
04756
04757 LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam;
04758 lpmmi->ptMaxTrackSize.y +=
HorizontalScrollSize;
04759 lpmmi->ptMaxTrackSize.x +=
VerticalScrollSize;
04760 }
04761
break;
04762
04763
default:
04764
goto CallDefWin;
04765 }
04766 }
else if (Message ==
ProgmanHandleMessage && lParam==0) {
04767
04768
04769
Status = 0;
04770
04771
04772
04773
if ((HWND)wParam !=
hWnd && Console->
bIconInit) {
04774 ATOM App,Topic;
04775
CHAR szItem[
ITEM_MAX_SIZE+1];
04776 PCHAR lpItem;
04777 ATOM aItem;
04778 HANDLE ConsoleHandle;
04779
04780
if (!(Console->
Flags &
CONSOLE_TERMINATING)) {
04781 ConsoleHandle = Console->
ConsoleHandle;
04782 Console->
hWndProgMan = (HWND)wParam;
04783
UnlockConsole(Console);
04784 App = GlobalAddAtomA(
"Shell");
04785 Topic = GlobalAddAtomA(
"AppIcon");
04786
SendMessage(Console->
hWndProgMan,
04787 WM_DDE_INITIATE,
04788 (WPARAM)
hWnd,
04789 MAKELONG(App,Topic)
04790 );
04791
04792
04793
Status =
RevalidateConsole(ConsoleHandle, &Console);
04794
if (
NT_SUCCESS(
Status)) {
04795 Console->
bIconInit =
FALSE;
04796 lpItem = _itoa((
int)Console->
iIconId,szItem,10);
04797 aItem = GlobalAddAtomA(lpItem);
04798
PostMessage(Console->
hWndProgMan,
04799 WM_DDE_REQUEST,
04800 (WPARAM)
hWnd,
04801 MAKELONG(CF_TEXT,aItem)
04802 );
04803 }
04804 }
04805 }
04806 }
else {
04807
Status = 0;
04808
switch (Message) {
04809
case WM_DROPFILES:
04810
DoDrop (wParam,Console);
04811
break;
04812
case WM_MOVE:
04813
if (!
IsIconic(
hWnd)) {
04814
PositionConsoleWindow(Console, (Console->
WindowRect.left == CW_USEDEFAULT));
04815
#if defined(FE_IME)
04816
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
04817 {
04818 ConsoleImeResizeModeSystemView(Console,ScreenInfo->
Window);
04819 ConsoleImeResizeCompStrView(Console,ScreenInfo->
Window);
04820 }
04821
#endif // FE_IME
04822
}
04823
break;
04824
case WM_SIZE:
04825
04826
if (wParam != SIZE_MINIMIZED) {
04827
04828
04829
04830
04831
04832
04833
04834
if (!ScreenInfo->
ResizingWindow) {
04835
#ifdef THERESES_DEBUG
04836
DbgPrint(
"WM_SIZE message ");
04837
if (wParam == SIZEFULLSCREEN)
04838
DbgPrint(
"SIZEFULLSCREEN\n");
04839
else if (wParam == SIZENORMAL)
04840
DbgPrint(
"SIZENORMAL\n");
04841
DbgPrint(
" WindowSize is %d %d\n",
CONSOLE_WINDOW_SIZE_X(ScreenInfo),
CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
04842
#endif
04843
ScreenInfo->
WindowMaximized = (wParam == SIZE_MAXIMIZED);
04844
04845
if (Console->
ResizeFlags &
SCREEN_BUFFER_CHANGE) {
04846
UpdateWindowSize(Console,ScreenInfo);
04847 }
04848
PositionConsoleWindow(Console, (Console->
WindowRect.left == CW_USEDEFAULT));
04849
#if defined(FE_IME)
04850
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
04851 {
04852 ConsoleImeResizeModeSystemView(Console,ScreenInfo->
Window);
04853 ConsoleImeResizeCompStrView(Console,ScreenInfo->
Window);
04854 }
04855
#endif // FE_IME
04856
#ifdef THERESES_DEBUG
04857
DbgPrint(
" WindowRect is now %d %d %d %d\n",Console->
WindowRect.left,
04858 Console->
WindowRect.top,
04859 Console->
WindowRect.right,
04860 Console->
WindowRect.bottom);
04861
#endif
04862
if (Console->
ResizeFlags &
SCROLL_BAR_CHANGE) {
04863
InternalUpdateScrollBars(ScreenInfo);
04864 Console->
ResizeFlags &= ~
SCROLL_BAR_CHANGE;
04865 }
04866 }
04867 }
else {
04868
04869
04870
04871
04872
04873
04874
TrimConsoleWorkingSet(Console);
04875
04876 }
04877
04878
break;
04879
case WM_DDE_ACK:
04880
if (Console->
bIconInit) {
04881 Console->
hWndProgMan = (HWND)wParam;
04882 }
04883
break;
04884
case WM_DDE_DATA:
04885 {
04886 DDEDATA *lpDDEData;
04887
LPPMICONDATA lpIconData;
04888 HICON hIcon;
04889 HANDLE hDdeData;
04890
BOOL bRelease;
04891 WPARAM atomTemp;
04892
04893
UnpackDDElParam(WM_DDE_DATA, lParam, (WPARAM *)&hDdeData, &atomTemp);
04894
04895
if (hDdeData ==
NULL) {
04896
break;
04897 }
04898 lpDDEData = (DDEDATA *)GlobalLock(hDdeData);
04899
ASSERT(lpDDEData->cfFormat == CF_TEXT);
04900 lpIconData = (
LPPMICONDATA)lpDDEData->Value;
04901 hIcon =
CreateIconFromResourceEx(&lpIconData->
iResource,
04902 0,
TRUE, 0x30000, 0, 0, LR_DEFAULTSIZE);
04903
if (hIcon) {
04904
if (Console->
hIcon !=
NULL && Console->
hIcon !=
ghDefaultIcon) {
04905
DestroyIcon(Console->
hIcon);
04906 }
04907 Console->
hIcon = hIcon;
04908
SendMessage(
hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
04909
04910
if (Console->
hSmIcon !=
NULL) {
04911
if (Console->
hSmIcon !=
ghDefaultSmIcon) {
04912
DestroyIcon(Console->
hSmIcon);
04913 }
04914 Console->
hSmIcon =
NULL;
04915
SendMessage(
hWnd, WM_SETICON, ICON_SMALL, (LPARAM)
NULL);
04916 }
04917 }
04918
04919
if (lpDDEData->fAckReq) {
04920
04921
PostMessage(Console->
hWndProgMan,
04922 WM_DDE_ACK,
04923 (WPARAM)
hWnd,
04924
ReuseDDElParam(lParam, WM_DDE_DATA, WM_DDE_ACK, 0x8000, atomTemp));
04925 }
04926
04927 bRelease = lpDDEData->fRelease;
04928 GlobalUnlock(hDdeData);
04929
if (bRelease){
04930 GlobalFree(hDdeData);
04931 }
04932
PostMessage(Console->
hWndProgMan,
04933 WM_DDE_TERMINATE,
04934 (WPARAM)
hWnd,
04935 0
04936 );
04937
if (Console->
Flags &
CONSOLE_IS_ICONIC) {
04938
04939 InvalidateRect(
hWnd,
NULL,
TRUE);
04940 }
04941 }
04942
break;
04943
case WM_ACTIVATE:
04944
04945
04946
04947
04948
04949
04950
if (LOWORD(wParam) == WA_CLICKACTIVE) {
04951 Console->
Flags |=
CONSOLE_IGNORE_NEXT_MOUSE_INPUT;
04952 }
04953
goto CallDefWin;
04954
break;
04955
case WM_DDE_TERMINATE:
04956
break;
04957
04958
case CM_CONIME_KL_ACTIVATE:
04959
ActivateKeyboardLayout((HKL)wParam, KLF_SETFORPROCESS);
04960
break;
04961
case WM_INPUTLANGCHANGEREQUEST:
04962
if (
CONSOLE_IS_IME_ENABLED()) {
04963 ULONG ConimeMessage;
04964 LRESULT lResult;
04965
04966
if (wParam & INPUTLANGCHANGE_BACKWARD) {
04967 ConimeMessage =
CONIME_INPUTLANGCHANGEREQUESTBACKWARD;
04968 }
04969
else if (wParam & INPUTLANGCHANGE_FORWARD) {
04970 ConimeMessage =
CONIME_INPUTLANGCHANGEREQUESTFORWARD;
04971 }
04972
else {
04973 ConimeMessage =
CONIME_INPUTLANGCHANGEREQUEST;
04974 }
04975
04976
if (!
NT_SUCCESS(ConsoleImeMessagePumpWorker(Console,
04977 ConimeMessage,
04978 (WPARAM)Console->
ConsoleHandle,
04979 (LPARAM)lParam,
04980 &lResult)) ||
04981 !lResult) {
04982
04983
break;
04984 }
04985 }
04986
#ifdef LATER
04987
else if (
IS_IME_KBDLAYOUT(lParam)) {
04988
04989
04990
break;
04991 }
04992
04993
04994
#endif
04995
goto CallDefWin;
04996
04997
break;
04998
04999
05000
case WM_INPUTLANGCHANGE:
05001 Console->
hklActive = (HKL)lParam;
05002
05003
if (
CONSOLE_IS_IME_ENABLED()) {
05004
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
05005
CONIME_INPUTLANGCHANGE,
05006 (WPARAM)Console->
ConsoleHandle,
05007 (LPARAM)Console->
hklActive
05008 ))) {
05009
break;
05010 }
05011
else{
05012 GetImeKeyState(Console,
NULL) ;
05013 }
05014 }
05015
05016
goto CallDefWin;
05017
05018
break;
05019
05020
case WM_SETFOCUS:
05021
ModifyConsoleProcessFocus(Console,
TRUE);
05022
SetConsoleReserveKeys(
hWnd, Console->
ReserveKeys);
05023 Console->
Flags |=
CONSOLE_HAS_FOCUS;
05024
05025
SetTimer(
hWnd,
CURSOR_TIMER,
guCaretBlinkTime,
NULL);
05026
HandleFocusEvent(Console,
TRUE);
05027
if (!Console->
hklActive) {
05028
SystemParametersInfo(SPI_GETDEFAULTINPUTLANG, 0, &Console->
hklActive,
FALSE);
05029
GetNonBiDiKeyboardLayout(&Console->
hklActive);
05030 }
05031
ActivateKeyboardLayout(Console->
hklActive, 0);
05032
05033
if (
CONSOLE_IS_IME_ENABLED()) {
05034
05035
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
05036
CONIME_SETFOCUS,
05037 (WPARAM)Console->
ConsoleHandle,
05038 (LPARAM)Console->
hklActive
05039 ))) {
05040
break;
05041 }
05042
05043
if (Console->
InputBuffer.hWndConsoleIME)
05044 {
05045
05046
05047
05048
05049
05050 HWND hwnd =
GetLastActivePopup(Console->
InputBuffer.hWndConsoleIME);
05051
if (hwnd !=
NULL)
05052
SetForegroundWindow(hwnd);
05053 }
05054 }
05055
05056
break;
05057
case WM_KILLFOCUS:
05058
ModifyConsoleProcessFocus(Console,
FALSE);
05059
SetConsoleReserveKeys(
hWnd, CONSOLE_NOSHORTCUTKEY);
05060 Console->
Flags &= ~
CONSOLE_HAS_FOCUS;
05061
05062
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
05063
ConsoleHideCursor(ScreenInfo);
05064 ScreenInfo->
BufferInfo.TextInfo.UpdatingScreen -= 1;
05065 }
05066 KillTimer(
hWnd,
CURSOR_TIMER);
05067
HandleFocusEvent(Console,
FALSE);
05068
05069
05070
if (
CONSOLE_IS_IME_ENABLED()) {
05071
05072
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
05073
CONIME_KILLFOCUS,
05074 (WPARAM)Console->
ConsoleHandle,
05075 (LPARAM)
NULL
05076 ))) {
05077
break;
05078 }
05079 }
05080
05081
break;
05082
case WM_PAINT:
05083
05084
05085
05086
05087
ConsoleHideCursor(ScreenInfo);
05088 hDC =
BeginPaint(
hWnd, &ps);
05089
if (Console->
Flags &
CONSOLE_IS_ICONIC ||
05090 Console->
FullScreenFlags == CONSOLE_FULLSCREEN) {
05091 RECT rc;
05092
UINT cxIcon, cyIcon;
05093
GetClientRect(
hWnd, &rc);
05094 cxIcon =
GetSystemMetrics(SM_CXICON);
05095 cyIcon =
GetSystemMetrics(SM_CYICON);
05096
05097 rc.left = (rc.right - cxIcon) >> 1;
05098 rc.top = (rc.bottom - cyIcon) >> 1;
05099
05100
DrawIcon(hDC, rc.left, rc.top, Console->
hIcon);
05101 }
else {
05102
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
05103
PaintRect.Left = (
SHORT)((ps.rcPaint.left/
SCR_FONTSIZE(ScreenInfo).X)+ScreenInfo->
Window.Left);
05104
PaintRect.Right = (
SHORT)((ps.rcPaint.right/
SCR_FONTSIZE(ScreenInfo).X)+ScreenInfo->
Window.Left);
05105
PaintRect.Top = (
SHORT)((ps.rcPaint.top/
SCR_FONTSIZE(ScreenInfo).Y)+ScreenInfo->
Window.Top);
05106
PaintRect.Bottom = (
SHORT)((ps.rcPaint.bottom/
SCR_FONTSIZE(ScreenInfo).Y)+ScreenInfo->
Window.Top);
05107 }
else {
05108
PaintRect.Left = (
SHORT)(ps.rcPaint.left+ScreenInfo->
Window.Left);
05109
PaintRect.Right = (
SHORT)(ps.rcPaint.right+ScreenInfo->
Window.Left);
05110
PaintRect.Top = (
SHORT)(ps.rcPaint.top+ScreenInfo->
Window.Top);
05111
PaintRect.Bottom = (
SHORT)(ps.rcPaint.bottom+ScreenInfo->
Window.Top);
05112 }
05113 ScreenInfo->
BufferInfo.TextInfo.Flags &= ~
TEXT_VALID_HINT;
05114
WriteToScreen(ScreenInfo,&
PaintRect);
05115 }
05116 EndPaint(
hWnd,&ps);
05117
ConsoleShowCursor(ScreenInfo);
05118
break;
05119
case WM_CLOSE:
05120
if (!(Console->
Flags &
CONSOLE_NO_WINDOW) ||
05121 !(Console->
Flags &
CONSOLE_WOW_REGISTERED)) {
05122
HandleCtrlEvent(Console,CTRL_CLOSE_EVENT);
05123 }
05124
break;
05125
case WM_ERASEBKGND:
05126
05127
05128
05129
05130
if (Console->
Flags &
CONSOLE_IS_ICONIC ||
05131 Console->
FullScreenFlags == CONSOLE_FULLSCREEN) {
05132 Message = WM_ICONERASEBKGND;
05133
goto CallDefWin;
05134 }
05135
break;
05136
case WM_SETTINGCHANGE:
05137
05138
05139
05140
05141
if (wParam == SPI_SETKEYBOARDDELAY) {
05142
guCaretBlinkTime = GetCaretBlinkTime();
05143
if (Console->
Flags &
CONSOLE_HAS_FOCUS) {
05144 KillTimer(
hWnd,
CURSOR_TIMER);
05145
SetTimer(
hWnd,
CURSOR_TIMER,
guCaretBlinkTime,
NULL);
05146 }
05147 }
else {
05148
gfInitSystemMetrics =
TRUE;
05149 }
05150
break;
05151
case WM_DISPLAYCHANGE:
05152
gfInitSystemMetrics =
TRUE;
05153
break;
05154
case WM_SETCURSOR:
05155
if (lParam == -1) {
05156
05157
05158
05159
05160
05161
05162 POINT
Point;
05163 HWND hWndTmp;
05164
GetCursorPos(&
Point);
05165 hWndTmp =
WindowFromPoint(
Point);
05166
if (hWndTmp ==
hWnd) {
05167 lParam =
DefWindowProc(
hWnd,WM_NCHITTEST,0,MAKELONG((WORD)
Point.x, (WORD)
Point.y));
05168 }
05169 }
05170
if ((WORD)lParam == HTCLIENT) {
05171
if (ScreenInfo->
CursorDisplayCount < 0) {
05172
SetCursor(
NULL);
05173 }
else {
05174
SetCursor(ScreenInfo->
CursorHandle);
05175 }
05176 }
else {
05177
goto CallDefWin;
05178 }
05179
break;
05180
case WM_GETMINMAXINFO:
05181 {
05182 LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam;
05183 COORD FontSize;
05184
WINDOW_LIMITS WindowLimits;
05185
05186
GetWindowLimits(ScreenInfo, &WindowLimits);
05187
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
05188 FontSize =
SCR_FONTSIZE(ScreenInfo);
05189 }
else {
05190 FontSize.X = 1;
05191 FontSize.Y = 1;
05192 }
05193 lpmmi->ptMaxSize.x = lpmmi->ptMaxTrackSize.x = WindowLimits.
MaxWindow.X;
05194
if (!ScreenInfo->
WindowMaximizedY) {
05195 lpmmi->ptMaxTrackSize.x +=
VerticalScrollSize;
05196 lpmmi->ptMaxSize.x +=
VerticalScrollSize;
05197 }
05198
while (lpmmi->ptMaxSize.x > WindowLimits.
FullScreenSize.X +
VerticalClientToWindow) {
05199 lpmmi->ptMaxSize.x -= FontSize.X;
05200 }
05201 lpmmi->ptMaxSize.y = lpmmi->ptMaxTrackSize.y = WindowLimits.
MaxWindow.Y;
05202
if (!ScreenInfo->
WindowMaximizedX) {
05203 lpmmi->ptMaxTrackSize.y +=
HorizontalScrollSize;
05204 lpmmi->ptMaxSize.y +=
HorizontalScrollSize;
05205 }
05206
while (lpmmi->ptMaxSize.y > WindowLimits.
FullScreenSize.Y +
HorizontalClientToWindow) {
05207 lpmmi->ptMaxSize.y -= FontSize.Y;
05208 }
05209 lpmmi->ptMinTrackSize.x = WindowLimits.
MinimumWindowSize.X * FontSize.X +
VerticalClientToWindow;
05210 lpmmi->ptMinTrackSize.y =
HorizontalClientToWindow;
05211 }
05212
break;
05213
case WM_QUERYDRAGICON:
05214
Status = (LRESULT)Console->
hIcon;
05215
break;
05216
case WM_WINDOWPOSCHANGING:
05217
05218
if (
TRUE || (Console->
FullScreenFlags == 0)) {
05219 LPWINDOWPOS WindowPos = (LPWINDOWPOS)lParam;
05220
DWORD fMinimized;
05221
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231 fMinimized =
IsIconic(
hWnd);
05232
05233
if (fMinimized) {
05234
if (!(Console->
Flags &
CONSOLE_IS_ICONIC)) {
05235 Console->
Flags |=
CONSOLE_IS_ICONIC;
05236
05237
05238
05239
05240
05241
05242
05243
05244
if (ScreenInfo->
hPalette !=
NULL &&
05245 Console->
FullScreenFlags == 0) {
05246
SelectPalette(Console->
hDC,
05247 Console->
hSysPalette,
05248
FALSE);
05249
UnsetActivePalette(ScreenInfo);
05250 }
05251 }
05252 }
else {
05253
if (Console->
Flags &
CONSOLE_IS_ICONIC) {
05254 Console->
Flags &= ~
CONSOLE_IS_ICONIC;
05255
05256
05257
05258
05259
05260
05261
05262
05263
if (ScreenInfo->
hPalette !=
NULL &&
05264 Console->
FullScreenFlags == 0) {
05265
SelectPalette(Console->
hDC,
05266 ScreenInfo->
hPalette,
05267
FALSE);
05268
SetActivePalette(ScreenInfo);
05269 }
05270 }
05271 }
05272
if (!ScreenInfo->
ResizingWindow &&
05273 (WindowPos->cx || WindowPos->cy) &&
05274 !fMinimized) {
05275
ProcessResizeWindow(ScreenInfo,Console,WindowPos);
05276 }
05277 }
05278
break;
05279
case WM_CONTEXTMENU:
05280
if (
DefWindowProc(
hWnd, WM_NCHITTEST, 0, lParam) == HTCLIENT) {
05281 TrackPopupMenuEx(Console->
hHeirMenu,
05282 TPM_RIGHTBUTTON,
05283
GET_X_LPARAM(lParam),
05284
GET_Y_LPARAM(lParam),
05285
hWnd,
05286
NULL);
05287 }
else {
05288
goto CallDefWin;
05289 }
05290
break;
05291
case WM_NCLBUTTONDOWN:
05292
05293
switch (wParam & 0x00FF) {
05294
case HTCAPTION:
05295
UnlockConsole(Console);
05296 Console =
NULL;
05297 SetActiveWindow(
hWnd);
05298
SendMessage(
hWnd, WM_SYSCOMMAND,
05299 SC_MOVE | wParam, lParam);
05300
break;
05301
default:
05302
goto CallDefWin;
05303 }
05304
break;
05305
#if defined (FE_IME)
05306
05307
case WM_KEYDOWN +
CONIME_KEYDATA:
05308
case WM_KEYUP +
CONIME_KEYDATA:
05309
case WM_CHAR +
CONIME_KEYDATA:
05310
case WM_DEADCHAR +
CONIME_KEYDATA:
05311
05312
case WM_SYSKEYDOWN +
CONIME_KEYDATA:
05313
case WM_SYSKEYUP +
CONIME_KEYDATA:
05314
case WM_SYSCHAR +
CONIME_KEYDATA:
05315
case WM_SYSDEADCHAR+
CONIME_KEYDATA:
05316
#endif
05317
case WM_KEYDOWN:
05318
case WM_KEYUP:
05319
case WM_CHAR:
05320
case WM_DEADCHAR:
05321
HandleKeyEvent(Console,
hWnd,Message,wParam,lParam);
05322
break;
05323
case WM_SYSKEYDOWN:
05324
case WM_SYSKEYUP:
05325
case WM_SYSCHAR:
05326
case WM_SYSDEADCHAR:
05327
if (
HandleSysKeyEvent(Console,
hWnd,Message,wParam,lParam) && Console !=
NULL) {
05328
goto CallDefWin;
05329 }
05330
break;
05331
case WM_COMMAND:
05332
05333
05334
05335
05336
if ((wParam < cmCopy) || (wParam >
cmSelectAll)) {
05337
break;
05338 }
05339
05340
case WM_SYSCOMMAND:
05341
if (wParam >= ScreenInfo->
CommandIdLow &&
05342 wParam <= ScreenInfo->
CommandIdHigh) {
05343
HandleMenuEvent(Console,(
DWORD)wParam);
05344 }
else if (wParam ==
cmMark) {
05345
DoMark(Console);
05346 }
else if (wParam ==
cmCopy) {
05347
DoCopy(Console);
05348 }
else if (wParam ==
cmPaste) {
05349
DoPaste(Console);
05350 }
else if (wParam ==
cmScroll) {
05351
DoScroll(Console);
05352 }
else if (wParam ==
cmFind) {
05353
DoFind(Console);
05354 }
else if (wParam ==
cmSelectAll) {
05355
DoSelectAll(Console);
05356 }
else if (wParam ==
cmControl) {
05357
PropertiesDlgShow(Console,
TRUE);
05358 }
else if (wParam ==
cmDefaults) {
05359
PropertiesDlgShow(Console,
FALSE);
05360 }
else {
05361
05362
05363
05364
05365
if (wParam == SC_RESTORE) {
05366 MSG RestoreMsg;
05367
SetCapture(
hWnd);
05368
while (
GetCapture() !=
NULL &&
05369 (
GetKeyState(VK_LBUTTON) &
KEY_PRESSED)) {
05370
PeekMessage(&RestoreMsg,
05371
hWnd,
05372 WM_MOUSEFIRST,
05373 WM_MOUSELAST,
05374 PM_REMOVE
05375 );
05376 }
05377
ReleaseCapture();
05378 }
05379
05380
goto CallDefWin;
05381 }
05382
break;
05383
case WM_TIMER:
05384
#if defined(FE_IME)
05385
if (wParam == SCROLL_WAIT_TIMER)
05386 {
05387
ASSERT(
CONSOLE_IS_IME_ENABLED());
05388
if ((ScreenInfo->
Console->ConsoleIme.ScrollFlag & (HIDE_FOR_SCROLL)) &&
05389 (ScreenInfo->
Console->ConsoleIme.ScrollWaitCountDown > 0)
05390 ) {
05391
if ((ScreenInfo->
Console->ConsoleIme.ScrollWaitCountDown -=
guCaretBlinkTime) <= 0) {
05392 ConsoleImeBottomLineInUse(ScreenInfo);
05393 }
05394 }
05395
break;
05396 }
05397
#endif // FE_IME
05398
CursorTimerRoutine(ScreenInfo);
05399
ScrollIfNecessary(Console,ScreenInfo);
05400
break;
05401
case WM_HSCROLL:
05402
HorizontalScroll(ScreenInfo, LOWORD(wParam), HIWORD(wParam));
05403
break;
05404
case WM_VSCROLL:
05405
VerticalScroll(Console, ScreenInfo,LOWORD(wParam),HIWORD(wParam));
05406
break;
05407
case WM_INITMENU:
05408
HandleMenuEvent(Console,WM_INITMENU);
05409
InitializeMenu(Console);
05410
break;
05411
case WM_MENUSELECT:
05412
if (HIWORD(wParam) == 0xffff) {
05413
HandleMenuEvent(Console,WM_MENUSELECT);
05414 }
05415
break;
05416
case WM_MOUSEMOVE:
05417
case WM_LBUTTONDOWN:
05418
case WM_LBUTTONUP:
05419
case WM_LBUTTONDBLCLK:
05420
case WM_RBUTTONDOWN:
05421
case WM_RBUTTONUP:
05422
case WM_RBUTTONDBLCLK:
05423
case WM_MBUTTONDOWN:
05424
case WM_MBUTTONUP:
05425
case WM_MBUTTONDBLCLK:
05426
case WM_MOUSEWHEEL:
05427
if (
HandleMouseEvent(Console,ScreenInfo,Message,wParam,lParam)) {
05428
if (Message != WM_MOUSEWHEEL) {
05429
goto CallDefWin;
05430 }
05431 }
else {
05432
break;
05433 }
05434
05435
05436
05437
05438
if (wParam & (MK_CONTROL)) {
05439
goto CallDefWin;
05440 }
05441
05442
Status = 1;
05443
if (
gfInitSystemMetrics) {
05444
InitializeSystemMetrics();
05445 }
05446
05447 ScreenInfo->
WheelDelta -= (
short)HIWORD(wParam);
05448
if (
abs(ScreenInfo->
WheelDelta) >= WHEEL_DELTA &&
05449
gucWheelScrollLines > 0) {
05450
05451 COORD NewOrigin;
05452
SHORT dy;
05453
05454 NewOrigin.X = ScreenInfo->
Window.Left;
05455 NewOrigin.Y = ScreenInfo->
Window.Top;
05456
05457
05458
05459
05460
05461
05462
if (!(wParam & MK_SHIFT))
05463 dy = (
int)
min(
05464 (
UINT)
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - 1,
05465
gucWheelScrollLines);
05466
else
05467 dy =
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - 1;
05468
05469
if (dy == 0) {
05470 dy++;
05471 }
05472
05473 dy *= (ScreenInfo->WheelDelta / WHEEL_DELTA);
05474 ScreenInfo->WheelDelta %= WHEEL_DELTA;
05475
05476 NewOrigin.Y += dy;
05477
if (NewOrigin.Y < 0) {
05478 NewOrigin.Y = 0;
05479 }
else if (NewOrigin.Y +
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) >
05480 ScreenInfo->ScreenBufferSize.Y) {
05481 NewOrigin.Y = ScreenInfo->ScreenBufferSize.Y -
05482
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
05483 }
05484
05485
SetWindowOrigin(ScreenInfo,
TRUE, NewOrigin);
05486 }
05487
break;
05488
05489
case WM_PALETTECHANGED:
05490
if (Console->
FullScreenFlags == 0) {
05491
if (ScreenInfo->
hPalette !=
NULL) {
05492
SetActivePalette(ScreenInfo);
05493
if (ScreenInfo->
Flags &
CONSOLE_GRAPHICS_BUFFER) {
05494
WriteRegionToScreenBitMap(ScreenInfo,
05495 &ScreenInfo->
Window);
05496 }
05497 }
else {
05498
SetScreenColors(ScreenInfo, ScreenInfo->
Attributes,
05499 ScreenInfo->
PopupAttributes,
TRUE);
05500 }
05501 }
05502
break;
05503
#if defined(_X86_)
05504
case WM_FULLSCREEN:
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514
05515 KdPrint((
"CONSRV: WindowProc - WM_FULLSCREEN\n"));
05516
05517
Status =
DisplayModeTransition(wParam,Console,ScreenInfo);
05518
#if defined(FE_IME)
05519
if (
NT_SUCCESS(
Status)) {
05520
Status = ImeWmFullScreen(wParam,Console,ScreenInfo);
05521 }
05522
#endif // FE_IME
05523
break;
05524
#endif
05525
case CM_SET_WINDOW_SIZE:
05526
if (lParam == 0x47474747) {
05527
Status =
InternalSetWindowSize(Console,
05528 (
PSCREEN_INFORMATION)wParam,
05529 &ScreenInfo->
Window
05530 );
05531 }
05532
break;
05533
case CM_BEEP:
05534
if (lParam == 0x47474747) {
05535 Beep(800, 200);
05536 }
05537
break;
05538
case CM_UPDATE_SCROLL_BARS:
05539
InternalUpdateScrollBars(ScreenInfo);
05540
break;
05541
case CM_UPDATE_TITLE:
05542
SetWindowText(
hWnd,Console->
Title);
05543
break;
05544
case CM_CONSOLE_MSG:
05545
if (!
UnqueueConsoleMessage(Console, &Message, &wParam, &lParam)) {
05546
break;
05547 }
05548
switch (Message) {
05549
#if defined(_X86_)
05550
case CM_MODE_TRANSITION:
05551
05552 KdPrint((
"CONSRV: WindowProc - CM_MODE_TRANSITION\n"));
05553
05554
if (wParam == FULLSCREEN) {
05555
if (Console->
FullScreenFlags == 0) {
05556
ConvertToFullScreen(Console);
05557 Console->
FullScreenFlags |= CONSOLE_FULLSCREEN;
05558
ChangeDispSettings(Console,
hWnd, CDS_FULLSCREEN);
05559 }
05560 }
else {
05561
if (Console->
FullScreenFlags & CONSOLE_FULLSCREEN) {
05562
ConvertToWindowed(Console);
05563 Console->
FullScreenFlags &= ~CONSOLE_FULLSCREEN;
05564
ChangeDispSettings(Console,
hWnd, 0);
05565
05566
ShowWindow(
hWnd, SW_RESTORE);
05567 }
05568 }
05569
05570
UnlockConsole(Console);
05571 Console =
NULL;
05572
05573
NtSetEvent((HANDLE)lParam,
NULL);
05574
NtClose((HANDLE)lParam);
05575
break;
05576
#endif
05577
#if defined (FE_IME)
05578
case CM_SET_IME_CODEPAGE: {
05579
if (! LOWORD(lParam))
05580 {
05581
05582
Status = SetImeCodePage(Console);
05583 }
05584
else
05585 {
05586
05587
Status = SetImeOutputCodePage(Console, ScreenInfo, HIWORD(lParam));
05588 }
05589
05590
if (wParam) {
05591
NtSetEvent((HANDLE)wParam,
NULL);
05592
NtClose((HANDLE)wParam);
05593 }
05594
break;
05595 }
05596
case CM_SET_NLSMODE:
05597
Status = SetImeKeyState(Console,
ImmConversionFromConsole((
DWORD)lParam));
05598
if (wParam) {
05599
NtSetEvent((HANDLE)wParam,
NULL);
05600
NtClose((HANDLE)wParam);
05601 }
05602
break;
05603
case CM_GET_NLSMODE:
05604
if (Console->
InputThreadInfo->hWndConsoleIME)
05605 {
05606
ASSERT(
CONSOLE_IS_IME_ENABLED());
05607
05608
if (!
NT_SUCCESS(GetImeKeyState(Console,
NULL))) {
05609
if (wParam) {
05610
NtSetEvent((HANDLE)wParam,
NULL);
05611
NtClose((HANDLE)wParam);
05612 }
05613
break;
05614 }
05615
if (wParam) {
05616
NtSetEvent((HANDLE)wParam,
NULL);
05617
NtClose((HANDLE)wParam);
05618 }
05619 }
05620
else if (lParam < 10)
05621 {
05622
05623
05624
05625
Status =
QueueConsoleMessage(Console,
05626 CM_GET_NLSMODE,
05627 wParam,
05628 lParam+1
05629 );
05630
if (!
NT_SUCCESS(
Status)) {
05631
if (wParam) {
05632
NtSetEvent((HANDLE)wParam,
NULL);
05633
NtClose((HANDLE)wParam);
05634 }
05635 }
05636 }
05637
else
05638 {
05639
if (wParam) {
05640
NtSetEvent((HANDLE)wParam,
NULL);
05641
NtClose((HANDLE)wParam);
05642 }
05643 }
05644
break;
05645
#endif // FE_IME
05646
}
05647
break;
05648
05649
case CM_HIDE_WINDOW:
05650 ShowWindowAsync(
hWnd, SW_MINIMIZE);
05651
break;
05652
case CM_PROPERTIES_START:
05653 Console->
hWndProperties = (HWND)wParam;
05654
break;
05655
case CM_PROPERTIES_UPDATE:
05656
PropertiesUpdate(Console, (HANDLE)wParam);
05657
break;
05658
case CM_PROPERTIES_END:
05659 Console->
hWndProperties =
NULL;
05660
break;
05661
#if defined(FE_IME)
05662
case WM_COPYDATA:
05663
if (
CONSOLE_IS_IME_ENABLED() && CONSOLE_IS_DBCS_OUTPUTCP(Console)) {
05664
Status = ImeControl(Console,(HWND)wParam,(PCOPYDATASTRUCT)lParam);
05665 }
05666
break;
05667
05668
case WM_ENTERMENULOOP:
05669
if (Console->
Flags &
CONSOLE_HAS_FOCUS) {
05670 Console->
InputBuffer.ImeMode.Unavailable =
TRUE;
05671
if (
CONSOLE_IS_IME_ENABLED()) {
05672
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
05673
CONIME_KILLFOCUS,
05674 (WPARAM)Console->
ConsoleHandle,
05675 (LPARAM)
NULL
05676 ))) {
05677
break;
05678 }
05679 }
05680 }
05681
break;
05682
05683
case WM_EXITMENULOOP:
05684
if (Console->
Flags &
CONSOLE_HAS_FOCUS) {
05685
if (
CONSOLE_IS_IME_ENABLED()) {
05686
if (!
NT_SUCCESS(ConsoleImeMessagePump(Console,
05687
CONIME_SETFOCUS,
05688 (WPARAM)Console->
ConsoleHandle,
05689 (LPARAM)Console->
hklActive
05690 ))) {
05691
break;
05692 }
05693 }
05694 Console->
InputBuffer.ImeMode.Unavailable =
FALSE;
05695 }
05696
break;
05697
05698
case WM_ENTERSIZEMOVE:
05699
if (Console->
Flags &
CONSOLE_HAS_FOCUS) {
05700 Console->
InputBuffer.ImeMode.Unavailable =
TRUE;
05701 }
05702
break;
05703
05704
case WM_EXITSIZEMOVE:
05705
if (Console->
Flags &
CONSOLE_HAS_FOCUS) {
05706 Console->
InputBuffer.ImeMode.Unavailable =
FALSE;
05707 }
05708
break;
05709
#endif // FE_IME
05710
CallDefWin:
05711
default:
05712
if (Console !=
NULL) {
05713
UnlockConsole(Console);
05714 Console =
NULL;
05715 }
05716
Status = (
DefWindowProc(
hWnd,Message,wParam,lParam));
05717
break;
05718 }
05719 }
05720 } finally {
05721
if (Console !=
NULL) {
05722
UnlockConsole(Console);
05723 Console =
NULL;
05724 }
05725 }
05726
05727
return Status;
05728 }
05729
05730
05731
05732
05733
05734
05735
05736
05737
05738
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
05749
05750 UINT ConsoleDragQueryFile(
05751 IN HANDLE hDrop,
05752 IN PVOID lpFile,
05753 IN UINT cb
05754 )
05755 {
05756
UINT i = 0;
05757 LPDROPFILESTRUCT lpdfs;
05758
BOOL fWide;
05759
05760 lpdfs = (LPDROPFILESTRUCT)GlobalLock(hDrop);
05761
05762
if (lpdfs && lpdfs != hDrop)
05763 {
05764
try {
05765 fWide = (LOWORD(lpdfs->pFiles) ==
sizeof(DROPFILES));
05766
if (fWide)
05767 {
05768
05769
05770
05771 fWide = lpdfs->fWide;
05772
05773 }
05774
05775
if (fWide)
05776 {
05777 LPWSTR lpList;
05778
05779
05780
05781
05782
05783 lpList = (LPWSTR)((LPBYTE)lpdfs + lpdfs->pFiles);
05784
05785 i = lstrlenW(lpList);
05786
05787
if (!i)
05788
goto Exit;
05789
05790 cb--;
05791
if (cb < i)
05792 i = cb;
05793
05794 lstrcpynW((LPWSTR)lpFile, lpList, i + 1);
05795 }
05796
else
05797 {
05798 LPSTR lpList;
05799
05800
05801
05802
05803 lpList = (LPSTR)((LPBYTE)lpdfs + lpdfs->pFiles);
05804
05805 i = lstrlenA(lpList);
05806
05807
if (!i)
05808
goto Exit;
05809
05810 cb--;
05811
if (cb < i)
05812 i = cb;
05813
05814 MultiByteToWideChar(CP_ACP, 0, lpList, -1, (LPWSTR)lpFile, cb);
05815
05816 }
05817 } except(
EXCEPTION_EXECUTE_HANDLER ) {
05818 KdPrint((
"CONSRV: WM_DROPFILES raised exception\n"));
05819 i = 0;
05820 }
05821 Exit:
05822 GlobalUnlock(hDrop);
05823 GlobalFree(hDrop);
05824 }
05825
05826
return(i);
05827 }
05828
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838
05839
05840
05841
05842
05843
05844
05845
05846
05847
05848
05849
05850
05851
05852
05853 void DoDrop (WPARAM wParam,
05854
PCONSOLE_INFORMATION Console)
05855 {
05856 WCHAR szPath[
MAX_PATH];
05857
BOOL fAddQuotes;
05858
05859
if (
ConsoleDragQueryFile((HANDLE)wParam, szPath,
CharSizeOf(szPath))) {
05860 fAddQuotes = (wcschr(szPath,
L' ') !=
NULL);
05861
if (fAddQuotes)
05862
DoStringPaste(Console,
L"\"", 1);
05863
DoStringPaste(Console, szPath, wcslen(szPath));
05864
if (fAddQuotes)
05865
DoStringPaste(Console,
L"\"", 1);
05866 }
05867 }
05868
05869
BOOL
05870 CreateDbcsScreenBuffer(
05871 IN
PCONSOLE_INFORMATION Console,
05872 IN COORD dwScreenBufferSize,
05873 OUT PDBCS_SCREEN_BUFFER DbcsScreenBuffer
05874 )
05875 {
05876
if (CONSOLE_IS_DBCS_OUTPUTCP(Console)) {
05877 DbcsScreenBuffer->TransBufferCharacter =
05878 (PWCHAR)
ConsoleHeapAlloc(
05879
MAKE_TAG( SCREEN_DBCS_TAG ),
05880 (dwScreenBufferSize.X*dwScreenBufferSize.Y*
sizeof(WCHAR))+
sizeof(WCHAR));
05881
if (DbcsScreenBuffer->TransBufferCharacter ==
NULL) {
05882
return FALSE;
05883 }
05884
05885 DbcsScreenBuffer->TransBufferAttribute =
05886 (
PBYTE)
ConsoleHeapAlloc(
05887
MAKE_TAG( SCREEN_DBCS_TAG ),
05888 (dwScreenBufferSize.X*dwScreenBufferSize.Y*
sizeof(
BYTE))+
sizeof(
BYTE));
05889
if (DbcsScreenBuffer->TransBufferAttribute ==
NULL) {
05890
ConsoleHeapFree(DbcsScreenBuffer->TransBufferCharacter);
05891
return FALSE;
05892 }
05893
05894 DbcsScreenBuffer->TransWriteConsole =
05895 (PWCHAR)
ConsoleHeapAlloc(
05896
MAKE_TAG( SCREEN_DBCS_TAG ),
05897 (dwScreenBufferSize.X*dwScreenBufferSize.Y*
sizeof(WCHAR))+
sizeof(WCHAR));
05898
if (DbcsScreenBuffer->TransWriteConsole ==
NULL) {
05899
ConsoleHeapFree(DbcsScreenBuffer->TransBufferAttribute);
05900
ConsoleHeapFree(DbcsScreenBuffer->TransBufferCharacter);
05901
return FALSE;
05902 }
05903
05904 DbcsScreenBuffer->KAttrRows =
05905 (
PBYTE)
ConsoleHeapAlloc(
05906
MAKE_TAG( SCREEN_DBCS_TAG ),
05907 dwScreenBufferSize.X*dwScreenBufferSize.Y*
sizeof(
BYTE));
05908
if (DbcsScreenBuffer->KAttrRows ==
NULL) {
05909
ConsoleHeapFree(DbcsScreenBuffer->TransWriteConsole);
05910
ConsoleHeapFree(DbcsScreenBuffer->TransBufferAttribute);
05911
ConsoleHeapFree(DbcsScreenBuffer->TransBufferCharacter);
05912
return FALSE;
05913 }
05914 }
05915
else {
05916 DbcsScreenBuffer->TransBufferCharacter =
NULL;
05917 DbcsScreenBuffer->TransBufferAttribute =
NULL;
05918 DbcsScreenBuffer->TransWriteConsole =
NULL;
05919 DbcsScreenBuffer->KAttrRows =
NULL;
05920 }
05921
05922
return TRUE;
05923 }
05924
05925
BOOL
05926 DeleteDbcsScreenBuffer(
05927 IN PDBCS_SCREEN_BUFFER DbcsScreenBuffer
05928 )
05929 {
05930
if (DbcsScreenBuffer->KAttrRows) {
05931
ConsoleHeapFree(DbcsScreenBuffer->TransBufferCharacter);
05932
ConsoleHeapFree(DbcsScreenBuffer->TransBufferAttribute);
05933
ConsoleHeapFree(DbcsScreenBuffer->TransWriteConsole);
05934
ConsoleHeapFree(DbcsScreenBuffer->KAttrRows);
05935 }
05936
return TRUE;
05937 }
05938
05939
BOOL
05940 ReCreateDbcsScreenBufferWorker(
05941 IN
PCONSOLE_INFORMATION Console,
05942 IN
PSCREEN_INFORMATION ScreenInfo
05943 )
05944 {
05945
SHORT i;
05946
PBYTE KAttrRowPtr;
05947 COORD dwScreenBufferSize;
05948 DBCS_SCREEN_BUFFER NewDbcsScreenBuffer;
05949
05950
ASSERT(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER);
05951
if (!(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER)) {
05952
return FALSE;
05953 }
05954
05955 dwScreenBufferSize = ScreenInfo->ScreenBufferSize;
05956
05957
if (!
CreateDbcsScreenBuffer(Console,
05958 dwScreenBufferSize,
05959 &NewDbcsScreenBuffer)) {
05960
return FALSE;
05961 }
05962
05963 KAttrRowPtr = NewDbcsScreenBuffer.KAttrRows;
05964
for (i = 0; i < dwScreenBufferSize.Y; i++) {
05965 ScreenInfo->BufferInfo.TextInfo.Rows[i].CharRow.KAttrs = KAttrRowPtr;
05966
if (KAttrRowPtr) {
05967 RtlZeroMemory(KAttrRowPtr, dwScreenBufferSize.X);
05968 KAttrRowPtr += dwScreenBufferSize.X;
05969 }
05970 }
05971 ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer = NewDbcsScreenBuffer;
05972
05973
return TRUE;
05974 }
05975
05976
05977 typedef struct _DBCS_SCREEN_BUFFER_TRACKER {
05978 DBCS_SCREEN_BUFFER
data;
05979
#if DBG
05980
PSCREEN_INFORMATION pScreenInfo;
05981
#endif
05982
}
DBCS_SCREEN_BUFFER_TRACKER, *
PDBCS_SCREEN_BUFFER_TRACKER;
05983
05984
BOOL
05985 ReCreateDbcsScreenBuffer(
05986 IN
PCONSOLE_INFORMATION pConsole,
05987 IN UINT OldCodePage)
05988 {
05989
BOOL fResult =
FALSE;
05990
PDBCS_SCREEN_BUFFER_TRACKER pDbcsScreenBuffer;
05991
PSCREEN_INFORMATION pScreenInfo;
05992
UINT nScreen;
05993
UINT i;
05994
#if DBG
05995
UINT nScreenSave;
05996
#endif
05997
05998
05999
06000
06001
if (!
IsAvailableFarEastCodePage(OldCodePage) == !CONSOLE_IS_DBCS_OUTPUTCP(pConsole) )
06002
return TRUE;
06003
06004
06005
06006
06007
for (nScreen = 0, pScreenInfo = pConsole->ScreenBuffers; pScreenInfo; pScreenInfo = pScreenInfo->
Next) {
06008
06009
06010
06011
if (pScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
06012 ++nScreen;
06013 }
06014 }
06015
#if DBG
06016
nScreenSave = nScreen;
06017
#endif
06018
06019
06020
06021
06022 pDbcsScreenBuffer =
ConsoleHeapAlloc(
MAKE_TAG(TMP_DBCS_TAG),
sizeof *pDbcsScreenBuffer * nScreen);
06023
if (pDbcsScreenBuffer ==
NULL) {
06024 RIPMSG0(RIP_WARNING,
"ReCreateDbcsScreenBuffer: not enough memory.");
06025
return FALSE;
06026 }
06027
06028
06029
06030
06031
for (nScreen = 0, pScreenInfo = pConsole->ScreenBuffers; pScreenInfo; pScreenInfo = pScreenInfo->Next) {
06032
ASSERT(nScreen < nScreenSave);
06033
06034
06035
06036
06037
if (pScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
06038
06039
06040
06041
#if DBG
06042
pDbcsScreenBuffer[nScreen].pScreenInfo = pScreenInfo;
06043
#endif
06044
pDbcsScreenBuffer[nScreen++].
data = pScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer;
06045
06046
if (!
ReCreateDbcsScreenBufferWorker(pConsole, pScreenInfo)) {
06047
06048
06049
06050
06051 RIPMSG0(RIP_WARNING,
"ReCreateDbcsScreenBuffer: failed to recreate dbcs screen buffer.");
06052
06053
for (i = 0, pScreenInfo = pConsole->ScreenBuffers; i < nScreen; pScreenInfo = pScreenInfo->Next) {
06054
ASSERT(pScreenInfo);
06055
06056
if (pScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
06057
ASSERT(pDbcsScreenBuffer[i].pScreenInfo == pScreenInfo);
06058
if (i < nScreen - 1) {
06059
ASSERT(pScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.KAttrRows != pDbcsScreenBuffer[i].
data.KAttrRows);
06060
DeleteDbcsScreenBuffer(&pScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer);
06061 }
06062
06063 pScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer = pDbcsScreenBuffer[i++].
data;
06064 }
06065 }
06066
goto exit;
06067 }
06068 }
06069 }
06070
06071
06072
06073
06074
for (i = 0; i < nScreen; ++i) {
06075
DeleteDbcsScreenBuffer(&pDbcsScreenBuffer[i].data);
06076 }
06077
06078 fResult =
TRUE;
06079
06080
exit:
06081
ConsoleHeapFree(pDbcsScreenBuffer);
06082
06083
return fResult;
06084 }
06085
06086
06087 BOOL IsNotBiDILayout(HKL hkl)
06088 {
06089
BOOL bRet =
TRUE;
06090 LANGID LangID = PRIMARYLANGID(HandleToUlong(hkl));
06091
06092
if ( (LangID == LANG_ARABIC) || (LangID == LANG_HEBREW)) {
06093 bRet =
FALSE;
06094 }
06095
return bRet;
06096
06097 }
06098
06099 void GetNonBiDiKeyboardLayout(HKL *phklActive)
06100 {
06101 HKL hkl = *phklActive;
06102
06103
if (
IsNotBiDILayout(hkl) )
06104
return;
06105
06106
06107
ActivateKeyboardLayout(hkl, 0);
06108
06109
ActivateKeyboardLayout((HKL)HKL_NEXT, 0);
06110
06111
06112
while (hkl =
GetKeyboardLayout(0))
06113 {
06114
if ((hkl == *phklActive) ||
IsNotBiDILayout(hkl)) {
06115 *phklActive = hkl;
06116
break;
06117 }
06118
ActivateKeyboardLayout((HKL)HKL_NEXT, 0);
06119 }
06120 }
06121
06122
#if defined(FE_SB)
06123
06124
#define WWSB_NOFE
06125
#include "_output.h"
06126
#undef WWSB_NOFE
06127
#define WWSB_FE
06128
#include "_output.h"
06129
#undef WWSB_FE
06130
06131
#endif // FE_SB