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  )     (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  )     (((PCHAR_INFO)(p))->Attributes)
 

Definition at line 170 of file _output.h.

Referenced by WWSB_WriteRectToScreenBuffer().

#define ATTR_OF_VGA  )     (p[1])
 

Definition at line 174 of file _output.h.

Referenced by WWSB_WriteRectToScreenBuffer().

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

Definition at line 168 of file _output.h.

#define CHAR_OF_VGA  )     (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  )     (((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 }


Generated on Sat May 15 19:42:48 2004 for test by doxygen 1.3.7