Release 940510
[wine/multimedia.git] / loader / resource.c
blobdbd7d92588f1b372abe4402c37644d854c0687bd
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"
20 /* #define DEBUG_RESOURCE */
22 #define MIN(a,b) ((a) < (b) ? (a) : (b))
24 typedef struct resource_s
26 struct resource_s *next;
27 HANDLE info_mem;
28 int size_shift;
29 struct resource_nameinfo_s nameinfo;
30 HANDLE rsc_mem;
31 } RESOURCE;
33 static int ResourceFd = -1;
34 static HANDLE ResourceInst = 0;
35 static struct w_files *ResourceFileInfo = NULL;
36 static RESOURCE *Top = NULL;
37 extern HINSTANCE hSysRes;
39 HANDLE RSC_LoadResource(int instance, char *rsc_name, int type,
40 int *image_size_ret);
41 void RSC_LoadNameTable(void);
43 extern char *ProgramName;
46 /**********************************************************************
47 * RSC_LoadNameTable
49 #ifndef WINELIB
50 void
51 RSC_LoadNameTable()
53 struct resource_typeinfo_s typeinfo;
54 struct resource_nameinfo_s nameinfo;
55 unsigned short size_shift;
56 RESNAMTAB *top, *new;
57 char read_buf[1024];
58 char *p;
59 int i;
60 unsigned short len;
61 off_t rtoff;
62 off_t saved_pos;
64 top = NULL;
67 * Move to beginning of resource table.
69 rtoff = (ResourceFileInfo->mz_header->ne_offset +
70 ResourceFileInfo->ne_header->resource_tab_offset);
71 lseek(ResourceFd, rtoff, SEEK_SET);
74 * Read block size.
76 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
77 sizeof(size_shift))
79 return;
81 size_shift = CONV_SHORT(size_shift);
84 * Find resource.
86 typeinfo.type_id = 0xffff;
87 while (typeinfo.type_id != 0)
89 if (!load_typeinfo (ResourceFd, &typeinfo))
90 break;
92 if (typeinfo.type_id == 0)
93 break;
94 if (typeinfo.type_id == 0x800f)
96 for (i = 0; i < typeinfo.count; i++)
98 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
99 sizeof(nameinfo))
101 break;
104 saved_pos = lseek(ResourceFd, 0, SEEK_CUR);
105 lseek(ResourceFd, (long) nameinfo.offset << size_shift,
106 SEEK_SET);
107 read(ResourceFd, &len, sizeof(len));
108 while (len)
110 new = (RESNAMTAB *) GlobalQuickAlloc(sizeof(*new));
111 new->next = top;
112 top = new;
114 read(ResourceFd, &new->type_ord, 2);
115 read(ResourceFd, &new->id_ord, 2);
116 read(ResourceFd, read_buf, len - 6);
118 p = read_buf + strlen(read_buf) + 1;
119 strncpy(new->id, p, MAX_NAME_LENGTH);
120 new->id[MAX_NAME_LENGTH - 1] = '\0';
122 read(ResourceFd, &len, sizeof(len));
125 lseek(ResourceFd, saved_pos, SEEK_SET);
127 break;
129 else
131 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
135 ResourceFileInfo->resnamtab = top;
137 #endif /* WINELIB */
139 /**********************************************************************
140 * OpenResourceFile
143 OpenResourceFile(HANDLE instance)
145 struct w_files *w;
146 char *res_file;
148 if (ResourceInst == instance)
149 return ResourceFd;
151 w = GetFileInfo(instance);
152 if (w == NULL)
153 return -1;
154 ResourceFileInfo = w;
155 res_file = w->filename;
157 if (ResourceFd >= 0)
158 close(ResourceFd);
160 ResourceInst = instance;
161 ResourceFd = open (res_file, O_RDONLY);
162 #if 1
163 #ifndef WINELIB
164 if (w->resnamtab == (RESNAMTAB *) -1)
166 RSC_LoadNameTable();
168 #endif
169 #endif
171 #ifdef DEBUG_RESOURCE
172 printf("OpenResourceFile(%04X) // file='%s' hFile=%04X !\n",
173 instance, w->filename, ResourceFd);
174 #endif
175 return ResourceFd;
178 /**********************************************************************
179 * ConvertCoreBitmap
181 HBITMAP
182 ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
184 BITMAPINFO * bmpInfo;
185 HBITMAP hbitmap;
186 char * bits;
187 int i, size, n_colors;
189 n_colors = 1 << image->bcBitCount;
191 if (image->bcBitCount < 24)
193 size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);
194 bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
196 else
198 size = sizeof(BITMAPINFOHEADER);
199 bits = (char *) (image + 1);
201 bmpInfo = (BITMAPINFO *) malloc( size );
203 bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
204 bmpInfo->bmiHeader.biWidth = image->bcWidth;
205 bmpInfo->bmiHeader.biHeight = image->bcHeight;
206 bmpInfo->bmiHeader.biPlanes = image->bcPlanes;
207 bmpInfo->bmiHeader.biBitCount = image->bcBitCount;
208 bmpInfo->bmiHeader.biCompression = 0;
209 bmpInfo->bmiHeader.biSizeImage = 0;
210 bmpInfo->bmiHeader.biXPelsPerMeter = 0;
211 bmpInfo->bmiHeader.biYPelsPerMeter = 0;
212 bmpInfo->bmiHeader.biClrUsed = 0;
213 bmpInfo->bmiHeader.biClrImportant = 0;
215 if (image->bcBitCount < 24)
217 RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
218 RGBQUAD * newMap = bmpInfo->bmiColors;
219 for (i = 0; i < n_colors; i++, oldMap++, newMap++)
221 newMap->rgbRed = oldMap->rgbtRed;
222 newMap->rgbGreen = oldMap->rgbtGreen;
223 newMap->rgbBlue = oldMap->rgbtBlue;
224 newMap->rgbReserved = 0;
228 hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
229 bits, bmpInfo, DIB_RGB_COLORS );
230 free( bmpInfo );
231 return hbitmap;
234 /**********************************************************************
235 * ConvertInfoBitmap
237 HBITMAP
238 ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
240 char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
241 return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
242 bits, image, DIB_RGB_COLORS );
245 #ifndef WINELIB
246 load_typeinfo (int fd, struct resource_typeinfo_s *typeinfo)
248 return read (fd, typeinfo, sizeof (*typeinfo)) == sizeof (*typeinfo);
250 #endif
251 /**********************************************************************
252 * FindResourceByNumber
255 FindResourceByNumber(struct resource_nameinfo_s *result_p,
256 int type_id, int resource_id)
258 struct resource_typeinfo_s typeinfo;
259 struct resource_nameinfo_s nameinfo;
260 unsigned short size_shift;
261 int i;
262 off_t rtoff;
265 * Move to beginning of resource table.
267 rtoff = (ResourceFileInfo->mz_header->ne_offset +
268 ResourceFileInfo->ne_header->resource_tab_offset);
269 lseek(ResourceFd, rtoff, SEEK_SET);
272 * Read block size.
274 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
275 sizeof(size_shift))
277 printf("FindResourceByNumber (%s) bad block size !\n", resource_id);
278 return -1;
280 size_shift = CONV_SHORT(size_shift);
282 * Find resource.
284 typeinfo.type_id = 0xffff;
285 while (typeinfo.type_id != 0) {
286 if (!load_typeinfo (ResourceFd, &typeinfo)){
287 printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id);
288 return -1;
290 #ifdef DEBUG_RESOURCE
291 printf("FindResourceByNumber type=%X count=%d searched=%d \n",
292 typeinfo.type_id, typeinfo.count, type_id);
293 #endif
294 if (typeinfo.type_id == 0) break;
295 if (typeinfo.type_id == type_id || type_id == -1) {
296 for (i = 0; i < typeinfo.count; i++) {
297 #ifndef WINELIB
298 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
299 sizeof(nameinfo))
300 #else
301 if (!load_nameinfo (ResourceFd, &nameinfo))
302 #endif
304 printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id);
305 return -1;
307 #ifdef DEBUG_RESOURCE
308 printf("FindResource: search type=%X id=%X // type=%X id=%X\n",
309 type_id, resource_id, typeinfo.type_id, nameinfo.id);
310 #endif
311 if (nameinfo.id == resource_id) {
312 memcpy(result_p, &nameinfo, sizeof(nameinfo));
313 return size_shift;
317 else {
318 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
321 return -1;
324 /**********************************************************************
325 * FindResourceByName
328 FindResourceByName(struct resource_nameinfo_s *result_p,
329 int type_id, char *resource_name)
331 struct resource_typeinfo_s typeinfo;
332 struct resource_nameinfo_s nameinfo;
333 unsigned short size_shift;
334 off_t old_pos, new_pos;
335 unsigned char nbytes;
336 char name[256];
337 int i;
338 off_t rtoff;
341 * Check for loaded name table.
343 if (ResourceFileInfo->resnamtab != NULL)
345 RESNAMTAB *e;
347 for (e = ResourceFileInfo->resnamtab; e != NULL; e = e->next)
349 if (e->type_ord == (type_id & 0x000f) &&
350 strcasecmp(e->id, resource_name) == 0)
352 return FindResourceByNumber(result_p, type_id, e->id_ord);
356 return -1;
360 * Move to beginning of resource table.
362 rtoff = (ResourceFileInfo->mz_header->ne_offset +
363 ResourceFileInfo->ne_header->resource_tab_offset);
364 lseek(ResourceFd, rtoff, SEEK_SET);
367 * Read block size.
369 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
370 sizeof(size_shift))
372 printf("FindResourceByName (%s) bad block size !\n", resource_name);
373 return -1;
375 size_shift = CONV_SHORT (size_shift);
378 * Find resource.
380 typeinfo.type_id = 0xffff;
381 while (typeinfo.type_id != 0)
383 if (!load_typeinfo (ResourceFd, &typeinfo))
385 printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name);
386 return -1;
388 #ifdef DEBUG_RESOURCE
389 printf("FindResourceByName typeinfo.type_id=%X count=%d type_id=%X\n",
390 typeinfo.type_id, typeinfo.count, type_id);
391 #endif
392 if (typeinfo.type_id == 0) break;
393 if (typeinfo.type_id == type_id || type_id == -1)
395 for (i = 0; i < typeinfo.count; i++)
397 #ifndef WINELIB
398 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
399 sizeof(nameinfo))
400 #else
401 if (!load_nameinfo (ResourceFd, &nameinfo))
402 #endif
404 printf("FindResourceByName (%s) bad nameinfo size !\n", resource_name);
405 return -1;
408 if ((nameinfo.id & 0x8000) != 0) continue;
410 #ifdef DEBUG_RESOURCE
411 printf("FindResourceByName // nameinfo.id=%04X !\n", nameinfo.id);
412 #endif
413 old_pos = lseek(ResourceFd, 0, SEEK_CUR);
414 new_pos = rtoff + nameinfo.id;
415 lseek(ResourceFd, new_pos, SEEK_SET);
416 read(ResourceFd, &nbytes, 1);
417 #ifdef DEBUG_RESOURCE
418 printf("FindResourceByName // namesize=%d !\n", nbytes);
419 #endif
420 nbytes = CONV_CHAR_TO_LONG (nbytes);
421 read(ResourceFd, name, nbytes);
422 lseek(ResourceFd, old_pos, SEEK_SET);
423 name[nbytes] = '\0';
424 #ifdef DEBUG_RESOURCE
425 printf("FindResourceByName type_id=%X (%d of %d) name='%s' resource_name='%s'\n",
426 typeinfo.type_id, i + 1, typeinfo.count,
427 name, resource_name);
428 #endif
429 if (strcasecmp(name, resource_name) == 0)
431 memcpy(result_p, &nameinfo, sizeof(nameinfo));
432 return size_shift;
436 else {
437 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
440 return -1;
444 /**********************************************************************
445 * LoadIcon [USER.174]
447 HICON LoadIcon(HANDLE instance, LPSTR icon_name)
449 HICON hIcon;
450 HANDLE rsc_mem;
451 WORD *lp;
452 ICONDESCRIP *lpicodesc;
453 ICONALLOC *lpico;
454 int width, height;
455 BITMAPINFO *bmi;
456 BITMAPINFOHEADER *bih;
457 RGBQUAD *rgbq;
458 HBITMAP hBitMap;
459 HDC hMemDC;
460 HDC hMemDC2;
461 HDC hdc;
462 int i, j, image_size;
463 #ifdef DEBUG_RESOURCE
464 printf("LoadIcon: instance = %04x, name = %08x\n",
465 instance, icon_name);
466 #endif
468 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
469 if (instance == (HANDLE)NULL) instance = hSysRes;
470 rsc_mem = RSC_LoadResource(instance, icon_name, NE_RSCTYPE_GROUP_ICON,
471 &image_size);
472 if (rsc_mem == (HANDLE)NULL) {
473 printf("LoadIcon / Icon %04X not Found !\n", icon_name);
474 ReleaseDC(GetDesktopWindow(), hdc);
475 return 0;
477 lp = (WORD *)GlobalLock(rsc_mem);
478 if (lp == NULL) {
479 GlobalFree(rsc_mem);
480 ReleaseDC(GetDesktopWindow(), hdc);
481 return 0;
483 lpicodesc = (ICONDESCRIP *)(lp + 3);
484 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
485 if (hIcon == (HICON)NULL) {
486 GlobalFree(rsc_mem);
487 ReleaseDC(GetDesktopWindow(), hdc);
488 return 0;
490 lpico = (ICONALLOC *)GlobalLock(hIcon);
491 lpico->descriptor = *lpicodesc;
492 width = lpicodesc->Width;
493 height = lpicodesc->Height;
494 GlobalUnlock(rsc_mem);
495 GlobalFree(rsc_mem);
496 rsc_mem = RSC_LoadResource(instance,
497 MAKEINTRESOURCE(lpicodesc->icoDIBOffset),
498 NE_RSCTYPE_ICON, &image_size);
499 if (rsc_mem == (HANDLE)NULL) {
500 printf("LoadIcon / Icon %04X Bitmaps not Found !\n", icon_name);
501 ReleaseDC(GetDesktopWindow(), hdc);
502 return 0;
504 lp = (WORD *)GlobalLock(rsc_mem);
505 if (lp == NULL) {
506 GlobalFree(rsc_mem);
507 ReleaseDC(GetDesktopWindow(), hdc);
508 return 0;
510 bmi = (BITMAPINFO *)lp;
511 bih = (BITMAPINFOHEADER *)lp;
512 rgbq = &bmi->bmiColors[0];
513 bih->biHeight = bih->biHeight / 2;
515 printf("LoadIcon / image_size=%d width=%d height=%d bih->biBitCount=%d bih->biSizeImage=%ld\n",
516 image_size, width, height, bih->biBitCount, bih->biSizeImage);
518 if (bih->biSize == sizeof(BITMAPINFOHEADER))
519 lpico->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)bih);
520 else
521 lpico->hBitmap = 0;
522 bih->biBitCount = 1;
523 bih->biClrUsed = bih->biClrImportant = 2;
524 rgbq[0].rgbBlue = 0xFF;
525 rgbq[0].rgbGreen = 0xFF;
526 rgbq[0].rgbRed = 0xFF;
527 rgbq[0].rgbReserved = 0x00;
528 rgbq[1].rgbBlue = 0x00;
529 rgbq[1].rgbGreen = 0x00;
530 rgbq[1].rgbRed = 0x00;
531 rgbq[1].rgbReserved = 0x00;
532 lpico->hBitMask = CreateDIBitmap(hdc, bih, CBM_INIT,
533 (LPSTR)lp + bih->biSizeImage - sizeof(BITMAPINFOHEADER) / 2 - 4,
534 (BITMAPINFO *)bih, DIB_RGB_COLORS );
535 GlobalUnlock(rsc_mem);
536 GlobalFree(rsc_mem);
537 hMemDC = CreateCompatibleDC(hdc);
538 hMemDC2 = CreateCompatibleDC(hdc);
539 SelectObject(hMemDC, lpico->hBitmap);
540 SelectObject(hMemDC2, lpico->hBitMask);
541 BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0, SRCINVERT);
542 DeleteDC(hMemDC);
543 DeleteDC(hMemDC2);
544 ReleaseDC(GetDesktopWindow(), hdc);
545 GlobalUnlock(hIcon);
546 #ifdef DEBUG_RESOURCE
547 printf("LoadIcon Alloc hIcon=%X\n", hIcon);
548 #endif
549 return hIcon;
553 /**********************************************************************
554 * DestroyIcon [USER.457]
556 BOOL DestroyIcon(HICON hIcon)
558 ICONALLOC *lpico;
559 if (hIcon == (HICON)NULL) return FALSE;
560 lpico = (ICONALLOC *)GlobalLock(hIcon);
561 if (lpico->hBitmap != (HBITMAP)NULL) DeleteObject(lpico->hBitmap);
562 GlobalFree(hIcon);
563 return TRUE;
567 /**********************************************************************
568 * LoadAccelerators [USER.177]
570 HANDLE LoadAccelerators(HANDLE instance, LPSTR lpTableName)
572 HANDLE hAccel;
573 HANDLE rsc_mem;
574 BYTE *lp;
575 ACCELHEADER *lpAccelTbl;
576 int i, image_size;
577 #ifdef DEBUG_ACCEL
578 if (((LONG)lpTableName & 0xFFFF0000L) == 0L)
579 printf("LoadAccelerators: instance = %04X, name = %08X\n",
580 instance, lpTableName);
581 else
582 printf("LoadAccelerators: instance = %04X, name = '%s'\n",
583 instance, lpTableName);
584 #endif
585 if (instance == (HANDLE)NULL) instance = hSysRes;
586 rsc_mem = RSC_LoadResource(instance, lpTableName, NE_RSCTYPE_ACCELERATOR,
587 &image_size);
588 if (rsc_mem == (HANDLE)NULL) {
589 printf("LoadAccelerators / AccelTable %04X not Found !\n", lpTableName);
590 return 0;
592 lp = (BYTE *)GlobalLock(rsc_mem);
593 if (lp == NULL) {
594 GlobalFree(rsc_mem);
595 return 0;
597 #ifdef DEBUG_ACCEL
598 printf("LoadAccelerators / image_size=%d\n", image_size);
599 #endif
600 hAccel = GlobalAlloc(GMEM_MOVEABLE,
601 sizeof(ACCELHEADER) + sizeof(ACCELENTRY) + image_size);
602 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
603 lpAccelTbl->wCount = 0;
604 for (i = 0; ; i++) {
605 lpAccelTbl->tbl[i].type = *(lp++);
606 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
607 lp += 2;
608 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
609 lp += 2;
610 if (lpAccelTbl->tbl[i].wEvent == 0) break;
611 #ifdef DEBUG_ACCEL
612 printf("Accelerator #%u / event=%04X id=%04X type=%02X \n",
613 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
614 lpAccelTbl->tbl[i].type);
615 #endif
616 lpAccelTbl->wCount++;
618 GlobalUnlock(hAccel);
619 GlobalUnlock(rsc_mem);
620 GlobalFree(rsc_mem);
621 return hAccel;
624 /**********************************************************************
625 * TranslateAccelerator [USER.178]
627 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
629 ACCELHEADER *lpAccelTbl;
630 int i, image_size;
631 if (hAccel == 0 || msg == NULL) return 0;
632 if (msg->message != WM_KEYDOWN &&
633 msg->message != WM_KEYUP &&
634 msg->message != WM_CHAR) return 0;
635 #ifdef DEBUG_ACCEL
636 printf("TranslateAccelerators hAccel=%04X !\n", hAccel);
637 #endif
638 lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
639 for (i = 0; i < lpAccelTbl->wCount; i++) {
640 /* if (lpAccelTbl->tbl[i].type & SHIFT_ACCEL) { */
641 /* if (lpAccelTbl->tbl[i].type & CONTROL_ACCEL) { */
642 if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
643 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
644 msg->message == WM_KEYDOWN) {
645 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
646 return 1;
648 if (msg->message == WM_KEYUP) return 1;
650 else {
651 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
652 msg->message == WM_CHAR) {
653 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
654 return 1;
658 GlobalUnlock(hAccel);
659 return 0;
662 /**********************************************************************
663 * FindResource [KERNEL.60]
665 HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name)
667 RESOURCE *r;
668 HANDLE rh;
670 if (instance == 0)
671 return 0;
673 #ifdef DEBUG_RESOURCE
674 printf("FindResource hInst=%04X typename=%08X resname=%08X\n",
675 instance, type_name, resource_name);
676 #endif
677 if (OpenResourceFile(instance) < 0)
678 return 0;
680 rh = GlobalAlloc(GMEM_MOVEABLE, sizeof(*r));
681 if (rh == 0)
682 return 0;
683 r = (RESOURCE *)GlobalLock(rh);
685 r->next = Top;
686 Top = r;
687 r->info_mem = rh;
688 r->rsc_mem = 0;
690 if (((int) resource_name & 0xffff0000) == 0)
692 r->size_shift = FindResourceByNumber(&r->nameinfo, (int)type_name,
693 (int) resource_name | 0x8000);
695 else
697 r->size_shift = FindResourceByName(&r->nameinfo, (int)type_name,
698 resource_name);
701 if (r->size_shift == -1)
703 GlobalFree(rh);
704 return 0;
707 return rh;
710 /**********************************************************************
711 * LoadResource [KERNEL.61]
713 HANDLE LoadResource(HANDLE instance, HANDLE hResInfo)
715 RESOURCE *r;
716 int image_size;
717 void *image;
718 HANDLE h;
720 if (instance == 0)
721 return 0;
723 if (OpenResourceFile(instance) < 0)
724 return 0;
726 r = (RESOURCE *)GlobalLock(hResInfo);
727 if (r == NULL)
728 return 0;
730 image_size = r->nameinfo.length << r->size_shift;
732 h = r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
733 image = GlobalLock(h);
735 lseek(ResourceFd, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET);
737 if (image == NULL || read(ResourceFd, image, image_size) != image_size)
739 GlobalFree(h);
740 GlobalUnlock(hResInfo);
741 return 0;
744 GlobalUnlock(h);
745 GlobalUnlock(hResInfo);
746 return h;
749 /**********************************************************************
750 * LockResource [KERNEL.62]
752 LPSTR LockResource(HANDLE hResData)
754 return GlobalLock(hResData);
757 /**********************************************************************
758 * FreeResource [KERNEL.63]
760 HANDLE FreeResource(HANDLE hResData)
762 RESOURCE *r, *rp;
764 for (r = rp = Top; r != NULL; r = r->next)
766 if (r->info_mem == hResData)
768 if (rp != NULL)
769 rp->next = r->next;
770 else
771 Top = r->next;
773 GlobalFree(r->rsc_mem);
774 GlobalFree(r->info_mem);
775 return 0;
779 return hResData;
782 /**********************************************************************
783 * AccessResource [KERNEL.64]
785 int AccessResource(HANDLE instance, HANDLE hResInfo)
787 int resfile;
788 #ifdef DEBUG_RESOURCE
789 printf("AccessResource(%04X, %04X);\n", instance, hResInfo);
790 #endif
792 resfile = OpenResourceFile(instance);
793 return resfile;
795 return - 1;
800 /**********************************************************************
801 * RSC_LoadResource
803 HANDLE
804 RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret)
806 struct resource_nameinfo_s nameinfo;
807 HANDLE hmem;
808 void *image;
809 int image_size;
810 int size_shift;
813 * Built-in resources
815 if (instance == 0)
817 return 0;
819 else if (OpenResourceFile(instance) < 0)
820 return 0;
823 * Get resource by ordinal
825 if (((int) rsc_name & 0xffff0000) == 0)
827 size_shift = FindResourceByNumber(&nameinfo, type,
828 (int) rsc_name | 0x8000);
831 * Get resource by name
833 else
835 size_shift = FindResourceByName(&nameinfo, type, rsc_name);
837 if (size_shift == -1) {
838 if ((LONG)rsc_name >= 0x00010000L)
839 printf("RSC_LoadResource / Resource '%s' not Found !\n", rsc_name);
840 else
841 printf("RSC_LoadResource / Resource '%X' not Found !\n", rsc_name);
842 return 0;
845 * Read resource.
847 lseek(ResourceFd, ((int) nameinfo.offset << size_shift), SEEK_SET);
849 image_size = nameinfo.length << size_shift;
850 if (image_size_ret != NULL)
851 *image_size_ret = image_size;
852 hmem = GlobalAlloc(GMEM_MOVEABLE, image_size);
853 image = GlobalLock(hmem);
854 if (image == NULL || read(ResourceFd, image, image_size) != image_size)
856 GlobalFree(hmem);
857 return 0;
860 GlobalUnlock(hmem);
861 return hmem;
864 /**********************************************************************
865 * LoadString
868 LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
870 HANDLE hmem;
871 int rsc_size;
872 unsigned char *p;
873 int string_num;
874 int i;
876 #ifdef DEBUG_RESOURCE
877 printf("LoadString: instance = %04x, id = %d, "
878 "buffer = %08x, length = %d\n",
879 instance, resource_id, buffer, buflen);
880 #endif
882 hmem = RSC_LoadResource(instance, (char *) ((resource_id >> 4) + 1),
883 NE_RSCTYPE_STRING, &rsc_size);
884 if (hmem == 0)
885 return 0;
887 p = GlobalLock(hmem);
888 string_num = resource_id & 0x000f;
889 for (i = 0; i < string_num; i++)
890 p += *p + 1;
892 i = MIN(buflen - 1, *p);
893 if (i > 0) {
894 memcpy(buffer, p + 1, i);
895 buffer[i] = '\0';
897 else {
898 printf("LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
899 printf("LoadString // and try to obtain string '%s'\n", p + 1);
901 GlobalFree(hmem);
903 #ifdef DEBUG_RESOURCE
904 printf(" '%s'\n", buffer);
905 #endif
906 return i;
909 /**********************************************************************
910 * RSC_LoadMenu
912 HANDLE
913 RSC_LoadMenu(HANDLE instance, LPSTR menu_name)
915 #ifdef DEBUG_RESOURCE
916 printf("RSC_LoadMenu: instance = %04x, name = '%s'\n",
917 instance, menu_name);
918 #endif
919 return RSC_LoadResource(instance, menu_name, NE_RSCTYPE_MENU, NULL);
922 /**********************************************************************
923 * LoadBitmap
925 HBITMAP
926 LoadBitmap(HANDLE instance, LPSTR bmp_name)
928 HBITMAP hbitmap;
929 HANDLE rsc_mem;
930 HDC hdc;
931 long *lp;
932 int image_size;
933 int size;
935 #ifdef DEBUG_RESOURCE
936 printf("LoadBitmap: instance = %04x, name = %08x\n",
937 instance, bmp_name);
938 #endif
939 if (instance == (HANDLE)NULL) instance = hSysRes;
940 if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
942 rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP,
943 &image_size);
944 if (rsc_mem == (HANDLE)NULL) {
945 printf("LoadBitmap / BitMap %04X not Found !\n", bmp_name);
946 return 0;
948 lp = (long *) GlobalLock(rsc_mem);
949 if (lp == NULL)
951 GlobalFree(rsc_mem);
952 return 0;
954 size = CONV_LONG (*lp);
955 if (size == sizeof(BITMAPCOREHEADER)){
956 CONV_BITMAPCOREHEADER (lp);
957 hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp );
958 } else if (size == sizeof(BITMAPINFOHEADER)){
959 CONV_BITMAPINFO (lp);
960 hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
961 } else hbitmap = 0;
962 GlobalFree(rsc_mem);
963 ReleaseDC( 0, hdc );
964 return hbitmap;
967 /**********************************************************************
968 * CreateIcon [USER.407]
970 HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight,
971 BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits,
972 LPSTR lpXORbits)
974 HICON hIcon;
975 ICONALLOC *lpico;
977 #ifdef DEBUG_RESOURCE
978 printf("CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n",
979 hInstance, nWidth, nHeight);
980 printf(" nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel);
981 printf(" lpANDbits= %04x, lpXORbits = %04x, \n",lpANDbits, lpXORbits);
982 #endif
984 if (hInstance == (HANDLE)NULL) {
985 printf("CreateIcon / hInstance %04x not Found!\n",hInstance);
986 return 0;
988 hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
989 if (hIcon == (HICON)NULL) {
990 printf("Can't allocate memory for Icon in CreateIcon\n");
991 return 0;
993 lpico= (ICONALLOC *)GlobalLock(hIcon);
995 lpico->descriptor.Width=nWidth;
996 lpico->descriptor.Height=nHeight;
997 lpico->descriptor.ColorCount=16; /* Dummy Value */
998 lpico->descriptor.Reserved1=0;
999 lpico->descriptor.Reserved2=nPlanes;
1000 lpico->descriptor.Reserved3=nWidth*nHeight;
1002 /* either nPlanes and/or nBitCount is set to one */
1003 lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel;
1004 lpico->descriptor.icoDIBOffset=0;
1006 if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel,
1007 lpXORbits)) ) {
1008 printf("CreateIcon: couldn't create the XOR bitmap\n");
1009 return(0);
1012 /* the AND BitMask is always monochrome */
1013 if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) {
1014 printf("CreateIcon: couldn't create the AND bitmap\n");
1015 return(0);
1018 GlobalUnlock(hIcon);
1019 #ifdef DEBUG_RESOURCE
1020 printf("CreateIcon Alloc hIcon=%X\n", hIcon);
1021 #endif
1022 return hIcon;