Release 980601
[wine/gsoc_dplay.git] / tools / wrc / genres.c
blobb9e831cbf118ab32c1f34ed1b70592601287a1a8
1 /*
2 * Generate .res format from a resource-tree
4 * Copyright 1998 Bertho A. Stultiens
6 * 25-May-1998 BS - Added simple unicode -> char conversion for resource
7 * names in .s and .h files.
8 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <assert.h>
14 #include <ctype.h>
16 #include <config.h>
17 #include "wrc.h"
18 #include "genres.h"
19 #include "utils.h"
21 #define SetResSize(res, tag) *(DWORD *)&((res)->data[(tag)]) = \
22 (res)->size - *(DWORD *)&((res)->data[(tag)])
24 res_t *new_res(void)
26 res_t *r;
27 r = (res_t *)xmalloc(sizeof(res_t));
28 r->allocsize = RES_BLOCKSIZE;
29 r->size = 0;
30 r->data = (char *)xmalloc(RES_BLOCKSIZE);
31 return r;
34 res_t *grow_res(res_t *r, int add)
36 r->allocsize += add;
37 r->data = (char *)xrealloc(r->data, r->allocsize);
38 return r;
42 *****************************************************************************
43 * Function : put_byte
44 * put_word
45 * put_dword
46 * Syntax : void put_byte(res_t *res, unsigned c)
47 * void put_word(res_t *res, unsigned w)
48 * void put_dword(res_t *res, unsigned d)
49 * Input :
50 * res - Binary resource to put the data in
51 * c, w, d - Data to put
52 * Output : nop
53 * Description : Put primitives that put an item in the binary resource.
54 * The data array grows automatically.
55 * Remarks :
56 *****************************************************************************
58 void put_byte(res_t *res, unsigned c)
60 if(res->allocsize - res->size < sizeof(char))
61 grow_res(res, RES_BLOCKSIZE);
62 *(char *)&(res->data[res->size]) = (char)c;
63 res->size += sizeof(char);
66 void put_word(res_t *res, unsigned w)
68 if(res->allocsize - res->size < sizeof(WORD))
69 grow_res(res, RES_BLOCKSIZE);
70 *(WORD *)&(res->data[res->size]) = (WORD)w;
71 res->size += sizeof(WORD);
74 void put_dword(res_t *res, unsigned d)
76 if(res->allocsize - res->size < sizeof(DWORD))
77 grow_res(res, RES_BLOCKSIZE);
78 *(DWORD *)&(res->data[res->size]) = (DWORD)d;
79 res->size += sizeof(DWORD);
82 void put_pad(res_t *res)
84 while(res->size & 0x3)
85 put_byte(res, 0);
89 *****************************************************************************
90 * Function : string_to_upper
91 * Syntax : void string_to_upper(string_t *str)
92 * Input :
93 * Output :
94 * Description :
95 * Remarks : FIXME: codepages...
96 *****************************************************************************
98 void string_to_upper(string_t *str)
100 if(str->type == str_char)
102 char *cptr = str->str.cstr;
103 for(; *cptr; cptr++)
104 *cptr = (char)toupper(*cptr);
106 else if(str->type == str_unicode)
108 short *sptr = str->str.wstr;
109 for(; *sptr; sptr++)
110 if(isalpha(*sptr))
111 *sptr = (short)toupper(*sptr);
113 else
115 internal_error(__FILE__, __LINE__, "Invalid string type %d", str->type);
120 *****************************************************************************
121 * Function : put_string
122 * Syntax : void put_string(res_t *res, string_t *str, enum str_e type,
123 * int isterm)
124 * Input :
125 * res - Binary resource to put the data in
126 * str - String to put
127 * type - Data has to be written in either str_char or str_unicode
128 * isterm - The string is '\0' terminated (disregard the string's
129 * size member)
130 * Output : nop
131 * Description :
132 * Remarks :
133 *****************************************************************************
135 void put_string(res_t *res, string_t *str, enum str_e type, int isterm)
137 int cnt;
138 int c = !0;
139 assert(res != NULL);
140 assert(str != NULL);
141 if(!isterm && str->size == 0)
143 warning("String length is zero, not written");
144 return;
147 if(str->type == str_unicode && type == str_unicode)
149 for(cnt = 0; cnt < str->size; cnt++)
151 c = str->str.wstr[cnt];
152 put_word(res, c);
153 if(isterm && !c)
154 break;
156 if(isterm && (str->size == 0 || (cnt == str->size && c)))
157 put_word(res, 0);
159 else if(str->type == str_char && type == str_char)
161 for(cnt = 0; cnt < str->size; cnt++)
163 c = str->str.cstr[cnt];
164 put_byte(res, c);
165 if(isterm && !c)
166 break;
168 if(isterm && (str->size == 0 || (cnt == str->size && c)))
169 put_byte(res, 0);
171 else if(str->type == str_unicode && type == str_char)
173 for(cnt = 0; cnt < str->size; cnt++)
175 c = str->str.wstr[cnt];
176 put_byte(res, c);
177 if(isterm && !c)
178 break;
180 if(isterm && (str->size == 0 || (cnt == str->size && c)))
181 put_byte(res, 0);
183 else /* str->type == str_char && type == str_unicode */
185 for(cnt = 0; cnt < str->size; cnt++)
187 c = str->str.cstr[cnt];
188 put_word(res, c & 0xff);
189 if(isterm && !c)
190 break;
192 if(isterm && (str->size == 0 || (cnt == str->size && c)))
193 put_word(res, 0);
198 *****************************************************************************
199 * Function : put_name_id
200 * Syntax : void put_name_id(res_t *res, name_id_t *nid, int upcase)
201 * Input :
202 * Output :
203 * Description :
204 * Remarks :
205 *****************************************************************************
207 void put_name_id(res_t *res, name_id_t *nid, int upcase)
209 if(nid->type == name_ord)
211 if(win32)
212 put_word(res, 0xffff);
213 else
214 put_byte(res, 0xff);
215 put_word(res, (WORD)nid->name.i_name);
217 else if(nid->type == name_str)
219 if(upcase)
220 string_to_upper(nid->name.s_name);
221 put_string(res, nid->name.s_name, win32 ? str_unicode : str_char, TRUE);
223 else
225 internal_error(__FILE__, __LINE__, "Invalid name_id type %d", nid->type);
230 *****************************************************************************
231 * Function : put_lvc
232 * Syntax : void put_lvc(res_t *res, lvc_t *lvc)
233 * Input :
234 * Output :
235 * Description :
236 * Remarks :
237 *****************************************************************************
239 void put_lvc(res_t *res, lvc_t *lvc)
241 if(lvc && lvc->language)
242 put_word(res, MAKELANGID(lvc->language->id, lvc->language->sub));
243 else
244 put_word(res, 0); /* Neutral */
245 if(lvc && lvc->version)
246 put_dword(res, *(lvc->version));
247 else
248 put_dword(res, 0);
249 if(lvc && lvc->characts)
250 put_dword(res, *(lvc->characts));
251 else
252 put_dword(res, 0);
256 *****************************************************************************
257 * Function : put_raw_data
258 * Syntax : void put_raw_data(res_t *res, raw_data_t *raw, int offset)
259 * Input :
260 * Output :
261 * Description :
262 * Remarks :
263 *****************************************************************************
265 void put_raw_data(res_t *res, raw_data_t *raw, int offset)
267 int wsize = raw->size - offset;
268 if(res->allocsize - res->size < wsize)
269 grow_res(res, wsize);
270 memcpy(&(res->data[res->size]), raw->data + offset, wsize);
271 res->size += wsize;
275 *****************************************************************************
276 * Function : put_res_header
277 * Syntax : intput_res_header(res_t *res, int type, name_id_t *ntype,
278 * name_id_t *name, DWORD memopt, lvc_t *lvc)
280 * Input :
281 * res - Binary resource descriptor to write to
282 * type - Resource identifier (if ntype == NULL)
283 * ntype - Name id of type
284 * name - Resource's name
285 * memopt - Resource's memory options to write
286 * lvc - Language, version and characteristics (win32 only)
287 * Output : An index to the resource size field. The resource size field
288 * contains the header size upon exit.
289 * Description :
290 * Remarks :
291 *****************************************************************************
293 int put_res_header(res_t *res, int type, name_id_t *ntype, name_id_t *name,
294 DWORD memopt, lvc_t *lvc)
296 if(win32)
298 put_dword(res, 0); /* We will overwrite these later */
299 put_dword(res, 0);
300 if(!ntype)
302 put_word(res, 0xffff); /* ResType */
303 put_word(res, type);
305 else
306 put_name_id(res, ntype, TRUE);
307 put_name_id(res, name, TRUE); /* ResName */
308 put_pad(res);
309 put_dword(res, 0); /* DataVersion */
310 put_word(res, memopt); /* Memory options */
311 put_lvc(res, lvc); /* Language, version and characts */
312 ((DWORD *)res->data)[0] = res->size; /* Set preliminary resource */
313 ((DWORD *)res->data)[1] = res->size; /* Set HeaderSize */
314 res->dataidx = res->size;
315 return 0;
317 else /* win16 */
319 int tag;
320 if(!ntype)
322 put_byte(res, 0xff); /* ResType */
323 put_word(res, type);
325 else
326 put_name_id(res, ntype, TRUE);
327 put_name_id(res, name, TRUE); /* ResName */
328 put_word(res, memopt); /* Memory options */
329 tag = res->size;
330 put_dword(res, 0); /* ResSize overwritten later*/
331 *(DWORD *)&(res->data[tag]) = res->size;
332 res->dataidx = res->size;
333 return tag;
338 *****************************************************************************
339 * Function : accelerator2res
340 * Syntax : res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
341 * Input :
342 * name - Name/ordinal of the resource
343 * acc - The accelerator descriptor
344 * Output : New .res format structure
345 * Description :
346 * Remarks :
347 *****************************************************************************
349 res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
351 int restag;
352 res_t *res;
353 event_t *ev;
354 assert(name != NULL);
355 assert(acc != NULL);
357 ev = acc->events;
358 res = new_res();
359 if(win32)
361 restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, &(acc->lvc));
362 while(ev)
364 put_word(res, ev->flags | (ev->next ? 0 : 0x80));
365 put_word(res, ev->key);
366 put_word(res, ev->id);
367 put_word(res, 0); /* Padding */
368 ev = ev->next;
370 put_pad(res);
372 else /* win16 */
374 restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, NULL);
375 while(ev)
377 put_byte(res, ev->flags | (ev->next ? 0 : 0x80));
378 put_word(res, ev->key);
379 put_word(res, ev->id);
380 ev = ev->next;
383 /* Set ResourceSize */
384 SetResSize(res, restag);
385 return res;
389 *****************************************************************************
390 * Function : dialog2res
391 * Syntax : res_t *dialog2res(name_id_t *name, dialog_t *dlg)
392 * Input :
393 * name - Name/ordinal of the resource
394 * dlg - The dialog descriptor
395 * Output : New .res format structure
396 * Description :
397 * Remarks :
398 *****************************************************************************
400 res_t *dialog2res(name_id_t *name, dialog_t *dlg)
402 int restag;
403 res_t *res;
404 control_t *ctrl;
405 int tag_nctrl;
406 int nctrl = 0;
407 assert(name != NULL);
408 assert(dlg != NULL);
410 ctrl = dlg->controls;
411 res = new_res();
412 if(win32)
414 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlg->memopt, &(dlg->lvc));
416 put_dword(res, dlg->style);
417 put_dword(res, dlg->gotexstyle ? dlg->exstyle : 0);
418 tag_nctrl = res->size;
419 put_word(res, 0); /* Number of controls */
420 put_word(res, dlg->x);
421 put_word(res, dlg->y);
422 put_word(res, dlg->width);
423 put_word(res, dlg->height);
424 if(dlg->menu)
425 put_name_id(res, dlg->menu, TRUE);
426 else
427 put_word(res, 0);
428 if(dlg->dlgclass)
429 put_name_id(res, dlg->dlgclass, TRUE);
430 else
431 put_word(res, 0);
432 if(dlg->title)
433 put_string(res, dlg->title, str_unicode, TRUE);
434 else
435 put_word(res, 0);
436 if(dlg->font)
438 put_word(res, dlg->font->size);
439 put_string(res, dlg->font->name, str_unicode, TRUE);
442 put_pad(res);
443 while(ctrl)
445 /* FIXME: what is default control style? */
446 put_dword(res, ctrl->gotstyle ? ctrl->style : WS_CHILD);
447 put_dword(res, ctrl->gotexstyle ? ctrl->exstyle : 0);
448 put_word(res, ctrl->x);
449 put_word(res, ctrl->y);
450 put_word(res, ctrl->width);
451 put_word(res, ctrl->height);
452 put_word(res, ctrl->id);
453 if(ctrl->ctlclass)
454 put_name_id(res, ctrl->ctlclass, TRUE);
455 else
456 internal_error(__FILE__, __LINE__, "Control has no control-class");
457 if(ctrl->title)
458 put_string(res, ctrl->title, str_unicode, TRUE);
459 else
460 put_word(res, 0);
461 if(ctrl->extra)
463 put_word(res, ctrl->extra->size+2);
464 put_pad(res);
465 put_raw_data(res, ctrl->extra, 0);
467 else
468 put_word(res, 0);
470 if(ctrl->next)
471 put_pad(res);
472 nctrl++;
473 ctrl = ctrl->next;
475 /* Set number of controls */
476 *(WORD *)&((char *)res->data)[tag_nctrl] = (WORD)nctrl;
478 else /* win16 */
480 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlg->memopt, NULL);
482 put_dword(res, dlg->gotstyle ? dlg->style : WS_POPUPWINDOW);
483 tag_nctrl = res->size;
484 put_byte(res, 0); /* Number of controls */
485 put_word(res, dlg->x);
486 put_word(res, dlg->y);
487 put_word(res, dlg->width);
488 put_word(res, dlg->height);
489 if(dlg->menu)
490 put_name_id(res, dlg->menu, TRUE);
491 else
492 put_byte(res, 0);
493 if(dlg->dlgclass)
494 put_name_id(res, dlg->dlgclass, TRUE);
495 else
496 put_byte(res, 0);
497 if(dlg->title)
498 put_string(res, dlg->title, str_char, TRUE);
499 else
500 put_byte(res, 0);
501 if(dlg->font)
503 put_word(res, dlg->font->size);
504 put_string(res, dlg->font->name, str_char, TRUE);
507 while(ctrl)
509 put_word(res, ctrl->x);
510 put_word(res, ctrl->y);
511 put_word(res, ctrl->width);
512 put_word(res, ctrl->height);
513 put_word(res, ctrl->id);
514 put_dword(res, ctrl->gotstyle ? ctrl->style : WS_CHILD);
515 if(ctrl->ctlclass)
517 if(ctrl->ctlclass->type == name_ord
518 && ctrl->ctlclass->name.i_name >= 0x80
519 && ctrl->ctlclass->name.i_name <= 0x85)
520 put_byte(res, ctrl->ctlclass->name.i_name);
521 else if(ctrl->ctlclass->type == name_str)
522 put_name_id(res, ctrl->ctlclass, FALSE);
523 else
524 error("Unknown control-class %04x", ctrl->ctlclass->name.i_name);
526 else
527 internal_error(__FILE__, __LINE__, "Control has no control-class");
528 if(ctrl->title)
529 put_string(res, ctrl->title, str_char, TRUE);
530 else
531 put_byte(res, 0);
533 /* FIXME: What is this extra byte doing here? */
534 put_byte(res, 0);
536 nctrl++;
537 ctrl = ctrl->next;
539 /* Set number of controls */
540 ((char *)res->data)[tag_nctrl] = (char)nctrl;
542 /* Set ResourceSize */
543 SetResSize(res, restag);
544 return res;
548 *****************************************************************************
549 * Function : dialogex2res
550 * Syntax : res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
551 * Input :
552 * name - Name/ordinal of the resource
553 * dlgex - The dialogex descriptor
554 * Output : New .res format structure
555 * Description :
556 * Remarks :
557 *****************************************************************************
559 res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
561 int restag;
562 res_t *res;
563 control_t *ctrl;
564 int tag_nctrl;
565 int nctrl = 0;
566 assert(name != NULL);
567 assert(dlgex != NULL);
569 ctrl = dlgex->controls;
570 res = new_res();
571 if(win32)
573 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlgex->memopt, &(dlgex->lvc));
575 /* FIXME: MS doc says thet the first word must contain 0xffff
576 * and the second 0x0001 to signal a DLGTEMPLATEEX. Borland's
577 * compiler reverses the two words.
578 * I don't know which one to choose, but I write it as Mr. B
579 * writes it.
581 put_word(res, 1); /* Signature */
582 put_word(res, 0xffff); /* DlgVer */
583 put_dword(res, dlgex->gothelpid ? dlgex->helpid : 0);
584 put_dword(res, dlgex->gotexstyle ? dlgex->exstyle : 0);
585 put_dword(res, dlgex->gotstyle ? dlgex->style : WS_POPUPWINDOW);
586 tag_nctrl = res->size;
587 put_word(res, 0); /* Number of controls */
588 put_word(res, dlgex->x);
589 put_word(res, dlgex->y);
590 put_word(res, dlgex->width);
591 put_word(res, dlgex->height);
592 if(dlgex->menu)
593 put_name_id(res, dlgex->menu, TRUE);
594 else
595 put_word(res, 0);
596 if(dlgex->dlgclass)
597 put_name_id(res, dlgex->dlgclass, TRUE);
598 else
599 put_word(res, 0);
600 if(dlgex->title)
601 put_string(res, dlgex->title, str_unicode, TRUE);
602 else
603 put_word(res, 0);
604 if(dlgex->font)
606 put_word(res, dlgex->font->size);
607 put_word(res, dlgex->font->weight);
608 /* FIXME: ? TRUE should be sufficient to say that its
609 * italic, but Borland's compiler says its 0x0101.
610 * I just copy it here, and hope for the best.
612 put_word(res, dlgex->font->italic ? 0x0101 : 0);
613 put_string(res, dlgex->font->name, str_unicode, TRUE);
616 put_pad(res);
617 while(ctrl)
619 put_dword(res, ctrl->gothelpid ? ctrl->helpid : 0);
620 put_dword(res, ctrl->gotexstyle ? ctrl->exstyle : 0);
621 /* FIXME: what is default control style? */
622 put_dword(res, ctrl->gotstyle ? ctrl->style : WS_CHILD | WS_VISIBLE);
623 put_word(res, ctrl->x);
624 put_word(res, ctrl->y);
625 put_word(res, ctrl->width);
626 put_word(res, ctrl->height);
627 put_word(res, ctrl->id);
628 /* FIXME: Pad is _NOT_ documented!?! */
629 put_pad(res);
630 if(ctrl->ctlclass)
631 put_name_id(res, ctrl->ctlclass, TRUE);
632 else
633 internal_error(__FILE__, __LINE__, "Control has no control-class");
634 if(ctrl->title)
635 put_string(res, ctrl->title, str_unicode, TRUE);
636 else
637 put_word(res, 0);
638 if(ctrl->extra)
640 put_pad(res);
641 put_word(res, ctrl->extra->size);
642 put_raw_data(res, ctrl->extra, 0);
644 else
645 put_word(res, 0);
647 put_pad(res);
648 nctrl++;
649 ctrl = ctrl->next;
651 /* Set number of controls */
652 *(WORD *)&((char *)res->data)[tag_nctrl] = (WORD)nctrl;
653 /* Set ResourceSize */
654 SetResSize(res, restag);
655 put_pad(res);
657 else /* win16 */
659 /* Do not generate anything in 16-bit mode */
660 free(res->data);
661 free(res);
662 return NULL;
664 return res;
668 *****************************************************************************
669 * Function : menuitem2res
670 * Syntax : void menuitem2res(res_t *res, menu_item_t *item)
671 * Input :
672 * Output :
673 * Description :
674 * Remarks : Self recursive
675 *****************************************************************************
677 void menuitem2res(res_t *res, menu_item_t *menitem)
679 menu_item_t *itm = menitem;
680 if(win32)
682 while(itm)
684 put_word(res, itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0));
685 if(!itm->popup)
686 put_word(res, itm->id);
687 if(itm->name)
688 put_string(res, itm->name, str_unicode, TRUE);
689 else
690 put_word(res, 0);
691 if(itm->popup)
692 menuitem2res(res, itm->popup);
693 itm = itm->next;
696 else /* win16 */
698 while(itm)
700 put_word(res, itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0));
701 if(!itm->popup)
702 put_word(res, itm->id);
703 if(itm->name)
704 put_string(res, itm->name, str_char, TRUE);
705 else
706 put_byte(res, 0);
707 if(itm->popup)
708 menuitem2res(res, itm->popup);
709 itm = itm->next;
716 *****************************************************************************
717 * Function : menu2res
718 * Syntax : res_t *menu2res(name_id_t *name, menu_t *men)
719 * Input :
720 * name - Name/ordinal of the resource
721 * men - The menu descriptor
722 * Output : New .res format structure
723 * Description :
724 * Remarks :
725 *****************************************************************************
727 res_t *menu2res(name_id_t *name, menu_t *men)
729 int restag;
730 res_t *res;
731 assert(name != NULL);
732 assert(men != NULL);
734 res = new_res();
735 restag = put_res_header(res, WRC_RT_MENU, NULL, name, men->memopt, win32 ? &(men->lvc) : NULL);
737 put_dword(res, 0); /* Menuheader: Version and HeaderSize */
738 menuitem2res(res, men->items);
739 /* Set ResourceSize */
740 SetResSize(res, restag);
741 if(win32)
742 put_pad(res);
743 return res;
747 *****************************************************************************
748 * Function : menuexitem2res
749 * Syntax : void menuexitem2res(res_t *res, menuex_item_t *item)
750 * Input :
751 * Output : nop
752 * Description :
753 * Remarks : Self recursive
754 *****************************************************************************
756 void menuexitem2res(res_t *res, menuex_item_t *menitem)
758 menuex_item_t *itm = menitem;
759 assert(win32 != 0);
760 while(itm)
762 put_dword(res, itm->gottype ? itm->type : 0);
763 put_dword(res, itm->gotstate ? itm->state : 0);
764 put_dword(res, itm->gotid ? itm->id : 0); /* FIXME: Docu. says word */
765 put_word(res, (itm->popup ? 0x01 : 0) | (!itm->next ? MF_END : 0));
766 if(itm->name)
767 put_string(res, itm->name, str_unicode, TRUE);
768 else
769 put_word(res, 0);
770 put_pad(res);
771 if(itm->popup)
773 put_dword(res, itm->gothelpid ? itm->helpid : 0);
774 menuexitem2res(res, itm->popup);
776 itm = itm->next;
782 *****************************************************************************
783 * Function : menuex2res
784 * Syntax : res_t *menuex2res(name_id_t *name, menuex_t *menex)
785 * Input :
786 * name - Name/ordinal of the resource
787 * menex - The menuex descriptor
788 * Output : New .res format structure
789 * Description :
790 * Remarks :
791 *****************************************************************************
793 res_t *menuex2res(name_id_t *name, menuex_t *menex)
795 int restag;
796 res_t *res;
797 assert(name != NULL);
798 assert(menex != NULL);
800 res = new_res();
801 if(win32)
803 /* FIXME: Borland's rc compiler writes the default system's
804 * language if none specified (0x406 for me that is). I believe
805 * that this is a Borland bug (brc32 ver. 5.01), as the default
806 * should be 0 (system default).
808 restag = put_res_header(res, WRC_RT_MENU, NULL, name, menex->memopt, &(menex->lvc));
810 put_word(res, 1); /* Menuheader: Version */
811 put_word(res, 4); /* Offset */
812 put_dword(res, 0); /* HelpId */
813 put_pad(res);
814 menuexitem2res(res, menex->items);
815 /* Set ResourceSize */
816 SetResSize(res, restag);
817 put_pad(res);
819 else /* win16 */
821 /* Do not generate anything in 16-bit mode */
822 free(res->data);
823 free(res);
824 return NULL;
826 return res;
830 *****************************************************************************
831 * Function : cursorgroup2res
832 * Syntax : res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
833 * Input :
834 * name - Name/ordinal of the resource
835 * curg - The cursor descriptor
836 * Output : New .res format structure
837 * Description :
838 * Remarks :
839 *****************************************************************************
841 res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
843 int restag;
844 res_t *res;
845 cursor_t *cur;
846 assert(name != NULL);
847 assert(curg != NULL);
849 res = new_res();
850 restag = put_res_header(res, WRC_RT_GROUP_CURSOR, NULL, name, curg->memopt, NULL);
851 if(win32)
853 /* FIXME: Borland's rc compiler writes the default system's
854 * language if none specified (0x406 for me that is). I believe
855 * that this is a Borland bug (brc32 ver. 5.01), as the default
856 * should be 0 (system default).
859 put_word(res, 0); /* Reserved */
860 /* FIXME: The ResType in the NEWHEADER structure should
861 * contain 14 according to the MS win32 doc. This is
862 * not the case with the BRC compiler and I really doubt
863 * the latter. Putting one here is compliant to win16 spec,
864 * but who knows the true value?
866 put_word(res, 2); /* ResType */
867 put_word(res, curg->ncursor);
868 #if 0
869 for(cur = curg->cursorlist; cur; cur = cur->next)
870 #else
871 cur = curg->cursorlist;
872 while(cur->next)
873 cur = cur->next;
874 for(; cur; cur = cur->prev)
875 #endif
877 put_word(res, cur->width);
878 /* FIXME: The height of a cursor is half the size of
879 * the bitmap's height. BRC puts the height from the
880 * BITMAPINFOHEADER here instead of the cursorfile's
881 * height. MS doesn't seem to care...
883 put_word(res, cur->height);
884 /* FIXME: The next two are reversed in BRC and I don't
885 * know why. Probably a bug. But, we can safely ignore
886 * it because win16 does not support color cursors.
887 * A warning should have been generated by the parser.
889 put_word(res, cur->planes);
890 put_word(res, cur->bits);
891 /* FIXME: The +4 is the hotspot in the cursor resource.
892 * However, I cound not find this in the documentation.
893 * The hotspot bytes must either be included or MS
894 * doesn't care.
896 put_dword(res, cur->data->size +4);
897 put_word(res, cur->id);
900 else /* win16 */
902 put_word(res, 0); /* Reserved */
903 put_word(res, 2); /* ResType */
904 put_word(res, curg->ncursor);
905 #if 0
906 for(cur = curg->cursorlist; cur; cur = cur->next)
907 #else
908 cur = curg->cursorlist;
909 while(cur->next)
910 cur = cur->next;
911 for(; cur; cur = cur->prev)
912 #endif
914 put_word(res, cur->width);
915 /* FIXME: The height of a cursor is half the size of
916 * the bitmap's height. BRC puts the height from the
917 * BITMAPINFOHEADER here instead of the cursorfile's
918 * height. MS doesn't seem to care...
920 put_word(res, cur->height);
921 /* FIXME: The next two are reversed in BRC and I don't
922 * know why. Probably a bug. But, we can safely ignore
923 * it because win16 does not support color cursors.
924 * A warning should have been generated by the parser.
926 put_word(res, cur->planes);
927 put_word(res, cur->bits);
928 /* FIXME: The +4 is the hotspot in the cursor resource.
929 * However, I cound not find this in the documentation.
930 * The hotspot bytes must either be included or MS
931 * doesn't care.
933 put_dword(res, cur->data->size +4);
934 put_word(res, cur->id);
937 SetResSize(res, restag); /* Set ResourceSize */
938 if(win32)
939 put_pad(res);
941 return res;
945 *****************************************************************************
946 * Function : cursor2res
947 * Syntax : res_t *cursor2res(cursor_t *cur)
948 * Input :
949 * cur - The cursor descriptor
950 * Output : New .res format structure
951 * Description :
952 * Remarks :
953 *****************************************************************************
955 res_t *cursor2res(cursor_t *cur)
957 int restag;
958 res_t *res;
959 name_id_t name;
961 assert(cur != NULL);
963 res = new_res();
964 name.type = name_ord;
965 name.name.i_name = cur->id;
966 /* FIXME: Borland's rc compiler writes the default system's
967 * language if none specified (0x406 for me that is). I believe
968 * that this is a Borland bug (brc32 ver. 5.01), as the default
969 * should be 0 (system default).
971 restag = put_res_header(res, WRC_RT_CURSOR, NULL, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, NULL);
972 put_word(res, cur->xhot);
973 put_word(res, cur->yhot);
974 put_raw_data(res, cur->data, 0);
976 SetResSize(res, restag); /* Set ResourceSize */
977 if(win32)
978 put_pad(res);
980 return res;
984 *****************************************************************************
985 * Function : icongroup2res
986 * Syntax : res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
987 * Input :
988 * name - Name/ordinal of the resource
989 * icog - The icon group descriptor
990 * Output : New .res format structure
991 * Description :
992 * Remarks :
993 *****************************************************************************
995 res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
997 int restag;
998 res_t *res;
999 icon_t *ico;
1000 assert(name != NULL);
1001 assert(icog != NULL);
1003 res = new_res();
1004 restag = put_res_header(res, WRC_RT_GROUP_ICON, NULL, name, icog->memopt, NULL);
1005 if(win32)
1007 /* FIXME: Borland's rc compiler writes the default system's
1008 * language if none specified (0x406 for me that is). I believe
1009 * that this is a Borland bug (brc32 ver. 5.01), as the default
1010 * should be 0 (system default).
1013 put_word(res, 0); /* Reserved */
1014 /* FIXME: The ResType in the NEWHEADER structure should
1015 * contain 14 according to the MS win32 doc. This is
1016 * not the case with the BRC compiler and I really doubt
1017 * the latter. Putting one here is compliant to win16 spec,
1018 * but who knows the true value?
1020 put_word(res, 1); /* ResType */
1021 put_word(res, icog->nicon);
1022 for(ico = icog->iconlist; ico; ico = ico->next)
1024 put_byte(res, ico->width);
1025 put_byte(res, ico->height);
1026 put_byte(res, ico->nclr);
1027 put_byte(res, 0); /* Reserved */
1028 put_word(res, ico->planes);
1029 put_word(res, ico->bits);
1030 put_dword(res, ico->data->size);
1031 put_word(res, ico->id);
1034 else /* win16 */
1036 put_word(res, 0); /* Reserved */
1037 put_word(res, 1); /* ResType */
1038 put_word(res, icog->nicon);
1039 for(ico = icog->iconlist; ico; ico = ico->next)
1041 put_byte(res, ico->width);
1042 put_byte(res, ico->height);
1043 put_byte(res, ico->nclr);
1044 put_byte(res, 0); /* Reserved */
1045 put_word(res, ico->planes);
1046 put_word(res, ico->bits);
1047 put_dword(res, ico->data->size);
1048 put_word(res, ico->id);
1051 SetResSize(res, restag); /* Set ResourceSize */
1052 if(win32)
1053 put_pad(res);
1055 return res;
1059 *****************************************************************************
1060 * Function : icon2res
1061 * Syntax : res_t *icon2res(icon_t *ico)
1062 * Input :
1063 * ico - The icon descriptor
1064 * Output : New .res format structure
1065 * Description :
1066 * Remarks :
1067 *****************************************************************************
1069 res_t *icon2res(icon_t *ico)
1071 int restag;
1072 res_t *res;
1073 name_id_t name;
1075 assert(ico != NULL);
1077 res = new_res();
1078 name.type = name_ord;
1079 name.name.i_name = ico->id;
1080 /* FIXME: Borland's rc compiler writes the default system's
1081 * language if none specified (0x406 for me that is). I believe
1082 * that this is a Borland bug (brc32 ver. 5.01), as the default
1083 * should be 0 (system default).
1085 restag = put_res_header(res, WRC_RT_ICON, NULL, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, NULL);
1086 put_raw_data(res, ico->data, 0);
1088 SetResSize(res, restag); /* Set ResourceSize */
1089 if(win32)
1090 put_pad(res);
1092 return res;
1096 *****************************************************************************
1097 * Function : bitmap2res
1098 * Syntax : res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
1099 * Input :
1100 * name - Name/ordinal of the resource
1101 * bmp - The bitmap descriptor
1102 * Output : New .res format structure
1103 * Description :
1104 * Remarks :
1105 *****************************************************************************
1107 res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
1109 int restag;
1110 res_t *res;
1111 assert(name != NULL);
1112 assert(bmp != NULL);
1114 HEAPCHECK();
1115 res = new_res();
1116 HEAPCHECK();
1117 restag = put_res_header(res, WRC_RT_BITMAP, NULL, name, bmp->memopt, NULL);
1118 HEAPCHECK();
1119 if(bmp->data->data[0] == 'B'
1120 && bmp->data->data[1] == 'M'
1121 && ((BITMAPFILEHEADER *)bmp->data->data)->bfSize == bmp->data->size
1122 && bmp->data->size >= sizeof(BITMAPFILEHEADER))
1124 /* The File header is still attached, don't write it */
1125 put_raw_data(res, bmp->data, sizeof(BITMAPFILEHEADER));
1127 else
1129 put_raw_data(res, bmp->data, 0);
1131 HEAPCHECK();
1132 /* Set ResourceSize */
1133 SetResSize(res, restag);
1134 HEAPCHECK();
1135 if(win32)
1136 put_pad(res);
1137 HEAPCHECK();
1138 return res;
1142 *****************************************************************************
1143 * Function : font2res
1144 * Syntax : res_t *font2res(name_id_t *name, font_t *fnt)
1145 * Input :
1146 * name - Name/ordinal of the resource
1147 * fnt - The font descriptor
1148 * Output : New .res format structure
1149 * Description :
1150 * Remarks :
1151 *****************************************************************************
1153 res_t *font2res(name_id_t *name, font_t *fnt)
1155 assert(name != NULL);
1156 assert(fnt != NULL);
1157 warning("Fonts not yet implemented");
1158 return NULL;
1162 *****************************************************************************
1163 * Function : rcdata2res
1164 * Syntax : res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
1165 * Input :
1166 * name - Name/ordinal of the resource
1167 * rdt - The rcdata descriptor
1168 * Output : New .res format structure
1169 * Description :
1170 * Remarks :
1171 *****************************************************************************
1173 res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
1175 int restag;
1176 res_t *res;
1177 assert(name != NULL);
1178 assert(rdt != NULL);
1180 res = new_res();
1181 restag = put_res_header(res, WRC_RT_RCDATA, NULL, name, rdt->memopt, NULL);
1182 put_raw_data(res, rdt->data, 0);
1183 /* Set ResourceSize */
1184 SetResSize(res, restag);
1185 if(win32)
1186 put_pad(res);
1187 return res;
1191 *****************************************************************************
1192 * Function : messagetable2res
1193 * Syntax : res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
1194 * Input :
1195 * name - Name/ordinal of the resource
1196 * msg - The messagetable descriptor
1197 * Output : New .res format structure
1198 * Description :
1199 * Remarks :
1200 *****************************************************************************
1202 res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
1204 assert(name != NULL);
1205 assert(msg != NULL);
1206 warning("Messagetable not yet implemented");
1207 return NULL;
1211 *****************************************************************************
1212 * Function : stringtable2res
1213 * Syntax : res_t *stringtable2res(stringtable_t *stt)
1214 * Input :
1215 * stt - The stringtable descriptor
1216 * Output : New .res format structure
1217 * Description :
1218 * Remarks :
1219 *****************************************************************************
1221 res_t *stringtable2res(stringtable_t *stt)
1223 res_t *res;
1224 name_id_t name;
1225 int i;
1226 int restag;
1227 DWORD lastsize = 0;
1229 assert(stt != NULL);
1230 res = new_res();
1232 for(; stt; stt = stt->next)
1234 if(!stt->nentries)
1236 warning("Empty internal stringtable");
1237 continue;
1239 name.type = name_ord;
1240 name.name.i_name = (stt->idbase >> 4) + 1;
1241 restag = put_res_header(res, WRC_RT_STRING, NULL, &name, stt->memopt, win32 ? &(stt->lvc) : NULL);
1242 for(i = 0; i < stt->nentries; i++)
1244 if(stt->entries[i].str)
1246 if(win32)
1247 put_word(res, stt->entries[i].str->size);
1248 else
1249 put_byte(res, stt->entries[i].str->size);
1250 put_string(res, stt->entries[i].str, win32 ? str_unicode : str_char, FALSE);
1252 else
1254 if(win32)
1255 put_word(res, 0);
1256 else
1257 put_byte(res, 0);
1260 /* Set ResourceSize */
1261 SetResSize(res, restag - lastsize);
1262 if(win32)
1263 put_pad(res);
1264 lastsize = res->size;
1266 return res;
1270 *****************************************************************************
1271 * Function : user2res
1272 * Syntax : res_t *user2res(name_id_t *name, user_t *usr)
1273 * Input :
1274 * name - Name/ordinal of the resource
1275 * usr - The userresource descriptor
1276 * Output : New .res format structure
1277 * Description :
1278 * Remarks :
1279 *****************************************************************************
1281 res_t *user2res(name_id_t *name, user_t *usr)
1283 int restag;
1284 res_t *res;
1285 assert(name != NULL);
1286 assert(usr != NULL);
1288 res = new_res();
1289 restag = put_res_header(res, 0, usr->type, name, usr->memopt, NULL);
1290 put_raw_data(res, usr->data, 0);
1291 /* Set ResourceSize */
1292 SetResSize(res, restag);
1293 if(win32)
1294 put_pad(res);
1295 return res;
1299 *****************************************************************************
1300 * Function : versionblock2res
1301 * Syntax : void versionblock2res(res_t *res, ver_block_t *blk)
1302 * Input :
1303 * res - Binary resource to write to
1304 * blk - The version block to be written
1305 * Output :
1306 * Description :
1307 * Remarks : Self recursive
1308 *****************************************************************************
1310 void versionblock2res(res_t *res, ver_block_t *blk, int level)
1312 ver_value_t *val;
1313 int blksizetag;
1314 int valblksizetag;
1315 int valvalsizetag;
1316 int tag;
1317 int i;
1319 blksizetag = res->size;
1320 put_word(res, 0); /* Will be overwritten later */
1321 put_word(res, 0);
1322 if(win32)
1323 put_word(res, 0); /* level ? */
1324 put_string(res, blk->name, win32 ? str_unicode : str_char, TRUE);
1325 put_pad(res);
1326 for(val = blk->values; val; val = val->next)
1328 if(val->type == val_str)
1330 valblksizetag = res->size;
1331 put_word(res, 0); /* Will be overwritten later */
1332 valvalsizetag = res->size;
1333 put_word(res, 0); /* Will be overwritten later */
1334 if(win32)
1336 put_word(res, level);
1338 put_string(res, val->key, win32 ? str_unicode : str_char, TRUE);
1339 put_pad(res);
1340 tag = res->size;
1341 put_string(res, val->value.str, win32 ? str_unicode : str_char, TRUE);
1342 if(win32)
1343 *(WORD *)&(res->data[valvalsizetag]) = (WORD)((res->size - tag) >> 1);
1344 else
1345 *(WORD *)&(res->data[valvalsizetag]) = (WORD)(res->size - tag);
1346 *(WORD *)&(res->data[valblksizetag]) = (WORD)(res->size - valblksizetag);
1347 put_pad(res);
1349 else if(val->type == val_words)
1351 valblksizetag = res->size;
1352 put_word(res, 0); /* Will be overwritten later */
1353 valvalsizetag = res->size;
1354 put_word(res, 0); /* Will be overwritten later */
1355 if(win32)
1357 put_word(res, level);
1359 put_string(res, val->key, win32 ? str_unicode : str_char, TRUE);
1360 put_pad(res);
1361 tag = res->size;
1362 for(i = 0; i < val->value.words->nwords; i++)
1364 put_word(res, val->value.words->words[i]);
1366 *(WORD *)&(res->data[valvalsizetag]) = (WORD)(res->size - tag);
1367 *(WORD *)&(res->data[valblksizetag]) = (WORD)(res->size - valblksizetag);
1368 put_pad(res);
1370 else if(val->type == val_block)
1372 versionblock2res(res, val->value.block, level+1);
1374 else
1376 internal_error(__FILE__, __LINE__, "Invalid value indicator %d in VERSIONINFO", val->type);
1380 /* Set blocksize */
1381 *(WORD *)&(res->data[blksizetag]) = (WORD)(res->size - blksizetag);
1385 *****************************************************************************
1386 * Function : versioninfo2res
1387 * Syntax : res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
1388 * Input :
1389 * name - Name/ordinal of the resource
1390 * ver - The versioninfo descriptor
1391 * Output : New .res format structure
1392 * Description :
1393 * Remarks :
1394 *****************************************************************************
1396 res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
1398 int restag;
1399 int rootblocksizetag;
1400 int valsizetag;
1401 int tag;
1402 res_t *res;
1403 string_t vsvi;
1404 ver_block_t *blk;
1406 assert(name != NULL);
1407 assert(ver != NULL);
1409 vsvi.type = str_char;
1410 vsvi.str.cstr = "VS_VERSION_INFO";
1411 vsvi.size = 15; /* Excl. termination */
1413 res = new_res();
1414 restag = put_res_header(res, WRC_RT_VERSION, NULL, name, WRC_MO_MOVEABLE | WRC_MO_PURE, NULL);
1415 rootblocksizetag = res->size;
1416 put_word(res, 0); /* BlockSize filled in later */
1417 valsizetag = res->size;
1418 put_word(res, 0); /* ValueSize filled in later*/
1419 if(win32)
1420 put_word(res, 0); /* Tree-level ? */
1421 put_string(res, &vsvi, win32 ? str_unicode : str_char, TRUE);
1422 if(win32)
1423 put_pad(res);
1424 tag = res->size;
1425 put_dword(res, VS_FFI_SIGNATURE);
1426 put_dword(res, VS_FFI_STRUCVERSION);
1427 put_dword(res, (ver->filever_maj1 << 16) + (ver->filever_maj2 & 0xffff));
1428 put_dword(res, (ver->filever_min1 << 16) + (ver->filever_min2 & 0xffff));
1429 put_dword(res, (ver->prodver_maj1 << 16) + (ver->prodver_maj2 & 0xffff));
1430 put_dword(res, (ver->prodver_min1 << 16) + (ver->prodver_min2 & 0xffff));
1431 put_dword(res, ver->fileflagsmask);
1432 put_dword(res, ver->fileflags);
1433 put_dword(res, ver->fileos);
1434 put_dword(res, ver->filetype);
1435 put_dword(res, ver->filesubtype);
1436 put_dword(res, 0); /* FileDateMS */
1437 put_dword(res, 0); /* FileDateLS */
1438 /* Set ValueSize */
1439 *(WORD *)&(res->data[valsizetag]) = (WORD)(res->size - tag);
1440 /* Descend into the blocks */
1441 for(blk = ver->blocks; blk; blk = blk->next)
1442 versionblock2res(res, blk, 0);
1443 /* Set root block's size */
1444 *(WORD *)&(res->data[rootblocksizetag]) = (WORD)(res->size - rootblocksizetag);
1446 SetResSize(res, restag);
1447 if(win32)
1448 put_pad(res);
1450 return res;
1454 *****************************************************************************
1455 * Function : prep_nid_for_label
1456 * Syntax : char *prep_nid_for_label(name_id_t *nid)
1457 * Input :
1458 * Output :
1459 * Description : Converts a resource name into the first 32 (or less)
1460 * characters of the name with conversions.
1461 * Remarks :
1462 *****************************************************************************
1464 #define MAXNAMELEN 32
1465 char *prep_nid_for_label(name_id_t *nid)
1467 static char buf[MAXNAMELEN+1];
1469 assert(nid != NULL);
1471 if(nid->type == name_str && nid->name.s_name->type == str_unicode)
1473 short *sptr;
1474 int i;
1475 sptr = nid->name.s_name->str.wstr;
1476 buf[0] = '\0';
1477 for(i = 0; *sptr && i < MAXNAMELEN; i++)
1479 if((unsigned)*sptr < 0x80 && isprint((char)*sptr))
1480 buf[i] = *sptr++;
1481 else
1482 warning("Resourcename (str_unicode) contain unprintable characters or invalid translation, ignored");
1484 buf[i] = '\0';
1486 else if(nid->type == name_str && nid->name.s_name->type == str_char)
1488 char *cptr;
1489 int i;
1490 cptr = nid->name.s_name->str.cstr;
1491 buf[0] = '\0';
1492 for(i = 0; *cptr && i < MAXNAMELEN; i++)
1494 if((unsigned)*cptr < 0x80 && isprint(*cptr))
1495 buf[i] = *cptr++;
1496 else
1497 warning("Resourcename (str_char) contain unprintable characters, ignored");
1499 buf[i] = '\0';
1501 else if(nid->type == name_ord)
1503 sprintf(buf, "%u", nid->name.i_name);
1505 else
1507 internal_error(__FILE__, __LINE__, "Resource name_id with invalid type %d", nid->type);
1509 return buf;
1511 #undef MAXNAMELEN
1514 *****************************************************************************
1515 * Function : make_c_name
1516 * Syntax : char *make_c_name(char *base, name_id_t *nid, language_t *lan)
1517 * Input :
1518 * Output :
1519 * Description : Converts a resource name into a valid c-identifier in the
1520 * form "_base_nid".
1521 * Remarks :
1522 *****************************************************************************
1524 char *make_c_name(char *base, name_id_t *nid, language_t *lan)
1526 int nlen;
1527 char *buf;
1528 char *ret;
1529 char lanbuf[6];
1531 sprintf(lanbuf, "%d", lan ? MAKELANGID(lan->id, lan->sub) : 0);
1532 buf = prep_nid_for_label(nid);
1533 nlen = strlen(buf) + strlen(lanbuf);
1534 nlen += strlen(base) + 4; /* three time '_' and '\0' */
1535 ret = (char *)xmalloc(nlen);
1536 strcpy(ret, "_");
1537 strcat(ret, base);
1538 strcat(ret, "_");
1539 strcat(ret, buf);
1540 strcat(ret, "_");
1541 strcat(ret, lanbuf);
1542 return ret;
1546 *****************************************************************************
1547 * Function : get_c_typename
1548 * Syntax : char *get_c_typename(enum res_e type)
1549 * Input :
1550 * Output :
1551 * Description : Convert resource enum to char string to be used in c-name
1552 * creation.
1553 * Remarks :
1554 *****************************************************************************
1556 char *get_c_typename(enum res_e type)
1558 switch(type)
1560 case res_acc: return "Acc";
1561 case res_bmp: return "Bmp";
1562 case res_cur: return "Cur";
1563 case res_curg: return "CurGrp";
1564 case res_dlg:
1565 case res_dlgex: return "Dlg";
1566 case res_fnt: return "Fnt";
1567 case res_ico: return "Ico";
1568 case res_icog: return "IcoGrp";
1569 case res_men:
1570 case res_menex: return "Men";
1571 case res_rdt: return "RCDat";
1572 case res_stt: return "StrTab";
1573 case res_usr: return "Usr";
1574 case res_msg: return "MsgTab";
1575 case res_ver: return "VerInf";
1576 default: return "Oops";
1581 *****************************************************************************
1582 * Function : resources2res
1583 * Syntax : void resources2res(resource_t *top)
1584 * Input :
1585 * top - The resource-tree to convert
1586 * Output :
1587 * Description : Convert logical resource descriptors into binary data
1588 * Remarks :
1589 *****************************************************************************
1591 void resources2res(resource_t *top)
1593 while(top)
1595 switch(top->type)
1597 case res_acc:
1598 if(!top->binres)
1599 top->binres = accelerator2res(top->name, top->res.acc);
1600 break;
1601 case res_bmp:
1602 if(!top->binres)
1603 top->binres = bitmap2res(top->name, top->res.bmp);
1604 break;
1605 case res_cur:
1606 if(!top->binres)
1607 top->binres = cursor2res(top->res.cur);
1608 break;
1609 case res_curg:
1610 if(!top->binres)
1611 top->binres = cursorgroup2res(top->name, top->res.curg);
1612 break;
1613 case res_dlg:
1614 if(!top->binres)
1615 top->binres = dialog2res(top->name, top->res.dlg);
1616 break;
1617 case res_dlgex:
1618 if(!top->binres)
1619 top->binres = dialogex2res(top->name, top->res.dlgex);
1620 break;
1621 case res_fnt:
1622 if(!top->binres)
1623 top->binres = font2res(top->name, top->res.fnt);
1624 break;
1625 case res_ico:
1626 if(!top->binres)
1627 top->binres = icon2res(top->res.ico);
1628 break;
1629 case res_icog:
1630 if(!top->binres)
1631 top->binres = icongroup2res(top->name, top->res.icog);
1632 break;
1633 case res_men:
1634 if(!top->binres)
1635 top->binres = menu2res(top->name, top->res.men);
1636 break;
1637 case res_menex:
1638 if(!top->binres)
1639 top->binres = menuex2res(top->name, top->res.menex);
1640 break;
1641 case res_rdt:
1642 if(!top->binres)
1643 top->binres = rcdata2res(top->name, top->res.rdt);
1644 break;
1645 case res_stt:
1646 if(!top->binres)
1647 top->binres = stringtable2res(top->res.stt);
1648 break;
1649 case res_usr:
1650 if(!top->binres)
1651 top->binres = user2res(top->name, top->res.usr);
1652 break;
1653 case res_msg:
1654 if(!top->binres)
1655 top->binres = messagetable2res(top->name, top->res.msg);
1656 break;
1657 case res_ver:
1658 if(!top->binres)
1659 top->binres = versioninfo2res(top->name, top->res.ver);
1660 break;
1661 default:
1662 internal_error(__FILE__, __LINE__, "Unknown resource type encountered %d in binary res generation", top->type);
1664 top->c_name = make_c_name(get_c_typename(top->type), top->name, top->lan);
1665 top = top->next;