00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "precomp.h"
00022
#pragma hdrstop
00023
00024
00025
#ifdef PROFILE_GDI
00026
LONG InvertCount;
00027
#define INVERT_CALL InvertCount++
00028
#else
00029 #define INVERT_CALL
00030
#endif
00031
00032
VOID
00033 InvertPixels(
00034 IN
PSCREEN_INFORMATION ScreenInfo
00035 )
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 {
00055
#ifdef FE_SB
00056
if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console)) {
00057 PCONVERSIONAREA_INFORMATION ConvAreaInfo;
00058 SMALL_RECT Region;
00059 SMALL_RECT CursorRegion;
00060 SMALL_RECT ClippedRegion;
00061
00062
#ifdef DBG_KATTR
00063
00064
#endif
00065
00066 ConvAreaInfo = ScreenInfo->Console->ConsoleIme.ConvAreaRoot;
00067 CursorRegion.Left = CursorRegion.Right = ScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
00068 CursorRegion.Top = CursorRegion.Bottom = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
00069
while (ConvAreaInfo) {
00070
00071
if ((ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN+CA_HIDE_FOR_SCROLL))==0) {
00072
00073
00074
00075 Region.Left = ScreenInfo->Window.Left +
00076 ConvAreaInfo->CaInfo.rcViewCaWindow.Left +
00077 ConvAreaInfo->CaInfo.coordConView.X;
00078 Region.Right = Region.Left +
00079 (ConvAreaInfo->CaInfo.rcViewCaWindow.Right -
00080 ConvAreaInfo->CaInfo.rcViewCaWindow.Left);
00081 Region.Top = ScreenInfo->Window.Top +
00082 ConvAreaInfo->CaInfo.rcViewCaWindow.Top +
00083 ConvAreaInfo->CaInfo.coordConView.Y;
00084 Region.Bottom = Region.Top +
00085 (ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom -
00086 ConvAreaInfo->CaInfo.rcViewCaWindow.Top);
00087 ClippedRegion.Left =
max(Region.Left, ScreenInfo->Window.Left);
00088 ClippedRegion.Top =
max(Region.Top, ScreenInfo->Window.Top);
00089 ClippedRegion.Right =
min(Region.Right, ScreenInfo->Window.Right);
00090 ClippedRegion.Bottom =
min(Region.Bottom, ScreenInfo->Window.Bottom);
00091
if (ClippedRegion.Right < ClippedRegion.Left ||
00092 ClippedRegion.Bottom < ClippedRegion.Top) {
00093 ;
00094 }
00095
else {
00096 Region = ClippedRegion;
00097 ClippedRegion.Left =
max(Region.Left, CursorRegion.Left);
00098 ClippedRegion.Top =
max(Region.Top, CursorRegion.Top);
00099 ClippedRegion.Right =
min(Region.Right, CursorRegion.Right);
00100 ClippedRegion.Bottom =
min(Region.Bottom, CursorRegion.Bottom);
00101
if (ClippedRegion.Right < ClippedRegion.Left ||
00102 ClippedRegion.Bottom < ClippedRegion.Top) {
00103 ;
00104 }
00105
else {
00106
return;
00107 }
00108 }
00109 }
00110 ConvAreaInfo = ConvAreaInfo->ConvAreaNext;
00111 }
00112 }
00113
#endif // FE_SB
00114
00115 {
00116 ULONG CursorYSize;
00117 POLYPATBLT PolyData;
00118
#ifdef FE_SB
00119
SHORT RowIndex;
00120
PROW Row;
00121 COORD TargetPoint;
00122
int iTrailing = 0;
00123
int iDBCursor = 1;
00124
#endif
00125
00126
INVERT_CALL;
00127 CursorYSize = ScreenInfo->BufferInfo.TextInfo.CursorYSize;
00128
if (ScreenInfo->BufferInfo.TextInfo.DoubleCursor) {
00129
if (ScreenInfo->BufferInfo.TextInfo.CursorSize > 50)
00130 CursorYSize = CursorYSize >> 1;
00131
else
00132 CursorYSize = CursorYSize << 1;
00133 }
00134
#ifdef FE_SB
00135
if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console))
00136 {
00137 TargetPoint = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
00138 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
00139 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00140
ASSERT(Row);
00141
00142
if ((Row->
CharRow.KAttrs[TargetPoint.X] & ATTR_TRAILING_BYTE) &&
00143 ScreenInfo->BufferInfo.TextInfo.CursorDBEnable) {
00144
00145 iTrailing = 1;
00146 iDBCursor = 2;
00147 }
else if ((Row->
CharRow.KAttrs[TargetPoint.X] & ATTR_LEADING_BYTE) &&
00148 ScreenInfo->BufferInfo.TextInfo.CursorDBEnable) {
00149
00150 iDBCursor = 2;
00151 }
00152 }
00153
00154 PolyData.x = (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X -
00155 ScreenInfo->Window.Left - iTrailing) *
SCR_FONTSIZE(ScreenInfo).X;
00156 PolyData.y = (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y -
00157 ScreenInfo->Window.Top) *
SCR_FONTSIZE(ScreenInfo).Y +
00158 (
CURSOR_Y_OFFSET_IN_PIXELS(
SCR_FONTSIZE(ScreenInfo).Y,CursorYSize));
00159 PolyData.cx =
SCR_FONTSIZE(ScreenInfo).X * iDBCursor;
00160 PolyData.cy = CursorYSize;
00161
#else
00162
PolyData.x = (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X-ScreenInfo->Window.Left)*
SCR_FONTSIZE(ScreenInfo).X;
00163 PolyData.y = (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y-ScreenInfo->Window.Top)*
SCR_FONTSIZE(ScreenInfo).Y+(
CURSOR_Y_OFFSET_IN_PIXELS(
SCR_FONTSIZE(ScreenInfo).Y,CursorYSize));
00164 PolyData.cx =
SCR_FONTSIZE(ScreenInfo).X;
00165 PolyData.cy = CursorYSize;
00166
#endif
00167
PolyData.BrClr.hbr = GetStockObject(LTGRAY_BRUSH);
00168
00169 PolyPatBlt(ScreenInfo->Console->hDC, PATINVERT, &PolyData, 1, PPB_BRUSH);
00170
00171 GdiFlush();
00172 }
00173 }
00174
00175
VOID
00176 ConsoleShowCursor(
00177 IN
PSCREEN_INFORMATION ScreenInfo
00178 )
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 {
00198
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
00199
ASSERT (ScreenInfo->BufferInfo.TextInfo.UpdatingScreen>0);
00200
if (--ScreenInfo->BufferInfo.TextInfo.UpdatingScreen == 0) {
00201 ScreenInfo->BufferInfo.TextInfo.CursorOn =
FALSE;
00202 }
00203 }
00204 }
00205
00206
VOID
00207 ConsoleHideCursor(
00208 IN
PSCREEN_INFORMATION ScreenInfo
00209 )
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 {
00229
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
00230
if (++ScreenInfo->BufferInfo.TextInfo.UpdatingScreen == 1) {
00231
if (ScreenInfo->BufferInfo.TextInfo.CursorVisible &&
00232 ScreenInfo->BufferInfo.TextInfo.CursorOn &&
00233 ScreenInfo->Console->CurrentScreenBuffer == ScreenInfo &&
00234 !(ScreenInfo->Console->Flags &
CONSOLE_IS_ICONIC)) {
00235
InvertPixels(ScreenInfo);
00236 ScreenInfo->BufferInfo.TextInfo.CursorOn =
FALSE;
00237 }
00238 }
00239 }
00240 }
00241
00242
NTSTATUS
00243 SetCursorInformation(
00244 IN
PSCREEN_INFORMATION ScreenInfo,
00245 ULONG Size,
00246 BOOLEAN Visible
00247 )
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 {
00271
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
00272
ConsoleHideCursor(ScreenInfo);
00273 ScreenInfo->BufferInfo.TextInfo.CursorSize =
Size;
00274 ScreenInfo->BufferInfo.TextInfo.CursorVisible = Visible;
00275 ScreenInfo->BufferInfo.TextInfo.CursorYSize = (WORD)
CURSOR_SIZE_IN_PIXELS(
SCR_FONTSIZE(ScreenInfo).Y,ScreenInfo->BufferInfo.TextInfo.CursorSize);
00276
#ifdef i386
00277
if ((!(ScreenInfo->Console->Flags &
CONSOLE_VDM_REGISTERED)) &&
00278 ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
00279 SetCursorInformationHW(ScreenInfo,
Size,Visible);
00280 }
00281
#endif
00282
ConsoleShowCursor(ScreenInfo);
00283 }
00284
return STATUS_SUCCESS;
00285 }
00286
00287
NTSTATUS
00288 SetCursorMode(
00289 IN
PSCREEN_INFORMATION ScreenInfo,
00290 BOOLEAN DoubleCursor
00291 )
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 {
00314
if ((ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) &&
00315 (ScreenInfo->BufferInfo.TextInfo.DoubleCursor != DoubleCursor)) {
00316
ConsoleHideCursor(ScreenInfo);
00317 ScreenInfo->BufferInfo.TextInfo.DoubleCursor = DoubleCursor;
00318
#ifdef i386
00319
if ((!(ScreenInfo->Console->Flags &
CONSOLE_VDM_REGISTERED)) &&
00320 ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
00321 SetCursorInformationHW(ScreenInfo,
00322 ScreenInfo->BufferInfo.TextInfo.CursorSize,
00323 ScreenInfo->BufferInfo.TextInfo.CursorVisible);
00324 }
00325
#endif
00326
ConsoleShowCursor(ScreenInfo);
00327 }
00328
return STATUS_SUCCESS;
00329 }
00330
00331
VOID
00332 CursorTimerRoutine(
00333 IN
PSCREEN_INFORMATION ScreenInfo
00334 )
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 {
00354
if (!(ScreenInfo->Console->Flags &
CONSOLE_HAS_FOCUS))
00355
return;
00356
00357
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
00358
00359
00360
00361
00362
00363
if (ScreenInfo->BufferInfo.TextInfo.CursorMoved) {
00364
00365 CONSOLE_CARET_INFO ConsoleCaretInfo;
00366
00367 ScreenInfo->BufferInfo.TextInfo.CursorMoved =
FALSE;
00368 ConsoleCaretInfo.hwnd = ScreenInfo->Console->hWnd;
00369 ConsoleCaretInfo.rc.left = (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X - ScreenInfo->Window.Left) *
SCR_FONTSIZE(ScreenInfo).X;
00370 ConsoleCaretInfo.rc.top = (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y - ScreenInfo->Window.Top) *
SCR_FONTSIZE(ScreenInfo).Y;
00371 ConsoleCaretInfo.rc.right = ConsoleCaretInfo.rc.left +
SCR_FONTSIZE(ScreenInfo).X;
00372 ConsoleCaretInfo.rc.bottom = ConsoleCaretInfo.rc.top +
SCR_FONTSIZE(ScreenInfo).Y;
00373
NtUserConsoleControl(ConsoleSetCaretInfo,
00374 &ConsoleCaretInfo,
00375
sizeof(ConsoleCaretInfo));
00376 }
00377
00378
00379
00380
00381
00382
if (ScreenInfo->BufferInfo.TextInfo.DelayCursor) {
00383 ScreenInfo->BufferInfo.TextInfo.DelayCursor =
FALSE;
00384
return;
00385 }
00386
00387
00388
if (NtCurrentPeb()->SessionId > 0 &&
00389 ScreenInfo->BufferInfo.TextInfo.CursorOn) {
00390
00391
return;
00392 }
00393
00394
if (ScreenInfo->BufferInfo.TextInfo.CursorVisible &&
00395 !ScreenInfo->BufferInfo.TextInfo.UpdatingScreen) {
00396
InvertPixels(ScreenInfo);
00397 ScreenInfo->BufferInfo.TextInfo.CursorOn = !ScreenInfo->BufferInfo.TextInfo.CursorOn;
00398 }
00399 }
00400 }
00401
00402
#ifdef i386
00403
NTSTATUS
00404 SetCursorPositionHW(
00405 IN OUT
PSCREEN_INFORMATION ScreenInfo,
00406 IN COORD Position
00407 )
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 {
00429
#if defined(FE_SB)
00430
FSVIDEO_CURSOR_POSITION CursorPosition;
00431
SHORT RowIndex;
00432
PROW Row;
00433 COORD TargetPoint;
00434
00435
if (ScreenInfo->ConvScreenInfo)
00436
return STATUS_SUCCESS;
00437
00438 TargetPoint.X = Position.X;
00439 TargetPoint.Y = Position.Y;
00440 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
00441 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00442
00443
if (!CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console))
00444 CursorPosition.dwType = CHAR_TYPE_SBCS;
00445
else if (Row->
CharRow.KAttrs[TargetPoint.X] & ATTR_TRAILING_BYTE)
00446 CursorPosition.dwType = CHAR_TYPE_TRAILING;
00447
else if (Row->
CharRow.KAttrs[TargetPoint.X] & ATTR_LEADING_BYTE)
00448 CursorPosition.dwType = CHAR_TYPE_LEADING;
00449
else
00450 CursorPosition.dwType = CHAR_TYPE_SBCS;
00451
00452
00453
00454 CursorPosition.Coord.Column = Position.X - ScreenInfo->Window.Left;
00455 CursorPosition.Coord.Row = Position.Y - ScreenInfo->Window.Top;
00456
#else
00457
VIDEO_CURSOR_POSITION CursorPosition;
00458
00459
00460
00461 CursorPosition.Column = Position.X - ScreenInfo->Window.Left;
00462 CursorPosition.Row = Position.Y - ScreenInfo->Window.Top;
00463
#endif
00464
00465
return GdiFullscreenControl(FullscreenControlSetCursorPosition,
00466 (PVOID)&CursorPosition,
00467
sizeof(CursorPosition),
00468 NULL,
00469 0);
00470 }
00471
#endif
00472
00473
NTSTATUS
00474 SetCursorPosition(
00475 IN OUT
PSCREEN_INFORMATION ScreenInfo,
00476 IN COORD Position,
00477 IN BOOL TurnOn
00478 )
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 {
00502
00503
00504
00505
00506
if (Position.X >= ScreenInfo->ScreenBufferSize.X ||
00507 Position.Y >= ScreenInfo->ScreenBufferSize.Y) {
00508
return STATUS_INVALID_PARAMETER;
00509 }
00510
ConsoleHideCursor(ScreenInfo);
00511 ScreenInfo->BufferInfo.TextInfo.CursorPosition = Position;
00512
#ifdef i386
00513
if ((!(ScreenInfo->Console->Flags &
CONSOLE_VDM_REGISTERED)) &&
00514 ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
00515 SetCursorPositionHW(ScreenInfo,Position);
00516 }
00517
#endif
00518
ConsoleShowCursor(ScreenInfo);
00519
00520
00521
00522
if (ScreenInfo->Console->Flags &
CONSOLE_HAS_FOCUS) {
00523
00524
if (TurnOn) {
00525 ScreenInfo->BufferInfo.TextInfo.DelayCursor =
FALSE;
00526
CursorTimerRoutine(ScreenInfo);
00527 }
else {
00528 ScreenInfo->BufferInfo.TextInfo.DelayCursor =
TRUE;
00529 }
00530 ScreenInfo->BufferInfo.TextInfo.CursorMoved =
TRUE;
00531 }
00532
00533
return STATUS_SUCCESS;
00534 }
00535
00536
#ifdef i386
00537
NTSTATUS
00538 SetCursorInformationHW(
00539
PSCREEN_INFORMATION ScreenInfo,
00540 ULONG Size,
00541 BOOLEAN Visible
00542 )
00543 {
00544 VIDEO_CURSOR_ATTRIBUTES CursorAttr;
00545 ULONG FontSizeY;
00546
00547
if (ScreenInfo->
BufferInfo.TextInfo.DoubleCursor) {
00548
if (
Size > 50)
00549
Size =
Size >> 1;
00550
else
00551
Size =
Size << 1;
00552 }
00553
ASSERT (Size <= 100 && Size > 0);
00554 FontSizeY =
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) > 25 ? 8 : 16;
00555 CursorAttr.Height = (
USHORT)
CURSOR_PERCENTAGE_TO_TOP_SCAN_LINE(FontSizeY,Size);
00556 CursorAttr.Width = 31;
00557 CursorAttr.Enable = Visible;
00558
00559
return GdiFullscreenControl(FullscreenControlSetCursorAttributes,
00560 (PVOID)&CursorAttr,
00561
sizeof(CursorAttr),
00562 NULL,
00563 0);
00564
00565 }
00566
00567
00568
#endif