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

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

Rewrite for new win32 image classes

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