00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
#include "precomp.h"
00017
#pragma hdrstop
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 PCURSOR zzzSetCursor(
00029
PCURSOR pcur)
00030 {
00031
PQ pq;
00032
PCURSOR pcurPrev;
00033
PTHREADINFO ptiCurrent =
PtiCurrent();
00034
00035 pq = ptiCurrent->
pq;
00036
00037 pcurPrev = pq->
spcurCurrent;
00038
00039
if (pq->
spcurCurrent != pcur) {
00040
00041
00042
00043
00044
00045 pcurPrev =
LockQCursor(pq, pcur);
00046
00047
00048
00049
00050
00051
if (
gpqCursor ==
NULL)
00052
gpqCursor = pq;
00053
00054
00055
00056
00057
00058
if (pq ==
gpqCursor) {
00059
TL tlpcur;
00060
ThreadLockWithPti(ptiCurrent, pcurPrev, &tlpcur);
00061
zzzUpdateCursorImage();
00062 pcurPrev =
ThreadUnlock(&tlpcur);
00063 }
00064 }
00065
00066
return pcurPrev;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 BOOL zzzSetCursorPos(
00081
int x,
00082
int y)
00083 {
00084
00085
00086
00087
if (!
CheckWinstaWriteAttributesAccess()) {
00088
return FALSE;
00089 }
00090
00091
zzzInternalSetCursorPos(x, y);
00092
00093
00094
00095
00096
00097
SAVEPOINT(x, y,
00098
SYSMET(CXVIRTUALSCREEN) - 1,
00099
SYSMET(CYVIRTUALSCREEN) - 1,
00100
NtGetTickCount(), 0);
00101
00102
return TRUE;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 VOID zzzInternalSetCursorPos(
00115
int x,
00116
int y
00117 )
00118 {
00119
00120
gptCursorAsync.x = x;
00121
gptCursorAsync.y = y;
00122
00123
BoundCursor(&
gptCursorAsync);
00124
gpsi->ptCursor =
gptCursorAsync;
00125 GreMovePointer(
gpDispInfo->
hDev,
gpsi->ptCursor.x,
gpsi->ptCursor.y);
00126
00127
00128
00129
00130
00131
00132
zzzSetFMouseMoved();
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 VOID IncCursorLevel(
00148
PTHREADINFO pti)
00149 {
00150 pti->
iCursorLevel++;
00151 pti->
pq->
iCursorLevel++;
00152 }
00153
00154 VOID DecCursorLevel(
00155
PTHREADINFO pti)
00156 {
00157 pti->
iCursorLevel--;
00158 pti->
pq->
iCursorLevel--;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 int zzzShowCursor(
00171 BOOL fShow)
00172 {
00173
PTHREADINFO pti =
PtiCurrent();
00174
PQ pq;
00175
int iCursorLevel;
00176
00177 pq = pti->
pq;
00178
00179
00180
00181
DeferWinEventNotify();
00182
00183
if (fShow) {
00184
00185
IncCursorLevel(pti);
00186
00187
if ((pq ==
gpqCursor) && (pq->
iCursorLevel == 0))
00188
zzzUpdateCursorImage();
00189
00190 }
else {
00191
00192
DecCursorLevel(pti);
00193
00194
if ((pq ==
gpqCursor) && (pq->
iCursorLevel == -1))
00195
zzzUpdateCursorImage();
00196 }
00197
00198 iCursorLevel = pq->
iCursorLevel;
00199
zzzEndDeferWinEventNotify();
00200
00201
return iCursorLevel;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 BOOL zzzClipCursor(
00217 LPCRECT prcClip)
00218 {
00219
PEPROCESS Process =
PsGetCurrentProcess();
00220
00221
00222
00223
00224
if (Process !=
gpepCSRSS && !
CheckWinstaWriteAttributesAccess()) {
00225
return FALSE;
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
if (
PtiCurrent()->pq !=
gpqForeground &&
00241 prcClip !=
NULL &&
00242
IsRectEmpty(&
grcCursorClip)) {
00243 RIPERR0(ERROR_ACCESS_DENIED, RIP_WARNING,
"Access denied in _ClipCursor");
00244
return FALSE;
00245 }
00246
00247
if (prcClip ==
NULL) {
00248
00249
grcCursorClip =
gpDispInfo->
rcScreen;
00250
00251 }
else {
00252
00253
00254
00255
00256
00257
grcCursorClip.left =
max(
gpDispInfo->
rcScreen.left , prcClip->left);
00258
grcCursorClip.right =
min(
gpDispInfo->
rcScreen.right , prcClip->right);
00259
grcCursorClip.top =
max(
gpDispInfo->
rcScreen.top , prcClip->top);
00260
grcCursorClip.bottom =
min(
gpDispInfo->
rcScreen.bottom, prcClip->bottom);
00261
00262
00263
00264
00265
if (
grcCursorClip.left >
grcCursorClip.right ||
00266
grcCursorClip.top >
grcCursorClip.bottom) {
00267
00268
grcCursorClip =
gpDispInfo->
rcScreen;
00269 }
00270 }
00271
00272
00273
00274
00275
00276
if (!
PtInRect(&
grcCursorClip,
gpsi->ptCursor)) {
00277
zzzInternalSetCursorPos(
gpsi->ptCursor.x,
gpsi->ptCursor.y);
00278 }
00279
00280
return TRUE;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
#ifdef LOCK_MOUSE_CODE
00296
#pragma alloc_text(MOUSE, BoundCursor)
00297
#endif
00298
00299 VOID BoundCursor(
00300 LPPOINT lppt)
00301 {
00302
if (
TEST_PUDF(
PUDF_VDMBOUNDSACTIVE) &&
gspwndFullScreen !=
NULL) {
00303
00304
if (lppt->x <
grcVDMCursorBounds.left) {
00305 lppt->x =
grcVDMCursorBounds.left;
00306 }
else if (lppt->x >=
grcVDMCursorBounds.right) {
00307 lppt->x =
grcVDMCursorBounds.right - 1;
00308 }
00309
00310
if (lppt->y <
grcVDMCursorBounds.top) {
00311 lppt->y =
grcVDMCursorBounds.top;
00312 }
else if (lppt->y >=
grcVDMCursorBounds.bottom) {
00313 lppt->y =
grcVDMCursorBounds.bottom - 1;
00314 }
00315
00316 }
else {
00317
00318
if (lppt->x <
grcCursorClip.left) {
00319 lppt->x =
grcCursorClip.left;
00320 }
else if (lppt->x >=
grcCursorClip.right) {
00321 lppt->x =
grcCursorClip.right - 1;
00322 }
00323
00324
if (lppt->y <
grcCursorClip.top) {
00325 lppt->y =
grcCursorClip.top;
00326 }
else if (lppt->y >=
grcCursorClip.bottom) {
00327 lppt->y =
grcCursorClip.bottom - 1;
00328 }
00329 }
00330
00331
00332
00333
00334
00335
if (!
gpDispInfo->
fDesktopIsRect) {
00336
ClipPointToDesktop(lppt);
00337 }
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 VOID SetVDMCursorBounds(
00352 LPRECT lprc)
00353 {
00354
if (lprc !=
NULL) {
00355
00356
00357
00358
00359
00360
grcVDMCursorBounds = *lprc;
00361
SET_PUDF(
PUDF_VDMBOUNDSACTIVE);
00362
00363 }
else {
00364
00365
00366
00367
00368
CLEAR_PUDF(
PUDF_VDMBOUNDSACTIVE);
00369 }
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
#if defined (_M_IX86) && (_MSC_VER <= 1100)
00386
#pragma optimize("s", off)
00387
#endif
00388
00389 VOID zzzAnimateCursor(
00390
PWND pwndDummy,
00391 UINT message,
00392 UINT_PTR nID,
00393 LPARAM lParam)
00394 {
00395
int iicur;
00396
PACON pacon;
00397
TL tlpacon;
00398
int LostTime;
00399
int tTime;
00400
00401
pacon = (
PACON)
gpcurLogCurrent;
00402
00403
if (
pacon ==
NULL || !(
pacon->CURSORF_flags &
CURSORF_ACON)) {
00404
gdwLastAniTick = 0;
00405
return;
00406 }
00407
00408
00409
00410
00411
if (
gdwLastAniTick) {
00412
00413 LostTime =
NtGetTickCount() -
gdwLastAniTick -
00414 (
pacon->ajifRate[
pacon->iicur] * 100 / 6);
00415
00416
if (LostTime < 0)
00417 LostTime = 0;
00418
00419 }
else {
00420
00421 LostTime = 0;
00422 }
00423
00424
00425
00426
00427 iicur =
pacon->iicur + 1;
00428
if (iicur >=
pacon->cicur)
00429 iicur = 0;
00430
00431
pacon->iicur = iicur;
00432
00433
00434
00435
00436
ThreadLockAlways(
pacon, &tlpacon);
00437
zzzUpdateCursorImage();
00438
00439 tTime =
pacon->ajifRate[iicur] * 100 / 6;
00440
00441
while (tTime < LostTime) {
00442
00443
00444
00445
00446
00447 LostTime -= tTime;
00448
00449
00450
00451
00452 iicur =
pacon->iicur + 1;
00453
if (iicur >=
pacon->cicur)
00454 iicur = 0;
00455
00456
pacon->iicur = iicur;
00457
00458 tTime =
pacon->ajifRate[iicur] * 100 / 6;
00459 }
00460
ThreadUnlock(&tlpacon);
00461
00462
gdwLastAniTick =
NtGetTickCount() - LostTime;
00463
gidCursorTimer =
InternalSetTimer(
NULL,
gidCursorTimer, tTime - LostTime,
zzzAnimateCursor, TMRF_RIT | TMRF_ONESHOT);
00464
00465
return;
00466
00467
00468 DBG_UNREFERENCED_PARAMETER(pwndDummy);
00469 DBG_UNREFERENCED_PARAMETER(message);
00470 DBG_UNREFERENCED_PARAMETER(nID);
00471 DBG_UNREFERENCED_PARAMETER(lParam);
00472 }
00473
00474
00475
00476
00477
00478
00479 __inline
FCursorShadowed(PCURSINFO pci)
00480 {
00481
return (
TestALPHA(CURSORSHADOW) && (pci->CURSORF_flags & CURSORF_SYSTEM));
00482 }
00483
00484
#if defined (_M_IX86) && (_MSC_VER <= 1100)
00485
#pragma optimize("", on)
00486
#endif
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 VOID zzzUpdateCursorImage()
00497 {
00498
PCURSOR pcurLogNew;
00499
PCURSOR pcurPhysNew;
00500
PACON pacon;
00501
PCURSOR pcurPhysOld;
00502
00503
if (
gpqCursor ==
NULL)
00504
return;
00505
00506
if ((
gpqCursor->
iCursorLevel < 0) || (
gpqCursor->
spcurCurrent ==
NULL)) {
00507
00508 pcurLogNew =
NULL;
00509
00510 }
else {
00511
00512
00513
00514
00515 pcurLogNew =
gpqCursor->
spcurCurrent;
00516
00517
00518
00519
00520
if (
gtimeStartCursorHide != 0) {
00521
00522
if (
gpqCursor->
spcurCurrent ==
SYSCUR(ARROW) ||
00523
gpqCursor->
spcurCurrent ==
SYSCUR(APPSTARTING)) {
00524
00525 pcurLogNew =
SYSCUR(APPSTARTING);
00526 }
00527 }
00528 }
00529
00530
00531
00532
00533
00534
if (pcurLogNew !=
gpcurLogCurrent) {
00535
00536
00537
00538
00539
if (
gtmridAniCursor != 0) {
00540
00541
00542
00543
KILLRITTIMER(
NULL,
gtmridAniCursor);
00544
gtmridAniCursor = 0;
00545 }
00546
00547
00548
00549
00550
if ((pcurLogNew !=
NULL) && (pcurLogNew->CURSORF_flags &
CURSORF_ACON)) {
00551
00552
00553
00554
00555
pacon = (
PACON)pcurLogNew;
00556
pacon->iicur = 0;
00557
00558
gdwLastAniTick =
NtGetTickCount();
00559
00560
00561
00562
00563
00564
gtmridAniCursor =
InternalSetTimer(
NULL,
gtmridAniCursor,
00565
pacon->ajifRate[0] * 100 / 6,
zzzAnimateCursor, TMRF_RIT | TMRF_ONESHOT);
00566 }
00567 }
00568
00569
00570
00571
00572
00573
00574
if (pcurLogNew !=
NULL && pcurLogNew->CURSORF_flags &
CURSORF_ACON) {
00575
00576 pcurPhysNew = ((
PACON)pcurLogNew)->aspcur[((
PACON)pcurLogNew)->
00577 aicur[((
PACON)pcurLogNew)->iicur]];
00578 }
else {
00579
00580 pcurPhysNew = pcurLogNew;
00581 }
00582
00583
00584
00585
00586
gpcurLogCurrent = pcurLogNew;
00587
00588
00589
00590
00591
if (pcurPhysNew !=
gpcurPhysCurrent) {
00592
00593 pcurPhysOld =
gpcurPhysCurrent;
00594
00595
gpcurPhysCurrent = pcurPhysNew;
00596
00597
if (pcurPhysNew ==
NULL) {
00598
00599
SetPointer(
FALSE);
00600
00601 }
else {
00602 ULONG fl = 0;
00603
00604
if (pcurLogNew->CURSORF_flags &
CURSORF_ACON) {
00605 fl |= SPS_ANIMATEUPDATE;
00606 }
00607
if (
FCursorShadowed(
GETPCI(pcurLogNew))) {
00608 fl |= SPS_ALPHA;
00609 }
00610 GreSetPointer(
gpDispInfo->
hDev,
GETPCI(pcurPhysNew), fl);
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
if (
FWINABLE()) {
00620
DWORD event;
00621
00622
00623
00624
00625
00626
00627
00628
00629
if (!pcurPhysNew) {
00630 event = EVENT_OBJECT_HIDE;
00631 }
else if (!pcurPhysOld) {
00632 event = EVENT_OBJECT_SHOW;
00633 }
else {
00634 event = EVENT_OBJECT_NAMECHANGE;
00635 }
00636
zzzWindowEvent(event,
NULL, OBJID_CURSOR, INDEXID_CONTAINER,
WEF_USEPWNDTHREAD);
00637 }
00638 }
00639 }
00640
00641
#if DBG
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
PCURSOR DbgLockQCursor(
00655
PQ pq,
00656
PCURSOR pcur)
00657 {
00658
00659
00660
00661
00662 UserAssertMsg0(!(pq->
QF_flags & QF_INDESTROY),
00663
"LockQCursor: Attempting to lock cursor to freed queue");
00664
00665
return Lock(&pq->
spcurCurrent, pcur);
00666 }
00667
00668
#endif // DBG
00669
00670
00671
00672
00673
00674
00675
00676 void SetPointer(BOOL fSet)
00677 {
00678
if (fSet) {
00679
if (
gpqCursor !=
NULL &&
gpqCursor->
iCursorLevel >= 0 &&
00680
gpqCursor->
spcurCurrent !=
NULL &&
00681
SYSMET(MOUSEPRESENT)) {
00682
00683 PCURSINFO pci =
GETPCI(
gpqCursor->
spcurCurrent);
00684 ULONG fl =
FCursorShadowed(pci) ? SPS_ALPHA : 0;
00685
00686 GreSetPointer(
gpDispInfo->
hDev, pci, fl);
00687 }
00688 }
else {
00689 GreSetPointer(
gpDispInfo->
hDev,
NULL, 0);
00690 }
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 void zzzHideCursorNoCapture()
00702 {
00703
PTHREADINFO ptiCurrent =
PtiCurrentShared();
00704
00705
if (!ptiCurrent->
pq->
spwndCapture && (
GetAppCompatFlags2(
VER40) & GACF2_EDITNOMOUSEHIDE) == 0) {
00706
zzzSetCursor(
NULL);
00707 }
00708 }