source: trunk/src/kernel32/winres.cpp@ 386

Last change on this file since 386 was 386, checked in by sandervl, 26 years ago

OS2ResHandle bugfix

File size: 9.8 KB
Line 
1/* $Id: winres.cpp,v 1.5 1999-07-24 14:14:06 sandervl Exp $ */
2
3/*
4 * Win32 resource class
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_BASE
13#define INCL_WIN
14#define INCL_GPIBITMAPS
15#define INCL_BITMAPFILEFORMAT
16#define INCL_DOSMODULEMGR
17#include <os2wrap.h> //Odin32 OS/2 api wrappers
18#include <stdarg.h>
19#ifdef __IBMCPP__
20#include <builtin.h>
21#endif
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#define INCL_WINRES
26#include <win32type.h>
27#include <winres.h>
28#include <misc.h>
29#include <nameid.h>
30#include <winexe.h>
31
32static ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy)
33{
34 ULONG alignment;
35 ULONG factor;
36 BOOL flag = TRUE; //true: '*' false: '/'
37
38 cy = cy < 0 ? -cy : cy;
39
40 switch(cBits)
41 {
42 case 1:
43 factor = 8;
44 flag = FALSE;
45 break;
46
47 case 4:
48 factor = 2;
49 flag = FALSE;
50 break;
51
52 case 8:
53 factor = 1;
54 break;
55
56 case 16:
57 factor = 2;
58 break;
59
60 case 24:
61 factor = 3;
62 break;
63
64 case 32:
65 return cx*cy;
66
67 default:
68 return 0;
69 }
70
71 if (flag)
72 alignment = (cx = (cx*factor)) % 4;
73 else
74 alignment = (cx = ((cx+factor-1)/factor)) % 4;
75
76 if (alignment != 0)
77 cx += 4 - alignment;
78
79 return cx*cy;
80}
81
82//******************************************************************************
83//******************************************************************************
84Win32Resource::Win32Resource(Win32Image *module, HRSRC hRes, ULONG id, ULONG type) :
85 os2resdata(NULL), winresdata(NULL)
86{
87 APIRET rc;
88
89 next = module->winres;
90 module->winres = this;
91
92 this->module = module;
93 this->id = id;
94 this->type = type;
95 this->hres = hRes;
96
97 switch(type) {
98 case NTRT_NEWBITMAP:
99 case NTRT_BITMAP:
100 orgos2type = RT_BITMAP;
101 break;
102 case NTRT_CURSOR:
103 case NTRT_GROUP_CURSOR:
104 case NTRT_GROUP_ICON:
105 case NTRT_ICON:
106 orgos2type = RT_POINTER;
107 break;
108 case NTRT_ACCELERATORS:
109 orgos2type = RT_ACCELTABLE;
110 break;
111 case NTRT_NEWMENU:
112 case NTRT_MENU:
113 orgos2type = RT_MENU;
114 break;
115 case NTRT_NEWDIALOG:
116 case NTRT_DIALOG:
117 orgos2type = RT_DIALOG;
118 break;
119 case NTRT_FONTDIR:
120 case NTRT_FONT:
121 case NTRT_MESSAGETABLE:
122 case NTRT_STRING:
123 case NTRT_RCDATA:
124 case NTRT_VERSION:
125 default:
126 orgos2type = RT_RCDATA;
127 break;
128 }
129 OS2ResHandle = 0;
130
131 rc = DosQueryResourceSize(module->hinstance, type, id, &ressize);
132 if(rc) {
133 dprintf(("Win32Resource ctor: DosQueryResourceSize %x %d %d returned %X\n", module->hinstance, type, id, rc));
134 ressize = 0;
135 }
136}
137//******************************************************************************
138//******************************************************************************
139Win32Resource::Win32Resource(Win32Image *module, ULONG id, ULONG type,
140 ULONG size, char *resdata) : hres(NULL),
141 os2resdata(NULL), winresdata(NULL)
142{
143 next = module->winres;
144 module->winres = this;
145
146 this->module = module;
147 this->id = id;
148 this->type = type;
149 orgos2type = -1;
150 this->ressize = size;
151 winresdata = (char *)malloc(size);
152 if(winresdata == NULL) {
153 DebugInt3();
154 return;
155 }
156 memcpy(winresdata, resdata, size);
157}
158//******************************************************************************
159//******************************************************************************
160Win32Resource::~Win32Resource()
161{
162 Win32Resource *res = module->winres;
163
164#if 0
165 //returned by DosGetResource, so we don't (and mustn't) free it
166 if(os2resdata) free(os2resdata);
167#endif
168 if(winresdata) free(winresdata);
169
170 if(res == this) {
171 module->winres = res->next;
172 }
173 else {
174 while(res->next != this) {
175 res = res->next;
176 }
177 if(res)
178 res->next = next;
179 }
180}
181//******************************************************************************
182//******************************************************************************
183PVOID Win32Resource::lockResource()
184{
185 int restype = 0, newid;
186 void *resdata = NULL;
187 APIRET rc;
188 ULONG os2type = RT_RCDATA;
189
190 dprintf(("Win32Resource::lockResource %d\n", id));
191 if(winresdata)
192 return(winresdata);
193
194 switch(type) {
195 case NTRT_BITMAP:
196 rc = DosGetResource((HMODULE)module->hinstance, RT_BITMAP, id, (PPVOID)&resdata);
197 if(rc) return(NULL);
198 winresdata = ConvertBitmap((BITMAPFILEHEADER2 *)resdata);
199 break;
200
201 case NTRT_ACCELERATORS:
202 case NTRT_MENU:
203 case NTRT_DIALOG:
204 newid = module->getWin32ResourceId(id);
205
206 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, (int)newid, (PPVOID)&resdata);
207 if(rc) {
208 dprintf(("Can't find original resource!!!\n"));
209 return(NULL);
210 }
211 winresdata = (char *)malloc(ressize);
212 memcpy(winresdata, resdata, ressize);
213 break;
214
215 //TODO:not yet implemented
216 case NTRT_FONTDIR:
217 case NTRT_FONT:
218 case NTRT_MESSAGETABLE:
219 case NTRT_NEWBITMAP:
220 case NTRT_NEWMENU:
221 case NTRT_NEWDIALOG:
222 os2type = RT_RCDATA;
223 break;
224
225 //Can't do this right now (all group icons stored into a single one)
226 case NTRT_CURSOR:
227 case NTRT_GROUP_CURSOR:
228 case NTRT_GROUP_ICON:
229 case NTRT_ICON:
230 dprintf(("Can't convert this resource!!!!!\n"));
231 os2type = RT_POINTER;
232 break;
233
234 case NTRT_STRING:
235 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, id, (PPVOID)&resdata);
236 if(rc) {
237 dprintf(("Can't find original string!!!\n"));
238 return(NULL);
239 }
240 winresdata = (char *)malloc(ressize);
241 memcpy(winresdata, resdata, ressize);
242 DosFreeResource(resdata);
243 return((PVOID)((ULONG)winresdata+2)); //skip length word
244
245 //no conversion necessary
246 case NTRT_RCDATA:
247 case NTRT_VERSION:
248 default:
249 os2type = RT_RCDATA;
250 break;
251 }
252
253 if(winresdata == NULL) {
254 rc = DosGetResource((HMODULE)module->hinstance, os2type, id, (PPVOID)&resdata);
255 if(rc) {
256 dprintf(("Can't find original string!!!\n"));
257 return(NULL);
258 }
259 winresdata = (char *)malloc(ressize);
260 memcpy(winresdata, resdata, ressize);
261 }
262 if(resdata)
263 DosFreeResource(resdata);
264 return winresdata;
265}
266//******************************************************************************
267//******************************************************************************
268PVOID Win32Resource::lockOS2Resource()
269{
270 APIRET rc;
271 PVOID resdata;
272
273 dprintf(("Win32Resource::lockOS2Resource %d\n", id));
274 if(os2resdata == NULL) {
275 rc = DosGetResource((HMODULE)module->hinstance, orgos2type, id, (PPVOID)&resdata);
276 if(rc) return(NULL);
277 os2resdata = resdata;
278 }
279 return os2resdata;
280}
281//******************************************************************************
282//******************************************************************************
283PVOID Win32Resource::ConvertBitmap(void *bmpdata)
284{
285 BITMAPFILEHEADER2 *bmphdr = (BITMAPFILEHEADER2 *)bmpdata;
286 WINBITMAPINFOHEADER *winbmphdr;
287 RGBQUAD *rgb;
288 RGB2 *os2rgb;
289 int palsize = 0;
290 int imgsize;
291
292 if(bmphdr->cbSize != sizeof(BITMAPFILEHEADER2))
293 return(bmpdata); //don't convert OS/2 1.x bitmap
294
295 if(bmphdr->bmp2.cBitCount < 16) {
296 palsize = (1 << bmphdr->bmp2.cBitCount) * sizeof(RGBQUAD);
297 }
298
299 // EB: ->>> added imgsize
300 if(bmphdr->bmp2.cbImage == 0)
301 imgsize = CalcBitmapSize(bmphdr->bmp2.cBitCount,
302 bmphdr->bmp2.cx,
303 bmphdr->bmp2.cy);
304 else
305 imgsize = bmphdr->bmp2.cbImage;
306
307 winbmphdr = (WINBITMAPINFOHEADER *)malloc(sizeof(WINBITMAPINFOHEADER) +
308 imgsize + palsize);
309 memset((char *)winbmphdr, 0, sizeof(WINBITMAPINFOHEADER) + imgsize + palsize);
310
311 winbmphdr->biSize = sizeof(WINBITMAPINFOHEADER);
312 winbmphdr->biWidth = bmphdr->bmp2.cx;
313 winbmphdr->biHeight = bmphdr->bmp2.cy;
314 winbmphdr->biPlanes = bmphdr->bmp2.cPlanes;
315 winbmphdr->biBitCount = bmphdr->bmp2.cBitCount;
316 //TODO: Identical except for BI_BITFIELDS (3L) type!
317 winbmphdr->biCompression = bmphdr->bmp2.ulCompression;
318 winbmphdr->biSizeImage = bmphdr->bmp2.cbImage; //imgsize;
319 //TODO: Doesn't seem to be completely identical..
320 winbmphdr->biClrUsed = bmphdr->bmp2.cclrUsed;
321 winbmphdr->biClrImportant = bmphdr->bmp2.cclrImportant;
322 winbmphdr->biXPelsPerMeter = bmphdr->bmp2.cxResolution;
323 winbmphdr->biYPelsPerMeter = bmphdr->bmp2.cyResolution;
324
325 os2rgb = (RGB2 *)(bmphdr+1);
326 rgb = (RGBQUAD *)(winbmphdr+1);
327
328 if(palsize) {
329 memcpy((char *)rgb, (char *)os2rgb, palsize);
330 os2rgb = (RGB2 *)((int)os2rgb + palsize);
331 rgb = (RGBQUAD *)((int)rgb + palsize);
332 }
333 memcpy((char *)rgb, (char *)os2rgb, imgsize);
334 return((PVOID)winbmphdr);
335}
336//******************************************************************************
337//******************************************************************************
338void Win32Resource::destroyAll(Win32Image *module)
339{
340 Win32Resource *res = module->winres, *next;
341
342 while(res) {
343 next = res->next;
344 delete(res);
345 res = next;
346 }
347}
348//******************************************************************************
349//******************************************************************************
Note: See TracBrowser for help on using the repository browser.