4 * Copyright 1993 Alexandre Julliard
5 * Copyright 2021 Jacek Caban for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(gdi
);
35 static GDI_SHARED_MEMORY
*get_gdi_shared(void)
38 if (NtCurrentTeb()->GdiBatchCount
)
40 TEB64
*teb64
= (TEB64
*)(UINT_PTR
)NtCurrentTeb()->GdiBatchCount
;
41 PEB64
*peb64
= (PEB64
*)(UINT_PTR
)teb64
->Peb
;
42 return (GDI_SHARED_MEMORY
*)(UINT_PTR
)peb64
->GdiSharedHandleTable
;
45 return (GDI_SHARED_MEMORY
*)NtCurrentTeb()->Peb
->GdiSharedHandleTable
;
48 static inline GDI_HANDLE_ENTRY
*handle_entry( HGDIOBJ handle
)
50 GDI_SHARED_MEMORY
*gdi_shared
= get_gdi_shared();
51 unsigned int idx
= LOWORD(handle
);
53 if (idx
< GDI_MAX_HANDLE_COUNT
&& gdi_shared
->Handles
[idx
].Type
)
55 if (!HIWORD( handle
) || HIWORD( handle
) == gdi_shared
->Handles
[idx
].Unique
)
56 return &gdi_shared
->Handles
[idx
];
58 if (handle
) WARN( "invalid handle %p\n", handle
);
62 static WORD
get_object_type( HGDIOBJ obj
)
64 GDI_HANDLE_ENTRY
*entry
= handle_entry( obj
);
65 return entry
? entry
->ExtType
: 0;
68 void set_gdi_client_ptr( HGDIOBJ obj
, void *ptr
)
70 GDI_HANDLE_ENTRY
*entry
= handle_entry( obj
);
71 if (entry
) entry
->UserPointer
= (UINT_PTR
)ptr
;
74 void *get_gdi_client_ptr( HGDIOBJ obj
, WORD type
)
76 GDI_HANDLE_ENTRY
*entry
= handle_entry( obj
);
77 if (!entry
|| entry
->ExtType
!= type
|| !entry
->UserPointer
)
79 return (void *)(UINT_PTR
)entry
->UserPointer
;
82 /***********************************************************************
83 * GetObjectType (GDI32.@)
85 DWORD WINAPI
GetObjectType( HGDIOBJ handle
)
87 DWORD type
= get_object_type( handle
);
89 TRACE( "%p -> %u\n", handle
, type
);
93 case NTGDI_OBJ_PEN
: return OBJ_PEN
;
94 case NTGDI_OBJ_BRUSH
: return OBJ_BRUSH
;
95 case NTGDI_OBJ_DC
: return OBJ_DC
;
96 case NTGDI_OBJ_METADC
: return OBJ_METADC
;
97 case NTGDI_OBJ_PAL
: return OBJ_PAL
;
98 case NTGDI_OBJ_FONT
: return OBJ_FONT
;
99 case NTGDI_OBJ_BITMAP
: return OBJ_BITMAP
;
100 case NTGDI_OBJ_REGION
: return OBJ_REGION
;
101 case NTGDI_OBJ_METAFILE
: return OBJ_METAFILE
;
102 case NTGDI_OBJ_MEMDC
: return OBJ_MEMDC
;
103 case NTGDI_OBJ_EXTPEN
: return OBJ_EXTPEN
;
104 case NTGDI_OBJ_ENHMETADC
: return OBJ_ENHMETADC
;
105 case NTGDI_OBJ_ENHMETAFILE
: return OBJ_ENHMETAFILE
;
107 SetLastError( ERROR_INVALID_HANDLE
);
112 /***********************************************************************
113 * DeleteObject (GDI32.@)
115 * Delete a Gdi object.
117 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
119 return NtGdiDeleteObjectApp( obj
);
122 /***********************************************************************
123 * SelectObject (GDI32.@)
125 * Select a Gdi object into a device context.
127 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ obj
)
131 TRACE( "(%p,%p)\n", hdc
, obj
);
133 switch (get_object_type( obj
))
136 case NTGDI_OBJ_EXTPEN
:
137 ret
= NtGdiSelectPen( hdc
, obj
);
139 case NTGDI_OBJ_BRUSH
:
140 ret
= NtGdiSelectBrush( hdc
, obj
);
143 ret
= NtGdiSelectFont( hdc
, obj
);
145 case NTGDI_OBJ_BITMAP
:
146 ret
= NtGdiSelectBitmap( hdc
, obj
);
148 case NTGDI_OBJ_REGION
:
149 ret
= ULongToHandle(SelectClipRgn( hdc
, obj
));
155 if (!ret
) SetLastError( ERROR_INVALID_HANDLE
);
159 /***********************************************************************
160 * GetObjectW (GDI32.@)
162 INT WINAPI
GetObjectW( HGDIOBJ handle
, INT count
, void *buffer
)
166 TRACE( "%p %d %p\n", handle
, count
, buffer
);
168 result
= NtGdiExtGetObjectW( handle
, count
, buffer
);
169 if (!result
&& count
)
171 switch(get_object_type( handle
))
174 case NTGDI_OBJ_BITMAP
:
175 case NTGDI_OBJ_BRUSH
:
179 case NTGDI_OBJ_EXTPEN
:
182 SetLastError( ERROR_INVALID_HANDLE
);
188 /***********************************************************************
189 * GetObjectA (GDI32.@)
191 INT WINAPI
GetObjectA( HGDIOBJ handle
, INT count
, void *buffer
)
193 TRACE("%p %d %p\n", handle
, count
, buffer
);
195 if (get_object_type( handle
) == NTGDI_OBJ_FONT
)
197 LOGFONTA
*lfA
= buffer
;
200 if (!buffer
) return sizeof(*lfA
);
201 if (!GetObjectW( handle
, sizeof(lf
), &lf
)) return 0;
202 if (count
> sizeof(*lfA
)) count
= sizeof(*lfA
);
203 memcpy( lfA
, &lf
, min( count
, FIELD_OFFSET(LOGFONTA
, lfFaceName
) ));
204 if (count
> FIELD_OFFSET(LOGFONTA
, lfFaceName
))
206 WideCharToMultiByte( CP_ACP
, 0, lf
.lfFaceName
, -1, lfA
->lfFaceName
,
207 count
- FIELD_OFFSET(LOGFONTA
, lfFaceName
), NULL
, NULL
);
208 if (count
== sizeof(*lfA
)) lfA
->lfFaceName
[LF_FACESIZE
- 1] = 0;
213 return GetObjectW( handle
, count
, buffer
);
216 /***********************************************************************
217 * CreatePenIndirect (GDI32.@)
219 HPEN WINAPI
CreatePenIndirect( const LOGPEN
*pen
)
221 return CreatePen( pen
->lopnStyle
, pen
->lopnWidth
.x
, pen
->lopnColor
);
224 /***********************************************************************
225 * CreatePen (GDI32.@)
227 HPEN WINAPI
CreatePen( INT style
, INT width
, COLORREF color
)
229 if (style
< 0 || style
> PS_INSIDEFRAME
) style
= PS_SOLID
;
230 return NtGdiCreatePen( style
, width
, color
, NULL
);
233 /***********************************************************************
234 * CreateBitmapIndirect (GDI32.@)
236 HBITMAP WINAPI
CreateBitmapIndirect( const BITMAP
*bmp
)
238 if (!bmp
|| bmp
->bmType
)
240 SetLastError( ERROR_INVALID_PARAMETER
);
244 return CreateBitmap( bmp
->bmWidth
, bmp
->bmHeight
, bmp
->bmPlanes
,
245 bmp
->bmBitsPixel
, bmp
->bmBits
);
248 /******************************************************************************
249 * CreateBitmap (GDI32.@)
251 * Creates a bitmap with the specified info.
253 HBITMAP WINAPI
CreateBitmap( INT width
, INT height
, UINT planes
,
254 UINT bpp
, const void *bits
)
256 if (!width
|| !height
)
257 return GetStockObject( STOCK_LAST
+ 1 ); /* default 1x1 bitmap */
259 return NtGdiCreateBitmap( width
, height
, planes
, bpp
, bits
);
262 /******************************************************************************
263 * CreateDiscardableBitmap (GDI32.@)
265 * Creates a discardable bitmap.
267 HBITMAP WINAPI
CreateDiscardableBitmap( HDC hdc
, INT width
, INT height
)
269 return CreateCompatibleBitmap( hdc
, width
, height
);
272 /***********************************************************************
273 * ExtCreateRegion (GDI32.@)
275 * Creates a region as specified by the transformation data and region data.
277 HRGN WINAPI
ExtCreateRegion( const XFORM
*xform
, DWORD count
, const RGNDATA
*data
)
281 SetLastError( ERROR_INVALID_PARAMETER
);
285 return NtGdiExtCreateRegion( xform
, count
, data
);
288 /***********************************************************************
289 * CreateRectRgnIndirect (GDI32.@)
291 * Creates a simple rectangular region.
293 HRGN WINAPI
CreateRectRgnIndirect( const RECT
* rect
)
295 return NtGdiCreateRectRgn( rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
298 /***********************************************************************
299 * CreateEllipticRgnIndirect (GDI32.@)
301 * Creates an elliptical region.
303 HRGN WINAPI
CreateEllipticRgnIndirect( const RECT
*rect
)
305 return NtGdiCreateEllipticRgn( rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
308 /***********************************************************************
309 * CreatePolygonRgn (GDI32.@)
311 HRGN WINAPI
CreatePolygonRgn( const POINT
*points
, INT count
, INT mode
)
313 return CreatePolyPolygonRgn( points
, &count
, 1, mode
);