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

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

Added debug wrappers for all exports

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