ReactOS  0.4.13-dev-464-g6b95727
dcstate.c File Reference
#include <win32k.h>
#include <debug.h>
Include dependency graph for dcstate.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID FASTCALL DC_vCopyState (PDC pdcSrc, PDC pdcDst, BOOL To)
 
BOOL FASTCALL IntGdiCleanDC (HDC hDC)
 
__kernel_entry BOOL APIENTRY NtGdiResetDC (_In_ HDC hdc, _In_ LPDEVMODEW pdm, _Out_ PBOOL pbBanding, _In_opt_ DRIVER_INFO_2W *pDriverInfo2, _At_((PUMDHPDEV *) ppUMdhpdev, _Out_) PVOID ppUMdhpdev)
 
VOID NTAPI DC_vRestoreDC (IN PDC pdc, INT iSaveLevel)
 
BOOL APIENTRY NtGdiRestoreDC (HDC hdc, INT iSaveLevel)
 
INT APIENTRY NtGdiSaveDC (HDC hDC)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file dcstate.c.

Function Documentation

◆ DC_vCopyState()

VOID FASTCALL DC_vCopyState ( PDC  pdcSrc,
PDC  pdcDst,
BOOL  To 
)
Todo:
should aways be != NULL

Definition at line 16 of file dcstate.c.

17 {
18  DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr);
19 
20  /* Copy full DC attribute */
21  *pdcDst->pdcattr = *pdcSrc->pdcattr;
22 
23  /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
24  /* The VisRectRegion field needs to be set to a valid state */
25 
26  /* Mark some fields as dirty */
27  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....
28 
29  /* Copy DC level */
30  pdcDst->dclevel.pColorSpace = pdcSrc->dclevel.pColorSpace;
31  pdcDst->dclevel.laPath = pdcSrc->dclevel.laPath;
32  pdcDst->dclevel.ca = pdcSrc->dclevel.ca;
33  pdcDst->dclevel.mxWorldToDevice = pdcSrc->dclevel.mxWorldToDevice;
34  pdcDst->dclevel.mxDeviceToWorld = pdcSrc->dclevel.mxDeviceToWorld;
35  pdcDst->dclevel.mxWorldToPage = pdcSrc->dclevel.mxWorldToPage;
36  pdcDst->dclevel.efM11PtoD = pdcSrc->dclevel.efM11PtoD;
37  pdcDst->dclevel.efM22PtoD = pdcSrc->dclevel.efM22PtoD;
38  pdcDst->dclevel.sizl = pdcSrc->dclevel.sizl;
39  pdcDst->dclevel.hpal = pdcSrc->dclevel.hpal;
40 
41  /* Handle references here correctly */
42  DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill);
43  DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine);
44  DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal);
45 
46  /* Dereference the old font, reference the new one */
47  if (pdcDst->dclevel.plfnt) LFONT_ShareUnlockFont(pdcDst->dclevel.plfnt);
48  GDIOBJ_vReferenceObjectByPointer(&pdcSrc->dclevel.plfnt->BaseObject);
49  pdcDst->dclevel.plfnt = pdcSrc->dclevel.plfnt;
50 
51  /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
52  if (!To)
53  {
54  IntGdiExtSelectClipRgn(pdcDst, pdcSrc->dclevel.prgnClip, RGN_COPY);
55  if (pdcDst->dclevel.prgnMeta)
56  {
57  REGION_Delete(pdcDst->dclevel.prgnMeta);
58  pdcDst->dclevel.prgnMeta = NULL;
59  }
60  /* The only way to reset the Meta Region to its original state is to return to a previously saved version of the DC with SaveDC. */
61  if (pdcSrc->dclevel.prgnMeta)
62  {
63  pdcDst->dclevel.prgnMeta = IntSysCreateRectpRgn(0, 0, 0, 0);
64  IntGdiCombineRgn(pdcDst->dclevel.prgnMeta, pdcSrc->dclevel.prgnMeta, NULL, RGN_COPY);
65  }
66  pdcDst->fs |= DC_FLAG_DIRTY_RAO;
67  }
68 }
FORCEINLINE VOID DC_vSelectPalette(PDC pdc, PPALETTE ppal)
Definition: dc.h:286
#define DIRTY_CHARSET
Definition: ntgdihdl.h:149
#define LFONT_ShareUnlockFont(plfnt)
Definition: text.h:78
FORCEINLINE VOID DC_vSelectFillBrush(PDC pdc, PBRUSH pbrFill)
Definition: dc.h:262
#define DIRTY_BACKGROUND
Definition: ntgdihdl.h:148
INT FASTCALL IntGdiExtSelectClipRgn(PDC dc, PREGION prgn, int fnMode)
PREGION FASTCALL IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
Definition: region.c:2429
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
INT FASTCALL IntGdiCombineRgn(PREGION prgnDest, PREGION prgnSrc1, PREGION prgnSrc2, INT iCombineMode)
Definition: region.c:2509
#define DC_FLAG_DIRTY_RAO
Definition: ntgdihdl.h:132
#define DIRTY_TEXT
Definition: ntgdihdl.h:147
#define DC_ICM_NOT_CALIBRATED
Definition: ntgdihdl.h:162
#define DIRTY_FILL
Definition: ntgdihdl.h:145
#define RGN_COPY
Definition: wingdi.h:356
VOID NTAPI GDIOBJ_vReferenceObjectByPointer(POBJ pobj)
Definition: gdiobj.c:731
#define DIRTY_LINE
Definition: ntgdihdl.h:146
#define DC_ICM_NOT_SET
Definition: ntgdihdl.h:165
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2471
FORCEINLINE VOID DC_vSelectLineBrush(PDC pdc, PBRUSH pbrLine)
Definition: dc.h:274

Referenced by DC_InitHack(), DC_vRestoreDC(), IntGdiCleanDC(), and NtGdiSaveDC().

◆ DC_vRestoreDC()

VOID NTAPI DC_vRestoreDC ( IN PDC  pdc,
INT  iSaveLevel 
)

Definition at line 138 of file dcstate.c.

141 {
142  HDC hdcSave;
143  PDC pdcSave;
144 
145  NT_ASSERT(iSaveLevel > 0);
146  DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel);
147 
148  /* Loop the save levels */
149  while (pdc->dclevel.lSaveDepth > iSaveLevel)
150  {
151  hdcSave = pdc->dclevel.hdcSave;
152  DPRINT("RestoreDC = %p\n", hdcSave);
153 
154  /* Set us as the owner */
155  if (!GreSetObjectOwner(hdcSave, GDI_OBJ_HMGR_POWNED))
156  {
157  /* Could not get ownership. That's bad! */
158  DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n",
159  hdcSave, pdc->BaseObject.hHmgr);
160  NT_ASSERT(FALSE);
161  return;// FALSE;
162  }
163 
164  /* Lock the saved dc */
165  pdcSave = DC_LockDc(hdcSave);
166  if (!pdcSave)
167  {
168  /* WTF? Internal error! */
169  DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
170  hdcSave, pdc->BaseObject.hHmgr);
171  NT_ASSERT(FALSE);
172  return;// FALSE;
173  }
174 
175  /* Remove the saved dc from the queue */
176  pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave;
177 
178  /* Decrement save level */
179  pdc->dclevel.lSaveDepth--;
180 
181  /* Is this the state we want? */
182  if (pdc->dclevel.lSaveDepth == iSaveLevel)
183  {
184  /* Copy the state back */
185  DC_vCopyState(pdcSave, pdc, FALSE);
186 
187  /* Only memory DC's change their surface */
188  if (pdc->dctype == DCTYPE_MEMORY)
189  DC_vSelectSurface(pdc, pdcSave->dclevel.pSurface);
190 
191  if (pdcSave->dclevel.hPath)
192  {
193  PATH_RestorePath( pdc, pdcSave );
194  }
195  }
196 
197  /* Prevent save dc from being restored */
198  pdcSave->dclevel.lSaveDepth = 1;
199 
200  /* Unlock it */
201  DC_UnlockDc(pdcSave);
202  /* Delete the saved dc */
203  GreDeleteObject(hdcSave);
204  }
205 
206  DPRINT("Leave DC_vRestoreDC()\n");
207 }
BOOL NTAPI GreSetObjectOwner(HGDIOBJ hobj, ULONG ulOwner)
Definition: gdiobj.c:1252
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1155
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:219
FORCEINLINE VOID DC_vSelectSurface(PDC pdc, PSURFACE psurfNew)
Definition: dc.h:247
BOOL PATH_RestorePath(DC *dst, DC *src)
Definition: path.c:210
static HDC
Definition: imagelist.c:92
void DPRINT(...)
Definition: polytest.cpp:61
Definition: polytest.cpp:40
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:237
#define DPRINT1
Definition: precomp.h:8
VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
Definition: dcstate.c:16
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by DC_vCleanup(), DC_vSetOwner(), and NtGdiRestoreDC().

◆ IntGdiCleanDC()

BOOL FASTCALL IntGdiCleanDC ( HDC  hDC)

Definition at line 73 of file dcstate.c.

74 {
75  PDC dc;
76  if (!hDC) return FALSE;
77  dc = DC_LockDc(hDC);
78  if (!dc) return FALSE;
79  // Clean the DC
80  if (defaultDCstate)
81  {
83  /* Update the brushes now, because they reference some objects (the DC palette)
84  * Which belong to the current process, and this DC might be used for another process
85  * after being cleaned up (for GetDC(0) for instance) */
90  }
91 
92  // Remove Path and reset flags.
93  if (dc->dclevel.hPath)
94  {
95  DPRINT("Clean DC Remove Path\n");
96  if (!PATH_Delete(dc->dclevel.hPath))
97  {
98  DPRINT1("Failed to remove Path\n");
99  }
100  dc->dclevel.hPath = 0;
101  dc->dclevel.flPath = 0;
102  }
103 
104  /* DC_vCopyState frees the Clip rgn and the Meta rgn. Take care of the other ones
105  * There is no need to clear prgnVis, as UserGetDC updates it immediately. */
106  if (dc->prgnRao)
107  REGION_Delete(dc->prgnRao);
108  if (dc->prgnAPI)
109  REGION_Delete(dc->prgnAPI);
110  dc->prgnRao = dc->prgnAPI = NULL;
111 
112  dc->fs |= DC_FLAG_DIRTY_RAO;
113 
114  DC_UnlockDc(dc);
115 
116  return TRUE;
117 }
#define TRUE
Definition: types.h:120
VOID FASTCALL DC_vUpdateLineBrush(PDC pdc)
Definition: dcobjs.c:62
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:219
VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc)
Definition: dcobjs.c:126
HDC dc
Definition: cylfrac.c:34
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
VOID FASTCALL DC_vUpdateTextBrush(PDC pdc)
Definition: dcobjs.c:108
Definition: polytest.cpp:40
PDC defaultDCstate
Definition: device.c:14
#define DC_FLAG_DIRTY_RAO
Definition: ntgdihdl.h:132
static HDC hDC
Definition: 3dtext.c:33
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:237
#define DPRINT1
Definition: precomp.h:8
VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
Definition: dcstate.c:16
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2471
BOOL FASTCALL PATH_Delete(HPATH hPath)
Definition: path.c:91
VOID FASTCALL DC_vUpdateFillBrush(PDC pdc)
Definition: dcobjs.c:16

Referenced by DceReleaseDC(), and DxEngCleanDC().

◆ NtGdiResetDC()

__kernel_entry BOOL APIENTRY NtGdiResetDC ( _In_ HDC  hdc,
_In_ LPDEVMODEW  pdm,
_Out_ PBOOL  pbBanding,
_In_opt_ DRIVER_INFO_2W pDriverInfo2,
_At_((PUMDHPDEV *) ppUMdhpdev, _Out_) PVOID  ppUMdhpdev 
)

Definition at line 122 of file dcstate.c.

128 {
129  /* According to a comment in Windows SDK the size of the buffer for
130  pdm is (pdm->dmSize + pdm->dmDriverExtra) */
132  return FALSE;
133 }
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by ResetDCA(), and ResetDCW().

◆ NtGdiRestoreDC()

BOOL APIENTRY NtGdiRestoreDC ( HDC  hdc,
INT  iSaveLevel 
)

Definition at line 213 of file dcstate.c.

216 {
217  PDC pdc;
218 
219  DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel);
220 
221  /* Lock the original DC */
222  pdc = DC_LockDc(hdc);
223  if (!pdc)
224  {
226  return FALSE;
227  }
228 
229  ASSERT(pdc->dclevel.lSaveDepth > 0);
230 
231  /* Negative values are relative to the stack top */
232  if (iSaveLevel < 0)
233  iSaveLevel = pdc->dclevel.lSaveDepth + iSaveLevel;
234 
235  /* Check if we have a valid instance */
236  if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth)
237  {
238  DPRINT("Illegal save level, requested: %ld, current: %ld\n",
239  iSaveLevel, pdc->dclevel.lSaveDepth);
240  DC_UnlockDc(pdc);
242  return FALSE;
243  }
244 
245  /* Call the internal function */
246  DC_vRestoreDC(pdc, iSaveLevel);
247 
248  DC_UnlockDc(pdc);
249 
250  DPRINT("Leave NtGdiRestoreDC\n");
251  return TRUE;
252 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define TRUE
Definition: types.h:120
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:219
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
void DPRINT(...)
Definition: polytest.cpp:61
Definition: polytest.cpp:40
VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel)
Definition: dcstate.c:138
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
HDC hdc
Definition: main.c:9
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:237
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

◆ NtGdiSaveDC()

INT APIENTRY NtGdiSaveDC ( HDC  hDC)

Definition at line 257 of file dcstate.c.

259 {
260  HDC hdcSave;
261  PDC pdc, pdcSave;
262  INT lSaveDepth;
263 
264  DPRINT("NtGdiSaveDC(%p)\n", hDC);
265 
266  /* Lock the original dc */
267  pdc = DC_LockDc(hDC);
268  if (pdc == NULL)
269  {
270  DPRINT("Could not lock DC\n");
272  return 0;
273  }
274 
275  /* Allocate a new dc */
277  if (pdcSave == NULL)
278  {
279  DPRINT("Could not allocate a new DC\n");
280  DC_UnlockDc(pdc);
281  return 0;
282  }
283  hdcSave = pdcSave->BaseObject.hHmgr;
284 
285  InterlockedIncrement(&pdc->ppdev->cPdevRefs);
286  DC_vInitDc(pdcSave, DCTYPE_MEMORY, pdc->ppdev);
287 
288  /* Handle references here correctly */
289  //pdcSrc->dclevel.pSurface = NULL;
290  //pdcSrc->dclevel.pbrFill = NULL;
291  //pdcSrc->dclevel.pbrLine = NULL;
292  //pdcSrc->dclevel.ppal = NULL;
293 
294  /* Make it a kernel handle
295  (FIXME: Windows handles this differently, see Wiki) */
296  GDIOBJ_vSetObjectOwner(&pdcSave->BaseObject, GDI_OBJ_HMGR_PUBLIC);
297 
298  /* Copy the current state */
299  DC_vCopyState(pdc, pdcSave, FALSE);
300 
301  /* Only memory DC's change their surface */
302  if (pdc->dctype == DCTYPE_MEMORY)
303  DC_vSelectSurface(pdcSave, pdc->dclevel.pSurface);
304 
305  /* Copy path */
306  if (pdc->dclevel.hPath)
307  {
308  PATH_SavePath( pdcSave, pdc );
309  }
310  pdcSave->dclevel.flPath = pdc->dclevel.flPath | DCPATH_SAVESTATE;
311 
312  /* Set new dc as save dc */
313  pdcSave->dclevel.hdcSave = pdc->dclevel.hdcSave;
314  pdc->dclevel.hdcSave = hdcSave;
315 
316  /* Increase save depth, return old value */
317  lSaveDepth = pdc->dclevel.lSaveDepth++;
318 
319  /* Cleanup and return */
320  DC_UnlockDc(pdcSave);
321  DC_UnlockDc(pdc);
322 
323  DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave);
324  return lSaveDepth;
325 }
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:219
FORCEINLINE VOID DC_vSelectSurface(PDC pdc, PSURFACE psurfNew)
Definition: dc.h:247
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
static HDC
Definition: imagelist.c:92
BOOL PATH_SavePath(DC *dst, DC *src)
Definition: path.c:188
int32_t INT
Definition: typedefs.h:56
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI DC_vInitDc(PDC pdc, DCTYPE dctype, PPDEVOBJ ppdev)
Definition: dclife.c:129
Definition: polytest.cpp:40
PDC NTAPI DC_AllocDcWithHandle(GDILOOBJTYPE eDcObjType)
Definition: dclife.c:69
static HDC hDC
Definition: 3dtext.c:33
#define InterlockedIncrement
Definition: armddk.h:53
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:237
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
VOID NTAPI GDIOBJ_vSetObjectOwner(POBJ pobj, ULONG ulNewOwner)
Definition: gdiobj.c:962
VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
Definition: dcstate.c:16
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27