6 HGDIOBJ stock_objects
[NB_STOCK_OBJECTS
]; // temp location.
10 IntCreateDICW ( LPCWSTR lpwszDriver
,
16 UNICODE_STRING Device
, Output
;
18 BOOL Display
= FALSE
, Default
= TRUE
;
23 if ((!lpwszDevice
) && (!lpwszDriver
))
25 Default
= FALSE
; // Ask Win32k to set Default device.
26 Display
= TRUE
; // Most likely to be DISPLAY.
30 if (lpwszDevice
) // First
32 if (!_wcsnicmp(lpwszDevice
, L
"\\\\.\\DISPLAY",11)) Display
= TRUE
;
33 RtlInitUnicodeString(&Device
, lpwszDevice
);
37 if (lpwszDriver
) // Second
39 if ((!_wcsnicmp(lpwszDriver
, L
"DISPLAY",7)) ||
40 (!_wcsnicmp(lpwszDriver
, L
"\\\\.\\DISPLAY",11))) Display
= TRUE
;
41 RtlInitUnicodeString(&Device
, lpwszDriver
);
46 if (lpwszOutput
) RtlInitUnicodeString(&Output
, lpwszOutput
);
50 //Handle Print device or something else.
51 DPRINT1("Not a DISPLAY device! %wZ\n", &Device
);
54 hDC
= NtGdiOpenDCW( (Default
? &Device
: NULL
),
55 (PDEVMODEW
) lpInitData
,
56 (lpwszOutput
? &Output
: NULL
),
57 iType
, // DCW 0 and ICW 1.
59 (PVOID
) NULL
, // NULL for now.
62 // Handle something other than a normal dc object.
63 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
68 GdiGetHandleUserData((HGDIOBJ
) hDC
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
);
70 pLDC
= LocalAlloc(LMEM_ZEROINIT
, sizeof(LDC
));
72 Dc_Attr
->pvLDC
= pLDC
;
74 pLDC
->iType
= LDC_LDC
; // 1 (init) local DC, 2 EMF LDC
75 DbgPrint("DC_ATTR Allocated -> 0x%x\n",Dc_Attr
);
87 CreateCompatibleDC ( HDC hdc
)
92 rhDC
= NtGdiCreateCompatibleDC(hdc
);
96 if (GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
))
98 if ( Dc_Attr
->pvLIcm
) IcmCompatibleDC(rhDC
, hdc
, Dc_Attr
);
114 CONST DEVMODEA
* lpdvmInit
117 ANSI_STRING DriverA
, DeviceA
, OutputA
;
118 UNICODE_STRING DriverU
, DeviceU
, OutputU
;
119 LPDEVMODEW dvmInitW
= NULL
;
123 * If needed, convert to Unicode
124 * any string parameter.
127 if (NULL
!= lpszDriver
)
129 RtlInitAnsiString(&DriverA
, (LPSTR
)lpszDriver
);
130 RtlAnsiStringToUnicodeString(&DriverU
, &DriverA
, TRUE
);
132 DriverU
.Buffer
= NULL
;
133 if (NULL
!= lpszDevice
)
135 RtlInitAnsiString(&DeviceA
, (LPSTR
)lpszDevice
);
136 RtlAnsiStringToUnicodeString(&DeviceU
, &DeviceA
, TRUE
);
138 DeviceU
.Buffer
= NULL
;
139 if (NULL
!= lpszOutput
)
141 RtlInitAnsiString(&OutputA
, (LPSTR
)lpszOutput
);
142 RtlAnsiStringToUnicodeString(&OutputU
, &OutputA
, TRUE
);
144 OutputU
.Buffer
= NULL
;
147 dvmInitW
= GdiConvertToDevmodeW((LPDEVMODEA
)lpdvmInit
);
149 hDC
= IntCreateDICW ( DriverU
.Buffer
,
152 lpdvmInit
? dvmInitW
: NULL
,
154 HEAP_free (dvmInitW
);
156 * Free Unicode parameters.
158 RtlFreeUnicodeString(&DriverU
);
159 RtlFreeUnicodeString(&DeviceU
);
160 RtlFreeUnicodeString(&OutputU
);
163 * Return the possible DC handle.
178 CONST DEVMODEW
*lpInitData
182 return IntCreateDICW ( lpwszDriver
,
185 (PDEVMODEW
) lpInitData
,
199 CONST DEVMODEW
*lpdvmInit
202 return IntCreateDICW ( lpszDriver
,
205 (PDEVMODEW
) lpdvmInit
,
219 CONST DEVMODEA
*lpdvmInit
223 LPWSTR lpszDriverW
, lpszDeviceW
, lpszOutputW
;
224 LPDEVMODEW dvmInitW
= NULL
;
227 Status
= HEAP_strdupA2W ( &lpszDriverW
, lpszDriver
);
228 if (!NT_SUCCESS (Status
))
229 SetLastError (RtlNtStatusToDosError(Status
));
232 Status
= HEAP_strdupA2W ( &lpszDeviceW
, lpszDevice
);
233 if (!NT_SUCCESS (Status
))
234 SetLastError (RtlNtStatusToDosError(Status
));
237 Status
= HEAP_strdupA2W ( &lpszOutputW
, lpszOutput
);
238 if (!NT_SUCCESS (Status
))
239 SetLastError (RtlNtStatusToDosError(Status
));
243 dvmInitW
= GdiConvertToDevmodeW((LPDEVMODEA
)lpdvmInit
);
245 rc
= IntCreateDICW ( lpszDriverW
,
248 lpdvmInit
? dvmInitW
: NULL
,
250 HEAP_free (dvmInitW
);
251 HEAP_free ( lpszOutputW
);
253 HEAP_free ( lpszDeviceW
);
255 HEAP_free ( lpszDriverW
);
273 if (!GdiGetHandleUserData((HGDIOBJ
) hDC
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
277 pLDC
= Dc_Attr
->pvLDC
;
281 DPRINT1("Delete the Local DC structure\n");
286 Ret
= NtGdiDeleteObjectApp(hDC
);
296 DeleteObject(HGDIOBJ hObject
)
300 /* From Wine: DeleteObject does not SetLastError() on a null object */
301 if(!hObject
) return FALSE
;
303 if (0 != ((DWORD
) hObject
& GDI_HANDLE_STOCK_MASK
))
304 { // Relax! This is a normal return!
305 DPRINT("Trying to delete system object 0x%x\n", hObject
);
308 // If you dont own it?! Get OUT!
309 if(!GdiIsHandleValid(hObject
)) return FALSE
;
311 Type
= GDI_HANDLE_GET_TYPE(hObject
);
313 if ((Type
== GDI_OBJECT_TYPE_METAFILE
) ||
314 (Type
== GDI_OBJECT_TYPE_ENHMETAFILE
))
319 case GDI_OBJECT_TYPE_DC
:
320 return DeleteDC((HDC
) hObject
);
321 case GDI_OBJECT_TYPE_COLORSPACE
:
322 return NtGdiDeleteColorSpace((HCOLORSPACE
) hObject
);
323 case GDI_OBJECT_TYPE_REGION
:
324 return DeleteRegion((HRGN
) hObject
);
326 case GDI_OBJECT_TYPE_METADC
:
327 return MFDRV_DeleteObject( hObject
);
328 case GDI_OBJECT_TYPE_EMF
:
330 PLDC pLDC
= GdiGetLDC(hObject
);
331 if ( !pLDC
) return FALSE
;
332 return EMFDRV_DeleteObject( hObject
);
335 case GDI_OBJECT_TYPE_FONT
:
338 case GDI_OBJECT_TYPE_BRUSH
:
339 case GDI_OBJECT_TYPE_EXTPEN
:
340 case GDI_OBJECT_TYPE_PEN
:
342 PBRUSH_ATTR Brh_Attr
;
345 if ((!GdiGetHandleUserData(hObject
, (DWORD
)Type
, (PVOID
) &Brh_Attr
)) ||
346 (Brh_Attr
== NULL
) ) break;
348 pTeb
= NtCurrentTeb();
350 if (pTeb
->Win32ThreadInfo
== NULL
) break;
352 if ((pTeb
->GdiTebBatch
.Offset
+ sizeof(GDIBSOBJECT
)) <= GDIBATCHBUFSIZE
)
354 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
)(&pTeb
->GdiTebBatch
.Buffer
[0] +
355 pTeb
->GdiTebBatch
.Offset
);
356 pgO
->gbHdr
.Cmd
= GdiBCDelObj
;
357 pgO
->gbHdr
.Size
= sizeof(GDIBSOBJECT
);
358 pgO
->hgdiobj
= hObject
;
360 pTeb
->GdiTebBatch
.Offset
+= sizeof(GDIBSOBJECT
);
361 pTeb
->GdiBatchCount
++;
362 if (pTeb
->GdiBatchCount
>= GDI_BatchLimit
) NtGdiFlush();
367 case GDI_OBJECT_TYPE_BITMAP
:
371 return NtGdiDeleteObjectApp(hObject
);
376 GetArcDirection( HDC hdc
)
378 return GetDCDWord( hdc
, GdiGetArcDirection
, 0);
384 SetArcDirection( HDC hdc
, INT nDirection
)
386 return GetAndSetDCDWord( hdc
, GdiGetSetArcDirection
, nDirection
, 0, 0, 0 );
392 GetDCObject( HDC hDC
, INT iType
)
394 if((iType
== GDI_OBJECT_TYPE_BRUSH
) ||
395 (iType
== GDI_OBJECT_TYPE_EXTPEN
)||
396 (iType
== GDI_OBJECT_TYPE_PEN
) ||
397 (iType
== GDI_OBJECT_TYPE_COLORSPACE
))
402 if (!hDC
) return hGO
;
404 if (!GdiGetHandleUserData((HGDIOBJ
) hDC
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return NULL
;
408 case GDI_OBJECT_TYPE_BRUSH
:
409 hGO
= Dc_Attr
->hbrush
;
412 case GDI_OBJECT_TYPE_EXTPEN
:
413 case GDI_OBJECT_TYPE_PEN
:
417 case GDI_OBJECT_TYPE_COLORSPACE
:
418 hGO
= Dc_Attr
->hColorSpace
;
423 return NtGdiGetDCObject( hDC
, iType
);
433 GetCurrentObject(HDC hdc
,
440 uObjectType
= GDI_OBJECT_TYPE_PEN
;
443 uObjectType
= GDI_OBJECT_TYPE_BRUSH
;
446 uObjectType
= GDI_OBJECT_TYPE_PALETTE
;
449 uObjectType
= GDI_OBJECT_TYPE_FONT
;
452 uObjectType
= GDI_OBJECT_TYPE_BITMAP
;
455 uObjectType
= GDI_OBJECT_TYPE_COLORSPACE
;
457 /* tests show that OBJ_REGION is explicitly ignored */
460 /* the SDK only mentions those above */
462 SetLastError(ERROR_INVALID_PARAMETER
);
465 return GetDCObject(hdc
, uObjectType
);
474 GetDeviceCaps(HDC hDC
,
479 PDEVCAPS pDevCaps
= GdiDevCaps
; // Primary display device capabilities.
480 DPRINT("Device CAPS1\n");
482 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
484 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
486 if ( i
== TECHNOLOGY
) return DT_METAFILE
;
491 pLDC
= GdiGetLDC(hDC
);
494 SetLastError(ERROR_INVALID_HANDLE
);
497 if (!(pLDC
->Flags
& LDC_DEVCAPS
))
499 if (!NtGdiGetDeviceCapsAll(hDC
, &pLDC
->DevCaps
))
500 SetLastError(ERROR_INVALID_PARAMETER
);
501 pLDC
->Flags
|= LDC_DEVCAPS
;
503 pDevCaps
= &pLDC
->DevCaps
;
509 // Due to winlogon process/thread mapping issues we have this hax!
510 // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
511 return NtGdiGetDeviceCaps(hDC
,i
);
513 if (!GdiGetHandleUserData((HGDIOBJ
) hDC
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
))
515 if (!(Dc_Attr
->ulDirty_
& DC_PRIMARY_DISPLAY
) )
516 return NtGdiGetDeviceCaps(hDC
,i
);
518 DPRINT("Device CAPS2\n");
523 return pDevCaps
->ulVersion
;
526 return pDevCaps
->ulTechnology
;
529 return pDevCaps
->ulHorzSize
;
532 return pDevCaps
->ulVertSize
;
535 return pDevCaps
->ulHorzRes
;
538 return pDevCaps
->ulVertRes
;
541 return pDevCaps
->ulLogPixelsX
;
544 return pDevCaps
->ulLogPixelsY
;
547 return pDevCaps
->ulBitsPixel
;
550 return pDevCaps
->ulPlanes
;
556 return pDevCaps
->ulNumPens
;
559 return pDevCaps
->ulNumFonts
;
562 return pDevCaps
->ulNumColors
;
565 return pDevCaps
->ulAspectX
;
568 return pDevCaps
->ulAspectY
;
571 return pDevCaps
->ulAspectXY
;
577 return pDevCaps
->ulSizePalette
;
583 return pDevCaps
->ulColorRes
;
586 return pDevCaps
->ulVertRes
;
589 return pDevCaps
->ulHorzRes
;
592 return pDevCaps
->ulBltAlignment
;
595 return pDevCaps
->ulShadeBlend
;
598 return pDevCaps
->ulColorMgmtCaps
;
601 return pDevCaps
->ulPhysicalWidth
;
604 return pDevCaps
->ulPhysicalHeight
;
606 case PHYSICALOFFSETX
:
607 return pDevCaps
->ulPhysicalOffsetX
;
609 case PHYSICALOFFSETY
:
610 return pDevCaps
->ulPhysicalOffsetY
;
613 return pDevCaps
->ulVRefresh
;
616 return pDevCaps
->ulRasterCaps
;
619 return (CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
| CC_WIDE
|
620 CC_STYLED
| CC_WIDESTYLED
| CC_INTERIORS
| CC_ROUNDRECT
);
623 return (LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
624 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
);
627 return (PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
| PC_SCANLINE
|
628 PC_WIDE
| PC_STYLED
| PC_WIDESTYLED
| PC_INTERIORS
);
631 return pDevCaps
->ulTextCaps
;
652 return GetDCDWord( hdc
, GdiGetRelAbs
, 0);
666 return GetAndSetDCDWord( hdc
, GdiGetSetRelAbs
, Mode
, 0, 0, 0 );
675 GetAndSetDCDWord( HDC hDC
, INT u
, DWORD dwIn
, DWORD Unk1
, DWORD Unk2
, DWORD Unk3
)
678 // Handle something other than a normal dc object.
679 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
681 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
682 return 0; //call MFDRV
685 PLDC pLDC
= GdiGetLDC(hDC
);
688 SetLastError(ERROR_INVALID_HANDLE
);
691 if (pLDC
->iType
== LDC_EMFLDC
)
693 Ret
= TRUE
; //call EMFDRV
700 Ret
= NtGdiGetAndSetDCDword( hDC
, u
, dwIn
, (DWORD
*) &u
);
704 SetLastError(ERROR_INVALID_HANDLE
);
714 GetDCDWord( HDC hDC
, INT u
, DWORD Result
)
716 BOOL Ret
= NtGdiGetDCDword( hDC
, u
, (DWORD
*) &u
);
717 if (!Ret
) return Result
;
727 GetAspectRatioFilterEx(
732 return NtGdiGetDCPoint( hdc
, GdiGetAspectRatioFilter
, (LPPOINT
) lpAspectRatio
);
746 return NtGdiGetDCPoint( hdc
, GdiGetDCOrg
, lpPoint
);
759 // Officially obsolete by Microsoft
761 if (!GetDCOrgEx(hdc
, &Pt
))
763 return(MAKELONG(Pt
.x
, Pt
.y
));
768 GetNonFontObject(HGDIOBJ hGdiObj
, int cbSize
, LPVOID lpBuffer
)
772 hGdiObj
= (HANDLE
)GdiFixUpHandle(hGdiObj
);
773 dwType
= GDI_HANDLE_GET_TYPE(hGdiObj
);
775 if (!lpBuffer
) // Should pass it all to Win32k and let god sort it out. ;^)
779 case GDI_OBJECT_TYPE_PEN
:
780 return sizeof(LOGPEN
);
781 case GDI_OBJECT_TYPE_BRUSH
:
782 return sizeof(LOGBRUSH
);
783 case GDI_OBJECT_TYPE_BITMAP
:
784 return sizeof(BITMAP
);
785 case GDI_OBJECT_TYPE_PALETTE
:
787 case GDI_OBJECT_TYPE_EXTPEN
: /* we don't know the size, ask win32k */
794 case GDI_OBJECT_TYPE_PEN
: //Check the structures and see if A & W are the same.
795 case GDI_OBJECT_TYPE_EXTPEN
:
796 case GDI_OBJECT_TYPE_BRUSH
: // Mixing Apples and Oranges?
797 case GDI_OBJECT_TYPE_BITMAP
:
798 case GDI_OBJECT_TYPE_PALETTE
:
799 return NtGdiExtGetObjectW(hGdiObj
, cbSize
, lpBuffer
);
801 case GDI_OBJECT_TYPE_DC
:
802 case GDI_OBJECT_TYPE_REGION
:
803 case GDI_OBJECT_TYPE_METAFILE
:
804 case GDI_OBJECT_TYPE_ENHMETAFILE
:
805 case GDI_OBJECT_TYPE_EMF
:
806 SetLastError(ERROR_INVALID_HANDLE
);
817 GetObjectA(HGDIOBJ hGdiObj
, int cbSize
, LPVOID lpBuffer
)
819 ENUMLOGFONTEXDVW LogFont
;
823 dwType
= GDI_HANDLE_GET_TYPE(hGdiObj
);;
825 if(dwType
== GDI_OBJECT_TYPE_COLORSPACE
) //Stays here, processes struct A
827 SetLastError(ERROR_NOT_SUPPORTED
);
831 if (dwType
== GDI_OBJECT_TYPE_FONT
)
835 return sizeof(LOGFONTA
);
839 /* Windows does not SetLastError() */
842 // ENUMLOGFONTEXDVW is the default size and should be the structure for
843 // Entry->KernelData for Font objects.
844 Result
= NtGdiExtGetObjectW(hGdiObj
, sizeof(ENUMLOGFONTEXDVW
), &LogFont
);
853 case sizeof(ENUMLOGFONTEXDVA
):
854 // need to move more here.
855 case sizeof(ENUMLOGFONTEXA
):
856 EnumLogFontExW2A( (LPENUMLOGFONTEXA
) lpBuffer
, &LogFont
.elfEnumLogfontEx
);
859 case sizeof(ENUMLOGFONTA
):
860 // Same here, maybe? Check the structures.
861 case sizeof(EXTLOGFONTA
):
863 case sizeof(LOGFONTA
):
864 LogFontW2A((LPLOGFONTA
) lpBuffer
, &LogFont
.elfEnumLogfontEx
.elfLogFont
);
868 SetLastError(ERROR_BUFFER_OVERFLOW
);
874 return GetNonFontObject(hGdiObj
, cbSize
, lpBuffer
);
883 GetObjectW(HGDIOBJ hGdiObj
, int cbSize
, LPVOID lpBuffer
)
885 DWORD dwType
= GDI_HANDLE_GET_TYPE(hGdiObj
);
890 MSDN, "This can be a handle to one of the following: logical bitmap, a brush,
891 a font, a palette, a pen, or a device independent bitmap created by calling
892 the CreateDIBSection function."
894 if(dwType
== GDI_OBJECT_TYPE_COLORSPACE
) //Stays here, processes struct W
896 SetLastError(ERROR_NOT_SUPPORTED
); // Not supported yet.
900 if (dwType
== GDI_OBJECT_TYPE_FONT
)
904 return sizeof(LOGFONTW
);
909 /* Windows does not SetLastError() */
912 // Poorly written apps are not ReactOS problem!
913 // We fix it here if the size is larger than the default size.
914 if( cbSize
> sizeof(ENUMLOGFONTEXDVW
) ) cbSize
= sizeof(ENUMLOGFONTEXDVW
);
916 Result
= NtGdiExtGetObjectW(hGdiObj
, cbSize
, lpBuffer
); // Should handle the copy.
925 return GetNonFontObject(hGdiObj
, cbSize
, lpBuffer
);
940 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return CLR_INVALID
;
941 return (COLORREF
) Dc_Attr
->ulPenClr
;
955 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return CLR_INVALID
;
956 return (COLORREF
) Dc_Attr
->ulPenClr
;
970 COLORREF OldColor
= CLR_INVALID
;
972 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return OldColor
;
975 OldColor
= (COLORREF
) Dc_Attr
->ulBrushClr
;
976 Dc_Attr
->ulBrushClr
= (ULONG
) crColor
;
978 if ( Dc_Attr
->crBrushClr
!= crColor
) // if same, don't force a copy.
980 Dc_Attr
->ulDirty_
|= DIRTY_FILL
;
981 Dc_Attr
->crBrushClr
= crColor
;
998 COLORREF OldColor
= CLR_INVALID
;
1000 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return OldColor
;
1003 OldColor
= (COLORREF
) Dc_Attr
->ulPenClr
;
1004 Dc_Attr
->ulPenClr
= (ULONG
) crColor
;
1006 if ( Dc_Attr
->crPenClr
!= crColor
)
1008 Dc_Attr
->ulDirty_
|= DIRTY_LINE
;
1009 Dc_Attr
->crPenClr
= crColor
;
1024 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1025 return Dc_Attr
->ulBackgroundClr
;
1039 COLORREF OldColor
= CLR_INVALID
;
1041 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return OldColor
;
1043 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
1045 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
1046 return MFDRV_SetBkColor( hDC
, crColor
);
1049 PLDC pLDC
= Dc_Attr
->pvLDC
;
1052 SetLastError(ERROR_INVALID_HANDLE
);
1055 if (pLDC
->iType
== LDC_EMFLDC
)
1057 return EMFDRV_SetBkColor( hDC
, crColor
);
1062 OldColor
= (COLORREF
) Dc_Attr
->ulBackgroundClr
;
1063 Dc_Attr
->ulBackgroundClr
= (ULONG
) crColor
;
1065 if ( Dc_Attr
->crBackgroundClr
!= crColor
)
1067 Dc_Attr
->ulDirty_
|= (DIRTY_BACKGROUND
|DIRTY_LINE
|DIRTY_FILL
);
1068 Dc_Attr
->crBackgroundClr
= crColor
;
1082 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1083 return Dc_Attr
->lBkMode
;
1098 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return OldMode
;
1100 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
1102 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
1103 return MFDRV_SetBkMode( hdc
, iBkMode
)
1106 PLDC pLDC
= Dc_Attr
->pvLDC
;
1109 SetLastError(ERROR_INVALID_HANDLE
);
1112 if (pLDC
->iType
== LDC_EMFLDC
)
1114 return EMFDRV_SetBkMode( hdc
, iBkMode
)
1119 OldMode
= Dc_Attr
->lBkMode
;
1120 Dc_Attr
->jBkMode
= iBkMode
; // Processed
1121 Dc_Attr
->lBkMode
= iBkMode
; // Raw
1131 GetPolyFillMode(HDC hdc
)
1134 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1135 return Dc_Attr
->lFillMode
;
1143 SetPolyFillMode(HDC hdc
,
1149 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
1151 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
1152 return MFDRV_SetPolyFillMode( hdc
, iPolyFillMode
)
1155 PLDC pLDC
= GdiGetLDC(hdc
);
1158 SetLastError(ERROR_INVALID_HANDLE
);
1161 if (pLDC
->iType
== LDC_EMFLDC
)
1163 return EMFDRV_SetPolyFillMode( hdc
, iPolyFillMode
)
1168 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1170 if (NtCurrentTeb()->GdiTebBatch
.HDC
== hdc
)
1172 if (Dc_Attr
->ulDirty_
& DC_MODE_DIRTY
)
1174 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
1175 Dc_Attr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
1179 fmode
= Dc_Attr
->lFillMode
;
1180 Dc_Attr
->lFillMode
= iPolyFillMode
;
1191 GetGraphicsMode(HDC hdc
)
1194 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1195 return Dc_Attr
->iGraphicsMode
;
1203 SetGraphicsMode(HDC hdc
,
1208 if ((iMode
< GM_COMPATIBLE
) || (iMode
> GM_ADVANCED
))
1210 SetLastError(ERROR_INVALID_PARAMETER
);
1213 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1215 if (iMode
== Dc_Attr
->iGraphicsMode
) return iMode
;
1217 if (NtCurrentTeb()->GdiTebBatch
.HDC
== hdc
)
1219 if (Dc_Attr
->ulDirty_
& DC_MODE_DIRTY
)
1221 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
1222 Dc_Attr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
1225 /* One would think that setting the graphics mode to GM_COMPATIBLE
1226 * would also reset the world transformation matrix to the unity
1227 * matrix. However, in Windows, this is not the case. This doesn't
1228 * make a lot of sense to me, but that's the way it is.
1230 oMode
= Dc_Attr
->iGraphicsMode
;
1231 Dc_Attr
->iGraphicsMode
= iMode
;
1243 CONST DEVMODEW
*lpInitData
1246 NtGdiResetDC ( hdc
, (PDEVMODEW
)lpInitData
, NULL
, NULL
, NULL
);
1258 CONST DEVMODEA
*lpInitData
1261 LPDEVMODEW InitDataW
;
1263 InitDataW
= GdiConvertToDevmodeW((LPDEVMODEA
)lpInitData
);
1265 NtGdiResetDC ( hdc
, InitDataW
, NULL
, NULL
, NULL
);
1266 HEAP_free(InitDataW
);
1281 return NtGdiStartDoc ( hdc
, (DOCINFOW
*)a1
, NULL
, 0);
1296 if(GdiIsHandleValid(h
))
1298 LONG Type
= GDI_HANDLE_GET_TYPE(h
);
1301 case GDI_OBJECT_TYPE_PEN
:
1304 case GDI_OBJECT_TYPE_BRUSH
:
1307 case GDI_OBJECT_TYPE_BITMAP
:
1310 case GDI_OBJECT_TYPE_FONT
:
1313 case GDI_OBJECT_TYPE_PALETTE
:
1316 case GDI_OBJECT_TYPE_REGION
:
1319 case GDI_OBJECT_TYPE_DC
:
1320 if ( GetDCDWord( h
, GdiGetIsMemDc
, 0))
1327 case GDI_OBJECT_TYPE_COLORSPACE
:
1328 Ret
= OBJ_COLORSPACE
;
1330 case GDI_OBJECT_TYPE_METAFILE
:
1333 case GDI_OBJECT_TYPE_ENHMETAFILE
:
1334 Ret
= OBJ_ENHMETAFILE
;
1336 case GDI_OBJECT_TYPE_METADC
:
1339 case GDI_OBJECT_TYPE_EXTPEN
:
1344 DPRINT1("GetObjectType: Magic 0x%08x not implemented\n", Type
);
1349 /* From Wine: GetObjectType does SetLastError() on a null object */
1350 SetLastError(ERROR_INVALID_HANDLE
);
1365 if ((h
< 0) || (h
>= NB_STOCK_OBJECTS
)) return Ret
;
1366 Ret
= stock_objects
[h
];
1369 HGDIOBJ Obj
= NtGdiGetStockObject( h
);
1371 if (GdiIsHandleValid(Obj
))
1373 stock_objects
[h
] = Obj
;
1375 }// Returns Null anyway.
1380 /* FIXME: include correct header */
1381 HPALETTE WINAPI
NtUserSelectPalette(HDC hDC
,
1383 BOOL ForceBackground
);
1390 BOOL bForceBackground
)
1393 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
1395 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
1396 return MFDRV_SelectPalette( hDC
, hPal
, bForceBackground
);
1399 PLDC pLDC
= GdiGetLDC(hDC
);
1402 SetLastError(ERROR_INVALID_HANDLE
);
1405 if (pLDC
->iType
== LDC_EMFLDC
)
1407 if return EMFDRV_SelectPalette( hDC
, hPal
, bForceBackground
);
1412 return NtUserSelectPalette(hDC
, hPal
, bForceBackground
);
1424 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1425 return Dc_Attr
->iMapMode
;
1439 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1441 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
1443 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
1444 return MFDRV_SetMapMode(hdc
, Mode
);
1447 SetLastError(ERROR_INVALID_HANDLE
);
1451 // Force change if Isotropic is set for recompute.
1452 if ((Mode
!= Dc_Attr
->iMapMode
) || (Mode
== MM_ISOTROPIC
))
1454 Dc_Attr
->ulDirty_
&= ~SLOW_WIDTHS
;
1455 return GetAndSetDCDWord( hdc
, GdiGetSetMapMode
, Mode
, 0, 0, 0 );
1457 return Dc_Attr
->iMapMode
;
1466 GetStretchBltMode(HDC hdc
)
1469 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1470 return Dc_Attr
->lStretchBltMode
;
1478 SetStretchBltMode(HDC hdc
, int iStretchMode
)
1483 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
1485 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
1486 return MFDRV_SetStretchBltMode( hdc
, iStretchMode
);
1489 PLDC pLDC
= GdiGetLDC(hdc
);
1492 SetLastError(ERROR_INVALID_HANDLE
);
1495 if (pLDC
->iType
== LDC_EMFLDC
)
1497 return EMFDRV_SetStretchBltMode( hdc
, iStretchMode
);
1502 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1504 oSMode
= Dc_Attr
->lStretchBltMode
;
1505 Dc_Attr
->lStretchBltMode
= iStretchMode
;
1507 // Wine returns an error here. We set the default.
1508 if ((iStretchMode
<= 0) || (iStretchMode
> MAXSTRETCHBLTMODE
)) iStretchMode
= WHITEONBLACK
;
1510 Dc_Attr
->jStretchBltMode
= iStretchMode
;
1523 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return NULL
;
1524 return Dc_Attr
->hlfntNew
;
1534 SelectObject(HDC hDC
,
1538 HGDIOBJ hOldObj
= NULL
;
1541 if(!GdiGetHandleUserData(hDC
, GDI_OBJECT_TYPE_DC
, (PVOID
)&pDc_Attr
))
1543 SetLastError(ERROR_INVALID_HANDLE
);
1547 hGdiObj
= GdiFixUpHandle(hGdiObj
);
1548 if (!GdiIsHandleValid(hGdiObj
))
1553 UINT uType
= GDI_HANDLE_GET_TYPE(hGdiObj
);
1557 case GDI_OBJECT_TYPE_REGION
:
1558 return (HGDIOBJ
)ExtSelectClipRgn(hDC
, hGdiObj
, RGN_COPY
);
1560 case GDI_OBJECT_TYPE_BITMAP
:
1561 return NtGdiSelectBitmap(hDC
, hGdiObj
);
1563 case GDI_OBJECT_TYPE_BRUSH
:
1564 hOldObj
= pDc_Attr
->hbrush
;
1565 pDc_Attr
->ulDirty_
|= DC_BRUSH_DIRTY
;
1566 pDc_Attr
->hbrush
= hGdiObj
;
1568 // return NtGdiSelectBrush(hDC, hGdiObj);
1570 case GDI_OBJECT_TYPE_PEN
:
1571 case GDI_OBJECT_TYPE_EXTPEN
:
1572 hOldObj
= pDc_Attr
->hpen
;
1573 pDc_Attr
->ulDirty_
|= DC_PEN_DIRTY
;
1574 pDc_Attr
->hpen
= hGdiObj
;
1576 // return NtGdiSelectPen(hDC, hGdiObj);
1578 case GDI_OBJECT_TYPE_FONT
:
1579 hOldObj
= pDc_Attr
->hlfntNew
;
1580 if (hOldObj
== hGdiObj
) return hOldObj
;
1582 pDc_Attr
->ulDirty_
&= ~SLOW_WIDTHS
;
1583 pDc_Attr
->ulDirty_
|= DIRTY_CHARSET
;
1584 pDc_Attr
->hlfntNew
= hGdiObj
;
1585 pTeb
= NtCurrentTeb();
1586 if (((pTeb
->GdiTebBatch
.HDC
== 0) ||
1587 (pTeb
->GdiTebBatch
.HDC
== hDC
)) &&
1588 ((pTeb
->GdiTebBatch
.Offset
+ sizeof(GDIBSOBJECT
)) <= GDIBATCHBUFSIZE
) &&
1589 (!(pDc_Attr
->ulDirty_
& DC_DIBSECTION
)))
1591 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
)(&pTeb
->GdiTebBatch
.Buffer
[0] +
1592 pTeb
->GdiTebBatch
.Offset
);
1593 pgO
->gbHdr
.Cmd
= GdiBCSelObj
;
1594 pgO
->gbHdr
.Size
= sizeof(GDIBSOBJECT
);
1595 pgO
->hgdiobj
= hGdiObj
;
1597 pTeb
->GdiTebBatch
.Offset
+= sizeof(GDIBSOBJECT
);
1598 pTeb
->GdiTebBatch
.HDC
= hDC
;
1599 pTeb
->GdiBatchCount
++;
1600 if (pTeb
->GdiBatchCount
>= GDI_BatchLimit
) NtGdiFlush();
1604 // default for select object font
1605 return NtGdiSelectFont(hDC
, hGdiObj
);
1608 case GDI_OBJECT_TYPE_METADC
:
1609 return MFDRV_SelectObject( hDC
, hGdiObj
);
1610 case GDI_OBJECT_TYPE_EMF
:
1611 PLDC pLDC
= GdiGetLDC(hDC
);
1612 if ( !pLDC
) return NULL
;
1613 return EMFDRV_SelectObject( hDC
, hGdiObj
);
1615 case GDI_OBJECT_TYPE_COLORSPACE
:
1616 SetColorSpace(hDC
, (HCOLORSPACE
) hGdiObj
);
1619 case GDI_OBJECT_TYPE_PALETTE
:
1621 SetLastError(ERROR_INVALID_FUNCTION
);