Merge aicom-network-branch (without NDIS changes for now)
[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 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
129 BOOL APIENTRY
130 NtGdiCancelDC(HDC hDC)
131 {
132 UNIMPLEMENTED;
133 return FALSE;
134 }
135
136
137 WORD APIENTRY
138 IntGdiSetHookFlags(HDC hDC, WORD Flags)
139 {
140 WORD wRet;
141 DC *dc = DC_LockDc(hDC);
142
143 if (NULL == dc)
144 {
145 SetLastWin32Error(ERROR_INVALID_HANDLE);
146 return 0;
147 }
148
149 wRet = dc->fs & DC_FLAG_DIRTY_RAO; // Fixme wrong flag!
150
151 /* "Undocumented Windows" info is slightly confusing.
152 */
153
154 DPRINT("DC %p, Flags %04x\n", hDC, Flags);
155
156 if (Flags & DCHF_INVALIDATEVISRGN)
157 {
158 /* hVisRgn has to be updated */
159 dc->fs |= DC_FLAG_DIRTY_RAO;
160 }
161 else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
162 {
163 dc->fs &= ~DC_FLAG_DIRTY_RAO;
164 }
165
166 DC_UnlockDc(dc);
167
168 return wRet;
169 }
170
171
172 BOOL
173 APIENTRY
174 NtGdiGetDCDword(
175 HDC hDC,
176 UINT u,
177 DWORD *Result)
178 {
179 BOOL Ret = TRUE;
180 PDC pdc;
181 PDC_ATTR pdcattr;
182
183 DWORD SafeResult = 0;
184 NTSTATUS Status = STATUS_SUCCESS;
185
186 if (!Result)
187 {
188 SetLastWin32Error(ERROR_INVALID_PARAMETER);
189 return FALSE;
190 }
191
192 pdc = DC_LockDc(hDC);
193 if (!pdc)
194 {
195 SetLastWin32Error(ERROR_INVALID_HANDLE);
196 return FALSE;
197 }
198 pdcattr = pdc->pdcattr;
199
200 switch (u)
201 {
202 case GdiGetJournal:
203 break;
204
205 case GdiGetRelAbs:
206 SafeResult = pdcattr->lRelAbs;
207 break;
208
209 case GdiGetBreakExtra:
210 SafeResult = pdcattr->lBreakExtra;
211 break;
212
213 case GdiGerCharBreak:
214 SafeResult = pdcattr->cBreak;
215 break;
216
217 case GdiGetArcDirection:
218 if (pdcattr->dwLayout & LAYOUT_RTL)
219 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
220 else
221 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE;
222 break;
223
224 case GdiGetEMFRestorDc:
225 break;
226
227 case GdiGetFontLanguageInfo:
228 SafeResult = IntGetFontLanguageInfo(pdc);
229 break;
230
231 case GdiGetIsMemDc:
232 SafeResult = pdc->dctype;
233 break;
234
235 case GdiGetMapMode:
236 SafeResult = pdcattr->iMapMode;
237 break;
238
239 case GdiGetTextCharExtra:
240 SafeResult = pdcattr->lTextExtra;
241 break;
242
243 default:
244 SetLastWin32Error(ERROR_INVALID_PARAMETER);
245 Ret = FALSE;
246 break;
247 }
248
249 if (Ret)
250 {
251 _SEH2_TRY
252 {
253 ProbeForWrite(Result, sizeof(DWORD), 1);
254 *Result = SafeResult;
255 }
256 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
257 {
258 Status = _SEH2_GetExceptionCode();
259 }
260 _SEH2_END;
261
262 if (!NT_SUCCESS(Status))
263 {
264 SetLastNtError(Status);
265 Ret = FALSE;
266 }
267 }
268
269 DC_UnlockDc(pdc);
270 return Ret;
271 }
272
273 BOOL
274 APIENTRY
275 NtGdiGetAndSetDCDword(
276 HDC hDC,
277 UINT u,
278 DWORD dwIn,
279 DWORD *Result)
280 {
281 BOOL Ret = TRUE;
282 PDC pdc;
283 PDC_ATTR pdcattr;
284
285 DWORD SafeResult = 0;
286 NTSTATUS Status = STATUS_SUCCESS;
287
288 if (!Result)
289 {
290 SetLastWin32Error(ERROR_INVALID_PARAMETER);
291 return FALSE;
292 }
293
294 pdc = DC_LockDc(hDC);
295 if (!pdc)
296 {
297 SetLastWin32Error(ERROR_INVALID_HANDLE);
298 return FALSE;
299 }
300 pdcattr = pdc->pdcattr;
301
302 switch (u)
303 {
304 case GdiGetSetCopyCount:
305 SafeResult = pdc->ulCopyCount;
306 pdc->ulCopyCount = dwIn;
307 break;
308
309 case GdiGetSetTextAlign:
310 SafeResult = pdcattr->lTextAlign;
311 pdcattr->lTextAlign = dwIn;
312 // pdcattr->flTextAlign = dwIn; // Flags!
313 break;
314
315 case GdiGetSetRelAbs:
316 SafeResult = pdcattr->lRelAbs;
317 pdcattr->lRelAbs = dwIn;
318 break;
319
320 case GdiGetSetTextCharExtra:
321 SafeResult = pdcattr->lTextExtra;
322 pdcattr->lTextExtra = dwIn;
323 break;
324
325 case GdiGetSetSelectFont:
326 break;
327
328 case GdiGetSetMapperFlagsInternal:
329 if (dwIn & ~1)
330 {
331 SetLastWin32Error(ERROR_INVALID_PARAMETER);
332 Ret = FALSE;
333 break;
334 }
335 SafeResult = pdcattr->flFontMapper;
336 pdcattr->flFontMapper = dwIn;
337 break;
338
339 case GdiGetSetMapMode:
340 SafeResult = IntGdiSetMapMode(pdc, dwIn);
341 break;
342
343 case GdiGetSetArcDirection:
344 if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
345 {
346 SetLastWin32Error(ERROR_INVALID_PARAMETER);
347 Ret = FALSE;
348 break;
349 }
350 if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left
351 {
352 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
353 if (dwIn == AD_CLOCKWISE)
354 {
355 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
356 break;
357 }
358 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
359 }
360 else // Left to Right
361 {
362 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) +
363 AD_COUNTERCLOCKWISE;
364 if (dwIn == AD_COUNTERCLOCKWISE)
365 {
366 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
367 break;
368 }
369 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
370 }
371 break;
372
373 default:
374 SetLastWin32Error(ERROR_INVALID_PARAMETER);
375 Ret = FALSE;
376 break;
377 }
378
379 if (Ret)
380 {
381 _SEH2_TRY
382 {
383 ProbeForWrite(Result, sizeof(DWORD), 1);
384 *Result = SafeResult;
385 }
386 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
387 {
388 Status = _SEH2_GetExceptionCode();
389 }
390 _SEH2_END;
391
392 if (!NT_SUCCESS(Status))
393 {
394 SetLastNtError(Status);
395 Ret = FALSE;
396 }
397 }
398
399 DC_UnlockDc(pdc);
400 return Ret;
401 }