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

Last change on this file since 7635 was 7635, checked in by sandervl, 24 years ago

Added statistics for font, bitmap, pen, brush & region objects.

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