test: _output.h File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# _output.h File Reference

`#include "dispatch.h"`

Go to the source code of this file.

## Defines

#define | WWSB_NEUTRAL_FILE 1
#define | CHAR_OF_PCI(p) (((PCHAR_INFO)(p))->Char.AsciiChar)
#define | WCHAR_OF_PCI(p) (((PCHAR_INFO)(p))->Char.UnicodeChar)
#define | ATTR_OF_PCI(p) (((PCHAR_INFO)(p))->Attributes)
#define | SIZEOF_CI_CELL sizeof(CHAR_INFO)
#define | CHAR_OF_VGA(p) (p[0])
#define | ATTR_OF_VGA(p) (p[1])
#define | SIZEOF_VGA_CELL 4
#define | COMMON_LVB_MASK 0x33
#define | ATTR_OF_COMMON_LVB(p) (ATTR_OF_VGA(p) + (((p[2] & ~COMMON_LVB_MASK)) << 8))
#define | SIZEOF_COMMON_LVB_CELL 4
#define | MAX_POLY_LINES 80
#define | VERY_BIG_NUMBER 0x0FFFFFFF

## Functions

VOID | FE_StreamWriteToScreenBuffer (IN PWCHAR String, IN SHORT StringLength, IN PSCREEN_INFORMATION ScreenInfo, IN PCHAR StringA)
VOID | WWSB_WriteRectToScreenBuffer (PBYTE Source, COORD SourceSize, PSMALL_RECT SourceRect, PSCREEN_INFORMATION ScreenInfo, COORD TargetPoint, IN UINT Codepage)
VOID | WWSB_WriteRegionToScreen (IN PSCREEN_INFORMATION ScreenInfo, IN PSMALL_RECT Region)
VOID | WWSB_WriteToScreen (IN PSCREEN_INFORMATION ScreenInfo, IN PSMALL_RECT Region)
NTSTATUS | WWSB_WriteOutputString (IN PSCREEN_INFORMATION ScreenInfo, IN PVOID Buffer, IN COORD WriteCoord, IN ULONG StringType, IN OUT PULONG NumRecords, OUT PULONG NumColumns OPTIONAL)
NTSTATUS | WWSB_FillOutput (IN PSCREEN_INFORMATION ScreenInfo, IN WORD Element, IN COORD WriteCoord, IN ULONG ElementType, IN OUT PULONG Length)
VOID | WWSB_FillRectangle (IN CHAR_INFO Fill, IN OUT PSCREEN_INFORMATION ScreenInfo, IN PSMALL_RECT TargetRect)
BOOL | WWSB_PolyTextOutCandidate (IN PSCREEN_INFORMATION ScreenInfo, IN PSMALL_RECT Region)
VOID | WWSB_ConsolePolyTextOut (IN PSCREEN_INFORMATION ScreenInfo, IN PSMALL_RECT Region)

## Define Documentation

#define ATTR_OF_COMMON_LVB | ( | p |  | ) | (ATTR_OF_VGA(p) + (((p[2] & ~COMMON_LVB_MASK)) << 8))

| Definition at line 183 of file _output.h. Referenced by WWSB_WriteRectToScreenBuffer().

#define ATTR_OF_PCI | ( | p |  | ) | (((PCHAR_INFO)(p))->Attributes)

| Definition at line 170 of file _output.h. Referenced by WWSB_WriteRectToScreenBuffer().

#define ATTR_OF_VGA | ( | p |  | ) | (p[1])

| Definition at line 174 of file _output.h. Referenced by WWSB_WriteRectToScreenBuffer().

#define CHAR_OF_PCI | ( | p |  | ) | (((PCHAR_INFO)(p))->Char.AsciiChar)

| Definition at line 168 of file _output.h.

#define CHAR_OF_VGA | ( | p |  | ) | (p[0])

| Definition at line 173 of file _output.h. Referenced by WWSB_WriteRectToScreenBuffer().

#define COMMON_LVB_MASK 0x33

| Definition at line 182 of file _output.h.

#define MAX_POLY_LINES 80

| Definition at line 2134 of file _output.h. Referenced by WWSB_ConsolePolyTextOut().

#define SIZEOF_CI_CELL sizeof(CHAR_INFO)

| Definition at line 171 of file _output.h. Referenced by WWSB_WriteRectToScreenBuffer().

#define SIZEOF_COMMON_LVB_CELL 4

| Definition at line 184 of file _output.h. Referenced by WWSB_WriteRectToScreenBuffer().

#define SIZEOF_VGA_CELL 4

| Definition at line 178 of file _output.h. Referenced by WWSB_WriteRectToScreenBuffer().

#define VERY_BIG_NUMBER 0x0FFFFFFF

| Definition at line 2135 of file _output.h. Referenced by WWSB_ConsolePolyTextOut().

#define WCHAR_OF_PCI | ( | p |  | ) | (((PCHAR_INFO)(p))->Char.UnicodeChar)

| Definition at line 169 of file _output.h. Referenced by WWSB_WriteRectToScreenBuffer().

#define WWSB_NEUTRAL_FILE 1

| Definition at line 23 of file _output.h.

## Function Documentation

VOID FE_StreamWriteToScreenBuffer | ( | IN PWCHAR | String,
|  | IN SHORT | StringLength,
|  | IN PSCREEN_INFORMATION | ScreenInfo,
|  | IN PCHAR | StringA
| ) |

Definition at line 61 of file _output.h.

References ASSERT, _ATTR_PAIR::Attr, ATTR_PAIR, _ATTR_ROW::AttrPair, _ROW::AttrRow, _ATTR_ROW::Attrs, BisectWrite(), CHAR, _ROW::CharRow, _CHAR_ROW::Chars, CONSOLE_TEXTMODE_BUFFER, ConsoleHeapFree, DBGOUTPUT, INVALID_OLD_LENGTH, _CHAR_ROW::Left, _ATTR_ROW::Length, _ATTR_PAIR::Length, MergeAttrStrings(), NT_SUCCESS, _CHAR_ROW::OldLeft, _CHAR_ROW::OldRight, PROW, ResetTextFlags(), _CHAR_ROW::Right, SHORT, String, StringLength(), TEXT_VALID_HINT, and UNICODE_SPACE.

Referenced by WWSB_DoWriteConsole(), and WWSB_WriteChars().

    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     // copy chars
    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     // recalculate first and last non-space char
    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     // see if attr string is different.  if so, allocate a new
    00129     // attr buffer and merge the two strings.
    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 }

VOID WWSB_ConsolePolyTextOut | ( | IN PSCREEN_INFORMATION | ScreenInfo,
|  | IN PSMALL_RECT | Region
| ) |

Definition at line 2145 of file _output.h.

References ASSERT, _ATTR_PAIR::Attr, _ATTR_ROW::AttrPair, _ROW::AttrRow, _ROW::CharRow, ConvertAttrToRGB, _CONSOLE_INFORMATION::hDC, INVALID_OLD_LENGTH, _CONSOLE_INFORMATION::LastAttributes, _CHAR_ROW::Left, LOBYTE, max, MAX_POLY_LINES, min, NULL, _CHAR_ROW::OldLeft, _CHAR_ROW::OldRight, _CONSOLE_INFORMATION::OutputCP, RemoveDbcsMarkAll(), _CHAR_ROW::Right, SCR_FONTSIZE(), SHORT, TEXT_VALID_HINT, TextOutCommonLVB(), and VERY_BIG_NUMBER.

Referenced by WWSB_WriteRegionToScreen().

    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     // initialize the text rect and window position.
    02182     //
    02183
    02184     TextRect.top = (Region->Top - ScreenInfo->Window.Top) * ySize;
    02185     // TextRect.bottom is invalid.
    02186     BoundingRect.top = TextRect.top;
    02187     BoundingRect.left = VERY_BIG_NUMBER;
    02188     BoundingRect.right = 0;
    02189
    02190     //
    02191     // copy the chars and attrs from their respective arrays
    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      * Temporarly use the process heap to isolate the heap trash problem
    02220      * TransPolyTextOut = (PWCHAR)ConsoleHeapAlloc(
    02221      *                                    MAKE_TAG( TMP_DBCS_TAG ),
    02222      *                                    ScreenInfo->ScreenBufferSize.X*MAX_POLY_LINES*sizeof(WCHAR));
    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             // make the bounding rect smaller, if we can.  the TEXT_VALID_HINT
    02240             // flag gets set each time we write to the screen buffer.  it gets
    02241             // turned off any time we get asked to redraw the screen
    02242             // and we don't know exactly what needs to be redrawn
    02243             // (i.e. paint messages).
    02244             //
    02245             // we have the left and right bounds of the text on the
    02246             // line.  the opaqueing rectangle and the number of
    02247             // chars get set according to those values.
    02248             //
    02249
    02250             TextRect.left  = DefaultLeft;
    02251             TextRect.right = DefaultRight;
    02252
    02253             if (Flags & TEXT_VALID_HINT)
    02254             {
    02255             // We compute an opaquing interval.  If A is the old interval of text,
    02256             // B is the new interval, and R is the Region, then the opaquing interval
    02257             // must be R*(A+B), where * represents intersection and + represents union.
    02258
    02259                 if (Row->CharRow.OldLeft != INVALID_OLD_LENGTH)
    02260                 {
    02261                 // The min determines the left of (A+B).  The max intersects that with
    02262                 // the left of the region.
    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                 // The max determines the right of (A+B).  The min intersects that with
    02281                 // the right of the region.
    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             // We've got to draw any new text that appears in the region, so we just
    02300             // intersect the new text interval with the region.
    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             // Empty rows are represented by CharRow.Right=0, CharRow.Left=MAX, so we
    02316             // may have NumberOfChars<0 at this point if there is no text that needs
    02317             // drawing.  (I.e. the intersection was empty.)
    02318             //
    02319
    02320             if (NumberOfChars < 0) {
    02321                 NumberOfChars = 0;
    02322                 LeftChar = 0;
    02323                 RightChar = 0;
    02324             }
    02325
    02326             //
    02327             // We may also have TextRect.right<TextRect.left if the screen
    02328             // is already cleared, and we really don't need to do anything at all.
    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             // Advance the high res bounds.
    02370
    02371             TextRect.top += ySize;
    02372
    02373             // Advance the row pointer.
    02374
    02375             if (++Row >= LastRow)
    02376                 Row = ScreenInfo->BufferInfo.TextInfo.Rows;
    02377
    02378             // Draw now if the attributes are about to change.
    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      * ConsoleHeapFree(TransPolyTextOut);
    02435      */
    02436     LocalFree(TransPolyTextOut);
    02437 }

NTSTATUS WWSB_FillOutput | ( | IN PSCREEN_INFORMATION | ScreenInfo,
|  | IN WORD | Element,
|  | IN COORD | WriteCoord,
|  | IN ULONG | ElementType,
|  | IN OUT PULONG | Length
| ) |

Definition at line 1530 of file _output.h.

References ASSERT, _ATTR_PAIR::Attr, _ATTR_ROW::AttrPair, _ROW::AttrRow, _ATTR_ROW::Attrs, BisectWrite(), BisectWriteAttr(), BYTE, CHAR, _ROW::CharRow, _CHAR_ROW::Chars, CONSOLE_ASCII, CONSOLE_ATTRIBUTE, CONSOLE_FALSE_UNICODE, CONSOLE_OEMFONT_DISPLAY, CONSOLE_REAL_UNICODE, CONSOLE_TEXTMODE_BUFFER, ConsoleHeapFree, ConvertOutputToUnicode(), DBGOUTPUT, DWORD, INVALID_OLD_LENGTH, IsDBCSLeadByteConsole(), _CHAR_ROW::Left, _ATTR_ROW::Length, _ATTR_PAIR::Length, MergeAttrStrings(), NT_SUCCESS, _CHAR_ROW::OldLeft, _CHAR_ROW::OldRight, RealUnicodeToFalseUnicode(), ResetTextFlags(), _CHAR_ROW::Right, SHORT, TEXT_VALID_HINT, TRUE, UINT, UNICODE_SPACE, USACP, WINDOWSCP, and WWSB_WriteToScreen().

Referenced by WWSB_WriteChars().

    01540                    :
    01541
    01542     This routine fills the screen buffer with the specified character or
    01543     attribute.
    01544
    01545 Arguments:
    01546
    01547     ScreenInfo - Pointer to screen buffer information.
    01548
    01549     Element - Element to write.
    01550
    01551     WriteCoord - Screen buffer coordinate to begin writing to.
    01552
    01553     ElementType
    01554
    01555         CONSOLE_ASCII         - element is an ascii character.
    01556         CONSOLE_REAL_UNICODE  - element is a real unicode character. These will
    01557                                 get converted to False Unicode as required.
    01558         CONSOLE_FALSE_UNICODE - element is a False Unicode character.
    01559         CONSOLE_ATTRIBUTE     - element is an attribute.
    01560
    01561     Length - On input, the number of elements to write.  On output,
    01562     the number of elements written.
    01563
    01564 Return Value:
    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             // copy the chars into their arrays
    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             // recalculate first and last non-space char
    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             // copy the attrs into the screen buffer arrays
    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             // recalculate last non-space char
    01810
    01811             //
    01812             //  merge the two attribute strings.
    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     // determine write region.  if we're still on the same line we started
    01873     // on, left X is the X we started with and right X is the one we're on
    01874     // now.  otherwise, left X is 0 and right X is the rightmost column of
    01875     // the screen buffer.
    01876     //
    01877     // then update the screen.
    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 }

VOID WWSB_FillRectangle | ( | IN CHAR_INFO | Fill,
|  | IN OUT PSCREEN_INFORMATION | ScreenInfo,
|  | IN PSMALL_RECT | TargetRect
| ) |

Definition at line 1918 of file _output.h.

References ASSERT, _ATTR_PAIR::Attr, _ATTR_ROW::AttrPair, _ROW::AttrRow, _ATTR_ROW::Attrs, BisectWrite(), BOOL, _ROW::CharRow, _CHAR_ROW::Chars, CONSOLE_TEXTMODE_BUFFER, ConsoleHeapFree, DBGOUTPUT, INVALID_OLD_LENGTH, _CHAR_ROW::Left, _ATTR_ROW::Length, _ATTR_PAIR::Length, MergeAttrStrings(), NT_SUCCESS, _CHAR_ROW::OldLeft, _CHAR_ROW::OldRight, ResetTextFlags(), _CHAR_ROW::Right, SHORT, TEXT_VALID_HINT, and UNICODE_SPACE.

    01926                    :
    01927
    01928     This routine fills a rectangular region in the screen
    01929     buffer.  no clipping is done.
    01930
    01931 Arguments:
    01932
    01933     Fill - element to copy to each element in target rect
    01934
    01935     ScreenInfo - pointer to screen info
    01936
    01937     TargetRect - rectangle in screen buffer to fill
    01938
    01939 Return Value:
    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         // copy the chars and attrs into their respective arrays
    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         // recalculate first and last non-space char
    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         //  merge the two attribute strings.
    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 }

BOOL WWSB_PolyTextOutCandidate | ( | IN PSCREEN_INFORMATION | ScreenInfo,
|  | IN PSMALL_RECT | Region
| ) |

Definition at line 2077 of file _output.h.

References ASSERT, _ROW::AttrRow, CONSOLE_OEMFONT_DISPLAY, CONSOLE_TEXTMODE_BUFFER, CONSOLE_VDM_REGISTERED, FALSE, _ATTR_ROW::Length, SHORT, SINGLE_ATTRIBUTES_PER_LINE, and TRUE.

Referenced by WWSB_WriteRegionToScreen().

    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     // make sure there is only one attr per line.
    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 }

NTSTATUS WWSB_WriteOutputString | ( | IN PSCREEN_INFORMATION | ScreenInfo,
|  | IN PVOID | Buffer,
|  | IN COORD | WriteCoord,
|  | IN ULONG | StringType,
|  | IN OUT PULONG | NumRecords,
|  | OUT PULONG NumColumns | OPTIONAL
| ) |

Definition at line 1002 of file _output.h.

References ASSERT, _ATTR_PAIR::Attr, _ATTR_ROW::AttrPair, _ROW::AttrRow, _ATTR_ROW::Attrs, BisectWrite(), BisectWriteAttr(), BOOL, Buffer, c, CHAR, _ROW::CharRow, _CHAR_ROW::Chars, CONSOLE_ASCII, CONSOLE_ATTRIBUTE, CONSOLE_FALSE_UNICODE, CONSOLE_OEMFONT_DISPLAY, CONSOLE_REAL_UNICODE, CONSOLE_TEXTMODE_BUFFER, ConsoleHeapAlloc, ConsoleHeapFree, ConvertOutputToUnicode(), DBGOUTPUT, FALSE, INVALID_OLD_LENGTH, IsDBCSLeadByteConsole(), _CHAR_ROW::Left, _ATTR_ROW::Length, _ATTR_PAIR::Length, MAKE_TAG, MergeAttrStrings(), NT_SUCCESS, NULL, _CHAR_ROW::OldLeft, _CHAR_ROW::OldRight, PBYTE, RealUnicodeToFalseUnicode(), ResetTextFlags(), _CHAR_ROW::Right, SHORT, TEXT_VALID_HINT, TMP_TAG, TRUE, UINT, UNICODE_SPACE, USACP, WINDOWSCP, and WWSB_WriteToScreen().

Referenced by WWSB_WriteChars().

    01013                    :
    01014
    01015     This routine writes a string of characters or attributes to the
    01016     screen buffer.
    01017
    01018 Arguments:
    01019
    01020     ScreenInfo - Pointer to screen buffer information.
    01021
    01022     Buffer - Buffer to write from.
    01023
    01024     WriteCoord - Screen buffer coordinate to begin writing to.
    01025
    01026     StringType
    01027       One of the following:
    01028         CONSOLE_ASCII          - write a string of ascii characters.
    01029         CONSOLE_REAL_UNICODE   - write a string of real unicode characters.
    01030         CONSOLE_FALSE_UNICODE  - write a string of false unicode characters.
    01031         CONSOLE_ATTRIBUTE      - write a string of attributes.
    01032
    01033     NumRecords - On input, the number of elements to write.  On output,
    01034     the number of elements written.
    01035
    01036     NumColumns - receives the number of columns output, which could be more
    01037                  than NumRecords (FE fullwidth chars)
    01038 Return Value:
    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;      // MSKK Apr.02.1993 V-HirotS For KAttr
    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;               // MSKK APr.02.1993 V-HirotS For KAttr
    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         /* Avoid overflow into TransBufferCharacter , TransBufferAttribute
    01195          * because, if hit by IsConsoleFullWidth()
    01196          * then one unicde character needs two spaces on TransBuffer.
    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             // copy the chars into their arrays
    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                  * The text will not hit the right hand edge, copy it all
    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                  * The text will hit the right hand edge, copy only that much
    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             // recalculate first and last non-space char
    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                  * The string hit the right hand edge, so wrap around to the
    01339                  * next line by going back round the while loop, unless we
    01340                  * are at the end of the buffer - in which case we simply
    01341                  * abandon the remainder of the output string!
    01342                  */
    01343                 X = 0;
    01344                 Y++;
    01345                 if (Y >= ScreenInfo->ScreenBufferSize.Y) {
    01346                     break; // abandon output, string is truncated
    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             // copy the attrs into the screen buffer arrays
    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             // recalculate last non-space char
    01421
    01422             //
    01423             // see if attr string is different.  if so, allocate a new
    01424             // attr buffer and merge the two strings.
    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     // determine write region.  if we're still on the same line we started
    01504     // on, left X is the X we started with and right X is the one we're on
    01505     // now.  otherwise, left X is 0 and right X is the rightmost column of
    01506     // the screen buffer.
    01507     //
    01508     // then update the screen.
    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 }

VOID WWSB_WriteRectToScreenBuffer | ( | PBYTE | Source,
|  | COORD | SourceSize,
|  | PSMALL_RECT | SourceRect,
|  | PSCREEN_INFORMATION | ScreenInfo,
|  | COORD | TargetPoint,
|  | IN UINT | Codepage
| ) |

Definition at line 187 of file _output.h.

References ASSERT, _ATTR_PAIR::Attr, ATTR_OF_COMMON_LVB, ATTR_OF_PCI, ATTR_OF_VGA, _ATTR_ROW::AttrPair, _ROW::AttrRow, _ATTR_ROW::Attrs, BisectWrite(), BOOL, _SCREEN_INFORMATION::BufferInfo, CHAR, CHAR_OF_VGA, _ROW::CharRow, _CHAR_ROW::Chars, _SCREEN_INFORMATION::Console, CONSOLE_TEXTMODE_BUFFER, ConsoleHeapAlloc, ConsoleHeapFree, ConvertOutputToUnicode(), DBGOUTPUT, FALSE, _SCREEN_INFORMATION::Flags, INVALID_OLD_LENGTH, IsDBCSLeadByteConsole(), _CHAR_ROW::Left, _ATTR_ROW::Length, _ATTR_PAIR::Length, MAKE_TAG, MergeAttrStrings(), NT_SUCCESS, NULL, _CHAR_ROW::OldLeft, _CHAR_ROW::OldRight, PBYTE, ResetTextFlags(), _CHAR_ROW::Right, SCREEN_BUFFER_POINTER, _SCREEN_INFORMATION::ScreenBufferSize, SHORT, SIZEOF_CI_CELL, SIZEOF_COMMON_LVB_CELL, SIZEOF_VGA_CELL, TEXT_VALID_HINT, TMP_TAG, TRUE, UNICODE_SPACE, and WCHAR_OF_PCI.

    00198                    :
    00199
    00200     This routine copies a rectangular region to the screen buffer.
    00201     no clipping is done.
    00202
    00203     The source should contain Unicode or UnicodeOem chars.
    00204
    00205 Arguments:
    00206
    00207     Source - pointer to source buffer (a real VGA buffer or CHAR_INFO[])
    00208
    00209     SourceSize - dimensions of source buffer
    00210
    00211     SourceRect - rectangle in source buffer to copy
    00212
    00213     ScreenInfo - pointer to screen info
    00214
    00215     TargetPoint - upper left coordinates of target rectangle
    00216
    00217     Codepage - codepage to translate real VGA buffer from,
    00218                0xFFFFFFF if Source is CHAR_INFO[] (not requiring translation)
    00219 Return Value:
    00220
    00221     none.
    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         // copy the chars and attrs into their respective arrays
    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          * Two version of the following loop to keep it fast:
    00330          * one for VGA buffers, one for CHAR_INFO buffers.
    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                 // MSKK Apr.02.1993 V-HirotS For KAttr
    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                     // MSKK Apr.02.1993 V-HirotS For KAttr
    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         // recalculate first and last non-space char
    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             // if the attributes change after the last non-space, make the
    00494             // index of the last attribute change + 1 the length.  otherwise
    00495             // make the length one more than the last non-space.
    00496             //
    00497
    00498             Row->CharRow.Right = (SHORT)(LastNonSpace+1);
    00499         }
    00500
    00501         //
    00502         // see if attr string is different.  if so, allocate a new
    00503         // attr buffer and merge the two strings.
    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 }

VOID WWSB_WriteRegionToScreen | ( | IN PSCREEN_INFORMATION | ScreenInfo,
|  | IN PSMALL_RECT | Region
| ) |

Definition at line 552 of file _output.h.

References ASSERT, _ATTR_PAIR::Attr, _ROW::AttrRow, _ATTR_ROW::Attrs, BOOL, _ROW::CharRow, _CHAR_ROW::Chars, CheckEudcRangeInString(), CONSOLE_OEMFONT_DISPLAY, CONSOLE_TEXTMODE_BUFFER, CONSOLE_VDM_REGISTERED, ConsoleHeapAlloc, ConsoleHeapFree, ConvertAttrToRGB, _CONSOLE_INFORMATION::CurrentScreenBuffer, DBGOUTPUT, FALSE, FindAttrIndex(), _CONSOLE_INFORMATION::FullScreenFlags, _CONSOLE_INFORMATION::hDC, INVALID_OLD_LENGTH, InvertSelection(), _CONSOLE_INFORMATION::LastAttributes, _CHAR_ROW::Left, _ATTR_PAIR::Length, _ATTR_ROW::Length, LOBYTE, MAKE_TAG, max, min, NULL, _CHAR_ROW::OldLeft, _CHAR_ROW::OldRight, PCONSOLE_INFORMATION, PEUDC_INFORMATION, RemoveDbcsMarkAll(), _CHAR_ROW::Right, SCR_FONTSIZE(), SHORT, TEXT_VALID_HINT, TEXTCOLOR_CALL, TEXTOUT_CALL, TextOutEverything(), TRUE, UNICODE_SPACE, _SCREEN_INFORMATION::Window, WWSB_ConsolePolyTextOut(), WWSB_FE, and WWSB_PolyTextOutCandidate().

Referenced by WWSB_DoWriteConsole(), and WWSB_WriteToScreen().

    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;  // one line && one attribute per line
    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         // if we have a selection, turn it off.
    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                 // copy the chars and attrs from their respective arrays
    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                     // make the bounding rect smaller, if we can.  the TEXT_VALID_HINT
    00731                     // flag gets set each time we write to the screen buffer.  it gets
    00732                     // turned off any time we get asked to redraw the screen
    00733                     // and we don't know exactly what needs to be redrawn
    00734                     // (i.e. paint messages).
    00735                     //
    00736                     // we have the left and right bounds of the text on the
    00737                     // line.  the opaqueing rectangle and the number of
    00738                     // chars get set according to those values.
    00739                     //
    00740                     // if there's more than one attr per line (!SimpleWrite)
    00741                     // we bail on the opaqueing rect.
    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                      * Text out everything (i.e. SBCS/DBCS, Common LVB attribute, Local EUDC)
    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         // if we have a selection, turn it on.
    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 }

VOID WWSB_WriteToScreen | ( | IN PSCREEN_INFORMATION | ScreenInfo,
|  | IN PSMALL_RECT | Region
| ) |

Definition at line 918 of file _output.h.

References ACTIVE_SCREEN_BUFFER, CONSOLE_GRAPHICS_BUFFER, CONSOLE_IS_ICONIC, CONSOLE_NO_WINDOW, ConsoleHideCursor(), ConsoleShowCursor(), DBGOUTPUT, max, min, WriteRegionToScreenBitMap(), and WWSB_WriteRegionToScreen().

Referenced by WWSB_FillOutput(), WWSB_WriteChars(), and WWSB_WriteOutputString().

    00924                    :
    00925
    00926     This routine writes a screen buffer region to the screen.
    00927
    00928 Arguments:
    00929
    00930     ScreenInfo - Pointer to screen buffer information.
    00931
    00932     Region - Region to write in screen buffer coordinates.  Region is
    00933     inclusive
    00934
    00935 Return Value:
    00936
    00937     none.
    00938
    00939 --*/
    00940
    00941 {
    00942     SMALL_RECT ClippedRegion;
    00943
    00944     DBGOUTPUT(("WriteToScreen\n"));
    00945     //
    00946     // update to screen, if we're not iconic.  we're marked as
    00947     // iconic if we're fullscreen, so check for fullscreen.
    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     // clip region
    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 }