[GDI32]
[reactos.git] / reactos / subsystems / win32 / win32k / objects / dcutil.c
1
2 #include <win32k.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 crOldColor;
79 PDC pdc;
80 PDC_ATTR pdcattr;
81
82 pdc = DC_LockDc(hDC);
83 if (!pdc)
84 {
85 SetLastWin32Error(ERROR_INVALID_HANDLE);
86 return CLR_INVALID;
87 }
88 pdcattr = pdc->pdcattr;
89
90 // What about ulForegroundClr, like in gdi32?
91 crOldColor = pdcattr->crForegroundClr;
92 pdcattr->crForegroundClr = color;
93 DC_vUpdateTextBrush(pdc);
94
95 DC_UnlockDc(pdc);
96
97 return crOldColor;
98 }
99
100 VOID
101 FASTCALL
102 DCU_SetDcUndeletable(HDC hDC)
103 {
104 PDC dc = DC_LockDc(hDC);
105 if (!dc)
106 {
107 SetLastWin32Error(ERROR_INVALID_HANDLE);
108 return;
109 }
110
111 dc->fs |= DC_FLAG_PERMANENT;
112 DC_UnlockDc(dc);
113 return;
114 }
115
116 #if 0
117 BOOL FASTCALL
118 IntIsPrimarySurface(SURFOBJ *SurfObj)
119 {
120 if (PrimarySurface.pSurface == NULL)
121 {
122 return FALSE;
123 }
124 return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
125 }
126 #endif
127
128 BOOL
129 FASTCALL
130 IntSetDefaultRegion(PDC pdc)
131 {
132 PSURFACE pSurface;
133 PROSRGNDATA prgn;
134 RECTL rclWnd, rclClip;
135
136 IntGdiReleaseRaoRgn(pdc);
137
138 rclWnd.left = 0;
139 rclWnd.top = 0;
140 rclWnd.right = pdc->dclevel.sizl.cx;
141 rclWnd.bottom = pdc->dclevel.sizl.cy;
142 rclClip = rclWnd;
143
144 // EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
145 if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
146 {
147 pSurface = pdc->dclevel.pSurface;
148 if (pSurface && pSurface->flFlags & PDEV_SURFACE)
149 {
150 rclClip.left += pdc->ppdev->ptlOrigion.x;
151 rclClip.top += pdc->ppdev->ptlOrigion.y;
152 rclClip.right += pdc->ppdev->ptlOrigion.x;
153 rclClip.bottom += pdc->ppdev->ptlOrigion.y;
154 }
155 }
156 // EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
157
158 prgn = pdc->prgnVis;
159
160 if (prgn && prgn != prgnDefault)
161 {
162 REGION_SetRectRgn( prgn,
163 rclClip.left,
164 rclClip.top,
165 rclClip.right ,
166 rclClip.bottom );
167 }
168 else
169 {
170 prgn = IntSysCreateRectpRgn( rclClip.left,
171 rclClip.top,
172 rclClip.right ,
173 rclClip.bottom );
174 pdc->prgnVis = prgn;
175 }
176
177 if (prgn)
178 {
179 pdc->ptlDCOrig.x = 0;
180 pdc->ptlDCOrig.y = 0;
181 pdc->erclWindow = rclWnd;
182 pdc->erclClip = rclClip;
183 /* Might be an InitDC or DCE....*/
184 pdc->ptlFillOrigin.x = pdc->dcattr.VisRectRegion.Rect.right;
185 pdc->ptlFillOrigin.y = pdc->dcattr.VisRectRegion.Rect.bottom;
186 return TRUE;
187 }
188
189 pdc->prgnVis = prgnDefault;
190 return FALSE;
191 }
192
193
194 BOOL APIENTRY
195 NtGdiCancelDC(HDC hDC)
196 {
197 UNIMPLEMENTED;
198 return FALSE;
199 }
200
201
202 WORD APIENTRY
203 IntGdiSetHookFlags(HDC hDC, WORD Flags)
204 {
205 WORD wRet;
206 DC *dc = DC_LockDc(hDC);
207
208 if (NULL == dc)
209 {
210 SetLastWin32Error(ERROR_INVALID_HANDLE);
211 return 0;
212 }
213
214 wRet = dc->fs & DC_FLAG_DIRTY_RAO; // Fixme wrong flag!
215
216 /* "Undocumented Windows" info is slightly confusing.
217 */
218
219 DPRINT("DC %p, Flags %04x\n", hDC, Flags);
220
221 if (Flags & DCHF_INVALIDATEVISRGN)
222 {
223 /* hVisRgn has to be updated */
224 dc->fs |= DC_FLAG_DIRTY_RAO;
225 }
226 else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
227 {
228 dc->fs &= ~DC_FLAG_DIRTY_RAO;
229 }
230
231 DC_UnlockDc(dc);
232
233 return wRet;
234 }
235
236
237 BOOL
238 APIENTRY
239 NtGdiGetDCDword(
240 HDC hDC,
241 UINT u,
242 DWORD *Result)
243 {
244 BOOL Ret = TRUE;
245 PDC pdc;
246 PDC_ATTR pdcattr;
247
248 DWORD SafeResult = 0;
249 NTSTATUS Status = STATUS_SUCCESS;
250
251 if (!Result)
252 {
253 SetLastWin32Error(ERROR_INVALID_PARAMETER);
254 return FALSE;
255 }
256
257 pdc = DC_LockDc(hDC);
258 if (!pdc)
259 {
260 SetLastWin32Error(ERROR_INVALID_HANDLE);
261 return FALSE;
262 }
263 pdcattr = pdc->pdcattr;
264
265 switch (u)
266 {
267 case GdiGetJournal:
268 break;
269
270 case GdiGetRelAbs:
271 SafeResult = pdcattr->lRelAbs;
272 break;
273
274 case GdiGetBreakExtra:
275 SafeResult = pdcattr->lBreakExtra;
276 break;
277
278 case GdiGerCharBreak:
279 SafeResult = pdcattr->cBreak;
280 break;
281
282 case GdiGetArcDirection:
283 if (pdcattr->dwLayout & LAYOUT_RTL)
284 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
285 else
286 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE;
287 break;
288
289 case GdiGetEMFRestorDc:
290 break;
291
292 case GdiGetFontLanguageInfo:
293 SafeResult = IntGetFontLanguageInfo(pdc);
294 break;
295
296 case GdiGetIsMemDc:
297 SafeResult = pdc->dctype;
298 break;
299
300 case GdiGetMapMode:
301 SafeResult = pdcattr->iMapMode;
302 break;
303
304 case GdiGetTextCharExtra:
305 SafeResult = pdcattr->lTextExtra;
306 break;
307
308 default:
309 SetLastWin32Error(ERROR_INVALID_PARAMETER);
310 Ret = FALSE;
311 break;
312 }
313
314 if (Ret)
315 {
316 _SEH2_TRY
317 {
318 ProbeForWrite(Result, sizeof(DWORD), 1);
319 *Result = SafeResult;
320 }
321 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
322 {
323 Status = _SEH2_GetExceptionCode();
324 }
325 _SEH2_END;
326
327 if (!NT_SUCCESS(Status))
328 {
329 SetLastNtError(Status);
330 Ret = FALSE;
331 }
332 }
333
334 DC_UnlockDc(pdc);
335 return Ret;
336 }
337
338 BOOL
339 APIENTRY
340 NtGdiGetAndSetDCDword(
341 HDC hDC,
342 UINT u,
343 DWORD dwIn,
344 DWORD *Result)
345 {
346 BOOL Ret = TRUE;
347 PDC pdc;
348 PDC_ATTR pdcattr;
349
350 DWORD SafeResult = 0;
351 NTSTATUS Status = STATUS_SUCCESS;
352
353 if (!Result)
354 {
355 SetLastWin32Error(ERROR_INVALID_PARAMETER);
356 return FALSE;
357 }
358
359 pdc = DC_LockDc(hDC);
360 if (!pdc)
361 {
362 SetLastWin32Error(ERROR_INVALID_HANDLE);
363 return FALSE;
364 }
365 pdcattr = pdc->pdcattr;
366
367 switch (u)
368 {
369 case GdiGetSetCopyCount:
370 SafeResult = pdc->ulCopyCount;
371 pdc->ulCopyCount = dwIn;
372 break;
373
374 case GdiGetSetTextAlign:
375 SafeResult = pdcattr->lTextAlign;
376 pdcattr->lTextAlign = dwIn;
377 // pdcattr->flTextAlign = dwIn; // Flags!
378 break;
379
380 case GdiGetSetRelAbs:
381 SafeResult = pdcattr->lRelAbs;
382 pdcattr->lRelAbs = dwIn;
383 break;
384
385 case GdiGetSetTextCharExtra:
386 SafeResult = pdcattr->lTextExtra;
387 pdcattr->lTextExtra = dwIn;
388 break;
389
390 case GdiGetSetSelectFont:
391 break;
392
393 case GdiGetSetMapperFlagsInternal:
394 if (dwIn & ~1)
395 {
396 SetLastWin32Error(ERROR_INVALID_PARAMETER);
397 Ret = FALSE;
398 break;
399 }
400 SafeResult = pdcattr->flFontMapper;
401 pdcattr->flFontMapper = dwIn;
402 break;
403
404 case GdiGetSetMapMode:
405 SafeResult = IntGdiSetMapMode(pdc, dwIn);
406 break;
407
408 case GdiGetSetArcDirection:
409 if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
410 {
411 SetLastWin32Error(ERROR_INVALID_PARAMETER);
412 Ret = FALSE;
413 break;
414 }
415 if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left
416 {
417 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
418 if (dwIn == AD_CLOCKWISE)
419 {
420 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
421 break;
422 }
423 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
424 }
425 else // Left to Right
426 {
427 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) +
428 AD_COUNTERCLOCKWISE;
429 if (dwIn == AD_COUNTERCLOCKWISE)
430 {
431 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
432 break;
433 }
434 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
435 }
436 break;
437
438 default:
439 SetLastWin32Error(ERROR_INVALID_PARAMETER);
440 Ret = FALSE;
441 break;
442 }
443
444 if (Ret)
445 {
446 _SEH2_TRY
447 {
448 ProbeForWrite(Result, sizeof(DWORD), 1);
449 *Result = SafeResult;
450 }
451 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
452 {
453 Status = _SEH2_GetExceptionCode();
454 }
455 _SEH2_END;
456
457 if (!NT_SUCCESS(Status))
458 {
459 SetLastNtError(Status);
460 Ret = FALSE;
461 }
462 }
463
464 DC_UnlockDc(pdc);
465 return Ret;
466 }