source: trunk/src/gdi32/objhandle.cpp@ 7330

Last change on this file since 7330 was 7330, checked in by sandervl, 24 years ago

refuse DeleteObject for DEFAULT_GUI_FONT handle

File size: 12.0 KB
Line 
1/* $Id: objhandle.cpp,v 1.19 2001-11-13 15:42:06 sandervl Exp $ */
2/*
3 * Win32 Handle Management Code for OS/2
4 *
5 *
6 * Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * TODO: The table should be dynamically increased when necessary
10 * This is just a quick and dirty implementation
11 *
12 * Project Odin Software License can be found in LICENSE.TXT
13 *
14 */
15
16#include <os2win.h>
17#include <stdlib.h>
18#include <string.h>
19#include <vmutex.h>
20#include <objhandle.h>
21#include <dcdata.h>
22#include <winuser32.h>
23#include "oslibgpi.h"
24#include "dibsect.h"
25#include "region.h"
26#include <unicode.h>
27#include "font.h"
28
29#define DBG_LOCALLOG DBG_objhandle
30#include "dbglocal.h"
31
32//TODO: must use 16 bits gdi object handles
33#define GDIOBJ_PREFIX 0xe7000000
34
35//******************************************************************************
36
37typedef struct {
38 ULONG dwUserData;
39 ObjectType type;
40} GdiObject;
41
42static GdiObject objHandleTable[MAX_OBJECT_HANDLES] = {0};
43static ULONG lowestFreeIndex = 1;
44static VMutex objTableMutex;
45
46//******************************************************************************
47//******************************************************************************
48BOOL WIN32API ObjAllocateHandle(HANDLE *hObject, DWORD dwUserData, ObjectType type)
49{
50 objTableMutex.enter(VMUTEX_WAIT_FOREVER);
51 if(lowestFreeIndex == -1) {
52 //oops, out of handles
53 objTableMutex.leave();
54 dprintf(("ERROR: GDI: ObjAllocateHandle OUT OF GDI OBJECT HANDLES!!"));
55 DebugInt3();
56 return FALSE;
57 }
58 if(objHandleTable[0].type == 0) {
59 //first handle can never be used
60 objHandleTable[0].type = GDIOBJ_INVALID;
61 objHandleTable[0].dwUserData = -1;
62 }
63 *hObject = lowestFreeIndex;
64 *hObject |= MAKE_HANDLE(type);
65 objHandleTable[lowestFreeIndex].dwUserData = dwUserData;
66 objHandleTable[lowestFreeIndex].type = type;
67
68 lowestFreeIndex = -1;
69
70 //find next free handle
71 for(int i=0;i<MAX_OBJECT_HANDLES;i++) {
72 if(objHandleTable[i].dwUserData == 0) {
73 lowestFreeIndex = i;
74 break;
75 }
76 }
77 objTableMutex.leave();
78 return TRUE;
79}
80//******************************************************************************
81//******************************************************************************
82void WIN32API ObjFreeHandle(HANDLE hObject)
83{
84 hObject &= OBJHANDLE_MAGIC_MASK;
85 if(hObject < MAX_OBJECT_HANDLES) {
86 objTableMutex.enter(VMUTEX_WAIT_FOREVER);
87 objHandleTable[hObject].dwUserData = 0;
88 objHandleTable[hObject].type = GDIOBJ_NONE;
89 if(lowestFreeIndex == -1 || hObject < lowestFreeIndex)
90 lowestFreeIndex = hObject;
91
92 objTableMutex.leave();
93 }
94}
95//******************************************************************************
96//******************************************************************************
97DWORD WIN32API ObjGetHandleData(HANDLE hObject, ObjectType type)
98{
99 hObject &= OBJHANDLE_MAGIC_MASK;
100 if(hObject < MAX_OBJECT_HANDLES && type == objHandleTable[hObject].type) {
101 return objHandleTable[hObject].dwUserData;
102 }
103 return HANDLE_OBJ_ERROR;
104}
105//******************************************************************************
106//******************************************************************************
107ObjectType WIN32API ObjGetHandleType(HANDLE hObject)
108{
109 DWORD objtype;
110
111 switch(OBJHANDLE_MAGIC(hObject))
112 {
113 case GDIOBJ_REGION:
114 hObject &= OBJHANDLE_MAGIC_MASK;
115 if(hObject < MAX_OBJECT_HANDLES && objHandleTable[hObject].type == GDIOBJ_REGION) {
116 return GDIOBJ_REGION;
117 }
118 break;
119
120 case USEROBJ_MENU:
121 hObject &= OBJHANDLE_MAGIC_MASK;
122 if(hObject < MAX_OBJECT_HANDLES && objHandleTable[hObject].type == USEROBJ_MENU) {
123 return USEROBJ_MENU;
124 }
125 break;
126
127 case GDIOBJ_NONE:
128 //could be a cutoff menu handle, check this
129 //TODO: dangerous assumption! (need to rewrite object handle management)
130 hObject &= OBJHANDLE_MAGIC_MASK;
131 if(hObject < MAX_OBJECT_HANDLES && objHandleTable[hObject].dwUserData != 0 && objHandleTable[hObject].type == USEROBJ_MENU) {
132 return USEROBJ_MENU;
133 }
134 break;
135
136 case GDIOBJ_BITMAP:
137 case GDIOBJ_BRUSH:
138 case GDIOBJ_PALETTE:
139 case GDIOBJ_FONT:
140 case USEROBJ_ACCEL:
141 default:
142 break;
143 }
144 return GDIOBJ_NONE;
145}
146//******************************************************************************
147//******************************************************************************
148int WIN32API GetObjectA( HGDIOBJ hObject, int size, void *lpBuffer)
149{
150 int rc;
151
152 dprintf(("GDI32: GetObject %X %X %X\n", hObject, size, lpBuffer));
153 //TODO: must use 16 bits gdi object handles
154 if(HIWORD(hObject) == 0) {
155 hObject |= GDIOBJ_PREFIX;
156 }
157 if(lpBuffer == NULL)
158 { //return required size if buffer pointer == NULL
159 int objtype = GetObjectType(hObject);
160 switch(objtype)
161 {
162 case OBJ_PEN:
163 return sizeof(LOGPEN);
164
165 case OBJ_EXTPEN:
166 return sizeof(EXTLOGPEN);
167
168 case OBJ_BRUSH:
169 return sizeof(LOGBRUSH);
170
171 case OBJ_PAL:
172 return sizeof(USHORT);
173
174 case OBJ_FONT:
175 return sizeof(LOGFONTA);
176
177 case OBJ_BITMAP:
178 return sizeof(BITMAP); //also default for dib sections??? (TODO: NEED TO CHECK THIS)
179
180 case OBJ_DC:
181 case OBJ_METADC:
182 case OBJ_REGION:
183 case OBJ_METAFILE:
184 case OBJ_MEMDC:
185 case OBJ_ENHMETADC:
186 case OBJ_ENHMETAFILE:
187 dprintf(("warning: GetObjectA not defined for object type %d", objtype));
188 return 0;
189 }
190 }
191 if(DIBSection::getSection() != NULL)
192 {
193 DIBSection *dsect = DIBSection::findObj(hObject);
194 if(dsect)
195 {
196 rc = dsect->GetDIBSection(size, lpBuffer);
197 if(rc == 0) {
198 SetLastError(ERROR_INVALID_PARAMETER);
199 return 0;
200 }
201 SetLastError(ERROR_SUCCESS);
202 return rc;
203 }
204 }
205
206 return O32_GetObject(hObject, size, lpBuffer);
207}
208//******************************************************************************
209//******************************************************************************
210int WIN32API GetObjectW( HGDIOBJ hObject, int size, void *lpBuffer)
211{
212 int ret, objtype;
213
214 dprintf(("GDI32: GetObjectW %X, %d %X", hObject, size, lpBuffer));
215
216 //TODO: must use 16 bits gdi object handles
217 if(HIWORD(hObject) == 0) {
218 hObject |= GDIOBJ_PREFIX;
219 }
220 objtype = GetObjectType(hObject);
221
222 switch(objtype)
223 {
224 case OBJ_FONT:
225 {
226 LOGFONTA logfonta;
227
228 if(lpBuffer == NULL) {
229 return sizeof(LOGFONTW); //return required size if buffer pointer == NULL
230 }
231 ret = GetObjectA(hObject, sizeof(logfonta), (void *)&logfonta);
232 if(ret == sizeof(logfonta))
233 {
234 LOGFONTW *logfontw = (LOGFONTW *)lpBuffer;
235
236 if(size < sizeof(LOGFONTW)) {
237 dprintf(("GDI32: GetObjectW : buffer not big enough for LOGFONTW struct!!")); //is the correct? or copy only part?
238 return 0;
239 }
240 memcpy(logfontw, &logfonta, sizeof(LOGFONTA));
241 memset(logfontw->lfFaceName, 0, LF_FACESIZE);
242 AsciiToUnicodeN(logfonta.lfFaceName, logfontw->lfFaceName, LF_FACESIZE-1);
243
244 return sizeof(LOGFONTW);
245 }
246 return 0;
247 }
248 default:
249 return GetObjectA(hObject, size, lpBuffer);
250 }
251}
252//******************************************************************************
253//******************************************************************************
254HGDIOBJ WIN32API SelectObject(HDC hdc, HGDIOBJ hObj)
255{
256 HGDIOBJ rc;
257 DWORD handleType;
258
259 //TODO: must use 16 bits gdi object handles
260 if(HIWORD(hObj) == 0) {
261 hObj |= GDIOBJ_PREFIX;
262 }
263
264 handleType = GetObjectType(hObj);
265 dprintf2(("GDI32: SelectObject %x %x type %x", hdc, hObj, handleType));
266 if(handleType == GDIOBJ_REGION) {
267 //Return complexity here; not previously selected clip region
268 return (HGDIOBJ)SelectClipRgn(hdc, hObj);
269 }
270
271 if(handleType == OBJ_BITMAP && DIBSection::getSection() != NULL)
272 {
273 DIBSection *dsect;
274
275 dsect = DIBSection::findHDC(hdc);
276 if(dsect)
277 {
278 //remove previously selected dibsection
279 dsect->UnSelectDIBObject();
280 }
281 dsect = DIBSection::findObj(hObj);
282 if(dsect)
283 {
284 dsect->SelectDIBObject(hdc);
285 }
286 }
287 rc = O32_SelectObject(hdc, hObj);
288 if(rc != 0 && GetObjectType(rc) == OBJ_BITMAP && DIBSection::getSection != NULL)
289 {
290 DIBSection *dsect = DIBSection::findObj(rc);
291 if(dsect)
292 {
293 dsect->UnSelectDIBObject();
294 }
295 }
296#ifdef USING_OPEN32
297 if(handleType == OBJ_BITMAP)
298 {
299 //SvL: Open32 messes up the height of the hdc (for windows)
300 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
301 if(pHps && pHps->hwnd) {
302 dprintf2(("change back origin"));
303 selectClientArea(pHps);
304 setPageXForm(pHps);
305 }
306 }
307#endif
308 dprintf2(("GDI32: SelectObject %x %x returned %x", hdc, hObj, rc));
309
310 return(rc);
311}
312//******************************************************************************
313//Called from user32 ReleaseDC (for non CS_OWNDC hdcs)
314//******************************************************************************
315VOID WIN32API UnselectGDIObjects(HDC hdc)
316{
317 DIBSection *dsect;
318
319 dsect = DIBSection::findHDC(hdc);
320 if(dsect)
321 {
322 //remove previously selected dibsection
323 dsect->UnSelectDIBObject();
324 }
325}
326//******************************************************************************
327//******************************************************************************
328DWORD WIN32API GetObjectType( HGDIOBJ hObj)
329{
330 dprintf2(("GDI32: GetObjectType %x", hObj));
331 //TODO: must use 16 bits gdi object handles
332 if(HIWORD(hObj) == 0) {
333 hObj |= GDIOBJ_PREFIX;
334 }
335 if(ObjGetHandleType(hObj) == GDIOBJ_REGION) {
336 SetLastError(ERROR_SUCCESS);
337 return OBJ_REGION;
338 }
339 return O32_GetObjectType(hObj);
340}
341//******************************************************************************
342//TODO: System objects can't be deleted (TODO: any others?? (fonts?))!!!!)
343//******************************************************************************
344BOOL WIN32API DeleteObject(HANDLE hObj)
345{
346 dprintf(("GDI32: DeleteObject %x", hObj));
347
348 //TODO: must use 16 bits gdi object handles
349 if(HIWORD(hObj) == 0)
350 {
351 hObj |= GDIOBJ_PREFIX;
352 }
353
354 //System objects can't be deleted (TODO: any others?? (fonts?))!!!!)
355 switch (GetObjectType(hObj))
356 {
357 case OBJ_PEN:
358 if(IsSystemPen(hObj))
359 {
360 SetLastError(ERROR_SUCCESS);
361 return TRUE;
362 }
363 else
364 break;
365
366 case OBJ_BRUSH:
367 if(IsSystemBrush(hObj))
368 {
369 SetLastError(ERROR_SUCCESS);
370 return TRUE;
371 }
372 else
373 break;
374
375 case OBJ_FONT:
376 if(IsSystemFont(hObj))
377 {
378 SetLastError(ERROR_SUCCESS);
379 return TRUE;
380 }
381 else
382 break;
383
384 // add more system-type objects as required ...
385 }
386
387 if(ObjGetHandleType(hObj) == GDIOBJ_REGION)
388 {
389 OSLibDeleteRegion(ObjGetHandleData(hObj, GDIOBJ_REGION));
390 ObjFreeHandle(hObj);
391 SetLastError(ERROR_SUCCESS);
392 return TRUE;
393 }
394
395 DIBSection::deleteSection((DWORD)hObj);
396 return O32_DeleteObject(hObj);
397}
398//******************************************************************************
399//******************************************************************************
400BOOL WIN32API SetObjectOwner( HGDIOBJ arg1, int arg2 )
401{
402 // Here is a guess for a undocumented entry
403 dprintf(("WARNING: GDI32: SetObjectOwner - stub (TRUE)\n"));
404 return TRUE;
405}
406//******************************************************************************
407//******************************************************************************
Note: See TracBrowser for help on using the repository browser.