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

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

icongroup & cursorgroup fixes

File size: 13.7 KB
Line 
1/* $Id: winres.cpp,v 1.15 1999-09-04 12:41: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 //resources are in Unicode format by default; indirectly created resources
106 //can also be in ascii format
107 isUnicode = TRUE;
108}
109//******************************************************************************
110//******************************************************************************
111Win32Resource::Win32Resource(Win32Image *module, HRSRC hRes, ULONG id, ULONG type) :
112 os2resdata(NULL), winresdata(NULL), resType(RSRC_PE2LX)
113{
114 APIRET rc;
115
116 resmutex.enter();
117 next = module->winres;
118 module->winres = this;
119 resmutex.leave();
120
121 this->module = module;
122 this->id = id;
123 this->type = type;
124 this->hres = hRes;
125
126 switch(type) {
127 case NTRT_NEWBITMAP:
128 case NTRT_BITMAP:
129 orgos2type = RT_BITMAP;
130 break;
131 case NTRT_CURSOR:
132 case NTRT_GROUP_CURSOR:
133 case NTRT_GROUP_ICON:
134 case NTRT_ICON:
135 orgos2type = RT_POINTER;
136 break;
137 case NTRT_ACCELERATORS:
138 orgos2type = RT_ACCELTABLE;
139 break;
140 case NTRT_NEWMENU:
141 case NTRT_MENU:
142 orgos2type = RT_MENU;
143 break;
144 case NTRT_NEWDIALOG:
145 case NTRT_DIALOG:
146 orgos2type = RT_DIALOG;
147 break;
148 case NTRT_FONTDIR:
149 case NTRT_FONT:
150 case NTRT_MESSAGETABLE:
151 case NTRT_STRING:
152 case NTRT_RCDATA:
153 case NTRT_VERSION:
154 default:
155 orgos2type = RT_RCDATA;
156 break;
157 }
158 OS2ResHandle = 0;
159
160 rc = DosQueryResourceSize(module->hinstance, orgos2type, id, &ressize);
161 if(rc) {
162 dprintf(("Win32Resource ctor: DosQueryResourceSize %x %d %d returned %X\n", module->hinstance, type, id, rc));
163 ressize = 0;
164 }
165 //resources are in Unicode format by default
166 isUnicode = TRUE;
167}
168//******************************************************************************
169//******************************************************************************
170Win32Resource::Win32Resource(Win32Image *module, ULONG id, ULONG type,
171 ULONG size, char *resdata) : hres(NULL),
172 os2resdata(NULL), winresdata(NULL), resType(RSRC_PELOADER)
173{
174 resmutex.enter();
175 next = module->winres;
176 module->winres = this;
177 resmutex.leave();
178
179 this->module = module;
180 this->id = id;
181 this->type = type;
182 orgos2type = -1;
183 this->ressize = size;
184 winresdata = (char *)malloc(size);
185 if(winresdata == NULL) {
186 DebugInt3();
187 return;
188 }
189 OS2ResHandle = 0;
190
191 if(type == NTRT_STRING) {
192 memcpy(winresdata, resdata, size-sizeof(WCHAR));
193 ((USHORT *)winresdata)[size/sizeof(WCHAR)-1] = 0;
194 }
195 else memcpy(winresdata, resdata, size);
196
197 //resources are in Unicode format by default
198 isUnicode = TRUE;
199}
200//******************************************************************************
201//******************************************************************************
202Win32Resource::~Win32Resource()
203{
204 Win32Resource *res = module->winres;
205
206 //returned by DosGetResource, so we don't (and mustn't) free it
207 if(os2resdata && (resType == RSRC_PELOADER || resType == RSRC_CUSTOMINDIRECT))
208 free(os2resdata);
209
210 if(winresdata) free(winresdata);
211
212 resmutex.enter();
213 if(res == this) {
214 module->winres = res->next;
215 }
216 else {
217 while(res->next != this) {
218 res = res->next;
219 }
220 if(res)
221 res->next = next;
222 }
223 resmutex.leave();
224}
225//******************************************************************************
226//******************************************************************************
227PVOID Win32Resource::lockResource()
228{
229 int restype = 0, newid;
230 void *resdata = NULL;
231 APIRET rc;
232 ULONG os2type = RT_RCDATA;
233
234 dprintf(("Win32Resource::lockResource %d\n", id));
235 if(winresdata)
236 return(winresdata);
237
238 switch(type) {
239 case NTRT_BITMAP:
240 rc = DosGetResource((HMODULE)module->hinstance, RT_BITMAP, id, (PPVOID)&resdata);
241 if(rc) return(NULL);
242 winresdata = convertOS2Bitmap((BITMAPFILEHEADER2 *)resdata);
243 break;
244
245 case NTRT_ACCELERATORS:
246 case NTRT_MENU:
247 case NTRT_DIALOG:
248 newid = module->getWin32ResourceId(id);
249
250 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, (int)newid, (PPVOID)&resdata);
251 if(rc) {
252 dprintf(("Can't find original resource!!!\n"));
253 return(NULL);
254 }
255 winresdata = (char *)malloc(ressize);
256 memcpy(winresdata, resdata, ressize);
257 break;
258
259 //TODO:not yet implemented
260 case NTRT_FONTDIR:
261 case NTRT_FONT:
262 case NTRT_MESSAGETABLE:
263 case NTRT_NEWBITMAP:
264 case NTRT_NEWMENU:
265 case NTRT_NEWDIALOG:
266 os2type = RT_RCDATA;
267 break;
268
269 //Can't do this right now (all group icons stored into a single one)
270 case NTRT_CURSOR:
271 case NTRT_GROUP_CURSOR:
272 case NTRT_GROUP_ICON:
273 case NTRT_ICON:
274 dprintf(("Can't convert this resource!!!!!\n"));
275 os2type = RT_POINTER;
276 break;
277
278 case NTRT_STRING:
279 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, id, (PPVOID)&resdata);
280 if(rc) {
281 dprintf(("Can't find original string!!!\n"));
282 return(NULL);
283 }
284 winresdata = malloc(ressize+sizeof(WCHAR));
285 memcpy(winresdata, resdata, ressize);
286 *(USHORT *)(&((char *)winresdata)[ressize]) = 0;
287 DosFreeResource(resdata);
288 return((PVOID)((ULONG)winresdata+2)); //skip length word
289
290 //no conversion necessary
291 case NTRT_RCDATA:
292 case NTRT_VERSION:
293 default:
294 os2type = RT_RCDATA;
295 break;
296 }
297
298 if(winresdata == NULL) {
299 rc = DosGetResource((HMODULE)module->hinstance, os2type, id, (PPVOID)&resdata);
300 if(rc) {
301 dprintf(("Can't find original resource!!!\n"));
302 return(NULL);
303 }
304 winresdata = (char *)malloc(ressize);
305 memcpy(winresdata, resdata, ressize);
306 }
307 if(resdata)
308 DosFreeResource(resdata);
309
310 return winresdata;
311}
312//******************************************************************************
313//******************************************************************************
314PVOID Win32Resource::lockOS2Resource()
315{
316 APIRET rc;
317 PVOID resdata;
318
319 dprintf(("Win32Resource::lockOS2Resource %d\n", id));
320 if(os2resdata == NULL) {
321 if(resType == RSRC_PELOADER || resType == RSRC_CUSTOMINDIRECT) {
322 os2resdata = convertResource(winresdata);
323 }
324 else {
325 rc = DosGetResource((HMODULE)module->hinstance, orgos2type, id, (PPVOID)&resdata);
326 if(rc) return(NULL);
327 os2resdata = resdata;
328 }
329 }
330 return os2resdata;
331}
332//******************************************************************************
333//return size of converted win32 resource
334//******************************************************************************
335ULONG Win32Resource::getOS2Size()
336{
337 switch(type) {
338 case NTRT_NEWBITMAP:
339 case NTRT_BITMAP:
340 return QueryConvertedBitmapSize((WINBITMAPINFOHEADER *)winresdata, ressize);
341
342 case NTRT_CURSOR:
343 return QueryConvertedCursorSize((CursorComponent *)winresdata, ressize);
344
345 case NTRT_ICON:
346 return QueryConvertedIconSize((WINBITMAPINFOHEADER *)winresdata, ressize);
347
348 case NTRT_GROUP_ICON:
349 case NTRT_GROUP_CURSOR:
350 case NTRT_ACCELERATORS:
351 case NTRT_NEWMENU:
352 case NTRT_MENU:
353 case NTRT_NEWDIALOG:
354 case NTRT_DIALOG:
355 case NTRT_FONTDIR:
356 case NTRT_FONT:
357 case NTRT_MESSAGETABLE:
358 case NTRT_RCDATA:
359 case NTRT_VERSION:
360 case NTRT_STRING:
361 default:
362 dprintf(("Win32Resource::getOS2Size SHOULDN'T BE CALLED for this resource type (%d) (NOT IMPLEMENTED)!!", type));
363 break;
364 }
365 return 0;
366}
367//******************************************************************************
368//******************************************************************************
369PVOID Win32Resource::convertResource(void *win32res)
370{
371 int cvtressize;
372
373 switch(type) {
374 case NTRT_NEWBITMAP:
375 case NTRT_BITMAP:
376 return ConvertBitmap((WINBITMAPINFOHEADER *)win32res, ressize, &ressize);
377
378 case NTRT_CURSOR:
379 return ConvertCursor((CursorComponent *)win32res, ressize, &cvtressize);
380
381 case NTRT_GROUP_CURSOR:
382 return ConvertCursorGroup((CursorHeader *)win32res, ressize, module);
383
384 case NTRT_GROUP_ICON:
385 return ConvertIconGroup((IconHeader *)win32res, ressize, module);
386
387 case NTRT_ICON:
388 return ConvertIcon((WINBITMAPINFOHEADER *)win32res, ressize, &cvtressize);
389
390 case NTRT_ACCELERATORS:
391 return ConvertAccelerator((WINACCEL *)win32res, ressize);
392
393 case NTRT_NEWMENU:
394 case NTRT_MENU:
395 return ConvertMenu((MenuHeader *)win32res, ressize, isUnicode);
396
397 case NTRT_NEWDIALOG:
398 case NTRT_DIALOG:
399 break;
400 case NTRT_FONTDIR:
401 case NTRT_FONT:
402 case NTRT_MESSAGETABLE:
403 case NTRT_RCDATA:
404 case NTRT_VERSION:
405 case NTRT_STRING:
406 break;
407
408 default:
409 break;
410 }
411 dprintf(("Win32Resource::convertResource: Can't convert resource %d (type %d)", id, type));
412 return 0;
413}
414//******************************************************************************
415//NOTE: Will be removed once pe2lx rewrite has been completed
416//******************************************************************************
417PVOID Win32Resource::convertOS2Bitmap(void *bmpdata)
418{
419 BITMAPFILEHEADER2 *bmphdr = (BITMAPFILEHEADER2 *)bmpdata;
420 WINBITMAPINFOHEADER *winbmphdr;
421 RGBQUAD *rgb;
422 RGB2 *os2rgb;
423 int palsize = 0;
424 int imgsize;
425
426 if(bmphdr->cbSize != sizeof(BITMAPFILEHEADER2)) {
427 PVOID bmpdat = malloc(ressize);
428 memcpy(bmpdat, bmpdata, ressize);
429 return(bmpdat); //don't convert OS/2 1.x bitmap
430 }
431
432 if(bmphdr->bmp2.cBitCount < 16) {
433 palsize = (1 << bmphdr->bmp2.cBitCount) * sizeof(RGBQUAD);
434 }
435
436 //SvL: Always recalculate bitmap size (donut.exe has wrong size)
437 imgsize = CalcBitmapSize(bmphdr->bmp2.cBitCount,
438 bmphdr->bmp2.cx,
439 bmphdr->bmp2.cy);
440
441 winbmphdr = (WINBITMAPINFOHEADER *)malloc(sizeof(WINBITMAPINFOHEADER) +
442 imgsize + palsize);
443 memset((char *)winbmphdr, 0, sizeof(WINBITMAPINFOHEADER) + imgsize + palsize);
444
445 winbmphdr->biSize = sizeof(WINBITMAPINFOHEADER);
446 winbmphdr->biWidth = bmphdr->bmp2.cx;
447 winbmphdr->biHeight = bmphdr->bmp2.cy;
448 winbmphdr->biPlanes = bmphdr->bmp2.cPlanes;
449 winbmphdr->biBitCount = bmphdr->bmp2.cBitCount;
450 //TODO: Identical except for BI_BITFIELDS (3L) type!
451 winbmphdr->biCompression = bmphdr->bmp2.ulCompression;
452 winbmphdr->biSizeImage = imgsize;
453 //TODO: Doesn't seem to be completely identical..
454 winbmphdr->biClrUsed = bmphdr->bmp2.cclrUsed;
455 winbmphdr->biClrImportant = bmphdr->bmp2.cclrImportant;
456 winbmphdr->biXPelsPerMeter = bmphdr->bmp2.cxResolution;
457 winbmphdr->biYPelsPerMeter = bmphdr->bmp2.cyResolution;
458
459 os2rgb = (RGB2 *)(bmphdr+1);
460 rgb = (RGBQUAD *)(winbmphdr+1);
461
462 if(palsize) {
463 memcpy((char *)rgb, (char *)os2rgb, palsize);
464 os2rgb = (RGB2 *)((int)os2rgb + palsize);
465 rgb = (RGBQUAD *)((int)rgb + palsize);
466 }
467 memcpy((char *)rgb, (char *)os2rgb, imgsize);
468 return((PVOID)winbmphdr);
469}
470//******************************************************************************
471//******************************************************************************
472void Win32Resource::destroyAll(Win32Image *module)
473{
474 Win32Resource *res = module->winres, *next;
475
476 while(res) {
477 next = res->next;
478 delete(res);
479 res = next;
480 }
481}
482//******************************************************************************
483//******************************************************************************
Note: See TracBrowser for help on using the repository browser.