Release 940714
[wine/multimedia.git] / loader / resource.c
blob421170453bf64a8e935aa821016f970f01e56fae
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";
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>
12 #include "arch.h"
13 #include "prototypes.h"
14 #include "windows.h"
15 #include "gdi.h"
16 #include "wine.h"
17 #include "icon.h"
18 #include "accel.h"
19 #include "dlls.h"
21 /* #define DEBUG_RESOURCE */
23 #define MIN(a,b) ((a) < (b) ? (a) : (b))
25 typedef struct resource_s
27 struct resource_s *next;
28 HANDLE info_mem;
29 int size_shift;
30 struct resource_nameinfo_s nameinfo;
31 HANDLE rsc_mem;
32 } RESOURCE;
34 static int ResourceFd = -1;
35 static HANDLE ResourceInst = 0;
36 static struct w_files *ResourceFileInfo = NULL;
37 static RESOURCE *Top = NULL;
38 extern HINSTANCE hSysRes;
40 HANDLE RSC_LoadResource(int instance, char *rsc_name, int type,
41 int *image_size_ret);
42 void RSC_LoadNameTable(void);
44 extern char *ProgramName;
47 /**********************************************************************
48 * RSC_LoadNameTable
50 #ifndef WINELIB
51 void
52 RSC_LoadNameTable()
54 struct resource_typeinfo_s typeinfo;
55 struct resource_nameinfo_s nameinfo;
56 unsigned short size_shift;
57 RESNAMTAB *top, *new;
58 char read_buf[1024];
59 char *p;
60 int i;
61 unsigned short len;
62 off_t rtoff;
63 off_t saved_pos;
65 top = NULL;
68 * Move to beginning of resource table.
70 rtoff = (ResourceFileInfo->mz_header->ne_offset +
71 ResourceFileInfo->ne_header->resource_tab_offset);
72 lseek(ResourceFd, rtoff, SEEK_SET);
75 * Read block size.
77 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
78 sizeof(size_shift))
80 return;
82 size_shift = CONV_SHORT(size_shift);
85 * Find resource.
87 typeinfo.type_id = 0xffff;
88 while (typeinfo.type_id != 0)
90 if (!load_typeinfo (ResourceFd, &typeinfo))
91 break;
93 if (typeinfo.type_id == 0)
94 break;
95 if (typeinfo.type_id == 0x800f)
97 for (i = 0; i < typeinfo.count; i++)
99 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
100 sizeof(nameinfo))
102 break;
105 saved_pos = lseek(ResourceFd, 0, SEEK_CUR);
106 lseek(ResourceFd, (long) nameinfo.offset << size_shift,
107 SEEK_SET);
108 read(ResourceFd, &len, sizeof(len));
109 while (len)
111 new = (RESNAMTAB *) GlobalQuickAlloc(sizeof(*new));
112 new->next = top;
113 top = new;
115 read(ResourceFd, &new->type_ord, 2);
116 read(ResourceFd, &new->id_ord, 2);
117 read(ResourceFd, read_buf, len - 6);
119 p = read_buf + strlen(read_buf) + 1;
120 strncpy(new->id, p, MAX_NAME_LENGTH);
121 new->id[MAX_NAME_LENGTH - 1] = '\0';
123 read(ResourceFd, &len, sizeof(len));
126 lseek(ResourceFd, saved_pos, SEEK_SET);
128 break;
130 else
132 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
136 ResourceFileInfo->resnamtab = top;
138 #endif /* WINELIB */
140 /**********************************************************************
141 * OpenResourceFile
144 OpenResourceFile(HANDLE instance)
146 struct w_files *w;
147 char *res_file;
149 if (ResourceInst == instance)
150 return ResourceFd;
152 w = GetFileInfo(instance);
153 if (w == NULL)
154 return -1;
155 ResourceFileInfo = w;
156 res_file = w->filename;
158 if (ResourceFd >= 0)
159 close(ResourceFd);
161 ResourceInst = instance;
162 ResourceFd = open (res_file, O_RDONLY);
163 #if 1
164 #ifndef WINELIB
165 if (w->resnamtab == (RESNAMTAB *) -1)
167 RSC_LoadNameTable();
169 #endif
170 #endif
172 #ifdef DEBUG_RESOURCE
173 printf("OpenResourceFile(%04X) // file='%s' hFile=%04X !\n",
174 instance, w->filename, ResourceFd);
175 #endif
176 return ResourceFd;
179 /**********************************************************************
180 * ConvertCoreBitmap
182 HBITMAP
183 ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
185 BITMAPINFO * bmpInfo;
186 HBITMAP hbitmap;
187 char * bits;
188 int i, size, n_colors;
190 n_colors = 1 << image->bcBitCount;
192 if (image->bcBitCount < 24)
194 size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);
195 bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
197 else
199 size = sizeof(BITMAPINFOHEADER);
200 bits = (char *) (image + 1);
202 bmpInfo = (BITMAPINFO *) malloc( size );
204 bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
205 bmpInfo->bmiHeader.biWidth = image->bcWidth;
206 bmpInfo->bmiHeader.biHeight = image->bcHeight;
207 bmpInfo->bmiHeader.biPlanes = image->bcPlanes;
208 bmpInfo->bmiHeader.biBitCount = image->bcBitCount;
209 bmpInfo->bmiHeader.biCompression = 0;
210 bmpInfo->bmiHeader.biSizeImage = 0;
211 bmpInfo->bmiHeader.biXPelsPerMeter = 0;
212 bmpInfo->bmiHeader.biYPelsPerMeter = 0;
213 bmpInfo->bmiHeader.biClrUsed = 0;
214 bmpInfo->bmiHeader.biClrImportant = 0;
216 if (image->bcBitCount < 24)
218 RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
219 RGBQUAD * newMap = bmpInfo->bmiColors;
220 for (i = 0; i < n_colors; i++, oldMap++, newMap++)
222 newMap->rgbRed = oldMap->rgbtRed;
223 newMap->rgbGreen = oldMap->rgbtGreen;
224 newMap->rgbBlue = oldMap->rgbtBlue;
225 newMap->rgbReserved = 0;
229 hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
230 bits, bmpInfo, DIB_RGB_COLORS );
231 free( bmpInfo );
232 return hbitmap;
235 /**********************************************************************
236 * ConvertInfoBitmap
238 HBITMAP
239 ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
241 char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
242 return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
243 bits, image, DIB_RGB_COLORS );
246 #ifndef WINELIB
247 load_typeinfo (int fd, struct resource_typeinfo_s *typeinfo)
249 return read (fd, typeinfo, sizeof (*typeinfo)) == sizeof (*typeinfo);
251 #endif
254 type_match(int type_id1, int type_id2, int fd, off_t off)
256 off_t old_pos;
257 unsigned char c;
258 size_t nbytes;
259 char name[256];
261 if (type_id1 == -1)
262 return 1;
263 if ((type_id1 & 0xffff0000) == 0) {
264 if ((type_id2 & 0x8000) == 0)
265 return 0;
266 return (type_id1 & 0x000f) == (type_id2 & 0x000f);
268 if ((type_id2 & 0x8000) != 0)
269 return 0;
270 #ifdef DEBUG_RESOURCE
271 printf("type_compare: type_id2=%04X !\n", type_id2);
272 #endif
273 old_pos = lseek(fd, 0, SEEK_CUR);
274 lseek(fd, off + type_id2, SEEK_SET);
275 read(fd, &c, 1);
276 nbytes = CONV_CHAR_TO_LONG (c);
277 #ifdef DEBUG_RESOURCE
278 printf("type_compare: namesize=%d\n", nbytes);
279 #endif
280 read(fd, name, nbytes);
281 lseek(fd, old_pos, SEEK_SET);
282 name[nbytes] = '\0';
283 #ifdef DEBUG_RESOURCE
284 printf("type_compare: name=`%s'\n", name);
285 #endif
286 return strcasecmp((char *) type_id1, name) == 0;
289 /**********************************************************************
290 * FindResourceByNumber
293 FindResourceByNumber(struct resource_nameinfo_s *result_p,
294 int type_id, int resource_id)
296 struct resource_typeinfo_s typeinfo;
297 struct resource_nameinfo_s nameinfo;
298 unsigned short size_shift;
299 int i;
300 off_t rtoff;
303 * Move to beginning of resource table.
305 rtoff = (ResourceFileInfo->mz_header->ne_offset +
306 ResourceFileInfo->ne_header->resource_tab_offset);
307 lseek(ResourceFd, rtoff, SEEK_SET);
310 * Read block size.
312 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
313 sizeof(size_shift))
315 printf("FindResourceByNumber (%s) bad block size !\n", resource_id);
316 return -1;
318 size_shift = CONV_SHORT(size_shift);
320 * Find resource.
322 for (;;) {
323 if (!load_typeinfo (ResourceFd, &typeinfo)){
324 printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id);
325 return -1;
327 #ifdef DEBUG_RESOURCE
328 printf("FindResourceByNumber type=%X count=%d searched=%d \n",
329 typeinfo.type_id, typeinfo.count, type_id);
330 #endif
331 if (typeinfo.type_id == 0) break;
332 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) {
334 for (i = 0; i < typeinfo.count; i++) {
335 #ifndef WINELIB
336 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
337 sizeof(nameinfo))
338 #else
339 if (!load_nameinfo (ResourceFd, &nameinfo))
340 #endif
342 printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id);
343 return -1;
345 #ifdef DEBUG_RESOURCE
346 printf("FindResource: search type=%X id=%X // type=%X id=%X\n",
347 type_id, resource_id, typeinfo.type_id, nameinfo.id);
348 #endif
349 if (nameinfo.id == resource_id) {
350 memcpy(result_p, &nameinfo, sizeof(nameinfo));
351 return size_shift;
355 else {
356 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
359 return -1;
362 /**********************************************************************
363 * FindResourceByName
366 FindResourceByName(struct resource_nameinfo_s *result_p,
367 int type_id, char *resource_name)
369 struct resource_typeinfo_s typeinfo;
370 struct resource_nameinfo_s nameinfo;
371 unsigned short size_shift;
372 off_t old_pos, new_pos;
373 unsigned char nbytes;
374 char name[256];
375 int i;
376 off_t rtoff;
379 * Check for loaded name table.
381 if (ResourceFileInfo->resnamtab != NULL)
383 RESNAMTAB *e;
385 for (e = ResourceFileInfo->resnamtab; e != NULL; e = e->next)
387 if (e->type_ord == (type_id & 0x000f) &&
388 strcasecmp(e->id, resource_name) == 0)
390 return FindResourceByNumber(result_p, type_id, e->id_ord);
394 return -1;
398 * Move to beginning of resource table.
400 rtoff = (ResourceFileInfo->mz_header->ne_offset +
401 ResourceFileInfo->ne_header->resource_tab_offset);
402 lseek(ResourceFd, rtoff, SEEK_SET);
405 * Read block size.
407 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
408 sizeof(size_shift))
410 printf("FindResourceByName (%s) bad block size !\n", resource_name);
411 return -1;
413 size_shift = CONV_SHORT (size_shift);
416 * Find resource.
418 for (;;)
420 if (!load_typeinfo (ResourceFd, &typeinfo))
422 printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name);
423 return -1;
425 #ifdef DEBUG_RESOURCE
426 printf("FindResourceByName typeinfo.type_id=%X count=%d type_id=%X\n",
427 typeinfo.type_id, typeinfo.count, type_id);
428 #endif
429 if (typeinfo.type_id == 0) break;
430 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff))
432 for (i = 0; i < typeinfo.count; i++)
434 #ifndef WINELIB
435 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
436 sizeof(nameinfo))
437 #else
438 if (!load_nameinfo (ResourceFd, &nameinfo))
439 #endif
441 printf("FindResourceByName (%s) bad nameinfo size !\n", resource_name);
442 return -1;
445 if ((nameinfo.id & 0x8000) != 0) continue;
447 #ifdef DEBUG_RESOURCE
448 printf("FindResourceByName // nameinfo.id=%04X !\n", nameinfo.id);
449 #endif
450 old_pos = lseek(ResourceFd, 0, SEEK_CUR);
451 new_pos = rtoff + nameinfo.id;
452 lseek(ResourceFd, new_pos, SEEK_SET);
453 read(ResourceFd, &nbytes, 1);
454 #ifdef DEBUG_RESOURCE
455 printf("FindResourceByName // namesize=%d !\n", nbytes);
456 #endif
457 nbytes = CONV_CHAR_TO_LONG (nbytes);
458 read(ResourceFd, name, nbytes);
459 lseek(ResourceFd, old_pos, SEEK_SET);
460 name[nbytes] = '\0';
461 #ifdef DEBUG_RESOURCE
462 printf("FindResourceByName type_id=%X (%d of %d) name='%s' resource_name='%s'\n",
463 typeinfo.type_id, i + 1, typeinfo.count,
464 name, resource_name);
465 #endif
466 if (strcasecmp(name, resource_name) == 0)
468 memcpy(result_p, &nameinfo, sizeof(nameinfo));
469 return size_shift;
473 else {
474 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
477 return -1;
481 /**********************************************************************
482 * GetRsrcCount [internal]
484 int GetRsrcCount(HINSTANCE hInst, int type_id)
486 struct resource_typeinfo_s typeinfo;
487 struct resource_nameinfo_s nameinfo;
488 unsigned short size_shift;
489 /* off_t old_pos, new_pos;
490 unsigned char nbytes;
491 char name[256]; */
492 int i;
493 off_t rtoff;
494 if (hInst == 0) return 0;
495 #ifdef DEBUG_RESOURCE
496 printf("GetRsrcCount hInst=%04X typename=%08X\n", hInst, type_name);
497 #endif
498 if (OpenResourceFile(hInst) < 0) return 0;
501 * Move to beginning of resource table.
503 rtoff = (ResourceFileInfo->mz_header->ne_offset +
504 ResourceFileInfo->ne_header->resource_tab_offset);
505 lseek(ResourceFd, rtoff, SEEK_SET);
507 * Read block size.
509 if (read(ResourceFd, &size_shift, sizeof(size_shift)) != sizeof(size_shift)) {
510 printf("GetRsrcCount // bad block size !\n");
511 return -1;
513 size_shift = CONV_SHORT (size_shift);
514 for (;;) {
515 if (!load_typeinfo (ResourceFd, &typeinfo)) {
516 printf("GetRsrcCount // bad typeinfo size !\n");
517 return 0;
519 #ifdef DEBUG_RESOURCE
520 printf("GetRsrcCount // typeinfo.type_id=%X count=%d type_id=%X\n",
521 typeinfo.type_id, typeinfo.count, type_id);
522 #endif
523 if (typeinfo.type_id == 0) break;
524 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) {
525 return typeinfo.count;
527 else {
528 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
531 return 0;
535 /**********************************************************************
536 * LoadIcon [USER.174]
538 HICON LoadIcon(HANDLE instance, LPSTR icon_name)
540 HICON hIcon;
541 HANDLE rsc_mem;
542 WORD *lp;
543 ICONDESCRIP *lpicodesc;
544 ICONALLOC *lpico;
545 int width, height;
546 BITMAPINFO *bmi;
547 BITMAPINFOHEADER *bih;
548 RGBQUAD *rgbq;
549 HBITMAP hBitMap;
550 HDC hMemDC;
551 HDC hMemDC2;
552 HDC hdc;
553 int i, j, image_size;
554 #ifdef DEBUG_RESOURCE
555 printf("LoadIcon: instance = %04x, name = %08x\n",
556 instance, icon_name);
557 #endif
559 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
560 if (instance == (HANDLE)NULL) instance = hSysRes;
561 rsc_mem = RSC_LoadResource(instance, icon_name, NE_RSCTYPE_GROUP_ICON,
562 &image_size);
563 if (rsc_mem == (HANDLE)NULL) {
564 printf("LoadIcon / Icon %04X not Found !\n", icon_name);
565 ReleaseDC(GetDesktopWindow(), hdc);
566 return 0;
568 lp = (WORD *)GlobalLock(rsc_mem);
569 if (lp == NULL) {
570 GlobalFree(rsc_mem);
571 ReleaseDC(GetDesktopWindow(), hdc);
572 return 0;
574 lpicodesc = (ICONDESCRIP *)(lp + 3);
575 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
576 if (hIcon == (HICON)NULL) {
577 GlobalFree(rsc_mem);
578 ReleaseDC(GetDesktopWindow(), hdc);
579 return 0;
581 lpico = (ICONALLOC *)GlobalLock(hIcon);
582 lpico->descriptor = *lpicodesc;
583 width = lpicodesc->Width;
584 height = lpicodesc->Height;
585 GlobalUnlock(rsc_mem);
586 GlobalFree(rsc_mem);
587 rsc_mem = RSC_LoadResource(instance,
588 MAKEINTRESOURCE(lpicodesc->icoDIBOffset),
589 NE_RSCTYPE_ICON, &image_size);
590 if (rsc_mem == (HANDLE)NULL) {
591 printf("LoadIcon / Icon %04X Bitmaps not Found !\n", icon_name);
592 ReleaseDC(GetDesktopWindow(), hdc);
593 return 0;
595 lp = (WORD *)GlobalLock(rsc_mem);
596 if (lp == NULL) {
597 GlobalFree(rsc_mem);
598 ReleaseDC(GetDesktopWindow(), hdc);
599 return 0;
601 bmi = (BITMAPINFO *)lp;
602 bih = (BITMAPINFOHEADER *)lp;
603 rgbq = &bmi->bmiColors[0];
604 bih->biHeight = bih->biHeight / 2;
606 printf("LoadIcon / image_size=%d width=%d height=%d bih->biBitCount=%d bih->biSizeImage=%ld\n",
607 image_size, width, height, bih->biBitCount, bih->biSizeImage);
609 if (bih->biSize == sizeof(BITMAPINFOHEADER))
610 lpico->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)bih);
611 else
612 lpico->hBitmap = 0;
613 bih->biBitCount = 1;
614 bih->biClrUsed = bih->biClrImportant = 2;
615 rgbq[0].rgbBlue = 0xFF;
616 rgbq[0].rgbGreen = 0xFF;
617 rgbq[0].rgbRed = 0xFF;
618 rgbq[0].rgbReserved = 0x00;
619 rgbq[1].rgbBlue = 0x00;
620 rgbq[1].rgbGreen = 0x00;
621 rgbq[1].rgbRed = 0x00;
622 rgbq[1].rgbReserved = 0x00;
623 if (bih->biSizeImage == 0) {
624 if (bih->biCompression != BI_RGB) {
625 printf("Unknown size for compressed Icon bitmap.\n");
626 GlobalFree(rsc_mem);
627 ReleaseDC(GetDesktopWindow(), hdc);
628 return 0;
630 bih->biSizeImage = (bih->biWidth * bih->biHeight * bih->biBitCount
631 + 7) / 8;
633 lpico->hBitMask = CreateDIBitmap(hdc, bih, CBM_INIT,
634 (LPSTR)lp + bih->biSizeImage - sizeof(BITMAPINFOHEADER) / 2 - 4,
635 (BITMAPINFO *)bih, DIB_RGB_COLORS );
636 GlobalUnlock(rsc_mem);
637 GlobalFree(rsc_mem);
638 hMemDC = CreateCompatibleDC(hdc);
639 hMemDC2 = CreateCompatibleDC(hdc);
640 SelectObject(hMemDC, lpico->hBitmap);
641 SelectObject(hMemDC2, lpico->hBitMask);
642 BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0, SRCINVERT);
643 DeleteDC(hMemDC);
644 DeleteDC(hMemDC2);
645 ReleaseDC(GetDesktopWindow(), hdc);
646 GlobalUnlock(hIcon);
647 #ifdef DEBUG_RESOURCE
648 printf("LoadIcon Alloc hIcon=%X\n", hIcon);
649 #endif
650 return hIcon;
654 /**********************************************************************
655 * DestroyIcon [USER.457]
657 BOOL DestroyIcon(HICON hIcon)
659 ICONALLOC *lpico;
660 if (hIcon == (HICON)NULL) return FALSE;
661 lpico = (ICONALLOC *)GlobalLock(hIcon);
662 if (lpico->hBitmap != (HBITMAP)NULL) DeleteObject(lpico->hBitmap);
663 GlobalFree(hIcon);
664 return TRUE;
668 /**********************************************************************
669 * LoadAccelerators [USER.177]
671 HANDLE LoadAccelerators(HANDLE instance, LPSTR lpTableName)
673 HANDLE hAccel;
674 HANDLE rsc_mem;
675 BYTE *lp;
676 ACCELHEADER *lpAccelTbl;
677 int i, image_size, n;
678 #ifdef DEBUG_ACCEL
679 if (((LONG)lpTableName & 0xFFFF0000L) == 0L)
680 printf("LoadAccelerators: instance = %04X, name = %08X\n",
681 instance, lpTableName);
682 else
683 printf("LoadAccelerators: instance = %04X, name = '%s'\n",
684 instance, lpTableName);
685 #endif
686 if (instance == (HANDLE)NULL) instance = hSysRes;
687 rsc_mem = RSC_LoadResource(instance, lpTableName, NE_RSCTYPE_ACCELERATOR,
688 &image_size);
689 if (rsc_mem == (HANDLE)NULL) {
690 printf("LoadAccelerators / AccelTable %04X not Found !\n", lpTableName);
691 return 0;
693 lp = (BYTE *)GlobalLock(rsc_mem);
694 if (lp == NULL) {
695 GlobalFree(rsc_mem);
696 return 0;
698 #ifdef DEBUG_ACCEL
699 printf("LoadAccelerators / image_size=%d\n", image_size);
700 #endif
701 n = image_size/5;
702 hAccel = GlobalAlloc(GMEM_MOVEABLE,
703 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
704 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
705 lpAccelTbl->wCount = 0;
706 for (i = 0; i < n; i++) {
707 lpAccelTbl->tbl[i].type = *(lp++);
708 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
709 lp += 2;
710 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
711 lp += 2;
712 if (lpAccelTbl->tbl[i].wEvent == 0) break;
713 #ifdef DEBUG_ACCEL
714 printf("Accelerator #%u / event=%04X id=%04X type=%02X \n",
715 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
716 lpAccelTbl->tbl[i].type);
717 #endif
718 lpAccelTbl->wCount++;
720 GlobalUnlock(hAccel);
721 GlobalUnlock(rsc_mem);
722 GlobalFree(rsc_mem);
723 return hAccel;
726 /**********************************************************************
727 * TranslateAccelerator [USER.178]
729 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
731 ACCELHEADER *lpAccelTbl;
732 int i, image_size;
733 if (hAccel == 0 || msg == NULL) return 0;
734 if (msg->message != WM_KEYDOWN &&
735 msg->message != WM_KEYUP &&
736 msg->message != WM_CHAR) return 0;
737 #ifdef DEBUG_ACCEL
738 printf("TranslateAccelerators hAccel=%04X !\n", hAccel);
739 #endif
740 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
741 for (i = 0; i < lpAccelTbl->wCount; i++) {
742 if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
743 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
744 msg->message == WM_KEYDOWN) {
745 if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
746 !(GetKeyState(VK_SHIFT) & 0xf)) {
747 GlobalUnlock(hAccel);
748 return 0;
750 if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
751 !(GetKeyState(VK_CONTROL) & 0xf)) {
752 GlobalUnlock(hAccel);
753 return 0;
755 if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
756 !(GetKeyState(VK_MENU) & 0xf)) {
757 GlobalUnlock(hAccel);
758 return 0;
760 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
761 GlobalUnlock(hAccel);
762 return 1;
764 if (msg->message == WM_KEYUP) return 1;
766 else {
767 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
768 msg->message == WM_CHAR) {
769 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
770 GlobalUnlock(hAccel);
771 return 1;
775 GlobalUnlock(hAccel);
776 return 0;
779 /**********************************************************************
780 * FindResource [KERNEL.60]
782 HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name)
784 RESOURCE *r;
785 HANDLE rh;
786 int type;
788 if (instance == 0)
789 return 0;
791 #ifdef DEBUG_RESOURCE
792 printf("FindResource hInst=%04X typename=%08X resname=%08X\n",
793 instance, type_name, resource_name);
794 #endif
795 if (OpenResourceFile(instance) < 0)
796 return 0;
798 rh = GlobalAlloc(GMEM_MOVEABLE, sizeof(*r));
799 if (rh == 0)
800 return 0;
801 r = (RESOURCE *)GlobalLock(rh);
803 r->next = Top;
804 Top = r;
805 r->info_mem = rh;
806 r->rsc_mem = 0;
808 if (((int) type_name & 0xffff0000) == 0)
810 type = (int) type_name;
812 else if (type_name[0] == '\0')
814 type = -1;
816 else if (type_name[0] == '#')
818 type = atoi(type_name + 1);
820 else
822 type = (int) type_name;
824 if (((int) resource_name & 0xffff0000) == 0)
826 r->size_shift = FindResourceByNumber(&r->nameinfo, type,
827 (int) resource_name | 0x8000);
829 else if (resource_name[0] == '\0')
831 r->size_shift = FindResourceByNumber(&r->nameinfo, type, -1);
833 else if (resource_name[0] == '#')
835 r->size_shift = FindResourceByNumber(&r->nameinfo, type,
836 atoi(resource_name + 1));
838 else
840 r->size_shift = FindResourceByName(&r->nameinfo, type, resource_name);
843 if (r->size_shift == -1)
845 printf("FindResource hInst=%04X typename=%08X resname=%08X not found!\n",
846 instance, type_name, resource_name);
847 GlobalFree(rh);
848 return 0;
851 return rh;
854 /**********************************************************************
855 * AllocResource [KERNEL.66]
857 HANDLE AllocResource(HANDLE instance, HANDLE hResInfo, DWORD dwSize)
859 RESOURCE *r;
860 int image_size;
862 if (instance == 0)
863 return 0;
865 if (OpenResourceFile(instance) < 0)
866 return 0;
868 r = (RESOURCE *)GlobalLock(hResInfo);
869 if (r == NULL)
870 return 0;
872 image_size = r->nameinfo.length << r->size_shift;
874 if (dwSize == 0)
875 r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
876 else
877 r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, dwSize);
879 GlobalUnlock(hResInfo);
881 return r->rsc_mem;
884 /**********************************************************************
885 * LoadResource [KERNEL.61]
887 HANDLE LoadResource(HANDLE instance, HANDLE hResInfo)
889 RESOURCE *r;
890 int image_size;
891 void *image;
892 HANDLE h;
894 if (instance == 0)
895 return 0;
897 if (OpenResourceFile(instance) < 0)
898 return 0;
900 r = (RESOURCE *)GlobalLock(hResInfo);
901 if (r == NULL)
902 return 0;
904 image_size = r->nameinfo.length << r->size_shift;
906 h = r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
907 image = GlobalLock(h);
909 lseek(ResourceFd, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET);
911 if (image == NULL || read(ResourceFd, image, image_size) != image_size)
913 GlobalFree(h);
914 GlobalUnlock(hResInfo);
915 return 0;
918 GlobalUnlock(h);
919 GlobalUnlock(hResInfo);
920 return h;
923 /**********************************************************************
924 * LockResource [KERNEL.62]
926 LPSTR LockResource(HANDLE hResData)
928 return GlobalLock(hResData);
931 /**********************************************************************
932 * FreeResource [KERNEL.63]
934 HANDLE FreeResource(HANDLE hResData)
936 RESOURCE *r, *rp;
938 for (r = rp = Top; r != NULL; r = r->next)
940 if (r->info_mem == hResData)
942 if (rp != NULL)
943 rp->next = r->next;
944 else
945 Top = r->next;
947 GlobalFree(r->rsc_mem);
948 GlobalFree(r->info_mem);
949 return 0;
951 rp = r;
954 return hResData;
957 /**********************************************************************
958 * AccessResource [KERNEL.64]
960 int AccessResource(HANDLE instance, HANDLE hResInfo)
962 int resfile, image_size;
963 RESOURCE *r;
965 /* #ifdef DEBUG_RESOURCE */
966 printf("AccessResource(%04X, %04X);\n", instance, hResInfo);
967 /* #endif */
969 if (instance == 0)
970 return -1;
972 if ((resfile = OpenResourceFile(instance)) < 0)
973 return -1;
975 if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
976 return -1;
978 lseek(resfile, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET);
979 GlobalUnlock(hResInfo);
981 return resfile;
984 /**********************************************************************
985 * SizeofResource [KERNEL.65]
987 WORD SizeofResource(HANDLE instance, HANDLE hResInfo)
989 int image_size;
990 RESOURCE *r;
992 /* #ifdef DEBUG_RESOURCE */
993 printf("SizeofResource(%04X, %04X);\n", instance, hResInfo);
994 /* #endif */
996 if (instance == 0)
997 return 0;
999 if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
1000 return 0;
1002 image_size = r->nameinfo.length << r->size_shift;
1004 GlobalUnlock(hResInfo);
1006 /* #ifdef DEBUG_RESOURCE */
1007 printf("SizeofResource return %d\n", image_size);
1008 /* #endif */
1010 return image_size;
1013 /**********************************************************************
1014 * RSC_LoadResource
1016 HANDLE
1017 RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret)
1019 struct resource_nameinfo_s nameinfo;
1020 HANDLE hmem;
1021 void *image;
1022 int image_size;
1023 int size_shift;
1026 * Built-in resources
1028 if (instance == 0)
1030 return 0;
1032 else if (OpenResourceFile(instance) < 0)
1033 return 0;
1036 * Get resource by ordinal
1038 if (((int) rsc_name & 0xffff0000) == 0)
1040 size_shift = FindResourceByNumber(&nameinfo, type,
1041 (int) rsc_name | 0x8000);
1044 * Get resource by name
1046 else
1048 size_shift = FindResourceByName(&nameinfo, type, rsc_name);
1050 if (size_shift == -1) {
1051 if ((LONG)rsc_name >= 0x00010000L)
1052 printf("RSC_LoadResource / Resource '%s' not Found !\n", rsc_name);
1053 else
1054 printf("RSC_LoadResource / Resource '%X' not Found !\n", rsc_name);
1055 return 0;
1058 * Read resource.
1060 lseek(ResourceFd, ((int) nameinfo.offset << size_shift), SEEK_SET);
1062 image_size = nameinfo.length << size_shift;
1063 if (image_size_ret != NULL)
1064 *image_size_ret = image_size;
1065 hmem = GlobalAlloc(GMEM_MOVEABLE, image_size);
1066 image = GlobalLinearLock(hmem);
1067 if (image == NULL || read(ResourceFd, image, image_size) != image_size)
1069 GlobalFree(hmem);
1070 return 0;
1073 GlobalLinearUnlock(hmem);
1074 return hmem;
1077 /**********************************************************************
1078 * LoadString
1081 LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
1083 HANDLE hmem;
1084 int rsc_size;
1085 unsigned char *p;
1086 int string_num;
1087 int i;
1089 #ifdef DEBUG_RESOURCE
1090 printf("LoadString: instance = %04x, id = %d, "
1091 "buffer = %08x, length = %d\n",
1092 instance, resource_id, buffer, buflen);
1093 #endif
1095 hmem = RSC_LoadResource(instance, (char *) ((resource_id >> 4) + 1),
1096 NE_RSCTYPE_STRING, &rsc_size);
1097 if (hmem == 0)
1098 return 0;
1100 p = GlobalLock(hmem);
1101 string_num = resource_id & 0x000f;
1102 for (i = 0; i < string_num; i++)
1103 p += *p + 1;
1105 i = MIN(buflen - 1, *p);
1106 if (i > 0) {
1107 memcpy(buffer, p + 1, i);
1108 buffer[i] = '\0';
1110 else {
1111 if (buflen > 1) {
1112 buffer[0] = '\0';
1113 return 0;
1115 printf("LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
1116 printf("LoadString // and try to obtain string '%s'\n", p + 1);
1118 GlobalFree(hmem);
1120 #ifdef DEBUG_RESOURCE
1121 printf("LoadString // '%s' copied !\n", buffer);
1122 #endif
1123 return i;
1126 /**********************************************************************
1127 * RSC_LoadMenu
1129 HANDLE
1130 RSC_LoadMenu(HANDLE instance, LPSTR menu_name)
1132 #ifdef DEBUG_RESOURCE
1133 printf("RSC_LoadMenu: instance = %04x, name = '%s'\n",
1134 instance, menu_name);
1135 #endif
1136 return RSC_LoadResource(instance, menu_name, NE_RSCTYPE_MENU, NULL);
1139 /**********************************************************************
1140 * LoadBitmap
1142 HBITMAP
1143 LoadBitmap(HANDLE instance, LPSTR bmp_name)
1145 HBITMAP hbitmap;
1146 HANDLE rsc_mem;
1147 HDC hdc;
1148 long *lp;
1149 int image_size;
1150 int size;
1152 #ifdef DEBUG_RESOURCE
1153 printf("LoadBitmap: instance = %04x, name = %08x\n",
1154 instance, bmp_name);
1155 #endif
1156 if (instance == (HANDLE)NULL) instance = hSysRes;
1157 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
1159 rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP,
1160 &image_size);
1161 if (rsc_mem == (HANDLE)NULL) {
1162 printf("LoadBitmap / BitMap %04X not Found !\n", bmp_name);
1163 return 0;
1165 lp = (long *) GlobalLinearLock(rsc_mem);
1166 if (lp == NULL)
1168 GlobalFree(rsc_mem);
1169 return 0;
1171 size = CONV_LONG (*lp);
1172 if (size == sizeof(BITMAPCOREHEADER)){
1173 CONV_BITMAPCOREHEADER (lp);
1174 hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp );
1175 } else if (size == sizeof(BITMAPINFOHEADER)){
1176 CONV_BITMAPINFO (lp);
1177 hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
1178 } else hbitmap = 0;
1179 GlobalFree(rsc_mem);
1180 ReleaseDC( 0, hdc );
1181 return hbitmap;
1184 /**********************************************************************
1185 * CreateIcon [USER.407]
1187 HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight,
1188 BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits,
1189 LPSTR lpXORbits)
1191 HICON hIcon;
1192 ICONALLOC *lpico;
1194 #ifdef DEBUG_RESOURCE
1195 printf("CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n",
1196 hInstance, nWidth, nHeight);
1197 printf(" nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel);
1198 printf(" lpANDbits= %04x, lpXORbits = %04x, \n",lpANDbits, lpXORbits);
1199 #endif
1201 if (hInstance == (HANDLE)NULL) {
1202 printf("CreateIcon / hInstance %04x not Found!\n",hInstance);
1203 return 0;
1205 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
1206 if (hIcon == (HICON)NULL) {
1207 printf("Can't allocate memory for Icon in CreateIcon\n");
1208 return 0;
1210 lpico= (ICONALLOC *)GlobalLock(hIcon);
1212 lpico->descriptor.Width=nWidth;
1213 lpico->descriptor.Height=nHeight;
1214 lpico->descriptor.ColorCount=16; /* Dummy Value */
1215 lpico->descriptor.Reserved1=0;
1216 lpico->descriptor.Reserved2=nPlanes;
1217 lpico->descriptor.Reserved3=nWidth*nHeight;
1219 /* either nPlanes and/or nBitCount is set to one */
1220 lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel;
1221 lpico->descriptor.icoDIBOffset=0;
1223 if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel,
1224 lpXORbits)) ) {
1225 printf("CreateIcon: couldn't create the XOR bitmap\n");
1226 return(0);
1229 /* the AND BitMask is always monochrome */
1230 if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) {
1231 printf("CreateIcon: couldn't create the AND bitmap\n");
1232 return(0);
1235 GlobalUnlock(hIcon);
1236 #ifdef DEBUG_RESOURCE
1237 printf("CreateIcon Alloc hIcon=%X\n", hIcon);
1238 #endif
1239 return hIcon;