00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define WWSB_NEUTRAL_FILE 1
00024
00025
#if !defined(FE_SB)
00026
#error This header file should be included with FE_SB
00027
#endif
00028
00029
#if !defined(WWSB_FE) && !defined(WWSB_NOFE)
00030
#error Either WWSB_FE and WWSB_NOFE must be defined.
00031
#endif
00032
00033
#if defined(WWSB_FE) && defined(WWSB_NOFE)
00034
#error Both WWSB_FE and WWSB_NOFE defined.
00035
#endif
00036
00037
#include "dispatch.h"
00038
00039
#if defined(WWSB_FE)
00040
#pragma alloc_text(FE_TEXT, FE_StreamWriteToScreenBuffer)
00041
#pragma alloc_text(FE_TEXT, FE_WriteRectToScreenBuffer)
00042
#pragma alloc_text(FE_TEXT, FE_WriteRegionToScreen)
00043
#pragma alloc_text(FE_TEXT, FE_WriteToScreen)
00044
#pragma alloc_text(FE_TEXT, FE_WriteOutputString)
00045
#pragma alloc_text(FE_TEXT, FE_FillOutput)
00046
#pragma alloc_text(FE_TEXT, FE_FillRectangle)
00047
#pragma alloc_text(FE_TEXT, FE_PolyTextOutCandidate)
00048
#pragma alloc_text(FE_TEXT, FE_ConsolePolyTextOut)
00049
#endif
00050
00051
00052
#if defined(WWSB_NOFE)
00053
VOID
00054
SB_StreamWriteToScreenBuffer(
00055 IN PWCHAR String,
00056 IN SHORT StringLength,
00057 IN
PSCREEN_INFORMATION ScreenInfo
00058 )
00059 #
else
00060
VOID
00061 FE_StreamWriteToScreenBuffer(
00062 IN PWCHAR String,
00063 IN SHORT StringLength,
00064 IN
PSCREEN_INFORMATION ScreenInfo,
00065 IN PCHAR StringA
00066 )
00067 #endif
00068 {
00069
SHORT RowIndex;
00070
PROW Row;
00071 PWCHAR Char;
00072 COORD TargetPoint;
00073
00074
DBGOUTPUT((
"StreamWriteToScreenBuffer\n"));
00075
#ifdef WWSB_FE
00076
ASSERT(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER);
00077
#endif
00078
ScreenInfo->BufferInfo.TextInfo.Flags |=
TEXT_VALID_HINT;
00079 TargetPoint = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
00080 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
00081 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00082
DBGOUTPUT((
"RowIndex = %x, Row = %x, TargetPoint = (%x,%x)\n",
00083 RowIndex, Row, TargetPoint.X, TargetPoint.Y));
00084
00085
00086
00087
00088
#ifdef WWSB_FE
00089
BisectWrite(
StringLength,TargetPoint,ScreenInfo);
00090
if (TargetPoint.Y == ScreenInfo->ScreenBufferSize.Y-1 &&
00091 TargetPoint.X+
StringLength >= ScreenInfo->ScreenBufferSize.X &&
00092 *(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) & ATTR_LEADING_BYTE
00093 ) {
00094 *(
String+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) =
UNICODE_SPACE;
00095 *(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) = 0;
00096
if (
StringLength > ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) {
00097 *(
String+ScreenInfo->ScreenBufferSize.X-TargetPoint.X) =
UNICODE_SPACE;
00098 *(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X) = 0;
00099 }
00100 }
00101
00102 RtlCopyMemory(&Row->
CharRow.KAttrs[TargetPoint.X],StringA,
StringLength*
sizeof(
CHAR));
00103
#endif
00104
00105 RtlCopyMemory(&Row->
CharRow.
Chars[TargetPoint.X],
String,
StringLength*
sizeof(WCHAR));
00106
00107
00108
00109 Row->
CharRow.
OldLeft = Row->
CharRow.
Left;
00110
if (TargetPoint.X < Row->
CharRow.
Left) {
00111 PWCHAR LastChar = &Row->
CharRow.
Chars[ScreenInfo->ScreenBufferSize.X];
00112
00113
for (Char=&Row->
CharRow.
Chars[TargetPoint.X];Char < LastChar && *Char==(WCHAR)
' ';Char++)
00114 ;
00115 Row->
CharRow.
Left = (
SHORT)(Char-Row->
CharRow.
Chars);
00116 }
00117
00118 Row->
CharRow.
OldRight = Row->
CharRow.
Right;
00119
if ((TargetPoint.X+
StringLength) >= Row->
CharRow.
Right) {
00120 PWCHAR FirstChar = Row->
CharRow.
Chars;
00121
00122
for (Char=&Row->
CharRow.
Chars[TargetPoint.X+
StringLength-1];*Char==(WCHAR)
' ' && Char >= FirstChar;Char--)
00123 ;
00124 Row->
CharRow.
Right = (
SHORT)(Char+1-FirstChar);
00125 }
00126
00127
00128
00129
00130
00131
00132
if (Row->
AttrRow.
Length != 1 ||
00133 Row->
AttrRow.
Attrs->
Attr != ScreenInfo->Attributes) {
00134
PATTR_PAIR NewAttrs;
00135 WORD NewAttrsLength;
00136
ATTR_PAIR Attrs;
00137
00138 Attrs.
Length =
StringLength;
00139 Attrs.
Attr = ScreenInfo->Attributes;
00140
if (!
NT_SUCCESS(
MergeAttrStrings(Row->
AttrRow.
Attrs,
00141 Row->
AttrRow.
Length,
00142 &Attrs,
00143 1,
00144 &NewAttrs,
00145 &NewAttrsLength,
00146 TargetPoint.X,
00147 (
SHORT)(TargetPoint.X+
StringLength-1),
00148 Row,
00149 ScreenInfo
00150 ))) {
00151
return;
00152 }
00153
if (Row->
AttrRow.
Length > 1) {
00154
ConsoleHeapFree(Row->
AttrRow.
Attrs);
00155 }
00156
else {
00157
ASSERT(Row->
AttrRow.
Attrs == &Row->
AttrRow.
AttrPair);
00158 }
00159 Row->
AttrRow.
Attrs = NewAttrs;
00160 Row->
AttrRow.
Length = NewAttrsLength;
00161 Row->
CharRow.
OldLeft =
INVALID_OLD_LENGTH;
00162 Row->
CharRow.
OldRight =
INVALID_OLD_LENGTH;
00163 }
00164
ResetTextFlags(ScreenInfo,TargetPoint.Y,TargetPoint.Y);
00165 }
00166
00167
00168 #define CHAR_OF_PCI(p) (((PCHAR_INFO)(p))->Char.AsciiChar)
00169 #define WCHAR_OF_PCI(p) (((PCHAR_INFO)(p))->Char.UnicodeChar)
00170 #define ATTR_OF_PCI(p) (((PCHAR_INFO)(p))->Attributes)
00171 #define SIZEOF_CI_CELL sizeof(CHAR_INFO)
00172
00173 #define CHAR_OF_VGA(p) (p[0])
00174 #define ATTR_OF_VGA(p) (p[1])
00175
#ifdef i386
00176
#define SIZEOF_VGA_CELL 2
00177
#else // risc
00178 #define SIZEOF_VGA_CELL 4
00179
#endif
00180
00181
00182 #define COMMON_LVB_MASK 0x33
00183 #define ATTR_OF_COMMON_LVB(p) (ATTR_OF_VGA(p) + (((p[2] & ~COMMON_LVB_MASK)) << 8))
00184 #define SIZEOF_COMMON_LVB_CELL 4
00185
00186
VOID
00187 WWSB_WriteRectToScreenBuffer(
00188
PBYTE Source,
00189 COORD SourceSize,
00190 PSMALL_RECT SourceRect,
00191
PSCREEN_INFORMATION ScreenInfo,
00192 COORD TargetPoint,
00193 IN UINT Codepage
00194 )
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 {
00226
00227
PBYTE SourcePtr;
00228
SHORT i,j;
00229
SHORT XSize,YSize;
00230 BOOLEAN WholeSource;
00231
SHORT RowIndex;
00232
PROW Row;
00233 PWCHAR Char;
00234
ATTR_PAIR Attrs[80];
00235
PATTR_PAIR AttrBuf;
00236
PATTR_PAIR Attr;
00237
SHORT AttrLength;
00238
BOOL bVGABuffer;
00239 ULONG ulCellSize;
00240
#ifdef WWSB_FE
00241
PCHAR AttrP;
00242
#endif
00243
00244
DBGOUTPUT((
"WriteRectToScreenBuffer\n"));
00245
#ifdef WWSB_FE
00246
ASSERT(ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER);
00247
#endif
00248
00249 ScreenInfo->
BufferInfo.TextInfo.Flags |=
TEXT_VALID_HINT;
00250 XSize = (
SHORT)(SourceRect->Right - SourceRect->Left + 1);
00251 YSize = (
SHORT)(SourceRect->Bottom - SourceRect->Top + 1);
00252
00253
00254 AttrBuf = Attrs;
00255
if (XSize > 80) {
00256 AttrBuf = (
PATTR_PAIR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),XSize *
sizeof(
ATTR_PAIR));
00257
if (AttrBuf ==
NULL)
00258
return;
00259 }
00260
00261 bVGABuffer = (Codepage != 0xFFFFFFFF);
00262
if (bVGABuffer) {
00263
#ifdef WWSB_FE
00264
ulCellSize = (ScreenInfo->
Console->fVDMVideoMode) ?
SIZEOF_COMMON_LVB_CELL :
SIZEOF_VGA_CELL;
00265
#else
00266
ulCellSize =
SIZEOF_VGA_CELL;
00267
#endif
00268
}
else {
00269 ulCellSize =
SIZEOF_CI_CELL;
00270 }
00271
00272 SourcePtr = Source;
00273
00274 WholeSource =
FALSE;
00275
if (XSize == SourceSize.X) {
00276
ASSERT (SourceRect->Left == 0);
00277
if (SourceRect->Top != 0) {
00278 SourcePtr +=
SCREEN_BUFFER_POINTER(SourceRect->Left,
00279 SourceRect->Top,
00280 SourceSize.X,
00281 ulCellSize);
00282 }
00283 WholeSource =
TRUE;
00284 }
00285 RowIndex = (ScreenInfo->
BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->
ScreenBufferSize.Y;
00286
for (i=0;i<YSize;i++) {
00287
if (!WholeSource) {
00288 SourcePtr = Source +
SCREEN_BUFFER_POINTER(SourceRect->Left,
00289 SourceRect->Top+i,
00290 SourceSize.X,
00291 ulCellSize);
00292 }
00293
00294
00295
00296
00297
00298
#ifdef WWSB_FE
00299
if (! bVGABuffer) {
00300 COORD TPoint;
00301
00302 TPoint.X = TargetPoint.X;
00303 TPoint.Y = TargetPoint.Y + i;
00304
BisectWrite(XSize,TPoint,ScreenInfo);
00305
if (TPoint.Y == ScreenInfo->
ScreenBufferSize.Y-1 &&
00306 TPoint.X+XSize-1 >= ScreenInfo->
ScreenBufferSize.X &&
00307
ATTR_OF_PCI(SourcePtr+ScreenInfo->
ScreenBufferSize.X-TPoint.X-1) & COMMON_LVB_LEADING_BYTE)
00308 {
00309
WCHAR_OF_PCI(SourcePtr+ScreenInfo->
ScreenBufferSize.X-TPoint.X-1) =
UNICODE_SPACE;
00310
ATTR_OF_PCI(SourcePtr+ScreenInfo->
ScreenBufferSize.X-TPoint.X-1) &= ~COMMON_LVB_SBCSDBCS;
00311
if (XSize-1 > ScreenInfo->
ScreenBufferSize.X-TPoint.X-1) {
00312
WCHAR_OF_PCI(SourcePtr+ScreenInfo->
ScreenBufferSize.X-TPoint.X) =
UNICODE_SPACE;
00313
ATTR_OF_PCI(SourcePtr+ScreenInfo->
ScreenBufferSize.X-TPoint.X) &= ~COMMON_LVB_SBCSDBCS;
00314 }
00315 }
00316 }
00317
#endif
00318
00319 Row = &ScreenInfo->
BufferInfo.TextInfo.Rows[RowIndex];
00320 Char = &Row->
CharRow.
Chars[TargetPoint.X];
00321
#ifdef WWSB_FE
00322
AttrP = &Row->
CharRow.KAttrs[TargetPoint.X];
00323
#endif
00324
Attr = AttrBuf;
00325 Attr->
Length = 0;
00326 AttrLength = 1;
00327
00328
00329
00330
00331
00332
if (bVGABuffer) {
00333
#ifdef WWSB_FE
00334
Attr->
Attr = (ScreenInfo->
Console->fVDMVideoMode) ?
ATTR_OF_COMMON_LVB(SourcePtr) :
ATTR_OF_VGA(SourcePtr);
00335
#else
00336
Attr->
Attr =
ATTR_OF_VGA(SourcePtr);
00337
#endif
00338
for (j = SourceRect->Left;
00339 j <= SourceRect->Right;
00340 j++,
00341
#ifdef WWSB_FE
00342
SourcePtr += (ScreenInfo->
Console->fVDMVideoMode) ?
SIZEOF_COMMON_LVB_CELL :
SIZEOF_VGA_CELL
00343
#else
00344
SourcePtr +=
SIZEOF_VGA_CELL
00345
#endif
00346
) {
00347
00348
#ifdef WWSB_FE
00349
UCHAR TmpBuff[2];
00350
00351
if (
IsDBCSLeadByteConsole(
CHAR_OF_VGA(SourcePtr),&ScreenInfo->
Console->OutputCPInfo)) {
00352
if (j+1 > SourceRect->Right) {
00353 *Char =
UNICODE_SPACE;
00354 *AttrP = 0;
00355 }
00356
else {
00357 TmpBuff[0] =
CHAR_OF_VGA(SourcePtr);
00358 TmpBuff[1] =
CHAR_OF_VGA((SourcePtr + ((ScreenInfo->
Console->fVDMVideoMode) ?
SIZEOF_COMMON_LVB_CELL :
SIZEOF_VGA_CELL)));
00359
ConvertOutputToUnicode(Codepage,
00360 TmpBuff,
00361 2,
00362 Char,
00363 2);
00364 Char++;
00365 j++;
00366 *AttrP++ = ATTR_LEADING_BYTE;
00367 *Char++ = *(Char-1);
00368 *AttrP++ = ATTR_TRAILING_BYTE;
00369
00370
if (ScreenInfo->
Console->fVDMVideoMode) {
00371
if (Attr->
Attr ==
ATTR_OF_COMMON_LVB(SourcePtr)) {
00372 Attr->
Length += 1;
00373 }
00374
else {
00375 Attr++;
00376 Attr->
Length = 1;
00377 Attr->
Attr =
ATTR_OF_COMMON_LVB(SourcePtr);
00378 AttrLength += 1;
00379 }
00380 }
00381
else
00382 {
00383
if (Attr->
Attr ==
ATTR_OF_VGA(SourcePtr)) {
00384 Attr->
Length += 1;
00385 }
00386
else {
00387 Attr++;
00388 Attr->
Length = 1;
00389 Attr->
Attr =
ATTR_OF_VGA(SourcePtr);
00390 AttrLength += 1;
00391 }
00392 }
00393
00394 SourcePtr += (ScreenInfo->
Console->fVDMVideoMode) ?
SIZEOF_COMMON_LVB_CELL :
SIZEOF_VGA_CELL;
00395 }
00396 }
00397
else {
00398
ConvertOutputToUnicode(Codepage,
00399 &
CHAR_OF_VGA(SourcePtr),
00400 1,
00401 Char,
00402 1);
00403 Char++;
00404 *AttrP++ = 0;
00405 }
00406
#else
00407
*Char++ = SB_CharToWcharGlyph(Codepage,
CHAR_OF_VGA(SourcePtr));
00408
#endif
00409
00410
#ifdef WWSB_FE
00411
if (ScreenInfo->
Console->fVDMVideoMode) {
00412
if (Attr->
Attr ==
ATTR_OF_COMMON_LVB(SourcePtr)) {
00413 Attr->
Length += 1;
00414 }
00415
else {
00416 Attr++;
00417 Attr->
Length = 1;
00418 Attr->
Attr =
ATTR_OF_COMMON_LVB(SourcePtr);
00419 AttrLength += 1;
00420 }
00421 }
00422
else
00423
#endif
00424
if (Attr->
Attr ==
ATTR_OF_VGA(SourcePtr)) {
00425 Attr->
Length += 1;
00426 }
00427
else {
00428 Attr++;
00429 Attr->
Length = 1;
00430 Attr->
Attr =
ATTR_OF_VGA(SourcePtr);
00431 AttrLength += 1;
00432 }
00433 }
00434 }
else {
00435
#ifdef WWSB_FE
00436
Attr->
Attr =
ATTR_OF_PCI(SourcePtr) & ~COMMON_LVB_SBCSDBCS;
00437
#else
00438
Attr->
Attr =
ATTR_OF_PCI(SourcePtr);
00439
#endif
00440
for (j = SourceRect->Left;
00441 j <= SourceRect->Right;
00442 j++, SourcePtr +=
SIZEOF_CI_CELL) {
00443
00444 *Char++ =
WCHAR_OF_PCI(SourcePtr);
00445
#ifdef WWSB_FE
00446
00447 *AttrP++ = (
CHAR)((
ATTR_OF_PCI(SourcePtr) & COMMON_LVB_SBCSDBCS) >>8);
00448
#endif
00449
00450
#ifdef WWSB_FE
00451
if (Attr->
Attr == (
ATTR_OF_PCI(SourcePtr) & ~COMMON_LVB_SBCSDBCS))
00452
#else
00453
if (Attr->
Attr ==
ATTR_OF_PCI(SourcePtr))
00454
#endif
00455
{
00456 Attr->
Length += 1;
00457 }
00458
else {
00459 Attr++;
00460 Attr->
Length = 1;
00461
#ifdef WWSB_FE
00462
00463 Attr->
Attr =
ATTR_OF_PCI(SourcePtr) & ~COMMON_LVB_SBCSDBCS;
00464
#else
00465
Attr->
Attr =
ATTR_OF_PCI(SourcePtr);
00466
#endif
00467
AttrLength += 1;
00468 }
00469 }
00470 }
00471
00472
00473
00474 Row->
CharRow.
OldLeft = Row->
CharRow.
Left;
00475
if (TargetPoint.X < Row->
CharRow.
Left) {
00476 PWCHAR LastChar = &Row->
CharRow.
Chars[ScreenInfo->
ScreenBufferSize.X];
00477
00478
for (Char=&Row->
CharRow.
Chars[TargetPoint.X];Char < LastChar && *Char==(WCHAR)
' ';Char++)
00479 ;
00480 Row->
CharRow.
Left = (
SHORT)(Char-Row->
CharRow.
Chars);
00481 }
00482
00483 Row->
CharRow.
OldRight = Row->
CharRow.
Right;
00484
if ((TargetPoint.X+XSize) >= Row->
CharRow.
Right) {
00485
SHORT LastNonSpace;
00486 PWCHAR FirstChar = Row->
CharRow.
Chars;
00487
00488 LastNonSpace = (
SHORT)(TargetPoint.X+XSize-1);
00489
for (Char=&Row->
CharRow.
Chars[(TargetPoint.X+XSize-1)];*Char==(WCHAR)
' ' && Char >= FirstChar;Char--)
00490 LastNonSpace--;
00491
00492
00493
00494
00495
00496
00497
00498 Row->
CharRow.
Right = (
SHORT)(LastNonSpace+1);
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
if (AttrLength != Row->
AttrRow.
Length ||
00508 memcmp(Row->
AttrRow.
Attrs,AttrBuf,AttrLength*
sizeof(*Attr))) {
00509
PATTR_PAIR NewAttrs;
00510 WORD NewAttrsLength;
00511
00512
if (!
NT_SUCCESS(
MergeAttrStrings(Row->
AttrRow.
Attrs,
00513 Row->
AttrRow.
Length,
00514 AttrBuf,
00515 AttrLength,
00516 &NewAttrs,
00517 &NewAttrsLength,
00518 TargetPoint.X,
00519 (
SHORT)(TargetPoint.X+XSize-1),
00520 Row,
00521 ScreenInfo
00522 ))) {
00523
if (XSize > 80) {
00524
ConsoleHeapFree(AttrBuf);
00525 }
00526
ResetTextFlags(ScreenInfo,TargetPoint.Y,(
SHORT)(TargetPoint.Y+YSize-1));
00527
return;
00528 }
00529
if (Row->
AttrRow.
Length > 1) {
00530
ConsoleHeapFree(Row->
AttrRow.
Attrs);
00531 }
00532
else {
00533
ASSERT(Row->
AttrRow.
Attrs == &Row->
AttrRow.
AttrPair);
00534 }
00535 Row->
AttrRow.
Attrs = NewAttrs;
00536 Row->
AttrRow.
Length = NewAttrsLength;
00537 Row->
CharRow.
OldLeft =
INVALID_OLD_LENGTH;
00538 Row->
CharRow.
OldRight =
INVALID_OLD_LENGTH;
00539 }
00540
if (++RowIndex == ScreenInfo->
ScreenBufferSize.Y) {
00541 RowIndex = 0;
00542 }
00543 }
00544
ResetTextFlags(ScreenInfo,TargetPoint.Y,(
SHORT)(TargetPoint.Y+YSize-1));
00545
00546
if (XSize > 80) {
00547
ConsoleHeapFree(AttrBuf);
00548 }
00549 }
00550
00551
VOID
00552 WWSB_WriteRegionToScreen(
00553 IN
PSCREEN_INFORMATION ScreenInfo,
00554 IN PSMALL_RECT Region
00555 )
00556 {
00557 COORD Window;
00558
int i,j;
00559
PATTR_PAIR Attr;
00560 RECT TextRect;
00561
SHORT RowIndex;
00562
SHORT CountOfAttr;
00563
PROW Row;
00564
BOOL OneLine, SimpleWrite;
00565
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
00566 PWCHAR TransBufferCharacter =
NULL ;
00567
#ifdef WWSB_FE
00568
BOOL DoubleColorDbcs;
00569
SHORT CountOfAttrOriginal;
00570
SHORT RegionRight;
00571
BOOL LocalEUDCFlag;
00572 SMALL_RECT CaTextRect;
00573 PCONVERSIONAREA_INFORMATION ConvAreaInfo = ScreenInfo->ConvScreenInfo;
00574
#endif
00575
00576
DBGOUTPUT((
"WriteRegionToScreen\n"));
00577
00578
#ifdef WWSB_FE
00579
if (ConvAreaInfo) {
00580 CaTextRect.Left = Region->Left - ScreenInfo->Console->CurrentScreenBuffer->Window.Left - ConvAreaInfo->CaInfo.coordConView.X;
00581 CaTextRect.Right = CaTextRect.Left + (Region->Right - Region->Left);
00582 CaTextRect.Top = Region->Top - ScreenInfo->Console->CurrentScreenBuffer->Window.Top - ConvAreaInfo->CaInfo.coordConView.Y;
00583 CaTextRect.Bottom = CaTextRect.Top + (Region->Bottom - Region->Top);
00584 }
00585
00586
if (Region->Left && (ScreenInfo->BisectFlag & BISECT_LEFT)) {
00587 Region->Left--;
00588 }
00589
if (Region->Right+1 < ScreenInfo->ScreenBufferSize.X && (ScreenInfo->BisectFlag & BISECT_RIGHT)) {
00590 Region->Right++;
00591 }
00592 ScreenInfo->BisectFlag &= ~(BISECT_LEFT | BISECT_RIGHT);
00593 Console->ConsoleIme.ScrollWaitCountDown = Console->ConsoleIme.ScrollWaitTimeout;
00594
#endif
00595
00596
if (Console->
FullScreenFlags == 0) {
00597
00598
00599
00600
00601
00602
InvertSelection(Console,
TRUE);
00603
00604
ASSERT(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER);
00605
if (
WWSB_PolyTextOutCandidate(ScreenInfo,Region)) {
00606
WWSB_ConsolePolyTextOut(ScreenInfo,Region);
00607 }
00608
else {
00609
00610
#ifdef WWSB_FE
00611
if (ConvAreaInfo) {
00612 Window.Y = Region->Top - Console->
CurrentScreenBuffer->
Window.Top;
00613 Window.X = Region->Left - Console->
CurrentScreenBuffer->
Window.Left;
00614 }
00615
else {
00616
#endif
00617
Window.Y = Region->Top - ScreenInfo->Window.Top;
00618 Window.X = Region->Left - ScreenInfo->Window.Left;
00619
#ifdef WWSB_FE
00620
}
00621
#endif
00622
00623
#ifdef WWSB_FE
00624
RowIndex = (ConvAreaInfo ? CaTextRect.Top :
00625 (ScreenInfo->BufferInfo.TextInfo.FirstRow+Region->Top) % ScreenInfo->ScreenBufferSize.Y
00626 );
00627 RegionRight = Region->Right;
00628
#else
00629
RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+Region->Top) % ScreenInfo->ScreenBufferSize.Y;
00630
#endif
00631
OneLine = (Region->Top==Region->Bottom);
00632
00633 TransBufferCharacter = (PWCHAR)
ConsoleHeapAlloc(
00634
MAKE_TAG( TMP_DBCS_TAG ),
00635 (ScreenInfo->ScreenBufferSize.X*
sizeof(WCHAR))+
sizeof(WCHAR));
00636
if (TransBufferCharacter ==
NULL)
00637 {
00638 KdPrint((
"CONSRV: WriteRegionToScreen cannot allocate memory\n"));
00639
return ;
00640 }
00641
00642
for (i=Region->Top;i<=Region->Bottom;i++,Window.Y++) {
00643
#ifdef WWSB_FE
00644
DoubleColorDbcs =
FALSE;
00645 Region->Right = RegionRight;
00646
#endif
00647
00648
00649
00650
00651
00652 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00653
00654
if (Row->
AttrRow.
Length == 1) {
00655 Attr = Row->
AttrRow.
Attrs;
00656 CountOfAttr = ScreenInfo->ScreenBufferSize.X;
00657 SimpleWrite =
TRUE;
00658 }
else {
00659 SimpleWrite =
FALSE;
00660
FindAttrIndex(Row->
AttrRow.
Attrs,
00661 #ifdef
WWSB_FE
00662 (
SHORT)(ConvAreaInfo ? CaTextRect.Left : Region->Left),
00663 #
else
00664 Region->Left,
00665 #endif
00666 &Attr,
00667 &CountOfAttr
00668 );
00669 }
00670
if (Console->
LastAttributes != Attr->
Attr) {
00671
TEXTCOLOR_CALL;
00672
#ifdef WWSB_FE
00673
if (Attr->
Attr & COMMON_LVB_REVERSE_VIDEO)
00674 {
00675 SetBkColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr->
Attr)));
00676 SetTextColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr->
Attr >> 4)));
00677 }
00678
else{
00679
#endif
00680
SetTextColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr->
Attr)));
00681 SetBkColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr->
Attr >> 4)));
00682
#ifdef WWSB_FE
00683
}
00684
#endif
00685
Console->
LastAttributes = Attr->
Attr;
00686 }
00687 TextRect.top = Window.Y*
SCR_FONTSIZE(ScreenInfo).Y;
00688 TextRect.bottom = TextRect.top +
SCR_FONTSIZE(ScreenInfo).Y;
00689
for (j=Region->Left;j<=Region->Right;) {
00690
SHORT NumberOfChars;
00691
int TextLeft;
00692
SHORT LeftChar,RightChar;
00693
00694
if (CountOfAttr > (
SHORT)(Region->Right - j + 1)) {
00695 CountOfAttr = (
SHORT)(Region->Right - j + 1);
00696 }
00697
00698
#ifdef WWSB_FE
00699
CountOfAttrOriginal = CountOfAttr;
00700
00701
00702 LocalEUDCFlag =
FALSE;
00703
if((ScreenInfo->Console->Flags &
CONSOLE_VDM_REGISTERED &&
00704 ((
PEUDC_INFORMATION)(ScreenInfo->Console->EudcInformation))->LocalVDMEudcMode)){
00705 LocalEUDCFlag =
CheckEudcRangeInString(
00706 Console,
00707 &Row->
CharRow.
Chars[ConvAreaInfo ?
00708 CaTextRect.Left + (j-Region->Left) : j],
00709 CountOfAttr,
00710 &CountOfAttr);
00711 }
00712
if (!(ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
00713 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN) &&
00714 ((
PEUDC_INFORMATION)(ScreenInfo->Console->EudcInformation))->LocalKeisenEudcMode
00715 ) {
00716
SHORT k;
00717 PWCHAR Char2;
00718 Char2 = &Row->
CharRow.
Chars[ConvAreaInfo ? CaTextRect.Left + (j-Region->Left) : j];
00719
for ( k = 0 ; k < CountOfAttr ; k++,Char2++){
00720
if (*Char2 <
UNICODE_SPACE){
00721 CountOfAttr = k ;
00722 LocalEUDCFlag =
TRUE;
00723
break;
00724 }
00725 }
00726 }
00727
#endif
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
if (ScreenInfo->BufferInfo.TextInfo.Flags &
TEXT_VALID_HINT && SimpleWrite) {
00745
if (Row->
CharRow.
OldLeft !=
INVALID_OLD_LENGTH) {
00746 TextRect.left = (
max(
min(Row->
CharRow.
Left,Row->
CharRow.
OldLeft),j)-ScreenInfo->Window.Left) *
00747
SCR_FONTSIZE(ScreenInfo).X;
00748 }
else {
00749 TextRect.left = Window.X*
SCR_FONTSIZE(ScreenInfo).X;
00750 }
00751
00752
if (Row->
CharRow.
OldRight !=
INVALID_OLD_LENGTH) {
00753 TextRect.right = (
min(
max(Row->
CharRow.
Right,Row->
CharRow.
OldRight),j+CountOfAttr)-ScreenInfo->Window.Left) *
00754
SCR_FONTSIZE(ScreenInfo).X;
00755 }
else {
00756 TextRect.right = TextRect.left + CountOfAttr*
SCR_FONTSIZE(ScreenInfo).X;
00757 }
00758 LeftChar =
max(Row->
CharRow.
Left,j);
00759 RightChar =
min(Row->
CharRow.
Right,j+CountOfAttr);
00760 NumberOfChars = RightChar - LeftChar;
00761 TextLeft = (LeftChar-ScreenInfo->Window.Left)*
SCR_FONTSIZE(ScreenInfo).X;
00762 }
else {
00763
#ifdef WWSB_FE
00764
LeftChar = ConvAreaInfo ? CaTextRect.Left + (j-Region->Left) : j;
00765
#else
00766
LeftChar = (
SHORT)j;
00767
#endif
00768
TextRect.left = Window.X*
SCR_FONTSIZE(ScreenInfo).X;
00769 TextRect.right = TextRect.left + CountOfAttr*
SCR_FONTSIZE(ScreenInfo).X;
00770
#ifdef WWSB_FE
00771
if (ConvAreaInfo)
00772 NumberOfChars = (Row->
CharRow.
Right > (
SHORT)((CaTextRect.Left+(j-Region->Left)) + CountOfAttr)) ?
00773 (CountOfAttr) : (
SHORT)(Row->
CharRow.
Right-(CaTextRect.Left+(j-Region->Left)));
00774
else
00775
#endif
00776
NumberOfChars = (Row->
CharRow.
Right > (
SHORT)(j + CountOfAttr)) ? (CountOfAttr) : (
SHORT)(Row->
CharRow.
Right-j);
00777 TextLeft = TextRect.left;
00778 }
00779
00780
if (NumberOfChars < 0)
00781 {
00782 NumberOfChars = 0;
00783
#ifdef WWSB_FE
00784
TextRect.left = Window.X*
SCR_FONTSIZE(ScreenInfo).X;
00785 TextRect.right = TextRect.left + CountOfAttr*
SCR_FONTSIZE(ScreenInfo).X;
00786
#endif
00787
}
00788
TEXTOUT_CALL;
00789
#ifdef WWSB_FE
00790
00791
00792
00793
TextOutEverything(Console,
00794 ScreenInfo,
00795 (
SHORT)j,
00796 &Region->Right,
00797 &CountOfAttr,
00798 CountOfAttrOriginal,
00799 &DoubleColorDbcs,
00800 LocalEUDCFlag,
00801 Row,
00802 Attr,
00803 LeftChar,
00804 RightChar,
00805 TextLeft,
00806 TextRect,
00807 NumberOfChars);
00808
#else
00809
NumberOfChars =
00810 (
SHORT)
RemoveDbcsMarkAll(ScreenInfo,
00811 Row,
00812 &LeftChar,
00813 &TextRect,
00814 &TextLeft,
00815 TransBufferCharacter,
00816 NumberOfChars);
00817 ExtTextOutW(Console->
hDC,
00818 TextLeft,
00819 TextRect.top,
00820 ETO_OPAQUE,
00821 &TextRect,
00822 TransBufferCharacter,
00823 NumberOfChars,
00824
NULL
00825 );
00826
#endif
00827
if (OneLine && SimpleWrite) {
00828
break;
00829 }
00830 j+=CountOfAttr;
00831
if (j <= Region->Right) {
00832 Window.X += CountOfAttr;
00833
#ifdef WWSB_FE
00834
if (CountOfAttr < CountOfAttrOriginal){
00835 CountOfAttr = CountOfAttrOriginal - CountOfAttr;
00836 }
00837
else {
00838
#endif
00839
Attr++;
00840 CountOfAttr = Attr->
Length;
00841
#ifdef WWSB_FE
00842
}
00843
#endif
00844
#ifdef WWSB_FE
00845
if (Attr->
Attr & COMMON_LVB_REVERSE_VIDEO)
00846 {
00847 SetBkColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr->
Attr)));
00848 SetTextColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr->
Attr >> 4)));
00849 }
00850
else{
00851
#endif
00852
SetTextColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr->
Attr)));
00853 SetBkColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr->
Attr >> 4)));
00854
#ifdef WWSB_FE
00855
}
00856
#endif
00857
Console->
LastAttributes = Attr->
Attr;
00858 }
00859 }
00860 Window.X = Region->Left - ScreenInfo->Window.Left;
00861
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
00862 RowIndex = 0;
00863 }
00864 }
00865 GdiFlush();
00866
ConsoleHeapFree(TransBufferCharacter);
00867 }
00868
00869
00870
00871
00872
00873
InvertSelection(Console,
FALSE);
00874 }
00875
#ifdef i386
00876
else if (Console->
FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
00877
#ifdef WWSB_FE
00878
if (! ScreenInfo->ConvScreenInfo) {
00879
if (ScreenInfo->Console->CurrentScreenBuffer == ScreenInfo) {
00880 WWSB_WriteRegionToScreenHW(ScreenInfo,Region);
00881 }
00882 }
00883
else if (ScreenInfo->Console->CurrentScreenBuffer->Flags &
CONSOLE_TEXTMODE_BUFFER)
00884
#endif
00885
WWSB_WriteRegionToScreenHW(ScreenInfo,Region);
00886 }
00887
#endif
00888
00889
#ifdef WWSB_FE
00890
{
00891 SMALL_RECT TmpRegion;
00892
00893
if (ScreenInfo->BisectFlag & BISECT_TOP) {
00894 ScreenInfo->BisectFlag &= ~BISECT_TOP;
00895
if (Region->Top) {
00896 TmpRegion.Top = Region->Top-1;
00897 TmpRegion.Bottom = Region->Top-1;
00898 TmpRegion.Left = ScreenInfo->ScreenBufferSize.X-1;
00899 TmpRegion.Right = ScreenInfo->ScreenBufferSize.X-1;
00900
WWSB_WriteRegionToScreen(ScreenInfo,&TmpRegion);
00901 }
00902 }
00903
if (ScreenInfo->BisectFlag & BISECT_BOTTOM) {
00904 ScreenInfo->BisectFlag &= ~BISECT_BOTTOM;
00905
if (Region->Bottom+1 < ScreenInfo->ScreenBufferSize.Y) {
00906 TmpRegion.Top = Region->Bottom+1;
00907 TmpRegion.Bottom = Region->Bottom+1;
00908 TmpRegion.Left = 0;
00909 TmpRegion.Right = 0;
00910
WWSB_WriteRegionToScreen(ScreenInfo,&TmpRegion);
00911 }
00912 }
00913 }
00914
#endif
00915
}
00916
00917
VOID
00918 WWSB_WriteToScreen(
00919 IN
PSCREEN_INFORMATION ScreenInfo,
00920 IN PSMALL_RECT Region
00921 )
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 {
00942 SMALL_RECT ClippedRegion;
00943
00944
DBGOUTPUT((
"WriteToScreen\n"));
00945
00946
00947
00948
00949
00950
if (!
ACTIVE_SCREEN_BUFFER(ScreenInfo) ||
00951 (ScreenInfo->Console->Flags & (
CONSOLE_IS_ICONIC |
CONSOLE_NO_WINDOW) &&
00952 ScreenInfo->Console->FullScreenFlags == 0)) {
00953
return;
00954 }
00955
00956
00957
00958 ClippedRegion.Left =
max(Region->Left, ScreenInfo->Window.Left);
00959 ClippedRegion.Top =
max(Region->Top, ScreenInfo->Window.Top);
00960 ClippedRegion.Right =
min(Region->Right, ScreenInfo->Window.Right);
00961 ClippedRegion.Bottom =
min(Region->Bottom, ScreenInfo->Window.Bottom);
00962
if (ClippedRegion.Right < ClippedRegion.Left ||
00963 ClippedRegion.Bottom < ClippedRegion.Top) {
00964
return;
00965 }
00966
00967
if (ScreenInfo->Flags &
CONSOLE_GRAPHICS_BUFFER) {
00968
if (ScreenInfo->Console->FullScreenFlags == 0) {
00969
WriteRegionToScreenBitMap(ScreenInfo, &ClippedRegion);
00970 }
00971 }
else {
00972
ConsoleHideCursor(ScreenInfo);
00973
WWSB_WriteRegionToScreen(ScreenInfo, &ClippedRegion);
00974
#ifdef WWSB_FE
00975
if (!(ScreenInfo->Console->ConsoleIme.ScrollFlag & HIDE_FOR_SCROLL))
00976 {
00977 PCONVERSIONAREA_INFORMATION ConvAreaInfo;
00978
00979
if (! ScreenInfo->Console->CurrentScreenBuffer->ConvScreenInfo) {
00980 WriteConvRegionToScreen(ScreenInfo,
00981 ScreenInfo->Console->ConsoleIme.ConvAreaRoot,
00982 Region);
00983 }
00984
else if (ConvAreaInfo = ScreenInfo->Console->ConsoleIme.ConvAreaRoot) {
00985
do {
00986
if (ConvAreaInfo->ScreenBuffer == ScreenInfo)
00987
break;
00988 }
while (ConvAreaInfo = ConvAreaInfo->ConvAreaNext);
00989
if (ConvAreaInfo) {
00990 WriteConvRegionToScreen(ScreenInfo,
00991 ConvAreaInfo->ConvAreaNext,
00992 Region);
00993 }
00994 }
00995 }
00996
#endif
00997
ConsoleShowCursor(ScreenInfo);
00998 }
00999 }
01000
01001
NTSTATUS
01002 WWSB_WriteOutputString(
01003 IN
PSCREEN_INFORMATION ScreenInfo,
01004 IN PVOID Buffer,
01005 IN COORD WriteCoord,
01006 IN ULONG StringType,
01007 IN OUT PULONG NumRecords,
01008 OUT PULONG NumColumns OPTIONAL
01009 )
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043 {
01044 ULONG NumWritten;
01045
SHORT X,Y,LeftX;
01046 SMALL_RECT WriteRegion;
01047
PROW Row;
01048 PWCHAR Char;
01049
SHORT RowIndex;
01050
SHORT j;
01051 PWCHAR TransBuffer;
01052
#ifdef WWSB_NOFE
01053
WCHAR SingleChar;
01054
#endif
01055
UINT Codepage;
01056
#ifdef WWSB_FE
01057
PBYTE AttrP;
01058
PBYTE TransBufferA;
01059
PBYTE BufferA;
01060 ULONG NumRecordsSavedForUnicode;
01061
BOOL fLocalHeap =
FALSE;
01062
#endif
01063
01064
DBGOUTPUT((
"WriteOutputString\n"));
01065
#ifdef WWSB_FE
01066
ASSERT(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER);
01067
#endif
01068
01069
if (*NumRecords == 0)
01070
return STATUS_SUCCESS;
01071
01072 NumWritten = 0;
01073 X=WriteCoord.X;
01074 Y=WriteCoord.Y;
01075
if (X>=ScreenInfo->ScreenBufferSize.X ||
01076 X<0 ||
01077 Y>=ScreenInfo->ScreenBufferSize.Y ||
01078 Y<0) {
01079 *NumRecords = 0;
01080
return STATUS_SUCCESS;
01081 }
01082
01083 ScreenInfo->BufferInfo.TextInfo.Flags |=
TEXT_VALID_HINT;
01084 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+WriteCoord.Y) % ScreenInfo->ScreenBufferSize.Y;
01085
01086
if (StringType ==
CONSOLE_ASCII) {
01087
#ifdef WWSB_FE
01088
PCHAR TmpBuf;
01089 PWCHAR TmpTrans;
01090 ULONG i;
01091 PCHAR TmpTransA;
01092
#endif
01093
01094
if ((ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01095 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
01096
if (ScreenInfo->Console->OutputCP !=
WINDOWSCP)
01097 Codepage =
USACP;
01098
else
01099 Codepage =
WINDOWSCP;
01100 }
else {
01101 Codepage = ScreenInfo->Console->OutputCP;
01102 }
01103
01104
#ifdef WWSB_FE
01105
if (*NumRecords > (ULONG)(ScreenInfo->ScreenBufferSize.X * ScreenInfo->ScreenBufferSize.Y)) {
01106
01107 TransBuffer =
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),*NumRecords * 2 *
sizeof(WCHAR));
01108
if (TransBuffer ==
NULL) {
01109
return STATUS_NO_MEMORY;
01110 }
01111 TransBufferA =
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),*NumRecords * 2 *
sizeof(
CHAR));
01112
if (TransBufferA ==
NULL) {
01113
ConsoleHeapFree(TransBuffer);
01114
return STATUS_NO_MEMORY;
01115 }
01116
01117 fLocalHeap =
TRUE;
01118 }
01119
else {
01120 TransBuffer = ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferCharacter;
01121 TransBufferA = ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferAttribute;
01122 }
01123
01124 TmpBuf =
Buffer;
01125 TmpTrans = TransBuffer;
01126 TmpTransA = TransBufferA;
01127
for (i=0; i < *NumRecords;) {
01128
if (
IsDBCSLeadByteConsole(*TmpBuf,&ScreenInfo->Console->OutputCPInfo)) {
01129
if (i+1 >= *NumRecords) {
01130 *TmpTrans =
UNICODE_SPACE;
01131 *TmpTransA = 0;
01132 i++;
01133 }
01134
else {
01135
ConvertOutputToUnicode(Codepage,
01136 TmpBuf,
01137 2,
01138 TmpTrans,
01139 2);
01140 *(TmpTrans+1) = *TmpTrans;
01141 TmpTrans += 2;
01142 TmpBuf += 2;
01143 *TmpTransA++ = ATTR_LEADING_BYTE;
01144 *TmpTransA++ = ATTR_TRAILING_BYTE;
01145 i += 2;
01146 }
01147 }
01148
else {
01149
ConvertOutputToUnicode(Codepage,
01150 TmpBuf,
01151 1,
01152 TmpTrans,
01153 1);
01154 TmpTrans++;
01155 TmpBuf++;
01156 *TmpTransA++ = 0;
01157 i++;
01158 }
01159 }
01160 BufferA = TransBufferA;
01161
Buffer = TransBuffer;
01162
#else
01163
if (*NumRecords == 1) {
01164 TransBuffer =
NULL;
01165 SingleChar = SB_CharToWcharGlyph(Codepage, *((
char *)
Buffer));
01166
Buffer = &SingleChar;
01167 }
else {
01168 TransBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),*NumRecords *
sizeof(WCHAR));
01169
if (TransBuffer ==
NULL) {
01170
return STATUS_NO_MEMORY;
01171 }
01172
ConvertOutputToUnicode(Codepage,
Buffer, *NumRecords,
01173 TransBuffer, *NumRecords);
01174
Buffer = TransBuffer;
01175 }
01176
#endif
01177
}
else if (StringType ==
CONSOLE_REAL_UNICODE &&
01178 (ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01179 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
01180
RealUnicodeToFalseUnicode(
Buffer,
01181 *NumRecords,
01182 ScreenInfo->Console->OutputCP
01183 );
01184 }
01185
01186
#ifdef WWSB_FE
01187
if ((StringType ==
CONSOLE_REAL_UNICODE) || (StringType ==
CONSOLE_FALSE_UNICODE)) {
01188 PWCHAR TmpBuf;
01189 PWCHAR TmpTrans;
01190 PCHAR TmpTransA;
01191 ULONG i,j;
01192 WCHAR
c;
01193
01194
01195
01196
01197
01198
if ((*NumRecords*2) > (ULONG)(ScreenInfo->ScreenBufferSize.X * ScreenInfo->ScreenBufferSize.Y)) {
01199
01200 TransBuffer =
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),*NumRecords * 2 *
sizeof(WCHAR));
01201
if (TransBuffer ==
NULL) {
01202
return STATUS_NO_MEMORY;
01203 }
01204 TransBufferA =
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),*NumRecords * 2 *
sizeof(
CHAR));
01205
if (TransBufferA ==
NULL) {
01206
ConsoleHeapFree(TransBuffer);
01207
return STATUS_NO_MEMORY;
01208 }
01209
01210 fLocalHeap =
TRUE;
01211 }
01212
else {
01213 TransBuffer = ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferCharacter;
01214 TransBufferA = ScreenInfo->BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferAttribute;
01215 }
01216
01217 TmpBuf =
Buffer;
01218 TmpTrans = TransBuffer;
01219 TmpTransA = TransBufferA;
01220
for (i=0,j=0; i < *NumRecords; i++,j++) {
01221 *TmpTrans++ =
c = *TmpBuf++;
01222 *TmpTransA = 0;
01223
if (IsConsoleFullWidth(ScreenInfo->Console->hDC,
01224 ScreenInfo->Console->OutputCP,
c)) {
01225 *TmpTransA++ = ATTR_LEADING_BYTE;
01226 *TmpTrans++ =
c;
01227 *TmpTransA = ATTR_TRAILING_BYTE;
01228 j++;
01229 }
01230 TmpTransA++;
01231 }
01232 NumRecordsSavedForUnicode = *NumRecords;
01233 *NumRecords = j;
01234
Buffer = TransBuffer;
01235 BufferA = TransBufferA;
01236 }
01237
#endif
01238
01239
if ((StringType ==
CONSOLE_REAL_UNICODE) ||
01240 (StringType ==
CONSOLE_FALSE_UNICODE) ||
01241 (StringType ==
CONSOLE_ASCII)) {
01242
while (
TRUE) {
01243
01244 LeftX = X;
01245
01246
01247
01248
01249
01250 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01251 Char = &Row->
CharRow.
Chars[X];
01252
#ifdef WWSB_FE
01253
AttrP = &Row->
CharRow.KAttrs[X];
01254
#endif
01255
if ((ULONG)(ScreenInfo->ScreenBufferSize.X - X) >= (*NumRecords - NumWritten)) {
01256
01257
01258
01259
#ifdef WWSB_FE
01260
COORD TPoint;
01261
01262 TPoint.X = X;
01263 TPoint.Y = Y;
01264
BisectWrite((
SHORT)(*NumRecords-NumWritten),TPoint,ScreenInfo);
01265
if (TPoint.Y == ScreenInfo->ScreenBufferSize.Y-1 &&
01266 (
SHORT)(TPoint.X+*NumRecords-NumWritten) >= ScreenInfo->ScreenBufferSize.X &&
01267 *((PCHAR)BufferA+ScreenInfo->ScreenBufferSize.X-TPoint.X-1) & ATTR_LEADING_BYTE
01268 ) {
01269 *((PWCHAR)
Buffer+ScreenInfo->ScreenBufferSize.X-TPoint.X-1) =
UNICODE_SPACE;
01270 *((PCHAR)BufferA+ScreenInfo->ScreenBufferSize.X-TPoint.X-1) = 0;
01271
if ((
SHORT)(*NumRecords-NumWritten) > (
SHORT)(ScreenInfo->ScreenBufferSize.X-TPoint.X-1)) {
01272 *((PWCHAR)
Buffer+ScreenInfo->ScreenBufferSize.X-TPoint.X) =
UNICODE_SPACE;
01273 *((PCHAR)BufferA+ScreenInfo->ScreenBufferSize.X-TPoint.X) = 0;
01274 }
01275 }
01276 RtlCopyMemory(AttrP,BufferA,(*NumRecords - NumWritten) *
sizeof(
CHAR));
01277
#endif
01278
RtlCopyMemory(Char,
Buffer,(*NumRecords - NumWritten) *
sizeof(WCHAR));
01279 X=(
SHORT)(X+*NumRecords - NumWritten-1);
01280 NumWritten = *NumRecords;
01281 }
01282
else {
01283
01284
01285
01286
#ifdef WWSB_FE
01287
COORD TPoint;
01288
01289 TPoint.X = X;
01290 TPoint.Y = Y;
01291
BisectWrite((
SHORT)(ScreenInfo->ScreenBufferSize.X-X),TPoint,ScreenInfo);
01292
if (TPoint.Y == ScreenInfo->ScreenBufferSize.Y-1 &&
01293 TPoint.X+ScreenInfo->ScreenBufferSize.X-X >= ScreenInfo->ScreenBufferSize.X &&
01294 *((PCHAR)BufferA+ScreenInfo->ScreenBufferSize.X-TPoint.X-1) & ATTR_LEADING_BYTE
01295 ) {
01296 *((PWCHAR)
Buffer+ScreenInfo->ScreenBufferSize.X-TPoint.X-1) =
UNICODE_SPACE;
01297 *((PCHAR)BufferA+ScreenInfo->ScreenBufferSize.X-TPoint.X-1) = 0;
01298
if (ScreenInfo->ScreenBufferSize.X-X > ScreenInfo->ScreenBufferSize.X-TPoint.X-1) {
01299 *((PWCHAR)
Buffer+ScreenInfo->ScreenBufferSize.X-TPoint.X) =
UNICODE_SPACE;
01300 *((PCHAR)BufferA+ScreenInfo->ScreenBufferSize.X-TPoint.X) = 0;
01301 }
01302 }
01303 RtlCopyMemory(AttrP,BufferA,(ScreenInfo->ScreenBufferSize.X - X) *
sizeof(
CHAR));
01304 BufferA = (PVOID)((
PBYTE)BufferA + ((ScreenInfo->ScreenBufferSize.X - X) *
sizeof(
CHAR)));
01305
#endif
01306
RtlCopyMemory(Char,
Buffer,(ScreenInfo->ScreenBufferSize.X - X) *
sizeof(WCHAR));
01307
Buffer = (PVOID)((
PBYTE)
Buffer + ((ScreenInfo->ScreenBufferSize.X - X) *
sizeof(WCHAR)));
01308 NumWritten += ScreenInfo->ScreenBufferSize.X - X;
01309 X = (
SHORT)(ScreenInfo->ScreenBufferSize.X-1);
01310 }
01311
01312
01313
01314 Row->
CharRow.
OldLeft = Row->
CharRow.
Left;
01315
if (LeftX < Row->
CharRow.
Left) {
01316 PWCHAR LastChar = &Row->
CharRow.
Chars[ScreenInfo->ScreenBufferSize.X];
01317
01318
for (Char=&Row->
CharRow.
Chars[LeftX];Char < LastChar && *Char==(WCHAR)
' ';Char++)
01319 ;
01320 Row->
CharRow.
Left = (
SHORT)(Char-Row->
CharRow.
Chars);
01321 }
01322
01323 Row->
CharRow.
OldRight = Row->
CharRow.
Right;
01324
if ((X+1) >= Row->
CharRow.
Right) {
01325 WORD LastNonSpace;
01326 PWCHAR FirstChar = Row->
CharRow.
Chars;
01327
01328 LastNonSpace = X;
01329
for (Char=&Row->
CharRow.
Chars[X];*Char==(WCHAR)
' ' && Char >= FirstChar;Char--)
01330 LastNonSpace--;
01331 Row->
CharRow.
Right = (
SHORT)(LastNonSpace+1);
01332 }
01333
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01334 RowIndex = 0;
01335 }
01336
if (NumWritten < *NumRecords) {
01337
01338
01339
01340
01341
01342
01343 X = 0;
01344 Y++;
01345
if (Y >= ScreenInfo->ScreenBufferSize.Y) {
01346
break;
01347 }
01348 }
else {
01349
break;
01350 }
01351 }
01352 }
else if (StringType ==
CONSOLE_ATTRIBUTE) {
01353 PWORD SourcePtr=
Buffer;
01354
PATTR_PAIR AttrBuf;
01355
ATTR_PAIR Attrs[80];
01356
PATTR_PAIR Attr;
01357
SHORT AttrLength;
01358
01359 AttrBuf = Attrs;
01360
if (ScreenInfo->ScreenBufferSize.X > 80) {
01361 AttrBuf = (
PATTR_PAIR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),ScreenInfo->ScreenBufferSize.X *
sizeof(
ATTR_PAIR));
01362
if (AttrBuf ==
NULL)
01363
return STATUS_NO_MEMORY;
01364 }
01365
#ifdef WWSB_FE
01366
{
01367 COORD TPoint;
01368 TPoint.X = X;
01369 TPoint.Y = Y;
01370
if ((ULONG)(ScreenInfo->ScreenBufferSize.X - X) >= (*NumRecords - NumWritten)) {
01371
BisectWriteAttr((
SHORT)(*NumRecords-NumWritten),TPoint,ScreenInfo);
01372 }
01373
else{
01374
BisectWriteAttr((
SHORT)(ScreenInfo->ScreenBufferSize.X-X),TPoint,ScreenInfo);
01375 }
01376 }
01377
#endif
01378
while (
TRUE) {
01379
01380
01381
01382
01383
01384 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01385 Attr = AttrBuf;
01386 Attr->
Length = 0;
01387
#ifdef WWSB_FE
01388
Attr->
Attr = *SourcePtr & ~COMMON_LVB_SBCSDBCS;
01389
#else
01390
Attr->
Attr = *SourcePtr;
01391
#endif
01392
AttrLength = 1;
01393
for (j=X;j<ScreenInfo->ScreenBufferSize.X;j++,SourcePtr++) {
01394
#ifdef WWSB_FE
01395
if (Attr->
Attr == (*SourcePtr & ~COMMON_LVB_SBCSDBCS))
01396
#else
01397
if (Attr->
Attr == *SourcePtr)
01398
#endif
01399
{
01400 Attr->
Length += 1;
01401 }
01402
else {
01403 Attr++;
01404 Attr->
Length = 1;
01405
#ifdef WWSB_FE
01406
Attr->
Attr = *SourcePtr & ~COMMON_LVB_SBCSDBCS;
01407
#else
01408
Attr->
Attr = *SourcePtr;
01409
#endif
01410
AttrLength += 1;
01411 }
01412 NumWritten++;
01413 X++;
01414
if (NumWritten == *NumRecords) {
01415
break;
01416 }
01417 }
01418 X--;
01419
01420
01421
01422
01423
01424
01425
01426
01427
if (AttrLength != Row->
AttrRow.
Length ||
01428 memcmp(Row->
AttrRow.
Attrs,AttrBuf,AttrLength*
sizeof(*Attr))) {
01429
PATTR_PAIR NewAttrs;
01430 WORD NewAttrsLength;
01431
01432
if (!
NT_SUCCESS(
MergeAttrStrings(Row->
AttrRow.
Attrs,
01433 Row->
AttrRow.
Length,
01434 AttrBuf,
01435 AttrLength,
01436 &NewAttrs,
01437 &NewAttrsLength,
01438 (
SHORT)((Y == WriteCoord.Y) ? WriteCoord.X : 0),
01439 X,
01440 Row,
01441 ScreenInfo
01442 ))) {
01443
if (ScreenInfo->ScreenBufferSize.X > 80) {
01444
ConsoleHeapFree(AttrBuf);
01445 }
01446
ResetTextFlags(ScreenInfo,WriteCoord.Y,Y);
01447
return STATUS_NO_MEMORY;
01448 }
01449
if (Row->
AttrRow.
Length > 1) {
01450
ConsoleHeapFree(Row->
AttrRow.
Attrs);
01451 }
01452
else {
01453
ASSERT(Row->
AttrRow.
Attrs == &Row->
AttrRow.
AttrPair);
01454 }
01455 Row->
AttrRow.
Attrs = NewAttrs;
01456 Row->
AttrRow.
Length = NewAttrsLength;
01457 Row->
CharRow.
OldLeft =
INVALID_OLD_LENGTH;
01458 Row->
CharRow.
OldRight =
INVALID_OLD_LENGTH;
01459 }
01460
01461
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01462 RowIndex = 0;
01463 }
01464
if (NumWritten < *NumRecords) {
01465 X = 0;
01466 Y++;
01467
if (Y>=ScreenInfo->ScreenBufferSize.Y) {
01468
break;
01469 }
01470 }
else {
01471
break;
01472 }
01473 }
01474
ResetTextFlags(ScreenInfo,WriteCoord.Y,Y);
01475
if (ScreenInfo->ScreenBufferSize.X > 80) {
01476
ConsoleHeapFree(AttrBuf);
01477 }
01478 }
else {
01479 *NumRecords = 0;
01480
return STATUS_INVALID_PARAMETER;
01481 }
01482
if ((StringType ==
CONSOLE_ASCII) && (TransBuffer !=
NULL)) {
01483
#ifdef WWSB_FE
01484
if (fLocalHeap) {
01485
ConsoleHeapFree(TransBuffer);
01486
ConsoleHeapFree(TransBufferA);
01487 }
01488
#else
01489
ConsoleHeapFree(TransBuffer);
01490
#endif
01491
}
01492
#ifdef WWSB_FE
01493
else if ((StringType ==
CONSOLE_FALSE_UNICODE) || (StringType ==
CONSOLE_REAL_UNICODE)) {
01494
if (fLocalHeap) {
01495
ConsoleHeapFree(TransBuffer);
01496
ConsoleHeapFree(TransBufferA);
01497 }
01498 NumWritten = NumRecordsSavedForUnicode - (*NumRecords - NumWritten);
01499 }
01500
#endif
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511 WriteRegion.Top = WriteCoord.Y;
01512 WriteRegion.Bottom = Y;
01513
if (Y != WriteCoord.Y) {
01514 WriteRegion.Left = 0;
01515 WriteRegion.Right = (
SHORT)(ScreenInfo->ScreenBufferSize.X-1);
01516 }
01517
else {
01518 WriteRegion.Left = WriteCoord.X;
01519 WriteRegion.Right = X;
01520 }
01521
WWSB_WriteToScreen(ScreenInfo,&WriteRegion);
01522
if (NumColumns) {
01523 *NumColumns = X + (WriteCoord.Y - Y) * ScreenInfo->ScreenBufferSize.X - WriteCoord.X + 1;
01524 }
01525 *NumRecords = NumWritten;
01526
return STATUS_SUCCESS;
01527 }
01528
01529
NTSTATUS
01530 WWSB_FillOutput(
01531 IN
PSCREEN_INFORMATION ScreenInfo,
01532 IN WORD Element,
01533 IN COORD WriteCoord,
01534 IN ULONG ElementType,
01535 IN OUT PULONG Length
01536 )
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 {
01570 ULONG NumWritten;
01571
SHORT X,Y,LeftX;
01572 SMALL_RECT WriteRegion;
01573
PROW Row;
01574 PWCHAR Char;
01575
SHORT RowIndex;
01576
SHORT j;
01577
#ifdef WWSB_FE
01578
PCHAR AttrP;
01579
#endif
01580
01581
DBGOUTPUT((
"FillOutput\n"));
01582
if (*Length == 0)
01583
return STATUS_SUCCESS;
01584 NumWritten = 0;
01585 X=WriteCoord.X;
01586 Y=WriteCoord.Y;
01587
if (X>=ScreenInfo->ScreenBufferSize.X ||
01588 X<0 ||
01589 Y>=ScreenInfo->ScreenBufferSize.Y ||
01590 Y<0) {
01591 *Length = 0;
01592
return STATUS_SUCCESS;
01593 }
01594
01595
#ifdef WWSB_FE
01596
ASSERT(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER);
01597
#endif
01598
01599 ScreenInfo->BufferInfo.TextInfo.Flags |=
TEXT_VALID_HINT;
01600 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+WriteCoord.Y) % ScreenInfo->ScreenBufferSize.Y;
01601
01602
if (ElementType ==
CONSOLE_ASCII) {
01603
UINT Codepage;
01604
if ((ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01605 ((ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
01606
if (ScreenInfo->Console->OutputCP !=
WINDOWSCP)
01607 Codepage =
USACP;
01608
else
01609 Codepage =
WINDOWSCP;
01610 }
else {
01611 Codepage = ScreenInfo->Console->OutputCP;
01612 }
01613
#ifdef WWSB_FE
01614
if (ScreenInfo->FillOutDbcsLeadChar == 0){
01615
if (
IsDBCSLeadByteConsole((
CHAR)Element,&ScreenInfo->Console->OutputCPInfo)) {
01616 ScreenInfo->FillOutDbcsLeadChar = (
CHAR)Element;
01617 *Length = 0;
01618
return STATUS_SUCCESS;
01619 }
else{
01620
CHAR Char=(
CHAR)Element;
01621
ConvertOutputToUnicode(Codepage,
01622 &Char,
01623 1,
01624 &Element,
01625 1);
01626 }
01627 }
else{
01628
CHAR Char[2];
01629 Char[0]=ScreenInfo->FillOutDbcsLeadChar;
01630 Char[1]=(
BYTE)Element;
01631 ScreenInfo->FillOutDbcsLeadChar = 0;
01632
ConvertOutputToUnicode(Codepage,
01633 Char,
01634 2,
01635 &Element,
01636 2);
01637 }
01638
#else
01639
Element = SB_CharToWchar(Codepage, (
CHAR)Element);
01640
#endif
01641
}
else if (ElementType ==
CONSOLE_REAL_UNICODE &&
01642 (ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01643 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
01644
RealUnicodeToFalseUnicode(&Element,
01645 1,
01646 ScreenInfo->Console->OutputCP
01647 );
01648 }
01649
01650
if ((ElementType ==
CONSOLE_ASCII) ||
01651 (ElementType ==
CONSOLE_REAL_UNICODE) ||
01652 (ElementType ==
CONSOLE_FALSE_UNICODE)) {
01653
#ifdef WWSB_FE
01654
DWORD StartPosFlag ;
01655 StartPosFlag = 0;
01656
#endif
01657
while (
TRUE) {
01658
01659
01660
01661
01662
01663 LeftX = X;
01664 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01665 Char = &Row->
CharRow.
Chars[X];
01666
#ifdef WWSB_FE
01667
AttrP = &Row->
CharRow.KAttrs[X];
01668
#endif
01669
if ((ULONG)(ScreenInfo->ScreenBufferSize.X - X) >= (*Length - NumWritten)) {
01670
#ifdef WWSB_FE
01671
{
01672 COORD TPoint;
01673
01674 TPoint.X = X;
01675 TPoint.Y = Y;
01676
BisectWrite((
SHORT)(*Length-NumWritten),TPoint,ScreenInfo);
01677 }
01678
#endif
01679
#ifdef WWSB_FE
01680
if (IsConsoleFullWidth(ScreenInfo->Console->hDC,
01681 ScreenInfo->Console->OutputCP,(WCHAR)Element)) {
01682
for (j=0;j<(
SHORT)(*Length - NumWritten);j++) {
01683 *Char++ = (WCHAR)Element;
01684 *AttrP &= ~ATTR_DBCSSBCS_BYTE;
01685
if(StartPosFlag++ & 1)
01686 *AttrP++ |= ATTR_TRAILING_BYTE;
01687
else
01688 *AttrP++ |= ATTR_LEADING_BYTE;
01689 }
01690
if(StartPosFlag & 1){
01691 *(Char-1) =
UNICODE_SPACE;
01692 *(AttrP-1) &= ~ATTR_DBCSSBCS_BYTE;
01693 }
01694 }
01695
else {
01696
#endif
01697
for (j=0;j<(
SHORT)(*Length - NumWritten);j++) {
01698 *Char++ = (WCHAR)Element;
01699
#ifdef WWSB_FE
01700
*AttrP++ &= ~ATTR_DBCSSBCS_BYTE;
01701
#endif
01702
}
01703
#ifdef WWSB_FE
01704
}
01705
#endif
01706
X=(
SHORT)(X+*Length - NumWritten - 1);
01707 NumWritten = *Length;
01708 }
01709
else {
01710
#ifdef WWSB_FE
01711
{
01712 COORD TPoint;
01713
01714 TPoint.X = X;
01715 TPoint.Y = Y;
01716
BisectWrite((
SHORT)(ScreenInfo->ScreenBufferSize.X-X),TPoint,ScreenInfo);
01717 }
01718
#endif
01719
#ifdef WWSB_FE
01720
if (IsConsoleFullWidth(ScreenInfo->Console->hDC,
01721 ScreenInfo->Console->OutputCP,(WCHAR)Element)) {
01722
for (j=0;j<ScreenInfo->ScreenBufferSize.X - X;j++) {
01723 *Char++ = (WCHAR)Element;
01724 *AttrP &= ~ATTR_DBCSSBCS_BYTE;
01725
if(StartPosFlag++ & 1)
01726 *AttrP++ |= ATTR_TRAILING_BYTE;
01727
else
01728 *AttrP++ |= ATTR_LEADING_BYTE;
01729 }
01730 }
01731
else {
01732
#endif
01733
for (j=0;j<ScreenInfo->ScreenBufferSize.X - X;j++) {
01734 *Char++ = (WCHAR)Element;
01735
#ifdef WWSB_FE
01736
*AttrP++ &= ~ATTR_DBCSSBCS_BYTE;
01737
#endif
01738
}
01739
#ifdef WWSB_FE
01740
}
01741
#endif
01742
NumWritten += ScreenInfo->ScreenBufferSize.X - X;
01743 X = (
SHORT)(ScreenInfo->ScreenBufferSize.X-1);
01744 }
01745
01746
01747
01748 Row->
CharRow.
OldLeft = Row->
CharRow.
Left;
01749
if (LeftX < Row->
CharRow.
Left) {
01750
if (Element ==
UNICODE_SPACE) {
01751 Row->
CharRow.
Left = X+1;
01752 }
else {
01753 Row->
CharRow.
Left = LeftX;
01754 }
01755 }
01756 Row->
CharRow.
OldRight = Row->
CharRow.
Right;
01757
if ((X+1) >= Row->
CharRow.
Right) {
01758
if (Element ==
UNICODE_SPACE) {
01759 Row->
CharRow.
Right = LeftX;
01760 }
else {
01761 Row->
CharRow.
Right = X+1;
01762 }
01763 }
01764
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01765 RowIndex = 0;
01766 }
01767
if (NumWritten < *Length) {
01768 X = 0;
01769 Y++;
01770
if (Y>=ScreenInfo->ScreenBufferSize.Y) {
01771
break;
01772 }
01773 }
else {
01774
break;
01775 }
01776 }
01777 }
else if (ElementType ==
CONSOLE_ATTRIBUTE) {
01778
ATTR_PAIR Attr;
01779
01780
#ifdef WWSB_FE
01781
COORD TPoint;
01782 TPoint.X = X;
01783 TPoint.Y = Y;
01784
01785
if ((ULONG)(ScreenInfo->ScreenBufferSize.X - X) >= (*Length - NumWritten)) {
01786
BisectWriteAttr((
SHORT)(*Length-NumWritten),TPoint,ScreenInfo);
01787 }
01788
else{
01789
BisectWriteAttr((
SHORT)(ScreenInfo->ScreenBufferSize.X-X),TPoint,ScreenInfo);
01790 }
01791
#endif
01792
01793
while (
TRUE) {
01794
01795
01796
01797
01798
01799 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01800
if ((ULONG)(ScreenInfo->ScreenBufferSize.X - X) >= (*Length - NumWritten)) {
01801 X=(
SHORT)(X+*Length - NumWritten - 1);
01802 NumWritten = *Length;
01803 }
01804
else {
01805 NumWritten += ScreenInfo->ScreenBufferSize.X - X;
01806 X = (
SHORT)(ScreenInfo->ScreenBufferSize.X-1);
01807 }
01808
01809
01810
01811
01812
01813
01814
01815 Attr.
Length = (
SHORT)((Y == WriteCoord.Y) ? (X-WriteCoord.X+1) : (X+1));
01816
#ifdef WWSB_FE
01817
Attr.
Attr = Element & ~COMMON_LVB_SBCSDBCS;
01818
#else
01819
Attr.
Attr = Element;
01820
#endif
01821
if (1 != Row->
AttrRow.
Length ||
01822 memcmp(Row->
AttrRow.
Attrs,&Attr,
sizeof(Attr))) {
01823
PATTR_PAIR NewAttrs;
01824 WORD NewAttrsLength;
01825
01826
if (!
NT_SUCCESS(
MergeAttrStrings(Row->
AttrRow.
Attrs,
01827 Row->
AttrRow.
Length,
01828 &Attr,
01829 1,
01830 &NewAttrs,
01831 &NewAttrsLength,
01832 (
SHORT)(X-Attr.Length+1),
01833 X,
01834 Row,
01835 ScreenInfo
01836 ))) {
01837
ResetTextFlags(ScreenInfo,WriteCoord.Y,Y);
01838
return STATUS_NO_MEMORY;
01839 }
01840
if (Row->
AttrRow.
Length > 1) {
01841
ConsoleHeapFree(Row->
AttrRow.
Attrs);
01842 }
01843
else {
01844
ASSERT(Row->
AttrRow.
Attrs == &Row->
AttrRow.
AttrPair);
01845 }
01846 Row->
AttrRow.
Attrs = NewAttrs;
01847 Row->
AttrRow.
Length = NewAttrsLength;
01848 Row->
CharRow.
OldLeft =
INVALID_OLD_LENGTH;
01849 Row->
CharRow.
OldRight =
INVALID_OLD_LENGTH;
01850 }
01851
01852
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
01853 RowIndex = 0;
01854 }
01855
if (NumWritten < *Length) {
01856 X = 0;
01857 Y++;
01858
if (Y>=ScreenInfo->ScreenBufferSize.Y) {
01859
break;
01860 }
01861 }
else {
01862
break;
01863 }
01864 }
01865
ResetTextFlags(ScreenInfo,WriteCoord.Y,Y);
01866 }
else {
01867 *Length = 0;
01868
return STATUS_INVALID_PARAMETER;
01869 }
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
#ifdef WWSB_FE
01881
if (ScreenInfo->ConvScreenInfo) {
01882 WriteRegion.Top = WriteCoord.Y + ScreenInfo->Window.Left + ScreenInfo->ConvScreenInfo->CaInfo.coordConView.Y;
01883 WriteRegion.Bottom = Y + ScreenInfo->Window.Left + ScreenInfo->ConvScreenInfo->CaInfo.coordConView.Y;
01884
if (Y != WriteCoord.Y) {
01885 WriteRegion.Left = 0;
01886 WriteRegion.Right = (
SHORT)(ScreenInfo->Console->CurrentScreenBuffer->ScreenBufferSize.X-1);
01887 }
01888
else {
01889 WriteRegion.Left = WriteCoord.X + ScreenInfo->Window.Top + ScreenInfo->ConvScreenInfo->CaInfo.coordConView.X;
01890 WriteRegion.Right = X + ScreenInfo->Window.Top + ScreenInfo->ConvScreenInfo->CaInfo.coordConView.X;
01891 }
01892 WriteConvRegionToScreen(ScreenInfo->Console->CurrentScreenBuffer,
01893 ScreenInfo->ConvScreenInfo,
01894 &WriteRegion
01895 );
01896 ScreenInfo->BisectFlag &= ~(BISECT_LEFT | BISECT_RIGHT | BISECT_TOP | BISECT_BOTTOM);
01897 *Length = NumWritten;
01898
return STATUS_SUCCESS;
01899 }
01900
#endif
01901
01902 WriteRegion.Top = WriteCoord.Y;
01903 WriteRegion.Bottom = Y;
01904
if (Y != WriteCoord.Y) {
01905 WriteRegion.Left = 0;
01906 WriteRegion.Right = (
SHORT)(ScreenInfo->ScreenBufferSize.X-1);
01907 }
01908
else {
01909 WriteRegion.Left = WriteCoord.X;
01910 WriteRegion.Right = X;
01911 }
01912
WWSB_WriteToScreen(ScreenInfo,&WriteRegion);
01913 *Length = NumWritten;
01914
return STATUS_SUCCESS;
01915 }
01916
01917
VOID
01918 WWSB_FillRectangle(
01919 IN CHAR_INFO Fill,
01920 IN OUT
PSCREEN_INFORMATION ScreenInfo,
01921 IN PSMALL_RECT TargetRect
01922 )
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943 {
01944
SHORT i,j;
01945
SHORT XSize;
01946
SHORT RowIndex;
01947
PROW Row;
01948 PWCHAR Char;
01949
ATTR_PAIR Attr;
01950
#ifdef WWSB_FE
01951
PCHAR AttrP;
01952
BOOL Width;
01953
#endif
01954
DBGOUTPUT((
"FillRectangle\n"));
01955
#ifdef WWFE_SB
01956
ASSERT(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER);
01957
#endif
01958
01959 XSize = (
SHORT)(TargetRect->Right - TargetRect->Left + 1);
01960
01961 ScreenInfo->BufferInfo.TextInfo.Flags |=
TEXT_VALID_HINT;
01962 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetRect->Top) % ScreenInfo->ScreenBufferSize.Y;
01963
for (i=TargetRect->Top;i<=TargetRect->Bottom;i++) {
01964
01965
01966
01967
01968
01969
#ifdef WWSB_FE
01970
{
01971 COORD TPoint;
01972
01973 TPoint.X = TargetRect->Left;
01974 TPoint.Y = i;
01975
BisectWrite(XSize,TPoint,ScreenInfo);
01976 Width = IsConsoleFullWidth(ScreenInfo->Console->hDC,
01977 ScreenInfo->Console->OutputCP,Fill.Char.UnicodeChar);
01978 }
01979
#endif
01980
01981 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
01982 Char = &Row->
CharRow.
Chars[TargetRect->Left];
01983
#ifdef WWSB_FE
01984
AttrP = &Row->
CharRow.KAttrs[TargetRect->Left];
01985
#endif
01986
for (j=0;j<XSize;j++) {
01987
#ifdef WWSB_FE
01988
if (Width){
01989
if (j < XSize-1){
01990 *Char++ = Fill.Char.UnicodeChar;
01991 *Char++ = Fill.Char.UnicodeChar;
01992 *AttrP++ = ATTR_LEADING_BYTE;
01993 *AttrP++ = ATTR_TRAILING_BYTE;
01994 j++;
01995 }
01996
else{
01997 *Char++ =
UNICODE_SPACE;
01998 *AttrP++ = 0 ;
01999 }
02000 }
02001
else{
02002
#endif
02003
*Char++ = Fill.Char.UnicodeChar;
02004
#ifdef WWSB_FE
02005
*AttrP++ = 0 ;
02006 }
02007
#endif
02008
}
02009
02010
02011
02012 Row->
CharRow.
OldLeft = Row->
CharRow.
Left;
02013
if (TargetRect->Left < Row->
CharRow.
Left) {
02014
if (Fill.Char.UnicodeChar ==
UNICODE_SPACE) {
02015 Row->
CharRow.
Left = (
SHORT)(TargetRect->Right+1);
02016 }
02017
else {
02018 Row->
CharRow.
Left = (
SHORT)(TargetRect->Left);
02019 }
02020 }
02021
02022 Row->
CharRow.
OldRight = Row->
CharRow.
Right;
02023
if (TargetRect->Right >= Row->
CharRow.
Right) {
02024
if (Fill.Char.UnicodeChar ==
UNICODE_SPACE) {
02025 Row->
CharRow.
Right = (
SHORT)(TargetRect->Left);
02026 }
02027
else {
02028 Row->
CharRow.
Right = (
SHORT)(TargetRect->Right+1);
02029 }
02030 }
02031
02032 Attr.
Length = XSize;
02033 Attr.
Attr = Fill.Attributes;
02034
02035
02036
02037
02038
02039
if (1 != Row->
AttrRow.
Length ||
02040 memcmp(Row->
AttrRow.
Attrs,&Attr,
sizeof(Attr))) {
02041
PATTR_PAIR NewAttrs;
02042 WORD NewAttrsLength;
02043
02044
if (!
NT_SUCCESS(
MergeAttrStrings(Row->
AttrRow.
Attrs,
02045 Row->
AttrRow.
Length,
02046 &Attr,
02047 1,
02048 &NewAttrs,
02049 &NewAttrsLength,
02050 TargetRect->Left,
02051 TargetRect->Right,
02052 Row,
02053 ScreenInfo
02054 ))) {
02055
ResetTextFlags(ScreenInfo,TargetRect->Top,TargetRect->Bottom);
02056
return;
02057 }
02058
if (Row->
AttrRow.
Length > 1) {
02059
ConsoleHeapFree(Row->
AttrRow.
Attrs);
02060 }
02061
else {
02062
ASSERT(Row->
AttrRow.
Attrs == &Row->
AttrRow.
AttrPair);
02063 }
02064 Row->
AttrRow.
Attrs = NewAttrs;
02065 Row->
AttrRow.
Length = NewAttrsLength;
02066 Row->
CharRow.
OldLeft =
INVALID_OLD_LENGTH;
02067 Row->
CharRow.
OldRight =
INVALID_OLD_LENGTH;
02068 }
02069
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
02070 RowIndex = 0;
02071 }
02072 }
02073
ResetTextFlags(ScreenInfo,TargetRect->Top,TargetRect->Bottom);
02074 }
02075
02076
BOOL
02077 WWSB_PolyTextOutCandidate(
02078 IN
PSCREEN_INFORMATION ScreenInfo,
02079 IN PSMALL_RECT Region
02080 )
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090 {
02091
SHORT RowIndex;
02092
PROW Row;
02093
SHORT i;
02094
02095
#ifdef WWSB_FE
02096
if((ScreenInfo->Console->Flags &
CONSOLE_VDM_REGISTERED &&
02097 ((
PEUDC_INFORMATION)(ScreenInfo->Console->EudcInformation))->LocalVDMEudcMode)){
02098
return FALSE;
02099 }
02100
if (!(ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
02101 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN) &&
02102 ((
PEUDC_INFORMATION)(ScreenInfo->Console->EudcInformation))->LocalKeisenEudcMode
02103 ) {
02104
return FALSE;
02105 }
02106
ASSERT(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER);
02107
if (ScreenInfo->BufferInfo.TextInfo.Flags & CONSOLE_CONVERSION_AREA_REDRAW) {
02108
return FALSE;
02109 }
02110
#endif
02111
02112
if (ScreenInfo->BufferInfo.TextInfo.Flags &
SINGLE_ATTRIBUTES_PER_LINE) {
02113
return TRUE;
02114 }
02115
02116
02117
02118
02119
02120 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+Region->Top) % ScreenInfo->ScreenBufferSize.Y;
02121
for (i=Region->Top;i<=Region->Bottom;i++) {
02122 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
02123
if (Row->
AttrRow.
Length != 1) {
02124
return FALSE;
02125 }
02126
if (++RowIndex == ScreenInfo->ScreenBufferSize.Y) {
02127 RowIndex = 0;
02128 }
02129 }
02130
return TRUE;
02131 }
02132
02133
02134 #define MAX_POLY_LINES 80
02135 #define VERY_BIG_NUMBER 0x0FFFFFFF
02136
02137
#ifdef WWSB_FE
02138
typedef struct _KEISEN_INFORMATION {
02139 COORD Coord;
02140 WORD
n;
02141 } KEISEN_INFORMATION, *PKEISEN_INFORMATION;
02142
#endif
02143
02144
VOID
02145 WWSB_ConsolePolyTextOut(
02146 IN
PSCREEN_INFORMATION ScreenInfo,
02147 IN PSMALL_RECT Region
02148 )
02149
02150
02151
02152
02153
02154
02155
02156
02157 {
02158
PROW Row,LastRow;
02159
SHORT i,k;
02160 WORD Attr;
02161 POLYTEXTW TextInfo[
MAX_POLY_LINES];
02162 RECT TextRect;
02163 RECTL BoundingRect;
02164
int xSize =
SCR_FONTSIZE(ScreenInfo).X;
02165
int ySize =
SCR_FONTSIZE(ScreenInfo).Y;
02166 ULONG Flags = ScreenInfo->BufferInfo.TextInfo.Flags;
02167
int WindowLeft = ScreenInfo->Window.Left;
02168
int RegionLeft = Region->Left;
02169
int RegionRight = Region->Right + 1;
02170
int DefaultLeft = (RegionLeft - WindowLeft) * xSize;
02171
int DefaultRight = (RegionRight - WindowLeft) * xSize;
02172
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
02173 PWCHAR TransPolyTextOut =
NULL ;
02174
#ifdef WWSB_FE
02175
KEISEN_INFORMATION KeisenInfo[
MAX_POLY_LINES];
02176
SHORT j;
02177 WORD OldAttr;
02178
#endif
02179
02180
02181
02182
02183
02184 TextRect.top = (Region->Top - ScreenInfo->Window.Top) * ySize;
02185
02186 BoundingRect.top = TextRect.top;
02187 BoundingRect.left =
VERY_BIG_NUMBER;
02188 BoundingRect.right = 0;
02189
02190
02191
02192
02193
02194 Row = &ScreenInfo->BufferInfo.TextInfo.Rows
02195 [ScreenInfo->BufferInfo.TextInfo.FirstRow+Region->Top];
02196 LastRow = &ScreenInfo->BufferInfo.TextInfo.Rows[ScreenInfo->ScreenBufferSize.Y];
02197
if (Row >= LastRow)
02198 Row -= ScreenInfo->ScreenBufferSize.Y;
02199
02200 Attr = Row->
AttrRow.
AttrPair.
Attr;
02201
if (Console->
LastAttributes != Attr) {
02202
#ifdef WWSB_FE
02203
if (Attr & COMMON_LVB_REVERSE_VIDEO)
02204 {
02205 SetBkColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr)));
02206 SetTextColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr >> 4)));
02207 }
02208
else{
02209
#endif
02210
SetTextColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr)));
02211 SetBkColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr >> 4)));
02212
#ifdef WWSB_FE
02213
}
02214
#endif
02215
Console->
LastAttributes = Attr;
02216 }
02217
02218
02219
02220
02221
02222
02223
02224 TransPolyTextOut = (PWCHAR)LocalAlloc(LPTR, ScreenInfo->ScreenBufferSize.X*
MAX_POLY_LINES*
sizeof(WCHAR));
02225
if (TransPolyTextOut ==
NULL)
02226 {
02227 KdPrint((
"CONSRV: ConsoleTextOut cannot allocate memory\n"));
02228
return ;
02229 }
02230
02231
for (i=Region->Top;i<=Region->Bottom;) {
02232 PWCHAR TmpChar;
02233 TmpChar = TransPolyTextOut;
02234
for(k=0;i<=Region->Bottom&&k<
MAX_POLY_LINES;i++) {
02235
SHORT NumberOfChars;
02236
SHORT LeftChar,RightChar;
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250 TextRect.left = DefaultLeft;
02251 TextRect.right = DefaultRight;
02252
02253
if (Flags &
TEXT_VALID_HINT)
02254 {
02255
02256
02257
02258
02259
if (Row->
CharRow.
OldLeft !=
INVALID_OLD_LENGTH)
02260 {
02261
02262
02263
02264 TextRect.left = (
02265
max
02266 (
02267
min
02268 (
02269 Row->
CharRow.
Left,
02270 Row->
CharRow.
OldLeft
02271 ),
02272 RegionLeft
02273 )
02274 -WindowLeft
02275 ) * xSize;
02276 }
02277
02278
if (Row->
CharRow.
OldRight !=
INVALID_OLD_LENGTH)
02279 {
02280
02281
02282
02283 TextRect.right = (
02284
min
02285 (
02286
max
02287 (
02288 Row->
CharRow.
Right,
02289 Row->
CharRow.
OldRight
02290 ),
02291 RegionRight
02292 )
02293 -WindowLeft
02294 ) * xSize;
02295 }
02296 }
02297
02298
02299
02300
02301
02302
02303 LeftChar =
max(Row->
CharRow.
Left,RegionLeft);
02304 RightChar =
min(Row->
CharRow.
Right,RegionRight);
02305 NumberOfChars = RightChar - LeftChar;
02306
#ifdef WWSB_FE
02307
if (Row->
CharRow.KAttrs[RightChar-1] & ATTR_LEADING_BYTE){
02308
if(TextRect.right <= ScreenInfo->Window.Right*xSize) {
02309 TextRect.right += xSize;
02310 }
02311 }
02312
#endif
02313
02314
02315
02316
02317
02318
02319
02320
if (NumberOfChars < 0) {
02321 NumberOfChars = 0;
02322 LeftChar = 0;
02323 RightChar = 0;
02324 }
02325
02326
02327
02328
02329
02330
02331
if (TextRect.right > TextRect.left)
02332 {
02333 NumberOfChars = (
SHORT)
RemoveDbcsMarkAll(ScreenInfo,Row,&LeftChar,&TextRect,
NULL,TmpChar,NumberOfChars);
02334 TextInfo[k].x = (LeftChar-WindowLeft) * xSize;
02335 TextInfo[k].y = TextRect.top;
02336 TextRect.bottom = TextRect.top + ySize;
02337 TextInfo[k].n = NumberOfChars;
02338 TextInfo[k].lpstr = TmpChar;
02339
#ifdef WWSB_FE
02340
if (CheckBisectStringW(ScreenInfo,
02341 Console->
OutputCP,
02342 TmpChar,
02343 NumberOfChars,
02344 (TextRect.right-
max(TextRect.left,TextInfo[k].x))/xSize
02345 )
02346 ) {
02347 TextRect.right += xSize;
02348 }
02349
#endif
02350
TmpChar += NumberOfChars;
02351 TextInfo[k].rcl = TextRect;
02352 TextInfo[k].pdx =
NULL;
02353 TextInfo[k].uiFlags = ETO_OPAQUE;
02354
#ifdef WWSB_FE
02355
KeisenInfo[k].n = DefaultRight-DefaultLeft ;
02356 KeisenInfo[k].Coord.Y = (WORD)TextRect.top;
02357 KeisenInfo[k].Coord.X = (WORD)DefaultLeft;
02358
#endif
02359
k++;
02360
02361
if (BoundingRect.left > TextRect.left) {
02362 BoundingRect.left = TextRect.left;
02363 }
02364
if (BoundingRect.right < TextRect.right) {
02365 BoundingRect.right = TextRect.right;
02366 }
02367 }
02368
02369
02370
02371 TextRect.top += ySize;
02372
02373
02374
02375
if (++Row >= LastRow)
02376 Row = ScreenInfo->BufferInfo.TextInfo.Rows;
02377
02378
02379
02380
#ifdef WWSB_FE
02381
OldAttr = Attr ;
02382
#endif
02383
if (Attr != Row->
AttrRow.
AttrPair.
Attr) {
02384 Attr = Row->
AttrRow.
AttrPair.
Attr;
02385 i++;
02386
break;
02387 }
02388 }
02389
02390
if (k)
02391 {
02392 BoundingRect.bottom = TextRect.top;
02393
ASSERT(BoundingRect.left !=
VERY_BIG_NUMBER);
02394
ASSERT(BoundingRect.left <= BoundingRect.right);
02395
ASSERT(BoundingRect.top <= BoundingRect.bottom);
02396 GdiConsoleTextOut(Console->
hDC,
02397 TextInfo,
02398 k,
02399 &BoundingRect);
02400
#ifdef WWSB_FE
02401
for ( j = 0 ; j < k ; j++){
02402 RECT TextRect;
02403
02404 TextRect.left = KeisenInfo[j].Coord.X;
02405 TextRect.top = KeisenInfo[j].Coord.Y;
02406 TextRect.right = KeisenInfo[j].n + TextRect.left;
02407 TextRect.bottom = KeisenInfo[j].Coord.Y + ySize;
02408
TextOutCommonLVB(ScreenInfo->Console, OldAttr, TextRect);
02409 }
02410
#endif
02411
}
02412
if (Console->
LastAttributes != Attr) {
02413
#ifdef WWSB_FE
02414
if (Attr & COMMON_LVB_REVERSE_VIDEO)
02415 {
02416 SetBkColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr)));
02417 SetTextColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr >> 4)));
02418 }
02419
else{
02420
#endif
02421
SetTextColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr)));
02422 SetBkColor(Console->
hDC,
ConvertAttrToRGB(Console,
LOBYTE(Attr >> 4)));
02423
#ifdef WWSB_FE
02424
}
02425
#endif
02426
Console->
LastAttributes = Attr;
02427 BoundingRect.top = TextRect.top;
02428 BoundingRect.left =
VERY_BIG_NUMBER;
02429 BoundingRect.right = 0;
02430 }
02431 }
02432 GdiFlush();
02433
02434
02435
02436 LocalFree(TransPolyTextOut);
02437 }