xref: /reactos/win32ss/gdi/gdi32/objects/gdiobj.c (revision c3a45b67)
1c2c66affSColin Finck #include <precomp.h>
2c2c66affSColin Finck 
3c2c66affSColin Finck #define NDEBUG
4c2c66affSColin Finck #include <debug.h>
5c2c66affSColin Finck 
6c2c66affSColin Finck HGDIOBJ stock_objects[NB_STOCK_OBJECTS];
7c2c66affSColin Finck 
8c2c66affSColin Finck /*
9c2c66affSColin Finck  * @implemented
10c2c66affSColin Finck  */
11c2c66affSColin Finck HGDIOBJ
12c2c66affSColin Finck WINAPI
GetStockObject(INT fnObject)13c2c66affSColin Finck GetStockObject(
14c2c66affSColin Finck     INT fnObject)
15c2c66affSColin Finck {
16c2c66affSColin Finck     HGDIOBJ hobj;
17c2c66affSColin Finck 
18c2c66affSColin Finck     if ((fnObject < 0) || (fnObject >= NB_STOCK_OBJECTS))
19c2c66affSColin Finck         return NULL;
20c2c66affSColin Finck 
21c2c66affSColin Finck     hobj = stock_objects[fnObject];
22c2c66affSColin Finck     if (hobj == NULL)
23c2c66affSColin Finck     {
24c2c66affSColin Finck         hobj = NtGdiGetStockObject(fnObject);
25c2c66affSColin Finck 
26c2c66affSColin Finck         if (!GdiValidateHandle(hobj))
27c2c66affSColin Finck         {
28c2c66affSColin Finck             return NULL;
29c2c66affSColin Finck         }
30c2c66affSColin Finck 
31c2c66affSColin Finck         stock_objects[fnObject] = hobj;
32c2c66affSColin Finck     }
33c2c66affSColin Finck 
34c2c66affSColin Finck     return hobj;
35c2c66affSColin Finck }
36c2c66affSColin Finck 
37c2c66affSColin Finck 
38c2c66affSColin Finck /*
39c2c66affSColin Finck  * @implemented
40c2c66affSColin Finck  */
41c2c66affSColin Finck DWORD
42c2c66affSColin Finck WINAPI
GetObjectType(HGDIOBJ h)43c2c66affSColin Finck GetObjectType(
44c2c66affSColin Finck     HGDIOBJ h)
45c2c66affSColin Finck {
46c2c66affSColin Finck     DWORD Ret = 0;
47c2c66affSColin Finck 
48c2c66affSColin Finck     if (GdiValidateHandle(h))
49c2c66affSColin Finck     {
50c2c66affSColin Finck         LONG Type = GDI_HANDLE_GET_TYPE(h);
51c2c66affSColin Finck         switch(Type)
52c2c66affSColin Finck         {
53c2c66affSColin Finck         case GDI_OBJECT_TYPE_PEN:
54c2c66affSColin Finck             Ret = OBJ_PEN;
55c2c66affSColin Finck             break;
56c2c66affSColin Finck         case GDI_OBJECT_TYPE_BRUSH:
57c2c66affSColin Finck             Ret = OBJ_BRUSH;
58c2c66affSColin Finck             break;
59c2c66affSColin Finck         case GDI_OBJECT_TYPE_BITMAP:
60c2c66affSColin Finck             Ret = OBJ_BITMAP;
61c2c66affSColin Finck             break;
62c2c66affSColin Finck         case GDI_OBJECT_TYPE_FONT:
63c2c66affSColin Finck             Ret = OBJ_FONT;
64c2c66affSColin Finck             break;
65c2c66affSColin Finck         case GDI_OBJECT_TYPE_PALETTE:
66c2c66affSColin Finck             Ret = OBJ_PAL;
67c2c66affSColin Finck             break;
68c2c66affSColin Finck         case GDI_OBJECT_TYPE_REGION:
69c2c66affSColin Finck             Ret = OBJ_REGION;
70c2c66affSColin Finck             break;
71c2c66affSColin Finck         case GDI_OBJECT_TYPE_DC:
72c2c66affSColin Finck             if ( GetDCDWord( h, GdiGetIsMemDc, 0))
73c2c66affSColin Finck             {
74c2c66affSColin Finck                 Ret = OBJ_MEMDC;
75c2c66affSColin Finck             }
76c2c66affSColin Finck             else
77c2c66affSColin Finck                 Ret = OBJ_DC;
78c2c66affSColin Finck             break;
79c2c66affSColin Finck         case GDI_OBJECT_TYPE_COLORSPACE:
80c2c66affSColin Finck             Ret = OBJ_COLORSPACE;
81c2c66affSColin Finck             break;
82c2c66affSColin Finck         case GDI_OBJECT_TYPE_METAFILE:
83c2c66affSColin Finck             Ret = OBJ_METAFILE;
84c2c66affSColin Finck             break;
85c2c66affSColin Finck         case GDI_OBJECT_TYPE_ENHMETAFILE:
86c2c66affSColin Finck             Ret = OBJ_ENHMETAFILE;
87c2c66affSColin Finck             break;
88c2c66affSColin Finck         case GDI_OBJECT_TYPE_METADC:
89c2c66affSColin Finck             Ret = OBJ_METADC;
90c2c66affSColin Finck             break;
91c2c66affSColin Finck         case GDI_OBJECT_TYPE_EXTPEN:
92c2c66affSColin Finck             Ret = OBJ_EXTPEN;
93c2c66affSColin Finck             break;
94c2c66affSColin Finck 
95c2c66affSColin Finck         case GDILoObjType_LO_ALTDC_TYPE:
96c2c66affSColin Finck             // FIXME: could be something else?
97c2c66affSColin Finck             Ret = OBJ_ENHMETADC;
98c2c66affSColin Finck             break;
99c2c66affSColin Finck 
100c2c66affSColin Finck         default:
101c2c66affSColin Finck             DPRINT1("GetObjectType: Magic 0x%08x not implemented\n", Type);
102c2c66affSColin Finck             break;
103c2c66affSColin Finck         }
104c2c66affSColin Finck     }
105c2c66affSColin Finck     else
106c2c66affSColin Finck         /* From Wine: GetObjectType does SetLastError() on a null object */
107c2c66affSColin Finck         SetLastError(ERROR_INVALID_HANDLE);
108c2c66affSColin Finck     return Ret;
109c2c66affSColin Finck }
110c2c66affSColin Finck 
111c2c66affSColin Finck ULONG
112c2c66affSColin Finck WINAPI
GetFontObjectA(_In_ HGDIOBJ hfont,_In_ ULONG cbSize,_Out_ LPVOID lpBuffer)113c2c66affSColin Finck GetFontObjectA(
114c2c66affSColin Finck     _In_ HGDIOBJ hfont,
115c2c66affSColin Finck     _In_ ULONG cbSize,
116c2c66affSColin Finck     _Out_ LPVOID lpBuffer)
117c2c66affSColin Finck {
118c2c66affSColin Finck     ENUMLOGFONTEXDVW elfedvW;
119c2c66affSColin Finck     ENUMLOGFONTEXDVA elfedvA;
120c2c66affSColin Finck     ULONG cbResult;
121c2c66affSColin Finck 
122c2c66affSColin Finck     /* Check if size only is requested */
123c2c66affSColin Finck     if (!lpBuffer) return sizeof(LOGFONTA);
124c2c66affSColin Finck 
125c2c66affSColin Finck     /* Check for size 0 */
126c2c66affSColin Finck     if (cbSize == 0)
127c2c66affSColin Finck     {
128c2c66affSColin Finck         /* Windows does not SetLastError() */
129c2c66affSColin Finck         return 0;
130c2c66affSColin Finck     }
131c2c66affSColin Finck 
132c2c66affSColin Finck     /* Windows does this ... */
133c2c66affSColin Finck     if (cbSize == sizeof(LOGFONTW)) cbSize = sizeof(LOGFONTA);
134c2c66affSColin Finck 
135c2c66affSColin Finck     /* Call win32k to get the logfont (widechar) */
136c2c66affSColin Finck     cbResult = NtGdiExtGetObjectW(hfont, sizeof(ENUMLOGFONTEXDVW), &elfedvW);
137c2c66affSColin Finck     if (cbResult == 0)
138c2c66affSColin Finck     {
139c2c66affSColin Finck         return 0;
140c2c66affSColin Finck     }
141c2c66affSColin Finck 
142c2c66affSColin Finck     /* Convert the logfont from widechar to ansi */
143c2c66affSColin Finck     EnumLogFontExW2A(&elfedvA.elfEnumLogfontEx, &elfedvW.elfEnumLogfontEx);
144c2c66affSColin Finck     elfedvA.elfDesignVector = elfedvW.elfDesignVector;
145c2c66affSColin Finck 
146c2c66affSColin Finck     /* Don't copy more than maximum */
147c2c66affSColin Finck     if (cbSize > sizeof(ENUMLOGFONTEXDVA)) cbSize = sizeof(ENUMLOGFONTEXDVA);
148c2c66affSColin Finck 
149c2c66affSColin Finck     /* Copy the number of bytes requested */
150c2c66affSColin Finck     memcpy(lpBuffer, &elfedvA, cbSize);
151c2c66affSColin Finck 
152c2c66affSColin Finck     /* Return the number of bytes copied */
153c2c66affSColin Finck     return cbSize;
154c2c66affSColin Finck }
155c2c66affSColin Finck 
156c2c66affSColin Finck 
157c2c66affSColin Finck /*
158c2c66affSColin Finck  * @implemented
159c2c66affSColin Finck  */
160c2c66affSColin Finck int
161c2c66affSColin Finck WINAPI
GetObjectA(_In_ HGDIOBJ hGdiObj,_In_ int cbSize,_Out_ LPVOID lpBuffer)162c2c66affSColin Finck GetObjectA(
163c2c66affSColin Finck     _In_ HGDIOBJ hGdiObj,
164c2c66affSColin Finck     _In_ int cbSize,
165c2c66affSColin Finck     _Out_ LPVOID lpBuffer)
166c2c66affSColin Finck {
167c2c66affSColin Finck     DWORD dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
168c2c66affSColin Finck 
169c2c66affSColin Finck     /* Chjeck if this is anything else but a font */
170c2c66affSColin Finck     if (dwType == GDI_OBJECT_TYPE_FONT)
171c2c66affSColin Finck     {
172c2c66affSColin Finck         return GetFontObjectA(hGdiObj, cbSize, lpBuffer);
173c2c66affSColin Finck     }
174c2c66affSColin Finck     else
175c2c66affSColin Finck     {
176c2c66affSColin Finck         /* Simply pass it to the widechar version */
177c2c66affSColin Finck         return GetObjectW(hGdiObj, cbSize, lpBuffer);
178c2c66affSColin Finck     }
179c2c66affSColin Finck }
180c2c66affSColin Finck 
181c2c66affSColin Finck 
182c2c66affSColin Finck /*
183c2c66affSColin Finck  * @implemented
184c2c66affSColin Finck  */
185c2c66affSColin Finck int
186c2c66affSColin Finck WINAPI
GetObjectW(_In_ HGDIOBJ hGdiObj,_In_ int cbSize,_Out_ LPVOID lpBuffer)187c2c66affSColin Finck GetObjectW(
188c2c66affSColin Finck     _In_ HGDIOBJ hGdiObj,
189c2c66affSColin Finck     _In_ int cbSize,
190c2c66affSColin Finck     _Out_ LPVOID lpBuffer)
191c2c66affSColin Finck {
192c2c66affSColin Finck     DWORD dwType;
193c2c66affSColin Finck     INT cbResult = 0;
194c2c66affSColin Finck 
195c2c66affSColin Finck     /* Fixup handles with upper 16 bits masked */
196c2c66affSColin Finck     hGdiObj = GdiFixUpHandle(hGdiObj);
197c2c66affSColin Finck 
198c2c66affSColin Finck     /* Get the object type */
199c2c66affSColin Finck     dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
200c2c66affSColin Finck 
201c2c66affSColin Finck     /* Check what kind of object we have */
202c2c66affSColin Finck     switch (dwType)
203c2c66affSColin Finck     {
204c2c66affSColin Finck         case GDI_OBJECT_TYPE_PEN:
205c2c66affSColin Finck             if (!lpBuffer) return sizeof(LOGPEN);
206c2c66affSColin Finck             break;
207c2c66affSColin Finck 
208c2c66affSColin Finck         case GDI_OBJECT_TYPE_BRUSH:
209b57be0a7SVictor Martinez Calvo             if (!lpBuffer) return sizeof(LOGBRUSH);
210c2c66affSColin Finck             break;
211c2c66affSColin Finck 
212c2c66affSColin Finck         case GDI_OBJECT_TYPE_BITMAP:
213c2c66affSColin Finck             if (!lpBuffer) return sizeof(BITMAP);
214c2c66affSColin Finck             break;
215c2c66affSColin Finck 
216c2c66affSColin Finck         case GDI_OBJECT_TYPE_PALETTE:
217c2c66affSColin Finck             if (!lpBuffer) return sizeof(WORD);
218c2c66affSColin Finck             break;
219c2c66affSColin Finck 
220c2c66affSColin Finck         case GDI_OBJECT_TYPE_FONT:
221c2c66affSColin Finck             if (!lpBuffer) return sizeof(LOGFONTW);
222c2c66affSColin Finck             break;
223c2c66affSColin Finck 
224c2c66affSColin Finck         case GDI_OBJECT_TYPE_EXTPEN:
225c2c66affSColin Finck             /* we don't know the size, ask win32k */
226c2c66affSColin Finck             break;
227c2c66affSColin Finck 
228c2c66affSColin Finck         case GDI_OBJECT_TYPE_COLORSPACE:
229c2c66affSColin Finck             if ((cbSize < 328) || !lpBuffer)
230c2c66affSColin Finck             {
231c2c66affSColin Finck                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
232c2c66affSColin Finck                 return 0;
233c2c66affSColin Finck             }
234c2c66affSColin Finck             break;
235c2c66affSColin Finck 
236c2c66affSColin Finck         case GDI_OBJECT_TYPE_DC:
237c2c66affSColin Finck         case GDI_OBJECT_TYPE_REGION:
238c2c66affSColin Finck         case GDI_OBJECT_TYPE_EMF:
239c2c66affSColin Finck         case GDI_OBJECT_TYPE_METAFILE:
240c2c66affSColin Finck         case GDI_OBJECT_TYPE_ENHMETAFILE:
241c2c66affSColin Finck             SetLastError(ERROR_INVALID_HANDLE);
242c2c66affSColin Finck         default:
243c2c66affSColin Finck             return 0;
244c2c66affSColin Finck     }
245c2c66affSColin Finck 
246c2c66affSColin Finck     /* Call win32k */
247c2c66affSColin Finck     cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
248c2c66affSColin Finck 
249c2c66affSColin Finck     /* Handle error */
250c2c66affSColin Finck     if (cbResult == 0)
251c2c66affSColin Finck     {
252c2c66affSColin Finck         if (!GdiValidateHandle(hGdiObj))
253c2c66affSColin Finck         {
254c2c66affSColin Finck             if ((dwType == GDI_OBJECT_TYPE_PEN) ||
255c2c66affSColin Finck                 (dwType == GDI_OBJECT_TYPE_EXTPEN) ||
256c2c66affSColin Finck                 (dwType == GDI_OBJECT_TYPE_BRUSH) ||
257c2c66affSColin Finck                 (dwType == GDI_OBJECT_TYPE_COLORSPACE))
258c2c66affSColin Finck             {
259c2c66affSColin Finck                 SetLastError(ERROR_INVALID_PARAMETER);
260c2c66affSColin Finck             }
261c2c66affSColin Finck         }
262c2c66affSColin Finck         else
263c2c66affSColin Finck         {
264c2c66affSColin Finck             if ((dwType == GDI_OBJECT_TYPE_PEN) ||
265c2c66affSColin Finck                 (dwType == GDI_OBJECT_TYPE_BRUSH) ||
266c2c66affSColin Finck                 (dwType == GDI_OBJECT_TYPE_COLORSPACE) ||
267c2c66affSColin Finck                 ( (dwType == GDI_OBJECT_TYPE_EXTPEN) &&
268*c3a45b67SJose Carlos Jesus                     ( (cbSize >= sizeof(EXTLOGPEN)))) ||
269c2c66affSColin Finck                 ( (dwType == GDI_OBJECT_TYPE_BITMAP) && (cbSize >= sizeof(BITMAP)) ))
270c2c66affSColin Finck             {
271*c3a45b67SJose Carlos Jesus                 if (cbSize)
272c2c66affSColin Finck                     SetLastError(ERROR_NOACCESS);
273c2c66affSColin Finck             }
274c2c66affSColin Finck         }
275c2c66affSColin Finck     }
276c2c66affSColin Finck 
277c2c66affSColin Finck     return cbResult;
278c2c66affSColin Finck }
279c2c66affSColin Finck 
280c2c66affSColin Finck static
281c2c66affSColin Finck BOOL
GdiDeleteBrushOrPen(HGDIOBJ hobj)282c2c66affSColin Finck GdiDeleteBrushOrPen(
283c2c66affSColin Finck     HGDIOBJ hobj)
284c2c66affSColin Finck {
285c2c66affSColin Finck     GDILOOBJTYPE eObjectType;
286c2c66affSColin Finck     PBRUSH_ATTR pbrattr;
287c2c66affSColin Finck     PTEB pTeb;
288c2c66affSColin Finck     PGDIBSOBJECT pgO;
289c2c66affSColin Finck 
290c2c66affSColin Finck     eObjectType = GDI_HANDLE_GET_TYPE(hobj);
291c2c66affSColin Finck 
292c2c66affSColin Finck     if ((GdiGetHandleUserData(hobj, eObjectType, (PVOID*)&pbrattr)) &&
293c2c66affSColin Finck         (pbrattr != NULL))
294c2c66affSColin Finck     {
295c2c66affSColin Finck         pTeb = NtCurrentTeb();
296c2c66affSColin Finck         if (pTeb->Win32ThreadInfo != NULL)
297c2c66affSColin Finck         {
298c2c66affSColin Finck             pgO = GdiAllocBatchCommand(NULL, GdiBCDelObj);
299c2c66affSColin Finck             if (pgO)
300c2c66affSColin Finck             {
301c2c66affSColin Finck                 /// FIXME: we need to mark the object as deleted!
302c2c66affSColin Finck                 pgO->hgdiobj = hobj;
303c2c66affSColin Finck                 return TRUE;
304c2c66affSColin Finck             }
305c2c66affSColin Finck         }
306c2c66affSColin Finck     }
307c2c66affSColin Finck 
308c2c66affSColin Finck     return NtGdiDeleteObjectApp(hobj);
309c2c66affSColin Finck }
310c2c66affSColin Finck 
311c2c66affSColin Finck /*
312c2c66affSColin Finck  * @implemented
313c2c66affSColin Finck  */
314c2c66affSColin Finck BOOL
315c2c66affSColin Finck WINAPI
DeleteObject(HGDIOBJ hObject)316c2c66affSColin Finck DeleteObject(HGDIOBJ hObject)
317c2c66affSColin Finck {
318c2c66affSColin Finck     /* Check if the handle is valid (FIXME: we need some special
319c2c66affSColin Finck        sauce for the stock object flag) */
320c2c66affSColin Finck     if (!GdiValidateHandle(hObject))
321c2c66affSColin Finck         return FALSE;
322c2c66affSColin Finck 
323c2c66affSColin Finck     /* Check if this is a stock object */
324dd75ae8eSThamatip Chitpong     if (GDI_HANDLE_IS_STOCKOBJ(hObject))
325c2c66affSColin Finck     {
326c2c66affSColin Finck         /* Ignore the attempt to delete a stock object */
327fc16259fSJames Tabor         DPRINT1("Trying to delete system object 0x%p\n", hObject);
328c2c66affSColin Finck         return TRUE;
329c2c66affSColin Finck     }
330c2c66affSColin Finck 
331c2c66affSColin Finck     /* If we have any METAFILE objects, we need to check them */
332c2c66affSColin Finck     if (gcClientObj > 0)
333c2c66affSColin Finck     {
334fc16259fSJames Tabor         DPRINT("Going Glue\n");
335fc16259fSJames Tabor         METADC_RosGlueDeleteObject(hObject);
336c2c66affSColin Finck     }
337c2c66affSColin Finck 
338c2c66affSColin Finck     /* Switch by object type */
339c2c66affSColin Finck     switch (GDI_HANDLE_GET_TYPE(hObject))
340c2c66affSColin Finck     {
341c2c66affSColin Finck         case GDILoObjType_LO_METAFILE16_TYPE:
342c2c66affSColin Finck         case GDILoObjType_LO_METAFILE_TYPE:
343c2c66affSColin Finck             return FALSE;
344c2c66affSColin Finck 
345c2c66affSColin Finck         case GDILoObjType_LO_DC_TYPE:
346c2c66affSColin Finck         case GDILoObjType_LO_ALTDC_TYPE:
347c2c66affSColin Finck             return DeleteDC(hObject);
348c2c66affSColin Finck 
349c2c66affSColin Finck         case GDILoObjType_LO_ICMLCS_TYPE:
350c2c66affSColin Finck             return NtGdiDeleteColorSpace(hObject);
351c2c66affSColin Finck 
352c2c66affSColin Finck         case GDILoObjType_LO_REGION_TYPE:
353c2c66affSColin Finck             return DeleteRegion(hObject);
354fc16259fSJames Tabor 
355c2c66affSColin Finck         case GDILoObjType_LO_BRUSH_TYPE:
356c2c66affSColin Finck         case GDILoObjType_LO_PEN_TYPE:
357c2c66affSColin Finck         case GDILoObjType_LO_EXTPEN_TYPE:
358c2c66affSColin Finck             return GdiDeleteBrushOrPen(hObject);
359c2c66affSColin Finck 
360c2c66affSColin Finck         case GDILoObjType_LO_FONT_TYPE:
361c2c66affSColin Finck         case GDILoObjType_LO_BITMAP_TYPE:
362c2c66affSColin Finck         default:
363c2c66affSColin Finck             break;
364c2c66affSColin Finck     }
365c2c66affSColin Finck 
366c2c66affSColin Finck     return NtGdiDeleteObjectApp(hObject);
367c2c66affSColin Finck }
368c2c66affSColin Finck 
369c2c66affSColin Finck 
370