Release 940815
[wine/gsoc-2012-control.git] / loader / resource.c
blobb69c5f2acbbff1ac774c9679fab1eb45b160734b
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 extern HBITMAP BITMAP_LoadOEMBitmap( WORD id ); /* objects/bitmap.c */
42 HANDLE RSC_LoadResource(int instance, char *rsc_name, int type,
43 int *image_size_ret);
44 void RSC_LoadNameTable(void);
46 extern char *ProgramName;
49 /**********************************************************************
50 * RSC_LoadNameTable
52 #ifndef WINELIB
53 void
54 RSC_LoadNameTable()
56 struct resource_typeinfo_s typeinfo;
57 struct resource_nameinfo_s nameinfo;
58 unsigned short size_shift;
59 RESNAMTAB *top, *new;
60 char read_buf[1024];
61 char *p;
62 int i;
63 unsigned short len;
64 off_t rtoff;
65 off_t saved_pos;
67 top = NULL;
70 * Move to beginning of resource table.
72 rtoff = (ResourceFileInfo->mz_header->ne_offset +
73 ResourceFileInfo->ne_header->resource_tab_offset);
74 lseek(ResourceFd, rtoff, SEEK_SET);
77 * Read block size.
79 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
80 sizeof(size_shift))
82 return;
84 size_shift = CONV_SHORT(size_shift);
87 * Find resource.
89 typeinfo.type_id = 0xffff;
90 while (typeinfo.type_id != 0)
92 if (!load_typeinfo (ResourceFd, &typeinfo))
93 break;
95 if (typeinfo.type_id == 0)
96 break;
97 if (typeinfo.type_id == 0x800f)
99 for (i = 0; i < typeinfo.count; i++)
101 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
102 sizeof(nameinfo))
104 break;
107 saved_pos = lseek(ResourceFd, 0, SEEK_CUR);
108 lseek(ResourceFd, (long) nameinfo.offset << size_shift,
109 SEEK_SET);
110 read(ResourceFd, &len, sizeof(len));
111 while (len)
113 new = (RESNAMTAB *) GlobalQuickAlloc(sizeof(*new));
114 new->next = top;
115 top = new;
117 read(ResourceFd, &new->type_ord, 2);
118 read(ResourceFd, &new->id_ord, 2);
119 read(ResourceFd, read_buf, len - 6);
121 p = read_buf + strlen(read_buf) + 1;
122 strncpy(new->id, p, MAX_NAME_LENGTH);
123 new->id[MAX_NAME_LENGTH - 1] = '\0';
125 read(ResourceFd, &len, sizeof(len));
128 lseek(ResourceFd, saved_pos, SEEK_SET);
130 break;
132 else
134 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
138 ResourceFileInfo->resnamtab = top;
140 #endif /* WINELIB */
142 /**********************************************************************
143 * OpenResourceFile
146 OpenResourceFile(HANDLE instance)
148 struct w_files *w;
149 char *res_file;
151 if (ResourceInst == instance)
152 return ResourceFd;
154 w = GetFileInfo(instance);
155 if (w == NULL)
156 return -1;
157 ResourceFileInfo = w;
158 res_file = w->filename;
160 if (ResourceFd >= 0)
161 close(ResourceFd);
163 ResourceInst = instance;
164 ResourceFd = open (res_file, O_RDONLY);
165 #if 1
166 #ifndef WINELIB
167 if (w->resnamtab == (RESNAMTAB *) -1)
169 RSC_LoadNameTable();
171 #endif
172 #endif
174 #ifdef DEBUG_RESOURCE
175 printf("OpenResourceFile(%04X) // file='%s' hFile=%04X !\n",
176 instance, w->filename, ResourceFd);
177 #endif
178 return ResourceFd;
181 /**********************************************************************
182 * ConvertCoreBitmap
184 HBITMAP
185 ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
187 BITMAPINFO * bmpInfo;
188 HBITMAP hbitmap;
189 char * bits;
190 int i, size, n_colors;
192 n_colors = 1 << image->bcBitCount;
194 if (image->bcBitCount < 24)
196 size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);
197 bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
199 else
201 size = sizeof(BITMAPINFOHEADER);
202 bits = (char *) (image + 1);
204 bmpInfo = (BITMAPINFO *) malloc( size );
206 bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
207 bmpInfo->bmiHeader.biWidth = image->bcWidth;
208 bmpInfo->bmiHeader.biHeight = image->bcHeight;
209 bmpInfo->bmiHeader.biPlanes = image->bcPlanes;
210 bmpInfo->bmiHeader.biBitCount = image->bcBitCount;
211 bmpInfo->bmiHeader.biCompression = 0;
212 bmpInfo->bmiHeader.biSizeImage = 0;
213 bmpInfo->bmiHeader.biXPelsPerMeter = 0;
214 bmpInfo->bmiHeader.biYPelsPerMeter = 0;
215 bmpInfo->bmiHeader.biClrUsed = 0;
216 bmpInfo->bmiHeader.biClrImportant = 0;
218 if (image->bcBitCount < 24)
220 RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
221 RGBQUAD * newMap = bmpInfo->bmiColors;
222 for (i = 0; i < n_colors; i++, oldMap++, newMap++)
224 newMap->rgbRed = oldMap->rgbtRed;
225 newMap->rgbGreen = oldMap->rgbtGreen;
226 newMap->rgbBlue = oldMap->rgbtBlue;
227 newMap->rgbReserved = 0;
231 hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
232 bits, bmpInfo, DIB_RGB_COLORS );
233 free( bmpInfo );
234 return hbitmap;
237 /**********************************************************************
238 * ConvertInfoBitmap
240 HBITMAP
241 ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
243 char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
244 return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
245 bits, image, DIB_RGB_COLORS );
248 #ifndef WINELIB
249 load_typeinfo (int fd, struct resource_typeinfo_s *typeinfo)
251 return read (fd, typeinfo, sizeof (*typeinfo)) == sizeof (*typeinfo);
253 #endif
256 type_match(int type_id1, int type_id2, int fd, off_t off)
258 off_t old_pos;
259 unsigned char c;
260 size_t nbytes;
261 char name[256];
263 if (type_id1 == -1)
264 return 1;
265 if ((type_id1 & 0xffff0000) == 0) {
266 if ((type_id2 & 0x8000) == 0)
267 return 0;
268 return (type_id1 & 0x000f) == (type_id2 & 0x000f);
270 if ((type_id2 & 0x8000) != 0)
271 return 0;
272 #ifdef DEBUG_RESOURCE
273 printf("type_compare: type_id2=%04X !\n", type_id2);
274 #endif
275 old_pos = lseek(fd, 0, SEEK_CUR);
276 lseek(fd, off + type_id2, SEEK_SET);
277 read(fd, &c, 1);
278 nbytes = CONV_CHAR_TO_LONG (c);
279 #ifdef DEBUG_RESOURCE
280 printf("type_compare: namesize=%d\n", nbytes);
281 #endif
282 read(fd, name, nbytes);
283 lseek(fd, old_pos, SEEK_SET);
284 name[nbytes] = '\0';
285 #ifdef DEBUG_RESOURCE
286 printf("type_compare: name=`%s'\n", name);
287 #endif
288 return strcasecmp((char *) type_id1, name) == 0;
291 /**********************************************************************
292 * FindResourceByNumber
295 FindResourceByNumber(struct resource_nameinfo_s *result_p,
296 int type_id, int resource_id)
298 struct resource_typeinfo_s typeinfo;
299 struct resource_nameinfo_s nameinfo;
300 unsigned short size_shift;
301 int i;
302 off_t rtoff;
305 * Move to beginning of resource table.
307 rtoff = (ResourceFileInfo->mz_header->ne_offset +
308 ResourceFileInfo->ne_header->resource_tab_offset);
309 lseek(ResourceFd, rtoff, SEEK_SET);
312 * Read block size.
314 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
315 sizeof(size_shift))
317 printf("FindResourceByNumber (%s) bad block size !\n", resource_id);
318 return -1;
320 size_shift = CONV_SHORT(size_shift);
322 * Find resource.
324 for (;;) {
325 if (!load_typeinfo (ResourceFd, &typeinfo)){
326 printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id);
327 return -1;
329 #ifdef DEBUG_RESOURCE
330 printf("FindResourceByNumber type=%X count=%d searched=%d \n",
331 typeinfo.type_id, typeinfo.count, type_id);
332 #endif
333 if (typeinfo.type_id == 0) break;
334 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) {
336 for (i = 0; i < typeinfo.count; i++) {
337 #ifndef WINELIB
338 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
339 sizeof(nameinfo))
340 #else
341 if (!load_nameinfo (ResourceFd, &nameinfo))
342 #endif
344 printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id);
345 return -1;
347 #ifdef DEBUG_RESOURCE
348 printf("FindResource: search type=%X id=%X // type=%X id=%X\n",
349 type_id, resource_id, typeinfo.type_id, nameinfo.id);
350 #endif
351 if (nameinfo.id == resource_id) {
352 memcpy(result_p, &nameinfo, sizeof(nameinfo));
353 return size_shift;
357 else {
358 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
361 return -1;
364 /**********************************************************************
365 * FindResourceByName
368 FindResourceByName(struct resource_nameinfo_s *result_p,
369 int type_id, char *resource_name)
371 struct resource_typeinfo_s typeinfo;
372 struct resource_nameinfo_s nameinfo;
373 unsigned short size_shift;
374 off_t old_pos, new_pos;
375 unsigned char nbytes;
376 char name[256];
377 int i;
378 off_t rtoff;
381 * Check for loaded name table.
383 if (ResourceFileInfo->resnamtab != NULL)
385 RESNAMTAB *e;
387 for (e = ResourceFileInfo->resnamtab; e != NULL; e = e->next)
389 if (e->type_ord == (type_id & 0x000f) &&
390 strcasecmp(e->id, resource_name) == 0)
392 return FindResourceByNumber(result_p, type_id, e->id_ord);
396 return -1;
400 * Move to beginning of resource table.
402 rtoff = (ResourceFileInfo->mz_header->ne_offset +
403 ResourceFileInfo->ne_header->resource_tab_offset);
404 lseek(ResourceFd, rtoff, SEEK_SET);
407 * Read block size.
409 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
410 sizeof(size_shift))
412 printf("FindResourceByName (%s) bad block size !\n", resource_name);
413 return -1;
415 size_shift = CONV_SHORT (size_shift);
418 * Find resource.
420 for (;;)
422 if (!load_typeinfo (ResourceFd, &typeinfo))
424 printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name);
425 return -1;
427 #ifdef DEBUG_RESOURCE
428 printf("FindResourceByName typeinfo.type_id=%X count=%d type_id=%X\n",
429 typeinfo.type_id, typeinfo.count, type_id);
430 #endif
431 if (typeinfo.type_id == 0) break;
432 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff))
434 for (i = 0; i < typeinfo.count; i++)
436 #ifndef WINELIB
437 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
438 sizeof(nameinfo))
439 #else
440 if (!load_nameinfo (ResourceFd, &nameinfo))
441 #endif
443 printf("FindResourceByName (%s) bad nameinfo size !\n", resource_name);
444 return -1;
447 if ((nameinfo.id & 0x8000) != 0) continue;
449 #ifdef DEBUG_RESOURCE
450 printf("FindResourceByName // nameinfo.id=%04X !\n", nameinfo.id);
451 #endif
452 old_pos = lseek(ResourceFd, 0, SEEK_CUR);
453 new_pos = rtoff + nameinfo.id;
454 lseek(ResourceFd, new_pos, SEEK_SET);
455 read(ResourceFd, &nbytes, 1);
456 #ifdef DEBUG_RESOURCE
457 printf("FindResourceByName // namesize=%d !\n", nbytes);
458 #endif
459 nbytes = CONV_CHAR_TO_LONG (nbytes);
460 read(ResourceFd, name, nbytes);
461 lseek(ResourceFd, old_pos, SEEK_SET);
462 name[nbytes] = '\0';
463 #ifdef DEBUG_RESOURCE
464 printf("FindResourceByName type_id=%X (%d of %d) name='%s' resource_name='%s'\n",
465 typeinfo.type_id, i + 1, typeinfo.count,
466 name, resource_name);
467 #endif
468 if (strcasecmp(name, resource_name) == 0)
470 memcpy(result_p, &nameinfo, sizeof(nameinfo));
471 return size_shift;
475 else {
476 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
479 return -1;
483 /**********************************************************************
484 * GetRsrcCount [internal]
486 int GetRsrcCount(HINSTANCE hInst, int type_id)
488 struct resource_typeinfo_s typeinfo;
489 struct resource_nameinfo_s nameinfo;
490 unsigned short size_shift;
491 /* off_t old_pos, new_pos;
492 unsigned char nbytes;
493 char name[256]; */
494 int i;
495 off_t rtoff;
496 if (hInst == 0) return 0;
497 #ifdef DEBUG_RESOURCE
498 printf("GetRsrcCount hInst=%04X typename=%08X\n", hInst, type_id);
499 #endif
500 if (OpenResourceFile(hInst) < 0) return 0;
503 * Move to beginning of resource table.
505 rtoff = (ResourceFileInfo->mz_header->ne_offset +
506 ResourceFileInfo->ne_header->resource_tab_offset);
507 lseek(ResourceFd, rtoff, SEEK_SET);
509 * Read block size.
511 if (read(ResourceFd, &size_shift, sizeof(size_shift)) != sizeof(size_shift)) {
512 printf("GetRsrcCount // bad block size !\n");
513 return -1;
515 size_shift = CONV_SHORT (size_shift);
516 for (;;) {
517 if (!load_typeinfo (ResourceFd, &typeinfo)) {
518 printf("GetRsrcCount // bad typeinfo size !\n");
519 return 0;
521 #ifdef DEBUG_RESOURCE
522 printf("GetRsrcCount // typeinfo.type_id=%X count=%d type_id=%X\n",
523 typeinfo.type_id, typeinfo.count, type_id);
524 #endif
525 if (typeinfo.type_id == 0) break;
526 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) {
527 return typeinfo.count;
529 else {
530 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
533 return 0;
537 /**********************************************************************
538 * LoadIcon [USER.174]
540 HICON LoadIcon(HANDLE instance, LPSTR icon_name)
542 HICON hIcon;
543 HANDLE rsc_mem;
544 WORD *lp;
545 ICONDESCRIP *lpicodesc;
546 ICONALLOC *lpico;
547 int width, height;
548 BITMAPINFO *bmi;
549 BITMAPINFOHEADER *bih;
550 RGBQUAD *rgbq;
551 HBITMAP hBitMap;
552 HDC hMemDC;
553 HDC hMemDC2;
554 HDC hdc;
555 int i, j, image_size;
556 #ifdef DEBUG_RESOURCE
557 printf("LoadIcon: instance = %04x, name = %08x\n",
558 instance, icon_name);
559 #endif
561 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
562 if (instance == (HANDLE)NULL) instance = hSysRes;
563 rsc_mem = RSC_LoadResource(instance, icon_name, NE_RSCTYPE_GROUP_ICON,
564 &image_size);
565 if (rsc_mem == (HANDLE)NULL) {
566 printf("LoadIcon / Icon %04X not Found !\n", icon_name);
567 ReleaseDC(GetDesktopWindow(), hdc);
568 return 0;
570 lp = (WORD *)GlobalLock(rsc_mem);
571 if (lp == NULL) {
572 GlobalFree(rsc_mem);
573 ReleaseDC(GetDesktopWindow(), hdc);
574 return 0;
576 lpicodesc = (ICONDESCRIP *)(lp + 3);
577 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
578 if (hIcon == (HICON)NULL) {
579 GlobalFree(rsc_mem);
580 ReleaseDC(GetDesktopWindow(), hdc);
581 return 0;
583 lpico = (ICONALLOC *)GlobalLock(hIcon);
584 lpico->descriptor = *lpicodesc;
585 width = lpicodesc->Width;
586 height = lpicodesc->Height;
587 GlobalUnlock(rsc_mem);
588 GlobalFree(rsc_mem);
589 rsc_mem = RSC_LoadResource(instance,
590 MAKEINTRESOURCE(lpicodesc->icoDIBOffset),
591 NE_RSCTYPE_ICON, &image_size);
592 if (rsc_mem == (HANDLE)NULL) {
593 printf("LoadIcon / Icon %04X Bitmaps not Found !\n", icon_name);
594 ReleaseDC(GetDesktopWindow(), hdc);
595 return 0;
597 lp = (WORD *)GlobalLock(rsc_mem);
598 if (lp == NULL) {
599 GlobalFree(rsc_mem);
600 ReleaseDC(GetDesktopWindow(), hdc);
601 return 0;
603 bmi = (BITMAPINFO *)lp;
604 bih = (BITMAPINFOHEADER *)lp;
605 rgbq = &bmi->bmiColors[0];
606 bih->biHeight = bih->biHeight / 2;
608 printf("LoadIcon / image_size=%d width=%d height=%d bih->biBitCount=%d bih->biSizeImage=%ld\n",
609 image_size, width, height, bih->biBitCount, bih->biSizeImage);
611 if (bih->biSize == sizeof(BITMAPINFOHEADER))
612 lpico->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)bih);
613 else
614 lpico->hBitmap = 0;
615 bih->biBitCount = 1;
616 bih->biClrUsed = bih->biClrImportant = 2;
617 rgbq[0].rgbBlue = 0xFF;
618 rgbq[0].rgbGreen = 0xFF;
619 rgbq[0].rgbRed = 0xFF;
620 rgbq[0].rgbReserved = 0x00;
621 rgbq[1].rgbBlue = 0x00;
622 rgbq[1].rgbGreen = 0x00;
623 rgbq[1].rgbRed = 0x00;
624 rgbq[1].rgbReserved = 0x00;
625 if (bih->biSizeImage == 0) {
626 if (bih->biCompression != BI_RGB) {
627 printf("Unknown size for compressed Icon bitmap.\n");
628 GlobalFree(rsc_mem);
629 ReleaseDC(GetDesktopWindow(), hdc);
630 return 0;
632 bih->biSizeImage = (bih->biWidth * bih->biHeight * bih->biBitCount
633 + 7) / 8;
635 lpico->hBitMask = CreateDIBitmap(hdc, bih, CBM_INIT,
636 (LPSTR)lp + bih->biSizeImage - sizeof(BITMAPINFOHEADER) / 2 - 4,
637 (BITMAPINFO *)bih, DIB_RGB_COLORS );
638 GlobalUnlock(rsc_mem);
639 GlobalFree(rsc_mem);
640 hMemDC = CreateCompatibleDC(hdc);
641 hMemDC2 = CreateCompatibleDC(hdc);
642 SelectObject(hMemDC, lpico->hBitmap);
643 SelectObject(hMemDC2, lpico->hBitMask);
644 BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0, SRCINVERT);
645 DeleteDC(hMemDC);
646 DeleteDC(hMemDC2);
647 ReleaseDC(GetDesktopWindow(), hdc);
648 GlobalUnlock(hIcon);
649 #ifdef DEBUG_RESOURCE
650 printf("LoadIcon Alloc hIcon=%X\n", hIcon);
651 #endif
652 return hIcon;
656 /**********************************************************************
657 * DestroyIcon [USER.457]
659 BOOL DestroyIcon(HICON hIcon)
661 ICONALLOC *lpico;
662 if (hIcon == (HICON)NULL) return FALSE;
663 lpico = (ICONALLOC *)GlobalLock(hIcon);
664 if (lpico->hBitmap != (HBITMAP)NULL) DeleteObject(lpico->hBitmap);
665 GlobalFree(hIcon);
666 return TRUE;
670 /**********************************************************************
671 * LoadAccelerators [USER.177]
673 HANDLE LoadAccelerators(HANDLE instance, LPSTR lpTableName)
675 HANDLE hAccel;
676 HANDLE rsc_mem;
677 BYTE *lp;
678 ACCELHEADER *lpAccelTbl;
679 int i, image_size, n;
680 #ifdef DEBUG_ACCEL
681 if (((LONG)lpTableName & 0xFFFF0000L) == 0L)
682 printf("LoadAccelerators: instance = %04X, name = %08X\n",
683 instance, lpTableName);
684 else
685 printf("LoadAccelerators: instance = %04X, name = '%s'\n",
686 instance, lpTableName);
687 #endif
688 if (instance == (HANDLE)NULL) instance = hSysRes;
689 rsc_mem = RSC_LoadResource(instance, lpTableName, NE_RSCTYPE_ACCELERATOR,
690 &image_size);
691 if (rsc_mem == (HANDLE)NULL) {
692 printf("LoadAccelerators / AccelTable %04X not Found !\n", lpTableName);
693 return 0;
695 lp = (BYTE *)GlobalLock(rsc_mem);
696 if (lp == NULL) {
697 GlobalFree(rsc_mem);
698 return 0;
700 #ifdef DEBUG_ACCEL
701 printf("LoadAccelerators / image_size=%d\n", image_size);
702 #endif
703 n = image_size/5;
704 hAccel = GlobalAlloc(GMEM_MOVEABLE,
705 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
706 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
707 lpAccelTbl->wCount = 0;
708 for (i = 0; i < n; i++) {
709 lpAccelTbl->tbl[i].type = *(lp++);
710 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
711 lp += 2;
712 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
713 lp += 2;
714 if (lpAccelTbl->tbl[i].wEvent == 0) break;
715 #ifdef DEBUG_ACCEL
716 printf("Accelerator #%u / event=%04X id=%04X type=%02X \n",
717 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
718 lpAccelTbl->tbl[i].type);
719 #endif
720 lpAccelTbl->wCount++;
722 GlobalUnlock(hAccel);
723 GlobalUnlock(rsc_mem);
724 GlobalFree(rsc_mem);
725 return hAccel;
728 /**********************************************************************
729 * TranslateAccelerator [USER.178]
731 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
733 ACCELHEADER *lpAccelTbl;
734 int i, image_size;
735 if (hAccel == 0 || msg == NULL) return 0;
736 if (msg->message != WM_KEYDOWN &&
737 msg->message != WM_KEYUP &&
738 msg->message != WM_CHAR) return 0;
739 #ifdef DEBUG_ACCEL
740 printf("TranslateAccelerators hAccel=%04X !\n", hAccel);
741 #endif
742 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
743 for (i = 0; i < lpAccelTbl->wCount; i++) {
744 if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
745 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
746 msg->message == WM_KEYDOWN) {
747 if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
748 !(GetKeyState(VK_SHIFT) & 0xf)) {
749 GlobalUnlock(hAccel);
750 return 0;
752 if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
753 !(GetKeyState(VK_CONTROL) & 0xf)) {
754 GlobalUnlock(hAccel);
755 return 0;
757 if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
758 !(GetKeyState(VK_MENU) & 0xf)) {
759 GlobalUnlock(hAccel);
760 return 0;
762 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
763 GlobalUnlock(hAccel);
764 return 1;
766 if (msg->message == WM_KEYUP) return 1;
768 else {
769 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
770 msg->message == WM_CHAR) {
771 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
772 GlobalUnlock(hAccel);
773 return 1;
777 GlobalUnlock(hAccel);
778 return 0;
781 /**********************************************************************
782 * FindResource [KERNEL.60]
784 HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name)
786 RESOURCE *r;
787 HANDLE rh;
788 int type;
790 if (instance == 0)
791 return 0;
793 #ifdef DEBUG_RESOURCE
794 printf("FindResource hInst=%04X typename=%08X resname=%08X\n",
795 instance, type_name, resource_name);
796 #endif
797 if (OpenResourceFile(instance) < 0)
798 return 0;
800 rh = GlobalAlloc(GMEM_MOVEABLE, sizeof(*r));
801 if (rh == 0)
802 return 0;
803 r = (RESOURCE *)GlobalLock(rh);
805 r->next = Top;
806 Top = r;
807 r->info_mem = rh;
808 r->rsc_mem = 0;
810 if (((int) type_name & 0xffff0000) == 0)
812 type = (int) type_name;
814 else if (type_name[0] == '\0')
816 type = -1;
818 else if (type_name[0] == '#')
820 type = atoi(type_name + 1);
822 else
824 type = (int) type_name;
826 if (((int) resource_name & 0xffff0000) == 0)
828 r->size_shift = FindResourceByNumber(&r->nameinfo, type,
829 (int) resource_name | 0x8000);
831 else if (resource_name[0] == '\0')
833 r->size_shift = FindResourceByNumber(&r->nameinfo, type, -1);
835 else if (resource_name[0] == '#')
837 r->size_shift = FindResourceByNumber(&r->nameinfo, type,
838 atoi(resource_name + 1));
840 else
842 r->size_shift = FindResourceByName(&r->nameinfo, type, resource_name);
845 if (r->size_shift == -1)
847 printf("FindResource hInst=%04X typename=%08X resname=%08X not found!\n",
848 instance, type_name, resource_name);
849 GlobalFree(rh);
850 return 0;
853 return rh;
856 /**********************************************************************
857 * AllocResource [KERNEL.66]
859 HANDLE AllocResource(HANDLE instance, HANDLE hResInfo, DWORD dwSize)
861 RESOURCE *r;
862 int image_size;
864 if (instance == 0)
865 return 0;
867 if (OpenResourceFile(instance) < 0)
868 return 0;
870 r = (RESOURCE *)GlobalLock(hResInfo);
871 if (r == NULL)
872 return 0;
874 image_size = r->nameinfo.length << r->size_shift;
876 if (dwSize == 0)
877 r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
878 else
879 r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, dwSize);
881 GlobalUnlock(hResInfo);
883 return r->rsc_mem;
886 /**********************************************************************
887 * LoadResource [KERNEL.61]
889 HANDLE LoadResource(HANDLE instance, HANDLE hResInfo)
891 RESOURCE *r;
892 int image_size;
893 void *image;
894 HANDLE h;
896 if (instance == 0)
897 return 0;
899 if (OpenResourceFile(instance) < 0)
900 return 0;
902 r = (RESOURCE *)GlobalLock(hResInfo);
903 if (r == NULL)
904 return 0;
906 image_size = r->nameinfo.length << r->size_shift;
908 h = r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
909 image = GlobalLock(h);
911 lseek(ResourceFd, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET);
913 if (image == NULL || read(ResourceFd, image, image_size) != image_size)
915 GlobalFree(h);
916 GlobalUnlock(hResInfo);
917 return 0;
920 GlobalUnlock(h);
921 GlobalUnlock(hResInfo);
922 return h;
925 /**********************************************************************
926 * LockResource [KERNEL.62]
928 LPSTR LockResource(HANDLE hResData)
930 return GlobalLock(hResData);
933 /**********************************************************************
934 * FreeResource [KERNEL.63]
936 HANDLE FreeResource(HANDLE hResData)
938 RESOURCE *r, *rp;
940 for (r = rp = Top; r != NULL; r = r->next)
942 if (r->info_mem == hResData)
944 if (rp != NULL)
945 rp->next = r->next;
946 else
947 Top = r->next;
949 GlobalFree(r->rsc_mem);
950 GlobalFree(r->info_mem);
951 return 0;
953 rp = r;
956 return hResData;
959 /**********************************************************************
960 * AccessResource [KERNEL.64]
962 int AccessResource(HANDLE instance, HANDLE hResInfo)
964 int resfile, image_size;
965 RESOURCE *r;
967 /* #ifdef DEBUG_RESOURCE */
968 printf("AccessResource(%04X, %04X);\n", instance, hResInfo);
969 /* #endif */
971 if (instance == 0)
972 return -1;
974 if ((resfile = OpenResourceFile(instance)) < 0)
975 return -1;
977 if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
978 return -1;
980 lseek(resfile, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET);
981 GlobalUnlock(hResInfo);
983 return dup(resfile);
986 /**********************************************************************
987 * SizeofResource [KERNEL.65]
989 WORD SizeofResource(HANDLE instance, HANDLE hResInfo)
991 int image_size;
992 RESOURCE *r;
994 /* #ifdef DEBUG_RESOURCE */
995 printf("SizeofResource(%04X, %04X);\n", instance, hResInfo);
996 /* #endif */
998 if (instance == 0)
999 return 0;
1001 if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
1002 return 0;
1004 image_size = r->nameinfo.length << r->size_shift;
1006 GlobalUnlock(hResInfo);
1008 /* #ifdef DEBUG_RESOURCE */
1009 printf("SizeofResource return %d\n", image_size);
1010 /* #endif */
1012 return image_size;
1015 /**********************************************************************
1016 * RSC_LoadResource
1018 HANDLE
1019 RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret)
1021 struct resource_nameinfo_s nameinfo;
1022 HANDLE hmem;
1023 void *image;
1024 int image_size;
1025 int size_shift;
1028 * Built-in resources
1030 if (instance == 0)
1032 return 0;
1034 else if (OpenResourceFile(instance) < 0)
1035 return 0;
1038 * Get resource by ordinal
1040 if (((int) rsc_name & 0xffff0000) == 0)
1042 size_shift = FindResourceByNumber(&nameinfo, type,
1043 (int) rsc_name | 0x8000);
1046 * Get resource by name
1048 else
1050 size_shift = FindResourceByName(&nameinfo, type, rsc_name);
1052 if (size_shift == -1) {
1053 if ((LONG)rsc_name >= 0x00010000L)
1054 printf("RSC_LoadResource inst (%x)/ Resource '%s' not Found !\n", instance, rsc_name);
1055 else
1056 printf("RSC_LoadResource inst (%x)/ Resource '0x%X' not Found !\n", instance, rsc_name);
1057 return 0;
1060 * Read resource.
1062 lseek(ResourceFd, ((int) nameinfo.offset << size_shift), SEEK_SET);
1064 image_size = nameinfo.length << size_shift;
1065 if (image_size_ret != NULL)
1066 *image_size_ret = image_size;
1067 hmem = GlobalAlloc(GMEM_MOVEABLE, image_size);
1068 image = GlobalLinearLock(hmem);
1069 if (image == NULL || read(ResourceFd, image, image_size) != image_size)
1071 GlobalFree(hmem);
1072 return 0;
1075 GlobalLinearUnlock(hmem);
1076 return hmem;
1079 /**********************************************************************
1080 * LoadString
1083 LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
1085 HANDLE hmem;
1086 int rsc_size;
1087 unsigned char *p;
1088 int string_num;
1089 int i;
1091 #ifdef DEBUG_RESOURCE
1092 printf("LoadString: instance = %04x, id = %d, "
1093 "buffer = %08x, length = %d\n",
1094 instance, resource_id, buffer, buflen);
1095 #endif
1097 hmem = RSC_LoadResource(instance, (char *) ((resource_id >> 4) + 1),
1098 NE_RSCTYPE_STRING, &rsc_size);
1099 if (hmem == 0)
1100 return 0;
1102 p = GlobalLock(hmem);
1103 string_num = resource_id & 0x000f;
1104 for (i = 0; i < string_num; i++)
1105 p += *p + 1;
1107 i = MIN(buflen - 1, *p);
1108 if (i > 0) {
1109 memcpy(buffer, p + 1, i);
1110 buffer[i] = '\0';
1112 else {
1113 if (buflen > 1) {
1114 buffer[0] = '\0';
1115 return 0;
1117 printf("LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
1118 printf("LoadString // and try to obtain string '%s'\n", p + 1);
1120 GlobalFree(hmem);
1122 #ifdef DEBUG_RESOURCE
1123 printf("LoadString // '%s' copied !\n", buffer);
1124 #endif
1125 return i;
1128 /**********************************************************************
1129 * RSC_LoadMenu
1131 HANDLE
1132 RSC_LoadMenu(HANDLE instance, LPSTR menu_name)
1134 #ifdef DEBUG_RESOURCE
1135 printf("RSC_LoadMenu: instance = %04x, name = '%s'\n",
1136 instance, menu_name);
1137 #endif
1138 return RSC_LoadResource(instance, menu_name, NE_RSCTYPE_MENU, NULL);
1141 /**********************************************************************
1142 * LoadBitmap
1144 HBITMAP
1145 LoadBitmap(HANDLE instance, LPSTR bmp_name)
1147 HBITMAP hbitmap;
1148 HANDLE rsc_mem;
1149 HDC hdc;
1150 long *lp;
1151 int image_size;
1152 int size;
1154 #ifdef DEBUG_RESOURCE
1155 printf("LoadBitmap: instance = %04x, name = %08x\n",
1156 instance, bmp_name);
1157 #endif
1158 if (!instance)
1160 /* Try to create an OEM bitmap */
1161 hbitmap = BITMAP_LoadOEMBitmap( ((int)bmp_name) & 0xffff );
1162 if (hbitmap) return hbitmap;
1163 /* Failed -> load it from sysres.dll */
1164 instance = hSysRes;
1167 rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP,
1168 &image_size);
1169 if (rsc_mem == (HANDLE)NULL) {
1170 printf("LoadBitmap / BitMap %04X not Found !\n", bmp_name);
1171 return 0;
1173 lp = (long *) GlobalLinearLock(rsc_mem);
1174 if (!(hdc = GetDC(0))) lp = NULL;
1175 if (lp == NULL)
1177 GlobalFree(rsc_mem);
1178 return 0;
1180 size = CONV_LONG (*lp);
1181 if (size == sizeof(BITMAPCOREHEADER)){
1182 CONV_BITMAPCOREHEADER (lp);
1183 hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp );
1184 } else if (size == sizeof(BITMAPINFOHEADER)){
1185 CONV_BITMAPINFO (lp);
1186 hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
1187 } else hbitmap = 0;
1188 GlobalFree(rsc_mem);
1189 ReleaseDC( 0, hdc );
1190 return hbitmap;
1193 /**********************************************************************
1194 * CreateIcon [USER.407]
1196 HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight,
1197 BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits,
1198 LPSTR lpXORbits)
1200 HICON hIcon;
1201 ICONALLOC *lpico;
1203 #ifdef DEBUG_RESOURCE
1204 printf("CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n",
1205 hInstance, nWidth, nHeight);
1206 printf(" nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel);
1207 printf(" lpANDbits= %04x, lpXORbits = %04x, \n",lpANDbits, lpXORbits);
1208 #endif
1210 if (hInstance == (HANDLE)NULL) {
1211 printf("CreateIcon / hInstance %04x not Found!\n",hInstance);
1212 return 0;
1214 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
1215 if (hIcon == (HICON)NULL) {
1216 printf("Can't allocate memory for Icon in CreateIcon\n");
1217 return 0;
1219 lpico= (ICONALLOC *)GlobalLock(hIcon);
1221 lpico->descriptor.Width=nWidth;
1222 lpico->descriptor.Height=nHeight;
1223 lpico->descriptor.ColorCount=16; /* Dummy Value */
1224 lpico->descriptor.Reserved1=0;
1225 lpico->descriptor.Reserved2=nPlanes;
1226 lpico->descriptor.Reserved3=nWidth*nHeight;
1228 /* either nPlanes and/or nBitCount is set to one */
1229 lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel;
1230 lpico->descriptor.icoDIBOffset=0;
1232 if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel,
1233 lpXORbits)) ) {
1234 printf("CreateIcon: couldn't create the XOR bitmap\n");
1235 return(0);
1238 /* the AND BitMask is always monochrome */
1239 if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) {
1240 printf("CreateIcon: couldn't create the AND bitmap\n");
1241 return(0);
1244 GlobalUnlock(hIcon);
1245 #ifdef DEBUG_RESOURCE
1246 printf("CreateIcon Alloc hIcon=%X\n", hIcon);
1247 #endif
1248 return hIcon;