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

multimon.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: multimon.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Multimonitor APIs. 00007 * 00008 * History: 00009 * 27-Sep-1996 adams Stub implementation for NT 5. 00010 * 20-Feb-1997 adams Port from NT4 SP3. 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 /* last monitor the cursor was clipped to */ 00017 PMONITOR gpMonitorMouse; 00018 00019 /***************************************************************************\ 00020 * ClipPointToDesktop 00021 * 00022 * Clips the point the nearest monitor on the desktop. 00023 * 00024 * Arguments: 00025 * lppt - The point to clip. 00026 * 00027 * History: 00028 * 22-Sep-1996 adams Created. 00029 * 04-Sep-1998 MCostea Use _MonitorFromPoint() 00030 \***************************************************************************/ 00031 00032 void 00033 ClipPointToDesktop(LPPOINT lppt) 00034 { 00035 PMONITOR pMonitor; 00036 00037 UserAssert(!gpDispInfo->fDesktopIsRect && 00038 "You shouldn't call this function if the desktop is a rectangle.\n" 00039 "Just clip to gpsi->rcScreen instead."); 00040 00041 /* 00042 * Optimization: The cursor is likely to be on the monitor it was last on, 00043 * so check for that case. 00044 */ 00045 if (gpMonitorMouse != NULL && PtInRect(&gpMonitorMouse->rcMonitor, *lppt)) { 00046 return; 00047 } 00048 00049 pMonitor = _MonitorFromPoint(*lppt, MONITOR_DEFAULTTONEAREST); 00050 00051 /* 00052 * Remember the monitor the cursor is on. 00053 */ 00054 gpMonitorMouse = pMonitor; 00055 00056 if (lppt->x < pMonitor->rcMonitor.left) { 00057 lppt->x = pMonitor->rcMonitor.left; 00058 } else if (lppt->x >= pMonitor->rcMonitor.right) { 00059 lppt->x = pMonitor->rcMonitor.right-1; 00060 } 00061 if (lppt->y < pMonitor->rcMonitor.top) { 00062 lppt->y = pMonitor->rcMonitor.top; 00063 } else if (lppt->y >= pMonitor->rcMonitor.bottom) { 00064 lppt->y = pMonitor->rcMonitor.bottom-1; 00065 } 00066 } 00067 00068 /***************************************************************************\ 00069 * xxxEnumDisplayMonitors 00070 * 00071 * Enumerates the monitors in a display. 00072 * 00073 * Arguments: 00074 * hdcPaint - An HDC with a particular visible region. The HDC 00075 * passed to lpfnEnum will have the capabilities of that monitor, 00076 * with its visible region clipped to the monitor and hdcPaint. 00077 * If hdcPaint is NULL, the hdcMonitor passed to lpfnEnum will be NULL. 00078 * 00079 * lprcClip - A rectangle to clip the area to. If hdcPaint is non-NULL, 00080 * the coordinates have the origin of hdcPaint. If hdcPaint is NULL, 00081 * the coordinates are virtual screen coordinates. If lprcClip is NULL, 00082 * no clipping is performed. 00083 * 00084 * lpfnEnum - The enumeration function. 00085 * 00086 * dwData - Application-defined data that is passed through to the 00087 * enumeration function. 00088 * 00089 * fInternal - TRUE if the callback is in the kernel, FALSE otherwise. 00090 * 00091 * BUGBUG: This function is only a skeleton for the real thing. It needs 00092 * to handle different displays and possibly different bit depths. 00093 * 00094 * History: 00095 * 22-Sep-1996 adams Created. 00096 \***************************************************************************/ 00097 00098 BOOL 00099 xxxEnumDisplayMonitors( 00100 HDC hdcPaint, 00101 LPRECT lprcPaint, 00102 MONITORENUMPROC lpfnEnum, 00103 LPARAM lData, 00104 BOOL fInternal) 00105 { 00106 RECT rcPaint; 00107 POINT ptOrg; 00108 RECT rcMonitorPaint; 00109 BOOL fReturn; 00110 PMONITOR pMonitor; 00111 TL tlpMonitor; 00112 PTHREADINFO ptiCurrent = PtiCurrent(); 00113 PDCE pdcePaint; 00114 HDC hdcMonitor; 00115 PWND pwndOrg; 00116 00117 /* 00118 * Validate the DC passed in. 00119 */ 00120 if (hdcPaint) { 00121 00122 if ((pdcePaint = LookupDC(hdcPaint)) == NULL) { 00123 RIPMSG0(RIP_WARNING, "EnumDisplayMonitors: LookupDC failed"); 00124 return FALSE; 00125 } 00126 00127 pwndOrg = pdcePaint->pwndOrg; 00128 00129 /* 00130 * Intersect the painting area with the clipbox. If there 00131 * isn't anything, bail out now. 00132 */ 00133 if (GreGetClipBox(hdcPaint, &rcPaint, FALSE) == NULLREGION) 00134 return TRUE; 00135 00136 if (lprcPaint && !IntersectRect(&rcPaint, &rcPaint, lprcPaint)) 00137 return TRUE; 00138 00139 /* 00140 * rcPaint is in dc coordinates. We must convert to screen 00141 * coords so we can intersect with monitors. 00142 */ 00143 GreGetDCOrg(hdcPaint, &ptOrg); 00144 OffsetRect(&rcPaint, ptOrg.x, ptOrg.y); 00145 } else { 00146 CopyRect(&rcPaint, &gpDispInfo->rcScreen); 00147 if (lprcPaint && !IntersectRect(&rcPaint, &rcPaint, lprcPaint)) 00148 return TRUE; 00149 } 00150 00151 fReturn = TRUE; 00152 00153 for (pMonitor = gpDispInfo->pMonitorFirst; pMonitor != NULL; 00154 pMonitor = pMonitor->pMonitorNext) { 00155 00156 /* 00157 * Note: the check for MONF_VISIBLE was removed to allow mirror drivers 00158 * to see monitor specific updates. 00159 */ 00160 if (!IntersectRect(&rcMonitorPaint, &rcPaint, &pMonitor->rcMonitor)) { 00161 continue; 00162 } 00163 00164 if (hdcPaint) { 00165 00166 if ((hdcMonitor = GetMonitorDC(pdcePaint, pMonitor)) == NULL) { 00167 RIPMSG0(RIP_WARNING, "EnumDisplayMonitors: GetMonitorDC failed"); 00168 return FALSE; 00169 } 00170 00171 OffsetRect(&rcMonitorPaint, -ptOrg.x, -ptOrg.y); 00172 GreIntersectClipRect( 00173 hdcMonitor, 00174 rcMonitorPaint.left, 00175 rcMonitorPaint.top, 00176 rcMonitorPaint.right, 00177 rcMonitorPaint.bottom); 00178 } else { 00179 00180 hdcMonitor = NULL; 00181 } 00182 00183 ThreadLockAlwaysWithPti(ptiCurrent, pMonitor, &tlpMonitor); 00184 00185 if (fInternal) { 00186 fReturn = (*lpfnEnum) ( 00187 (HMONITOR) pMonitor, 00188 hdcMonitor, 00189 &rcMonitorPaint, 00190 lData); 00191 00192 } else { 00193 fReturn = xxxClientMonitorEnumProc( 00194 PtoH(pMonitor), 00195 hdcMonitor, 00196 &rcMonitorPaint, 00197 lData, 00198 lpfnEnum); 00199 } 00200 00201 /* 00202 * We just called back and the monitor has been freed if 00203 * ThreadUnlock returns NULL. The entire monitor configuration may 00204 * have changed, the monitors may have been rearranged, so just stop 00205 * enumerating at this point. 00206 */ 00207 if (ThreadUnlock(&tlpMonitor) == NULL) { 00208 fReturn = FALSE; 00209 } 00210 00211 if (hdcMonitor) 00212 ReleaseCacheDC(hdcMonitor, FALSE); 00213 00214 if (!fReturn) 00215 break; 00216 00217 /* 00218 * Revalidate hdcPaint, since it could have been messed with 00219 * in the callback. 00220 */ 00221 if (hdcPaint) { 00222 if ((pdcePaint = LookupDC(hdcPaint)) == NULL) { 00223 RIPMSG0(RIP_WARNING, "EnumDisplayMonitors: LookupDC failed"); 00224 return FALSE; 00225 } 00226 00227 if (pdcePaint->pwndOrg != pwndOrg) { 00228 RIPMSG0(RIP_WARNING, "EnumDisplayMonitors: wrong window"); 00229 return FALSE; 00230 } 00231 } 00232 } 00233 00234 return fReturn; 00235 } 00236 00237 /***************************************************************************\ 00238 * DestroyMonitor 00239 * 00240 * This function doesn't keep track of the visible monitors count because 00241 * it assumes that after it was called the count will be recalculated, such 00242 * as the case during mode changes. For a final unlock the monitor will have 00243 * been removed from the monitor list already, so the count doesn't need to 00244 * be recalculated. 00245 * 00246 * 5-May-1998 vadimg created 00247 \***************************************************************************/ 00248 00249 void DestroyMonitor(PMONITOR pMonitor) 00250 { 00251 UserAssert(pMonitor); 00252 00253 /* 00254 * Remove references to this monitor from the global data. 00255 */ 00256 if (pMonitor == gpMonitorMouse) { 00257 gpMonitorMouse = NULL; 00258 } 00259 00260 /* 00261 * Remove from the monitor list. 00262 */ 00263 REMOVE_FROM_LIST(MONITOR, gpDispInfo->pMonitorFirst, pMonitor, pMonitorNext); 00264 00265 /* 00266 * Make sure the primary monitor points to a valid monitor. During the 00267 * mode changes the primary monitor will be recalculated as appropriate. 00268 */ 00269 if (pMonitor == gpDispInfo->pMonitorPrimary) { 00270 gpDispInfo->pMonitorPrimary = gpDispInfo->pMonitorFirst; 00271 } 00272 00273 if (HMMarkObjectDestroy(pMonitor)) { 00274 00275 if (pMonitor->hrgnMonitor) { 00276 GreDeleteObject(pMonitor->hrgnMonitor); 00277 } 00278 00279 HMFreeObject(pMonitor); 00280 } 00281 }

Generated on Sat May 15 19:40:53 2004 for test by doxygen 1.3.7