gdi32: Use NtGdiCreateClientObj for metafile objects.
[wine.git] / dlls / gdi32 / objects.c
blob63a7925522421953103d08e986593473c914d7c8
1 /*
2 * GDI functions
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
22 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winnls.h"
27 #include "ntgdi.h"
28 #include "winternl.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
35 static GDI_SHARED_MEMORY *get_gdi_shared(void)
37 #ifndef _WIN64
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;
44 #endif
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 );
59 return NULL;
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)
78 return NULL;
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 );
91 switch (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;
106 default:
107 SetLastError( ERROR_INVALID_HANDLE );
108 return 0;
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 )
129 HGDIOBJ ret;
131 TRACE( "(%p,%p)\n", hdc, obj );
133 switch (get_object_type( obj ))
135 case NTGDI_OBJ_PEN:
136 case NTGDI_OBJ_EXTPEN:
137 ret = NtGdiSelectPen( hdc, obj );
138 break;
139 case NTGDI_OBJ_BRUSH:
140 ret = NtGdiSelectBrush( hdc, obj );
141 break;
142 case NTGDI_OBJ_FONT:
143 ret = NtGdiSelectFont( hdc, obj );
144 break;
145 case NTGDI_OBJ_BITMAP:
146 ret = NtGdiSelectBitmap( hdc, obj );
147 break;
148 case NTGDI_OBJ_REGION:
149 ret = ULongToHandle(SelectClipRgn( hdc, obj ));
150 break;
151 default:
152 return 0;
155 if (!ret) SetLastError( ERROR_INVALID_HANDLE );
156 return ret;
159 /***********************************************************************
160 * GetObjectW (GDI32.@)
162 INT WINAPI GetObjectW( HGDIOBJ handle, INT count, void *buffer )
164 int result;
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 ))
173 case 0:
174 case NTGDI_OBJ_BITMAP:
175 case NTGDI_OBJ_BRUSH:
176 case NTGDI_OBJ_FONT:
177 case NTGDI_OBJ_PAL:
178 case NTGDI_OBJ_PEN:
179 case NTGDI_OBJ_EXTPEN:
180 break;
181 default:
182 SetLastError( ERROR_INVALID_HANDLE );
185 return result;
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;
198 LOGFONTW lf;
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;
210 return count;
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 );
241 return NULL;
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 )
279 if (!data)
281 SetLastError( ERROR_INVALID_PARAMETER );
282 return 0;
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 );