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

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

minor updates

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