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

Last change on this file since 8875 was 8875, checked in by sandervl, 23 years ago

dynamically allocate GDI handle array; no need to waste shared memory for local data

File size: 16.4 KB
Line 
1/* $Id: objhandle.cpp,v 1.23 2002-07-15 12:44:27 sandervl Exp $ */
2/*
3 * Win32 Handle Management Code for OS/2
4 *
5 *
6 * Copyright 2000-2002 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * TODO: The table should be dynamically increased when necessary
9 * This is just a quick and dirty implementation
10 *
11 * System objects can't be deleted (TODO: any others?? (fonts?))!!!!)
12 *
13 * Project Odin Software License can be found in LICENSE.TXT
14 *
15 */
16
17#include <os2win.h>
18#include <stdlib.h>
19#include <string.h>
20#include <vmutex.h>
21#include <objhandle.h>
22#include <dcdata.h>
23#include <winuser32.h>
24#include "oslibgpi.h"
25#include "dibsect.h"
26#include "region.h"
27#include <unicode.h>
28#include "font.h"
29#include <stats.h>
30
31#define DBG_LOCALLOG DBG_objhandle
32#include "dbglocal.h"
33
34//TODO: must use 16 bits gdi object handles
35#define GDIOBJ_PREFIX 0xe7000000
36
37//******************************************************************************
38
39typedef struct {
40 DWORD dwUserData;
41 DWORD dwGDI32Data;
42 DWORD dwFlags;
43 DWORD dwType;
44} GdiObject;
45
46static GdiObject *objHandleTable = NULL;
47static ULONG lowestFreeIndex = 1;
48static VMutex objTableMutex;
49
50//******************************************************************************
51//******************************************************************************
52BOOL WIN32API ObjAllocateHandle(HANDLE *hObject, DWORD dwUserData, DWORD dwType)
53{
54 objTableMutex.enter();
55 if(objHandleTable == NULL) {
56 objHandleTable = (GdiObject *)malloc(MAX_OBJECT_HANDLES*sizeof(GdiObject));
57 if(objHandleTable == NULL) {
58 DebugInt3();
59 }
60 }
61
62 if(lowestFreeIndex == -1) {
63 //oops, out of handles
64 objTableMutex.leave();
65 dprintf(("ERROR: GDI: ObjAllocateHandle OUT OF GDI OBJECT HANDLES!!"));
66 DebugInt3();
67 return FALSE;
68 }
69 if(objHandleTable[0].dwType == HNDL_NONE) {
70 //first handle can never be used
71 objHandleTable[0].dwType = HNDL_INVALID;
72 objHandleTable[0].dwUserData = -1;
73 }
74 *hObject = lowestFreeIndex;
75 *hObject = MAKE_HANDLE(*hObject);
76 objHandleTable[lowestFreeIndex].dwUserData = dwUserData;
77 objHandleTable[lowestFreeIndex].dwType = dwType;
78 objHandleTable[lowestFreeIndex].dwGDI32Data = 0;
79 objHandleTable[lowestFreeIndex].dwFlags = 0;
80 lowestFreeIndex = -1;
81
82 //find next free handle
83 for(int i=0;i<MAX_OBJECT_HANDLES;i++) {
84 if(objHandleTable[i].dwUserData == 0) {
85 lowestFreeIndex = i;
86 break;
87 }
88 }
89 objTableMutex.leave();
90 return TRUE;
91}
92//******************************************************************************
93//******************************************************************************
94BOOL WIN32API ObjDeleteHandle(HANDLE hObject, DWORD dwType)
95{
96 hObject &= OBJHANDLE_MAGIC_MASK;
97 if(hObject < MAX_OBJECT_HANDLES) {
98 objTableMutex.enter();
99 if(!(objHandleTable[hObject].dwFlags & OBJHANDLE_FLAG_NODELETE))
100 {
101 objHandleTable[hObject].dwUserData = 0;
102 objHandleTable[hObject].dwType = HNDL_NONE;
103 if(lowestFreeIndex == -1 || hObject < lowestFreeIndex)
104 lowestFreeIndex = hObject;
105 }
106 else {
107 dprintf(("ObjDeleteHandle: unable to delete system object %x", MAKE_HANDLE(hObject)));
108 }
109 objTableMutex.leave();
110 return TRUE;
111 }
112 return FALSE;
113}
114//******************************************************************************
115//******************************************************************************
116DWORD WIN32API ObjQueryHandleData(HANDLE hObject, DWORD dwType)
117{
118 DWORD dwUserData = HANDLE_INVALID_DATA;
119
120 objTableMutex.enter();
121 hObject &= OBJHANDLE_MAGIC_MASK;
122 if(hObject < MAX_OBJECT_HANDLES &&
123 ((dwType == HNDL_ANY && objHandleTable[hObject].dwType != HNDL_NONE) ||
124 dwType == objHandleTable[hObject].dwType))
125 {
126 dwUserData = objHandleTable[hObject].dwUserData;
127 }
128 objTableMutex.leave();
129 return dwUserData;
130}
131//******************************************************************************
132//******************************************************************************
133BOOL WIN32API ObjSetHandleData(HANDLE hObject, DWORD dwType, DWORD dwUserData)
134{
135 BOOL fSuccess = FALSE;
136
137 objTableMutex.enter();
138 hObject &= OBJHANDLE_MAGIC_MASK;
139 if(hObject < MAX_OBJECT_HANDLES &&
140 ((dwType == HNDL_ANY && objHandleTable[hObject].dwType != HNDL_NONE) ||
141 dwType == objHandleTable[hObject].dwType))
142 {
143 objHandleTable[hObject].dwUserData = dwUserData;
144 fSuccess = TRUE;
145 }
146 objTableMutex.leave();
147 return fSuccess;
148}
149//******************************************************************************
150//******************************************************************************
151DWORD WIN32API ObjQueryHandleGDI32Data(HANDLE hObject, DWORD dwType)
152{
153 DWORD dwGDI32Data = HANDLE_INVALID_DATA;
154
155 objTableMutex.enter();
156 hObject &= OBJHANDLE_MAGIC_MASK;
157 if(hObject < MAX_OBJECT_HANDLES &&
158 ((dwType == HNDL_ANY && objHandleTable[hObject].dwType != HNDL_NONE) ||
159 dwType == objHandleTable[hObject].dwType))
160 {
161 dwGDI32Data = objHandleTable[hObject].dwGDI32Data;
162 }
163 objTableMutex.leave();
164 return dwGDI32Data;
165}
166//******************************************************************************
167//******************************************************************************
168BOOL WIN32API ObjSetHandleGDI32Data(HANDLE hObject, DWORD dwType, DWORD dwGDI32Data)
169{
170 BOOL fSuccess = FALSE;
171
172 objTableMutex.enter();
173 hObject &= OBJHANDLE_MAGIC_MASK;
174 if(hObject < MAX_OBJECT_HANDLES &&
175 ((dwType == HNDL_ANY && objHandleTable[hObject].dwType != HNDL_NONE) ||
176 dwType == objHandleTable[hObject].dwType))
177 {
178 objHandleTable[hObject].dwGDI32Data = dwGDI32Data;
179 fSuccess = TRUE;
180 }
181 objTableMutex.leave();
182 return fSuccess;
183}
184//******************************************************************************
185//******************************************************************************
186DWORD WIN32API ObjQueryHandleFlags(OBJHANDLE hObject)
187{
188 DWORD dwFlags = HANDLE_INVALID_DATA;
189
190 objTableMutex.enter();
191 hObject &= OBJHANDLE_MAGIC_MASK;
192 if(hObject < MAX_OBJECT_HANDLES && objHandleTable[hObject].dwType != HNDL_NONE)
193 {
194 dwFlags = objHandleTable[hObject].dwFlags;
195 }
196 objTableMutex.leave();
197 return dwFlags;
198}
199//******************************************************************************
200//******************************************************************************
201BOOL WIN32API ObjSetHandleFlag(HANDLE hObject, DWORD dwFlag, BOOL fSet)
202{
203 BOOL fSuccess = FALSE;
204
205 objTableMutex.enter();
206 hObject &= OBJHANDLE_MAGIC_MASK;
207 if(hObject < MAX_OBJECT_HANDLES && objHandleTable[hObject].dwType != HNDL_NONE) {
208 if(fSet) {
209 objHandleTable[hObject].dwFlags |= dwFlag;
210 }
211 else objHandleTable[hObject].dwFlags &= ~dwFlag;
212
213 dprintf(("ObjSetHandleFlag %x -> %x", MAKE_HANDLE(hObject), dwFlag));
214
215 fSuccess = TRUE;
216 }
217 objTableMutex.leave();
218 return fSuccess;
219}
220//******************************************************************************
221//******************************************************************************
222DWORD WIN32API ObjQueryHandleType(HANDLE hObject)
223{
224 DWORD objtype = 0;
225
226 objTableMutex.enter();
227 hObject &= OBJHANDLE_MAGIC_MASK;
228 if(hObject < MAX_OBJECT_HANDLES && objHandleTable[hObject].dwType != HNDL_NONE) {
229 objtype = objHandleTable[hObject].dwType;
230 }
231 objTableMutex.leave();
232 return objtype;
233}
234//******************************************************************************
235//******************************************************************************
236int WIN32API GetObjectA( HGDIOBJ hObject, int size, void *lpBuffer)
237{
238 int rc;
239
240 dprintf(("GDI32: GetObject %X %X %X\n", hObject, size, lpBuffer));
241
242 if(lpBuffer == NULL)
243 { //return required size if buffer pointer == NULL
244 int objtype = GetObjectType(hObject);
245 switch(objtype)
246 {
247 case OBJ_PEN:
248 return sizeof(LOGPEN);
249
250 case OBJ_EXTPEN:
251 return sizeof(EXTLOGPEN);
252
253 case OBJ_BRUSH:
254 return sizeof(LOGBRUSH);
255
256 case OBJ_PAL:
257 return sizeof(USHORT);
258
259 case OBJ_FONT:
260 return sizeof(LOGFONTA);
261
262 case OBJ_BITMAP:
263 return sizeof(BITMAP); //also default for dib sections??? (TODO: NEED TO CHECK THIS)
264
265 case OBJ_DC:
266 case OBJ_METADC:
267 case OBJ_REGION:
268 case OBJ_METAFILE:
269 case OBJ_MEMDC:
270 case OBJ_ENHMETADC:
271 case OBJ_ENHMETAFILE:
272 dprintf(("warning: GetObjectA not defined for object type %d", objtype));
273 return 0;
274 }
275 }
276 if(DIBSection::getSection() != NULL)
277 {
278 DIBSection *dsect = DIBSection::findObj(hObject);
279 if(dsect)
280 {
281 rc = dsect->GetDIBSection(size, lpBuffer);
282 if(rc == 0) {
283 SetLastError(ERROR_INVALID_PARAMETER);
284 return 0;
285 }
286 SetLastError(ERROR_SUCCESS);
287 return rc;
288 }
289 }
290
291 return O32_GetObject(hObject, size, lpBuffer);
292}
293//******************************************************************************
294//******************************************************************************
295int WIN32API GetObjectW( HGDIOBJ hObject, int size, void *lpBuffer)
296{
297 int ret, objtype;
298
299 dprintf(("GDI32: GetObjectW %X, %d %X", hObject, size, lpBuffer));
300
301 objtype = GetObjectType(hObject);
302
303 switch(objtype)
304 {
305 case OBJ_FONT:
306 {
307 LOGFONTA logfonta;
308
309 if(lpBuffer == NULL) {
310 return sizeof(LOGFONTW); //return required size if buffer pointer == NULL
311 }
312 ret = GetObjectA(hObject, sizeof(logfonta), (void *)&logfonta);
313 if(ret == sizeof(logfonta))
314 {
315 LOGFONTW *logfontw = (LOGFONTW *)lpBuffer;
316
317 if(size < sizeof(LOGFONTW)) {
318 dprintf(("GDI32: GetObjectW : buffer not big enough for LOGFONTW struct!!")); //is the correct? or copy only part?
319 return 0;
320 }
321 memcpy(logfontw, &logfonta, sizeof(LOGFONTA));
322 memset(logfontw->lfFaceName, 0, LF_FACESIZE);
323 AsciiToUnicodeN(logfonta.lfFaceName, logfontw->lfFaceName, LF_FACESIZE-1);
324
325 return sizeof(LOGFONTW);
326 }
327 return 0;
328 }
329 default:
330 return GetObjectA(hObject, size, lpBuffer);
331 }
332}
333//******************************************************************************
334//******************************************************************************
335#ifdef DEBUG
336static char *gditypenames[] = {
337"NULL",
338"OBJ_PEN",
339"OBJ_BRUSH",
340"OBJ_DC",
341"OBJ_METADC",
342"OBJ_PAL",
343"OBJ_FONT",
344"OBJ_BITMAP",
345"OBJ_REGION",
346"OBJ_METAFILE",
347"OBJ_MEMDC",
348"OBJ_EXTPEN",
349"OBJ_ENHMETADC",
350"OBJ_ENHMETAFILE"
351};
352
353char *DbgGetGDITypeName(DWORD handleType)
354{
355 if(handleType <= OBJ_ENHMETAFILE) {
356 return gditypenames[handleType];
357 }
358 return "UNKNOWN TYPE";
359}
360#endif
361//******************************************************************************
362//******************************************************************************
363HGDIOBJ WIN32API SelectObject(HDC hdc, HGDIOBJ hObj)
364{
365 HGDIOBJ rc;
366 DWORD handleType;
367
368 //TODO: must use 16 bits gdi object handles
369 if(HIWORD(hObj) == 0) {
370 hObj |= GDIOBJ_PREFIX;
371 }
372
373 handleType = GetObjectType(hObj);
374 dprintf2(("GDI32: SelectObject %x %x type %s", hdc, hObj, DbgGetGDITypeName(handleType)));
375 if(handleType == HNDL_REGION) {
376 //Return complexity here; not previously selected clip region
377 return (HGDIOBJ)SelectClipRgn(hdc, hObj);
378 }
379
380 if(handleType == OBJ_BITMAP && DIBSection::getSection() != NULL)
381 {
382 DIBSection *dsect;
383
384 dsect = DIBSection::findHDC(hdc);
385 if(dsect)
386 {
387 //remove previously selected dibsection
388 dsect->UnSelectDIBObject();
389 }
390 dsect = DIBSection::findObj(hObj);
391 if(dsect)
392 {
393 dsect->SelectDIBObject(hdc);
394 }
395 }
396 rc = O32_SelectObject(hdc, hObj);
397 if(rc != 0 && GetObjectType(rc) == OBJ_BITMAP && DIBSection::getSection != NULL)
398 {
399 DIBSection *dsect = DIBSection::findObj(rc);
400 if(dsect)
401 {
402 dsect->UnSelectDIBObject();
403 }
404 }
405 dprintf2(("GDI32: SelectObject %x %x returned %x", hdc, hObj, rc));
406
407 return(rc);
408}
409//******************************************************************************
410//Called from user32 ReleaseDC (for non CS_OWNDC hdcs)
411//******************************************************************************
412VOID WIN32API UnselectGDIObjects(HDC hdc)
413{
414 DIBSection *dsect;
415
416 dsect = DIBSection::findHDC(hdc);
417 if(dsect)
418 {
419 //remove previously selected dibsection
420 dsect->UnSelectDIBObject();
421 }
422}
423//******************************************************************************
424//******************************************************************************
425DWORD WIN32API GetObjectType( HGDIOBJ hObj)
426{
427 DWORD objtype = ObjQueryHandleType(hObj);
428
429 switch(objtype) {
430 case HNDL_PEN:
431 objtype = OBJ_PEN;
432 break;
433 case HNDL_BRUSH:
434 objtype = OBJ_BRUSH;
435 break;
436 case HNDL_DC:
437 objtype = OBJ_DC;
438 break;
439 case HNDL_METADC:
440 objtype = OBJ_METADC;
441 break;
442 case HNDL_PALETTE:
443 objtype = OBJ_PAL;
444 break;
445 case HNDL_FONT:
446 objtype = OBJ_FONT;
447 break;
448 case HNDL_BITMAP:
449 case HNDL_DIBSECTION:
450 objtype = OBJ_BITMAP;
451 break;
452 case HNDL_REGION:
453 objtype = OBJ_REGION;
454 break;
455 case HNDL_METAFILE:
456 objtype = OBJ_METAFILE;
457 break;
458 case HNDL_ENHMETAFILE:
459 objtype = OBJ_ENHMETAFILE;
460 break;
461 case HNDL_MEMDC:
462 objtype = OBJ_MEMDC;
463 break;
464 case HNDL_EXTPEN:
465 objtype = OBJ_EXTPEN;
466 break;
467 case HNDL_ENHMETADC:
468 objtype = OBJ_ENHMETADC;
469 break;
470 default:
471 objtype = 0;
472 break;
473 }
474 dprintf2(("GDI32: GetObjectType %x objtype %d (%s)", hObj, objtype, DbgGetGDITypeName(objtype)));
475 return objtype;
476}
477//******************************************************************************
478//TODO: System objects can't be deleted (TODO: any others?? (fonts?))!!!!)
479//******************************************************************************
480BOOL WIN32API DeleteObject(HANDLE hObj)
481{
482 DWORD objtype;
483
484 dprintf(("GDI32: DeleteObject %x", hObj));
485
486 STATS_DeleteObject(hObj, objtype);
487
488 if(ObjQueryHandleType(hObj) == HNDL_REGION)
489 {
490 OSLibDeleteRegion(ObjQueryHandleData(hObj, HNDL_REGION));
491 ObjDeleteHandle(hObj, HNDL_REGION);
492 SetLastError(ERROR_SUCCESS);
493 return TRUE;
494 }
495
496 DIBSection::deleteSection((DWORD)hObj);
497 return O32_DeleteObject(hObj);
498}
499//******************************************************************************
500//******************************************************************************
501int WIN32API EnumObjects( HDC hdc, int objType, GOBJENUMPROC objFunc, LPARAM lParam)
502{
503 //calling convention differences
504 dprintf(("!ERROR!: GDI32: EnumObjects STUB"));
505// return O32_EnumObjects(arg1, arg2, arg3, arg4);
506 return 0;
507}
508//******************************************************************************
509//******************************************************************************
510HANDLE WIN32API GetCurrentObject( HDC hdc, UINT arg2)
511{
512 dprintf(("GDI32: GetCurrentObject %x %x", hdc, arg2));
513 return (HANDLE)O32_GetCurrentObject(hdc, arg2);
514}
515//******************************************************************************
516//******************************************************************************
517BOOL WIN32API SetObjectOwner( HGDIOBJ arg1, int arg2 )
518{
519 // Here is a guess for a undocumented entry
520 dprintf(("WARNING: GDI32: SetObjectOwner - stub (TRUE)\n"));
521 return TRUE;
522}
523//******************************************************************************
524//******************************************************************************
525BOOL WIN32API UnrealizeObject( HGDIOBJ hObject)
526{
527 dprintf(("GDI32: UnrealizeObject %x", hObject));
528 return O32_UnrealizeObject(hObject);
529}
530//******************************************************************************
531//******************************************************************************
Note: See TracBrowser for help on using the repository browser.