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

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

Resource support for DIB type (DISABLED)

File size: 14.1 KB
Line 
1/* $Id: winres.cpp,v 1.20 1999-10-19 12:51:25 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
238 if(winresdata)
239 return(winresdata);
240
241 switch(type) {
242 case NTRT_BITMAP:
243 rc = DosGetResource((HMODULE)module->hinstance, RT_BITMAP, id, (PPVOID)&resdata);
244 if(rc) return(NULL);
245 winresdata = convertOS2Bitmap((BITMAPFILEHEADER2 *)resdata);
246 break;
247
248 case NTRT_ACCELERATORS:
249 case NTRT_MENU:
250 case NTRT_DIALOG:
251 {
252//TODO->!!!!
253// newid = ((Win32Pe2LxImage *)module)->getWin32ResourceId(id);
254//TODO->!!!!
255
256 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, (int)newid, (PPVOID)&resdata);
257 if(rc) {
258 dprintf(("Can't find original resource!!!\n"));
259 return(NULL);
260 }
261 winresdata = (char *)malloc(ressize);
262 memcpy(winresdata, resdata, ressize);
263 break;
264 }
265
266 //TODO:not yet implemented
267 case NTRT_FONTDIR:
268 case NTRT_FONT:
269 case NTRT_MESSAGETABLE:
270 case NTRT_NEWBITMAP:
271 case NTRT_NEWMENU:
272 case NTRT_NEWDIALOG:
273 os2type = RT_RCDATA;
274 break;
275
276 //Can't do this right now (all group icons stored into a single one)
277 case NTRT_CURSOR:
278 case NTRT_GROUP_CURSOR:
279 case NTRT_GROUP_ICON:
280 case NTRT_ICON:
281 dprintf(("Can't convert this resource!!!!!\n"));
282 os2type = RT_POINTER;
283 break;
284
285 case NTRT_STRING:
286 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, id, (PPVOID)&resdata);
287 if(rc) {
288 dprintf(("Can't find original string!!!\n"));
289 return(NULL);
290 }
291 winresdata = malloc(ressize+sizeof(WCHAR));
292 memcpy(winresdata, resdata, ressize);
293 *(USHORT *)(&((char *)winresdata)[ressize]) = 0;
294 DosFreeResource(resdata);
295 return((PVOID)((ULONG)winresdata+2)); //skip length word
296
297 //no conversion necessary
298 case NTRT_RCDATA:
299 case NTRT_VERSION:
300 default:
301 os2type = RT_RCDATA;
302 break;
303 }
304
305 if(winresdata == NULL) {
306 rc = DosGetResource((HMODULE)module->hinstance, os2type, id, (PPVOID)&resdata);
307 if(rc) {
308 dprintf(("Can't find original resource!!!\n"));
309 return(NULL);
310 }
311 winresdata = (char *)malloc(ressize);
312 memcpy(winresdata, resdata, ressize);
313 }
314 if(resdata)
315 DosFreeResource(resdata);
316
317 return winresdata;
318}
319//******************************************************************************
320//******************************************************************************
321PVOID Win32Resource::lockOS2Resource()
322{
323 APIRET rc;
324 PVOID resdata;
325
326 dprintf(("Win32Resource::lockOS2Resource %d\n", id));
327 if(os2resdata == NULL) {
328 if(resType == RSRC_PELOADER || resType == RSRC_CUSTOMINDIRECT) {
329 os2resdata = convertResource(winresdata);
330 }
331 else {
332 rc = DosGetResource((HMODULE)module->hinstance, orgos2type, id, (PPVOID)&resdata);
333 if(rc) return(NULL);
334 os2resdata = resdata;
335 }
336 }
337 return os2resdata;
338}
339//******************************************************************************
340//return size of converted win32 resource
341//******************************************************************************
342ULONG Win32Resource::getOS2Size()
343{
344 switch(type) {
345 case NTRT_NEWBITMAP:
346 case NTRT_BITMAP:
347 return QueryConvertedBitmapSize((WINBITMAPINFOHEADER *)winresdata, ressize);
348
349 case NTRT_CURSOR:
350 return QueryConvertedCursorSize((CursorComponent *)winresdata, ressize);
351
352 case NTRT_ICON:
353 return QueryConvertedIconSize((WINBITMAPINFOHEADER *)winresdata, ressize);
354
355 case NTRT_GROUP_ICON:
356 case NTRT_GROUP_CURSOR:
357 case NTRT_ACCELERATORS:
358 case NTRT_NEWMENU:
359 case NTRT_MENU:
360 case NTRT_NEWDIALOG:
361 case NTRT_DIALOG:
362 case NTRT_FONTDIR:
363 case NTRT_FONT:
364 case NTRT_MESSAGETABLE:
365 case NTRT_RCDATA:
366 case NTRT_VERSION:
367 case NTRT_STRING:
368 default:
369 dprintf(("Win32Resource::getOS2Size SHOULDN'T BE CALLED for this resource type (%d) (NOT IMPLEMENTED)!!", type));
370 break;
371 }
372 return 0;
373}
374//******************************************************************************
375//******************************************************************************
376PVOID Win32Resource::convertResource(void *win32res)
377{
378 int cvtressize;
379
380 switch(type) {
381 case NTRT_NEWBITMAP:
382 case NTRT_BITMAP:
383 return ConvertBitmap((WINBITMAPINFOHEADER *)win32res, ressize, &ressize);
384
385 case NTRT_CURSOR:
386 return ConvertCursor((CursorComponent *)win32res, ressize, &cvtressize);
387
388 case NTRT_GROUP_CURSOR:
389 return ConvertCursorGroup((CursorHeader *)win32res, ressize, module);
390
391 case NTRT_GROUP_ICON:
392 return ConvertIconGroup((IconHeader *)win32res, ressize, module);
393
394 case NTRT_ICON:
395 return ConvertIcon((WINBITMAPINFOHEADER *)win32res, ressize, &cvtressize);
396
397 case NTRT_ACCELERATORS:
398 return ConvertAccelerator((WINACCEL *)win32res, ressize);
399
400 case NTRT_NEWMENU:
401 case NTRT_MENU:
402 return ConvertMenu((MenuHeader *)win32res, ressize, isUnicode);
403
404 case NTRT_NEWDIALOG:
405 case NTRT_DIALOG:
406 break;
407 case NTRT_FONTDIR:
408 case NTRT_FONT:
409 case NTRT_MESSAGETABLE:
410 case NTRT_RCDATA:
411 case NTRT_VERSION:
412 case NTRT_STRING:
413 break;
414
415 default:
416 break;
417 }
418 dprintf(("Win32Resource::convertResource: Can't convert resource %d (type %d)", id, type));
419 return 0;
420}
421//******************************************************************************
422//NOTE: Will be removed once pe2lx rewrite has been completed
423//******************************************************************************
424PVOID Win32Resource::convertOS2Bitmap(void *bmpdata)
425{
426 BITMAPFILEHEADER2 *bmphdr = (BITMAPFILEHEADER2 *)bmpdata;
427 WINBITMAPINFOHEADER *winbmphdr;
428 RGBQUAD *rgb;
429 RGB2 *os2rgb;
430 int palsize = 0;
431 int imgsize;
432
433 if(bmphdr->cbSize != sizeof(BITMAPFILEHEADER2)) {
434 PVOID bmpdat = malloc(ressize);
435 memcpy(bmpdat, bmpdata, ressize);
436 return(bmpdat); //don't convert OS/2 1.x bitmap
437 }
438
439 if(bmphdr->bmp2.cBitCount < 16) {
440 palsize = (1 << bmphdr->bmp2.cBitCount) * sizeof(RGBQUAD);
441 }
442
443 //SvL: Always recalculate bitmap size (donut.exe has wrong size)
444 imgsize = CalcBitmapSize(bmphdr->bmp2.cBitCount,
445 bmphdr->bmp2.cx,
446 bmphdr->bmp2.cy);
447
448 winbmphdr = (WINBITMAPINFOHEADER *)malloc(sizeof(WINBITMAPINFOHEADER) +
449 imgsize + palsize);
450 memset((char *)winbmphdr, 0, sizeof(WINBITMAPINFOHEADER) + imgsize + palsize);
451
452 winbmphdr->biSize = sizeof(WINBITMAPINFOHEADER);
453 winbmphdr->biWidth = bmphdr->bmp2.cx;
454 winbmphdr->biHeight = bmphdr->bmp2.cy;
455 winbmphdr->biPlanes = bmphdr->bmp2.cPlanes;
456 winbmphdr->biBitCount = bmphdr->bmp2.cBitCount;
457 //TODO: Identical except for BI_BITFIELDS (3L) type!
458 winbmphdr->biCompression = bmphdr->bmp2.ulCompression;
459 winbmphdr->biSizeImage = imgsize;
460 //TODO: Doesn't seem to be completely identical..
461 winbmphdr->biClrUsed = bmphdr->bmp2.cclrUsed;
462 winbmphdr->biClrImportant = bmphdr->bmp2.cclrImportant;
463 winbmphdr->biXPelsPerMeter = bmphdr->bmp2.cxResolution;
464 winbmphdr->biYPelsPerMeter = bmphdr->bmp2.cyResolution;
465
466 os2rgb = (RGB2 *)(bmphdr+1);
467 rgb = (RGBQUAD *)(winbmphdr+1);
468
469 if(palsize) {
470 memcpy((char *)rgb, (char *)os2rgb, palsize);
471 os2rgb = (RGB2 *)((int)os2rgb + palsize);
472 rgb = (RGBQUAD *)((int)rgb + palsize);
473 }
474 memcpy((char *)rgb, (char *)os2rgb, imgsize);
475 return((PVOID)winbmphdr);
476}
477//******************************************************************************
478//******************************************************************************
479void Win32Resource::destroyAll(Win32ImageBase *module)
480{
481 Win32Resource *res = module->winres, *next;
482
483 while(res) {
484 next = res->next;
485 delete(res);
486 res = next;
487 }
488}
489//******************************************************************************
490//******************************************************************************
Note: See TracBrowser for help on using the repository browser.