00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "precomp.h"
00020
#pragma hdrstop
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
BOOL
00070 MyInvert(
00071 IN
PCONSOLE_INFORMATION Console,
00072 IN PSMALL_RECT SmallRect
00073 )
00074
00075
00076
00077
00078
00079
00080
00081 {
00082 RECT
Rect;
00083
PSCREEN_INFORMATION ScreenInfo;
00084
#ifdef FE_SB
00085
SMALL_RECT SmallRect2;
00086 COORD TargetPoint;
00087
SHORT StringLength;
00088
#endif // FE_SB
00089
00090 ScreenInfo = Console->CurrentScreenBuffer;
00091
#ifdef FE_SB
00092
if (CONSOLE_IS_DBCS_OUTPUTCP(Console) &&
00093 ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
00094
for (SmallRect2.Top=SmallRect->Top; SmallRect2.Top <= SmallRect->Bottom;SmallRect2.Top++) {
00095 SmallRect2.Bottom = SmallRect2.Top;
00096 SmallRect2.Left = SmallRect->Left;
00097 SmallRect2.Right = SmallRect->Right;
00098
00099 TargetPoint.X = SmallRect2.Left;
00100 TargetPoint.Y = SmallRect2.Top;
00101
StringLength = SmallRect2.Right - SmallRect2.Left + 1;
00102
BisectClipbrd(
StringLength,TargetPoint,ScreenInfo,&SmallRect2);
00103
00104
if (SmallRect2.Left <= SmallRect2.Right) {
00105
Rect.
left = SmallRect2.Left-ScreenInfo->
Window.Left;
00106
Rect.
top = SmallRect2.Top-ScreenInfo->
Window.Top;
00107
Rect.
right = SmallRect2.Right+1-ScreenInfo->
Window.Left;
00108
Rect.
bottom = SmallRect2.Bottom+1-ScreenInfo->
Window.Top;
00109
Rect.
left *=
SCR_FONTSIZE(ScreenInfo).X;
00110
Rect.
top *=
SCR_FONTSIZE(ScreenInfo).Y;
00111
Rect.
right *=
SCR_FONTSIZE(ScreenInfo).X;
00112
Rect.
bottom *=
SCR_FONTSIZE(ScreenInfo).Y;
00113 PatBlt(Console->hDC,
00114
Rect.
left,
00115
Rect.
top,
00116
Rect.
right -
Rect.
left,
00117
Rect.
bottom -
Rect.
top,
00118 DSTINVERT
00119 );
00120 }
00121 }
00122 }
else
00123
#endif // FE_SB
00124
{
00125
Rect.
left = SmallRect->Left-ScreenInfo->
Window.Left;
00126
Rect.
top = SmallRect->Top-ScreenInfo->
Window.Top;
00127
Rect.
right = SmallRect->Right+1-ScreenInfo->
Window.Left;
00128
Rect.
bottom = SmallRect->Bottom+1-ScreenInfo->
Window.Top;
00129
#ifdef FE_SB
00130
if (!CONSOLE_IS_DBCS_OUTPUTCP(Console) &&
00131 ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER)
00132
#else
00133
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER)
00134
#endif
00135
{
00136
Rect.
left *=
SCR_FONTSIZE(ScreenInfo).X;
00137
Rect.
top *=
SCR_FONTSIZE(ScreenInfo).Y;
00138
Rect.
right *=
SCR_FONTSIZE(ScreenInfo).X;
00139
Rect.
bottom *=
SCR_FONTSIZE(ScreenInfo).Y;
00140 }
00141
00142 PatBlt(Console->hDC,
00143
Rect.
left,
00144
Rect.
top,
00145
Rect.
right -
Rect.
left,
00146
Rect.
bottom -
Rect.
top,
00147 DSTINVERT
00148 );
00149 }
00150
00151
return(
TRUE);
00152 }
00153
00154
VOID
00155 InvertSelection(
00156 IN
PCONSOLE_INFORMATION Console,
00157 BOOL Inverting
00158 )
00159 {
00160
BOOL Inverted;
00161
if (Console->Flags &
CONSOLE_SELECTING &&
00162 Console->SelectionFlags &
CONSOLE_SELECTION_NOT_EMPTY) {
00163 Inverted = (Console->SelectionFlags &
CONSOLE_SELECTION_INVERTED) ?
TRUE :
FALSE;
00164
if (Inverting == Inverted) {
00165
return;
00166 }
00167
if (Inverting) {
00168 Console->SelectionFlags |=
CONSOLE_SELECTION_INVERTED;
00169 }
else {
00170 Console->SelectionFlags &= ~
CONSOLE_SELECTION_INVERTED;
00171 }
00172
MyInvert(Console,&Console->SelectionRect);
00173 }
00174
00175 }
00176
00177
VOID
00178 ExtendSelection(
00179 IN
PCONSOLE_INFORMATION Console,
00180 IN COORD CursorPosition
00181 )
00182
00183
00184
00185
00186
00187
00188
00189 {
00190 SMALL_RECT OldSelectionRect;
00191 HRGN OldRegion,NewRegion,CombineRegion;
00192 COORD FontSize;
00193
PSCREEN_INFORMATION ScreenInfo = Console->CurrentScreenBuffer;
00194
00195
if (CursorPosition.X < 0) {
00196 CursorPosition.X = 0;
00197 }
else if (CursorPosition.X >= ScreenInfo->
ScreenBufferSize.X) {
00198 CursorPosition.X = ScreenInfo->
ScreenBufferSize.X-1;
00199 }
00200
00201
if (CursorPosition.Y < 0) {
00202 CursorPosition.Y = 0;
00203 }
else if (CursorPosition.Y >= ScreenInfo->
ScreenBufferSize.Y) {
00204 CursorPosition.Y = ScreenInfo->
ScreenBufferSize.Y-1;
00205 }
00206
00207
if (!(Console->SelectionFlags &
CONSOLE_SELECTION_NOT_EMPTY)) {
00208
00209
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
00210
00211
MakeCursorVisible(ScreenInfo, CursorPosition);
00212
ASSERT(!(Console->SelectionFlags &
CONSOLE_MOUSE_SELECTION));
00213
00214
00215
00216
00217
00218
00219
ConsoleHideCursor(ScreenInfo);
00220 }
00221 Console->SelectionFlags |=
CONSOLE_SELECTION_NOT_EMPTY;
00222 Console->SelectionRect.Left =Console->SelectionRect.Right = Console->SelectionAnchor.X;
00223 Console->SelectionRect.Top = Console->SelectionRect.Bottom = Console->SelectionAnchor.Y;
00224
00225
00226
00227
#ifdef FE_SB
00228
if (!CONSOLE_IS_DBCS_OUTPUTCP(Console) &&
00229 ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER)
00230
#else
00231
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER)
00232
#endif
00233
{
00234
MyInvert(Console,&Console->SelectionRect);
00235 }
00236 }
else {
00237
00238
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
00239
00240
MakeCursorVisible(ScreenInfo,CursorPosition);
00241 }
00242
#ifdef FE_SB
00243
00244
00245
00246
if (CONSOLE_IS_DBCS_OUTPUTCP(Console)) {
00247
MyInvert(Console, &Console->SelectionRect);
00248 }
00249
#endif // FE_SB
00250
}
00251
00252
00253
00254
00255
00256 OldSelectionRect = Console->SelectionRect;
00257
if (CursorPosition.X <= Console->SelectionAnchor.X) {
00258 Console->SelectionRect.Left = CursorPosition.X;
00259 Console->SelectionRect.Right = Console->SelectionAnchor.X;
00260 }
else if (CursorPosition.X > Console->SelectionAnchor.X) {
00261 Console->SelectionRect.Right = CursorPosition.X;
00262 Console->SelectionRect.Left = Console->SelectionAnchor.X;
00263 }
00264
if (CursorPosition.Y <= Console->SelectionAnchor.Y) {
00265 Console->SelectionRect.Top = CursorPosition.Y;
00266 Console->SelectionRect.Bottom = Console->SelectionAnchor.Y;
00267 }
else if (CursorPosition.Y > Console->SelectionAnchor.Y) {
00268 Console->SelectionRect.Bottom = CursorPosition.Y;
00269 Console->SelectionRect.Top = Console->SelectionAnchor.Y;
00270 }
00271
00272
00273
00274
00275
#ifdef FE_SB
00276
if (CONSOLE_IS_DBCS_OUTPUTCP(Console)) {
00277
MyInvert(Console, &Console->SelectionRect);
00278 }
else
00279
#endif
00280
{
00281
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
00282 FontSize =
CON_FONTSIZE(Console);
00283 }
else {
00284 FontSize.X = 1;
00285 FontSize.Y = 1;
00286 }
00287 CombineRegion = CreateRectRgn(0,0,0,0);
00288 OldRegion = CreateRectRgn((OldSelectionRect.Left-ScreenInfo->
Window.Left)*FontSize.X,
00289 (OldSelectionRect.Top-ScreenInfo->
Window.Top)*FontSize.Y,
00290 (OldSelectionRect.Right-ScreenInfo->
Window.Left+1)*FontSize.X,
00291 (OldSelectionRect.Bottom-ScreenInfo->
Window.Top+1)*FontSize.Y
00292 );
00293 NewRegion = CreateRectRgn((Console->SelectionRect.Left-ScreenInfo->
Window.Left)*FontSize.X,
00294 (Console->SelectionRect.Top-ScreenInfo->
Window.Top)*FontSize.Y,
00295 (Console->SelectionRect.Right-ScreenInfo->
Window.Left+1)*FontSize.X,
00296 (Console->SelectionRect.Bottom-ScreenInfo->
Window.Top+1)*FontSize.Y
00297 );
00298 CombineRgn(CombineRegion,OldRegion,NewRegion,RGN_XOR);
00299
00300 InvertRgn(Console->hDC,CombineRegion);
00301 DeleteObject(OldRegion);
00302 DeleteObject(NewRegion);
00303 DeleteObject(CombineRegion);
00304 }
00305 }
00306
00307
VOID
00308 CancelMouseSelection(
00309 IN
PCONSOLE_INFORMATION Console
00310 )
00311
00312
00313
00314
00315
00316
00317
00318 {
00319
00320
00321
00322
00323 Console->Flags &= ~
CONSOLE_SELECTING;
00324
00325
SetWinText(Console,
msgSelectMode,
FALSE);
00326
00327
00328
00329
00330
00331
00332
MyInvert(Console,&Console->SelectionRect);
00333
00334
ReleaseCapture();
00335 }
00336
00337
VOID
00338 CancelKeySelection(
00339 IN
PCONSOLE_INFORMATION Console,
00340 IN BOOL JustCursor
00341 )
00342
00343
00344
00345
00346
00347
00348
00349 {
00350
PSCREEN_INFORMATION ScreenInfo;
00351
00352
if (!JustCursor) {
00353
00354
00355
00356
00357
00358 Console->Flags &= ~
CONSOLE_SELECTING;
00359
00360
SetWinText(Console,
msgMarkMode,
FALSE);
00361 }
00362
00363
00364
00365
00366
00367 ScreenInfo = Console->CurrentScreenBuffer;
00368
if (Console->SelectionFlags &
CONSOLE_SELECTION_NOT_EMPTY) {
00369
MyInvert(Console,&Console->SelectionRect);
00370 }
else {
00371
ConsoleHideCursor(ScreenInfo);
00372 }
00373
00374
00375
00376
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
00377
SetCursorInformation(ScreenInfo,
00378 Console->TextCursorSize,
00379 Console->TextCursorVisible
00380 );
00381
SetCursorPosition(ScreenInfo,
00382 Console->TextCursorPosition,
00383
TRUE
00384 );
00385 }
00386
ConsoleShowCursor(ScreenInfo);
00387 }
00388
00389
VOID
00390 ConvertToMouseSelect(
00391 IN
PCONSOLE_INFORMATION Console,
00392 IN COORD MousePosition
00393 )
00394
00395
00396
00397
00398
00399
00400
00401 {
00402 Console->SelectionFlags |=
CONSOLE_MOUSE_SELECTION |
CONSOLE_MOUSE_DOWN;
00403
00404
00405
00406
00407
00408
CancelKeySelection(Console,
TRUE);
00409
00410 Console->SelectionFlags |=
CONSOLE_SELECTION_NOT_EMPTY;
00411
00412
00413
00414
00415
00416 Console->SelectionAnchor = MousePosition;
00417 Console->SelectionRect.Left =Console->SelectionRect.Right = Console->SelectionAnchor.X;
00418 Console->SelectionRect.Top = Console->SelectionRect.Bottom = Console->SelectionAnchor.Y;
00419
MyInvert(Console,&Console->SelectionRect);
00420
00421
00422
00423
00424
00425
SetWinText(Console,
msgMarkMode,
FALSE);
00426
SetWinText(Console,
msgSelectMode,
TRUE);
00427
00428
00429
00430
00431
00432
SetCapture(Console->hWnd);
00433 }
00434
00435
00436
VOID
00437 ClearSelection(
00438 IN
PCONSOLE_INFORMATION Console
00439 )
00440 {
00441
if (Console->Flags &
CONSOLE_SELECTING) {
00442
if (Console->SelectionFlags &
CONSOLE_MOUSE_SELECTION) {
00443
CancelMouseSelection(Console);
00444 }
else {
00445
CancelKeySelection(Console,
FALSE);
00446 }
00447
UnblockWriteConsole(Console,
CONSOLE_SELECTING);
00448 }
00449 }
00450
00451
VOID
00452 StoreSelection(
00453 IN
PCONSOLE_INFORMATION Console
00454 )
00455
00456
00457
00458
00459
00460
00461
00462 {
00463 PCHAR_INFO Selection,CurCharInfo;
00464 COORD SourcePoint;
00465 COORD TargetSize;
00466 SMALL_RECT TargetRect;
00467 PWCHAR CurChar,CharBuf;
00468 HANDLE ClipboardDataHandle;
00469
SHORT i,j;
00470
BOOL Success;
00471
PSCREEN_INFORMATION ScreenInfo;
00472
BOOL bFalseUnicode;
00473
BOOL bMungeData;
00474
#if defined(FE_SB)
00475
COORD TargetSize2;
00476 PWCHAR TmpClipboardData;
00477 SMALL_RECT SmallRect2;
00478 COORD TargetPoint;
00479
SHORT StringLength;
00480 WCHAR wchCARRIAGERETURN;
00481 WCHAR wchLINEFEED;
00482
int iExtra = 0;
00483
int iFeReserve = 1;
00484
#endif
00485
00486
00487
00488
00489
00490
if (!(Console->SelectionFlags &
CONSOLE_SELECTION_NOT_EMPTY)) {
00491
return;
00492 }
00493
00494
00495
00496
00497
00498 ScreenInfo = Console->CurrentScreenBuffer;
00499
if (Console->SelectionRect.Left < 0) {
00500 Console->SelectionRect.Left = 0;
00501 }
00502
if (Console->SelectionRect.Top < 0) {
00503 Console->SelectionRect.Top = 0;
00504 }
00505
if (Console->SelectionRect.Right >= ScreenInfo->
ScreenBufferSize.X) {
00506 Console->SelectionRect.Right = (
SHORT)(ScreenInfo->
ScreenBufferSize.X-1);
00507 }
00508
if (Console->SelectionRect.Bottom >= ScreenInfo->
ScreenBufferSize.Y) {
00509 Console->SelectionRect.Bottom = (
SHORT)(ScreenInfo->
ScreenBufferSize.Y-1);
00510 }
00511
00512 TargetSize.X =
WINDOW_SIZE_X(&Console->SelectionRect);
00513 TargetSize.Y =
WINDOW_SIZE_Y(&Console->SelectionRect);
00514
if (ScreenInfo->
Flags &
CONSOLE_TEXTMODE_BUFFER) {
00515
#if defined(FE_SB)
00516
00517
if (CONSOLE_IS_DBCS_CP(Console)) {
00518 iExtra = 4 ;
00519 iFeReserve = 2 ;
00520 TmpClipboardData = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),(
sizeof(WCHAR) * TargetSize.Y * (TargetSize.X + iExtra) +
sizeof(WCHAR)));
00521
if (TmpClipboardData ==
NULL) {
00522
return;
00523 }
00524 }
else {
00525 TmpClipboardData =
NULL;
00526 }
00527
00528 Selection = (PCHAR_INFO)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),
sizeof(CHAR_INFO) * (TargetSize.X + iExtra) * TargetSize.Y * iFeReserve);
00529
if (Selection ==
NULL)
00530 {
00531
if (TmpClipboardData)
00532
ConsoleHeapFree(TmpClipboardData);
00533
return;
00534 }
00535
#else
00536
Selection = (PCHAR_INFO)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),
sizeof(CHAR_INFO) * TargetSize.X * TargetSize.Y);
00537
if (Selection ==
NULL)
00538
return;
00539
#endif
00540
00541
#if defined(FE_SB)
00542
if (!CONSOLE_IS_DBCS_CP(Console)) {
00543
#endif
00544
00545
#ifdef i386
00546
if ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) &&
00547 (Console->Flags &
CONSOLE_VDM_REGISTERED)) {
00548 ReadRegionFromScreenHW(ScreenInfo,
00549 &Console->SelectionRect,
00550 Selection);
00551 CurCharInfo = Selection;
00552
for (i=0; i<TargetSize.Y; i++) {
00553
for (j=0; j<TargetSize.X; j++,CurCharInfo++) {
00554 CurCharInfo->Char.UnicodeChar = SB_CharToWcharGlyph(Console->OutputCP, CurCharInfo->Char.AsciiChar);
00555 }
00556 }
00557 }
else {
00558
#endif
00559
SourcePoint.X = Console->SelectionRect.Left;
00560 SourcePoint.Y = Console->SelectionRect.Top;
00561 TargetRect.Left = TargetRect.Top = 0;
00562 TargetRect.Right = (
SHORT)(TargetSize.X-1);
00563 TargetRect.Bottom = (
SHORT)(TargetSize.Y-1);
00564
ReadRectFromScreenBuffer(ScreenInfo,
00565 SourcePoint,
00566 Selection,
00567 TargetSize,
00568 &TargetRect);
00569
#ifdef i386
00570
}
00571
#endif
00572
00573
00574 ClipboardDataHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
00575 (TargetSize.Y * (TargetSize.X + 2) + 1) *
sizeof(WCHAR));
00576
if (ClipboardDataHandle ==
NULL) {
00577
ConsoleHeapFree(Selection);
00578
return;
00579 }
00580
#if defined(FE_SB)
00581
}
00582
#endif
00583
00584
00585
00586
00587
00588
#if defined(FE_SB)
00589
if (CONSOLE_IS_DBCS_CP(Console)) {
00590
if ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
00591 !(Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
00592
00593
00594
00595
00596
00597
00598 wchCARRIAGERETURN = 0x0000;
00599 wchLINEFEED = 0x0000;
00600 }
else {
00601 wchCARRIAGERETURN =
UNICODE_CARRIAGERETURN;
00602 wchLINEFEED =
UNICODE_LINEFEED;
00603 }
00604
00605 CurChar = TmpClipboardData;
00606 bMungeData = (
GetKeyState(VK_SHIFT) &
KEY_PRESSED) == 0;
00607
for (i=0;i<TargetSize.Y;i++) {
00608 PWCHAR pwchLineStart = CurChar;
00609
00610 SourcePoint.X = Console->SelectionRect.Left;
00611 SourcePoint.Y = Console->SelectionRect.Top + i;
00612 TargetSize2.X = TargetSize.X;
00613 TargetSize2.Y = 1;
00614
00615 SmallRect2.Left = SourcePoint.X;
00616 SmallRect2.Top = SourcePoint.Y;
00617 SmallRect2.Right = SourcePoint.X + TargetSize2.X - 1;
00618 SmallRect2.Bottom = SourcePoint.Y;
00619 TargetPoint = SourcePoint;
00620
StringLength = TargetSize2.X;
00621
BisectClipbrd(
StringLength,TargetPoint,ScreenInfo,&SmallRect2);
00622
00623 SourcePoint.X = SmallRect2.Left;
00624 SourcePoint.Y = SmallRect2.Top;
00625 TargetSize2.X = SmallRect2.Right - SmallRect2.Left + 1;
00626 TargetSize2.Y = 1;
00627 TargetRect.Left = TargetRect.Top = TargetRect.Bottom = 0;
00628 TargetRect.Right = (
SHORT)(TargetSize2.X-1);
00629
00630
ReadRectFromScreenBuffer(ScreenInfo,
00631 SourcePoint,
00632 Selection,
00633 TargetSize2,
00634 &TargetRect);
00635
00636 CurCharInfo = Selection;
00637
for (j=0;j<TargetSize2.X;j++,CurCharInfo++) {
00638
if (!(CurCharInfo->Attributes & COMMON_LVB_TRAILING_BYTE))
00639 *CurChar++ = CurCharInfo->Char.UnicodeChar;
00640 }
00641
00642
if (bMungeData) {
00643 CurChar--;
00644
while ((CurChar >= pwchLineStart) && (*CurChar ==
UNICODE_SPACE))
00645 CurChar--;
00646 CurChar++;
00647 *CurChar++ = wchCARRIAGERETURN;
00648 *CurChar++ = wchLINEFEED;
00649 }
00650 }
00651 }
00652
else {
00653
#endif
00654
CurCharInfo = Selection;
00655 CurChar = CharBuf = GlobalLock(ClipboardDataHandle);
00656 bFalseUnicode = ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
00657 !(Console->FullScreenFlags & CONSOLE_FULLSCREEN));
00658 bMungeData = (
GetKeyState(VK_SHIFT) &
KEY_PRESSED) == 0;
00659
for (i=0;i<TargetSize.Y;i++) {
00660 PWCHAR pwchLineStart = CurChar;
00661
00662
for (j=0;j<TargetSize.X;j++,CurCharInfo++,CurChar++) {
00663 *CurChar = CurCharInfo->Char.UnicodeChar;
00664
if (*CurChar == 0) {
00665 *CurChar =
UNICODE_SPACE;
00666 }
00667 }
00668
00669
if (bMungeData) {
00670 CurChar--;
00671
while ((CurChar >= pwchLineStart) && (*CurChar ==
UNICODE_SPACE))
00672 CurChar--;
00673 CurChar++;
00674 }
00675
00676
if (bFalseUnicode) {
00677
FalseUnicodeToRealUnicode(pwchLineStart,
00678 (ULONG)(CurChar - pwchLineStart), Console->OutputCP);
00679 }
00680
if (bMungeData) {
00681 *CurChar++ =
UNICODE_CARRIAGERETURN;
00682 *CurChar++ =
UNICODE_LINEFEED;
00683 }
00684 }
00685
#if defined(FE_SB)
00686
}
00687
#endif
00688
if (bMungeData) {
00689
if (TargetSize.Y)
00690 CurChar -= 2;
00691 }
00692 *CurChar =
'\0';
00693
00694
#if defined(FE_SB)
00695
if (CONSOLE_IS_DBCS_CP(Console)) {
00696
00697 ClipboardDataHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
00698 (
sizeof(WCHAR) * TargetSize.Y * (TargetSize.X+(4*
sizeof(WCHAR)))) +
00699 (1*
sizeof(WCHAR)));
00700
if (ClipboardDataHandle ==
NULL) {
00701
ConsoleHeapFree(Selection);
00702
ConsoleHeapFree(TmpClipboardData);
00703
return;
00704 }
00705
00706 CharBuf = GlobalLock(ClipboardDataHandle);
00707 RtlCopyMemory(CharBuf,TmpClipboardData,
ConsoleHeapSize(TmpClipboardData));
00708 CurChar = CharBuf + (CurChar - TmpClipboardData);
00709
00710
if (wchCARRIAGERETURN == 0x0000) {
00711
00712
00713
00714
00715
00716 PWCHAR pwch;
00717
FalseUnicodeToRealUnicode(CharBuf,
00718 (ULONG)(CurChar - CharBuf),
00719 Console->OutputCP
00720 );
00721
for (pwch = CharBuf; pwch < CurChar; pwch++) {
00722
if ((*pwch == 0x0000) && (pwch[1] == 0x0000)) {
00723 *pwch++ =
UNICODE_CARRIAGERETURN;
00724 *pwch =
UNICODE_LINEFEED;
00725 }
00726 }
00727 }
00728 }
00729
#endif
00730
00731 GlobalUnlock(ClipboardDataHandle);
00732
#if defined(FE_SB)
00733
if (TmpClipboardData)
00734
ConsoleHeapFree(TmpClipboardData);
00735
#endif
00736
ConsoleHeapFree(Selection);
00737 Success =
OpenClipboard(Console->hWnd);
00738
if (!Success) {
00739 GlobalFree(ClipboardDataHandle);
00740
return;
00741 }
00742
00743 Success = EmptyClipboard();
00744
if (!Success) {
00745 GlobalFree(ClipboardDataHandle);
00746
return;
00747 }
00748
00749
SetClipboardData(CF_UNICODETEXT,ClipboardDataHandle);
00750
CloseClipboard();
00751 }
else {
00752 HBITMAP hBitmapTarget, hBitmapOld;
00753 HDC hDCMem;
00754 HPALETTE hPaletteOld;
00755
int Height;
00756
00757
NtWaitForSingleObject(ScreenInfo->
BufferInfo.GraphicsInfo.hMutex,
00758
FALSE,
NULL);
00759
00760 hDCMem = CreateCompatibleDC(Console->hDC);
00761 hBitmapTarget = CreateCompatibleBitmap(Console->hDC,
00762 TargetSize.X,
00763 TargetSize.Y);
00764
if (hBitmapTarget) {
00765 hBitmapOld = SelectObject(hDCMem, hBitmapTarget);
00766
if (ScreenInfo->
hPalette) {
00767 hPaletteOld =
SelectPalette(hDCMem,
00768 ScreenInfo->
hPalette,
00769
FALSE);
00770 }
00771
MyInvert(Console,&Console->SelectionRect);
00772
00773
00774
00775
00776
00777
00778 Height = ScreenInfo->
BufferInfo.GraphicsInfo.lpBitMapInfo->bmiHeader.biHeight;
00779
00780 StretchDIBits(hDCMem, 0, 0,
00781 TargetSize.X, TargetSize.Y,
00782 Console->SelectionRect.Left + ScreenInfo->
Window.Left,
00783 (Height < 0) ? -Height - (Console->SelectionRect.Bottom + ScreenInfo->
Window.Top) - 1
00784 : Console->SelectionRect.Bottom + ScreenInfo->
Window.Top,
00785 TargetSize.X, TargetSize.Y,
00786 ScreenInfo->
BufferInfo.GraphicsInfo.BitMap,
00787 ScreenInfo->
BufferInfo.GraphicsInfo.lpBitMapInfo,
00788 ScreenInfo->
BufferInfo.GraphicsInfo.dwUsage,
00789 SRCCOPY);
00790
MyInvert(Console,&Console->SelectionRect);
00791
if (ScreenInfo->
hPalette) {
00792
SelectPalette(hDCMem, hPaletteOld,
FALSE);
00793 }
00794 SelectObject(hDCMem, hBitmapOld);
00795
OpenClipboard(Console->hWnd);
00796 EmptyClipboard();
00797
SetClipboardData(CF_BITMAP,hBitmapTarget);
00798
CloseClipboard();
00799 }
00800 DeleteDC(hDCMem);
00801
NtReleaseMutant(ScreenInfo->
BufferInfo.GraphicsInfo.hMutex,
NULL);
00802 }
00803
00804 }
00805
00806
VOID
00807 DoCopy(
00808 IN
PCONSOLE_INFORMATION Console
00809 )
00810 {
00811
StoreSelection(Console);
00812
ClearSelection(Console);
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
VOID
00835 DoStringPaste(
00836 IN
PCONSOLE_INFORMATION Console,
00837 IN PWCHAR pwStr,
00838 IN UINT DataSize
00839 )
00840 {
00841 PINPUT_RECORD StringData,CurRecord;
00842 PWCHAR CurChar;
00843 WCHAR Char;
00844
DWORD i;
00845
DWORD ChunkSize,j;
00846 ULONG EventsWritten;
00847
00848
00849
if(!pwStr) {
00850
return;
00851 }
00852
00853
if (DataSize >
DATA_CHUNK_SIZE) {
00854 ChunkSize =
DATA_CHUNK_SIZE;
00855 }
else {
00856 ChunkSize = DataSize;
00857 }
00858
00859
00860
00861
00862
00863 StringData = (PINPUT_RECORD)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),ChunkSize*
sizeof(INPUT_RECORD)*8);
00864
if (StringData ==
NULL) {
00865
return;
00866 }
00867
00868
00869
00870
00871
00872 CurChar = pwStr;
00873
for (j = 0; j < DataSize; j += ChunkSize) {
00874
if (ChunkSize > DataSize - j) {
00875 ChunkSize = DataSize - j;
00876 }
00877 CurRecord = StringData;
00878
for (i = 0, EventsWritten = 0; i < ChunkSize; i++) {
00879
00880 Char = *CurChar;
00881
if (Char !=
UNICODE_LINEFEED || (i==0 && j==0) || (*(CurChar-1)) !=
UNICODE_CARRIAGERETURN) {
00882
SHORT KeyState;
00883
BYTE KeyFlags;
00884
BOOL AltGr=
FALSE;
00885
BOOL Shift=
FALSE;
00886
00887
if (Char == 0) {
00888 j = DataSize;
00889
break;
00890 }
00891
00892 KeyState =
VkKeyScan(Char);
00893
#if defined(FE_SB)
00894
if (
CONSOLE_IS_DBCS_ENABLED() &&
00895 (KeyState == -1)) {
00896 WORD CharType;
00897
00898
00899
00900
00901
00902
00903 GetStringTypeW(CT_CTYPE3,&Char,1,&CharType);
00904
if ((CharType & C3_ALPHA) ||
00905 IsConsoleFullWidth(Console->hDC,Console->OutputCP,Char)) {
00906 KeyState = 0;
00907 }
00908 }
00909
#endif
00910
00911
00912
00913
00914
if (KeyState == -1) {
00915
CHAR CharString[4];
00916 UCHAR OemChar;
00917 PCHAR pCharString;
00918
00919
ConvertToOem(Console->OutputCP,
00920 &Char,
00921 1,
00922 &OemChar,
00923 1
00924 );
00925
00926 _itoa(OemChar, CharString, 10);
00927
00928 EventsWritten++;
00929
LoadKeyEvent(CurRecord,
TRUE,0,VK_MENU,0x38,LEFT_ALT_PRESSED);
00930 CurRecord++;
00931
00932
for (pCharString=CharString;*pCharString;pCharString++) {
00933 WORD wVirtualKey, wScancode;
00934 EventsWritten++;
00935 wVirtualKey = *pCharString-
'0'+VK_NUMPAD0;
00936 wScancode = (WORD)
MapVirtualKey(wVirtualKey, 0);
00937
LoadKeyEvent(CurRecord,
TRUE,0,wVirtualKey,wScancode,LEFT_ALT_PRESSED);
00938 CurRecord++;
00939 EventsWritten++;
00940
LoadKeyEvent(CurRecord,
FALSE,0,wVirtualKey,wScancode,LEFT_ALT_PRESSED);
00941 CurRecord++;
00942 }
00943
00944 EventsWritten++;
00945
LoadKeyEvent(CurRecord,
FALSE,Char,VK_MENU,0x38,0);
00946 CurRecord++;
00947 }
else {
00948 KeyFlags =
HIBYTE(KeyState);
00949
00950
00951
if ((KeyFlags & 6) == 6) {
00952 AltGr=
TRUE;
00953 EventsWritten++;
00954
LoadKeyEvent(CurRecord,
TRUE,0,VK_MENU,0x38,ENHANCED_KEY | LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED);
00955 CurRecord++;
00956 }
else if (KeyFlags & 1) {
00957 Shift=
TRUE;
00958 EventsWritten++;
00959
LoadKeyEvent(CurRecord,
TRUE,0,VK_SHIFT,0x2a,SHIFT_PRESSED);
00960 CurRecord++;
00961 }
00962
00963 EventsWritten++;
00964
LoadKeyEvent(CurRecord,
00965
TRUE,
00966 Char,
00967
LOBYTE(KeyState),
00968 (WORD)
MapVirtualKey(CurRecord->Event.KeyEvent.wVirtualKeyCode,0),
00969 0);
00970
if (KeyFlags & 1)
00971 CurRecord->Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
00972
if (KeyFlags & 2)
00973 CurRecord->Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED;
00974
if (KeyFlags & 4)
00975 CurRecord->Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED;
00976 CurRecord++;
00977
00978 EventsWritten++;
00979 *CurRecord = *(CurRecord-1);
00980 CurRecord->Event.KeyEvent.bKeyDown =
FALSE;
00981 CurRecord++;
00982
00983
00984
if (AltGr) {
00985 EventsWritten++;
00986
LoadKeyEvent(CurRecord,
FALSE,0,VK_MENU,0x38,ENHANCED_KEY);
00987 CurRecord++;
00988 }
else if (Shift) {
00989 EventsWritten++;
00990
LoadKeyEvent(CurRecord,
FALSE,0,VK_SHIFT,0x2a,0);
00991 CurRecord++;
00992 }
00993 }
00994 }
00995 CurChar++;
00996 }
00997 EventsWritten =
WriteInputBuffer(Console,
00998 &Console->InputBuffer,
00999 StringData,
01000 EventsWritten
01001 );
01002 }
01003
ConsoleHeapFree(StringData);
01004
return;
01005 }
01006
01007
VOID
01008 DoPaste(
01009 IN
PCONSOLE_INFORMATION Console
01010 )
01011
01012
01013
01014
01015
01016
01017
01018
01019 {
01020
BOOL Success;
01021 HANDLE ClipboardDataHandle;
01022
01023
if (Console->Flags &
CONSOLE_SCROLLING) {
01024
return;
01025 }
01026
01027
01028
01029
01030
01031 Success =
OpenClipboard(Console->hWnd);
01032
if (!Success)
01033
return;
01034
01035
if (Console->CurrentScreenBuffer->Flags &
CONSOLE_TEXTMODE_BUFFER) {
01036 PWCHAR pwstr;
01037
01038 ClipboardDataHandle =
GetClipboardData(CF_UNICODETEXT);
01039
if (ClipboardDataHandle ==
NULL) {
01040
CloseClipboard();
01041
return;
01042 }
01043 pwstr = GlobalLock(ClipboardDataHandle);
01044
DoStringPaste(Console,pwstr,(ULONG)GlobalSize(ClipboardDataHandle)/
sizeof(WCHAR));
01045 GlobalUnlock(ClipboardDataHandle);
01046
01047 }
else {
01048 HBITMAP hBitmapSource,hBitmapTarget;
01049 HDC hDCMemSource,hDCMemTarget;
01050 BITMAP bm;
01051
PSCREEN_INFORMATION ScreenInfo;
01052
01053 hBitmapSource =
GetClipboardData(CF_BITMAP);
01054
if (hBitmapSource) {
01055
01056 ScreenInfo = Console->CurrentScreenBuffer;
01057
NtWaitForSingleObject(ScreenInfo->
BufferInfo.GraphicsInfo.hMutex,
01058
FALSE,
NULL);
01059
01060 hBitmapTarget = CreateDIBitmap(Console->hDC,
01061 &ScreenInfo->
BufferInfo.GraphicsInfo.lpBitMapInfo->bmiHeader,
01062 CBM_INIT,
01063 ScreenInfo->
BufferInfo.GraphicsInfo.BitMap,
01064 ScreenInfo->
BufferInfo.GraphicsInfo.lpBitMapInfo,
01065 ScreenInfo->
BufferInfo.GraphicsInfo.dwUsage
01066 );
01067
if (hBitmapTarget) {
01068 hDCMemTarget = CreateCompatibleDC ( Console->hDC );
01069 hDCMemSource = CreateCompatibleDC ( Console->hDC );
01070 SelectObject( hDCMemTarget, hBitmapTarget );
01071 SelectObject( hDCMemSource, hBitmapSource );
01072 GetObjectW(hBitmapSource,
sizeof (BITMAP), (LPSTR) &bm);
01073 BitBlt ( hDCMemTarget, 0, 0, bm.bmWidth, bm.bmHeight,
01074 hDCMemSource, 0, 0, SRCCOPY);
01075 GetObjectW(hBitmapTarget,
sizeof (BITMAP), (LPSTR) &bm);
01076
01077
01078
01079 GetDIBits(hDCMemTarget, hBitmapTarget, 0, bm.bmHeight,
01080 ScreenInfo->
BufferInfo.GraphicsInfo.BitMap,
01081 ScreenInfo->
BufferInfo.GraphicsInfo.lpBitMapInfo,
01082 ScreenInfo->
BufferInfo.GraphicsInfo.dwUsage);
01083 DeleteDC(hDCMemSource);
01084 DeleteDC(hDCMemTarget);
01085 DeleteObject(hBitmapTarget);
01086 InvalidateRect(Console->hWnd,
NULL,
FALSE);
01087 }
01088
NtReleaseMutant(ScreenInfo->
BufferInfo.GraphicsInfo.hMutex,
NULL);
01089 }
01090 }
01091
CloseClipboard();
01092
return;
01093 }
01094
01095
VOID
01096 InitSelection(
01097 IN
PCONSOLE_INFORMATION Console
01098 )
01099
01100
01101
01102
01103
01104
01105
01106
01107 {
01108 COORD Position;
01109
PSCREEN_INFORMATION ScreenInfo;
01110
01111
01112
01113
01114
01115
if (Console->Flags &
CONSOLE_SELECTING) {
01116
if (Console->SelectionFlags &
CONSOLE_MOUSE_SELECTION) {
01117
CancelMouseSelection(Console);
01118 }
else {
01119
CancelKeySelection(Console,
FALSE);
01120 }
01121 }
01122
01123
01124
01125
01126
01127 Console->Flags |=
CONSOLE_SELECTING;
01128 Console->SelectionFlags = 0;
01129
01130
01131
01132
01133
01134
01135 ScreenInfo = Console->CurrentScreenBuffer;
01136 Console->TextCursorPosition = ScreenInfo->
BufferInfo.TextInfo.CursorPosition;
01137 Console->TextCursorVisible = (BOOLEAN)ScreenInfo->
BufferInfo.TextInfo.CursorVisible;
01138 Console->TextCursorSize = ScreenInfo->
BufferInfo.TextInfo.CursorSize;
01139
ConsoleHideCursor(ScreenInfo);
01140
SetCursorInformation(ScreenInfo,
01141 100,
01142
TRUE
01143 );
01144 Position.X = ScreenInfo->
Window.Left;
01145 Position.Y = ScreenInfo->
Window.Top;
01146
SetCursorPosition(ScreenInfo,
01147 Position,
01148
TRUE
01149 );
01150
ConsoleShowCursor(ScreenInfo);
01151
01152
01153
01154
01155
01156 Console->SelectionAnchor = Position;
01157
01158
01159
01160
01161
01162
SetWinText(Console,
msgMarkMode,
TRUE);
01163
01164 }
01165
01166
VOID
01167 DoMark(
01168 IN
PCONSOLE_INFORMATION Console
01169 )
01170 {
01171
InitSelection(Console);
01172 }
01173
01174
VOID
01175 DoSelectAll(
01176 IN
PCONSOLE_INFORMATION Console
01177 )
01178 {
01179 COORD Position;
01180 COORD WindowOrigin;
01181
PSCREEN_INFORMATION ScreenInfo;
01182
01183
01184
if (Console->Flags &
CONSOLE_SELECTING) {
01185
ClearSelection(Console);
01186 }
01187
01188
01189 ScreenInfo = Console->CurrentScreenBuffer;
01190 WindowOrigin.X = ScreenInfo->
Window.Left;
01191 WindowOrigin.Y = ScreenInfo->
Window.Top;
01192
01193
01194 Console->Flags |=
CONSOLE_SELECTING;
01195 Console->SelectionFlags =
CONSOLE_MOUSE_SELECTION |
CONSOLE_SELECTION_NOT_EMPTY;
01196 Console->SelectionAnchor.X = Console->SelectionRect.Left = Console->SelectionRect.Right = 0;
01197 Console->SelectionAnchor.Y = Console->SelectionRect.Top = Console->SelectionRect.Bottom = 0;
01198
MyInvert(Console,&Console->SelectionRect);
01199
SetWinText(Console,
msgSelectMode,
TRUE);
01200
01201
01202 Position.X = ScreenInfo->
ScreenBufferSize.X - 1;
01203 Position.Y = ScreenInfo->
BufferInfo.TextInfo.CursorPosition.Y;
01204
ExtendSelection(Console, Position);
01205
01206
01207
SetWindowOrigin(ScreenInfo,
TRUE, WindowOrigin);
01208 }
01209
01210
VOID
01211 DoScroll(
01212 IN
PCONSOLE_INFORMATION Console
01213 )
01214 {
01215
if (!(Console->Flags &
CONSOLE_SCROLLING)) {
01216
SetWinText(Console,
msgScrollMode,
TRUE);
01217 Console->Flags |=
CONSOLE_SCROLLING;
01218 }
01219 }
01220
01221
VOID
01222 ClearScroll(
01223 IN
PCONSOLE_INFORMATION Console
01224 )
01225 {
01226
SetWinText(Console,
msgScrollMode,
FALSE);
01227 Console->Flags &= ~
CONSOLE_SCROLLING;
01228 }
01229
01230
VOID
01231 ScrollIfNecessary(
01232 IN
PCONSOLE_INFORMATION Console,
01233 IN
PSCREEN_INFORMATION ScreenInfo
01234 )
01235 {
01236 POINT CursorPos;
01237 RECT ClientRect;
01238 COORD MousePosition;
01239
01240
if (Console->Flags &
CONSOLE_SELECTING &&
01241 Console->SelectionFlags &
CONSOLE_MOUSE_DOWN) {
01242
if (!
GetCursorPos(&CursorPos)) {
01243
return;
01244 }
01245
if (!
GetClientRect(Console->hWnd,&ClientRect)) {
01246
return;
01247 }
01248
MapWindowPoints(Console->hWnd,
NULL,(LPPOINT)&ClientRect,2);
01249
if (!(
PtInRect(&ClientRect,CursorPos))) {
01250
ScreenToClient(Console->hWnd,&CursorPos);
01251 MousePosition.X = (
SHORT)CursorPos.x;
01252 MousePosition.Y = (
SHORT)CursorPos.y;
01253
if (ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER) {
01254 MousePosition.X /=
SCR_FONTSIZE(ScreenInfo).X;
01255 MousePosition.Y /=
SCR_FONTSIZE(ScreenInfo).Y;
01256 }
01257 MousePosition.X += ScreenInfo->Window.Left;
01258 MousePosition.Y += ScreenInfo->Window.Top;
01259
01260
ExtendSelection(Console,
01261 MousePosition
01262 );
01263 }
01264 }
01265 }