More dc cleanup: make DC_AllocDC return a pointer, not a handle, like done with the...
[reactos.git] / reactos / subsystems / win32 / win32k / objects / dcutil.c
1
2 #include <w32k.h>
3
4 #define NDEBUG
5 #include <debug.h>
6
7 COLORREF FASTCALL
8 IntGdiSetBkColor(HDC hDC, COLORREF color)
9 {
10 COLORREF oldColor;
11 PDC dc;
12 PDC_ATTR pdcattr;
13 HBRUSH hBrush;
14
15 if (!(dc = DC_LockDc(hDC)))
16 {
17 SetLastWin32Error(ERROR_INVALID_HANDLE);
18 return CLR_INVALID;
19 }
20 pdcattr = dc->pdcattr;
21 oldColor = pdcattr->crBackgroundClr;
22 pdcattr->crBackgroundClr = color;
23 pdcattr->ulBackgroundClr = (ULONG)color;
24 pdcattr->ulDirty_ &= ~(DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
25 hBrush = pdcattr->hbrush;
26 DC_UnlockDc(dc);
27 NtGdiSelectBrush(hDC, hBrush);
28 return oldColor;
29 }
30
31 INT FASTCALL
32 IntGdiSetBkMode(HDC hDC, INT Mode)
33 {
34 COLORREF oldMode;
35 PDC dc;
36 PDC_ATTR pdcattr;
37
38 if (!(dc = DC_LockDc(hDC)))
39 {
40 SetLastWin32Error(ERROR_INVALID_HANDLE);
41 return CLR_INVALID;
42 }
43 pdcattr = dc->pdcattr;
44 oldMode = pdcattr->lBkMode;
45 pdcattr->jBkMode = Mode;
46 pdcattr->lBkMode = Mode;
47 DC_UnlockDc(dc);
48 return oldMode;
49 }
50
51 UINT
52 FASTCALL
53 IntGdiSetTextAlign(HDC hDC,
54 UINT Mode)
55 {
56 UINT prevAlign;
57 DC *dc;
58 PDC_ATTR pdcattr;
59
60 dc = DC_LockDc(hDC);
61 if (!dc)
62 {
63 SetLastWin32Error(ERROR_INVALID_HANDLE);
64 return GDI_ERROR;
65 }
66 pdcattr = dc->pdcattr;
67 prevAlign = pdcattr->lTextAlign;
68 pdcattr->lTextAlign = Mode;
69 DC_UnlockDc(dc);
70 return prevAlign;
71 }
72
73 COLORREF
74 FASTCALL
75 IntGdiSetTextColor(HDC hDC,
76 COLORREF color)
77 {
78 COLORREF oldColor;
79 PDC dc = DC_LockDc(hDC);
80 PDC_ATTR pdcattr;
81 HBRUSH hBrush;
82
83 if (!dc)
84 {
85 SetLastWin32Error(ERROR_INVALID_HANDLE);
86 return CLR_INVALID;
87 }
88 pdcattr = dc->pdcattr;
89
90 oldColor = pdcattr->crForegroundClr;
91 pdcattr->crForegroundClr = color;
92 hBrush = pdcattr->hbrush;
93 pdcattr->ulDirty_ &= ~(DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
94 DC_UnlockDc(dc);
95 NtGdiSelectBrush(hDC, hBrush);
96 return oldColor;
97 }
98
99 VOID
100 FASTCALL
101 DCU_SetDcUndeletable(HDC hDC)
102 {
103 PDC dc = DC_LockDc(hDC);
104 if (!dc)
105 {
106 SetLastWin32Error(ERROR_INVALID_HANDLE);
107 return;
108 }
109
110 dc->fs |= DC_FLAG_PERMANENT;
111 DC_UnlockDc(dc);
112 return;
113 }
114
115 #if 0
116 BOOL FASTCALL
117 IntIsPrimarySurface(SURFOBJ *SurfObj)
118 {
119 if (PrimarySurface.pSurface == NULL)
120 {
121 return FALSE;
122 }
123 return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
124 }
125 #endif
126
127
128 BOOL APIENTRY
129 NtGdiCancelDC(HDC hDC)
130 {
131 UNIMPLEMENTED;
132 return FALSE;
133 }
134
135
136 WORD APIENTRY
137 IntGdiSetHookFlags(HDC hDC, WORD Flags)
138 {
139 WORD wRet;
140 DC *dc = DC_LockDc(hDC);
141
142 if (NULL == dc)
143 {
144 SetLastWin32Error(ERROR_INVALID_HANDLE);
145 return 0;
146 }
147
148 wRet = dc->fs & DC_FLAG_DIRTY_RAO; // Fixme wrong flag!
149
150 /* "Undocumented Windows" info is slightly confusing.
151 */
152
153 DPRINT("DC %p, Flags %04x\n", hDC, Flags);
154
155 if (Flags & DCHF_INVALIDATEVISRGN)
156 {
157 /* hVisRgn has to be updated */
158 dc->fs |= DC_FLAG_DIRTY_RAO;
159 }
160 else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
161 {
162 dc->fs &= ~DC_FLAG_DIRTY_RAO;
163 }
164
165 DC_UnlockDc(dc);
166
167 return wRet;
168 }
169
170
171 BOOL
172 APIENTRY
173 NtGdiGetDCDword(
174 HDC hDC,
175 UINT u,
176 DWORD *Result)
177 {
178 BOOL Ret = TRUE;
179 PDC pdc;
180 PDC_ATTR pdcattr;
181
182 DWORD SafeResult = 0;
183 NTSTATUS Status = STATUS_SUCCESS;
184
185 if (!Result)
186 {
187 SetLastWin32Error(ERROR_INVALID_PARAMETER);
188 return FALSE;
189 }
190
191 pdc = DC_LockDc(hDC);
192 if (!pdc)
193 {
194 SetLastWin32Error(ERROR_INVALID_HANDLE);
195 return FALSE;
196 }
197 pdcattr = pdc->pdcattr;
198
199 switch (u)
200 {
201 case GdiGetJournal:
202 break;
203
204 case GdiGetRelAbs:
205 SafeResult = pdcattr->lRelAbs;
206 break;
207
208 case GdiGetBreakExtra:
209 SafeResult = pdcattr->lBreakExtra;
210 break;
211
212 case GdiGerCharBreak:
213 SafeResult = pdcattr->cBreak;
214 break;
215
216 case GdiGetArcDirection:
217 if (pdcattr->dwLayout & LAYOUT_RTL)
218 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
219 else
220 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE;
221 break;
222
223 case GdiGetEMFRestorDc:
224 break;
225
226 case GdiGetFontLanguageInfo:
227 SafeResult = IntGetFontLanguageInfo(pdc);
228 break;
229
230 case GdiGetIsMemDc:
231 SafeResult = pdc->dctype;
232 break;
233
234 case GdiGetMapMode:
235 SafeResult = pdcattr->iMapMode;
236 break;
237
238 case GdiGetTextCharExtra:
239 SafeResult = pdcattr->lTextExtra;
240 break;
241
242 default:
243 SetLastWin32Error(ERROR_INVALID_PARAMETER);
244 Ret = FALSE;
245 break;
246 }
247
248 if (Ret)
249 {
250 _SEH2_TRY
251 {
252 ProbeForWrite(Result, sizeof(DWORD), 1);
253 *Result = SafeResult;
254 }
255 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
256 {
257 Status = _SEH2_GetExceptionCode();
258 }
259 _SEH2_END;
260
261 if (!NT_SUCCESS(Status))
262 {
263 SetLastNtError(Status);
264 Ret = FALSE;
265 }
266 }
267
268 DC_UnlockDc(pdc);
269 return Ret;
270 }
271
272 BOOL
273 APIENTRY
274 NtGdiGetAndSetDCDword(
275 HDC hDC,
276 UINT u,
277 DWORD dwIn,
278 DWORD *Result)
279 {
280 BOOL Ret = TRUE;
281 PDC pdc;
282 PDC_ATTR pdcattr;
283
284 DWORD SafeResult = 0;
285 NTSTATUS Status = STATUS_SUCCESS;
286
287 if (!Result)
288 {
289 SetLastWin32Error(ERROR_INVALID_PARAMETER);
290 return FALSE;
291 }
292
293 pdc = DC_LockDc(hDC);
294 if (!pdc)
295 {
296 SetLastWin32Error(ERROR_INVALID_HANDLE);
297 return FALSE;
298 }
299 pdcattr = pdc->pdcattr;
300
301 switch (u)
302 {
303 case GdiGetSetCopyCount:
304 SafeResult = pdc->ulCopyCount;
305 pdc->ulCopyCount = dwIn;
306 break;
307
308 case GdiGetSetTextAlign:
309 SafeResult = pdcattr->lTextAlign;
310 pdcattr->lTextAlign = dwIn;
311 // pdcattr->flTextAlign = dwIn; // Flags!
312 break;
313
314 case GdiGetSetRelAbs:
315 SafeResult = pdcattr->lRelAbs;
316 pdcattr->lRelAbs = dwIn;
317 break;
318
319 case GdiGetSetTextCharExtra:
320 SafeResult = pdcattr->lTextExtra;
321 pdcattr->lTextExtra = dwIn;
322 break;
323
324 case GdiGetSetSelectFont:
325 break;
326
327 case GdiGetSetMapperFlagsInternal:
328 if (dwIn & ~1)
329 {
330 SetLastWin32Error(ERROR_INVALID_PARAMETER);
331 Ret = FALSE;
332 break;
333 }
334 SafeResult = pdcattr->flFontMapper;
335 pdcattr->flFontMapper = dwIn;
336 break;
337
338 case GdiGetSetMapMode:
339 SafeResult = IntGdiSetMapMode(pdc, dwIn);
340 break;
341
342 case GdiGetSetArcDirection:
343 if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
344 {
345 SetLastWin32Error(ERROR_INVALID_PARAMETER);
346 Ret = FALSE;
347 break;
348 }
349 if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left
350 {
351 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
352 if (dwIn == AD_CLOCKWISE)
353 {
354 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
355 break;
356 }
357 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
358 }
359 else // Left to Right
360 {
361 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) +
362 AD_COUNTERCLOCKWISE;
363 if (dwIn == AD_COUNTERCLOCKWISE)
364 {
365 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
366 break;
367 }
368 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
369 }
370 break;
371
372 default:
373 SetLastWin32Error(ERROR_INVALID_PARAMETER);
374 Ret = FALSE;
375 break;
376 }
377
378 if (Ret)
379 {
380 _SEH2_TRY
381 {
382 ProbeForWrite(Result, sizeof(DWORD), 1);
383 *Result = SafeResult;
384 }
385 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
386 {
387 Status = _SEH2_GetExceptionCode();
388 }
389 _SEH2_END;
390
391 if (!NT_SUCCESS(Status))
392 {
393 SetLastNtError(Status);
394 Ret = FALSE;
395 }
396 }
397
398 DC_UnlockDc(pdc);
399 return Ret;
400 }