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