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

cursor.c File Reference

#include "precomp.h"

Go to the source code of this file.

Functions

PCURSOR zzzSetCursor (PCURSOR pcur)
BOOL zzzSetCursorPos (int x, int y)
VOID zzzInternalSetCursorPos (int x, int y)
VOID IncCursorLevel (PTHREADINFO pti)
VOID DecCursorLevel (PTHREADINFO pti)
int zzzShowCursor (BOOL fShow)
BOOL zzzClipCursor (LPCRECT prcClip)
VOID BoundCursor (LPPOINT lppt)
VOID SetVDMCursorBounds (LPRECT lprc)
VOID zzzAnimateCursor (PWND pwndDummy, UINT message, UINT_PTR nID, LPARAM lParam)
__inline FCursorShadowed (PCURSINFO pci)
VOID zzzUpdateCursorImage ()
void SetPointer (BOOL fSet)
void zzzHideCursorNoCapture ()


Function Documentation

VOID BoundCursor LPPOINT  lppt  ) 
 

Definition at line 299 of file ntuser/kernel/cursor.c.

References ClipPointToDesktop(), tagDISPLAYINFO::fDesktopIsRect, gpDispInfo, grcCursorClip, grcVDMCursorBounds, gspwndFullScreen, NULL, PUDF_VDMBOUNDSACTIVE, TEST_PUDF, and VOID().

Referenced by xxxMoveEventAbsolute(), zzzActiveCursorTracking(), and zzzInternalSetCursorPos().

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 * If we have more than one monitor, then we need to clip the 00333 * cursor to a point on the desktop. 00334 */ 00335 if (!gpDispInfo->fDesktopIsRect) { 00336 ClipPointToDesktop(lppt); 00337 } 00338 }

VOID DecCursorLevel PTHREADINFO  pti  ) 
 

Definition at line 154 of file ntuser/kernel/cursor.c.

References tagQ::iCursorLevel, tagTHREADINFO::iCursorLevel, tagTHREADINFO::pq, and VOID().

Referenced by zzzShowCursor().

00156 { 00157 pti->iCursorLevel--; 00158 pti->pq->iCursorLevel--; 00159 }

__inline FCursorShadowed PCURSINFO  pci  ) 
 

Definition at line 479 of file ntuser/kernel/cursor.c.

References TestALPHA.

Referenced by SetPointer(), and zzzUpdateCursorImage().

00480 { 00481 return (TestALPHA(CURSORSHADOW) && (pci->CURSORF_flags & CURSORF_SYSTEM)); 00482 }

VOID IncCursorLevel PTHREADINFO  pti  ) 
 

Definition at line 147 of file ntuser/kernel/cursor.c.

References tagQ::iCursorLevel, tagTHREADINFO::iCursorLevel, tagTHREADINFO::pq, and VOID().

Referenced by zzzShowCursor().

00149 { 00150 pti->iCursorLevel++; 00151 pti->pq->iCursorLevel++; 00152 }

void SetPointer BOOL  fSet  ) 
 

Definition at line 676 of file ntuser/kernel/cursor.c.

References FCursorShadowed(), GETPCI, gpDispInfo, gpqCursor, tagDISPLAYINFO::hDev, tagQ::iCursorLevel, NULL, tagQ::spcurCurrent, and SYSMET.

Referenced by xxxMakeWindowForegroundWithState(), xxxRemoteReconnect(), xxxSwitchDesktop(), xxxSystemParametersInfo(), xxxUserChangeDisplaySettings(), xxxUserResetDisplayDevice(), and zzzUpdateCursorImage().

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 }

VOID SetVDMCursorBounds LPRECT  lprc  ) 
 

Definition at line 351 of file ntuser/kernel/cursor.c.

References CLEAR_PUDF, grcVDMCursorBounds, NULL, PUDF_VDMBOUNDSACTIVE, SET_PUDF, and VOID().

Referenced by xxxConsoleControl(), and xxxMakeWindowForegroundWithState().

00353 { 00354 if (lprc != NULL) { 00355 00356 /* 00357 * Set grcVDMCursorBounds before TEST_PUDF(PUDF_VDMBOUNDSACTIVE), because 00358 * MoveEvent() calls BoundCursor() from outside the USER CritSect! 00359 */ 00360 grcVDMCursorBounds = *lprc; 00361 SET_PUDF(PUDF_VDMBOUNDSACTIVE); 00362 00363 } else { 00364 00365 /* 00366 * Turn vdm bounds off. 00367 */ 00368 CLEAR_PUDF(PUDF_VDMBOUNDSACTIVE); 00369 } 00370 }

VOID zzzAnimateCursor PWND  pwndDummy,
UINT  message,
UINT_PTR  nID,
LPARAM  lParam
 

Definition at line 389 of file ntuser/kernel/cursor.c.

References CURSORF_ACON, gdwLastAniTick, gidCursorTimer, gpcurLogCurrent, InternalSetTimer(), NtGetTickCount(), NULL, pacon, ThreadLockAlways, ThreadUnlock, VOID(), zzzAnimateCursor(), and zzzUpdateCursorImage().

Referenced by zzzAnimateCursor(), and zzzUpdateCursorImage().

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 * Find out actual time loss since last update. 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 * Increment the animation index. 00426 */ 00427 iicur = pacon->iicur + 1; 00428 if (iicur >= pacon->cicur) 00429 iicur = 0; 00430 00431 pacon->iicur = iicur; 00432 00433 /* 00434 * This forces the new cursor to be drawn. 00435 */ 00436 ThreadLockAlways(pacon, &tlpacon); 00437 zzzUpdateCursorImage(); 00438 00439 tTime = pacon->ajifRate[iicur] * 100 / 6; 00440 00441 while (tTime < LostTime) { 00442 00443 /* 00444 * Animation is outrunning our ability to render it - skip frames 00445 * to catch up. 00446 */ 00447 LostTime -= tTime; 00448 00449 /* 00450 * Increment the animation index. 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 }

BOOL zzzClipCursor LPCRECT  prcClip  ) 
 

Definition at line 216 of file ntuser/kernel/cursor.c.

References BOOL, CheckWinstaWriteAttributesAccess(), FALSE, gpDispInfo, gpepCSRSS, gpqForeground, gpsi, grcCursorClip, IsRectEmpty(), max, min, NULL, PsGetCurrentProcess, PtiCurrent, PtInRect(), tagDISPLAYINFO::rcScreen, TRUE, and zzzInternalSetCursorPos().

Referenced by NtUserClipCursor(), xxxDWP_DoCancelMode(), xxxMoveSize(), xxxMS_TrackMove(), xxxProcessEventMessage(), xxxResetDisplayDevice(), xxxSetForegroundWindow2(), and xxxTrackInitSize().

00218 { 00219 PEPROCESS Process = PsGetCurrentProcess(); 00220 00221 /* 00222 * Don't let this happen if it doesn't have access. 00223 */ 00224 if (Process != gpepCSRSS && !CheckWinstaWriteAttributesAccess()) { 00225 return FALSE; 00226 } 00227 00228 /* 00229 * The comment from NT 3.51: 00230 * Non-foreground threads can only set the clipping rectangle 00231 * if it was empty, or if they are restoring it to the whole screen. 00232 * 00233 * But the code from NT 3.51 says "IsRectEmpty" instead of 00234 * "!IsRectEmpty", as would follow from the comment. We leave 00235 * the code as it was, as following the comment appears to 00236 * break apps. 00237 * 00238 * CONSIDER: Removing this test altogether after NT4.0 ships. 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 * Never let our cursor leave the screen. Can't use IntersectRect() 00255 * because it doesn't allow rects with 0 width or height. 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 * Check for invalid clip rect. 00264 */ 00265 if (grcCursorClip.left > grcCursorClip.right || 00266 grcCursorClip.top > grcCursorClip.bottom) { 00267 00268 grcCursorClip = gpDispInfo->rcScreen; 00269 } 00270 } 00271 00272 /* 00273 * Update the cursor position if it's currently outside the 00274 * cursor clip-rect. 00275 */ 00276 if (!PtInRect(&grcCursorClip, gpsi->ptCursor)) { 00277 zzzInternalSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y); 00278 } 00279 00280 return TRUE; 00281 }

void zzzHideCursorNoCapture void   ) 
 

Definition at line 701 of file ntuser/kernel/cursor.c.

References GetAppCompatFlags2(), NULL, tagTHREADINFO::pq, PtiCurrentShared, tagQ::spwndCapture, VER40, and zzzSetCursor().

00702 { 00703 PTHREADINFO ptiCurrent = PtiCurrentShared(); 00704 00705 if (!ptiCurrent->pq->spwndCapture && (GetAppCompatFlags2(VER40) & GACF2_EDITNOMOUSEHIDE) == 0) { 00706 zzzSetCursor(NULL); 00707 } 00708 }

VOID zzzInternalSetCursorPos int  x,
int  y
 

Definition at line 114 of file ntuser/kernel/cursor.c.

References BoundCursor(), gpDispInfo, gpsi, gptCursorAsync, tagDISPLAYINFO::hDev, VOID(), and zzzSetFMouseMoved().

Referenced by ResetSharedDesktops(), xxxCallJournalPlaybackHook(), xxxMakeWindowForegroundWithState(), xxxMoveSize(), xxxMS_TrackMove(), xxxSwitchDesktop(), xxxUserResetDisplayDevice(), zzzActiveCursorTracking(), zzzClipCursor(), and zzzSetCursorPos().

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 * Cursor has changed position, so generate a mouse event so the 00129 * window underneath the new location knows it's there and sets the 00130 * shape accordingly. 00131 */ 00132 zzzSetFMouseMoved(); 00133 }

PCURSOR zzzSetCursor PCURSOR  pcur  ) 
 

Definition at line 28 of file ntuser/kernel/cursor.c.

References gpqCursor, LockQCursor, NULL, tagTHREADINFO::pq, PtiCurrent, tagQ::spcurCurrent, ThreadLockWithPti, ThreadUnlock, and zzzUpdateCursorImage().

Referenced by NtUserSetCursor(), xxxDragObject(), xxxDWP_SetCursor(), xxxHelpLoop(), xxxMoveSize(), xxxScanSysQueue(), xxxSwitchWndProc(), xxxTrackInitSize(), and zzzHideCursorNoCapture().

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 * Lock() returns pobjOld - if it is still valid. Don't want to 00043 * return a pcurPrev that is an invalid pointer. 00044 */ 00045 pcurPrev = LockQCursor(pq, pcur); 00046 00047 /* 00048 * If no thread 'owns' the cursor, we must be in initialization 00049 * so go ahead and assign it to ourself. 00050 */ 00051 if (gpqCursor == NULL) 00052 gpqCursor = pq; 00053 00054 /* 00055 * If we're changing the local-cursor for the thread currently 00056 * representing the global-cursor, update the cursor image now. 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 }

BOOL zzzSetCursorPos int  x,
int  y
 

Definition at line 80 of file ntuser/kernel/cursor.c.

References BOOL, CheckWinstaWriteAttributesAccess(), FALSE, NtGetTickCount(), SAVEPOINT, SYSMET, TRUE, and zzzInternalSetCursorPos().

00083 { 00084 /* 00085 * Blow it off if the caller doesn't have the proper access rights 00086 */ 00087 if (!CheckWinstaWriteAttributesAccess()) { 00088 return FALSE; 00089 } 00090 00091 zzzInternalSetCursorPos(x, y); 00092 00093 /* 00094 * Save the absolute coordinates in the global array 00095 * for GetMouseMovePointsEx. 00096 */ 00097 SAVEPOINT(x, y, 00098 SYSMET(CXVIRTUALSCREEN) - 1, 00099 SYSMET(CYVIRTUALSCREEN) - 1, 00100 NtGetTickCount(), 0); 00101 00102 return TRUE; 00103 }

int zzzShowCursor BOOL  fShow  ) 
 

Definition at line 170 of file ntuser/kernel/cursor.c.

References DecCursorLevel(), DeferWinEventNotify, gpqCursor, tagQ::iCursorLevel, IncCursorLevel(), tagTHREADINFO::pq, PtiCurrent, zzzEndDeferWinEventNotify, and zzzUpdateCursorImage().

Referenced by xxxDragObject(), and xxxMoveSize().

00172 { 00173 PTHREADINFO pti = PtiCurrent(); 00174 PQ pq; 00175 int iCursorLevel; 00176 00177 pq = pti->pq; 00178 /* 00179 * To preserve pq 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 }

VOID zzzUpdateCursorImage  ) 
 

Definition at line 496 of file ntuser/kernel/cursor.c.

References CURSORF_ACON, DWORD, FALSE, FCursorShadowed(), FWINABLE, gdwLastAniTick, GETPCI, gpcurLogCurrent, gpcurPhysCurrent, gpDispInfo, gpqCursor, gtimeStartCursorHide, gtmridAniCursor, tagDISPLAYINFO::hDev, tagQ::iCursorLevel, InternalSetTimer(), KILLRITTIMER, NtGetTickCount(), NULL, pacon, SetPointer(), tagQ::spcurCurrent, SYSCUR, VOID(), WEF_USEPWNDTHREAD, zzzAnimateCursor(), and zzzWindowEvent.

Referenced by xxxUserChangeDisplaySettings(), zzzAnimateCursor(), zzzCalcStartCursorHide(), zzzSetCursor(), zzzSetFMouseMoved(), zzzSetSystemImage(), and zzzShowCursor().

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 * Assume we're using the current cursor. 00514 */ 00515 pcurLogNew = gpqCursor->spcurCurrent; 00516 00517 /* 00518 * Check to see if we should use the "app starting" cursor. 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 * If the logical cursor is changing then start/stop the cursor 00532 * animation timer as appropriate. 00533 */ 00534 if (pcurLogNew != gpcurLogCurrent) { 00535 00536 /* 00537 * If the old cursor was animating, shut off the animation timer. 00538 */ 00539 if (gtmridAniCursor != 0) { 00540 /* 00541 * Disable animation. 00542 */ 00543 KILLRITTIMER(NULL, gtmridAniCursor); 00544 gtmridAniCursor = 0; 00545 } 00546 00547 /* 00548 * If the new cursor is animated, start the animation timer. 00549 */ 00550 if ((pcurLogNew != NULL) && (pcurLogNew->CURSORF_flags & CURSORF_ACON)) { 00551 00552 /* 00553 * Start the animation over from the beginning. 00554 */ 00555 pacon = (PACON)pcurLogNew; 00556 pacon->iicur = 0; 00557 00558 gdwLastAniTick = NtGetTickCount(); 00559 00560 /* 00561 * Use the rate table to keep the timer on track. 00562 * 1 Jiffy = 1/60 sec = 100/6 ms 00563 */ 00564 gtmridAniCursor = InternalSetTimer(NULL, gtmridAniCursor, 00565 pacon->ajifRate[0] * 100 / 6, zzzAnimateCursor, TMRF_RIT | TMRF_ONESHOT); 00566 } 00567 } 00568 00569 /* 00570 * If this is an animated cursor, find and use the current frame 00571 * of the animation. NOTE: this is done AFTER the AppStarting 00572 * business so the AppStarting cursor itself can be animated. 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 * Remember the new logical cursor. 00585 */ 00586 gpcurLogCurrent = pcurLogNew; 00587 00588 /* 00589 * If the physical cursor is changing then update screen. 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 * Notify anyone who cares about the change 00615 * This can happen on the RIT, so we need to pass on the real 00616 * thread/process ID. Hence we use hwndCursor. 00617 * This comment is from WIn'95 so it may not be true - IanJa. 00618 */ 00619 if (FWINABLE()) { 00620 DWORD event; 00621 /* 00622 * These are the events we send: 00623 * hcurPhys now NULL -> EVENT_OBJECT_HIDE 00624 * hcurPhys was NULL -> EVENT_OBJECT_SHOW 00625 * hcurPhys changing -> EVENT_OBJECT_NAMECHANGE 00626 * Since we only go through this code if hcurPhys is actually 00627 * changing, these checks are simple. 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 }


Generated on Sat May 15 19:43:23 2004 for test by doxygen 1.3.7