1 #include <win32k.h>
2
3 #define NDEBUG
4 #include <debug.h>
5
6 BOOL FASTCALL
GreDPtoLP(HDC hdc,LPPOINT lpPoints,INT nCount)7 GreDPtoLP(HDC hdc, LPPOINT lpPoints, INT nCount)
8 {
9 PDC dc;
10 if (!(dc = DC_LockDc(hdc)))
11 {
12 EngSetLastError(ERROR_INVALID_HANDLE);
13 return FALSE;
14 }
15 IntDPtoLP(dc, lpPoints, nCount);
16 DC_UnlockDc(dc);
17 return TRUE;
18 }
19
20 BOOL FASTCALL
GreLPtoDP(HDC hdc,LPPOINT lpPoints,INT nCount)21 GreLPtoDP(HDC hdc, LPPOINT lpPoints, INT nCount)
22 {
23 PDC dc;
24 if (!(dc = DC_LockDc(hdc)))
25 {
26 EngSetLastError(ERROR_INVALID_HANDLE);
27 return FALSE;
28 }
29 IntLPtoDP(dc, lpPoints, nCount);
30 DC_UnlockDc(dc);
31 return TRUE;
32 }
33
34 int FASTCALL
GreGetBkMode(HDC hdc)35 GreGetBkMode(HDC hdc)
36 {
37 PDC dc;
38 LONG lBkMode;
39 if (!(dc = DC_LockDc(hdc)))
40 {
41 EngSetLastError(ERROR_INVALID_HANDLE);
42 return CLR_INVALID;
43 }
44 lBkMode = dc->pdcattr->lBkMode;
45 DC_UnlockDc(dc);
46 return lBkMode;
47 }
48
49 COLORREF FASTCALL
GreGetBkColor(HDC hdc)50 GreGetBkColor(HDC hdc)
51 {
52 PDC dc;
53 COLORREF crBk;
54 if (!(dc = DC_LockDc(hdc)))
55 {
56 EngSetLastError(ERROR_INVALID_HANDLE);
57 return CLR_INVALID;
58 }
59 crBk = dc->pdcattr->ulBackgroundClr;
60 DC_UnlockDc(dc);
61 return crBk;
62 }
63
64 int FASTCALL
GreGetMapMode(HDC hdc)65 GreGetMapMode(HDC hdc)
66 {
67 PDC dc;
68 INT iMapMode;
69 if (!(dc = DC_LockDc(hdc)))
70 {
71 EngSetLastError(ERROR_INVALID_HANDLE);
72 return CLR_INVALID;
73 }
74 iMapMode = dc->pdcattr->iMapMode;
75 DC_UnlockDc(dc);
76 return iMapMode;
77 }
78
79 COLORREF FASTCALL
GreGetTextColor(HDC hdc)80 GreGetTextColor(HDC hdc)
81 {
82 PDC dc;
83 ULONG ulForegroundClr;
84 if (!(dc = DC_LockDc(hdc)))
85 {
86 EngSetLastError(ERROR_INVALID_HANDLE);
87 return CLR_INVALID;
88 }
89 ulForegroundClr = dc->pdcattr->ulForegroundClr;
90 DC_UnlockDc(dc);
91 return ulForegroundClr;
92 }
93
94 COLORREF FASTCALL
IntGdiSetBkColor(HDC hDC,COLORREF color)95 IntGdiSetBkColor(HDC hDC, COLORREF color)
96 {
97 COLORREF oldColor;
98 PDC dc;
99 PDC_ATTR pdcattr;
100 HBRUSH hBrush;
101
102 if (!(dc = DC_LockDc(hDC)))
103 {
104 EngSetLastError(ERROR_INVALID_HANDLE);
105 return CLR_INVALID;
106 }
107 pdcattr = dc->pdcattr;
108
109 oldColor = pdcattr->ulBackgroundClr;
110 pdcattr->ulBackgroundClr = color;
111
112 if (pdcattr->crBackgroundClr != color)
113 {
114 pdcattr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
115 pdcattr->crBackgroundClr = color;
116 }
117 hBrush = pdcattr->hbrush;
118 DC_UnlockDc(dc);
119 NtGdiSelectBrush(hDC, hBrush);
120 return oldColor;
121 }
122
123 INT FASTCALL
IntGdiSetBkMode(HDC hDC,INT Mode)124 IntGdiSetBkMode(HDC hDC, INT Mode)
125 {
126 COLORREF oldMode;
127 PDC dc;
128 PDC_ATTR pdcattr;
129
130 if (!(dc = DC_LockDc(hDC)))
131 {
132 EngSetLastError(ERROR_INVALID_HANDLE);
133 return CLR_INVALID;
134 }
135 pdcattr = dc->pdcattr;
136 oldMode = pdcattr->lBkMode;
137 pdcattr->jBkMode = Mode;
138 pdcattr->lBkMode = Mode;
139 DC_UnlockDc(dc);
140 return oldMode;
141 }
142
143 UINT
144 FASTCALL
IntGdiSetTextAlign(HDC hDC,UINT Mode)145 IntGdiSetTextAlign(HDC hDC,
146 UINT Mode)
147 {
148 UINT prevAlign;
149 DC *dc;
150 PDC_ATTR pdcattr;
151
152 dc = DC_LockDc(hDC);
153 if (!dc)
154 {
155 EngSetLastError(ERROR_INVALID_HANDLE);
156 return GDI_ERROR;
157 }
158 pdcattr = dc->pdcattr;
159 prevAlign = pdcattr->lTextAlign;
160 pdcattr->lTextAlign = Mode;
161 if (pdcattr->dwLayout & LAYOUT_RTL)
162 {
163 if ((Mode & TA_CENTER) != TA_CENTER) Mode ^= TA_RIGHT;
164 }
165 pdcattr->flTextAlign = Mode & TA_MASK;
166 DC_UnlockDc(dc);
167 return prevAlign;
168 }
169
170 COLORREF
171 FASTCALL
IntGdiSetTextColor(HDC hDC,COLORREF color)172 IntGdiSetTextColor(HDC hDC,
173 COLORREF color)
174 {
175 COLORREF crOldColor;
176 PDC pdc;
177 PDC_ATTR pdcattr;
178
179 pdc = DC_LockDc(hDC);
180 if (!pdc)
181 {
182 EngSetLastError(ERROR_INVALID_HANDLE);
183 return CLR_INVALID;
184 }
185 pdcattr = pdc->pdcattr;
186
187 crOldColor = (COLORREF) pdcattr->ulForegroundClr;
188 pdcattr->ulForegroundClr = (ULONG)color;
189
190 if (pdcattr->crForegroundClr != color)
191 {
192 pdcattr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
193 pdcattr->crForegroundClr = color;
194 }
195
196 DC_vUpdateTextBrush(pdc);
197 DC_vUpdateLineBrush(pdc);
198 DC_vUpdateFillBrush(pdc);
199
200 DC_UnlockDc(pdc);
201
202 return crOldColor;
203 }
204
205 COLORREF FASTCALL
IntSetDCBrushColor(HDC hdc,COLORREF crColor)206 IntSetDCBrushColor(HDC hdc, COLORREF crColor)
207 {
208 COLORREF OldColor = CLR_INVALID;
209 PDC dc;
210 if (!(dc = DC_LockDc(hdc)))
211 {
212 EngSetLastError(ERROR_INVALID_HANDLE);
213 return CLR_INVALID;
214 }
215 else
216 {
217 OldColor = (COLORREF) dc->pdcattr->ulBrushClr;
218 dc->pdcattr->ulBrushClr = (ULONG) crColor;
219
220 if ( dc->pdcattr->crBrushClr != crColor )
221 {
222 dc->pdcattr->ulDirty_ |= DIRTY_FILL;
223 dc->pdcattr->crBrushClr = crColor;
224 }
225 }
226 DC_UnlockDc(dc);
227 return OldColor;
228 }
229
230 BOOL FASTCALL
GreSetBrushOrg(HDC hdc,INT x,INT y,LPPOINT pptOut)231 GreSetBrushOrg(
232 HDC hdc,
233 INT x,
234 INT y,
235 LPPOINT pptOut)
236 {
237 PDC pdc = DC_LockDc(hdc);
238 if (pdc == NULL)
239 {
240 EngSetLastError(ERROR_INVALID_HANDLE);
241 return FALSE;
242 }
243
244 if (pptOut != NULL)
245 {
246 *pptOut = pdc->pdcattr->ptlBrushOrigin;
247 }
248
249 pdc->pdcattr->ptlBrushOrigin.x = x;
250 pdc->pdcattr->ptlBrushOrigin.y = y;
251
252 DC_vSetBrushOrigin(pdc, x, y);
253
254 DC_UnlockDc(pdc);
255 return TRUE;
256 }
257
258 COLORREF FASTCALL
IntSetDCPenColor(HDC hdc,COLORREF crColor)259 IntSetDCPenColor(HDC hdc, COLORREF crColor)
260 {
261 COLORREF OldColor;
262 PDC dc;
263 if (!(dc = DC_LockDc(hdc)))
264 {
265 EngSetLastError(ERROR_INVALID_PARAMETER);
266 return CLR_INVALID;
267 }
268
269 OldColor = (COLORREF)dc->pdcattr->ulPenClr;
270 dc->pdcattr->ulPenClr = (ULONG)crColor;
271
272 if (dc->pdcattr->crPenClr != crColor)
273 {
274 dc->pdcattr->ulDirty_ |= DIRTY_LINE;
275 dc->pdcattr->crPenClr = crColor;
276 }
277 DC_UnlockDc(dc);
278 return OldColor;
279 }
280
281 int
282 FASTCALL
GreSetStretchBltMode(HDC hDC,int iStretchMode)283 GreSetStretchBltMode(HDC hDC, int iStretchMode)
284 {
285 PDC pdc;
286 PDC_ATTR pdcattr;
287 INT oSMode = 0;
288
289 pdc = DC_LockDc(hDC);
290 if (pdc)
291 {
292 pdcattr = pdc->pdcattr;
293 oSMode = pdcattr->lStretchBltMode;
294 pdcattr->lStretchBltMode = iStretchMode;
295
296 // Wine returns an error here. We set the default.
297 if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
298
299 pdcattr->jStretchBltMode = iStretchMode;
300 DC_UnlockDc(pdc);
301 }
302 return oSMode;
303 }
304
305 int FASTCALL
GreGetGraphicsMode(HDC hdc)306 GreGetGraphicsMode(HDC hdc)
307 {
308 PDC dc;
309 int GraphicsMode;
310 if (!(dc = DC_LockDc(hdc)))
311 {
312 EngSetLastError(ERROR_INVALID_HANDLE);
313 return CLR_INVALID;
314 }
315 GraphicsMode = dc->pdcattr->iGraphicsMode;
316 DC_UnlockDc(dc);
317 return GraphicsMode;
318 }
319
320 VOID
321 FASTCALL
DCU_SetDcUndeletable(HDC hDC)322 DCU_SetDcUndeletable(HDC hDC)
323 {
324 PDC dc = DC_LockDc(hDC);
325 if (!dc)
326 {
327 EngSetLastError(ERROR_INVALID_HANDLE);
328 return;
329 }
330
331 dc->fs |= DC_PERMANANT;
332 DC_UnlockDc(dc);
333 return;
334 }
335
336 #if 0
337 BOOL FASTCALL
338 IntIsPrimarySurface(SURFOBJ *SurfObj)
339 {
340 if (PrimarySurface.pSurface == NULL)
341 {
342 return FALSE;
343 }
344 return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
345 }
346 #endif
347
348 BOOL
349 FASTCALL
IntSetDefaultRegion(PDC pdc)350 IntSetDefaultRegion(PDC pdc)
351 {
352 PSURFACE pSurface;
353 PREGION prgn;
354 RECTL rclWnd, rclClip;
355
356 IntGdiReleaseRaoRgn(pdc);
357
358 rclWnd.left = 0;
359 rclWnd.top = 0;
360 rclWnd.right = pdc->dclevel.sizl.cx;
361 rclWnd.bottom = pdc->dclevel.sizl.cy;
362 rclClip = rclWnd;
363
364 //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
365 if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
366 {
367 pSurface = pdc->dclevel.pSurface;
368 if (pSurface && pSurface->flags & PDEV_SURFACE)
369 {
370 rclClip.left += pdc->ppdev->ptlOrigion.x;
371 rclClip.top += pdc->ppdev->ptlOrigion.y;
372 rclClip.right += pdc->ppdev->ptlOrigion.x;
373 rclClip.bottom += pdc->ppdev->ptlOrigion.y;
374 }
375 }
376 //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
377
378 prgn = pdc->prgnVis;
379
380 if (prgn && prgn != prgnDefault)
381 {
382 REGION_SetRectRgn( prgn,
383 rclClip.left,
384 rclClip.top,
385 rclClip.right ,
386 rclClip.bottom );
387 }
388 else
389 {
390 prgn = IntSysCreateRectpRgn( rclClip.left,
391 rclClip.top,
392 rclClip.right ,
393 rclClip.bottom );
394 pdc->prgnVis = prgn;
395 }
396
397 if (prgn)
398 {
399 pdc->ptlDCOrig.x = 0;
400 pdc->ptlDCOrig.y = 0;
401 pdc->erclWindow = rclWnd;
402 pdc->erclClip = rclClip;
403 /* Might be an InitDC or DCE... */
404 pdc->ptlFillOrigin = pdc->dcattr.ptlBrushOrigin;
405 return TRUE;
406 }
407 // No Vis use the Default System Region.
408 pdc->prgnVis = prgnDefault;
409 return FALSE;
410 }
411
412
413 BOOL APIENTRY
NtGdiCancelDC(HDC hDC)414 NtGdiCancelDC(HDC hDC)
415 {
416 UNIMPLEMENTED;
417 return FALSE;
418 }
419
420
421 WORD APIENTRY
IntGdiSetHookFlags(HDC hDC,WORD Flags)422 IntGdiSetHookFlags(HDC hDC, WORD Flags)
423 {
424 WORD wRet;
425 DC *dc = DC_LockDc(hDC);
426
427 if (NULL == dc)
428 {
429 EngSetLastError(ERROR_INVALID_HANDLE);
430 return 0;
431 }
432
433 wRet = dc->fs & DC_DIRTY_RAO; // FIXME: Wrong flag!
434
435 /* Info in "Undocumented Windows" is slightly confusing. */
436 DPRINT("DC %p, Flags %04x\n", hDC, Flags);
437
438 if (Flags & DCHF_INVALIDATEVISRGN)
439 {
440 /* hVisRgn has to be updated */
441 dc->fs |= DC_DIRTY_RAO;
442 }
443 else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
444 {
445 //dc->fs &= ~DC_DIRTY_RAO;
446 }
447
448 DC_UnlockDc(dc);
449
450 return wRet;
451 }
452
453
454 BOOL
455 APIENTRY
NtGdiGetDCDword(HDC hDC,UINT u,DWORD * Result)456 NtGdiGetDCDword(
457 HDC hDC,
458 UINT u,
459 DWORD *Result)
460 {
461 BOOL Ret = TRUE;
462 PDC pdc;
463 PDC_ATTR pdcattr;
464
465 DWORD SafeResult = 0;
466 NTSTATUS Status = STATUS_SUCCESS;
467
468 if (!Result)
469 {
470 EngSetLastError(ERROR_INVALID_PARAMETER);
471 return FALSE;
472 }
473
474 pdc = DC_LockDc(hDC);
475 if (!pdc)
476 {
477 EngSetLastError(ERROR_INVALID_HANDLE);
478 return FALSE;
479 }
480 pdcattr = pdc->pdcattr;
481
482 switch (u)
483 {
484 case GdiGetJournal:
485 break;
486
487 case GdiGetRelAbs:
488 SafeResult = pdcattr->lRelAbs;
489 break;
490
491 case GdiGetBreakExtra:
492 SafeResult = pdcattr->lBreakExtra;
493 break;
494
495 case GdiGetCharBreak:
496 SafeResult = pdcattr->cBreak;
497 break;
498
499 case GdiGetArcDirection:
500 if (pdcattr->dwLayout & LAYOUT_RTL)
501 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
502 else
503 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE;
504 break;
505
506 case GdiGetEMFRestorDc:
507 SafeResult = pdc->dclevel.lSaveDepth;
508 break;
509
510 case GdiGetFontLanguageInfo:
511 SafeResult = IntGetFontLanguageInfo(pdc);
512 break;
513
514 case GdiGetIsMemDc:
515 SafeResult = pdc->dctype;
516 break;
517
518 case GdiGetMapMode:
519 SafeResult = pdcattr->iMapMode;
520 break;
521
522 case GdiGetTextCharExtra:
523 SafeResult = pdcattr->lTextExtra;
524 break;
525
526 default:
527 EngSetLastError(ERROR_INVALID_PARAMETER);
528 Ret = FALSE;
529 break;
530 }
531
532 if (Ret)
533 {
534 _SEH2_TRY
535 {
536 ProbeForWrite(Result, sizeof(DWORD), 1);
537 *Result = SafeResult;
538 }
539 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
540 {
541 Status = _SEH2_GetExceptionCode();
542 }
543 _SEH2_END;
544
545 if (!NT_SUCCESS(Status))
546 {
547 SetLastNtError(Status);
548 Ret = FALSE;
549 }
550 }
551
552 DC_UnlockDc(pdc);
553 return Ret;
554 }
555
556 _Success_(return != FALSE)
557 BOOL
558 APIENTRY
NtGdiGetAndSetDCDword(_In_ HDC hdc,_In_ UINT u,_In_ DWORD dwIn,_Out_ DWORD * pdwResult)559 NtGdiGetAndSetDCDword(
560 _In_ HDC hdc,
561 _In_ UINT u,
562 _In_ DWORD dwIn,
563 _Out_ DWORD *pdwResult)
564 {
565 BOOL Ret = TRUE;
566 PDC pdc;
567 PDC_ATTR pdcattr;
568
569 DWORD SafeResult = 0;
570 NTSTATUS Status = STATUS_SUCCESS;
571
572 if (!pdwResult)
573 {
574 EngSetLastError(ERROR_INVALID_PARAMETER);
575 return FALSE;
576 }
577
578 pdc = DC_LockDc(hdc);
579 if (!pdc)
580 {
581 EngSetLastError(ERROR_INVALID_HANDLE);
582 return FALSE;
583 }
584 pdcattr = pdc->pdcattr;
585
586 switch (u)
587 {
588 case GdiGetSetEPSPrintingEscape:
589 SafeResult = pdc->fs & DC_EPSPRINTINGESCAPE;
590 pdc->fs &= ~DC_EPSPRINTINGESCAPE;
591 break;
592
593 case GdiGetSetCopyCount:
594 SafeResult = pdc->ulCopyCount;
595 pdc->ulCopyCount = dwIn;
596 break;
597
598 case GdiGetSetTextAlign:
599 SafeResult = pdcattr->lTextAlign;
600 pdcattr->lTextAlign = dwIn;
601 // pdcattr->flTextAlign = dwIn; // Flags!
602 break;
603
604 case GdiGetSetRelAbs:
605 SafeResult = pdcattr->lRelAbs;
606 pdcattr->lRelAbs = dwIn;
607 break;
608
609 case GdiGetSetTextCharExtra:
610 SafeResult = pdcattr->lTextExtra;
611 pdcattr->lTextExtra = dwIn;
612 break;
613
614 case GdiGetSetSelectFont:
615 break;
616
617 case GdiGetSetMapperFlagsInternal:
618 if (dwIn & ~1)
619 {
620 EngSetLastError(ERROR_INVALID_PARAMETER);
621 Ret = FALSE;
622 break;
623 }
624 SafeResult = pdcattr->flFontMapper;
625 pdcattr->flFontMapper = dwIn;
626 break;
627
628 case GdiGetSetMapMode:
629 SafeResult = IntGdiSetMapMode(pdc, dwIn);
630 break;
631
632 case GdiGetSetArcDirection:
633 if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
634 {
635 EngSetLastError(ERROR_INVALID_PARAMETER);
636 Ret = FALSE;
637 break;
638 }
639 if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left
640 {
641 SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
642 if (dwIn == AD_CLOCKWISE)
643 {
644 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
645 break;
646 }
647 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
648 }
649 else // Left to Right
650 {
651 SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) +
652 AD_COUNTERCLOCKWISE;
653 if (dwIn == AD_COUNTERCLOCKWISE)
654 {
655 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
656 break;
657 }
658 pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
659 }
660 break;
661
662 default:
663 EngSetLastError(ERROR_INVALID_PARAMETER);
664 Ret = FALSE;
665 break;
666 }
667
668 if (Ret)
669 {
670 _SEH2_TRY
671 {
672 ProbeForWrite(pdwResult, sizeof(DWORD), 1);
673 *pdwResult = SafeResult;
674 }
675 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
676 {
677 Status = _SEH2_GetExceptionCode();
678 }
679 _SEH2_END;
680
681 if (!NT_SUCCESS(Status))
682 {
683 SetLastNtError(Status);
684 Ret = FALSE;
685 }
686 }
687
688 DC_UnlockDc(pdc);
689 return Ret;
690 }
691
692 VOID
693 FASTCALL
IntUpdateBoundsRect(PDC pdc,PRECTL pRect)694 IntUpdateBoundsRect(PDC pdc, PRECTL pRect)
695 {
696 if (pdc->fs & DC_ACCUM_APP)
697 {
698 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, pRect);
699 }
700 if (pdc->fs & DC_ACCUM_WMGR)
701 {
702 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, pRect);
703 }
704 }
705
706 DWORD
707 APIENTRY
NtGdiGetBoundsRect(IN HDC hdc,OUT LPRECT prc,IN DWORD flags)708 NtGdiGetBoundsRect(
709 IN HDC hdc,
710 OUT LPRECT prc,
711 IN DWORD flags)
712 {
713 DWORD ret;
714 PDC pdc;
715 RECT rc;
716
717 /* Lock the DC */
718 if (!(pdc = DC_LockDc(hdc))) return 0;
719
720 if (!(flags & DCB_WINDOWMGR))
721 {
722 rc = pdc->erclBoundsApp;
723
724 if (RECTL_bIsEmptyRect(&rc))
725 {
726 rc.left = rc.top = rc.right = rc.bottom = 0;
727 ret = DCB_RESET;
728 }
729 else
730 {
731 RECTL rcRgn;
732 if (pdc->fs & DC_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc);
733 if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn))
734 {
735 REGION_GetRgnBox(pdc->prgnVis, &rcRgn);
736 }
737 rc.left = max( rc.left, 0 );
738 rc.top = max( rc.top, 0 );
739 rc.right = min( rc.right, rcRgn.right - rcRgn.left );
740 rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top );
741 DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top);
742 DPRINT("rc l %d t %d\n",rc.left,rc.top);
743 DPRINT(" r %d b %d\n",rc.right,rc.bottom);
744 ret = DCB_SET;
745 }
746 IntDPtoLP(pdc, (PPOINTL)&rc, 2);
747 DPRINT("rc1 l %d t %d\n",rc.left,rc.top);
748 DPRINT(" r %d b %d\n",rc.right,rc.bottom);
749 }
750 else
751 {
752 rc = pdc->erclBounds;
753 ret = DCB_SET;
754 }
755
756 /* Copy the rect to the caller */
757 _SEH2_TRY
758 {
759 ProbeForWrite(prc, sizeof(RECT), 1);
760 *prc = rc;
761 }
762 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
763 {
764 ret = 0;
765 }
766 _SEH2_END;
767
768 if (flags & DCB_RESET)
769 {
770 if (!(flags & DCB_WINDOWMGR))
771 {
772 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
773 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
774 }
775 else
776 {
777 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
778 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
779 }
780 }
781
782 DC_UnlockDc(pdc);
783 return ret;
784 }
785
786 DWORD
787 APIENTRY
NtGdiSetBoundsRect(IN HDC hdc,IN LPRECT prc,IN DWORD flags)788 NtGdiSetBoundsRect(
789 IN HDC hdc,
790 IN LPRECT prc,
791 IN DWORD flags)
792 {
793 DWORD ret;
794 PDC pdc;
795 RECTL rcl;
796
797 /* Verify arguments */
798 if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0;
799
800 /* Lock the DC */
801 if (!(pdc = DC_LockDc(hdc))) return 0;
802
803 /* Get the return value */
804 ret = DCB_RESET; /* we don't have device-specific bounds */
805 ret = (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR) ? DCB_ENABLE : DCB_DISABLE) |
806 (RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? ret & DCB_SET : DCB_SET );
807 ret |= (flags & DCB_WINDOWMGR);
808
809 if (flags & DCB_RESET)
810 {
811 if (!(flags & DCB_WINDOWMGR))
812 {
813 pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
814 pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
815 }
816 else
817 {
818 pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
819 pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
820 }
821 }
822
823 if (flags & DCB_ACCUMULATE && prc != NULL)
824 {
825 /* Capture the rect */
826 _SEH2_TRY
827 {
828 ProbeForRead(prc, sizeof(RECT), 1);
829 rcl = *prc;
830 }
831 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
832 {
833 DC_UnlockDc(pdc);
834 _SEH2_YIELD(return 0;)
835 }
836 _SEH2_END;
837
838 RECTL_vMakeWellOrdered(&rcl);
839
840 if (!(flags & DCB_WINDOWMGR))
841 {
842 IntLPtoDP( pdc, (POINT *)&rcl, 2 );
843 RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl);
844 }
845 else
846 RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, &rcl);
847 }
848
849 if (flags & DCB_ENABLE)
850 {
851 if (!(flags & DCB_WINDOWMGR))
852 pdc->fs |= DC_ACCUM_APP;
853 else
854 pdc->fs |= DC_ACCUM_WMGR;
855 }
856 if (flags & DCB_DISABLE)
857 {
858 if (!(flags & DCB_WINDOWMGR))
859 pdc->fs &= ~DC_ACCUM_APP;
860 else
861 pdc->fs &= ~DC_ACCUM_WMGR;
862 }
863 DC_UnlockDc(pdc);
864 return ret;
865 }
866
867 /* Translates a COLORREF to the right color in the specified DC color space */
868 ULONG
TranslateCOLORREF(PDC pdc,COLORREF crColor)869 TranslateCOLORREF(PDC pdc, COLORREF crColor)
870 {
871 PSURFACE psurfDC;
872 PPALETTE ppalDC;
873 ULONG index, ulColor, iBitmapFormat;
874 EXLATEOBJ exlo;
875
876 /* Get the DC surface */
877 psurfDC = pdc->dclevel.pSurface;
878
879 /* If no surface is selected, use the default bitmap */
880 if (!psurfDC)
881 psurfDC = psurfDefaultBitmap;
882
883 /* Check what color type this is */
884 switch (crColor >> 24)
885 {
886 case 0x00: /* RGB color */
887 break;
888
889 case 0x01: /* PALETTEINDEX */
890 index = crColor & 0xFFFFFF;
891 ppalDC = pdc->dclevel.ppal;
892 if (index >= ppalDC->NumColors) index = 0;
893
894 /* Get the RGB value */
895 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
896 break;
897
898 case 0x02: /* PALETTERGB */
899
900 if (pdc->dclevel.hpal != StockObjects[DEFAULT_PALETTE])
901 {
902 /* First find the nearest index in the dc palette */
903 ppalDC = pdc->dclevel.ppal;
904 index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF);
905
906 /* Get the RGB value */
907 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
908 }
909 else
910 {
911 /* Use the pure color */
912 crColor = crColor & 0x00FFFFFF;
913 }
914 break;
915
916 case 0x10: /* DIBINDEX */
917 /* Mask the value to match the target bpp */
918 iBitmapFormat = psurfDC->SurfObj.iBitmapFormat;
919 if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1;
920 else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf;
921 else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF;
922 else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF;
923 else index = crColor & 0xFFFFFF;
924 return index;
925
926 default:
927 DPRINT("Unsupported color type %u passed\n", crColor >> 24);
928 crColor &= 0xFFFFFF;
929 }
930
931 /* Initialize an XLATEOBJ from RGB to the target surface */
932 EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurfDC->ppal, 0xFFFFFF, 0, 0);
933
934 /* Translate the color to the target format */
935 ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
936
937 /* Cleanup the XLATEOBJ */
938 EXLATEOBJ_vCleanup(&exlo);
939
940 return ulColor;
941 }
942
943
944