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

capture.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: capture.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * History: 00007 * 08-Nov-1990 DavidPe Created. 00008 * 01-Feb-1991 MikeKe Added Revalidation code 00009 \***************************************************************************/ 00010 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 /***************************************************************************\ 00015 * xxxSetCapture (API) 00016 * 00017 * This function sets the capture window for the current queue. 00018 * 00019 * History: 00020 * 08-Nov-1990 DavidPe Created. 00021 \***************************************************************************/ 00022 00023 PWND xxxSetCapture( 00024 PWND pwnd) 00025 { 00026 PQ pq; 00027 PWND pwndCaptureOld; 00028 HWND hwndCaptureOld; 00029 PTHREADINFO ptiCurrent = PtiCurrent(); 00030 00031 pq = (PQ)PtiCurrent()->pq; 00032 00033 /* 00034 * If the capture is locked, bail 00035 */ 00036 if (pq->QF_flags & QF_CAPTURELOCKED) { 00037 RIPMSG2(RIP_WARNING, "xxxSetCapture(%#p): Capture is locked. pq:%#p", pwnd, pq); 00038 return NULL; 00039 } 00040 00041 /* 00042 * Don't allow the app to set capture to a window 00043 * from another queue. 00044 */ 00045 if ((pwnd != NULL) && GETPTI(pwnd)->pq != pq) 00046 return NULL; 00047 00048 /* 00049 * If full screen capture don't allow any other capture 00050 */ 00051 if (gspwndScreenCapture) 00052 return NULL; 00053 00054 pwndCaptureOld = pq->spwndCapture; 00055 hwndCaptureOld = HW(pwndCaptureOld); 00056 00057 xxxCapture(ptiCurrent, pwnd, CLIENT_CAPTURE); 00058 00059 if (hwndCaptureOld != NULL) { 00060 00061 if (RevalidateHwnd(hwndCaptureOld)) 00062 return pwndCaptureOld; 00063 } 00064 00065 return NULL; 00066 } 00067 00068 /***************************************************************************\ 00069 * xxxReleaseCapture (API) 00070 * 00071 * This function release the capture for the current queue. 00072 * 00073 * History: 00074 * 08-Nov-1990 DavidPe Created. 00075 * 16-May-1991 MikeKe Changed to return BOOL 00076 \***************************************************************************/ 00077 00078 BOOL xxxReleaseCapture(VOID) 00079 { 00080 PTHREADINFO ptiCurrent = PtiCurrent(); 00081 /* 00082 * If the capture is locked, bail 00083 */ 00084 if (ptiCurrent->pq->QF_flags & QF_CAPTURELOCKED) { 00085 RIPMSG0(RIP_WARNING, "xxxReleaseCapture: Capture is locked"); 00086 return FALSE; 00087 } 00088 00089 /* 00090 * If we're releasing the capture from a window during tracking, 00091 * cancel tracking first. 00092 */ 00093 if (ptiCurrent->pmsd != NULL) { 00094 00095 /* 00096 * Only remove the tracking rectangle if it's 00097 * been made visible. 00098 */ 00099 if (ptiCurrent->TIF_flags & TIF_TRACKRECTVISIBLE) { 00100 00101 bSetDevDragRect(gpDispInfo->hDev, NULL, NULL); 00102 00103 if (!(ptiCurrent->pmsd->fDragFullWindows)) 00104 xxxDrawDragRect(ptiCurrent->pmsd, NULL, DDR_ENDCANCEL); 00105 00106 ptiCurrent->TIF_flags &= ~(TIF_TRACKRECTVISIBLE | TIF_MOVESIZETRACKING); 00107 } 00108 } 00109 00110 xxxCapture(ptiCurrent, NULL, NO_CAP_CLIENT); 00111 00112 return TRUE; 00113 } 00114 00115 /***************************************************************************\ 00116 * xxxCapture 00117 * 00118 * This is the workhorse routine of capture setting and releasing. 00119 * 00120 * History: 00121 * 13-Nov-1990 DavidPe Created. 00122 \***************************************************************************/ 00123 00124 VOID xxxCapture( 00125 PTHREADINFO pti, 00126 PWND pwnd, 00127 UINT code) 00128 { 00129 CheckLock(pwnd); 00130 UserAssert(IsWinEventNotifyDeferredOK()); 00131 00132 if ((gspwndScreenCapture == NULL) || 00133 (code == FULLSCREEN_CAPTURE) || 00134 ((pwnd == NULL) && (code == NO_CAP_CLIENT) && (pti->pq != GETPTI(gspwndScreenCapture)->pq))) { 00135 00136 PQ pq; 00137 PWND pwndCaptureOld = NULL; 00138 00139 if (code == FULLSCREEN_CAPTURE) { 00140 if (pwnd) { 00141 00142 Lock(&gspwndScreenCapture, pwnd); 00143 00144 /* 00145 * We're going full screen so clear the mouse owner 00146 */ 00147 Unlock(&gspwndMouseOwner); 00148 00149 } else { 00150 00151 Unlock(&gspwndScreenCapture); 00152 } 00153 } 00154 00155 /* 00156 * Internal capture works like Win 3.1 capture unlike the NT capture 00157 * which can be lost if the user clicks down on another application 00158 */ 00159 if (code == CLIENT_CAPTURE_INTERNAL) { 00160 Lock(&gspwndInternalCapture, pwnd); 00161 code = CLIENT_CAPTURE; 00162 } 00163 00164 /* 00165 * Free the internal capture if the app (thread) that did the internal 00166 * capture is freeing the capture. 00167 */ 00168 if ((code == NO_CAP_CLIENT) && 00169 gspwndInternalCapture && 00170 (pti == GETPTI(gspwndInternalCapture))) { 00171 00172 Unlock(&gspwndInternalCapture); 00173 } 00174 00175 if ((pq = pti->pq) != NULL) { 00176 PDESKTOP pdesk = pti->rpdesk; 00177 00178 UserAssert(!(pq->QF_flags & QF_CAPTURELOCKED)); 00179 00180 /* 00181 * If someone is tracking mouse events in the client area and 00182 * we're setting or releasing an internal capture mode (!= CLIENT_CAPTURE), 00183 * then cancel tracking -- because we're either taking or relinquishing 00184 * control over the mouse. 00185 */ 00186 if ((pdesk->dwDTFlags & DF_TRACKMOUSEEVENT) 00187 && (pdesk->htEx == HTCLIENT) 00188 && ((pdesk->spwndTrack == pwnd) 00189 && (code != CLIENT_CAPTURE) 00190 || ((pdesk->spwndTrack == pq->spwndCapture) 00191 && (pq->codeCapture != CLIENT_CAPTURE)))) { 00192 00193 BEGINATOMICCHECK(); 00194 xxxCancelMouseMoveTracking(pdesk->dwDTFlags, pdesk->spwndTrack, 00195 pdesk->htEx, DF_TRACKMOUSEEVENT); 00196 ENDATOMICCHECK(); 00197 00198 } 00199 00200 pwndCaptureOld = pq->spwndCapture; 00201 LockCaptureWindow(pq, pwnd); 00202 pq->codeCapture = code; 00203 } else { 00204 /* 00205 * A thread without a queue? 00206 */ 00207 UserAssert(pti->pq != NULL); 00208 } 00209 00210 /* 00211 * If there was a capture window and we're releasing it, post 00212 * a WM_MOUSEMOVE to the window we're over so they can know about 00213 * the current mouse position. 00214 * Defer WinEvent notifications to protect pwndCaptureOld 00215 */ 00216 DeferWinEventNotify(); 00217 00218 if (pwnd == NULL && pwndCaptureOld != NULL) { 00219 #ifdef REDIRECTION 00220 if (!IsGlobalHooked(pti, WHF_FROM_WH(WH_HITTEST))) 00221 #endif 00222 zzzSetFMouseMoved(); 00223 } 00224 00225 if (FWINABLE()) { 00226 if (pwndCaptureOld) { 00227 zzzWindowEvent(EVENT_SYSTEM_CAPTUREEND, pwndCaptureOld, OBJID_WINDOW, 00228 INDEXID_CONTAINER, WEF_USEPWNDTHREAD); 00229 } 00230 00231 if (pwnd) { 00232 zzzWindowEvent(EVENT_SYSTEM_CAPTURESTART, pwnd, OBJID_WINDOW, 00233 INDEXID_CONTAINER, WEF_USEPWNDTHREAD); 00234 } 00235 } 00236 00237 /* 00238 * New for win95 - send WM_CAPTURECHANGED. 00239 * 00240 * The FNID_DELETED_BIT is set in xxxFreeWindow which means we 00241 * DON'T want to send the message. 00242 */ 00243 if (pwndCaptureOld && 00244 TestWF(pwndCaptureOld, WFWIN40COMPAT) && 00245 !(pwndCaptureOld->fnid & FNID_DELETED_BIT)) { 00246 00247 TL tlpwnd; 00248 00249 /* 00250 * If we are in menu mode and just set capture, 00251 * don't let them take it from us during this 00252 * callback. 00253 */ 00254 if ((pti->pMenuState != NULL) && (pwnd != NULL)) { 00255 pq->QF_flags |= QF_CAPTURELOCKED; 00256 } 00257 00258 ThreadLockAlways(pwndCaptureOld, &tlpwnd); 00259 zzzEndDeferWinEventNotify(); 00260 xxxSendMessageCallback(pwndCaptureOld, 00261 WM_CAPTURECHANGED, 00262 FALSE, 00263 (LPARAM)HW(pwnd), 00264 NULL, 00265 0, 00266 FALSE); 00267 /* The thread's queue may have changed during the callback, 00268 * so we need to refresh the local. Bug #377795 00269 */ 00270 pq = pti->pq; 00271 UserAssert(pq != NULL); 00272 ThreadUnlock(&tlpwnd); 00273 00274 /* 00275 * Release the temporary lock, if any 00276 */ 00277 pq->QF_flags &= ~QF_CAPTURELOCKED; 00278 } else { 00279 zzzEndDeferWinEventNotify(); 00280 } 00281 } 00282 }

Generated on Sat May 15 19:39:21 2004 for test by doxygen 1.3.7