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
);
479 return GetDCDWord( hdc
, GdiGetRelAbs
, 0);
493 return GetAndSetDCDWord( hdc
, GdiGetSetRelAbs
, Mode
, 0, 0, 0 );
502 GetAndSetDCDWord( HDC hDC
, INT u
, DWORD dwIn
, DWORD Unk1
, DWORD Unk2
, DWORD Unk3
)
505 // Handle something other than a normal dc object.
506 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
508 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
509 return 0; //call MFDRV
512 PLDC pLDC
= GdiGetLDC(hDC
);
515 SetLastError(ERROR_INVALID_HANDLE
);
518 if (pLDC
->iType
== LDC_EMFLDC
)
520 Ret
= TRUE
; //call EMFDRV
527 Ret
= NtGdiGetAndSetDCDword( hDC
, u
, dwIn
, (DWORD
*) &u
);
531 SetLastError(ERROR_INVALID_HANDLE
);
541 GetDCDWord( HDC hDC
, INT u
, DWORD Result
)
543 BOOL Ret
= NtGdiGetDCDword( hDC
, u
, (DWORD
*) &u
);
544 if (!Ret
) return Result
;
554 GetAspectRatioFilterEx(
559 return NtGdiGetDCPoint( hdc
, GdiGetAspectRatioFilter
, (LPPOINT
) lpAspectRatio
);
573 return NtGdiGetDCPoint( hdc
, GdiGetDCOrg
, lpPoint
);
586 // Officially obsolete by Microsoft
588 if (!GetDCOrgEx(hdc
, &Pt
))
590 return(MAKELONG(Pt
.x
, Pt
.y
));
595 GetNonFontObject(HGDIOBJ hGdiObj
, int cbSize
, LPVOID lpBuffer
)
599 hGdiObj
= (HANDLE
)GdiFixUpHandle(hGdiObj
);
600 dwType
= GDI_HANDLE_GET_TYPE(hGdiObj
);
602 if (!lpBuffer
) // Should pass it all to Win32k and let god sort it out. ;^)
606 case GDI_OBJECT_TYPE_PEN
:
607 return sizeof(LOGPEN
);
608 case GDI_OBJECT_TYPE_BRUSH
:
609 return sizeof(LOGBRUSH
);
610 case GDI_OBJECT_TYPE_BITMAP
:
611 return sizeof(BITMAP
);
612 case GDI_OBJECT_TYPE_PALETTE
:
614 case GDI_OBJECT_TYPE_EXTPEN
: /* we don't know the size, ask win32k */
621 case GDI_OBJECT_TYPE_PEN
: //Check the structures and see if A & W are the same.
622 case GDI_OBJECT_TYPE_EXTPEN
:
623 case GDI_OBJECT_TYPE_BRUSH
: // Mixing Apples and Oranges?
624 case GDI_OBJECT_TYPE_BITMAP
:
625 case GDI_OBJECT_TYPE_PALETTE
:
626 return NtGdiExtGetObjectW(hGdiObj
, cbSize
, lpBuffer
);
628 case GDI_OBJECT_TYPE_DC
:
629 case GDI_OBJECT_TYPE_REGION
:
630 case GDI_OBJECT_TYPE_METAFILE
:
631 case GDI_OBJECT_TYPE_ENHMETAFILE
:
632 case GDI_OBJECT_TYPE_EMF
:
633 SetLastError(ERROR_INVALID_HANDLE
);
644 GetObjectA(HGDIOBJ hGdiObj
, int cbSize
, LPVOID lpBuffer
)
646 ENUMLOGFONTEXDVW LogFont
;
650 dwType
= GDI_HANDLE_GET_TYPE(hGdiObj
);;
652 if(dwType
== GDI_OBJECT_TYPE_COLORSPACE
) //Stays here, processes struct A
654 SetLastError(ERROR_NOT_SUPPORTED
);
658 if (dwType
== GDI_OBJECT_TYPE_FONT
)
662 return sizeof(LOGFONTA
);
666 /* Windows does not SetLastError() */
669 // ENUMLOGFONTEXDVW is the default size and should be the structure for
670 // Entry->KernelData for Font objects.
671 Result
= NtGdiExtGetObjectW(hGdiObj
, sizeof(ENUMLOGFONTEXDVW
), &LogFont
);
680 case sizeof(ENUMLOGFONTEXDVA
):
681 // need to move more here.
682 case sizeof(ENUMLOGFONTEXA
):
683 EnumLogFontExW2A( (LPENUMLOGFONTEXA
) lpBuffer
, &LogFont
.elfEnumLogfontEx
);
686 case sizeof(ENUMLOGFONTA
):
687 // Same here, maybe? Check the structures.
688 case sizeof(EXTLOGFONTA
):
690 case sizeof(LOGFONTA
):
691 LogFontW2A((LPLOGFONTA
) lpBuffer
, &LogFont
.elfEnumLogfontEx
.elfLogFont
);
695 SetLastError(ERROR_BUFFER_OVERFLOW
);
701 return GetNonFontObject(hGdiObj
, cbSize
, lpBuffer
);
710 GetObjectW(HGDIOBJ hGdiObj
, int cbSize
, LPVOID lpBuffer
)
712 DWORD dwType
= GDI_HANDLE_GET_TYPE(hGdiObj
);
717 MSDN, "This can be a handle to one of the following: logical bitmap, a brush,
718 a font, a palette, a pen, or a device independent bitmap created by calling
719 the CreateDIBSection function."
721 if(dwType
== GDI_OBJECT_TYPE_COLORSPACE
) //Stays here, processes struct W
723 SetLastError(ERROR_NOT_SUPPORTED
); // Not supported yet.
727 if (dwType
== GDI_OBJECT_TYPE_FONT
)
731 return sizeof(LOGFONTW
);
736 /* Windows does not SetLastError() */
739 // Poorly written apps are not ReactOS problem!
740 // We fix it here if the size is larger than the default size.
741 if( cbSize
> sizeof(ENUMLOGFONTEXDVW
) ) cbSize
= sizeof(ENUMLOGFONTEXDVW
);
743 Result
= NtGdiExtGetObjectW(hGdiObj
, cbSize
, lpBuffer
); // Should handle the copy.
752 return GetNonFontObject(hGdiObj
, cbSize
, lpBuffer
);
767 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return CLR_INVALID
;
768 return (COLORREF
) Dc_Attr
->ulPenClr
;
782 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return CLR_INVALID
;
783 return (COLORREF
) Dc_Attr
->ulPenClr
;
797 COLORREF OldColor
= CLR_INVALID
;
799 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return OldColor
;
802 OldColor
= (COLORREF
) Dc_Attr
->ulBrushClr
;
803 Dc_Attr
->ulBrushClr
= (ULONG
) crColor
;
805 if ( Dc_Attr
->crBrushClr
!= crColor
) // if same, don't force a copy.
807 Dc_Attr
->ulDirty_
|= DIRTY_FILL
;
808 Dc_Attr
->crBrushClr
= crColor
;
825 COLORREF OldColor
= CLR_INVALID
;
827 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return OldColor
;
830 OldColor
= (COLORREF
) Dc_Attr
->ulPenClr
;
831 Dc_Attr
->ulPenClr
= (ULONG
) crColor
;
833 if ( Dc_Attr
->crPenClr
!= crColor
)
835 Dc_Attr
->ulDirty_
|= DIRTY_LINE
;
836 Dc_Attr
->crPenClr
= crColor
;
851 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
852 return Dc_Attr
->ulBackgroundClr
;
866 COLORREF OldColor
= CLR_INVALID
;
868 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return OldColor
;
870 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
872 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
873 return MFDRV_SetBkColor( hDC
, crColor
);
876 PLDC pLDC
= Dc_Attr
->pvLDC
;
879 SetLastError(ERROR_INVALID_HANDLE
);
882 if (pLDC
->iType
== LDC_EMFLDC
)
884 return EMFDRV_SetBkColor( hDC
, crColor
);
889 OldColor
= (COLORREF
) Dc_Attr
->ulBackgroundClr
;
890 Dc_Attr
->ulBackgroundClr
= (ULONG
) crColor
;
892 if ( Dc_Attr
->crBackgroundClr
!= crColor
)
894 Dc_Attr
->ulDirty_
|= DIRTY_LINE
;
895 Dc_Attr
->crBackgroundClr
= crColor
;
909 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
910 return Dc_Attr
->lBkMode
;
925 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return OldMode
;
927 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
929 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
930 return MFDRV_SetBkMode( hdc
, iBkMode
)
933 PLDC pLDC
= Dc_Attr
->pvLDC
;
936 SetLastError(ERROR_INVALID_HANDLE
);
939 if (pLDC
->iType
== LDC_EMFLDC
)
941 return EMFDRV_SetBkMode( hdc
, iBkMode
)
946 OldMode
= Dc_Attr
->lBkMode
;
947 Dc_Attr
->jBkMode
= iBkMode
; // Processed
948 Dc_Attr
->lBkMode
= iBkMode
; // Raw
958 GetPolyFillMode(HDC hdc
)
961 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
962 return Dc_Attr
->lFillMode
;
970 SetPolyFillMode(HDC hdc
,
976 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
978 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
979 return MFDRV_SetPolyFillMode( hdc
, iPolyFillMode
)
982 PLDC pLDC
= GdiGetLDC(hdc
);
985 SetLastError(ERROR_INVALID_HANDLE
);
988 if (pLDC
->iType
== LDC_EMFLDC
)
990 return EMFDRV_SetPolyFillMode( hdc
, iPolyFillMode
)
995 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
997 if (NtCurrentTeb()->GdiTebBatch
.HDC
== hdc
)
999 if (Dc_Attr
->ulDirty_
& DC_MODE_DIRTY
)
1001 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
1002 Dc_Attr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
1006 fmode
= Dc_Attr
->lFillMode
;
1007 Dc_Attr
->lFillMode
= iPolyFillMode
;
1018 GetGraphicsMode(HDC hdc
)
1021 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1022 return Dc_Attr
->iGraphicsMode
;
1030 SetGraphicsMode(HDC hdc
,
1035 if ((iMode
< GM_COMPATIBLE
) || (iMode
> GM_ADVANCED
))
1037 SetLastError(ERROR_INVALID_PARAMETER
);
1040 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1042 if (iMode
== Dc_Attr
->iGraphicsMode
) return iMode
;
1044 if (NtCurrentTeb()->GdiTebBatch
.HDC
== hdc
)
1046 if (Dc_Attr
->ulDirty_
& DC_MODE_DIRTY
)
1048 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
1049 Dc_Attr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
1052 /* One would think that setting the graphics mode to GM_COMPATIBLE
1053 * would also reset the world transformation matrix to the unity
1054 * matrix. However, in Windows, this is not the case. This doesn't
1055 * make a lot of sense to me, but that's the way it is.
1057 oMode
= Dc_Attr
->iGraphicsMode
;
1058 Dc_Attr
->iGraphicsMode
= iMode
;
1070 CONST DEVMODEW
*lpInitData
1073 NtGdiResetDC ( hdc
, (PDEVMODEW
)lpInitData
, NULL
, NULL
, NULL
);
1085 CONST DEVMODEA
*lpInitData
1088 LPDEVMODEW InitDataW
;
1090 InitDataW
= GdiConvertToDevmodeW((LPDEVMODEA
)lpInitData
);
1092 NtGdiResetDC ( hdc
, InitDataW
, NULL
, NULL
, NULL
);
1093 HEAP_free(InitDataW
);
1108 return NtGdiStartDoc ( hdc
, (DOCINFOW
*)a1
, NULL
, 0);
1123 if(GdiIsHandleValid(h
))
1125 LONG Type
= GDI_HANDLE_GET_TYPE(h
);
1128 case GDI_OBJECT_TYPE_PEN
:
1131 case GDI_OBJECT_TYPE_BRUSH
:
1134 case GDI_OBJECT_TYPE_BITMAP
:
1137 case GDI_OBJECT_TYPE_FONT
:
1140 case GDI_OBJECT_TYPE_PALETTE
:
1143 case GDI_OBJECT_TYPE_REGION
:
1146 case GDI_OBJECT_TYPE_DC
:
1147 if ( GetDCDWord( h
, GdiGetIsMemDc
, 0))
1154 case GDI_OBJECT_TYPE_COLORSPACE
:
1155 Ret
= OBJ_COLORSPACE
;
1157 case GDI_OBJECT_TYPE_METAFILE
:
1160 case GDI_OBJECT_TYPE_ENHMETAFILE
:
1161 Ret
= OBJ_ENHMETAFILE
;
1163 case GDI_OBJECT_TYPE_METADC
:
1166 case GDI_OBJECT_TYPE_EXTPEN
:
1171 DPRINT1("GetObjectType: Magic 0x%08x not implemented\n", Type
);
1176 /* From Wine: GetObjectType does SetLastError() on a null object */
1177 SetLastError(ERROR_INVALID_HANDLE
);
1192 if ((h
< 0) || (h
>= NB_STOCK_OBJECTS
)) return Ret
;
1193 Ret
= stock_objects
[h
];
1196 HGDIOBJ Obj
= NtGdiGetStockObject( h
);
1198 if (GdiIsHandleValid(Obj
))
1200 stock_objects
[h
] = Obj
;
1202 }// Returns Null anyway.
1207 /* FIXME: include correct header */
1208 HPALETTE STDCALL
NtUserSelectPalette(HDC hDC
,
1210 BOOL ForceBackground
);
1217 BOOL bForceBackground
)
1220 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
1222 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
1223 return MFDRV_SelectPalette( hDC
, hPal
, bForceBackground
);
1226 PLDC pLDC
= GdiGetLDC(hDC
);
1229 SetLastError(ERROR_INVALID_HANDLE
);
1232 if (pLDC
->iType
== LDC_EMFLDC
)
1234 if return EMFDRV_SelectPalette( hDC
, hPal
, bForceBackground
);
1239 return NtUserSelectPalette(hDC
, hPal
, bForceBackground
);
1251 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1252 return Dc_Attr
->iMapMode
;
1266 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1268 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
1270 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
1271 return MFDRV_SetMapMode(hdc
, Mode
);
1274 SetLastError(ERROR_INVALID_HANDLE
);
1278 // Force change if Isotropic is set for recompute.
1279 if ((Mode
!= Dc_Attr
->iMapMode
) || (Mode
== MM_ISOTROPIC
))
1281 Dc_Attr
->ulDirty_
&= ~SLOW_WIDTHS
;
1282 return GetAndSetDCDWord( hdc
, GdiGetSetMapMode
, Mode
, 0, 0, 0 );
1284 return Dc_Attr
->iMapMode
;
1293 GetStretchBltMode(HDC hdc
)
1296 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1297 return Dc_Attr
->lStretchBltMode
;
1305 SetStretchBltMode(HDC hdc
, int iStretchMode
)
1310 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
1312 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
1313 return MFDRV_SetStretchBltMode( hdc
, iStretchMode
);
1316 PLDC pLDC
= GdiGetLDC(hdc
);
1319 SetLastError(ERROR_INVALID_HANDLE
);
1322 if (pLDC
->iType
== LDC_EMFLDC
)
1324 return EMFDRV_SetStretchBltMode( hdc
, iStretchMode
);
1329 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return 0;
1331 oSMode
= Dc_Attr
->lStretchBltMode
;
1332 Dc_Attr
->lStretchBltMode
= iStretchMode
;
1334 // Wine returns an error here. We set the default.
1335 if ((iStretchMode
<= 0) || (iStretchMode
> MAXSTRETCHBLTMODE
)) iStretchMode
= WHITEONBLACK
;
1337 Dc_Attr
->jStretchBltMode
= iStretchMode
;
1350 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return NULL
;
1351 return Dc_Attr
->hlfntNew
;
1361 SelectObject(HDC hDC
,
1365 // HGDIOBJ hOldObj = NULL;
1368 if(!GdiGetHandleUserData(hDC
, GDI_OBJECT_TYPE_DC
, (PVOID
)&pDc_Attr
))
1370 SetLastError(ERROR_INVALID_HANDLE
);
1374 hGdiObj
= GdiFixUpHandle(hGdiObj
);
1375 if (!GdiIsHandleValid(hGdiObj
))
1380 UINT uType
= GDI_HANDLE_GET_TYPE(hGdiObj
);
1384 case GDI_OBJECT_TYPE_REGION
:
1385 return (HGDIOBJ
)ExtSelectClipRgn(hDC
, hGdiObj
, RGN_COPY
);
1387 case GDI_OBJECT_TYPE_BITMAP
:
1388 return NtGdiSelectBitmap(hDC
, hGdiObj
);
1390 case GDI_OBJECT_TYPE_BRUSH
:
1391 #if 0 // enable this when support is ready in win32k
1392 hOldObj
= pDc_Attr
->hbrush
;
1393 pDc_Attr
->ulDirty_
|= DC_BRUSH_DIRTY
;
1394 pDc_Attr
->hbrush
= hGdiObj
;
1397 return NtGdiSelectBrush(hDC
, hGdiObj
);
1399 case GDI_OBJECT_TYPE_PEN
:
1400 case GDI_OBJECT_TYPE_EXTPEN
:
1401 #if 0 // enable this when support is ready in win32k
1402 hOldObj
= pDc_Attr
->hpen
;
1403 pDc_Attr
->ulDirty_
|= DC_PEN_DIRTY
;
1404 pDc_Attr
->hpen
= hGdiObj
;
1407 return NtGdiSelectPen(hDC
, hGdiObj
);
1409 case GDI_OBJECT_TYPE_FONT
:
1411 pTeb
= NtCurrentTeb();
1412 if (((pTeb
->GdiTebBatch
.HDC
== 0) ||
1413 (pTeb
->GdiTebBatch
.HDC
== (ULONG
)hDC
)) &&
1414 ((pTeb
->GdiTebBatch
.Offset
+ sizeof(GDIBSOBJECT
)) <= GDIBATCHBUFSIZE
) &&
1415 (!(pDc_Attr
->ulDirty_
& DC_DIBSECTION
)))
1417 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
)(&pTeb
->GdiTebBatch
.Buffer
[0] +
1418 pTeb
->GdiTebBatch
.Offset
);
1419 pgO
->gbHdr
.Cmd
= GdiBCSelObj
;
1420 pgO
->gbHdr
.Size
= sizeof(GDIBSOBJECT
);
1421 pgO
->hgdiobj
= hGdiObj
;
1423 pTeb
->GdiTebBatch
.Offset
+= sizeof(GDIBSOBJECT
);
1424 pTeb
->GdiTebBatch
.HDC
= (ULONG
)hDC
;
1425 pTeb
->GdiBatchCount
++;
1426 if (pTeb
->GdiBatchCount
>= GDI_BatchLimit
) NtGdiFlush();
1427 return pDc_Attr
->hlfntNew
;
1430 // default for select object font
1431 return NtGdiSelectFont(hDC
, hGdiObj
);
1433 case GDI_OBJECT_TYPE_METADC
:
1434 return MFDRV_SelectObject( hDC
, hGdiObj
);
1435 case GDI_OBJECT_TYPE_EMF
:
1436 PLDC pLDC
= GdiGetLDC(hDC
);
1437 if ( !pLDC
) return NULL
;
1438 return EMFDRV_SelectObject( hDC
, hGdiObj
);
1440 case GDI_OBJECT_TYPE_COLORSPACE
:
1441 SetColorSpace(hDC
, (HCOLORSPACE
) hGdiObj
);
1444 case GDI_OBJECT_TYPE_PALETTE
:
1446 SetLastError(ERROR_INVALID_FUNCTION
);