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

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

Handle management updates

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