test: caret.c File Reference

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

# caret.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Functions

BOOL | UT_CaretSet (PWND pwnd)
void | UT_InvertCaret ()
void | zzzInternalDestroyCaret ()
BOOL | zzzDestroyCaret ()
BOOL | xxxCreateCaret (PWND pwnd, HBITMAP hBitmap, int cx, int cy)
void | zzzInternalShowCaret ()
void | zzzInternalHideCaret ()
BOOL | zzzShowCaret (PWND pwnd)
BOOL | zzzHideCaret (PWND pwnd)
VOID | CaretBlinkProc (PWND pwnd, UINT message, UINT_PTR id, LPARAM lParam)
BOOL | _SetCaretBlinkTime (UINT cmsBlink)
BOOL | zzzSetCaretPos (int x, int y)

## Function Documentation

BOOL _SetCaretBlinkTime | ( | UINT | cmsBlink | ) |

Definition at line 513 of file caret.c.

References _KillSystemTimer(), _SetSystemTimer(), BOOL, tagQ::caret, CaretBlinkProc(), CheckWinstaWriteAttributesAccess(), FALSE, gpsi, tagCARET::hTimer, IDSYS_CARET, tagTHREADINFO::pq, PtiCurrent, tagCARET::spwnd, and TRUE.

Referenced by xxxUpdatePerUserSystemParameters().

    00515 {
    00516     PQ pq;
    00517     PTHREADINFO  ptiCurrent = PtiCurrent();
    00518
    00519     /*
    00520      * Blow it off if the caller doesn't have the proper access rights
    00521      */
    00522     if (!CheckWinstaWriteAttributesAccess()) {
    00523         return FALSE;
    00524     }
    00525
    00526     gpsi->dtCaretBlink = cmsBlink;
    00527
    00528     pq = ptiCurrent->pq;
    00529
    00530     if (pq->caret.spwnd) {
    00531         _KillSystemTimer(pq->caret.spwnd, IDSYS_CARET);
    00532         pq->caret.hTimer = _SetSystemTimer(pq->caret.spwnd, IDSYS_CARET,
    00533             gpsi->dtCaretBlink, CaretBlinkProc);
    00534     }
    00535
    00536     return TRUE;
    00537 }

VOID CaretBlinkProc | ( | PWND | pwnd,
|  | UINT | message,
|  | UINT_PTR | id,
|  | LPARAM | lParam
| ) |

Definition at line 454 of file caret.c.

References _KillSystemTimer(), tagQ::caret, tagCARET::fOn, tagCARET::fVisible, gbRemoteSession, gpsi, IDSYS_CARET, tagCARET::iHideLevel, PtiCurrent, tagCARET::spwnd, UT_InvertCaret(), and VOID().

Referenced by _SetCaretBlinkTime(), xxxCreateCaret(), and zzzSetCaretPos().

    00459 {
    00460     PQ pq;
    00461
    00462     /*
    00463      * If this window doesn't even have a timer, just return.  TRUE is
    00464      * returned, which gets returned from DispatchMessage().  Why? Because
    00465      * it is compatible with Win3.
    00466      */
    00467     pq = PtiCurrent()->pq;
    00468     if (pwnd != pq->caret.spwnd)
    00469         return;
    00470
    00471     /*
    00472      * leave caret on, don't blink it off for remote sessions
    00473      */
    00474
    00475     if (gbRemoteSession && (gpsi->dtCaretBlink >= 1200) && pq->caret.fOn && pq->caret.fVisible) {
    00476
    00477         /*
    00478          * Kill the timer for performance
    00479          */
    00480         _KillSystemTimer(pq->caret.spwnd, IDSYS_CARET);
    00481         return;
    00482     }
    00483
    00484     /*
    00485      * Flip the logical cursor state.  If the hide level permits it, flip
    00486      * the physical state and draw the caret.
    00487      */
    00488     pq->caret.fOn ^= 1;
    00489     if (pq->caret.iHideLevel == 0) {
    00490         pq->caret.fVisible ^= 1;
    00491         UT_InvertCaret();
    00492     }
    00493
    00494     return;
    00495
    00496     DBG_UNREFERENCED_PARAMETER(message);
    00497     DBG_UNREFERENCED_PARAMETER(id);
    00498     DBG_UNREFERENCED_PARAMETER(lParam);
    00499 }

BOOL UT_CaretSet | ( | PWND | pwnd | ) |

Definition at line 28 of file caret.c.

References BOOL, tagQ::caret, FALSE, NULL, tagTHREADINFO::ppi, tagTHREADINFO::pq, PtiCurrent, PtiFromThreadId(), tagCARET::spwnd, tagCARET::tid, TIDq, TIF_16BIT, tagTHREADINFO::TIF_flags, and TRUE.

Referenced by zzzDestroyCaret(), zzzHideCaret(), zzzSetCaretPos(), and zzzShowCaret().

    00030 {
    00031     PQ pq;
    00032     PTHREADINFO ptiCurrent;
    00033
    00034     /*
    00035      * Current queue have a caret? If not, return FALSE.
    00036      */
    00037     ptiCurrent = PtiCurrent();
    00038     pq = ptiCurrent->pq;
    00039
    00040     if (pq->caret.spwnd == NULL) {
    00041         RIPERR0(ERROR_ACCESS_DENIED,
    00042                 RIP_VERBOSE,
    00043                 "Access denied in UT_CaretSet to current queue's caret");
    00044
    00045         return FALSE;
    00046     }
    00047
    00048     /*
    00049      * If the current task does not own the caret, then return FALSE
    00050      * but we let 32 bit multithreaded apps set the caret position from
    00051      * a second thread for compatibility to our NT 3.1 BETAs
    00052      */
    00053     if (pq->caret.tid != TIDq(ptiCurrent)) {
    00054         PTHREADINFO ptiCursorOwner;
    00055
    00056         ptiCursorOwner = PtiFromThreadId(pq->caret.tid);
    00057
    00058         if ((ptiCurrent->TIF_flags & TIF_16BIT) || ptiCursorOwner == NULL ||
    00059                 (ptiCurrent->ppi != ptiCursorOwner->ppi))  {
    00060             RIPERR0(ERROR_ACCESS_DENIED,
    00061                     RIP_VERBOSE,
    00062                     "Access denied in UT_CaretSet");
    00063
    00064             return FALSE;
    00065         }
    00066     }
    00067
    00068     /*
    00069      * If pwnd == NULL, just checking to see if current queue has caret.
    00070      * It does, so return TRUE.
    00071      */
    00072     if (pwnd == NULL)
    00073         return TRUE;
    00074
    00075     /*
    00076      * pwnd != NULL.  Check to see if the caret is for pwnd.  If so, return
    00077      * TRUE.
    00078      */
    00079     if (pwnd == pq->caret.spwnd)
    00080         return TRUE;
    00081
    00082     return FALSE;
    00083 }

void UT_InvertCaret | ( |  | ) |

Definition at line 94 of file caret.c.

References _ExcludeUpdateRgn(), _GetDC(), _ReleaseDC(), BOOL, tagQ::caret, tagCARET::cx, tagCARET::cy, FALSE, tagCARET::fVisible, ghbrWhite, ghdcMem, gpsi, tagCARET::hBitmap, tagWND::hrgnUpdate, IsVisible(), NULL, PtiCurrent, tagCARET::spwnd, TestWF, TRUE, WFWIN31COMPAT, tagCARET::x, and tagCARET::y.

Referenced by CaretBlinkProc(), zzzInternalHideCaret(), zzzInternalShowCaret(), and zzzSetCaretPos().

    00095 {
    00096     HDC hdc;
    00097     PWND pwnd;
    00098     PQ pq;
    00099     HBITMAP hbmSave;
    00100     BOOL fRestore;
    00101
    00102     pq = PtiCurrent()->pq;
    00103     pwnd = pq->caret.spwnd;
    00104
    00105
    00106     if (pwnd == NULL || !IsVisible(pwnd)) {
    00107         pq->caret.fVisible = FALSE;
    00108         return;
    00109     }
    00110
    00111     /*
    00112      * Don't have a dc.  Get one for this window and draw the caret.
    00113      */
    00114     hdc = _GetDC(pwnd);
    00115
    00116     if (fRestore = (pwnd->hrgnUpdate ? TRUE : FALSE)) {
    00117         GreSaveDC(hdc);
    00118         if (TestWF(pwnd, WFWIN31COMPAT))
    00119             _ExcludeUpdateRgn(hdc, pwnd);
    00120     }
    00121
    00122     /*
    00123      * If the caret bitmap is NULL, the caret is a white pattern invert
    00124      * If the caret bitmap is == 1, the caret is a gray pattern.
    00125      * If the caret bitmap is  > 1, the caret is really a bitmap.
    00126      */
    00127     if ((pq->caret.hBitmap) > (HBITMAP)1) {
    00128
    00129         /*
    00130          * The caret is a bitmap...  SRCINVERT it onto the screen.
    00131          */
    00132         hbmSave = GreSelectBitmap(ghdcMem, pq->caret.hBitmap);
    00133         GreBitBlt(hdc, pq->caret.x, pq->caret.y, pq->caret.cx,
    00134               pq->caret.cy, ghdcMem, 0, 0, SRCINVERT, 0);
    00135
    00136         GreSelectBitmap(ghdcMem, hbmSave);
    00137
    00138     } else {
    00139
    00140         POLYPATBLT PolyData;
    00141
    00142         /*
    00143          * The caret is a pattern (gray or white).  PATINVERT it onto the
    00144          * screen.  Remember to unrealize the gray object so it aligns
    00145          * to the window correctly.
    00146          *
    00147          * Remove call to UnrealizeObject.  GDI handles this on NT for
    00148          * brushes.
    00149          *
    00150          * UnrealizeObject(hbrGray);
    00151          */
    00152         PolyData.x  = pq->caret.x;
    00153         PolyData.y  = pq->caret.y;
    00154         PolyData.cx = pq->caret.cx;
    00155         PolyData.cy = pq->caret.cy;
    00156
    00157         if ((pq->caret.hBitmap) == (HBITMAP)1) {
    00158             //hbrSave = GreSelectBrush(hdc, ghbrGray);
    00159             PolyData.BrClr.hbr = gpsi->hbrGray;
    00160         } else {
    00161             //hbrSave = GreSelectBrush(hdc, ghbrWhite);
    00162             PolyData.BrClr.hbr = ghbrWhite;
    00163         }
    00164
    00165         GrePolyPatBlt(hdc,PATINVERT,&PolyData,1,PPB_BRUSH);
    00166
    00167         //GrePatBlt(hdc, pq->caret.x, pq->caret.y, pq->caret.cx, pq->caret.cy,
    00168         //        PATINVERT);
    00169         //
    00170         //GreSelectBrush(hdc,hbrSave);
    00171     }
    00172
    00173     if (fRestore)
    00174         GreRestoreDC(hdc, -1);
    00175
    00176     _ReleaseDC(hdc);
    00177 }

BOOL xxxCreateCaret | ( | PWND | pwnd,
|  | HBITMAP | hBitmap,
|  | int | cx,
|  | int | cy
| ) |

Definition at line 254 of file caret.c.

References _SetSystemTimer(), BOOL, tagQ::caret, CaretBlinkProc(), CheckLock, tagCARET::cx, cy, tagCARET::cy, DeferWinEventNotify, FALSE, tagCARET::fOn, tagCARET::fVisible, FWINABLE, GETPTI, gpsi, tagCARET::hBitmap, tagCARET::hTimer, IDSYS_CARET, tagCARET::iHideLevel, IsWinEventNotifyDeferredOK, Lock, NULL, tagTHREADINFO::pq, PtiCurrent, tagCARET::spwnd, SYSMET, tagCARET::tid, TIDq, TRUE, xxxWindowEvent(), zzzEndDeferWinEventNotify, and zzzInternalDestroyCaret().

Referenced by NtUserCreateCaret(), and xxxSBWndProc().

    00259 {
    00260     PQ pq;
    00261     BITMAP bitmap;
    00262     PTHREADINFO  ptiCurrent = PtiCurrent();
    00263
    00264     CheckLock(pwnd);
    00265     UserAssert(IsWinEventNotifyDeferredOK());
    00266
    00267     pq = ptiCurrent->pq;
    00268
    00269     /*
    00270      * Don't allow the app to create a caret in a window
    00271      * from another queue.
    00272      */
    00273     if (GETPTI(pwnd)->pq != pq) {
    00274         return FALSE;
    00275     }
    00276
    00277     /*
    00278      * Defer WinEvent notifications to preserve pq
    00279      */
    00280     DeferWinEventNotify();
    00281
    00282     if (pq->caret.spwnd != NULL)
    00283         zzzInternalDestroyCaret();
    00284
    00285     Lock(&pq->caret.spwnd, pwnd);
    00286     pq->caret.iHideLevel = 1;
    00287     pq->caret.fOn = TRUE;
    00288     pq->caret.fVisible = FALSE;
    00289     pq->caret.tid = TIDq(ptiCurrent);
    00290
    00291     if (cy == 0)
    00292         cy = SYSMET(CYBORDER);
    00293     if (cx == 0)
    00294         cx = SYSMET(CXBORDER);
    00295
    00296     if ((pq->caret.hBitmap = hBitmap) > (HBITMAP)1) {
    00297         GreExtGetObjectW(hBitmap, sizeof(BITMAP), &bitmap);
    00298         cy = bitmap.bmHeight;
    00299         cx = bitmap.bmWidth;
    00300     }
    00301
    00302     pq->caret.cy = cy;
    00303     pq->caret.cx = cx;
    00304
    00305     pq->caret.hTimer = _SetSystemTimer(pwnd, IDSYS_CARET, gpsi->dtCaretBlink,
    00306             CaretBlinkProc);
    00307
    00308     UserAssert(pwnd == pq->caret.spwnd);
    00309     zzzEndDeferWinEventNotify();
    00310     if (FWINABLE()) {
    00311         /*
    00312          * It's best to force this routine to be an xxx routine: that way we can
    00313          * force pwnd to be locked and force notifications from within this routine
    00314          * and all of the callers are happy with this.
    00315          */
    00316         xxxWindowEvent(EVENT_OBJECT_CREATE, pwnd, OBJID_CARET, INDEXID_CONTAINER, 0);
    00317     }
    00318
    00319     return TRUE;
    00320 }

BOOL zzzDestroyCaret | ( |  | ) |

Definition at line 234 of file caret.c.

References BOOL, FALSE, NULL, TRUE, UT_CaretSet(), and zzzInternalDestroyCaret().

Referenced by xxxCheckFocus(), and xxxSBWndProc().

    00235 {
    00236     if (UT_CaretSet(NULL)) {
    00237         zzzInternalDestroyCaret();
    00238         return TRUE;
    00239     }
    00240     return FALSE;
    00241 }

BOOL zzzHideCaret | ( | PWND | pwnd | ) |

Definition at line 434 of file caret.c.

References BOOL, FALSE, TRUE, UT_CaretSet(), and zzzInternalHideCaret().

Referenced by NtUserHideCaret(), and xxxSBWndProc().

    00436 {
    00437     if (UT_CaretSet(pwnd)) {
    00438         zzzInternalHideCaret();
    00439         return TRUE;
    00440     }
    00441     return FALSE;
    00442 }

void zzzInternalDestroyCaret | ( |  | ) |

Definition at line 189 of file caret.c.

References _KillSystemTimer(), tagQ::caret, FWINABLE, tagCARET::hBitmap, tagCARET::hTimer, IDSYS_CARET, tagCARET::iHideLevel, NULL, tagTHREADINFO::pq, PtiCurrent, tagCARET::spwnd, ThreadLockWithPti, ThreadUnlock, Unlock, zzzInternalHideCaret(), and zzzWindowEvent.

Referenced by xxxCreateCaret(), xxxDestroyWindow(), and zzzDestroyCaret().

    00190 {
    00191     PQ pq;
    00192     PTHREADINFO ptiCurrent = PtiCurrent();
    00193     PWND pwndCaret;
    00194     TL tlpwndCaret;
    00195
    00196     /*
    00197      * Hide the caret, kill the timer, and null out the caret structure.
    00198      */
    00199     zzzInternalHideCaret();
    00200     pq = ptiCurrent->pq;
    00201     _KillSystemTimer(pq->caret.spwnd, IDSYS_CARET);
    00202
    00203     pq->caret.hTimer = 0;
    00204     pq->caret.hBitmap = NULL;
    00205     pq->caret.iHideLevel = 0;
    00206
    00207     pwndCaret = pq->caret.spwnd;
    00208     if (pwndCaret != NULL) {
    00209         /*
    00210          * Threadlock caret's spwnd for WinEvent notification below
    00211          */
    00212         ThreadLockWithPti(ptiCurrent, pwndCaret, &tlpwndCaret);
    00213         Unlock(&pq->caret.spwnd);
    00214
    00215         if (FWINABLE()) {
    00216             zzzWindowEvent(EVENT_OBJECT_DESTROY, pwndCaret, OBJID_CARET, INDEXID_CONTAINER, 0);
    00217         }
    00218
    00219         ThreadUnlock(&tlpwndCaret);
    00220     }
    00221 }

void zzzInternalHideCaret | ( |  | ) |

Definition at line 376 of file caret.c.

References tagQ::caret, FALSE, tagCARET::fVisible, FWINABLE, tagCARET::iHideLevel, tagTHREADINFO::pq, PtiCurrent, tagCARET::spwnd, UT_InvertCaret(), and zzzWindowEvent.

Referenced by xxxBeginPaint(), xxxScrollWindowEx(), zzzHideCaret(), and zzzInternalDestroyCaret().

    00377 {
    00378     PQ pq;
    00379     PTHREADINFO ptiCurrent = PtiCurrent();
    00380
    00381     pq = ptiCurrent->pq;
    00382
    00383     /*
    00384      * If the caret is physically visible, invert it to turn off the bits.
    00385      * Adjust the hide count upwards to remember this hide level.
    00386      */
    00387     if (pq->caret.fVisible)
    00388         UT_InvertCaret();
    00389
    00390     pq->caret.fVisible = FALSE;
    00391     pq->caret.iHideLevel++;
    00392
    00393     /*
    00394      * Is the caret transitioning to being hidden?  If so, iHideLevel is
    00395      * going from 0 to 1.
    00396      */
    00397     if (FWINABLE() && (pq->caret.iHideLevel == 1)) {
    00398         zzzWindowEvent(EVENT_OBJECT_HIDE, pq->caret.spwnd, OBJID_CARET, INDEXID_CONTAINER, 0);
    00399     }
    00400 }

void zzzInternalShowCaret | ( |  | ) |

Definition at line 331 of file caret.c.

References tagQ::caret, tagCARET::fOn, tagCARET::fVisible, FWINABLE, tagCARET::iHideLevel, tagTHREADINFO::pq, PtiCurrent, tagCARET::spwnd, UT_InvertCaret(), and zzzWindowEvent.

Referenced by xxxEndPaint(), xxxScrollWindowEx(), and zzzShowCaret().

    00332 {
    00333     PQ pq;
    00334     PTHREADINFO ptiCurrent = PtiCurrent();
    00335
    00336     pq = ptiCurrent->pq;
    00337
    00338     /*
    00339      * If the caret hide level is aleady 0 (meaning it's ok to show) and the
    00340      * caret is not physically on, try to invert now if it's turned on.
    00341      */
    00342     if (pq->caret.iHideLevel == 0) {
    00343         if (!pq->caret.fVisible) {
    00344             if ((pq->caret.fVisible = pq->caret.fOn) != 0) {
    00345                 UT_InvertCaret();
    00346             }
    00347         }
    00348         return;
    00349     }
    00350
    00351     /*
    00352      * Adjust the hide caret hide count.  If we hit 0, we can show the
    00353      * caret.  Try to invert it if it's turned on.
    00354      */
    00355
    00356     if (--pq->caret.iHideLevel == 0) {
    00357         if ((pq->caret.fVisible = pq->caret.fOn) != 0)
    00358             UT_InvertCaret();
    00359
    00360         if (FWINABLE()) {
    00361             zzzWindowEvent(EVENT_OBJECT_SHOW, pq->caret.spwnd, OBJID_CARET, INDEXID_CONTAINER, 0);
    00362         }
    00363     }
    00364 }

BOOL zzzSetCaretPos | ( | int | x,
|  | int | y
| ) |

Definition at line 550 of file caret.c.

References _KillSystemTimer(), _SetSystemTimer(), BOOL, tagQ::caret, CaretBlinkProc(), FALSE, tagCARET::fOn, tagCARET::fVisible, FWINABLE, gpsi, tagCARET::hTimer, IDSYS_CARET, tagCARET::iHideLevel, NULL, tagTHREADINFO::pq, PtiCurrent, tagCARET::spwnd, TRUE, UT_CaretSet(), UT_InvertCaret(), tagCARET::x, tagCARET::y, and zzzWindowEvent.

Referenced by zzzSetSBCaretPos().

    00553 {
    00554     PQ pq;
    00555     PTHREADINFO  ptiCurrent = PtiCurrent();
    00556
    00557     /*
    00558      * If this thread does not have the caret set, return FALSE.
    00559      */
    00560     if (!UT_CaretSet(NULL)) {
    00561         RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, "Access denied in zzzSetCaretPos");
    00562         return FALSE;
    00563     }
    00564
    00565     /*
    00566      * If the caret isn't changing position, do nothing (but return success).
    00567      */
    00568     pq = ptiCurrent->pq;
    00569     if (pq->caret.x == x && pq->caret.y == y)
    00570         return TRUE;
    00571
    00572     /*
    00573      * If the caret is visible, turn it off while we move it.
    00574      */
    00575     if (pq->caret.fVisible)
    00576         UT_InvertCaret();
    00577
    00578     /*
    00579      * Adjust to the new position.
    00580      */
    00581     pq->caret.x = x;
    00582     pq->caret.y = y;
    00583
    00584     /*
    00585      * Set a new timer so it'll blink in the new position dtCaretBlink
    00586      * milliseconds from now.
    00587      */
    00588     _KillSystemTimer(pq->caret.spwnd, IDSYS_CARET);
    00589     pq->caret.hTimer = _SetSystemTimer(pq->caret.spwnd, IDSYS_CARET,
    00590             gpsi->dtCaretBlink, CaretBlinkProc);
    00591
    00592     pq->caret.fOn = TRUE;
    00593
    00594     /*
    00595      * Draw it immediately now if the hide level permits it.
    00596      */
    00597     pq->caret.fVisible = FALSE;
    00598     if (pq->caret.iHideLevel == 0) {
    00599         pq->caret.fVisible = TRUE;
    00600         UT_InvertCaret();
    00601     }
    00602
    00603     if (FWINABLE()) {
    00604         zzzWindowEvent(EVENT_OBJECT_LOCATIONCHANGE, pq->caret.spwnd, OBJID_CARET, INDEXID_CONTAINER, 0);
    00605     }
    00606
    00607     return TRUE;
    00608 }

BOOL zzzShowCaret | ( | PWND | pwnd | ) |

Definition at line 413 of file caret.c.

References BOOL, FALSE, TRUE, UT_CaretSet(), and zzzInternalShowCaret().

Referenced by NtUserShowCaret(), xxxEndScroll(), xxxSBTrackInit(), and xxxSBWndProc().

    00415 {
    00416     if (UT_CaretSet(pwnd)) {
    00417         zzzInternalShowCaret();
    00418         return TRUE;
    00419     }
    00420     return FALSE;
    00421 }