Release 950620
[wine/multimedia.git] / loader / resource.c
blob2a008ab4d321817cd38ab1ea78b59538beb68dfe
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 "global.h"
20 #include "neexe.h"
21 #include "icon.h"
22 #include "accel.h"
23 #include "dlls.h"
24 #include "module.h"
25 #include "resource.h"
26 #include "stddebug.h"
27 #include "debug.h"
29 #define PrintId(name) \
30 if (HIWORD((DWORD)name)) \
31 dprintf_resource( stddeb, "'%s'", (char *)PTR_SEG_TO_LIN(name)); \
32 else \
33 dprintf_resource( stddeb, "#%04x", LOWORD(name));
35 /**********************************************************************
36 * FindResource (KERNEL.60)
38 HRSRC FindResource( HMODULE hModule, SEGPTR name, SEGPTR type )
40 WORD *pModule;
42 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
43 dprintf_resource(stddeb, "FindResource: module=%04x type=", hModule );
44 PrintId( type );
45 dprintf_resource( stddeb, " name=" );
46 PrintId( name );
47 dprintf_resource( stddeb, "\n" );
48 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
49 switch(*pModule)
51 case NE_SIGNATURE:
52 return NE_FindResource( hModule, type, name );
53 case PE_SIGNATURE:
54 return 0;
55 default:
56 return 0;
61 /**********************************************************************
62 * LoadResource (KERNEL.61)
64 HGLOBAL LoadResource( HMODULE hModule, HRSRC hRsrc )
66 WORD *pModule;
68 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
69 dprintf_resource(stddeb, "LoadResource: module=%04x res=%04x\n",
70 hModule, hRsrc );
71 if (!hRsrc) return 0;
72 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
73 switch(*pModule)
75 case NE_SIGNATURE:
76 return NE_LoadResource( hModule, hRsrc );
77 case PE_SIGNATURE:
78 return 0;
79 default:
80 return 0;
85 /**********************************************************************
86 * LockResource (KERNEL.62)
88 /* 16-bit version */
89 SEGPTR WIN16_LockResource( HGLOBAL handle )
91 HMODULE hModule;
92 WORD *pModule;
94 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
95 if (!handle) return (SEGPTR)0;
96 hModule = GetExePtr( handle );
97 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
98 switch(*pModule)
100 case NE_SIGNATURE:
101 return NE_LockResource( hModule, handle );
102 case PE_SIGNATURE:
103 return 0;
104 default:
105 return 0;
109 /* 32-bit version */
110 LPSTR LockResource( HGLOBAL handle )
112 HMODULE hModule;
113 WORD *pModule;
115 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
116 if (!handle) return NULL;
117 hModule = GetExePtr( handle );
118 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
119 switch(*pModule)
121 case NE_SIGNATURE:
122 return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) );
123 case PE_SIGNATURE:
124 return 0;
125 default:
126 return 0;
131 /**********************************************************************
132 * FreeResource (KERNEL.63)
134 BOOL FreeResource( HGLOBAL handle )
136 HMODULE hModule;
137 WORD *pModule;
139 dprintf_resource(stddeb, "FreeResource: handle=%04x\n", handle );
140 if (!handle) return FALSE;
141 hModule = GetExePtr( handle );
142 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
143 switch(*pModule)
145 case NE_SIGNATURE:
146 return NE_FreeResource( hModule, handle );
147 case PE_SIGNATURE:
148 return FALSE;
149 default:
150 return FALSE;
155 /**********************************************************************
156 * AccessResource (KERNEL.64)
158 int AccessResource( HMODULE hModule, HRSRC hRsrc )
160 WORD *pModule;
162 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
163 dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
164 hModule, hRsrc );
165 if (!hRsrc) return 0;
166 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
167 switch(*pModule)
169 case NE_SIGNATURE:
170 return NE_AccessResource( hModule, hRsrc );
171 case PE_SIGNATURE:
172 return 0;
173 default:
174 return 0;
179 /**********************************************************************
180 * SizeofResource (KERNEL.65)
182 DWORD SizeofResource( HMODULE hModule, HRSRC hRsrc )
184 WORD *pModule;
186 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
187 dprintf_resource(stddeb, "SizeofResource: module=%04x res=%04x\n",
188 hModule, hRsrc );
189 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
190 switch(*pModule)
192 case NE_SIGNATURE:
193 return NE_SizeofResource( hModule, hRsrc );
194 case PE_SIGNATURE:
195 return 0;
196 default:
197 return 0;
202 /**********************************************************************
203 * AllocResource (KERNEL.66)
205 HGLOBAL AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size )
207 WORD *pModule;
209 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
210 dprintf_resource(stddeb, "AllocResource: module=%04x res=%04x size=%ld\n",
211 hModule, hRsrc, size );
212 if (!hRsrc) return 0;
213 if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
214 switch(*pModule)
216 case NE_SIGNATURE:
217 return NE_AllocResource( hModule, hRsrc, size );
218 case PE_SIGNATURE:
219 return 0;
220 default:
221 return 0;
225 /**********************************************************************
226 * DirectResAlloc (KERNEL.168)
227 * Check Schulman, p. 232 for details
229 HANDLE DirectResAlloc(HANDLE hInstance, WORD wType, WORD wSize)
231 HANDLE hModule;
232 dprintf_resource(stddeb,"DirectResAlloc(%x,%x,%x)\n",hInstance,wType,wSize);
233 hModule = GetExePtr(hInstance);
234 if(!hModule)return 0;
235 if(wType != 0x10) /* 0x10 is the only observed value, passed from
236 CreateCursorIndirect. */
237 fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
238 /* This hopefully does per-module allocation rather than per-instance */
239 return GLOBAL_Alloc(GMEM_FIXED, wSize, hModule, FALSE, FALSE, FALSE);
243 /**********************************************************************
244 * ConvertCoreBitmap
246 HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
248 BITMAPINFO * bmpInfo;
249 HBITMAP hbitmap;
250 char * bits;
251 int i, size, n_colors;
253 n_colors = 1 << image->bcBitCount;
254 if (image->bcBitCount < 24)
256 size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);
257 bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
259 else
261 size = sizeof(BITMAPINFOHEADER);
262 bits = (char *) (image + 1);
264 bmpInfo = (BITMAPINFO *) malloc( size );
266 bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
267 bmpInfo->bmiHeader.biWidth = image->bcWidth;
268 bmpInfo->bmiHeader.biHeight = image->bcHeight;
269 bmpInfo->bmiHeader.biPlanes = image->bcPlanes;
270 bmpInfo->bmiHeader.biBitCount = image->bcBitCount;
271 bmpInfo->bmiHeader.biCompression = 0;
272 bmpInfo->bmiHeader.biSizeImage = 0;
273 bmpInfo->bmiHeader.biXPelsPerMeter = 0;
274 bmpInfo->bmiHeader.biYPelsPerMeter = 0;
275 bmpInfo->bmiHeader.biClrUsed = 0;
276 bmpInfo->bmiHeader.biClrImportant = 0;
278 if (image->bcBitCount < 24)
280 RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
281 RGBQUAD * newMap = bmpInfo->bmiColors;
282 for (i = 0; i < n_colors; i++, oldMap++, newMap++)
284 newMap->rgbRed = oldMap->rgbtRed;
285 newMap->rgbGreen = oldMap->rgbtGreen;
286 newMap->rgbBlue = oldMap->rgbtBlue;
287 newMap->rgbReserved = 0;
291 hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
292 bits, bmpInfo, DIB_RGB_COLORS );
293 free( bmpInfo );
294 return hbitmap;
297 /**********************************************************************
298 * ConvertInfoBitmap
300 HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
302 char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
303 return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
304 bits, image, DIB_RGB_COLORS );
308 /**********************************************************************
309 * LoadIcon [USER.174]
311 HICON LoadIcon( HANDLE instance, SEGPTR icon_name )
313 HICON hIcon;
314 HRSRC hRsrc;
315 HANDLE rsc_mem;
316 WORD *lp;
317 ICONDESCRIP *lpicodesc;
318 ICONALLOC *lpico;
319 int width, height;
320 BITMAPINFO *bmi;
321 BITMAPINFOHEADER *bih;
322 RGBQUAD *rgbq;
323 HDC hdc;
324 BITMAPINFO *pInfo;
325 char *bits;
326 int size;
328 if (HIWORD(icon_name))
329 dprintf_resource( stddeb, "LoadIcon: %04x '%s'\n",
330 instance, (char *)PTR_SEG_TO_LIN( icon_name ) );
331 else
332 dprintf_resource( stddeb, "LoadIcon: %04x %04x\n",
333 instance, LOWORD(icon_name) );
335 if (!instance)
337 if (HIWORD((int)icon_name)) return 0; /* FIXME: should handle '#xxx' */
338 return OBM_LoadIcon( LOWORD((int)icon_name) );
341 if (!(hRsrc = FindResource( instance, icon_name, RT_GROUP_ICON))) return 0;
342 rsc_mem = LoadResource( instance, hRsrc );
343 if (rsc_mem == (HANDLE)NULL) {
344 printf("LoadIcon / Icon %08x not Found !\n", (int) icon_name);
345 return 0;
347 lp = (WORD *)LockResource(rsc_mem);
348 lpicodesc = (ICONDESCRIP *)(lp + 3);
349 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
350 if (hIcon == (HICON)NULL) {
351 FreeResource( rsc_mem );
352 return 0;
354 lpico = (ICONALLOC *)GlobalLock(hIcon);
355 lpico->descriptor = *lpicodesc;
356 width = lpicodesc->Width;
357 height = lpicodesc->Height;
358 FreeResource( rsc_mem );
359 if (!(hRsrc = FindResource( instance,
360 MAKEINTRESOURCE(lpico->descriptor.icoDIBOffset),
361 RT_ICON ))) return 0;
362 if (!(rsc_mem = LoadResource( instance, hRsrc ))) return 0;
364 bmi = (BITMAPINFO *)LockResource(rsc_mem);
365 size = DIB_BitmapInfoSize( bmi, DIB_RGB_COLORS );
366 pInfo = (BITMAPINFO *)malloc( size );
367 memcpy( pInfo, bmi, size );
368 bih = &pInfo->bmiHeader;
369 bih->biHeight /= 2;
371 if (!(hdc = GetDC( 0 ))) return 0;
372 if (bih->biSize != sizeof(BITMAPINFOHEADER)) return 0;
373 lpico->hBitmap = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
374 (char*)bmi + size, pInfo, DIB_RGB_COLORS );
376 if (bih->biSizeImage == 0)
378 if (bih->biCompression != BI_RGB)
380 fprintf(stderr,"Unknown size for compressed Icon bitmap.\n");
381 FreeResource( rsc_mem );
382 ReleaseDC( 0, hdc);
383 return 0;
385 bih->biSizeImage = (DIB_GetImageWidthBytes(bih->biWidth,bih->biBitCount) +
386 DIB_GetImageWidthBytes(bih->biWidth,1)) * bih->biHeight/2;
388 bits = (char *)bmi + size +
389 bih->biSizeImage * bih->biBitCount / (bih->biBitCount+1);
390 bih->biBitCount = 1;
391 bih->biClrUsed = bih->biClrImportant = 2;
392 rgbq = &pInfo->bmiColors[0];
393 rgbq[0].rgbBlue = rgbq[0].rgbGreen = rgbq[0].rgbRed = 0x00;
394 rgbq[1].rgbBlue = rgbq[1].rgbGreen = rgbq[1].rgbRed = 0xff;
395 rgbq[0].rgbReserved = rgbq[1].rgbReserved = 0;
396 lpico->hBitMask = CreateDIBitmap(hdc, &pInfo->bmiHeader, CBM_INIT,
397 bits, pInfo, DIB_RGB_COLORS );
398 FreeResource( rsc_mem );
399 ReleaseDC( 0, hdc);
400 free( pInfo );
401 GlobalUnlock(hIcon);
402 dprintf_resource(stddeb,"LoadIcon Alloc hIcon=%X\n", hIcon);
403 return hIcon;
407 /**********************************************************************
408 * CreateIcon [USER.407]
410 HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight,
411 BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits,
412 LPSTR lpXORbits)
414 HICON hIcon;
415 ICONALLOC *lpico;
417 dprintf_resource(stddeb, "CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n",
418 hInstance, nWidth, nHeight);
419 dprintf_resource(stddeb, " nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel);
420 dprintf_resource(stddeb, " lpANDbits= %04x, lpXORbits = %04x, \n", (int)lpANDbits,
421 (int)lpXORbits);
423 if (hInstance == (HANDLE)NULL) {
424 printf("CreateIcon / hInstance %04x not Found!\n",hInstance);
425 return 0;
427 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
428 if (hIcon == (HICON)NULL) {
429 printf("Can't allocate memory for Icon in CreateIcon\n");
430 return 0;
432 lpico= (ICONALLOC *)GlobalLock(hIcon);
434 lpico->descriptor.Width=nWidth;
435 lpico->descriptor.Height=nHeight;
436 lpico->descriptor.ColorCount=16; /* Dummy Value */
437 lpico->descriptor.Reserved1=0;
438 lpico->descriptor.Reserved2=nPlanes;
439 lpico->descriptor.Reserved3=nWidth*nHeight;
441 /* either nPlanes and/or nBitCount is set to one */
442 lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel;
443 lpico->descriptor.icoDIBOffset=0;
445 if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel,
446 lpXORbits)) ) {
447 printf("CreateIcon: couldn't create the XOR bitmap\n");
448 return(0);
451 /* the AND BitMask is always monochrome */
452 if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) {
453 printf("CreateIcon: couldn't create the AND bitmap\n");
454 return(0);
457 GlobalUnlock(hIcon);
458 dprintf_resource(stddeb, "CreateIcon Alloc hIcon=%X\n", hIcon);
459 return hIcon;
462 /**********************************************************************
463 * DestroyIcon [USER.457]
465 BOOL DestroyIcon(HICON hIcon)
467 ICONALLOC *lpico;
469 if (hIcon == (HICON)NULL)
470 return FALSE;
471 lpico = (ICONALLOC *)GlobalLock(hIcon);
472 if (lpico->hBitmap != (HBITMAP)NULL)
473 DeleteObject(lpico->hBitmap);
474 GlobalFree(hIcon);
475 return TRUE;
478 /**********************************************************************
479 * DumpIcon [USER.459]
481 DWORD DumpIcon(void* cursorIconInfo, WORD FAR *lpLen, LPSTR FAR *lpXorBits,
482 LPSTR FAR *lpAndMask)
484 dprintf_resource(stdnimp,"DumpIcon: Empty Stub!!!\n");
485 return 0;
489 /**********************************************************************
490 * LoadAccelerators [USER.177]
492 HANDLE LoadAccelerators(HANDLE instance, SEGPTR lpTableName)
494 HANDLE hAccel;
495 HANDLE rsc_mem;
496 HRSRC hRsrc;
497 BYTE *lp;
498 ACCELHEADER *lpAccelTbl;
499 int i, n;
501 if (HIWORD(lpTableName))
502 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
503 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
504 else
505 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
506 instance, LOWORD(lpTableName) );
508 if (!(hRsrc = FindResource( instance, lpTableName, RT_ACCELERATOR )))
509 return 0;
510 if (!(rsc_mem = LoadResource( instance, hRsrc ))) return 0;
512 lp = (BYTE *)LockResource(rsc_mem);
513 n = SizeofResource( instance, hRsrc ) / sizeof(ACCELENTRY);
514 hAccel = GlobalAlloc(GMEM_MOVEABLE,
515 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
516 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
517 lpAccelTbl->wCount = 0;
518 for (i = 0; i < n; i++) {
519 lpAccelTbl->tbl[i].type = *(lp++);
520 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
521 lp += 2;
522 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
523 lp += 2;
524 if (lpAccelTbl->tbl[i].wEvent == 0) break;
525 dprintf_accel(stddeb,
526 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
527 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
528 lpAccelTbl->tbl[i].type);
529 lpAccelTbl->wCount++;
531 GlobalUnlock(hAccel);
532 FreeResource( rsc_mem );
533 return hAccel;
536 /**********************************************************************
537 * TranslateAccelerator [USER.178]
539 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
541 ACCELHEADER *lpAccelTbl;
542 int i;
544 if (hAccel == 0 || msg == NULL) return 0;
545 if (msg->message != WM_KEYDOWN &&
546 msg->message != WM_KEYUP &&
547 msg->message != WM_CHAR) return 0;
549 dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04X !\n", hAccel);
551 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
552 for (i = 0; i < lpAccelTbl->wCount; i++) {
553 if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
554 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
555 msg->message == WM_KEYDOWN) {
556 if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
557 !(GetKeyState(VK_SHIFT) & 0xf)) {
558 GlobalUnlock(hAccel);
559 return 0;
561 if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
562 !(GetKeyState(VK_CONTROL) & 0xf)) {
563 GlobalUnlock(hAccel);
564 return 0;
566 if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
567 !(GetKeyState(VK_MENU) & 0xf)) {
568 GlobalUnlock(hAccel);
569 return 0;
571 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
572 GlobalUnlock(hAccel);
573 return 1;
575 if (msg->message == WM_KEYUP) return 1;
577 else {
578 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
579 msg->message == WM_CHAR) {
580 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
581 GlobalUnlock(hAccel);
582 return 1;
586 GlobalUnlock(hAccel);
587 return 0;
590 /**********************************************************************
591 * LoadString
594 LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
596 HANDLE hmem, hrsrc;
597 unsigned char *p;
598 int string_num;
599 int i;
601 dprintf_resource(stddeb, "LoadString: instance = %04x, id = %d, buffer = %08x, "
602 "length = %d\n", instance, resource_id, (int) buffer, buflen);
604 hrsrc = FindResource( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING );
605 if (!hrsrc) return 0;
606 hmem = LoadResource( instance, hrsrc );
607 if (!hmem) return 0;
609 p = LockResource(hmem);
610 string_num = resource_id & 0x000f;
611 for (i = 0; i < string_num; i++)
612 p += *p + 1;
614 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
616 i = min(buflen - 1, *p);
617 if (i > 0) {
618 memcpy(buffer, p + 1, i);
619 buffer[i] = '\0';
620 } else {
621 if (buflen > 1) {
622 buffer[0] = '\0';
623 return 0;
625 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
626 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
628 FreeResource( hmem );
630 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
631 return i;