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

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

Added class for menu resources + fixed makefile

File size: 12.3 KB
Line 
1/* $Id: winres.cpp,v 1.13 1999-08-31 14:36:46 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 */
13#define INCL_BASE
14#define INCL_WIN
15#define INCL_GPIBITMAPS
16#define INCL_BITMAPFILEFORMAT
17#define INCL_DOSMODULEMGR
18#include <os2wrap.h> //Odin32 OS/2 api wrappers
19#include <stdarg.h>
20#ifdef __IBMCPP__
21#include <builtin.h>
22#endif
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#define INCL_WINRES
27#include <win32type.h>
28#include <winres.h>
29#include <misc.h>
30#include <nameid.h>
31#include <winexe.h>
32#include "cvtresource.h"
33#include <vmutex.h>
34
35VMutex resmutex;
36
37//******************************************************************************
38//******************************************************************************
39static ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy)
40{
41 ULONG alignment;
42 ULONG factor;
43 BOOL flag = TRUE; //true: '*' false: '/'
44
45 cy = cy < 0 ? -cy : cy;
46
47 switch(cBits)
48 {
49 case 1:
50 factor = 8;
51 flag = FALSE;
52 break;
53
54 case 4:
55 factor = 2;
56 flag = FALSE;
57 break;
58
59 case 8:
60 factor = 1;
61 break;
62
63 case 16:
64 factor = 2;
65 break;
66
67 case 24:
68 factor = 3;
69 break;
70
71 case 32:
72 return cx*cy;
73
74 default:
75 return 0;
76 }
77
78 if (flag)
79 alignment = (cx = (cx*factor)) % 4;
80 else
81 alignment = (cx = ((cx+factor-1)/factor)) % 4;
82
83 if (alignment != 0)
84 cx += 4 - alignment;
85
86 return cx*cy;
87}
88
89//******************************************************************************
90//******************************************************************************
91Win32Resource::Win32Resource() :
92 os2resdata(NULL), winresdata(NULL), resType(RSRC_CUSTOMNODATA)
93{
94 resmutex.enter();
95 next = module->winres;
96 module->winres = this;
97 resmutex.leave();
98
99 module = NULL;
100 id = -1;
101 type = -1;
102 hres = 0;
103 orgos2type = -1;
104 OS2ResHandle = 0;
105}
106//******************************************************************************
107//******************************************************************************
108Win32Resource::Win32Resource(Win32Image *module, HRSRC hRes, ULONG id, ULONG type) :
109 os2resdata(NULL), winresdata(NULL), resType(RSRC_PE2LX)
110{
111 APIRET rc;
112
113 resmutex.enter();
114 next = module->winres;
115 module->winres = this;
116 resmutex.leave();
117
118 this->module = module;
119 this->id = id;
120 this->type = type;
121 this->hres = hRes;
122
123 switch(type) {
124 case NTRT_NEWBITMAP:
125 case NTRT_BITMAP:
126 orgos2type = RT_BITMAP;
127 break;
128 case NTRT_CURSOR:
129 case NTRT_GROUP_CURSOR:
130 case NTRT_GROUP_ICON:
131 case NTRT_ICON:
132 orgos2type = RT_POINTER;
133 break;
134 case NTRT_ACCELERATORS:
135 orgos2type = RT_ACCELTABLE;
136 break;
137 case NTRT_NEWMENU:
138 case NTRT_MENU:
139 orgos2type = RT_MENU;
140 break;
141 case NTRT_NEWDIALOG:
142 case NTRT_DIALOG:
143 orgos2type = RT_DIALOG;
144 break;
145 case NTRT_FONTDIR:
146 case NTRT_FONT:
147 case NTRT_MESSAGETABLE:
148 case NTRT_STRING:
149 case NTRT_RCDATA:
150 case NTRT_VERSION:
151 default:
152 orgos2type = RT_RCDATA;
153 break;
154 }
155 OS2ResHandle = 0;
156
157 rc = DosQueryResourceSize(module->hinstance, orgos2type, id, &ressize);
158 if(rc) {
159 dprintf(("Win32Resource ctor: DosQueryResourceSize %x %d %d returned %X\n", module->hinstance, type, id, rc));
160 ressize = 0;
161 }
162}
163//******************************************************************************
164//******************************************************************************
165Win32Resource::Win32Resource(Win32Image *module, ULONG id, ULONG type,
166 ULONG size, char *resdata) : hres(NULL),
167 os2resdata(NULL), winresdata(NULL), resType(RSRC_PELOADER)
168{
169 resmutex.enter();
170 next = module->winres;
171 module->winres = this;
172 resmutex.leave();
173
174 this->module = module;
175 this->id = id;
176 this->type = type;
177 orgos2type = -1;
178 this->ressize = size;
179 winresdata = (char *)malloc(size);
180 if(winresdata == NULL) {
181 DebugInt3();
182 return;
183 }
184 OS2ResHandle = 0;
185
186 if(type == NTRT_STRING) {
187 memcpy(winresdata, resdata, size-sizeof(WCHAR));
188 ((USHORT *)winresdata)[size/sizeof(WCHAR)-1] = 0;
189 }
190 else memcpy(winresdata, resdata, size);
191}
192//******************************************************************************
193//******************************************************************************
194Win32Resource::~Win32Resource()
195{
196 Win32Resource *res = module->winres;
197
198 //returned by DosGetResource, so we don't (and mustn't) free it
199 if(os2resdata && resType == RSRC_PELOADER)
200 free(os2resdata);
201
202 if(winresdata) free(winresdata);
203
204 resmutex.enter();
205 if(res == this) {
206 module->winres = res->next;
207 }
208 else {
209 while(res->next != this) {
210 res = res->next;
211 }
212 if(res)
213 res->next = next;
214 }
215 resmutex.leave();
216}
217//******************************************************************************
218//******************************************************************************
219PVOID Win32Resource::lockResource()
220{
221 int restype = 0, newid;
222 void *resdata = NULL;
223 APIRET rc;
224 ULONG os2type = RT_RCDATA;
225
226 dprintf(("Win32Resource::lockResource %d\n", id));
227 if(winresdata)
228 return(winresdata);
229
230 switch(type) {
231 case NTRT_BITMAP:
232 rc = DosGetResource((HMODULE)module->hinstance, RT_BITMAP, id, (PPVOID)&resdata);
233 if(rc) return(NULL);
234 winresdata = convertOS2Bitmap((BITMAPFILEHEADER2 *)resdata);
235 break;
236
237 case NTRT_ACCELERATORS:
238 case NTRT_MENU:
239 case NTRT_DIALOG:
240 newid = module->getWin32ResourceId(id);
241
242 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, (int)newid, (PPVOID)&resdata);
243 if(rc) {
244 dprintf(("Can't find original resource!!!\n"));
245 return(NULL);
246 }
247 winresdata = (char *)malloc(ressize);
248 memcpy(winresdata, resdata, ressize);
249 break;
250
251 //TODO:not yet implemented
252 case NTRT_FONTDIR:
253 case NTRT_FONT:
254 case NTRT_MESSAGETABLE:
255 case NTRT_NEWBITMAP:
256 case NTRT_NEWMENU:
257 case NTRT_NEWDIALOG:
258 os2type = RT_RCDATA;
259 break;
260
261 //Can't do this right now (all group icons stored into a single one)
262 case NTRT_CURSOR:
263 case NTRT_GROUP_CURSOR:
264 case NTRT_GROUP_ICON:
265 case NTRT_ICON:
266 dprintf(("Can't convert this resource!!!!!\n"));
267 os2type = RT_POINTER;
268 break;
269
270 case NTRT_STRING:
271 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, id, (PPVOID)&resdata);
272 if(rc) {
273 dprintf(("Can't find original string!!!\n"));
274 return(NULL);
275 }
276 winresdata = malloc(ressize+sizeof(WCHAR));
277 memcpy(winresdata, resdata, ressize);
278 *(USHORT *)(&((char *)winresdata)[ressize]) = 0;
279 DosFreeResource(resdata);
280 return((PVOID)((ULONG)winresdata+2)); //skip length word
281
282 //no conversion necessary
283 case NTRT_RCDATA:
284 case NTRT_VERSION:
285 default:
286 os2type = RT_RCDATA;
287 break;
288 }
289
290 if(winresdata == NULL) {
291 rc = DosGetResource((HMODULE)module->hinstance, os2type, id, (PPVOID)&resdata);
292 if(rc) {
293 dprintf(("Can't find original resource!!!\n"));
294 return(NULL);
295 }
296 winresdata = (char *)malloc(ressize);
297 memcpy(winresdata, resdata, ressize);
298 }
299 if(resdata)
300 DosFreeResource(resdata);
301
302 return winresdata;
303}
304//******************************************************************************
305//******************************************************************************
306PVOID Win32Resource::lockOS2Resource()
307{
308 APIRET rc;
309 PVOID resdata;
310
311 dprintf(("Win32Resource::lockOS2Resource %d\n", id));
312 if(os2resdata == NULL) {
313 if(resType == RSRC_PELOADER || resType == RSRC_CUSTOMINDIRECT) {
314 os2resdata = convertResource(winresdata);
315 }
316 else {
317 rc = DosGetResource((HMODULE)module->hinstance, orgos2type, id, (PPVOID)&resdata);
318 if(rc) return(NULL);
319 os2resdata = resdata;
320 }
321 }
322 return os2resdata;
323}
324//******************************************************************************
325//******************************************************************************
326PVOID Win32Resource::convertResource(void *win32res)
327{
328 ULONG cvtressize;
329
330 switch(type) {
331 case NTRT_NEWBITMAP:
332 case NTRT_BITMAP:
333 return ConvertBitmap((WINBITMAPINFOHEADER *)win32res, ressize, &ressize);
334
335 case NTRT_CURSOR:
336 return ConvertCursor((CursorComponent *)win32res, ressize);
337
338 case NTRT_GROUP_CURSOR:
339 return ConvertCursorGroup((CursorHeader *)win32res, ressize, module);
340
341 case NTRT_GROUP_ICON:
342 return ConvertIconGroup((IconHeader *)win32res, ressize, module);
343
344 case NTRT_ICON:
345 return ConvertIcon((WINBITMAPINFOHEADER *)win32res, ressize);
346
347 case NTRT_ACCELERATORS:
348 return ConvertAccelerator((WINACCEL *)win32res, ressize);
349
350 case NTRT_NEWMENU:
351 case NTRT_MENU:
352 return ConvertMenu((MenuHeader *)win32res, ressize);
353
354 case NTRT_NEWDIALOG:
355 case NTRT_DIALOG:
356 break;
357 case NTRT_FONTDIR:
358 case NTRT_FONT:
359 case NTRT_MESSAGETABLE:
360 case NTRT_RCDATA:
361 case NTRT_VERSION:
362 case NTRT_STRING:
363 break;
364
365 default:
366 break;
367 }
368 dprintf(("Win32Resource::convertResource: Can't convert resource %d (type %d)", id, type));
369 return 0;
370}
371//******************************************************************************
372//NOTE: Will be removed once pe2lx rewrite has been completed
373//******************************************************************************
374PVOID Win32Resource::convertOS2Bitmap(void *bmpdata)
375{
376 BITMAPFILEHEADER2 *bmphdr = (BITMAPFILEHEADER2 *)bmpdata;
377 WINBITMAPINFOHEADER *winbmphdr;
378 RGBQUAD *rgb;
379 RGB2 *os2rgb;
380 int palsize = 0;
381 int imgsize;
382
383 if(bmphdr->cbSize != sizeof(BITMAPFILEHEADER2)) {
384 PVOID bmpdat = malloc(ressize);
385 memcpy(bmpdat, bmpdata, ressize);
386 return(bmpdat); //don't convert OS/2 1.x bitmap
387 }
388
389 if(bmphdr->bmp2.cBitCount < 16) {
390 palsize = (1 << bmphdr->bmp2.cBitCount) * sizeof(RGBQUAD);
391 }
392
393 //SvL: Always recalculate bitmap size (donut.exe has wrong size)
394 imgsize = CalcBitmapSize(bmphdr->bmp2.cBitCount,
395 bmphdr->bmp2.cx,
396 bmphdr->bmp2.cy);
397
398 winbmphdr = (WINBITMAPINFOHEADER *)malloc(sizeof(WINBITMAPINFOHEADER) +
399 imgsize + palsize);
400 memset((char *)winbmphdr, 0, sizeof(WINBITMAPINFOHEADER) + imgsize + palsize);
401
402 winbmphdr->biSize = sizeof(WINBITMAPINFOHEADER);
403 winbmphdr->biWidth = bmphdr->bmp2.cx;
404 winbmphdr->biHeight = bmphdr->bmp2.cy;
405 winbmphdr->biPlanes = bmphdr->bmp2.cPlanes;
406 winbmphdr->biBitCount = bmphdr->bmp2.cBitCount;
407 //TODO: Identical except for BI_BITFIELDS (3L) type!
408 winbmphdr->biCompression = bmphdr->bmp2.ulCompression;
409 winbmphdr->biSizeImage = imgsize;
410 //TODO: Doesn't seem to be completely identical..
411 winbmphdr->biClrUsed = bmphdr->bmp2.cclrUsed;
412 winbmphdr->biClrImportant = bmphdr->bmp2.cclrImportant;
413 winbmphdr->biXPelsPerMeter = bmphdr->bmp2.cxResolution;
414 winbmphdr->biYPelsPerMeter = bmphdr->bmp2.cyResolution;
415
416 os2rgb = (RGB2 *)(bmphdr+1);
417 rgb = (RGBQUAD *)(winbmphdr+1);
418
419 if(palsize) {
420 memcpy((char *)rgb, (char *)os2rgb, palsize);
421 os2rgb = (RGB2 *)((int)os2rgb + palsize);
422 rgb = (RGBQUAD *)((int)rgb + palsize);
423 }
424 memcpy((char *)rgb, (char *)os2rgb, imgsize);
425 return((PVOID)winbmphdr);
426}
427//******************************************************************************
428//******************************************************************************
429void Win32Resource::destroyAll(Win32Image *module)
430{
431 Win32Resource *res = module->winres, *next;
432
433 while(res) {
434 next = res->next;
435 delete(res);
436 res = next;
437 }
438}
439//******************************************************************************
440//******************************************************************************
Note: See TracBrowser for help on using the repository browser.