source: trunk/src/kernel32/old/winres.cpp@ 1036

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

Backup copy of old kernel32

File size: 12.7 KB
Line 
1/* $Id: winres.cpp,v 1.1 1999-09-15 23:33: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 <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//******************************************************************************
334PVOID Win32Resource::convertResource(void *win32res)
335{
336 int cvtressize;
337
338 switch(type) {
339 case NTRT_NEWBITMAP:
340 case NTRT_BITMAP:
341 return ConvertBitmap((WINBITMAPINFOHEADER *)win32res, ressize, &ressize);
342
343 case NTRT_CURSOR:
344 return ConvertCursor((CursorComponent *)win32res, ressize, &cvtressize);
345
346 case NTRT_GROUP_CURSOR:
347 return ConvertCursorGroup((CursorHeader *)win32res, ressize, module);
348
349 case NTRT_GROUP_ICON:
350 return ConvertIconGroup((IconHeader *)win32res, ressize, module);
351
352 case NTRT_ICON:
353 return ConvertIcon((WINBITMAPINFOHEADER *)win32res, ressize, &cvtressize);
354
355 case NTRT_ACCELERATORS:
356 return ConvertAccelerator((WINACCEL *)win32res, ressize);
357
358 case NTRT_NEWMENU:
359 case NTRT_MENU:
360 return ConvertMenu((MenuHeader *)win32res, ressize, isUnicode);
361
362 case NTRT_NEWDIALOG:
363 case NTRT_DIALOG:
364 break;
365 case NTRT_FONTDIR:
366 case NTRT_FONT:
367 case NTRT_MESSAGETABLE:
368 case NTRT_RCDATA:
369 case NTRT_VERSION:
370 case NTRT_STRING:
371 break;
372
373 default:
374 break;
375 }
376 dprintf(("Win32Resource::convertResource: Can't convert resource %d (type %d)", id, type));
377 return 0;
378}
379//******************************************************************************
380//NOTE: Will be removed once pe2lx rewrite has been completed
381//******************************************************************************
382PVOID Win32Resource::convertOS2Bitmap(void *bmpdata)
383{
384 BITMAPFILEHEADER2 *bmphdr = (BITMAPFILEHEADER2 *)bmpdata;
385 WINBITMAPINFOHEADER *winbmphdr;
386 RGBQUAD *rgb;
387 RGB2 *os2rgb;
388 int palsize = 0;
389 int imgsize;
390
391 if(bmphdr->cbSize != sizeof(BITMAPFILEHEADER2)) {
392 PVOID bmpdat = malloc(ressize);
393 memcpy(bmpdat, bmpdata, ressize);
394 return(bmpdat); //don't convert OS/2 1.x bitmap
395 }
396
397 if(bmphdr->bmp2.cBitCount < 16) {
398 palsize = (1 << bmphdr->bmp2.cBitCount) * sizeof(RGBQUAD);
399 }
400
401 //SvL: Always recalculate bitmap size (donut.exe has wrong size)
402 imgsize = CalcBitmapSize(bmphdr->bmp2.cBitCount,
403 bmphdr->bmp2.cx,
404 bmphdr->bmp2.cy);
405
406 winbmphdr = (WINBITMAPINFOHEADER *)malloc(sizeof(WINBITMAPINFOHEADER) +
407 imgsize + palsize);
408 memset((char *)winbmphdr, 0, sizeof(WINBITMAPINFOHEADER) + imgsize + palsize);
409
410 winbmphdr->biSize = sizeof(WINBITMAPINFOHEADER);
411 winbmphdr->biWidth = bmphdr->bmp2.cx;
412 winbmphdr->biHeight = bmphdr->bmp2.cy;
413 winbmphdr->biPlanes = bmphdr->bmp2.cPlanes;
414 winbmphdr->biBitCount = bmphdr->bmp2.cBitCount;
415 //TODO: Identical except for BI_BITFIELDS (3L) type!
416 winbmphdr->biCompression = bmphdr->bmp2.ulCompression;
417 winbmphdr->biSizeImage = imgsize;
418 //TODO: Doesn't seem to be completely identical..
419 winbmphdr->biClrUsed = bmphdr->bmp2.cclrUsed;
420 winbmphdr->biClrImportant = bmphdr->bmp2.cclrImportant;
421 winbmphdr->biXPelsPerMeter = bmphdr->bmp2.cxResolution;
422 winbmphdr->biYPelsPerMeter = bmphdr->bmp2.cyResolution;
423
424 os2rgb = (RGB2 *)(bmphdr+1);
425 rgb = (RGBQUAD *)(winbmphdr+1);
426
427 if(palsize) {
428 memcpy((char *)rgb, (char *)os2rgb, palsize);
429 os2rgb = (RGB2 *)((int)os2rgb + palsize);
430 rgb = (RGBQUAD *)((int)rgb + palsize);
431 }
432 memcpy((char *)rgb, (char *)os2rgb, imgsize);
433 return((PVOID)winbmphdr);
434}
435//******************************************************************************
436//******************************************************************************
437void Win32Resource::destroyAll(Win32Image *module)
438{
439 Win32Resource *res = module->winres, *next;
440
441 while(res) {
442 next = res->next;
443 delete(res);
444 res = next;
445 }
446}
447//******************************************************************************
448//******************************************************************************
Note: See TracBrowser for help on using the repository browser.