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

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

SelectObject bugfix for region handles. (fixes crash in Freecell)

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