Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendcstate.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Win32k subsystem 00004 * PURPOSE: Functions for saving and restoring dc states 00005 * FILE: subsystems/win32/win32k/objects/dcstate.c 00006 * PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org) 00007 */ 00008 00009 #include <win32k.h> 00010 00011 #define NDEBUG 00012 #include <debug.h> 00013 00014 VOID 00015 FASTCALL 00016 DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To) 00017 { 00018 DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr); 00019 00020 /* Copy full DC attribute */ 00021 *pdcDst->pdcattr = *pdcSrc->pdcattr; 00022 00023 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ 00024 /* The VisRectRegion field needs to be set to a valid state */ 00025 00026 /* Mark some fields as dirty */ 00027 pdcDst->pdcattr->ulDirty_ |= (DIRTY_FILL|DIRTY_LINE|DIRTY_TEXT|DIRTY_BACKGROUND|DIRTY_CHARSET|DC_ICM_NOT_CALIBRATED|DC_ICM_NOT_SET); // Note: Use if, To is FALSE.... 00028 00029 /* Copy DC level */ 00030 pdcDst->dclevel.pColorSpace = pdcSrc->dclevel.pColorSpace; 00031 pdcDst->dclevel.lSaveDepth = pdcSrc->dclevel.lSaveDepth; 00032 pdcDst->dclevel.hdcSave = pdcSrc->dclevel.hdcSave; 00033 pdcDst->dclevel.laPath = pdcSrc->dclevel.laPath; 00034 pdcDst->dclevel.ca = pdcSrc->dclevel.ca; 00035 pdcDst->dclevel.mxWorldToDevice = pdcSrc->dclevel.mxWorldToDevice; 00036 pdcDst->dclevel.mxDeviceToWorld = pdcSrc->dclevel.mxDeviceToWorld; 00037 pdcDst->dclevel.mxWorldToPage = pdcSrc->dclevel.mxWorldToPage; 00038 pdcDst->dclevel.efM11PtoD = pdcSrc->dclevel.efM11PtoD; 00039 pdcDst->dclevel.efM22PtoD = pdcSrc->dclevel.efM22PtoD; 00040 pdcDst->dclevel.sizl = pdcSrc->dclevel.sizl; 00041 pdcDst->dclevel.hpal = pdcSrc->dclevel.hpal; 00042 00043 /* Handle references here correctly */ 00044 DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill); 00045 DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine); 00046 DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal); 00047 00048 // FIXME: Handle refs 00049 pdcDst->dclevel.plfnt = pdcSrc->dclevel.plfnt; 00050 00051 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ 00052 if (To) // Copy "To" SaveDC state. 00053 { 00054 if (pdcSrc->rosdc.hClipRgn) 00055 { 00056 pdcDst->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); 00057 NtGdiCombineRgn(pdcDst->rosdc.hClipRgn, pdcSrc->rosdc.hClipRgn, 0, RGN_COPY); 00058 } 00059 // FIXME: Handle prgnMeta! 00060 } 00061 else // Copy "!To" RestoreDC state. 00062 { /* The VisRectRegion field needs to be set to a valid state */ 00063 GdiExtSelectClipRgn(pdcDst, pdcSrc->rosdc.hClipRgn, RGN_COPY); 00064 } 00065 } 00066 00067 00068 BOOL FASTCALL 00069 IntGdiCleanDC(HDC hDC) 00070 { 00071 PDC dc; 00072 if (!hDC) return FALSE; 00073 dc = DC_LockDc(hDC); 00074 if (!dc) return FALSE; 00075 // Clean the DC 00076 if (defaultDCstate) DC_vCopyState(defaultDCstate, dc, FALSE); 00077 00078 DC_UnlockDc(dc); 00079 00080 return TRUE; 00081 } 00082 00083 00084 BOOL 00085 APIENTRY 00086 NtGdiResetDC( 00087 IN HDC hdc, 00088 IN LPDEVMODEW pdm, 00089 OUT PBOOL pbBanding, 00090 IN OPTIONAL VOID *pDriverInfo2, 00091 OUT VOID *ppUMdhpdev) 00092 { 00093 UNIMPLEMENTED; 00094 return 0; 00095 } 00096 00097 00098 VOID 00099 NTAPI 00100 DC_vRestoreDC( 00101 IN PDC pdc, 00102 INT iSaveLevel) 00103 { 00104 HDC hdcSave; 00105 PDC pdcSave; 00106 00107 ASSERT(iSaveLevel > 0); 00108 DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel); 00109 00110 /* Loop the save levels */ 00111 while (pdc->dclevel.lSaveDepth > iSaveLevel) 00112 { 00113 hdcSave = pdc->dclevel.hdcSave; 00114 DPRINT("RestoreDC = %p\n", hdcSave); 00115 00116 /* Set us as the owner */ 00117 if (!GreSetObjectOwner(hdcSave, GDI_OBJ_HMGR_POWNED)) 00118 { 00119 /* Could not get ownership. That's bad! */ 00120 DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n", 00121 hdcSave, pdc->BaseObject.hHmgr); 00122 return;// FALSE; 00123 } 00124 00125 /* Lock the saved dc */ 00126 pdcSave = DC_LockDc(hdcSave); 00127 if (!pdcSave) 00128 { 00129 /* WTF? Internal error! */ 00130 DPRINT1("Could not lock the saved DC (%p) for dc %p!\n", 00131 hdcSave, pdc->BaseObject.hHmgr); 00132 return;// FALSE; 00133 } 00134 00135 /* Remove the saved dc from the queue */ 00136 pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave; 00137 00138 /* Decrement save level */ 00139 pdc->dclevel.lSaveDepth--; 00140 00141 /* Is this the state we want? */ 00142 if (pdc->dclevel.lSaveDepth == iSaveLevel) 00143 { 00144 /* Copy the state back */ 00145 DC_vCopyState(pdcSave, pdc, FALSE); 00146 00147 /* Only memory DC's change their surface */ 00148 if (pdc->dctype == DCTYPE_MEMORY) 00149 DC_vSelectSurface(pdc, pdcSave->dclevel.pSurface); 00150 00151 // Restore Path by removing it, if the Save flag is set. 00152 // BeginPath will takecare of the rest. 00153 if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE) 00154 { 00155 PATH_Delete(pdc->dclevel.hPath); 00156 pdc->dclevel.hPath = 0; 00157 pdc->dclevel.flPath &= ~DCPATH_SAVE; 00158 } 00159 } 00160 00161 /* Prevent save dc from being restored */ 00162 pdcSave->dclevel.lSaveDepth = 1; 00163 00164 /* Unlock it */ 00165 DC_UnlockDc(pdcSave); 00166 /* Delete the saved dc */ 00167 GreDeleteObject(hdcSave); 00168 } 00169 00170 DPRINT("Leave DC_vRestoreDC()\n"); 00171 } 00172 00173 00174 00175 BOOL 00176 APIENTRY 00177 NtGdiRestoreDC( 00178 HDC hdc, 00179 INT iSaveLevel) 00180 { 00181 PDC pdc; 00182 00183 DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel); 00184 00185 /* Lock the original DC */ 00186 pdc = DC_LockDc(hdc); 00187 if (!pdc) 00188 { 00189 EngSetLastError(ERROR_INVALID_HANDLE); 00190 return FALSE; 00191 } 00192 00193 ASSERT(pdc->dclevel.lSaveDepth > 0); 00194 00195 /* Negative values are relative to the stack top */ 00196 if (iSaveLevel < 0) 00197 iSaveLevel = pdc->dclevel.lSaveDepth + iSaveLevel; 00198 00199 /* Check if we have a valid instance */ 00200 if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth) 00201 { 00202 DPRINT("Illegal save level, requested: %ld, current: %ld\n", 00203 iSaveLevel, pdc->dclevel.lSaveDepth); 00204 DC_UnlockDc(pdc); 00205 EngSetLastError(ERROR_INVALID_PARAMETER); 00206 return FALSE; 00207 } 00208 00209 /* Call the internal function */ 00210 DC_vRestoreDC(pdc, iSaveLevel); 00211 00212 DC_UnlockDc(pdc); 00213 00214 DPRINT("Leave NtGdiRestoreDC\n"); 00215 return TRUE; 00216 } 00217 00218 00219 INT 00220 APIENTRY 00221 NtGdiSaveDC( 00222 HDC hDC) 00223 { 00224 HDC hdcSave; 00225 PDC pdc, pdcSave; 00226 INT lSaveDepth; 00227 00228 DPRINT("NtGdiSaveDC(%p)\n", hDC); 00229 00230 /* Lock the original dc */ 00231 pdc = DC_LockDc(hDC); 00232 if (pdc == NULL) 00233 { 00234 DPRINT("Could not lock DC\n"); 00235 EngSetLastError(ERROR_INVALID_HANDLE); 00236 return 0; 00237 } 00238 00239 /* Allocate a new dc */ 00240 pdcSave = DC_AllocDcWithHandle(); 00241 if (pdcSave == NULL) 00242 { 00243 DPRINT("Could not allocate a new DC\n"); 00244 DC_UnlockDc(pdc); 00245 return 0; 00246 } 00247 hdcSave = pdcSave->BaseObject.hHmgr; 00248 00249 InterlockedIncrement(&pdc->ppdev->cPdevRefs); 00250 DC_vInitDc(pdcSave, DCTYPE_MEMORY, pdc->ppdev); 00251 00252 /* Handle references here correctly */ 00253 //pdcSrc->dclevel.pSurface = NULL; 00254 //pdcSrc->dclevel.pbrFill = NULL; 00255 //pdcSrc->dclevel.pbrLine = NULL; 00256 //pdcSrc->dclevel.ppal = NULL; 00257 00258 /* Make it a kernel handle 00259 (FIXME: Windows handles this differently, see Wiki) */ 00260 GDIOBJ_vSetObjectOwner(&pdcSave->BaseObject, GDI_OBJ_HMGR_PUBLIC); 00261 00262 /* Copy the current state */ 00263 DC_vCopyState(pdc, pdcSave, TRUE); 00264 00265 /* Only memory DC's change their surface */ 00266 if (pdc->dctype == DCTYPE_MEMORY) 00267 DC_vSelectSurface(pdcSave, pdc->dclevel.pSurface); 00268 00269 /* Copy path */ 00270 /* FIXME: Why this way? */ 00271 pdcSave->dclevel.hPath = pdc->dclevel.hPath; 00272 pdcSave->dclevel.flPath = pdc->dclevel.flPath | DCPATH_SAVESTATE; 00273 if (pdcSave->dclevel.hPath) pdcSave->dclevel.flPath |= DCPATH_SAVE; 00274 00275 /* Set new dc as save dc */ 00276 pdc->dclevel.hdcSave = hdcSave; 00277 00278 /* Increase save depth, return old value */ 00279 lSaveDepth = pdc->dclevel.lSaveDepth++; 00280 00281 /* Cleanup and return */ 00282 DC_UnlockDc(pdcSave); 00283 DC_UnlockDc(pdc); 00284 00285 DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave); 00286 return lSaveDepth; 00287 } 00288 00289 /* EOF */ Generated on Sun May 27 2012 04:38:25 for ReactOS by
1.7.6.1
|