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