2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: dc.c,v 1.133 2004/04/28 18:38:07 navaraf Exp $
21 * DC.C - Device context functions
25 #undef WIN32_LEAN_AND_MEAN
27 #include <ddk/ntddk.h>
28 #include <ddk/ntddvdeo.h>
29 #include <internal/safe.h>
30 #include <win32k/bitmaps.h>
31 #include <win32k/brush.h>
32 #include <win32k/cliprgn.h>
33 #include <win32k/coord.h>
34 #include <win32k/dc.h>
35 #include <win32k/misc.h>
36 #include <win32k/print.h>
37 #include <win32k/region.h>
38 #include <win32k/gdiobj.h>
39 #include <win32k/paint.h>
40 #include <win32k/color.h>
41 #include <win32k/pen.h>
42 #include <win32k/text.h>
43 #include "../eng/clip.h"
44 #include "../eng/handle.h"
45 #include <include/dce.h>
46 #include <include/error.h>
47 #include <include/inteng.h>
48 #include <include/eng.h>
49 #include <include/palette.h>
50 #include <include/guicheck.h>
51 #include <include/desktop.h>
52 #include <include/intgdi.h>
53 #include <include/cleanup.h>
54 #include <include/tags.h>
55 #include <include/text.h>
58 #include <win32k/debug1.h>
60 #ifndef OBJ_COLORSPACE
61 #define OBJ_COLORSPACE (14)
64 static GDIDEVICE PrimarySurface
;
66 /* FIXME: DCs should probably be thread safe */
69 * DC device-independent Get/SetXXX functions
70 * (RJJ) swiped from WINE
73 #define DC_GET_VAL( func_type, func_name, dc_field ) \
74 func_type STDCALL func_name( HDC hdc ) \
77 PDC dc = DC_LockDc( hdc ); \
80 SetLastWin32Error(ERROR_INVALID_HANDLE); \
88 /* DC_GET_VAL_EX is used to define functions returning a POINT or a SIZE. It is
89 * important that the function has the right signature, for the implementation
90 * we can do whatever we want.
92 #define DC_GET_VAL_EX( FuncName, ret_x, ret_y, type, ax, ay ) \
93 VOID FASTCALL Int##FuncName ( PDC dc, LP##type pt) \
100 BOOL STDCALL NtGdi##FuncName ( HDC hdc, LP##type pt ) \
107 SetLastWin32Error(ERROR_INVALID_PARAMETER); \
110 if(!(dc = DC_LockDc(hdc))) \
112 SetLastWin32Error(ERROR_INVALID_HANDLE); \
115 Int##FuncName( dc, &Safept); \
117 Status = MmCopyToCaller(pt, &Safept, sizeof( type )); \
118 if(!NT_SUCCESS(Status)) \
120 SetLastNtError(Status); \
126 #define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
127 INT STDCALL func_name( HDC hdc, INT mode ) \
131 if ((mode < min_val) || (mode > max_val)) \
133 SetLastWin32Error(ERROR_INVALID_PARAMETER); \
136 dc = DC_LockDc ( hdc ); \
139 SetLastWin32Error(ERROR_INVALID_HANDLE); \
142 prevMode = dc->dc_field; \
143 dc->dc_field = mode; \
144 DC_UnlockDc ( hdc ); \
149 // --------------------------------------------------------- File Statics
151 // ----------------------------------------------------- Public Functions
154 NtGdiCancelDC(HDC hDC
)
160 NtGdiCreateCompatableDC(HDC hDC
)
164 HDC hNewDC
, DisplayDC
;
167 UNICODE_STRING DriverName
;
172 RtlInitUnicodeString(&DriverName
, L
"DISPLAY");
173 DisplayDC
= IntGdiCreateDC(&DriverName
, NULL
, NULL
, NULL
);
174 if (NULL
== DisplayDC
)
181 /* Allocate a new DC based on the original DC's device */
182 OrigDC
= DC_LockDc(hDC
);
185 if (NULL
!= DisplayDC
)
187 NtGdiDeleteDC(DisplayDC
);
191 hNewDC
= DC_AllocDC(&OrigDC
->DriverName
);
196 if (NULL
!= DisplayDC
)
198 NtGdiDeleteDC(DisplayDC
);
202 NewDC
= DC_LockDc( hNewDC
);
204 /* Copy information from original DC to new DC */
205 NewDC
->hSelf
= hNewDC
;
207 NewDC
->PDev
= OrigDC
->PDev
;
208 NewDC
->DMW
= OrigDC
->DMW
;
209 memcpy(NewDC
->FillPatternSurfaces
,
210 OrigDC
->FillPatternSurfaces
,
211 sizeof OrigDC
->FillPatternSurfaces
);
212 NewDC
->GDIInfo
= OrigDC
->GDIInfo
;
213 NewDC
->DevInfo
= OrigDC
->DevInfo
;
214 NewDC
->w
.bitsPerPixel
= OrigDC
->w
.bitsPerPixel
;
216 /* DriverName is copied in the AllocDC routine */
217 NewDC
->DeviceDriver
= OrigDC
->DeviceDriver
;
218 NewDC
->wndOrgX
= OrigDC
->wndOrgX
;
219 NewDC
->wndOrgY
= OrigDC
->wndOrgY
;
220 NewDC
->wndExtX
= OrigDC
->wndExtX
;
221 NewDC
->wndExtY
= OrigDC
->wndExtY
;
222 NewDC
->vportOrgX
= OrigDC
->vportOrgX
;
223 NewDC
->vportOrgY
= OrigDC
->vportOrgY
;
224 NewDC
->vportExtX
= OrigDC
->vportExtX
;
225 NewDC
->vportExtY
= OrigDC
->vportExtY
;
227 /* Create default bitmap */
228 if (!(hBitmap
= NtGdiCreateBitmap( 1, 1, 1, NewDC
->w
.bitsPerPixel
, NULL
)))
231 DC_UnlockDc( hNewDC
);
233 if (NULL
!= DisplayDC
)
235 NtGdiDeleteDC(DisplayDC
);
239 NewDC
->w
.flags
= DC_MEMORY
;
240 NewDC
->w
.hBitmap
= hBitmap
;
241 NewDC
->w
.hFirstBitmap
= hBitmap
;
242 NewDC
->GDIDevice
= OrigDC
->GDIDevice
;
243 pb
= BITMAPOBJ_LockBitmap(hBitmap
);
244 NewDC
->Surface
= (HSURF
)BitmapToSurf(pb
, NewDC
->GDIDevice
);
245 BITMAPOBJ_UnlockBitmap(hBitmap
);
247 NewDC
->w
.hPalette
= OrigDC
->w
.hPalette
;
248 NewDC
->w
.textColor
= OrigDC
->w
.textColor
;
249 NewDC
->w
.textAlign
= OrigDC
->w
.textAlign
;
250 NewDC
->w
.backgroundColor
= OrigDC
->w
.backgroundColor
;
251 NewDC
->w
.backgroundMode
= OrigDC
->w
.backgroundMode
;
253 if (NULL
!= DisplayDC
)
255 NtGdiDeleteDC(DisplayDC
);
259 hVisRgn
= NtGdiCreateRectRgn(0, 0, 1, 1);
260 NtGdiSelectVisRgn(hNewDC
, hVisRgn
);
261 NtGdiDeleteObject(hVisRgn
);
269 GetRegistryPath(PUNICODE_STRING RegistryPath
, ULONG DisplayNumber
)
271 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
272 WCHAR DeviceNameBuffer
[20];
275 swprintf(DeviceNameBuffer
, L
"\\Device\\Video%d", DisplayNumber
);
276 RtlInitUnicodeString(RegistryPath
, NULL
);
277 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
278 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
279 QueryTable
[0].Name
= DeviceNameBuffer
;
280 QueryTable
[0].EntryContext
= RegistryPath
;
282 Status
= RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP
,
287 if (! NT_SUCCESS(Status
))
289 DPRINT1("No \\Device\\Video%d value in DEVICEMAP\\VIDEO found\n", DisplayNumber
);
293 DPRINT("RegistryPath %S\n", RegistryPath
->Buffer
);
299 FindDriverFileNames(PUNICODE_STRING DriverFileNames
, ULONG DisplayNumber
)
301 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
302 UNICODE_STRING RegistryPath
;
305 if (! GetRegistryPath(&RegistryPath
, DisplayNumber
))
307 DPRINT("GetRegistryPath failed\n");
311 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
312 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
313 QueryTable
[0].Name
= L
"InstalledDisplayDrivers";
314 QueryTable
[0].EntryContext
= DriverFileNames
;
316 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
321 RtlFreeUnicodeString(&RegistryPath
);
322 if (! NT_SUCCESS(Status
))
324 DPRINT1("No InstalledDisplayDrivers value in service entry found\n");
328 DPRINT("DriverFileNames %S\n", DriverFileNames
->Buffer
);
333 static NTSTATUS STDCALL
334 DevModeCallback(IN PWSTR ValueName
,
337 IN ULONG ValueLength
,
339 IN PVOID EntryContext
)
341 PDEVMODEW DevMode
= (PDEVMODEW
) Context
;
343 DPRINT("Found registry value for name %S: type %d, length %d\n",
344 ValueName
, ValueType
, ValueLength
);
346 if (REG_DWORD
== ValueType
&& sizeof(DWORD
) == ValueLength
)
348 if (0 == _wcsicmp(ValueName
, L
"DefaultSettings.BitsPerPel"))
350 DevMode
->dmBitsPerPel
= *((DWORD
*) ValueData
);
352 else if (0 == _wcsicmp(ValueName
, L
"DefaultSettings.Flags"))
354 DevMode
->dmDisplayFlags
= *((DWORD
*) ValueData
);
356 else if (0 == _wcsicmp(ValueName
, L
"DefaultSettings.VRefresh"))
358 DevMode
->dmDisplayFrequency
= *((DWORD
*) ValueData
);
360 else if (0 == _wcsicmp(ValueName
, L
"DefaultSettings.XPanning"))
362 DevMode
->dmPanningWidth
= *((DWORD
*) ValueData
);
364 else if (0 == _wcsicmp(ValueName
, L
"DefaultSettings.XResolution"))
366 DevMode
->dmPelsWidth
= *((DWORD
*) ValueData
);
368 else if (0 == _wcsicmp(ValueName
, L
"DefaultSettings.YPanning"))
370 DevMode
->dmPanningHeight
= *((DWORD
*) ValueData
);
372 else if (0 == _wcsicmp(ValueName
, L
"DefaultSettings.YResolution"))
374 DevMode
->dmPelsHeight
= *((DWORD
*) ValueData
);
378 return STATUS_SUCCESS
;
382 SetupDevMode(PDEVMODEW DevMode
, ULONG DisplayNumber
)
384 static WCHAR RegistryMachineSystem
[] = L
"\\REGISTRY\\MACHINE\\SYSTEM\\";
385 static WCHAR CurrentControlSet
[] = L
"CURRENTCONTROLSET\\";
386 static WCHAR ControlSet
[] = L
"CONTROLSET";
387 static WCHAR Insert
[] = L
"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
388 UNICODE_STRING RegistryPath
;
390 PWCHAR AfterControlSet
;
392 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
395 if (! GetRegistryPath(&RegistryPath
, DisplayNumber
))
397 DPRINT("GetRegistryPath failed\n");
401 Valid
= (0 == _wcsnicmp(RegistryPath
.Buffer
, RegistryMachineSystem
,
402 wcslen(RegistryMachineSystem
)));
405 AfterControlSet
= RegistryPath
.Buffer
+ wcslen(RegistryMachineSystem
);
406 if (0 == _wcsnicmp(AfterControlSet
, CurrentControlSet
, wcslen(CurrentControlSet
)))
408 AfterControlSet
+= wcslen(CurrentControlSet
);
410 else if (0 == _wcsnicmp(AfterControlSet
, ControlSet
, wcslen(ControlSet
)))
412 AfterControlSet
+= wcslen(ControlSet
);
413 while (L
'0' <= *AfterControlSet
&& L
'9' <= *AfterControlSet
)
417 Valid
= (L
'\\' == *AfterControlSet
);
428 ProfilePath
= ExAllocatePoolWithTag(PagedPool
,
429 (wcslen(RegistryPath
.Buffer
) +
430 wcslen(Insert
) + 1) * sizeof(WCHAR
),
432 if (NULL
!= ProfilePath
)
434 wcsncpy(ProfilePath
, RegistryPath
.Buffer
, AfterControlSet
- RegistryPath
.Buffer
);
435 wcscpy(ProfilePath
+ (AfterControlSet
- RegistryPath
.Buffer
), Insert
);
436 wcscat(ProfilePath
, AfterControlSet
);
438 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
439 QueryTable
[0].QueryRoutine
= DevModeCallback
;
440 QueryTable
[0].Flags
= 0;
441 QueryTable
[0].Name
= NULL
;
442 QueryTable
[0].EntryContext
= NULL
;
443 QueryTable
[0].DefaultType
= REG_NONE
;
444 QueryTable
[0].DefaultData
= NULL
;
445 QueryTable
[0].DefaultLength
= 0;
447 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
452 if (! NT_SUCCESS(Status
))
454 DPRINT("RtlQueryRegistryValues for %S failed with status 0x%08x\n",
455 ProfilePath
, Status
);
460 DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
461 DevMode
->dmBitsPerPel
, DevMode
->dmDisplayFrequency
,
462 DevMode
->dmPelsWidth
, DevMode
->dmPelsHeight
);
463 if (0 == DevMode
->dmBitsPerPel
|| 0 == DevMode
->dmDisplayFrequency
464 || 0 == DevMode
->dmPelsWidth
|| 0 == DevMode
->dmPelsHeight
)
466 DPRINT("Not all required devmode members are set\n");
471 ExFreePool(ProfilePath
);
480 DPRINT1("Unparsable registry path %S in DEVICEMAP\\VIDEO0", RegistryPath
.Buffer
);
483 RtlFreeUnicodeString(&RegistryPath
);
487 RtlZeroMemory(DevMode
, sizeof(DEVMODEW
));
494 IntCreatePrimarySurface()
496 PGD_ENABLEDRIVER GDEnableDriver
;
500 UNICODE_STRING DriverFileNames
;
506 for (DisplayNumber
= 0; ; DisplayNumber
++)
508 DPRINT("Trying to load display driver no. %d\n", DisplayNumber
);
510 RtlZeroMemory(&PrimarySurface
, sizeof(PrimarySurface
));
511 ExInitializeFastMutex(&PrimarySurface
.DriverLock
);
513 PrimarySurface
.VideoFileObject
= DRIVER_FindMPDriver(DisplayNumber
);
515 /* Open the miniport driver */
516 if (PrimarySurface
.VideoFileObject
== NULL
)
518 DPRINT1("FindMPDriver failed\n");
522 /* Retrieve DDI driver names from registry */
523 RtlInitUnicodeString(&DriverFileNames
, NULL
);
524 if (!FindDriverFileNames(&DriverFileNames
, DisplayNumber
))
526 DPRINT1("FindDriverFileNames failed\n");
532 * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
533 * scan all of them until a good one found.
535 CurrentName
= DriverFileNames
.Buffer
;
538 CurrentName
< DriverFileNames
.Buffer
+ DriverFileNames
.Length
)
540 /* Get the DDI driver's entry point */
541 GDEnableDriver
= DRIVER_FindDDIDriver(CurrentName
);
542 if (NULL
== GDEnableDriver
)
544 DPRINT("FindDDIDriver failed for %S\n", CurrentName
);
548 /* Call DDI driver's EnableDriver function */
549 RtlZeroMemory(&DED
, sizeof(DED
));
551 if (! GDEnableDriver(DDI_DRIVER_VERSION_NT5_01
, sizeof(DED
), &DED
))
553 DPRINT("DrvEnableDriver failed for %S\n", CurrentName
);
563 /* Skip to the next name but never get past the Unicode string */
564 while (L
'\0' != *CurrentName
&&
565 CurrentName
< DriverFileNames
.Buffer
+ DriverFileNames
.Length
)
569 if (CurrentName
< DriverFileNames
.Buffer
+ DriverFileNames
.Length
)
576 RtlFreeUnicodeString(&DriverFileNames
);
580 ObDereferenceObject(PrimarySurface
.VideoFileObject
);
581 DPRINT1("No suitable DDI driver found\n");
586 DPRINT("Display driver %S loaded\n", CurrentName
);
588 DPRINT("Building DDI Functions\n");
590 /* Construct DDI driver function dispatch table */
591 if (!DRIVER_BuildDDIFunctions(&DED
, &PrimarySurface
.DriverFunctions
))
593 ObDereferenceObject(PrimarySurface
.VideoFileObject
);
594 DPRINT1("BuildDDIFunctions failed\n");
598 /* Allocate a phyical device handle from the driver */
599 if (SetupDevMode(&PrimarySurface
.DMW
, DisplayNumber
))
601 PrimarySurface
.PDev
= PrimarySurface
.DriverFunctions
.EnablePDev(
605 PrimarySurface
.FillPatterns
,
606 sizeof(PrimarySurface
.GDIInfo
),
607 (ULONG
*) &PrimarySurface
.GDIInfo
,
608 sizeof(PrimarySurface
.DevInfo
),
609 &PrimarySurface
.DevInfo
,
612 (HANDLE
) (PrimarySurface
.VideoFileObject
->DeviceObject
));
613 DoDefault
= (NULL
== PrimarySurface
.PDev
);
616 DPRINT1("DrvEnablePDev with registry parameters failed\n");
626 RtlZeroMemory(&(PrimarySurface
.DMW
), sizeof(DEVMODEW
));
627 PrimarySurface
.PDev
= PrimarySurface
.DriverFunctions
.EnablePDev(
631 PrimarySurface
.FillPatterns
,
632 sizeof(PrimarySurface
.GDIInfo
),
633 (ULONG
*) &PrimarySurface
.GDIInfo
,
634 sizeof(PrimarySurface
.DevInfo
),
635 &PrimarySurface
.DevInfo
,
638 (HANDLE
) (PrimarySurface
.VideoFileObject
->DeviceObject
));
640 if (NULL
== PrimarySurface
.PDev
)
642 ObDereferenceObject(PrimarySurface
.VideoFileObject
);
643 DPRINT1("DrvEnablePDEV with default parameters failed\n");
644 DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
650 if (0 == PrimarySurface
.GDIInfo
.ulLogPixelsX
)
652 DPRINT("Adjusting GDIInfo.ulLogPixelsX\n");
653 PrimarySurface
.GDIInfo
.ulLogPixelsX
= 96;
655 if (0 == PrimarySurface
.GDIInfo
.ulLogPixelsY
)
657 DPRINT("Adjusting GDIInfo.ulLogPixelsY\n");
658 PrimarySurface
.GDIInfo
.ulLogPixelsY
= 96;
661 DPRINT("calling completePDev\n");
663 /* Complete initialization of the physical device */
664 PrimarySurface
.DriverFunctions
.CompletePDev(
666 (HDEV
)&PrimarySurface
);
668 DPRINT("calling DRIVER_ReferenceDriver\n");
670 DRIVER_ReferenceDriver(L
"DISPLAY");
672 DPRINT("calling EnableSurface\n");
674 /* Enable the drawing surface */
675 PrimarySurface
.Handle
=
676 PrimarySurface
.DriverFunctions
.EnableSurface(PrimarySurface
.PDev
);
677 if (NULL
== PrimarySurface
.Handle
)
679 /* PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);*/
680 PrimarySurface
.DriverFunctions
.DisablePDev(PrimarySurface
.PDev
);
681 ObDereferenceObject(PrimarySurface
.VideoFileObject
);
682 DPRINT1("DrvEnableSurface failed\n");
687 SurfObj
= (SURFOBJ
*)AccessUserObject((ULONG
) PrimarySurface
.Handle
);
688 SurfObj
->dhpdev
= PrimarySurface
.PDev
;
689 SurfGDI
= (PSURFGDI
)AccessInternalObject((ULONG
) PrimarySurface
.Handle
);
691 IntGetActiveDesktop(),
692 SurfGDI
->SurfObj
.sizlBitmap
.cx
,
693 SurfGDI
->SurfObj
.sizlBitmap
.cy
);
701 IntDestroyPrimarySurface()
708 DRIVER_UnreferenceDriver(L
"DISPLAY");
711 DPRINT("Hiding mouse pointer\n" );
712 SurfObj
= (SURFOBJ
*)AccessUserObject((ULONG
) PrimarySurface
.Handle
);
713 SurfGDI
= (PSURFGDI
)AccessInternalObject((ULONG
) PrimarySurface
.Handle
);
714 SurfGDI
->SetPointerShape(SurfObj
, NULL
, NULL
, NULL
, 0, 0, 0, 0, 0, 0);
716 DPRINT("Reseting display\n" );
717 PrimarySurface
.DriverFunctions
.AssertMode(PrimarySurface
.PDev
, FALSE
);
718 PrimarySurface
.DriverFunctions
.DisableSurface(PrimarySurface
.PDev
);
719 PrimarySurface
.DriverFunctions
.DisablePDev(PrimarySurface
.PDev
);
723 ObDereferenceObject(PrimarySurface
.VideoFileObject
);
727 IntGdiCreateDC(PUNICODE_STRING Driver
,
728 PUNICODE_STRING Device
,
729 PUNICODE_STRING Output
,
730 CONST PDEVMODEW InitData
)
737 UNICODE_STRING StdDriver
;
739 RtlInitUnicodeString(&StdDriver
, L
"DISPLAY");
741 if (NULL
== Driver
|| 0 == RtlCompareUnicodeString(Driver
, &StdDriver
, TRUE
))
743 if (! IntGraphicsCheck(TRUE
))
745 DPRINT1("Unable to initialize graphics, returning NULL dc\n");
750 /* Check for existing DC object */
751 if ((hNewDC
= DC_FindOpenDC(Driver
)) != NULL
)
754 return NtGdiCreateCompatableDC(hDC
);
757 if (Driver
!= NULL
&& Driver
->Buffer
!= NULL
)
759 DPRINT("NAME: %S\n", Driver
->Buffer
); // FIXME: Should not crash if NULL
762 /* Allocate a DC object */
763 if ((hNewDC
= DC_AllocDC(Driver
)) == NULL
)
768 NewDC
= DC_LockDc( hNewDC
);
771 NewDC
->DMW
= PrimarySurface
.DMW
;
772 NewDC
->DevInfo
= &PrimarySurface
.DevInfo
;
773 NewDC
->GDIInfo
= &PrimarySurface
.GDIInfo
;
774 memcpy(NewDC
->FillPatternSurfaces
, PrimarySurface
.FillPatterns
,
775 sizeof(NewDC
->FillPatternSurfaces
));
776 NewDC
->PDev
= PrimarySurface
.PDev
;
777 NewDC
->Surface
= PrimarySurface
.Handle
;
778 NewDC
->GDIDevice
= (HDEV
)&PrimarySurface
;
779 NewDC
->DriverFunctions
= PrimarySurface
.DriverFunctions
;
781 NewDC
->DMW
.dmSize
= sizeof(NewDC
->DMW
);
782 NewDC
->DMW
.dmFields
= 0x000fc000;
784 /* FIXME: get mode selection information from somewhere */
786 NewDC
->DMW
.dmLogPixels
= 96;
787 SurfGDI
= (PSURFGDI
)AccessInternalObject((ULONG
) PrimarySurface
.Handle
);
788 NewDC
->DMW
.dmBitsPerPel
= SurfGDI
->BitsPerPixel
;
789 NewDC
->DMW
.dmPelsWidth
= SurfGDI
->SurfObj
.sizlBitmap
.cx
;
790 NewDC
->DMW
.dmPelsHeight
= SurfGDI
->SurfObj
.sizlBitmap
.cy
;
791 NewDC
->DMW
.dmDisplayFlags
= 0;
792 NewDC
->DMW
.dmDisplayFrequency
= 0;
794 NewDC
->w
.bitsPerPixel
= SurfGDI
->BitsPerPixel
; // FIXME: set this here??
796 NewDC
->w
.hPalette
= NewDC
->DevInfo
->hpalDefault
;
798 DPRINT("Bits per pel: %u\n", NewDC
->w
.bitsPerPixel
);
800 DC_UnlockDc( hNewDC
);
802 hVisRgn
= NtGdiCreateRectRgn(0, 0, SurfGDI
->SurfObj
.sizlBitmap
.cx
,
803 SurfGDI
->SurfObj
.sizlBitmap
.cy
);
804 NtGdiSelectVisRgn(hNewDC
, hVisRgn
);
805 NtGdiDeleteObject(hVisRgn
);
807 /* Initialize the DC state */
809 NtGdiSetTextColor(hNewDC
, RGB(0, 0, 0));
810 NtGdiSetTextAlign(hNewDC
, TA_TOP
);
811 NtGdiSetBkColor(hNewDC
, RGB(255, 255, 255));
812 NtGdiSetBkMode(hNewDC
, OPAQUE
);
818 NtGdiCreateDC(PUNICODE_STRING Driver
,
819 PUNICODE_STRING Device
,
820 PUNICODE_STRING Output
,
821 CONST PDEVMODEW InitData
)
823 UNICODE_STRING SafeDriver
, SafeDevice
;
824 DEVMODEW SafeInitData
;
830 Status
= MmCopyFromCaller(&SafeInitData
, InitData
, sizeof(DEVMODEW
));
831 if(!NT_SUCCESS(Status
))
833 SetLastNtError(Status
);
836 /* FIXME - InitData can have some more bytes! */
841 Status
= IntSafeCopyUnicodeString(&SafeDriver
, Driver
);
842 if(!NT_SUCCESS(Status
))
844 SetLastNtError(Status
);
851 Status
= IntSafeCopyUnicodeString(&SafeDevice
, Device
);
852 if(!NT_SUCCESS(Status
))
854 RtlFreeUnicodeString(&SafeDriver
);
855 SetLastNtError(Status
);
860 Ret
= IntGdiCreateDC(&SafeDriver
, &SafeDevice
, NULL
, &SafeInitData
);
866 NtGdiCreateIC(PUNICODE_STRING Driver
,
867 PUNICODE_STRING Device
,
868 PUNICODE_STRING Output
,
869 CONST PDEVMODEW DevMode
)
871 /* FIXME: this should probably do something else... */
872 return NtGdiCreateDC(Driver
, Device
, Output
, DevMode
);
876 NtGdiDeleteDC(HDC DCHandle
)
880 DCToDelete
= DC_LockDc(DCHandle
);
881 if (DCToDelete
== NULL
)
885 DPRINT( "Deleting DC\n" );
887 /* First delete all saved DCs */
888 while (DCToDelete
->saveLevel
)
893 savedHDC
= DC_GetNextDC (DCToDelete
);
894 savedDC
= DC_LockDc (savedHDC
);
899 DC_SetNextDC (DCToDelete
, DC_GetNextDC (savedDC
));
900 DCToDelete
->saveLevel
--;
901 DC_UnlockDc( savedHDC
);
902 NtGdiDeleteDC (savedHDC
);
905 /* Free GDI resources allocated to this DC */
906 if (!(DCToDelete
->w
.flags
& DC_SAVED
))
909 NtGdiSelectObject (DCHandle, STOCK_BLACK_PEN);
910 NtGdiSelectObject (DCHandle, STOCK_WHITE_BRUSH);
911 NtGdiSelectObject (DCHandle, STOCK_SYSTEM_FONT);
912 DC_LockDC (DCHandle); NtGdiSelectObject does not recognize stock objects yet */
913 if (DCToDelete
->w
.flags
& DC_MEMORY
)
915 EngDeleteSurface (DCToDelete
->Surface
);
916 NtGdiDeleteObject (DCToDelete
->w
.hFirstBitmap
);
919 if (DCToDelete
->w
.hClipRgn
)
921 NtGdiDeleteObject (DCToDelete
->w
.hClipRgn
);
923 if (DCToDelete
->w
.hVisRgn
)
925 NtGdiDeleteObject (DCToDelete
->w
.hVisRgn
);
927 if (NULL
!= DCToDelete
->CombinedClip
)
929 IntEngDeleteClipRegion(DCToDelete
->CombinedClip
);
931 if (DCToDelete
->w
.hGCClipRgn
)
933 NtGdiDeleteObject (DCToDelete
->w
.hGCClipRgn
);
936 PATH_DestroyGdiPath (&DCToDelete
->w
.path
);
938 DC_UnlockDc( DCHandle
);
939 DC_FreeDC ( DCHandle
);
945 NtGdiDrawEscape(HDC hDC
,
954 NtGdiEnumObjects(HDC hDC
,
956 GOBJENUMPROC ObjectFunc
,
962 DC_GET_VAL( COLORREF
, NtGdiGetBkColor
, w
.backgroundColor
)
963 DC_GET_VAL( INT
, NtGdiGetBkMode
, w
.backgroundMode
)
964 DC_GET_VAL_EX( GetBrushOrgEx
, w
.brushOrgX
, w
.brushOrgY
, POINT
, x
, y
)
965 DC_GET_VAL( HRGN
, NtGdiGetClipRgn
, w
.hClipRgn
)
968 NtGdiGetCurrentObject(HDC hDC
, UINT ObjectType
)
973 if(!(dc
= DC_LockDc(hDC
)))
975 SetLastWin32Error(ERROR_INVALID_HANDLE
);
982 SelObject
= dc
->w
.hPen
;
985 SelObject
= dc
->w
.hBrush
;
988 DPRINT1("FIXME: NtGdiGetCurrentObject() ObjectType OBJ_PAL not supported yet!\n");
991 SelObject
= dc
->w
.hFont
;
994 SelObject
= dc
->w
.hBitmap
;
997 DPRINT1("FIXME: NtGdiGetCurrentObject() ObjectType OBJ_COLORSPACE not supported yet!\n");
1001 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1009 DC_GET_VAL_EX ( GetCurrentPositionEx
, w
.CursPosX
, w
.CursPosY
, POINT
, x
, y
)
1012 IntGdiGetDCOrgEx(DC
*dc
, LPPOINT Point
)
1014 Point
->x
= dc
->w
.DCOrgX
;
1015 Point
->y
= dc
->w
.DCOrgY
;
1021 NtGdiGetDCOrgEx(HDC hDC
, LPPOINT Point
)
1030 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1034 dc
= DC_LockDc(hDC
);
1037 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1041 Ret
= IntGdiGetDCOrgEx(dc
, &SafePoint
);
1043 Status
= MmCopyToCaller(Point
, &SafePoint
, sizeof(POINT
));
1044 if(!NT_SUCCESS(Status
))
1046 SetLastNtError(Status
);
1056 NtGdiSetBkColor(HDC hDC
, COLORREF color
)
1062 if (!(dc
= DC_LockDc(hDC
)))
1064 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1068 oldColor
= dc
->w
.backgroundColor
;
1069 dc
->w
.backgroundColor
= color
;
1070 hBrush
= dc
->w
.hBrush
;
1071 DC_UnlockDc ( hDC
);
1072 NtGdiSelectObject(hDC
, hBrush
);
1077 NtGdiGetDCState(HDC hDC
)
1082 dc
= DC_LockDc(hDC
);
1085 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1089 hnewdc
= DC_AllocDC(NULL
);
1095 newdc
= DC_LockDc( hnewdc
);
1098 newdc
->w
.flags
= dc
->w
.flags
| DC_SAVED
;
1099 newdc
->w
.hPen
= dc
->w
.hPen
;
1100 newdc
->w
.hBrush
= dc
->w
.hBrush
;
1101 newdc
->w
.hFont
= dc
->w
.hFont
;
1102 newdc
->w
.hBitmap
= dc
->w
.hBitmap
;
1103 newdc
->w
.hFirstBitmap
= dc
->w
.hFirstBitmap
;
1105 newdc
->w
.hDevice
= dc
->w
.hDevice
;
1107 newdc
->w
.hPalette
= dc
->w
.hPalette
;
1108 newdc
->w
.totalExtent
= dc
->w
.totalExtent
;
1109 newdc
->w
.bitsPerPixel
= dc
->w
.bitsPerPixel
;
1110 newdc
->w
.ROPmode
= dc
->w
.ROPmode
;
1111 newdc
->w
.polyFillMode
= dc
->w
.polyFillMode
;
1112 newdc
->w
.stretchBltMode
= dc
->w
.stretchBltMode
;
1113 newdc
->w
.relAbsMode
= dc
->w
.relAbsMode
;
1114 newdc
->w
.backgroundMode
= dc
->w
.backgroundMode
;
1115 newdc
->w
.backgroundColor
= dc
->w
.backgroundColor
;
1116 newdc
->w
.textColor
= dc
->w
.textColor
;
1117 newdc
->w
.brushOrgX
= dc
->w
.brushOrgX
;
1118 newdc
->w
.brushOrgY
= dc
->w
.brushOrgY
;
1119 newdc
->w
.textAlign
= dc
->w
.textAlign
;
1120 newdc
->w
.charExtra
= dc
->w
.charExtra
;
1121 newdc
->w
.breakTotalExtra
= dc
->w
.breakTotalExtra
;
1122 newdc
->w
.breakCount
= dc
->w
.breakCount
;
1123 newdc
->w
.breakExtra
= dc
->w
.breakExtra
;
1124 newdc
->w
.breakRem
= dc
->w
.breakRem
;
1125 newdc
->w
.MapMode
= dc
->w
.MapMode
;
1126 newdc
->w
.GraphicsMode
= dc
->w
.GraphicsMode
;
1128 /* Apparently, the DC origin is not changed by [GS]etDCState */
1129 newdc
->w
.DCOrgX
= dc
->w
.DCOrgX
;
1130 newdc
->w
.DCOrgY
= dc
->w
.DCOrgY
;
1132 newdc
->w
.CursPosX
= dc
->w
.CursPosX
;
1133 newdc
->w
.CursPosY
= dc
->w
.CursPosY
;
1134 newdc
->w
.ArcDirection
= dc
->w
.ArcDirection
;
1135 newdc
->w
.xformWorld2Wnd
= dc
->w
.xformWorld2Wnd
;
1136 newdc
->w
.xformWorld2Vport
= dc
->w
.xformWorld2Vport
;
1137 newdc
->w
.xformVport2World
= dc
->w
.xformVport2World
;
1138 newdc
->w
.vport2WorldValid
= dc
->w
.vport2WorldValid
;
1139 newdc
->wndOrgX
= dc
->wndOrgX
;
1140 newdc
->wndOrgY
= dc
->wndOrgY
;
1141 newdc
->wndExtX
= dc
->wndExtX
;
1142 newdc
->wndExtY
= dc
->wndExtY
;
1143 newdc
->vportOrgX
= dc
->vportOrgX
;
1144 newdc
->vportOrgY
= dc
->vportOrgY
;
1145 newdc
->vportExtX
= dc
->vportExtX
;
1146 newdc
->vportExtY
= dc
->vportExtY
;
1148 newdc
->hSelf
= hnewdc
;
1149 newdc
->saveLevel
= 0;
1152 PATH_InitGdiPath( &newdc
->w
.path
);
1155 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
1158 newdc
->w
.hGCClipRgn
= newdc
->w
.hVisRgn
= 0;
1162 newdc
->w
.hClipRgn
= NtGdiCreateRectRgn( 0, 0, 0, 0 );
1163 NtGdiCombineRgn( newdc
->w
.hClipRgn
, dc
->w
.hClipRgn
, 0, RGN_COPY
);
1167 newdc
->w
.hClipRgn
= 0;
1169 DC_UnlockDc( hnewdc
);
1177 NtGdiSetDCState ( HDC hDC
, HDC hDCSave
)
1181 dc
= DC_LockDc ( hDC
);
1184 dcs
= DC_LockDc ( hDCSave
);
1187 if ( dcs
->w
.flags
& DC_SAVED
)
1189 dc
->w
.flags
= dcs
->w
.flags
& ~DC_SAVED
;
1191 dc
->w
.hFirstBitmap
= dcs
->w
.hFirstBitmap
;
1194 dc
->w
.hDevice
= dcs
->w
.hDevice
;
1197 dc
->w
.totalExtent
= dcs
->w
.totalExtent
;
1198 dc
->w
.ROPmode
= dcs
->w
.ROPmode
;
1199 dc
->w
.polyFillMode
= dcs
->w
.polyFillMode
;
1200 dc
->w
.stretchBltMode
= dcs
->w
.stretchBltMode
;
1201 dc
->w
.relAbsMode
= dcs
->w
.relAbsMode
;
1202 dc
->w
.backgroundMode
= dcs
->w
.backgroundMode
;
1203 dc
->w
.backgroundColor
= dcs
->w
.backgroundColor
;
1204 dc
->w
.textColor
= dcs
->w
.textColor
;
1205 dc
->w
.brushOrgX
= dcs
->w
.brushOrgX
;
1206 dc
->w
.brushOrgY
= dcs
->w
.brushOrgY
;
1207 dc
->w
.textAlign
= dcs
->w
.textAlign
;
1208 dc
->w
.charExtra
= dcs
->w
.charExtra
;
1209 dc
->w
.breakTotalExtra
= dcs
->w
.breakTotalExtra
;
1210 dc
->w
.breakCount
= dcs
->w
.breakCount
;
1211 dc
->w
.breakExtra
= dcs
->w
.breakExtra
;
1212 dc
->w
.breakRem
= dcs
->w
.breakRem
;
1213 dc
->w
.MapMode
= dcs
->w
.MapMode
;
1214 dc
->w
.GraphicsMode
= dcs
->w
.GraphicsMode
;
1216 /* Apparently, the DC origin is not changed by [GS]etDCState */
1217 dc
->w
.DCOrgX
= dcs
->w
.DCOrgX
;
1218 dc
->w
.DCOrgY
= dcs
->w
.DCOrgY
;
1220 dc
->w
.CursPosX
= dcs
->w
.CursPosX
;
1221 dc
->w
.CursPosY
= dcs
->w
.CursPosY
;
1222 dc
->w
.ArcDirection
= dcs
->w
.ArcDirection
;
1224 dc
->w
.xformWorld2Wnd
= dcs
->w
.xformWorld2Wnd
;
1225 dc
->w
.xformWorld2Vport
= dcs
->w
.xformWorld2Vport
;
1226 dc
->w
.xformVport2World
= dcs
->w
.xformVport2World
;
1227 dc
->w
.vport2WorldValid
= dcs
->w
.vport2WorldValid
;
1229 dc
->wndOrgX
= dcs
->wndOrgX
;
1230 dc
->wndOrgY
= dcs
->wndOrgY
;
1231 dc
->wndExtX
= dcs
->wndExtX
;
1232 dc
->wndExtY
= dcs
->wndExtY
;
1233 dc
->vportOrgX
= dcs
->vportOrgX
;
1234 dc
->vportOrgY
= dcs
->vportOrgY
;
1235 dc
->vportExtX
= dcs
->vportExtX
;
1236 dc
->vportExtY
= dcs
->vportExtY
;
1238 if (!(dc
->w
.flags
& DC_MEMORY
))
1240 dc
->w
.bitsPerPixel
= dcs
->w
.bitsPerPixel
;
1244 if (dcs
->w
.hClipRgn
)
1246 if (!dc
->w
.hClipRgn
)
1248 dc
->w
.hClipRgn
= NtGdiCreateRectRgn( 0, 0, 0, 0 );
1250 NtGdiCombineRgn( dc
->w
.hClipRgn
, dcs
->w
.hClipRgn
, 0, RGN_COPY
);
1256 NtGdiDeleteObject( dc
->w
.hClipRgn
);
1261 CLIPPING_UpdateGCRegion( dc
);
1262 DC_UnlockDc ( hDC
);
1264 DC_UnlockDc ( hDC
);
1265 NtGdiSelectClipRgn(hDC
, dcs
->w
.hClipRgn
);
1268 NtGdiSelectObject( hDC
, dcs
->w
.hBitmap
);
1269 NtGdiSelectObject( hDC
, dcs
->w
.hBrush
);
1270 NtGdiSelectObject( hDC
, dcs
->w
.hFont
);
1271 NtGdiSelectObject( hDC
, dcs
->w
.hPen
);
1272 NtGdiSetBkColor( hDC
, dcs
->w
.backgroundColor
);
1273 NtGdiSetTextColor( hDC
, dcs
->w
.textColor
);
1275 NtGdiSelectPalette( hDC
, dcs
->w
.hPalette
, FALSE
);
1278 GDISelectPalette16( hDC
, dcs
->w
.hPalette
, FALSE
);
1283 DC_UnlockDc ( hDCSave
);
1285 DC_UnlockDc ( hDC
);
1286 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1290 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1294 NtGdiGetDeviceCaps(HDC hDC
,
1301 dc
= DC_LockDc(hDC
);
1304 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1308 /* Retrieve capability */
1312 ret
= dc
->GDIInfo
->ulVersion
;
1316 ret
= dc
->GDIInfo
->ulTechnology
;
1320 ret
= dc
->GDIInfo
->ulHorzSize
;
1324 ret
= dc
->GDIInfo
->ulVertSize
;
1328 ret
= dc
->GDIInfo
->ulHorzRes
;
1332 ret
= dc
->GDIInfo
->ulVertRes
;
1336 ret
= dc
->GDIInfo
->ulLogPixelsX
;
1340 ret
= dc
->GDIInfo
->ulLogPixelsY
;
1344 ret
= dc
->GDIInfo
->cBitsPixel
;
1348 ret
= dc
->GDIInfo
->cPlanes
;
1352 UNIMPLEMENTED
; /* FIXME */
1356 UNIMPLEMENTED
; /* FIXME */
1360 UNIMPLEMENTED
; /* FIXME */
1364 ret
= dc
->GDIInfo
->ulNumColors
;
1368 ret
= dc
->GDIInfo
->ulAspectX
;
1372 ret
= dc
->GDIInfo
->ulAspectY
;
1376 ret
= dc
->GDIInfo
->ulAspectXY
;
1380 UNIMPLEMENTED
; /* FIXME */
1384 UNIMPLEMENTED
; /* FIXME */
1388 ret
= dc
->GDIInfo
->ulNumPalReg
; /* FIXME not sure */
1396 UNIMPLEMENTED
; /* FIXME */
1400 if(NtGdiEscape(hDC
, GETPHYSPAGESIZE
, 0, NULL
, (LPVOID
)&pt
) > 0)
1410 case PHYSICALHEIGHT
:
1411 if(NtGdiEscape(hDC
, GETPHYSPAGESIZE
, 0, NULL
, (LPVOID
)&pt
) > 0)
1421 case PHYSICALOFFSETX
:
1422 if(NtGdiEscape(hDC
, GETPRINTINGOFFSET
, 0, NULL
, (LPVOID
)&pt
) > 0)
1432 case PHYSICALOFFSETY
:
1433 if(NtGdiEscape(hDC
, GETPRINTINGOFFSET
, 0, NULL
, (LPVOID
)&pt
) > 0)
1444 UNIMPLEMENTED
; /* FIXME */
1447 case SCALINGFACTORX
:
1448 if(NtGdiEscape(hDC
, GETSCALINGFACTOR
, 0, NULL
, (LPVOID
)&pt
) > 0)
1458 case SCALINGFACTORY
:
1459 if(NtGdiEscape(hDC
, GETSCALINGFACTOR
, 0, NULL
, (LPVOID
)&pt
) > 0)
1470 ret
= dc
->GDIInfo
->flRaster
;
1474 UNIMPLEMENTED
; /* FIXME */
1478 UNIMPLEMENTED
; /* FIXME */
1482 UNIMPLEMENTED
; /* FIXME */
1486 ret
= dc
->GDIInfo
->flTextCaps
;
1494 DPRINT("(%04x,%d): returning %d\n", hDC
, Index
, ret
);
1500 DC_GET_VAL( INT
, NtGdiGetMapMode
, w
.MapMode
)
1501 DC_GET_VAL( INT
, NtGdiGetPolyFillMode
, w
.polyFillMode
)
1504 IntGdiGetObject(HANDLE Handle
, INT Count
, LPVOID Buffer
)
1506 PGDIOBJHDR GdiObject
;
1510 GdiObject
= GDIOBJ_LockObj(Handle
, GDI_OBJECT_TYPE_DONTCARE
);
1511 if (NULL
== GdiObject
)
1513 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1517 ObjectType
= GDIOBJ_GetObjectType(Handle
);
1521 case GDI_OBJECT_TYPE_PEN
:
1522 Result
= PEN_GetObject((PENOBJ
*) GdiObject
, Count
, Buffer
);
1524 case GDI_OBJECT_TYPE_BRUSH
:
1525 Result
= BRUSH_GetObject((BRUSHOBJ
*) GdiObject
, Count
, Buffer
);
1528 case GDI_OBJECT_TYPE_BITMAP
:
1529 Result
= BITMAP_GetObject((BITMAPOBJ
*) GdiObject
, Count
, Buffer
);
1531 case GDI_OBJECT_TYPE_FONT
:
1532 Result
= FontGetObject((PTEXTOBJ
) GdiObject
, Count
, Buffer
);
1534 // Fix the LOGFONT structure for the stock fonts
1535 if (FIRST_STOCK_HANDLE
<= Handle
&& Handle
<= LAST_STOCK_HANDLE
)
1537 FixStockFontSizeW(Handle
, Count
, Buffer
);
1542 case GDI_OBJECT_TYPE_PALETTE
:
1543 Result
= PALETTE_GetObject((PALETTEOBJ
*) GdiObject
, Count
, Buffer
);
1547 DPRINT1("GDI object type 0x%08x not implemented\n", ObjectType
);
1551 GDIOBJ_UnlockObj(Handle
, GDI_OBJECT_TYPE_DONTCARE
);
1557 NtGdiGetObject(HANDLE handle
, INT count
, LPVOID buffer
)
1568 SafeBuf
= ExAllocatePoolWithTag(NonPagedPool
, count
, TAG_GDIOBJ
);
1571 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1575 Ret
= IntGdiGetObject(handle
, count
, SafeBuf
);
1577 Status
= MmCopyToCaller(buffer
, SafeBuf
, count
);
1578 ExFreePool(SafeBuf
);
1579 if(!NT_SUCCESS(Status
))
1581 SetLastNtError(Status
);
1589 NtGdiGetObjectType(HANDLE handle
)
1595 ptr
= GDIOBJ_LockObj(handle
, GDI_OBJECT_TYPE_DONTCARE
);
1598 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1602 objectType
= GDIOBJ_GetObjectType(handle
);
1605 case GDI_OBJECT_TYPE_PEN
:
1608 case GDI_OBJECT_TYPE_BRUSH
:
1611 case GDI_OBJECT_TYPE_BITMAP
:
1612 result
= OBJ_BITMAP
;
1614 case GDI_OBJECT_TYPE_FONT
:
1617 case GDI_OBJECT_TYPE_PALETTE
:
1620 case GDI_OBJECT_TYPE_REGION
:
1621 result
= OBJ_REGION
;
1623 case GDI_OBJECT_TYPE_DC
:
1626 case GDI_OBJECT_TYPE_METADC
:
1627 result
= OBJ_METADC
;
1629 case GDI_OBJECT_TYPE_METAFILE
:
1630 result
= OBJ_METAFILE
;
1632 case GDI_OBJECT_TYPE_ENHMETAFILE
:
1633 result
= OBJ_ENHMETAFILE
;
1635 case GDI_OBJECT_TYPE_ENHMETADC
:
1636 result
= OBJ_ENHMETADC
;
1638 case GDI_OBJECT_TYPE_EXTPEN
:
1639 result
= OBJ_EXTPEN
;
1641 case GDI_OBJECT_TYPE_MEMDC
:
1645 DPRINT1("Magic 0x%08x not implemented\n", objectType
);
1648 GDIOBJ_UnlockObj(handle
, GDI_OBJECT_TYPE_DONTCARE
);
1652 DC_GET_VAL( INT
, NtGdiGetRelAbs
, w
.relAbsMode
)
1653 DC_GET_VAL( INT
, NtGdiGetROP2
, w
.ROPmode
)
1654 DC_GET_VAL( INT
, NtGdiGetStretchBltMode
, w
.stretchBltMode
)
1655 DC_GET_VAL( UINT
, NtGdiGetTextAlign
, w
.textAlign
)
1656 DC_GET_VAL( COLORREF
, NtGdiGetTextColor
, w
.textColor
)
1657 DC_GET_VAL_EX( GetViewportExtEx
, vportExtX
, vportExtY
, SIZE
, cx
, cy
)
1658 DC_GET_VAL_EX( GetViewportOrgEx
, vportOrgX
, vportOrgY
, POINT
, x
, y
)
1659 DC_GET_VAL_EX( GetWindowExtEx
, wndExtX
, wndExtY
, SIZE
, cx
, cy
)
1660 DC_GET_VAL_EX( GetWindowOrgEx
, wndOrgX
, wndOrgY
, POINT
, x
, y
)
1663 NtGdiResetDC(HDC hDC
, CONST DEVMODEW
*InitData
)
1669 NtGdiRestoreDC(HDC hDC
, INT SaveLevel
)
1674 dc
= DC_LockDc(hDC
);
1677 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1681 if (SaveLevel
== -1)
1683 SaveLevel
= dc
->saveLevel
;
1686 if ((SaveLevel
< 1) || (SaveLevel
> dc
->saveLevel
))
1692 while (dc
->saveLevel
>= SaveLevel
)
1694 HDC hdcs
= DC_GetNextDC (dc
);
1696 dcs
= DC_LockDc (hdcs
);
1701 DC_SetNextDC (dcs
, DC_GetNextDC (dcs
));
1702 if (--dc
->saveLevel
< SaveLevel
)
1705 DC_UnlockDc( hdcs
);
1706 NtGdiSetDCState(hDC
, hdcs
);
1708 if (!PATH_AssignGdiPath( &dc
->w
.path
, &dcs
->w
.path
))
1710 /* FIXME: This might not be quite right, since we're
1711 * returning FALSE but still destroying the saved DC state */
1715 dc
= DC_LockDc(hDC
);
1723 DC_UnlockDc( hdcs
);
1725 NtGdiDeleteDC (hdcs
);
1732 NtGdiSaveDC(HDC hDC
)
1738 if (!(hdcs
= NtGdiGetDCState(hDC
)))
1743 dcs
= DC_LockDc (hdcs
);
1746 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1749 dc
= DC_LockDc (hDC
);
1753 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1758 /* Copy path. The reason why path saving / restoring is in SaveDC/
1759 * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
1760 * functions are only in Win16 (which doesn't have paths) and that
1761 * SetDCState doesn't allow us to signal an error (which can happen
1762 * when copying paths).
1764 if (!PATH_AssignGdiPath (&dcs
->w
.path
, &dc
->w
.path
))
1766 NtGdiDeleteDC (hdcs
);
1771 DC_SetNextDC (dcs
, DC_GetNextDC (dc
));
1772 DC_SetNextDC (dc
, hdcs
);
1773 ret
= ++dc
->saveLevel
;
1774 DC_UnlockDc( hdcs
);
1782 NtGdiSelectObject(HDC hDC
, HGDIOBJ hGDIObj
)
1784 HGDIOBJ objOrg
= NULL
; // default to failure
1793 COLORREF MonoColorMap
[2];
1794 ULONG NumColors
, Index
;
1798 if(!hDC
|| !hGDIObj
) return NULL
;
1800 dc
= DC_LockDc(hDC
);
1803 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1807 objectType
= GDIOBJ_GetObjectType(hGDIObj
);
1811 case GDI_OBJECT_TYPE_PEN
:
1813 /* Convert the color of the pen to the format of the DC */
1814 PalGDI
= PALETTE_LockPalette(dc
->w
.hPalette
);
1817 Mode
= PalGDI
->Mode
;
1818 PALETTE_UnlockPalette(dc
->w
.hPalette
);
1819 XlateObj
= (XLATEOBJ
*)IntEngCreateXlate(Mode
, PAL_RGB
, dc
->w
.hPalette
, NULL
);
1820 if (NULL
!= XlateObj
)
1822 pen
= PENOBJ_LockPen((HPEN
) hGDIObj
);
1825 if (pen
->flAttrs
& GDIBRUSH_IS_SOLID
)
1827 pen
->BrushObject
.iSolidColor
=
1828 XLATEOBJ_iXlate(XlateObj
, pen
->BrushAttr
.lbColor
);
1832 pen
->BrushObject
.iSolidColor
= 0xFFFFFFFF;
1834 pen
->crBack
= XLATEOBJ_iXlate(XlateObj
, dc
->w
.backgroundColor
);
1835 pen
->crFore
= XLATEOBJ_iXlate(XlateObj
, dc
->w
.textColor
);
1836 PENOBJ_UnlockPen((HPEN
) hGDIObj
);
1837 objOrg
= (HGDIOBJ
)dc
->w
.hPen
;
1838 dc
->w
.hPen
= hGDIObj
;
1842 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1844 EngDeleteXlate(XlateObj
);
1848 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
1853 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1857 case GDI_OBJECT_TYPE_BRUSH
:
1859 /* Convert the color of the brush to the format of the DC */
1860 PalGDI
= PALETTE_LockPalette(dc
->w
.hPalette
);
1863 Mode
= PalGDI
->Mode
;
1864 PALETTE_UnlockPalette(dc
->w
.hPalette
);
1865 XlateObj
= (XLATEOBJ
*)IntEngCreateXlate(Mode
, PAL_RGB
, dc
->w
.hPalette
, NULL
);
1866 if (NULL
!= XlateObj
)
1868 brush
= BRUSHOBJ_LockBrush((HBRUSH
) hGDIObj
);
1871 if (brush
->flAttrs
& GDIBRUSH_IS_SOLID
)
1873 brush
->BrushObject
.iSolidColor
=
1874 XLATEOBJ_iXlate(XlateObj
, brush
->BrushAttr
.lbColor
);
1878 brush
->BrushObject
.iSolidColor
= 0xFFFFFFFF;
1880 brush
->crBack
= XLATEOBJ_iXlate(XlateObj
, dc
->w
.backgroundColor
);
1881 brush
->crFore
= XLATEOBJ_iXlate(XlateObj
, ((brush
->flAttrs
& GDIBRUSH_IS_HATCH
) ?
1882 brush
->BrushAttr
.lbColor
: dc
->w
.textColor
));
1883 /* according to the documentation of SetBrushOrgEx(), the origin is assigned to the
1884 next brush selected into the DC, so we should set it here */
1885 brush
->ptOrigin
.x
= dc
->w
.brushOrgX
;
1886 brush
->ptOrigin
.y
= dc
->w
.brushOrgY
;
1888 BRUSHOBJ_UnlockBrush((HBRUSH
) hGDIObj
);
1889 objOrg
= (HGDIOBJ
)dc
->w
.hBrush
;
1890 dc
->w
.hBrush
= (HBRUSH
) hGDIObj
;
1894 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1896 EngDeleteXlate(XlateObj
);
1900 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
1905 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1909 case GDI_OBJECT_TYPE_FONT
:
1910 objOrg
= (HGDIOBJ
)dc
->w
.hFont
;
1911 dc
->w
.hFont
= (HFONT
) hGDIObj
;
1912 TextIntRealizeFont(dc
->w
.hFont
);
1915 case GDI_OBJECT_TYPE_BITMAP
:
1916 // must be memory dc to select bitmap
1917 if (!(dc
->w
.flags
& DC_MEMORY
))
1922 pb
= BITMAPOBJ_LockBitmap(hGDIObj
);
1925 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1929 objOrg
= (HGDIOBJ
)dc
->w
.hBitmap
;
1931 /* Release the old bitmap, lock the new one and convert it to a SURF */
1932 EngDeleteSurface(dc
->Surface
);
1933 dc
->w
.hBitmap
= hGDIObj
;
1934 dc
->Surface
= (HSURF
)BitmapToSurf(pb
, dc
->GDIDevice
);
1936 // if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
1939 dc
->w
.bitsPerPixel
= pb
->dib
->dsBmih
.biBitCount
;
1941 if(pb
->dib
->dsBmih
.biBitCount
<= 8)
1943 if(pb
->dib
->dsBmih
.biBitCount
== 1) { NumColors
= 2; } else
1944 if(pb
->dib
->dsBmih
.biBitCount
== 4) { NumColors
= 16; } else
1945 if(pb
->dib
->dsBmih
.biBitCount
== 8) { NumColors
= 256; }
1947 ColorMap
= ExAllocatePoolWithTag(PagedPool
, sizeof(COLORREF
) * NumColors
, TAG_DC
);
1949 for (Index
= 0; Index
< NumColors
; Index
++)
1951 ColorMap
[Index
] = RGB(pb
->ColorMap
[Index
].rgbRed
,
1952 pb
->ColorMap
[Index
].rgbGreen
,
1953 pb
->ColorMap
[Index
].rgbBlue
);
1955 dc
->w
.hPalette
= PALETTE_AllocPalette(PAL_INDEXED
, NumColors
, (ULONG
*) ColorMap
, 0, 0, 0);
1956 ExFreePool(ColorMap
);
1958 else if ( 16 == pb
->dib
->dsBmih
.biBitCount
)
1960 dc
->w
.hPalette
= PALETTE_AllocPalette(PAL_BITFIELDS
, pb
->dib
->dsBmih
.biClrUsed
, NULL
, 0x7c00, 0x03e0, 0x001f);
1962 else if(pb
->dib
->dsBmih
.biBitCount
>= 24)
1964 dc
->w
.hPalette
= PALETTE_AllocPalette(PAL_RGB
, pb
->dib
->dsBmih
.biClrUsed
, NULL
, 0, 0, 0);
1969 dc
->w
.bitsPerPixel
= pb
->bitmap
.bmBitsPixel
;
1970 if (1 == dc
->w
.bitsPerPixel
)
1972 MonoColorMap
[0] = RGB(0, 0, 0);
1973 MonoColorMap
[1] = RGB(255, 255, 255);
1974 dc
->w
.hPalette
= PALETTE_AllocPalette(PAL_INDEXED
, 2, MonoColorMap
, 0, 0, 0);
1978 dc
->w
.hPalette
= dc
->DevInfo
->hpalDefault
;
1982 DC_UnlockDc ( hDC
);
1983 hVisRgn
= NtGdiCreateRectRgn ( 0, 0, pb
->bitmap
.bmWidth
, pb
->bitmap
.bmHeight
);
1984 NtGdiSelectVisRgn ( hDC
, hVisRgn
);
1985 NtGdiDeleteObject ( hVisRgn
);
1986 BITMAPOBJ_UnlockBitmap(hGDIObj
);
1990 case GDI_OBJECT_TYPE_REGION
:
1992 return (HGDIOBJ
) NtGdiSelectClipRgn(hDC
, (HRGN
) hGDIObj
);
2002 NtGdiSetHookFlags(HDC hDC
, WORD Flags
)
2005 DC
*dc
= DC_LockDc(hDC
);
2009 SetLastWin32Error(ERROR_INVALID_HANDLE
);
2013 wRet
= dc
->w
.flags
& DC_DIRTY
;
2015 /* "Undocumented Windows" info is slightly confusing.
2018 DPRINT("DC %p, Flags %04x\n", hDC
, Flags
);
2020 if (Flags
& DCHF_INVALIDATEVISRGN
)
2022 dc
->w
.flags
|= DC_DIRTY
;
2024 else if (Flags
& DCHF_VALIDATEVISRGN
|| 0 == Flags
)
2026 dc
->w
.flags
&= ~DC_DIRTY
;
2034 DC_SET_MODE( NtGdiSetBkMode
, w
.backgroundMode
, TRANSPARENT
, OPAQUE
)
2035 DC_SET_MODE( NtGdiSetPolyFillMode
, w
.polyFillMode
, ALTERNATE
, WINDING
)
2036 // DC_SET_MODE( NtGdiSetRelAbs, w.relAbsMode, ABSOLUTE, RELATIVE )
2037 DC_SET_MODE( NtGdiSetROP2
, w
.ROPmode
, R2_BLACK
, R2_WHITE
)
2038 DC_SET_MODE( NtGdiSetStretchBltMode
, w
.stretchBltMode
, BLACKONWHITE
, HALFTONE
)
2040 // ---------------------------------------------------- Private Interface
2043 DC_AllocDC(PUNICODE_STRING Driver
)
2051 Buf
= ExAllocatePoolWithTag(PagedPool
, Driver
->MaximumLength
, TAG_DC
);
2056 RtlCopyMemory(Buf
, Driver
->Buffer
, Driver
->MaximumLength
);
2059 hDC
= (HDC
) GDIOBJ_AllocObj(sizeof(DC
), GDI_OBJECT_TYPE_DC
, (GDICLEANUPPROC
) DC_InternalDeleteDC
);
2069 NewDC
= DC_LockDc(hDC
);
2073 RtlCopyMemory(&NewDC
->DriverName
, Driver
, sizeof(UNICODE_STRING
));
2074 NewDC
->DriverName
.Buffer
= Buf
;
2077 NewDC
->w
.xformWorld2Wnd
.eM11
= 1.0f
;
2078 NewDC
->w
.xformWorld2Wnd
.eM12
= 0.0f
;
2079 NewDC
->w
.xformWorld2Wnd
.eM21
= 0.0f
;
2080 NewDC
->w
.xformWorld2Wnd
.eM22
= 1.0f
;
2081 NewDC
->w
.xformWorld2Wnd
.eDx
= 0.0f
;
2082 NewDC
->w
.xformWorld2Wnd
.eDy
= 0.0f
;
2083 NewDC
->w
.xformWorld2Vport
= NewDC
->w
.xformWorld2Wnd
;
2084 NewDC
->w
.xformVport2World
= NewDC
->w
.xformWorld2Wnd
;
2085 NewDC
->w
.vport2WorldValid
= TRUE
;
2086 NewDC
->w
.MapMode
= MM_TEXT
;
2088 NewDC
->w
.hFont
= NtGdiGetStockObject(SYSTEM_FONT
);
2089 TextIntRealizeFont(NewDC
->w
.hFont
);
2091 NewDC
->w
.hPalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
2099 DC_FindOpenDC(PUNICODE_STRING Driver
)
2105 * Initialize some common fields in the Device Context structure.
2108 DC_InitDC(HDC DCHandle
)
2110 // NtGdiRealizeDefaultPalette(DCHandle);
2112 NtGdiSelectObject(DCHandle
, NtGdiGetStockObject( WHITE_BRUSH
));
2113 NtGdiSelectObject(DCHandle
, NtGdiGetStockObject( BLACK_PEN
));
2114 //NtGdiSelectObject(DCHandle, hFont);
2116 // CLIPPING_UpdateGCRegion(DCToInit);
2121 DC_FreeDC(HDC DCToFree
)
2123 if (!GDIOBJ_FreeObj(DCToFree
, GDI_OBJECT_TYPE_DC
, GDIOBJFLAG_DEFAULT
))
2125 DPRINT("DC_FreeDC failed\n");
2130 DC_InternalDeleteDC( PDC DCToDelete
)
2133 RtlFreeUnicodeString(&DCToDelete
->DriverName
);
2138 DC_GetNextDC (PDC pDC
)
2144 DC_SetNextDC (PDC pDC
, HDC hNextDC
)
2146 pDC
->hNext
= hNextDC
;
2150 DC_UpdateXforms(PDC dc
)
2152 XFORM xformWnd2Vport
;
2153 FLOAT scaleX
, scaleY
;
2155 /* Construct a transformation to do the window-to-viewport conversion */
2156 scaleX
= (dc
->wndExtX
? (FLOAT
)dc
->vportExtX
/ (FLOAT
)dc
->wndExtX
: 0.0);
2157 scaleY
= (dc
->wndExtY
? (FLOAT
)dc
->vportExtY
/ (FLOAT
)dc
->wndExtY
: 0.0);
2158 xformWnd2Vport
.eM11
= scaleX
;
2159 xformWnd2Vport
.eM12
= 0.0;
2160 xformWnd2Vport
.eM21
= 0.0;
2161 xformWnd2Vport
.eM22
= scaleY
;
2162 xformWnd2Vport
.eDx
= (FLOAT
)dc
->vportOrgX
- scaleX
* (FLOAT
)dc
->wndOrgX
;
2163 xformWnd2Vport
.eDy
= (FLOAT
)dc
->vportOrgY
- scaleY
* (FLOAT
)dc
->wndOrgY
;
2165 /* Combine with the world transformation */
2166 IntGdiCombineTransform(&dc
->w
.xformWorld2Vport
, &dc
->w
.xformWorld2Wnd
, &xformWnd2Vport
);
2168 /* Create inverse of world-to-viewport transformation */
2169 dc
->w
.vport2WorldValid
= DC_InvertXform(&dc
->w
.xformWorld2Vport
, &dc
->w
.xformVport2World
);
2173 DC_InvertXform(const XFORM
*xformSrc
,
2178 determinant
= xformSrc
->eM11
*xformSrc
->eM22
- xformSrc
->eM12
*xformSrc
->eM21
;
2179 if (determinant
> -1e-12 && determinant
< 1e-12)
2184 xformDest
->eM11
= xformSrc
->eM22
/ determinant
;
2185 xformDest
->eM12
= -xformSrc
->eM12
/ determinant
;
2186 xformDest
->eM21
= -xformSrc
->eM21
/ determinant
;
2187 xformDest
->eM22
= xformSrc
->eM11
/ determinant
;
2188 xformDest
->eDx
= -xformSrc
->eDx
* xformDest
->eM11
- xformSrc
->eDy
* xformDest
->eM21
;
2189 xformDest
->eDy
= -xformSrc
->eDx
* xformDest
->eM12
- xformSrc
->eDy
* xformDest
->eM22
;
2195 DC_SetOwnership(HDC hDC
, PEPROCESS Owner
)
2199 GDIOBJ_SetOwnership(hDC
, Owner
);
2200 DC
= DC_LockDc(hDC
);
2203 if (NULL
!= DC
->w
.hClipRgn
)
2205 GDIOBJ_CopyOwnership(hDC
, DC
->w
.hClipRgn
);
2207 if (NULL
!= DC
->w
.hVisRgn
)
2209 GDIOBJ_CopyOwnership(hDC
, DC
->w
.hVisRgn
);
2211 if (NULL
!= DC
->w
.hGCClipRgn
)
2213 GDIOBJ_CopyOwnership(hDC
, DC
->w
.hGCClipRgn
);
2220 IntIsPrimarySurface(PSURFGDI SurfGDI
)
2222 if (PrimarySurface
.Handle
== NULL
)
2226 return SurfGDI
== (PSURFGDI
)AccessInternalObject((ULONG
) PrimarySurface
.Handle
) ? TRUE
: FALSE
;
2230 * Returns the color of the brush or pen that is currently selected into the DC.
2231 * This function is called from GetDCBrushColor() and GetDCPenColor()
2234 IntGetDCColor(HDC hDC
, ULONG Object
)
2246 if(!(dc
= DC_LockDc(hDC
)))
2248 SetLastWin32Error(ERROR_INVALID_HANDLE
);
2256 if(!(pen
= PENOBJ_LockPen(dc
->w
.hPen
)))
2261 if(!(pen
->flAttrs
& GDIBRUSH_IS_SOLID
))
2263 /* FIXME - just bail here? */
2264 PENOBJ_UnlockPen(dc
->w
.hPen
);
2268 iColor
= pen
->BrushObject
.iSolidColor
;
2269 PENOBJ_UnlockPen(dc
->w
.hPen
);
2274 if(!(brush
= BRUSHOBJ_LockBrush(dc
->w
.hBrush
)))
2279 if(!(brush
->flAttrs
& GDIBRUSH_IS_SOLID
))
2281 /* FIXME - just bail here? */
2282 BRUSHOBJ_UnlockBrush(dc
->w
.hBrush
);
2286 iColor
= brush
->BrushObject
.iSolidColor
;
2287 BRUSHOBJ_UnlockBrush(dc
->w
.hBrush
);
2293 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2298 /* translate the color into RGB */
2301 Pal
= dc
->w
.hPalette
;
2303 Result
= CLR_INVALID
;
2305 if((PalGDI
= PALETTE_LockPalette(dc
->w
.hPalette
)))
2307 Mode
= PalGDI
->Mode
;
2308 PALETTE_UnlockPalette(dc
->w
.hPalette
);
2309 XlateObj
= (XLATEOBJ
*)IntEngCreateXlate(PAL_RGB
, Mode
, NULL
, Pal
);
2312 Result
= XLATEOBJ_iXlate(XlateObj
, iColor
);
2313 EngDeleteXlate(XlateObj
);
2322 * Changes the color of the brush or pen that is currently selected into the DC.
2323 * This function is called from SetDCBrushColor() and SetDCPenColor()
2326 IntSetDCColor(HDC hDC
, ULONG Object
, COLORREF Color
)
2338 if(Color
== CLR_INVALID
)
2340 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2344 if(!(dc
= DC_LockDc(hDC
)))
2346 SetLastWin32Error(ERROR_INVALID_HANDLE
);
2354 if(!(pen
= PENOBJ_LockPen(dc
->w
.hPen
)))
2359 if(!(pen
->flAttrs
& GDIBRUSH_IS_SOLID
))
2361 /* FIXME - just bail here? */
2362 PENOBJ_UnlockPen(dc
->w
.hPen
);
2367 /* save old color index, translate it to RGB later */
2368 iColor
= pen
->BrushObject
.iSolidColor
;
2370 if(!(PalGDI
= PALETTE_LockPalette(dc
->w
.hPalette
)))
2372 PENOBJ_UnlockPen(dc
->w
.hPen
);
2376 Mode
= PalGDI
->Mode
;
2377 PALETTE_UnlockPalette(dc
->w
.hPalette
);
2378 if(!(XlateObj
= (XLATEOBJ
*)IntEngCreateXlate(Mode
, PAL_RGB
, dc
->w
.hPalette
, NULL
)))
2380 PENOBJ_UnlockPen(dc
->w
.hPen
);
2384 pen
->BrushObject
.iSolidColor
= XLATEOBJ_iXlate(XlateObj
, (ULONG
)Color
);
2385 EngDeleteXlate(XlateObj
);
2386 PENOBJ_UnlockPen(dc
->w
.hPen
);
2391 if(!(brush
= BRUSHOBJ_LockBrush(dc
->w
.hBrush
)))
2396 if(!(brush
->flAttrs
& GDIBRUSH_IS_SOLID
))
2398 /* FIXME - just bail here? */
2399 BRUSHOBJ_UnlockBrush(dc
->w
.hBrush
);
2404 /* save old color index, translate it to RGB later */
2405 iColor
= brush
->BrushObject
.iSolidColor
;
2407 if(!(PalGDI
= PALETTE_LockPalette(dc
->w
.hPalette
)))
2409 PENOBJ_UnlockPen(dc
->w
.hPen
);
2413 Mode
= PalGDI
->Mode
;
2414 PALETTE_UnlockPalette(dc
->w
.hPalette
);
2415 if(!(XlateObj
= (XLATEOBJ
*)IntEngCreateXlate(Mode
, PAL_RGB
, dc
->w
.hPalette
, NULL
)))
2417 PENOBJ_UnlockPen(dc
->w
.hPen
);
2421 brush
->BrushObject
.iSolidColor
= XLATEOBJ_iXlate(XlateObj
, (ULONG
)Color
);
2422 EngDeleteXlate(XlateObj
);
2423 BRUSHOBJ_UnlockBrush(dc
->w
.hBrush
);
2429 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2434 /* translate the old color into RGB */
2437 Pal
= dc
->w
.hPalette
;
2439 Result
= CLR_INVALID
;
2441 if((PalGDI
= PALETTE_LockPalette(dc
->w
.hPalette
)))
2443 Mode
= PalGDI
->Mode
;
2444 PALETTE_UnlockPalette(dc
->w
.hPalette
);
2445 XlateObj
= (XLATEOBJ
*)IntEngCreateXlate(PAL_RGB
, Mode
, NULL
, Pal
);
2448 Result
= XLATEOBJ_iXlate(XlateObj
, iColor
);
2449 EngDeleteXlate(XlateObj
);