Release 941107
[wine] / loader / resource.c
1 static char RCSId[] = "$Id: resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include "arch.h"
12 #include "prototypes.h"
13 #include "windows.h"
14 #include "gdi.h"
15 #include "wine.h"
16 #include "icon.h"
17 #include "menu.h"
18 #include "accel.h"
19 #include "dlls.h"
20 #include "resource.h"
21 #include "stddebug.h"
22 /* #define DEBUG_RESOURCE */
23 /* #undef  DEBUG_RESOURCE */
24 /* #define DEBUG_ACCEL    */
25 /* #undef  DEBUG_ACCEL    */
26 #include "debug.h"
27 #include "../rc/sysresbm.h"
28
29 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
30
31 RESOURCE *Top = NULL;
32 extern HINSTANCE hSysRes;
33
34 extern int NE_FindResource(HANDLE, LPSTR, LPSTR, RESOURCE *);
35 extern int PE_FindResource(HANDLE, LPSTR, LPSTR, RESOURCE *);
36 extern HBITMAP OBM_LoadOEMBitmap( WORD id );  /* objects/oembitmap.c */
37
38 #define PrintId(name) \
39         if (HIWORD((DWORD)name)) \
40                 printf(", %s", name); \
41         else \
42                 printf(", #%d", (int) name); 
43
44 /**********************************************************************
45  *                      FindResource    [KERNEL.60]
46  */
47 HANDLE FindResource(HANDLE instance, LPSTR name, LPSTR type)
48 {
49         int status;
50         RESOURCE *r;
51         HANDLE rh;
52
53 #ifdef DEBUG_RESOURCE 
54         printf("FindResource(%04X", instance);
55         PrintId(name);
56         PrintId(type);
57         printf(")\n");
58 #endif
59
60         if (instance == (HANDLE)NULL)
61                 instance = hSysRes;
62
63         /* FIXME: did we already find this one ? */
64
65         if ((rh = GlobalAlloc(GMEM_MOVEABLE, sizeof(RESOURCE))) == 0)
66                 return 0;
67
68         r = (RESOURCE *)GlobalLock(rh);
69         r->next = Top;
70         Top = r;
71         r->info_mem = rh;
72         r->rsc_mem = 0;
73         r->count = 0;
74         if (HIWORD((DWORD)name))
75                 r->name = strdup(name);
76         else
77                 r->name = name;
78
79         if (HIWORD((DWORD)type))
80                 r->type = strdup(type);
81         else
82                 r->type = type;
83
84         r->wpnt = GetFileInfo(instance);
85         r->fd = dup(r->wpnt->fd);
86         if (r->wpnt->ne)
87                 status = NE_FindResource(instance, name, type, r);
88         else
89                 status = PE_FindResource(instance, name, type, r);
90
91         if (!status) {
92                 if (HIWORD((DWORD)r->name))
93                         free(r->name);
94
95                 if (HIWORD((DWORD)r->type))
96                         free(r->type);
97                 close(r->fd);
98
99                 Top = r->next;
100                 GlobalUnlock(rh);
101                 return 0;
102         } else
103                 return rh;
104 }
105
106 /**********************************************************************
107  *                      AllocResource   [KERNEL.66]
108  */
109 HANDLE AllocResource(HANDLE instance, HANDLE hResInfo, DWORD dwSize)
110 {
111         RESOURCE *r;
112         int image_size;
113
114         dprintf_resource(stddeb, "AllocResource(%04X, %04X, %08X);\n", 
115                 instance, hResInfo, (int) dwSize);
116
117         if (instance == (HANDLE)NULL)
118                 instance = hSysRes;
119
120         if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
121                 return 0;
122     
123         image_size = r->size;
124
125         if (dwSize == 0)
126                 r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
127         else
128                 r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, dwSize);
129
130         GlobalUnlock(hResInfo);
131
132         return r->rsc_mem;
133 }
134 \f
135 /**********************************************************************
136  *                              AccessResource  [KERNEL.64]
137  */
138 int AccessResource(HANDLE instance, HANDLE hResInfo)
139 {
140         int fd;
141         RESOURCE *r;
142
143         dprintf_resource(stddeb, "AccessResource(%04X, %04X);\n", 
144                 instance, hResInfo);
145
146         if (instance == (HANDLE)NULL)
147                 instance = hSysRes;
148
149         if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
150                 return -1;
151
152         fd = r->fd;
153         lseek(fd, r->offset, SEEK_SET);
154         GlobalUnlock(hResInfo);
155
156         return fd;
157 }
158 \f
159 /**********************************************************************
160  *                              SizeofResource  [KERNEL.65]
161  */
162 WORD SizeofResource(HANDLE instance, HANDLE hResInfo)
163 {
164         RESOURCE *r;
165         int size;
166         
167         dprintf_resource(stddeb, "SizeofResource(%04X, %04X);\n", 
168                 instance, hResInfo);
169
170         if (instance == (HANDLE)NULL)
171                 instance = hSysRes;
172
173         if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
174                 return 0;
175
176         size = r->size;
177         GlobalUnlock(hResInfo);
178
179         return size;
180 }
181
182 /**********************************************************************
183  *                      LoadResource    [KERNEL.61]
184  */
185 HANDLE LoadResource(HANDLE instance, HANDLE hResInfo)
186 {
187     RESOURCE *r;
188     int image_size, fd;
189     void *image;
190     HANDLE h;
191
192     dprintf_resource(stddeb, "LoadResource(%04X, %04X);\n", instance, hResInfo);
193
194     if (instance == (HANDLE)NULL)
195         instance = hSysRes;
196
197     if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
198         return 0;
199     
200     h = r->rsc_mem = AllocResource(instance, hResInfo, 0);
201     image = GlobalLinearLock(h);
202     image_size = r->size;
203     fd = AccessResource(instance, hResInfo);
204
205     if (image == NULL || read(fd, image, image_size) != image_size) {
206         GlobalFree(h);
207         GlobalUnlock(hResInfo);
208         return 0;
209     }
210     r->count++;
211     close(fd);
212     GlobalLinearUnlock(h);
213     GlobalUnlock(hResInfo);
214     return h;
215 }
216
217 /**********************************************************************
218  *                              LockResource    [KERNEL.62]
219  */
220 LPSTR LockResource(HANDLE hResData)
221 {
222     return GlobalLock(hResData);
223 }
224
225 /**********************************************************************
226  *                              FreeResource    [KERNEL.63]
227  */
228 HANDLE FreeResource(HANDLE hResData)
229 {
230     RESOURCE *r, *rp;
231
232     dprintf_resource(stddeb, "FreeResource: handle %04x\n", hResData);
233
234     for (r = rp = Top; r ; r = r->next) {
235         if (r->rsc_mem == hResData) {
236             if (r->count == 0) {
237                     if (rp != r)
238                         rp->next = r->next;
239                     else
240                         Top = r->next;
241
242                     if (HIWORD((DWORD)r->name))
243                         free(r->name);
244                     if (HIWORD((DWORD)r->type))
245                         free(r->type);
246                     GlobalFree(r->rsc_mem);
247                     GlobalFree(r->info_mem);
248                     return 0;
249             } else
250                 r->count--;
251         }
252         rp = r;
253     }
254     return hResData;
255 }
256 \f
257 /**********************************************************************
258  *                      ConvertCoreBitmap
259  */
260 HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
261 {
262     BITMAPINFO * bmpInfo;
263     HBITMAP hbitmap;
264     char * bits;
265     int i, size, n_colors;
266    
267     n_colors = 1 << image->bcBitCount;
268     if (image->bcBitCount < 24)
269     {
270         size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);   
271         bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
272     }
273     else
274     {
275         size = sizeof(BITMAPINFOHEADER);
276         bits = (char *) (image + 1);
277     }
278     bmpInfo = (BITMAPINFO *) malloc( size );
279
280     bmpInfo->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
281     bmpInfo->bmiHeader.biWidth         = image->bcWidth;
282     bmpInfo->bmiHeader.biHeight        = image->bcHeight;
283     bmpInfo->bmiHeader.biPlanes        = image->bcPlanes;
284     bmpInfo->bmiHeader.biBitCount      = image->bcBitCount;
285     bmpInfo->bmiHeader.biCompression   = 0;
286     bmpInfo->bmiHeader.biSizeImage     = 0;
287     bmpInfo->bmiHeader.biXPelsPerMeter = 0;
288     bmpInfo->bmiHeader.biYPelsPerMeter = 0;
289     bmpInfo->bmiHeader.biClrUsed       = 0;
290     bmpInfo->bmiHeader.biClrImportant  = 0;
291
292     if (image->bcBitCount < 24)
293     {
294         RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
295         RGBQUAD * newMap = bmpInfo->bmiColors;
296         for (i = 0; i < n_colors; i++, oldMap++, newMap++)
297         {
298             newMap->rgbRed      = oldMap->rgbtRed;
299             newMap->rgbGreen    = oldMap->rgbtGreen;
300             newMap->rgbBlue     = oldMap->rgbtBlue;
301             newMap->rgbReserved = 0;
302         }
303     }
304
305     hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
306                               bits, bmpInfo, DIB_RGB_COLORS );
307     free( bmpInfo );
308     return hbitmap;
309 }
310
311 /**********************************************************************
312  *                      ConvertInfoBitmap
313  */
314 HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
315 {
316     char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
317     return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
318                            bits, image, DIB_RGB_COLORS );
319
320
321 /**********************************************************************
322  *                      RSC_LoadResource
323  */
324 HANDLE
325 RSC_LoadResource(int instance, LPSTR rsc_name, LPSTR type, int *image_size_ret)
326 {
327         HANDLE hResInfo;
328         RESOURCE *r;
329
330         if (instance == (HANDLE)NULL)
331                 instance = hSysRes;
332
333         dprintf_resource(stddeb, "RSC_LoadResource: instance = %04x, name = %08x, type = %08x\n",
334            instance, (int) rsc_name, (int) type);
335
336         if ((hResInfo = FindResource(instance, rsc_name, (LPSTR) type)) == (HANDLE) NULL) {
337                 return (HANDLE)NULL;
338         }
339         r = (RESOURCE *)GlobalLock(hResInfo);
340         if (image_size_ret) 
341                 *image_size_ret = r->size;
342         r->count++;
343         GlobalUnlock(hResInfo);
344         return LoadResource(instance, hResInfo);
345 }
346 \f
347 /**********************************************************************
348  *                      LoadIcon [USER.174]
349  */
350 HICON LoadIcon(HANDLE instance, LPSTR icon_name)
351 {
352     HICON       hIcon;
353     HANDLE      rsc_mem;
354     WORD        *lp;
355     ICONDESCRIP *lpicodesc;
356     ICONALLOC   *lpico;
357     int         width, height;
358     BITMAPINFO  *bmi;
359     BITMAPINFOHEADER    *bih;
360     RGBQUAD     *rgbq;
361     HDC         hMemDC;
362     HDC         hMemDC2;
363     HDC         hdc;
364     int         image_size;
365     HBITMAP     hbmpOld1, hbmpOld2;
366
367 #ifdef DEBUG_RESOURCE
368         printf("LoadIcon(%04X", instance);
369         PrintId(icon_name);
370         printf(")\n");
371 #endif
372     
373     if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
374     rsc_mem = RSC_LoadResource(instance, icon_name, (LPSTR) NE_RSCTYPE_GROUP_ICON, 
375                                &image_size);
376     if (rsc_mem == (HANDLE)NULL) {
377         printf("LoadIcon / Icon %04X not Found !\n", (int) icon_name);
378         ReleaseDC(GetDesktopWindow(), hdc); 
379         return 0;
380         }
381     lp = (WORD *)GlobalLock(rsc_mem);
382     if (lp == NULL) {
383         GlobalFree(rsc_mem);
384         ReleaseDC(GetDesktopWindow(), hdc); 
385         return 0;
386         }
387     lpicodesc = (ICONDESCRIP *)(lp + 3);
388     hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
389     if (hIcon == (HICON)NULL) {
390         GlobalFree(rsc_mem);
391         ReleaseDC(GetDesktopWindow(), hdc); 
392         return 0;
393         }
394     lpico = (ICONALLOC *)GlobalLock(hIcon);
395     lpico->descriptor = *lpicodesc;
396     width = lpicodesc->Width;
397     height = lpicodesc->Height;
398     GlobalUnlock(rsc_mem);
399     GlobalFree(rsc_mem);
400     rsc_mem = RSC_LoadResource(instance, 
401         MAKEINTRESOURCE(lpicodesc->icoDIBOffset), 
402         (LPSTR) NE_RSCTYPE_ICON, &image_size);
403     if (rsc_mem == (HANDLE)NULL) {
404         printf("LoadIcon / Icon %04X Bitmaps not Found !\n", (int) icon_name);
405         ReleaseDC(GetDesktopWindow(), hdc); 
406         return 0;
407         }
408     lp = (WORD *)GlobalLock(rsc_mem);
409     if (lp == NULL) {
410         GlobalFree(rsc_mem);
411         ReleaseDC(GetDesktopWindow(), hdc); 
412         return 0;
413         }
414     bmi = (BITMAPINFO *)lp;
415     bih = (BITMAPINFOHEADER *)lp;
416     rgbq = &bmi->bmiColors[0];
417     bih->biHeight = bih->biHeight / 2;
418 /*
419     printf("LoadIcon / image_size=%d width=%d height=%d bih->biBitCount=%d bih->biSizeImage=%ld\n", 
420         image_size, width, height, bih->biBitCount, bih->biSizeImage);
421 */
422     if (bih->biSize == sizeof(BITMAPINFOHEADER))
423         lpico->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)bih);
424     else
425         lpico->hBitmap = 0;
426     bih->biBitCount = 1;
427     bih->biClrUsed = bih->biClrImportant  = 2;
428     rgbq[0].rgbBlue     = 0xFF;
429     rgbq[0].rgbGreen    = 0xFF;
430     rgbq[0].rgbRed      = 0xFF;
431     rgbq[0].rgbReserved = 0x00;
432     rgbq[1].rgbBlue     = 0x00;
433     rgbq[1].rgbGreen    = 0x00;
434     rgbq[1].rgbRed      = 0x00;
435     rgbq[1].rgbReserved = 0x00;
436     if (bih->biSizeImage == 0) {
437         if (bih->biCompression != BI_RGB) {
438             fprintf(stderr,"Unknown size for compressed Icon bitmap.\n");
439             GlobalFree(rsc_mem);
440             ReleaseDC(GetDesktopWindow(), hdc); 
441             return 0;
442             }
443         bih->biSizeImage = (bih->biWidth * bih->biHeight * bih->biBitCount
444                             + 7) / 8;
445         }
446     lpico->hBitMask = CreateDIBitmap(hdc, bih, CBM_INIT,
447         (LPSTR)lp + bih->biSizeImage - sizeof(BITMAPINFOHEADER) / 2 - 4,
448         (BITMAPINFO *)bih, DIB_RGB_COLORS );
449     GlobalUnlock(rsc_mem);
450     GlobalFree(rsc_mem);
451     hMemDC = CreateCompatibleDC(hdc);
452     hMemDC2 = CreateCompatibleDC(hdc);
453     hbmpOld1 = SelectObject(hMemDC, lpico->hBitmap);
454     hbmpOld2 = SelectObject(hMemDC2, lpico->hBitMask);
455     BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0,SRCINVERT);
456     SelectObject( hMemDC, hbmpOld1 );
457     SelectObject( hMemDC2, hbmpOld2 );
458     DeleteDC(hMemDC);
459     DeleteDC(hMemDC2);
460     ReleaseDC(GetDesktopWindow(), hdc);
461     GlobalUnlock(hIcon);
462     dprintf_resource(stddeb,"LoadIcon Alloc hIcon=%X\n", hIcon);
463     return hIcon;
464 }
465 \f
466 /**********************************************************************
467  *                      CreateIcon [USER.407]
468  */
469 HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight, 
470                  BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits, 
471                  LPSTR lpXORbits)
472 {
473     HICON       hIcon;
474     ICONALLOC   *lpico;
475
476     dprintf_resource(stddeb, "CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n",
477             hInstance, nWidth, nHeight);
478     dprintf_resource(stddeb, "  nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel);
479     dprintf_resource(stddeb, " lpANDbits= %04x, lpXORbits = %04x, \n", (int)lpANDbits,
480                 (int)lpXORbits);
481
482     if (hInstance == (HANDLE)NULL) { 
483         printf("CreateIcon / hInstance %04x not Found!\n",hInstance);
484         return 0;
485         }
486     hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
487     if (hIcon == (HICON)NULL) {
488         printf("Can't allocate memory for Icon in CreateIcon\n");
489         return 0;
490         }
491     lpico= (ICONALLOC *)GlobalLock(hIcon);
492
493     lpico->descriptor.Width=nWidth;
494     lpico->descriptor.Height=nHeight;
495     lpico->descriptor.ColorCount=16; /* Dummy Value */ 
496     lpico->descriptor.Reserved1=0;
497     lpico->descriptor.Reserved2=nPlanes;
498     lpico->descriptor.Reserved3=nWidth*nHeight;
499
500     /* either nPlanes and/or nBitCount is set to one */
501     lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel; 
502     lpico->descriptor.icoDIBOffset=0; 
503
504     if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel, 
505                                  lpXORbits)) ) {
506       printf("CreateIcon: couldn't create the XOR bitmap\n");
507       return(0);
508     }
509     
510     /* the AND BitMask is always monochrome */
511     if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) {
512       printf("CreateIcon: couldn't create the AND bitmap\n");
513       return(0);
514     }
515
516     GlobalUnlock(hIcon);
517     dprintf_resource(stddeb, "CreateIcon Alloc hIcon=%X\n", hIcon);
518     return hIcon;
519 }
520 \f
521 /**********************************************************************
522  *                      DestroyIcon [USER.457]
523  */
524 BOOL DestroyIcon(HICON hIcon)
525 {
526     ICONALLOC   *lpico;
527     
528     if (hIcon == (HICON)NULL)
529         return FALSE;
530     lpico = (ICONALLOC *)GlobalLock(hIcon);
531     if (lpico->hBitmap != (HBITMAP)NULL) 
532         DeleteObject(lpico->hBitmap);
533     GlobalFree(hIcon);
534     return TRUE;
535 }
536 \f
537 /**********************************************************************
538  *                      LoadAccelerators        [USER.177]
539  */
540 HANDLE LoadAccelerators(HANDLE instance, LPSTR lpTableName)
541 {
542     HANDLE      hAccel;
543     HANDLE      rsc_mem;
544     BYTE        *lp;
545     ACCELHEADER *lpAccelTbl;
546     int         i, image_size, n;
547
548 #ifdef DEBUG_ACCEL
549         printf("LoadAccelerators(%04X", instance);
550         PrintId(lpTableName);
551         printf(")\n");
552 #endif
553
554     rsc_mem = RSC_LoadResource(instance, lpTableName, (LPSTR) NE_RSCTYPE_ACCELERATOR, 
555                                &image_size);
556     if (rsc_mem == (HANDLE)NULL) {
557         printf("LoadAccelerators(%04X", instance);
558         PrintId(lpTableName);
559         printf(") not found !\n");
560         return 0;
561         }
562     lp = (BYTE *)GlobalLock(rsc_mem);
563     if (lp == NULL) {
564         GlobalFree(rsc_mem);
565         return 0;
566         }
567     dprintf_accel(stddeb,"LoadAccelerators / image_size=%d\n", image_size);
568     n = image_size/5;
569     hAccel = GlobalAlloc(GMEM_MOVEABLE, 
570         sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
571     lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
572     lpAccelTbl->wCount = 0;
573     for (i = 0; i < n; i++) {
574         lpAccelTbl->tbl[i].type = *(lp++);
575         lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
576         lp += 2;
577         lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
578         lp += 2;
579         if (lpAccelTbl->tbl[i].wEvent == 0) break;
580         dprintf_accel(stddeb,
581                 "Accelerator #%u / event=%04X id=%04X type=%02X \n", 
582                 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval, 
583                 lpAccelTbl->tbl[i].type);
584         lpAccelTbl->wCount++;
585         }
586     GlobalUnlock(hAccel);
587     GlobalUnlock(rsc_mem);
588     GlobalFree(rsc_mem);
589     return hAccel;
590 }
591 \f
592 /**********************************************************************
593  *                      TranslateAccelerator    [USER.178]
594  */
595 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
596 {
597     ACCELHEADER *lpAccelTbl;
598     int         i;
599     
600     if (hAccel == 0 || msg == NULL) return 0;
601     if (msg->message != WM_KEYDOWN &&
602         msg->message != WM_KEYUP &&
603         msg->message != WM_CHAR) return 0;
604
605     dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04X !\n", hAccel);
606
607     lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
608     for (i = 0; i < lpAccelTbl->wCount; i++) {
609         if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
610             if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
611                 msg->message == WM_KEYDOWN) {
612                 if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
613                     !(GetKeyState(VK_SHIFT) & 0xf)) {
614                     GlobalUnlock(hAccel);
615                     return 0;
616                 }
617                 if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
618                     !(GetKeyState(VK_CONTROL) & 0xf)) {
619                     GlobalUnlock(hAccel);
620                     return 0;
621                 }
622                 if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
623                     !(GetKeyState(VK_MENU) & 0xf)) {
624                     GlobalUnlock(hAccel);
625                     return 0;
626                 }
627                 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
628                 GlobalUnlock(hAccel);
629                 return 1;
630                 }
631             if (msg->message == WM_KEYUP) return 1;
632             }
633         else {
634             if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
635                 msg->message == WM_CHAR) {
636                 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
637                 GlobalUnlock(hAccel);
638                 return 1;
639                 }
640             }
641         }
642     GlobalUnlock(hAccel);
643     return 0;
644 }
645 \f
646 /**********************************************************************
647  *                                      LoadString
648  */
649 int
650 LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
651 {
652     HANDLE hmem;
653     int rsc_size;
654     unsigned char *p;
655     int string_num;
656     int i;
657
658     dprintf_resource(stddeb, "LoadString: instance = %04x, id = %d, buffer = %08x, "
659            "length = %d\n", instance, resource_id, (int) buffer, buflen);
660
661     hmem = RSC_LoadResource(instance, (char *) ((resource_id >> 4) + 1),
662                             (LPSTR) NE_RSCTYPE_STRING, &rsc_size);
663     if (hmem == 0)
664         return 0;
665     
666     p = GlobalLock(hmem);
667     string_num = resource_id & 0x000f;
668     for (i = 0; i < string_num; i++)
669         p += *p + 1;
670     
671     i = MIN(buflen - 1, *p);
672         if (i > 0) {
673                 memcpy(buffer, p + 1, i);
674                 buffer[i] = '\0';
675                 }
676         else {
677                 if (buflen > 1) {
678                         buffer[0] = '\0';
679                         return 0;
680                         }
681                 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
682                 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
683                 }
684     GlobalFree(hmem);
685
686     dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
687     return i;
688 }
689 \f
690 /**********************************************************************
691  *                      LoadMenu                [USER.150]
692  */
693 HMENU LoadMenu(HINSTANCE instance, char *menu_name)
694 {
695         HMENU                   hMenu;
696         HANDLE          hMenu_desc;
697         MENU_HEADER     *menu_desc;
698
699 #ifdef DEBUG_MENU
700         printf("LoadMenu(%04X", instance);
701         PrintId(menu_name);
702         printf(")\n");
703 #endif
704         if (menu_name == NULL)
705                 return 0;
706
707         if ((hMenu_desc = RSC_LoadResource(instance, menu_name, (LPSTR) NE_RSCTYPE_MENU, NULL)) == (HANDLE) NULL)
708                 return 0;
709         
710         menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc);
711         hMenu = LoadMenuIndirect((LPSTR)menu_desc);
712         return hMenu;
713 }
714 \f
715 /**********************************************************************
716  *                                      LoadBitmap
717  */
718 HBITMAP 
719 LoadBitmap(HANDLE instance, LPSTR bmp_name)
720 {
721     HBITMAP hbitmap;
722     HANDLE rsc_mem;
723     HDC hdc;
724     long *lp;
725     int image_size;
726     int size;
727     
728 #ifdef DEBUG_RESOURCE
729         printf("LoadBitmap(%04X", instance);
730         PrintId(bmp_name);
731         printf(")\n");
732 #endif
733
734     if (!instance) {
735         struct ResourceTable *it;
736         hbitmap = OBM_LoadOEMBitmap(((int) bmp_name) & 0xffff);
737         if (hbitmap)
738                 return hbitmap;
739         /* Load from sysresbm */
740         dprintf_resource(stddeb,"Searching for %d\n",bmp_name);
741         for(it=sysresbmTable;it;it++){
742             if(it->type==NE_RSCTYPE_BITMAP)
743             if((((int)bmp_name & 0xFFFF0000) == 0))
744                 {if(it->id==(int)bmp_name)break;}
745             else if(!strcmp(it->name,bmp_name))break;
746         }
747         if(!it)return 0;
748         dprintf_resource(stddeb,"Found %s\n",it->name);
749         lp=it->value;
750         rsc_mem=(HANDLE)NULL;
751     } else { /* Load from file - indent this code properly later */
752
753     rsc_mem = RSC_LoadResource(instance, bmp_name, (LPSTR) NE_RSCTYPE_BITMAP, 
754                                &image_size);
755     if (rsc_mem == (HANDLE)NULL) {
756         printf("LoadBitmap(%04X", instance);
757         PrintId(bmp_name);
758         printf(") NOT found!\n");
759         return 0;
760         }
761     lp = (long *) GlobalLinearLock(rsc_mem);
762     if (lp == NULL)
763     {
764         GlobalFree(rsc_mem);
765         return 0;
766     }
767     } /* Load from file */
768     if (!(hdc = GetDC(0))) lp = NULL;
769     size = CONV_LONG (*lp);
770     if (size == sizeof(BITMAPCOREHEADER)){
771         CONV_BITMAPCOREHEADER (lp);
772         hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp );
773     } else if (size == sizeof(BITMAPINFOHEADER)){
774         CONV_BITMAPINFO (lp);
775         hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
776     } else hbitmap = 0;
777     GlobalFree(rsc_mem);
778     ReleaseDC( 0, hdc );
779     return hbitmap;
780 }