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

Last change on this file since 5087 was 4963, checked in by sandervl, 25 years ago

SetDIBitsToDevice fix + more logging

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