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

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

changed vmutex usage

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