Release 950522
[wine.git] / loader / resource.c
blobadbfc803d7a2e9ae6f5035fd0bf88b1d102969c6
1 /*
2 * Resources
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
6 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include "arch.h"
16 #include "windows.h"
17 #include "gdi.h"
18 #include "bitmap.h"
19 #include "neexe.h"
20 #include "icon.h"
21 #include "accel.h"
22 #include "dlls.h"
23 #include "module.h"
24 #include "resource.h"
25 #include "stddebug.h"
26 #include "debug.h"
28 #define PrintId(name) \
29 if (HIWORD((DWORD)name)) \
30 dprintf_resource( stddeb, "'%s'", (char *)PTR_SEG_TO_LIN(name)); \
31 else \
32 dprintf_resource( stddeb, "#%04x", LOWORD(name));
34 /**********************************************************************
35 * FindResource (KERNEL.60)
37 HRSRC FindResource( HMODULE hModule, SEGPTR name, SEGPTR type )
39 WORD *pModule;
41 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
42 dprintf_resource(stddeb, "FindResource: module=%04x type=", hModule );
43 PrintId( type );
44 dprintf_resource( stddeb, " name=" );
45 PrintId( name );
46 dprintf_resource( stddeb, "\n" );
47 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
48 switch(*pModule)
50 case NE_SIGNATURE:
51 return NE_FindResource( hModule, type, name );
52 case PE_SIGNATURE:
53 return 0;
54 default:
55 return 0;
60 /**********************************************************************
61 * LoadResource (KERNEL.61)
63 HGLOBAL LoadResource( HMODULE hModule, HRSRC hRsrc )
65 WORD *pModule;
67 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
68 dprintf_resource(stddeb, "LoadResource: module=%04x res=%04x\n",
69 hModule, hRsrc );
70 if (!hRsrc) return 0;
71 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
72 switch(*pModule)
74 case NE_SIGNATURE:
75 return NE_LoadResource( hModule, hRsrc );
76 case PE_SIGNATURE:
77 return 0;
78 default:
79 return 0;
84 /**********************************************************************
85 * LockResource (KERNEL.62)
87 /* 16-bit version */
88 SEGPTR WIN16_LockResource( HGLOBAL handle )
90 HMODULE hModule;
91 WORD *pModule;
93 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
94 if (!handle) return (SEGPTR)0;
95 hModule = GetExePtr( handle );
96 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
97 switch(*pModule)
99 case NE_SIGNATURE:
100 return NE_LockResource( hModule, handle );
101 case PE_SIGNATURE:
102 return 0;
103 default:
104 return 0;
108 /* 32-bit version */
109 LPSTR LockResource( HGLOBAL handle )
111 HMODULE hModule;
112 WORD *pModule;
114 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
115 if (!handle) return NULL;
116 hModule = GetExePtr( handle );
117 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
118 switch(*pModule)
120 case NE_SIGNATURE:
121 return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) );
122 case PE_SIGNATURE:
123 return 0;
124 default:
125 return 0;
130 /**********************************************************************
131 * FreeResource (KERNEL.63)
133 BOOL FreeResource( HGLOBAL handle )
135 HMODULE hModule;
136 WORD *pModule;
138 dprintf_resource(stddeb, "FreeResource: handle=%04x\n", handle );
139 if (!handle) return FALSE;
140 hModule = GetExePtr( handle );
141 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
142 switch(*pModule)
144 case NE_SIGNATURE:
145 return NE_FreeResource( hModule, handle );
146 case PE_SIGNATURE:
147 return FALSE;
148 default:
149 return FALSE;
154 /**********************************************************************
155 * AccessResource (KERNEL.64)
157 int AccessResource( HMODULE hModule, HRSRC hRsrc )
159 WORD *pModule;
161 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
162 dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
163 hModule, hRsrc );
164 if (!hRsrc) return 0;
165 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
166 switch(*pModule)
168 case NE_SIGNATURE:
169 return NE_AccessResource( hModule, hRsrc );
170 case PE_SIGNATURE:
171 return 0;
172 default:
173 return 0;
178 /**********************************************************************
179 * SizeofResource (KERNEL.65)
181 DWORD SizeofResource( HMODULE hModule, HRSRC hRsrc )
183 WORD *pModule;
185 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
186 dprintf_resource(stddeb, "SizeofResource: module=%04x res=%04x\n",
187 hModule, hRsrc );
188 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
189 switch(*pModule)
191 case NE_SIGNATURE:
192 return NE_SizeofResource( hModule, hRsrc );
193 case PE_SIGNATURE:
194 return 0;
195 default:
196 return 0;
201 /**********************************************************************
202 * AllocResource (KERNEL.66)
204 HGLOBAL AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size )
206 WORD *pModule;
208 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
209 dprintf_resource(stddeb, "AllocResource: module=%04x res=%04x size=%ld\n",
210 hModule, hRsrc, size );
211 if (!hRsrc) return 0;
212 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
213 switch(*pModule)
215 case NE_SIGNATURE:
216 return NE_AllocResource( hModule, hRsrc, size );
217 case PE_SIGNATURE:
218 return 0;
219 default:
220 return 0;
225 /**********************************************************************
226 * ConvertCoreBitmap
228 HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
230 BITMAPINFO * bmpInfo;
231 HBITMAP hbitmap;
232 char * bits;
233 int i, size, n_colors;
235 n_colors = 1 << image->bcBitCount;
236 if (image->bcBitCount < 24)
238 size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);
239 bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
241 else
243 size = sizeof(BITMAPINFOHEADER);
244 bits = (char *) (image + 1);
246 bmpInfo = (BITMAPINFO *) malloc( size );
248 bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
249 bmpInfo->bmiHeader.biWidth = image->bcWidth;
250 bmpInfo->bmiHeader.biHeight = image->bcHeight;
251 bmpInfo->bmiHeader.biPlanes = image->bcPlanes;
252 bmpInfo->bmiHeader.biBitCount = image->bcBitCount;
253 bmpInfo->bmiHeader.biCompression = 0;
254 bmpInfo->bmiHeader.biSizeImage = 0;
255 bmpInfo->bmiHeader.biXPelsPerMeter = 0;
256 bmpInfo->bmiHeader.biYPelsPerMeter = 0;
257 bmpInfo->bmiHeader.biClrUsed = 0;
258 bmpInfo->bmiHeader.biClrImportant = 0;
260 if (image->bcBitCount < 24)
262 RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
263 RGBQUAD * newMap = bmpInfo->bmiColors;
264 for (i = 0; i < n_colors; i++, oldMap++, newMap++)
266 newMap->rgbRed = oldMap->rgbtRed;
267 newMap->rgbGreen = oldMap->rgbtGreen;
268 newMap->rgbBlue = oldMap->rgbtBlue;
269 newMap->rgbReserved = 0;
273 hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
274 bits, bmpInfo, DIB_RGB_COLORS );
275 free( bmpInfo );
276 return hbitmap;
279 /**********************************************************************
280 * ConvertInfoBitmap
282 HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
284 char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
285 return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
286 bits, image, DIB_RGB_COLORS );
290 /**********************************************************************
291 * LoadIcon [USER.174]
293 HICON LoadIcon( HANDLE instance, SEGPTR icon_name )
295 HICON hIcon;
296 HRSRC hRsrc;
297 HANDLE rsc_mem;
298 WORD *lp;
299 ICONDESCRIP *lpicodesc;
300 ICONALLOC *lpico;
301 int width, height;
302 BITMAPINFO *bmi;
303 BITMAPINFOHEADER *bih;
304 RGBQUAD *rgbq;
305 HDC hdc;
306 BITMAPINFO *pInfo;
307 char *bits;
308 int size;
310 if (HIWORD(icon_name))
311 dprintf_resource( stddeb, "LoadIcon: %04x '%s'\n",
312 instance, (char *)PTR_SEG_TO_LIN( icon_name ) );
313 else
314 dprintf_resource( stddeb, "LoadIcon: %04x %04x\n",
315 instance, LOWORD(icon_name) );
317 if (!instance)
319 if (HIWORD((int)icon_name)) return 0; /* FIXME: should handle '#xxx' */
320 return OBM_LoadIcon( LOWORD((int)icon_name) );
323 if (!(hRsrc = FindResource( instance, icon_name, RT_GROUP_ICON))) return 0;
324 rsc_mem = LoadResource( instance, hRsrc );
325 if (rsc_mem == (HANDLE)NULL) {
326 printf("LoadIcon / Icon %08x not Found !\n", (int) icon_name);
327 return 0;
329 lp = (WORD *)LockResource(rsc_mem);
330 lpicodesc = (ICONDESCRIP *)(lp + 3);
331 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
332 if (hIcon == (HICON)NULL) {
333 FreeResource( rsc_mem );
334 return 0;
336 lpico = (ICONALLOC *)GlobalLock(hIcon);
337 lpico->descriptor = *lpicodesc;
338 width = lpicodesc->Width;
339 height = lpicodesc->Height;
340 FreeResource( rsc_mem );
341 if (!(hRsrc = FindResource( instance,
342 MAKEINTRESOURCE(lpico->descriptor.icoDIBOffset),
343 RT_ICON ))) return 0;
344 if (!(rsc_mem = LoadResource( instance, hRsrc ))) return 0;
346 bmi = (BITMAPINFO *)LockResource(rsc_mem);
347 size = DIB_BitmapInfoSize( bmi, DIB_RGB_COLORS );
348 pInfo = (BITMAPINFO *)malloc( size );
349 memcpy( pInfo, bmi, size );
350 bih = &pInfo->bmiHeader;
351 bih->biHeight /= 2;
353 if (!(hdc = GetDC( 0 ))) return 0;
354 if (bih->biSize != sizeof(BITMAPINFOHEADER)) return 0;
355 lpico->hBitmap = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
356 (char*)bmi + size, pInfo, DIB_RGB_COLORS );
357 if (bih->biSizeImage == 0)
359 if (bih->biCompression != BI_RGB)
361 fprintf(stderr,"Unknown size for compressed Icon bitmap.\n");
362 FreeResource( rsc_mem );
363 ReleaseDC( 0, hdc);
364 return 0;
366 bih->biSizeImage = DIB_GetImageWidthBytes(bih->biWidth,bih->biBitCount)
367 * bih->biHeight;
369 bits = (char *)bmi + size +
370 bih->biSizeImage * bih->biBitCount / (bih->biBitCount+1);
371 bih->biBitCount = 1;
372 bih->biClrUsed = bih->biClrImportant = 2;
373 rgbq = &bmi->bmiColors[0];
374 rgbq[0].rgbBlue = rgbq[0].rgbGreen = rgbq[0].rgbRed = 0x00;
375 rgbq[1].rgbBlue = rgbq[1].rgbGreen = rgbq[1].rgbRed = 0xff;
376 rgbq[0].rgbReserved = rgbq[1].rgbReserved = 0;
377 lpico->hBitMask = CreateDIBitmap(hdc, &pInfo->bmiHeader, CBM_INIT,
378 /* (LPSTR)bmi + bih->biSizeImage - sizeof(BITMAPINFOHEADER) / 2 - 4,
379 (LPSTR)lp + bih->biSizeImage + bih->biSize + 4*lpicodesc->ColorCount, */
380 bits, pInfo, DIB_RGB_COLORS );
381 FreeResource( rsc_mem );
382 ReleaseDC( 0, hdc);
383 free( pInfo );
384 GlobalUnlock(hIcon);
385 dprintf_resource(stddeb,"LoadIcon Alloc hIcon=%X\n", hIcon);
386 return hIcon;
390 /**********************************************************************
391 * CreateIcon [USER.407]
393 HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight,
394 BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits,
395 LPSTR lpXORbits)
397 HICON hIcon;
398 ICONALLOC *lpico;
400 dprintf_resource(stddeb, "CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n",
401 hInstance, nWidth, nHeight);
402 dprintf_resource(stddeb, " nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel);
403 dprintf_resource(stddeb, " lpANDbits= %04x, lpXORbits = %04x, \n", (int)lpANDbits,
404 (int)lpXORbits);
406 if (hInstance == (HANDLE)NULL) {
407 printf("CreateIcon / hInstance %04x not Found!\n",hInstance);
408 return 0;
410 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
411 if (hIcon == (HICON)NULL) {
412 printf("Can't allocate memory for Icon in CreateIcon\n");
413 return 0;
415 lpico= (ICONALLOC *)GlobalLock(hIcon);
417 lpico->descriptor.Width=nWidth;
418 lpico->descriptor.Height=nHeight;
419 lpico->descriptor.ColorCount=16; /* Dummy Value */
420 lpico->descriptor.Reserved1=0;
421 lpico->descriptor.Reserved2=nPlanes;
422 lpico->descriptor.Reserved3=nWidth*nHeight;
424 /* either nPlanes and/or nBitCount is set to one */
425 lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel;
426 lpico->descriptor.icoDIBOffset=0;
428 if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel,
429 lpXORbits)) ) {
430 printf("CreateIcon: couldn't create the XOR bitmap\n");
431 return(0);
434 /* the AND BitMask is always monochrome */
435 if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) {
436 printf("CreateIcon: couldn't create the AND bitmap\n");
437 return(0);
440 GlobalUnlock(hIcon);
441 dprintf_resource(stddeb, "CreateIcon Alloc hIcon=%X\n", hIcon);
442 return hIcon;
445 /**********************************************************************
446 * DestroyIcon [USER.457]
448 BOOL DestroyIcon(HICON hIcon)
450 ICONALLOC *lpico;
452 if (hIcon == (HICON)NULL)
453 return FALSE;
454 lpico = (ICONALLOC *)GlobalLock(hIcon);
455 if (lpico->hBitmap != (HBITMAP)NULL)
456 DeleteObject(lpico->hBitmap);
457 GlobalFree(hIcon);
458 return TRUE;
461 /**********************************************************************
462 * DumpIcon [USER.459]
464 DWORD DumpIcon(void* cursorIconInfo, WORD FAR *lpLen, LPSTR FAR *lpXorBits,
465 LPSTR FAR *lpAndMask)
467 dprintf_resource(stdnimp,"DumpIcon: Empty Stub!!!\n");
468 return 0;
472 /**********************************************************************
473 * LoadAccelerators [USER.177]
475 HANDLE LoadAccelerators(HANDLE instance, SEGPTR lpTableName)
477 HANDLE hAccel;
478 HANDLE rsc_mem;
479 HRSRC hRsrc;
480 BYTE *lp;
481 ACCELHEADER *lpAccelTbl;
482 int i, n;
484 if (HIWORD(lpTableName))
485 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
486 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
487 else
488 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
489 instance, LOWORD(lpTableName) );
491 if (!(hRsrc = FindResource( instance, lpTableName, RT_ACCELERATOR )))
492 return 0;
493 if (!(rsc_mem = LoadResource( instance, hRsrc ))) return 0;
495 lp = (BYTE *)LockResource(rsc_mem);
496 n = SizeofResource( instance, hRsrc ) / sizeof(ACCELENTRY);
497 hAccel = GlobalAlloc(GMEM_MOVEABLE,
498 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
499 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
500 lpAccelTbl->wCount = 0;
501 for (i = 0; i < n; i++) {
502 lpAccelTbl->tbl[i].type = *(lp++);
503 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
504 lp += 2;
505 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
506 lp += 2;
507 if (lpAccelTbl->tbl[i].wEvent == 0) break;
508 dprintf_accel(stddeb,
509 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
510 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
511 lpAccelTbl->tbl[i].type);
512 lpAccelTbl->wCount++;
514 GlobalUnlock(hAccel);
515 FreeResource( rsc_mem );
516 return hAccel;
519 /**********************************************************************
520 * TranslateAccelerator [USER.178]
522 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
524 ACCELHEADER *lpAccelTbl;
525 int i;
527 if (hAccel == 0 || msg == NULL) return 0;
528 if (msg->message != WM_KEYDOWN &&
529 msg->message != WM_KEYUP &&
530 msg->message != WM_CHAR) return 0;
532 dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04X !\n", hAccel);
534 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
535 for (i = 0; i < lpAccelTbl->wCount; i++) {
536 if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
537 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
538 msg->message == WM_KEYDOWN) {
539 if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
540 !(GetKeyState(VK_SHIFT) & 0xf)) {
541 GlobalUnlock(hAccel);
542 return 0;
544 if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
545 !(GetKeyState(VK_CONTROL) & 0xf)) {
546 GlobalUnlock(hAccel);
547 return 0;
549 if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
550 !(GetKeyState(VK_MENU) & 0xf)) {
551 GlobalUnlock(hAccel);
552 return 0;
554 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
555 GlobalUnlock(hAccel);
556 return 1;
558 if (msg->message == WM_KEYUP) return 1;
560 else {
561 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
562 msg->message == WM_CHAR) {
563 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
564 GlobalUnlock(hAccel);
565 return 1;
569 GlobalUnlock(hAccel);
570 return 0;
573 /**********************************************************************
574 * LoadString
577 LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
579 HANDLE hmem, hrsrc;
580 unsigned char *p;
581 int string_num;
582 int i;
584 dprintf_resource(stddeb, "LoadString: instance = %04x, id = %d, buffer = %08x, "
585 "length = %d\n", instance, resource_id, (int) buffer, buflen);
587 hrsrc = FindResource( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING );
588 if (!hrsrc) return 0;
589 hmem = LoadResource( instance, hrsrc );
590 if (!hmem) return 0;
592 p = LockResource(hmem);
593 string_num = resource_id & 0x000f;
594 for (i = 0; i < string_num; i++)
595 p += *p + 1;
597 i = min(buflen - 1, *p);
598 if (i > 0) {
599 memcpy(buffer, p + 1, i);
600 buffer[i] = '\0';
602 else {
603 if (buflen > 1) {
604 buffer[0] = '\0';
605 return 0;
607 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
608 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
610 FreeResource( hmem );
612 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
613 return i;