Added support for WINEPREFIX environment variable.
[wine/multimedia.git] / tools / wrc / genres.c
blob0d527a3a65ca5dc384db1682521b1929775f465a
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 "config.h"
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <assert.h>
16 #include <ctype.h>
18 #include "wrc.h"
19 #include "genres.h"
20 #include "utils.h"
21 #include "windef.h"
22 #include "wingdi.h"
23 #include "winuser.h"
25 #define SetResSize(res, tag) *(DWORD *)&((res)->data[(tag)]) = \
26 (res)->size - *(DWORD *)&((res)->data[(tag)])
28 res_t *new_res(void)
30 res_t *r;
31 r = (res_t *)xmalloc(sizeof(res_t));
32 r->allocsize = RES_BLOCKSIZE;
33 r->size = 0;
34 r->data = (char *)xmalloc(RES_BLOCKSIZE);
35 return r;
38 res_t *grow_res(res_t *r, int add)
40 r->allocsize += add;
41 r->data = (char *)xrealloc(r->data, r->allocsize);
42 return r;
46 *****************************************************************************
47 * Function : put_byte
48 * put_word
49 * put_dword
50 * Syntax : void put_byte(res_t *res, unsigned c)
51 * void put_word(res_t *res, unsigned w)
52 * void put_dword(res_t *res, unsigned d)
53 * Input :
54 * res - Binary resource to put the data in
55 * c, w, d - Data to put
56 * Output : nop
57 * Description : Put primitives that put an item in the binary resource.
58 * The data array grows automatically.
59 * Remarks :
60 *****************************************************************************
62 void put_byte(res_t *res, unsigned c)
64 if(res->allocsize - res->size < sizeof(char))
65 grow_res(res, RES_BLOCKSIZE);
66 *(char *)&(res->data[res->size]) = (char)c;
67 res->size += sizeof(char);
70 void put_word(res_t *res, unsigned w)
72 if(res->allocsize - res->size < sizeof(WORD))
73 grow_res(res, RES_BLOCKSIZE);
74 *(WORD *)&(res->data[res->size]) = (WORD)w;
75 res->size += sizeof(WORD);
78 void put_dword(res_t *res, unsigned d)
80 if(res->allocsize - res->size < sizeof(DWORD))
81 grow_res(res, RES_BLOCKSIZE);
82 *(DWORD *)&(res->data[res->size]) = (DWORD)d;
83 res->size += sizeof(DWORD);
86 void put_pad(res_t *res)
88 while(res->size & 0x3)
89 put_byte(res, 0);
93 *****************************************************************************
94 * Function : string_to_upper
95 * Syntax : void string_to_upper(string_t *str)
96 * Input :
97 * Output :
98 * Description :
99 * Remarks : FIXME: codepages...
100 *****************************************************************************
102 void string_to_upper(string_t *str)
104 if(str->type == str_char)
106 char *cptr = str->str.cstr;
107 for(; *cptr; cptr++)
108 *cptr = (char)toupper(*cptr);
110 else if(str->type == str_unicode)
112 short *sptr = str->str.wstr;
113 for(; *sptr; sptr++)
114 if(isalpha(*sptr))
115 *sptr = (short)toupper(*sptr);
117 else
119 internal_error(__FILE__, __LINE__, "Invalid string type %d", str->type);
124 *****************************************************************************
125 * Function : put_string
126 * Syntax : void put_string(res_t *res, string_t *str, enum str_e type,
127 * int isterm)
128 * Input :
129 * res - Binary resource to put the data in
130 * str - String to put
131 * type - Data has to be written in either str_char or str_unicode
132 * isterm - The string is '\0' terminated (disregard the string's
133 * size member)
134 * Output : nop
135 * Description :
136 * Remarks :
137 *****************************************************************************
139 void put_string(res_t *res, string_t *str, enum str_e type, int isterm)
141 int cnt;
142 int c = !0;
143 assert(res != NULL);
144 assert(str != NULL);
145 if(!isterm && str->size == 0)
147 warning("String length is zero, not written");
148 return;
151 if(str->type == str_unicode && type == str_unicode)
153 for(cnt = 0; cnt < str->size; cnt++)
155 c = str->str.wstr[cnt];
156 put_word(res, c);
157 if(isterm && !c)
158 break;
160 if(isterm && (str->size == 0 || (cnt == str->size && c)))
161 put_word(res, 0);
163 else if(str->type == str_char && type == str_char)
165 for(cnt = 0; cnt < str->size; cnt++)
167 c = str->str.cstr[cnt];
168 put_byte(res, c);
169 if(isterm && !c)
170 break;
172 if(isterm && (str->size == 0 || (cnt == str->size && c)))
173 put_byte(res, 0);
175 else if(str->type == str_unicode && type == str_char)
177 for(cnt = 0; cnt < str->size; cnt++)
179 c = str->str.wstr[cnt];
180 put_byte(res, c);
181 if(isterm && !c)
182 break;
184 if(isterm && (str->size == 0 || (cnt == str->size && c)))
185 put_byte(res, 0);
187 else /* str->type == str_char && type == str_unicode */
189 for(cnt = 0; cnt < str->size; cnt++)
191 c = str->str.cstr[cnt];
192 put_word(res, c & 0xff);
193 if(isterm && !c)
194 break;
196 if(isterm && (str->size == 0 || (cnt == str->size && c)))
197 put_word(res, 0);
202 *****************************************************************************
203 * Function : put_name_id
204 * Syntax : void put_name_id(res_t *res, name_id_t *nid, int upcase)
205 * Input :
206 * Output :
207 * Description :
208 * Remarks :
209 *****************************************************************************
211 void put_name_id(res_t *res, name_id_t *nid, int upcase)
213 if(nid->type == name_ord)
215 if(win32)
216 put_word(res, 0xffff);
217 else
218 put_byte(res, 0xff);
219 put_word(res, (WORD)nid->name.i_name);
221 else if(nid->type == name_str)
223 if(upcase)
224 string_to_upper(nid->name.s_name);
225 put_string(res, nid->name.s_name, win32 ? str_unicode : str_char, TRUE);
227 else
229 internal_error(__FILE__, __LINE__, "Invalid name_id type %d", nid->type);
234 *****************************************************************************
235 * Function : put_lvc
236 * Syntax : void put_lvc(res_t *res, lvc_t *lvc)
237 * Input :
238 * Output :
239 * Description :
240 * Remarks :
241 *****************************************************************************
243 void put_lvc(res_t *res, lvc_t *lvc)
245 if(lvc && lvc->language)
246 put_word(res, MAKELANGID(lvc->language->id, lvc->language->sub));
247 else
248 put_word(res, 0); /* Neutral */
249 if(lvc && lvc->version)
250 put_dword(res, *(lvc->version));
251 else
252 put_dword(res, 0);
253 if(lvc && lvc->characts)
254 put_dword(res, *(lvc->characts));
255 else
256 put_dword(res, 0);
260 *****************************************************************************
261 * Function : put_raw_data
262 * Syntax : void put_raw_data(res_t *res, raw_data_t *raw, int offset)
263 * Input :
264 * Output :
265 * Description :
266 * Remarks :
267 *****************************************************************************
269 void put_raw_data(res_t *res, raw_data_t *raw, int offset)
271 int wsize = raw->size - offset;
272 if(res->allocsize - res->size < wsize)
273 grow_res(res, wsize);
274 memcpy(&(res->data[res->size]), raw->data + offset, wsize);
275 res->size += wsize;
279 *****************************************************************************
280 * Function : put_res_header
281 * Syntax : intput_res_header(res_t *res, int type, name_id_t *ntype,
282 * name_id_t *name, DWORD memopt, lvc_t *lvc)
284 * Input :
285 * res - Binary resource descriptor to write to
286 * type - Resource identifier (if ntype == NULL)
287 * ntype - Name id of type
288 * name - Resource's name
289 * memopt - Resource's memory options to write
290 * lvc - Language, version and characteristics (win32 only)
291 * Output : An index to the resource size field. The resource size field
292 * contains the header size upon exit.
293 * Description :
294 * Remarks :
295 *****************************************************************************
297 int put_res_header(res_t *res, int type, name_id_t *ntype, name_id_t *name,
298 DWORD memopt, lvc_t *lvc)
300 if(win32)
302 put_dword(res, 0); /* We will overwrite these later */
303 put_dword(res, 0);
304 if(!ntype)
306 put_word(res, 0xffff); /* ResType */
307 put_word(res, type);
309 else
310 put_name_id(res, ntype, TRUE);
311 put_name_id(res, name, TRUE); /* ResName */
312 put_pad(res);
313 put_dword(res, 0); /* DataVersion */
314 put_word(res, memopt); /* Memory options */
315 put_lvc(res, lvc); /* Language, version and characts */
316 ((DWORD *)res->data)[0] = res->size; /* Set preliminary resource */
317 ((DWORD *)res->data)[1] = res->size; /* Set HeaderSize */
318 res->dataidx = res->size;
319 return 0;
321 else /* win16 */
323 int tag;
324 if(!ntype)
326 put_byte(res, 0xff); /* ResType */
327 put_word(res, type);
329 else
330 put_name_id(res, ntype, TRUE);
331 put_name_id(res, name, TRUE); /* ResName */
332 put_word(res, memopt); /* Memory options */
333 tag = res->size;
334 put_dword(res, 0); /* ResSize overwritten later*/
335 *(DWORD *)&(res->data[tag]) = res->size;
336 res->dataidx = res->size;
337 return tag;
342 *****************************************************************************
343 * Function : accelerator2res
344 * Syntax : res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
345 * Input :
346 * name - Name/ordinal of the resource
347 * acc - The accelerator descriptor
348 * Output : New .res format structure
349 * Description :
350 * Remarks :
351 *****************************************************************************
353 res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
355 int restag;
356 res_t *res;
357 event_t *ev;
358 assert(name != NULL);
359 assert(acc != NULL);
361 ev = acc->events;
362 res = new_res();
363 if(win32)
365 restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, &(acc->lvc));
366 while(ev)
368 put_word(res, ev->flags | (ev->next ? 0 : 0x80));
369 put_word(res, ev->key);
370 put_word(res, ev->id);
371 put_word(res, 0); /* Padding */
372 ev = ev->next;
374 put_pad(res);
376 else /* win16 */
378 restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, NULL);
379 while(ev)
381 put_byte(res, ev->flags | (ev->next ? 0 : 0x80));
382 put_word(res, ev->key);
383 put_word(res, ev->id);
384 ev = ev->next;
387 /* Set ResourceSize */
388 SetResSize(res, restag);
389 return res;
393 *****************************************************************************
394 * Function : dialog2res
395 * Syntax : res_t *dialog2res(name_id_t *name, dialog_t *dlg)
396 * Input :
397 * name - Name/ordinal of the resource
398 * dlg - The dialog descriptor
399 * Output : New .res format structure
400 * Description :
401 * Remarks :
402 *****************************************************************************
404 res_t *dialog2res(name_id_t *name, dialog_t *dlg)
406 int restag;
407 res_t *res;
408 control_t *ctrl;
409 int tag_nctrl;
410 int nctrl = 0;
411 assert(name != NULL);
412 assert(dlg != NULL);
414 ctrl = dlg->controls;
415 res = new_res();
416 if(win32)
418 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlg->memopt, &(dlg->lvc));
420 put_dword(res, dlg->style->or_mask);
421 put_dword(res, dlg->gotexstyle ? dlg->exstyle->or_mask : 0);
422 tag_nctrl = res->size;
423 put_word(res, 0); /* Number of controls */
424 put_word(res, dlg->x);
425 put_word(res, dlg->y);
426 put_word(res, dlg->width);
427 put_word(res, dlg->height);
428 if(dlg->menu)
429 put_name_id(res, dlg->menu, TRUE);
430 else
431 put_word(res, 0);
432 if(dlg->dlgclass)
433 put_name_id(res, dlg->dlgclass, TRUE);
434 else
435 put_word(res, 0);
436 if(dlg->title)
437 put_string(res, dlg->title, str_unicode, TRUE);
438 else
439 put_word(res, 0);
440 if(dlg->font)
442 put_word(res, dlg->font->size);
443 put_string(res, dlg->font->name, str_unicode, TRUE);
446 put_pad(res);
447 while(ctrl)
449 /* FIXME: what is default control style? */
450 put_dword(res, ctrl->gotstyle ? ctrl->style->or_mask: WS_CHILD);
451 put_dword(res, ctrl->gotexstyle ? ctrl->exstyle->or_mask : 0);
452 put_word(res, ctrl->x);
453 put_word(res, ctrl->y);
454 put_word(res, ctrl->width);
455 put_word(res, ctrl->height);
456 put_word(res, ctrl->id);
457 if(ctrl->ctlclass)
458 put_name_id(res, ctrl->ctlclass, TRUE);
459 else
460 internal_error(__FILE__, __LINE__, "Control has no control-class");
461 if(ctrl->title)
462 put_name_id(res, ctrl->title, FALSE);
463 else
464 put_word(res, 0);
465 if(ctrl->extra)
467 put_word(res, ctrl->extra->size+2);
468 put_pad(res);
469 put_raw_data(res, ctrl->extra, 0);
471 else
472 put_word(res, 0);
474 if(ctrl->next)
475 put_pad(res);
476 nctrl++;
477 ctrl = ctrl->next;
479 /* Set number of controls */
480 *(WORD *)&((char *)res->data)[tag_nctrl] = (WORD)nctrl;
482 else /* win16 */
484 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlg->memopt, NULL);
486 put_dword(res, dlg->gotstyle ? dlg->style->or_mask : WS_POPUPWINDOW);
487 tag_nctrl = res->size;
488 put_byte(res, 0); /* Number of controls */
489 put_word(res, dlg->x);
490 put_word(res, dlg->y);
491 put_word(res, dlg->width);
492 put_word(res, dlg->height);
493 if(dlg->menu)
494 put_name_id(res, dlg->menu, TRUE);
495 else
496 put_byte(res, 0);
497 if(dlg->dlgclass)
498 put_name_id(res, dlg->dlgclass, TRUE);
499 else
500 put_byte(res, 0);
501 if(dlg->title)
502 put_string(res, dlg->title, str_char, TRUE);
503 else
504 put_byte(res, 0);
505 if(dlg->font)
507 put_word(res, dlg->font->size);
508 put_string(res, dlg->font->name, str_char, TRUE);
511 while(ctrl)
513 put_word(res, ctrl->x);
514 put_word(res, ctrl->y);
515 put_word(res, ctrl->width);
516 put_word(res, ctrl->height);
517 put_word(res, ctrl->id);
518 put_dword(res, ctrl->gotstyle ? ctrl->style->or_mask: WS_CHILD);
519 if(ctrl->ctlclass)
521 if(ctrl->ctlclass->type == name_ord
522 && ctrl->ctlclass->name.i_name >= 0x80
523 && ctrl->ctlclass->name.i_name <= 0x85)
524 put_byte(res, ctrl->ctlclass->name.i_name);
525 else if(ctrl->ctlclass->type == name_str)
526 put_name_id(res, ctrl->ctlclass, FALSE);
527 else
528 error("Unknown control-class %04x", ctrl->ctlclass->name.i_name);
530 else
531 internal_error(__FILE__, __LINE__, "Control has no control-class");
532 if(ctrl->title)
533 put_name_id(res, ctrl->title, FALSE);
534 else
535 put_byte(res, 0);
537 /* FIXME: What is this extra byte doing here? */
538 put_byte(res, 0);
540 nctrl++;
541 ctrl = ctrl->next;
543 /* Set number of controls */
544 ((char *)res->data)[tag_nctrl] = (char)nctrl;
546 /* Set ResourceSize */
547 SetResSize(res, restag);
548 return res;
552 *****************************************************************************
553 * Function : dialogex2res
554 * Syntax : res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
555 * Input :
556 * name - Name/ordinal of the resource
557 * dlgex - The dialogex descriptor
558 * Output : New .res format structure
559 * Description :
560 * Remarks :
561 *****************************************************************************
563 res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
565 int restag;
566 res_t *res;
567 control_t *ctrl;
568 int tag_nctrl;
569 int nctrl = 0;
570 assert(name != NULL);
571 assert(dlgex != NULL);
573 ctrl = dlgex->controls;
574 res = new_res();
575 if(win32)
577 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlgex->memopt, &(dlgex->lvc));
579 /* FIXME: MS doc says thet the first word must contain 0xffff
580 * and the second 0x0001 to signal a DLGTEMPLATEEX. Borland's
581 * compiler reverses the two words.
582 * I don't know which one to choose, but I write it as Mr. B
583 * writes it.
585 put_word(res, 1); /* Signature */
586 put_word(res, 0xffff); /* DlgVer */
587 put_dword(res, dlgex->gothelpid ? dlgex->helpid : 0);
588 put_dword(res, dlgex->gotexstyle ? dlgex->exstyle->or_mask : 0);
589 put_dword(res, dlgex->gotstyle ? dlgex->style->or_mask : WS_POPUPWINDOW);
590 tag_nctrl = res->size;
591 put_word(res, 0); /* Number of controls */
592 put_word(res, dlgex->x);
593 put_word(res, dlgex->y);
594 put_word(res, dlgex->width);
595 put_word(res, dlgex->height);
596 if(dlgex->menu)
597 put_name_id(res, dlgex->menu, TRUE);
598 else
599 put_word(res, 0);
600 if(dlgex->dlgclass)
601 put_name_id(res, dlgex->dlgclass, TRUE);
602 else
603 put_word(res, 0);
604 if(dlgex->title)
605 put_string(res, dlgex->title, str_unicode, TRUE);
606 else
607 put_word(res, 0);
608 if(dlgex->font)
610 put_word(res, dlgex->font->size);
611 put_word(res, dlgex->font->weight);
612 /* FIXME: ? TRUE should be sufficient to say that its
613 * italic, but Borland's compiler says its 0x0101.
614 * I just copy it here, and hope for the best.
616 put_word(res, dlgex->font->italic ? 0x0101 : 0);
617 put_string(res, dlgex->font->name, str_unicode, TRUE);
620 put_pad(res);
621 while(ctrl)
623 put_dword(res, ctrl->gothelpid ? ctrl->helpid : 0);
624 put_dword(res, ctrl->gotexstyle ? ctrl->exstyle->or_mask : 0);
625 /* FIXME: what is default control style? */
626 put_dword(res, ctrl->gotstyle ? ctrl->style->or_mask : WS_CHILD | WS_VISIBLE);
627 put_word(res, ctrl->x);
628 put_word(res, ctrl->y);
629 put_word(res, ctrl->width);
630 put_word(res, ctrl->height);
631 put_word(res, ctrl->id);
632 /* FIXME: Pad is _NOT_ documented!?! */
633 put_pad(res);
634 if(ctrl->ctlclass)
635 put_name_id(res, ctrl->ctlclass, TRUE);
636 else
637 internal_error(__FILE__, __LINE__, "Control has no control-class");
638 if(ctrl->title)
639 put_name_id(res, ctrl->title, FALSE);
640 else
641 put_word(res, 0);
642 if(ctrl->extra)
644 put_pad(res);
645 put_word(res, ctrl->extra->size);
646 put_raw_data(res, ctrl->extra, 0);
648 else
649 put_word(res, 0);
651 put_pad(res);
652 nctrl++;
653 ctrl = ctrl->next;
655 /* Set number of controls */
656 *(WORD *)&((char *)res->data)[tag_nctrl] = (WORD)nctrl;
657 /* Set ResourceSize */
658 SetResSize(res, restag);
659 put_pad(res);
661 else /* win16 */
663 /* Do not generate anything in 16-bit mode */
664 free(res->data);
665 free(res);
666 return NULL;
668 return res;
672 *****************************************************************************
673 * Function : menuitem2res
674 * Syntax : void menuitem2res(res_t *res, menu_item_t *item)
675 * Input :
676 * Output :
677 * Description :
678 * Remarks : Self recursive
679 *****************************************************************************
681 void menuitem2res(res_t *res, menu_item_t *menitem)
683 menu_item_t *itm = menitem;
684 if(win32)
686 while(itm)
688 put_word(res, itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0));
689 if(!itm->popup)
690 put_word(res, itm->id);
691 if(itm->name)
692 put_string(res, itm->name, str_unicode, TRUE);
693 else
694 put_word(res, 0);
695 if(itm->popup)
696 menuitem2res(res, itm->popup);
697 itm = itm->next;
700 else /* win16 */
702 while(itm)
704 put_word(res, itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0));
705 if(!itm->popup)
706 put_word(res, itm->id);
707 if(itm->name)
708 put_string(res, itm->name, str_char, TRUE);
709 else
710 put_byte(res, 0);
711 if(itm->popup)
712 menuitem2res(res, itm->popup);
713 itm = itm->next;
720 *****************************************************************************
721 * Function : menu2res
722 * Syntax : res_t *menu2res(name_id_t *name, menu_t *men)
723 * Input :
724 * name - Name/ordinal of the resource
725 * men - The menu descriptor
726 * Output : New .res format structure
727 * Description :
728 * Remarks :
729 *****************************************************************************
731 res_t *menu2res(name_id_t *name, menu_t *men)
733 int restag;
734 res_t *res;
735 assert(name != NULL);
736 assert(men != NULL);
738 res = new_res();
739 restag = put_res_header(res, WRC_RT_MENU, NULL, name, men->memopt, win32 ? &(men->lvc) : NULL);
741 put_dword(res, 0); /* Menuheader: Version and HeaderSize */
742 menuitem2res(res, men->items);
743 /* Set ResourceSize */
744 SetResSize(res, restag);
745 if(win32)
746 put_pad(res);
747 return res;
751 *****************************************************************************
752 * Function : menuexitem2res
753 * Syntax : void menuexitem2res(res_t *res, menuex_item_t *item)
754 * Input :
755 * Output : nop
756 * Description :
757 * Remarks : Self recursive
758 *****************************************************************************
760 void menuexitem2res(res_t *res, menuex_item_t *menitem)
762 menuex_item_t *itm = menitem;
763 assert(win32 != 0);
764 while(itm)
766 put_dword(res, itm->gottype ? itm->type : 0);
767 put_dword(res, itm->gotstate ? itm->state : 0);
768 put_dword(res, itm->gotid ? itm->id : 0); /* FIXME: Docu. says word */
769 put_word(res, (itm->popup ? 0x01 : 0) | (!itm->next ? MF_END : 0));
770 if(itm->name)
771 put_string(res, itm->name, str_unicode, TRUE);
772 else
773 put_word(res, 0);
774 put_pad(res);
775 if(itm->popup)
777 put_dword(res, itm->gothelpid ? itm->helpid : 0);
778 menuexitem2res(res, itm->popup);
780 itm = itm->next;
786 *****************************************************************************
787 * Function : menuex2res
788 * Syntax : res_t *menuex2res(name_id_t *name, menuex_t *menex)
789 * Input :
790 * name - Name/ordinal of the resource
791 * menex - The menuex descriptor
792 * Output : New .res format structure
793 * Description :
794 * Remarks :
795 *****************************************************************************
797 res_t *menuex2res(name_id_t *name, menuex_t *menex)
799 int restag;
800 res_t *res;
801 assert(name != NULL);
802 assert(menex != NULL);
804 res = new_res();
805 if(win32)
807 restag = put_res_header(res, WRC_RT_MENU, NULL, name, menex->memopt, &(menex->lvc));
809 put_word(res, 1); /* Menuheader: Version */
810 put_word(res, 4); /* Offset */
811 put_dword(res, 0); /* HelpId */
812 put_pad(res);
813 menuexitem2res(res, menex->items);
814 /* Set ResourceSize */
815 SetResSize(res, restag);
816 put_pad(res);
818 else /* win16 */
820 /* Do not generate anything in 16-bit mode */
821 free(res->data);
822 free(res);
823 return NULL;
825 return res;
829 *****************************************************************************
830 * Function : cursorgroup2res
831 * Syntax : res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
832 * Input :
833 * name - Name/ordinal of the resource
834 * curg - The cursor descriptor
835 * Output : New .res format structure
836 * Description :
837 * Remarks :
838 *****************************************************************************
840 res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
842 int restag;
843 res_t *res;
844 cursor_t *cur;
845 assert(name != NULL);
846 assert(curg != NULL);
848 res = new_res();
849 restag = put_res_header(res, WRC_RT_GROUP_CURSOR, NULL, name, curg->memopt, &(curg->lvc));
850 if(win32)
852 put_word(res, 0); /* Reserved */
853 /* FIXME: The ResType in the NEWHEADER structure should
854 * contain 14 according to the MS win32 doc. This is
855 * not the case with the BRC compiler and I really doubt
856 * the latter. Putting one here is compliant to win16 spec,
857 * but who knows the true value?
859 put_word(res, 2); /* ResType */
860 put_word(res, curg->ncursor);
861 #if 0
862 for(cur = curg->cursorlist; cur; cur = cur->next)
863 #else
864 cur = curg->cursorlist;
865 while(cur->next)
866 cur = cur->next;
867 for(; cur; cur = cur->prev)
868 #endif
870 put_word(res, cur->width);
871 /* FIXME: The height of a cursor is half the size of
872 * the bitmap's height. BRC puts the height from the
873 * BITMAPINFOHEADER here instead of the cursorfile's
874 * height. MS doesn't seem to care...
876 put_word(res, cur->height);
877 /* FIXME: The next two are reversed in BRC and I don't
878 * know why. Probably a bug. But, we can safely ignore
879 * it because win16 does not support color cursors.
880 * A warning should have been generated by the parser.
882 put_word(res, cur->planes);
883 put_word(res, cur->bits);
884 /* FIXME: The +4 is the hotspot in the cursor resource.
885 * However, I cound not find this in the documentation.
886 * The hotspot bytes must either be included or MS
887 * doesn't care.
889 put_dword(res, cur->data->size +4);
890 put_word(res, cur->id);
893 else /* win16 */
895 put_word(res, 0); /* Reserved */
896 put_word(res, 2); /* ResType */
897 put_word(res, curg->ncursor);
898 #if 0
899 for(cur = curg->cursorlist; cur; cur = cur->next)
900 #else
901 cur = curg->cursorlist;
902 while(cur->next)
903 cur = cur->next;
904 for(; cur; cur = cur->prev)
905 #endif
907 put_word(res, cur->width);
908 /* FIXME: The height of a cursor is half the size of
909 * the bitmap's height. BRC puts the height from the
910 * BITMAPINFOHEADER here instead of the cursorfile's
911 * height. MS doesn't seem to care...
913 put_word(res, cur->height);
914 /* FIXME: The next two are reversed in BRC and I don't
915 * know why. Probably a bug. But, we can safely ignore
916 * it because win16 does not support color cursors.
917 * A warning should have been generated by the parser.
919 put_word(res, cur->planes);
920 put_word(res, cur->bits);
921 /* FIXME: The +4 is the hotspot in the cursor resource.
922 * However, I cound not find this in the documentation.
923 * The hotspot bytes must either be included or MS
924 * doesn't care.
926 put_dword(res, cur->data->size +4);
927 put_word(res, cur->id);
930 SetResSize(res, restag); /* Set ResourceSize */
931 if(win32)
932 put_pad(res);
934 return res;
938 *****************************************************************************
939 * Function : cursor2res
940 * Syntax : res_t *cursor2res(cursor_t *cur)
941 * Input :
942 * cur - The cursor descriptor
943 * Output : New .res format structure
944 * Description :
945 * Remarks :
946 *****************************************************************************
948 res_t *cursor2res(cursor_t *cur)
950 int restag;
951 res_t *res;
952 name_id_t name;
954 assert(cur != NULL);
956 res = new_res();
957 name.type = name_ord;
958 name.name.i_name = cur->id;
959 restag = put_res_header(res, WRC_RT_CURSOR, NULL, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, &(cur->lvc));
960 put_word(res, cur->xhot);
961 put_word(res, cur->yhot);
962 put_raw_data(res, cur->data, 0);
964 SetResSize(res, restag); /* Set ResourceSize */
965 if(win32)
966 put_pad(res);
968 return res;
972 *****************************************************************************
973 * Function : icongroup2res
974 * Syntax : res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
975 * Input :
976 * name - Name/ordinal of the resource
977 * icog - The icon group descriptor
978 * Output : New .res format structure
979 * Description :
980 * Remarks :
981 *****************************************************************************
983 res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
985 int restag;
986 res_t *res;
987 icon_t *ico;
988 assert(name != NULL);
989 assert(icog != NULL);
991 res = new_res();
992 restag = put_res_header(res, WRC_RT_GROUP_ICON, NULL, name, icog->memopt, &(icog->lvc));
993 if(win32)
995 put_word(res, 0); /* Reserved */
996 /* FIXME: The ResType in the NEWHEADER structure should
997 * contain 14 according to the MS win32 doc. This is
998 * not the case with the BRC compiler and I really doubt
999 * the latter. Putting one here is compliant to win16 spec,
1000 * but who knows the true value?
1002 put_word(res, 1); /* ResType */
1003 put_word(res, icog->nicon);
1004 for(ico = icog->iconlist; ico; ico = ico->next)
1006 put_byte(res, ico->width);
1007 put_byte(res, ico->height);
1008 put_byte(res, ico->nclr);
1009 put_byte(res, 0); /* Reserved */
1010 put_word(res, ico->planes);
1011 put_word(res, ico->bits);
1012 put_dword(res, ico->data->size);
1013 put_word(res, ico->id);
1016 else /* win16 */
1018 put_word(res, 0); /* Reserved */
1019 put_word(res, 1); /* ResType */
1020 put_word(res, icog->nicon);
1021 for(ico = icog->iconlist; ico; ico = ico->next)
1023 put_byte(res, ico->width);
1024 put_byte(res, ico->height);
1025 put_byte(res, ico->nclr);
1026 put_byte(res, 0); /* Reserved */
1027 put_word(res, ico->planes);
1028 put_word(res, ico->bits);
1029 put_dword(res, ico->data->size);
1030 put_word(res, ico->id);
1033 SetResSize(res, restag); /* Set ResourceSize */
1034 if(win32)
1035 put_pad(res);
1037 return res;
1041 *****************************************************************************
1042 * Function : icon2res
1043 * Syntax : res_t *icon2res(icon_t *ico)
1044 * Input :
1045 * ico - The icon descriptor
1046 * Output : New .res format structure
1047 * Description :
1048 * Remarks :
1049 *****************************************************************************
1051 res_t *icon2res(icon_t *ico)
1053 int restag;
1054 res_t *res;
1055 name_id_t name;
1057 assert(ico != NULL);
1059 res = new_res();
1060 name.type = name_ord;
1061 name.name.i_name = ico->id;
1062 restag = put_res_header(res, WRC_RT_ICON, NULL, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, &(ico->lvc));
1063 put_raw_data(res, ico->data, 0);
1065 SetResSize(res, restag); /* Set ResourceSize */
1066 if(win32)
1067 put_pad(res);
1069 return res;
1073 *****************************************************************************
1074 * Function : bitmap2res
1075 * Syntax : res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
1076 * Input :
1077 * name - Name/ordinal of the resource
1078 * bmp - The bitmap descriptor
1079 * Output : New .res format structure
1080 * Description :
1081 * Remarks :
1082 *****************************************************************************
1084 res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
1086 int restag;
1087 res_t *res;
1088 assert(name != NULL);
1089 assert(bmp != NULL);
1091 HEAPCHECK();
1092 res = new_res();
1093 HEAPCHECK();
1094 restag = put_res_header(res, WRC_RT_BITMAP, NULL, name, bmp->memopt, NULL);
1095 HEAPCHECK();
1096 if(bmp->data->data[0] == 'B'
1097 && bmp->data->data[1] == 'M'
1098 && ((BITMAPFILEHEADER *)bmp->data->data)->bfSize == bmp->data->size
1099 && bmp->data->size >= sizeof(BITMAPFILEHEADER))
1101 /* The File header is still attached, don't write it */
1102 put_raw_data(res, bmp->data, sizeof(BITMAPFILEHEADER));
1104 else
1106 put_raw_data(res, bmp->data, 0);
1108 HEAPCHECK();
1109 /* Set ResourceSize */
1110 SetResSize(res, restag);
1111 HEAPCHECK();
1112 if(win32)
1113 put_pad(res);
1114 HEAPCHECK();
1115 return res;
1119 *****************************************************************************
1120 * Function : font2res
1121 * Syntax : res_t *font2res(name_id_t *name, font_t *fnt)
1122 * Input :
1123 * name - Name/ordinal of the resource
1124 * fnt - The font descriptor
1125 * Output : New .res format structure
1126 * Description :
1127 * Remarks :
1128 *****************************************************************************
1130 res_t *font2res(name_id_t *name, font_t *fnt)
1132 assert(name != NULL);
1133 assert(fnt != NULL);
1134 warning("Fonts not yet implemented");
1135 return NULL;
1139 *****************************************************************************
1140 * Function : rcdata2res
1141 * Syntax : res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
1142 * Input :
1143 * name - Name/ordinal of the resource
1144 * rdt - The rcdata descriptor
1145 * Output : New .res format structure
1146 * Description :
1147 * Remarks :
1148 *****************************************************************************
1150 res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
1152 int restag;
1153 res_t *res;
1154 assert(name != NULL);
1155 assert(rdt != NULL);
1157 res = new_res();
1158 restag = put_res_header(res, WRC_RT_RCDATA, NULL, name, rdt->memopt, NULL);
1159 put_raw_data(res, rdt->data, 0);
1160 /* Set ResourceSize */
1161 SetResSize(res, restag);
1162 if(win32)
1163 put_pad(res);
1164 return res;
1168 *****************************************************************************
1169 * Function : messagetable2res
1170 * Syntax : res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
1171 * Input :
1172 * name - Name/ordinal of the resource
1173 * msg - The messagetable descriptor
1174 * Output : New .res format structure
1175 * Description :
1176 * Remarks :
1177 *****************************************************************************
1179 res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
1181 assert(name != NULL);
1182 assert(msg != NULL);
1183 warning("Messagetable not yet implemented");
1184 return NULL;
1188 *****************************************************************************
1189 * Function : stringtable2res
1190 * Syntax : res_t *stringtable2res(stringtable_t *stt)
1191 * Input :
1192 * stt - The stringtable descriptor
1193 * Output : New .res format structure
1194 * Description :
1195 * Remarks :
1196 *****************************************************************************
1198 res_t *stringtable2res(stringtable_t *stt)
1200 res_t *res;
1201 name_id_t name;
1202 int i;
1203 int restag;
1204 DWORD lastsize = 0;
1206 assert(stt != NULL);
1207 res = new_res();
1209 for(; stt; stt = stt->next)
1211 if(!stt->nentries)
1213 warning("Empty internal stringtable");
1214 continue;
1216 name.type = name_ord;
1217 name.name.i_name = (stt->idbase >> 4) + 1;
1218 restag = put_res_header(res, WRC_RT_STRING, NULL, &name, stt->memopt, win32 ? &(stt->lvc) : NULL);
1219 for(i = 0; i < stt->nentries; i++)
1221 if(stt->entries[i].str)
1223 if(win32)
1224 put_word(res, stt->entries[i].str->size);
1225 else
1226 put_byte(res, stt->entries[i].str->size);
1227 put_string(res, stt->entries[i].str, win32 ? str_unicode : str_char, FALSE);
1229 else
1231 if(win32)
1232 put_word(res, 0);
1233 else
1234 put_byte(res, 0);
1237 /* Set ResourceSize */
1238 SetResSize(res, restag - lastsize);
1239 if(win32)
1240 put_pad(res);
1241 lastsize = res->size;
1243 return res;
1247 *****************************************************************************
1248 * Function : user2res
1249 * Syntax : res_t *user2res(name_id_t *name, user_t *usr)
1250 * Input :
1251 * name - Name/ordinal of the resource
1252 * usr - The userresource descriptor
1253 * Output : New .res format structure
1254 * Description :
1255 * Remarks :
1256 *****************************************************************************
1258 res_t *user2res(name_id_t *name, user_t *usr)
1260 int restag;
1261 res_t *res;
1262 assert(name != NULL);
1263 assert(usr != NULL);
1265 res = new_res();
1266 restag = put_res_header(res, 0, usr->type, name, usr->memopt, NULL);
1267 put_raw_data(res, usr->data, 0);
1268 /* Set ResourceSize */
1269 SetResSize(res, restag);
1270 if(win32)
1271 put_pad(res);
1272 return res;
1276 *****************************************************************************
1277 * Function : versionblock2res
1278 * Syntax : void versionblock2res(res_t *res, ver_block_t *blk)
1279 * Input :
1280 * res - Binary resource to write to
1281 * blk - The version block to be written
1282 * Output :
1283 * Description :
1284 * Remarks : Self recursive
1285 *****************************************************************************
1287 void versionblock2res(res_t *res, ver_block_t *blk, int level)
1289 ver_value_t *val;
1290 int blksizetag;
1291 int valblksizetag;
1292 int valvalsizetag;
1293 int tag;
1294 int i;
1296 blksizetag = res->size;
1297 put_word(res, 0); /* Will be overwritten later */
1298 put_word(res, 0);
1299 if(win32)
1300 put_word(res, 0); /* level ? */
1301 put_string(res, blk->name, win32 ? str_unicode : str_char, TRUE);
1302 put_pad(res);
1303 for(val = blk->values; val; val = val->next)
1305 if(val->type == val_str)
1307 valblksizetag = res->size;
1308 put_word(res, 0); /* Will be overwritten later */
1309 valvalsizetag = res->size;
1310 put_word(res, 0); /* Will be overwritten later */
1311 if(win32)
1313 put_word(res, level);
1315 put_string(res, val->key, win32 ? str_unicode : str_char, TRUE);
1316 put_pad(res);
1317 tag = res->size;
1318 put_string(res, val->value.str, win32 ? str_unicode : str_char, TRUE);
1319 if(win32)
1320 *(WORD *)&(res->data[valvalsizetag]) = (WORD)((res->size - tag) >> 1);
1321 else
1322 *(WORD *)&(res->data[valvalsizetag]) = (WORD)(res->size - tag);
1323 *(WORD *)&(res->data[valblksizetag]) = (WORD)(res->size - valblksizetag);
1324 put_pad(res);
1326 else if(val->type == val_words)
1328 valblksizetag = res->size;
1329 put_word(res, 0); /* Will be overwritten later */
1330 valvalsizetag = res->size;
1331 put_word(res, 0); /* Will be overwritten later */
1332 if(win32)
1334 put_word(res, level);
1336 put_string(res, val->key, win32 ? str_unicode : str_char, TRUE);
1337 put_pad(res);
1338 tag = res->size;
1339 for(i = 0; i < val->value.words->nwords; i++)
1341 put_word(res, val->value.words->words[i]);
1343 *(WORD *)&(res->data[valvalsizetag]) = (WORD)(res->size - tag);
1344 *(WORD *)&(res->data[valblksizetag]) = (WORD)(res->size - valblksizetag);
1345 put_pad(res);
1347 else if(val->type == val_block)
1349 versionblock2res(res, val->value.block, level+1);
1351 else
1353 internal_error(__FILE__, __LINE__, "Invalid value indicator %d in VERSIONINFO", val->type);
1357 /* Set blocksize */
1358 *(WORD *)&(res->data[blksizetag]) = (WORD)(res->size - blksizetag);
1362 *****************************************************************************
1363 * Function : versioninfo2res
1364 * Syntax : res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
1365 * Input :
1366 * name - Name/ordinal of the resource
1367 * ver - The versioninfo descriptor
1368 * Output : New .res format structure
1369 * Description :
1370 * Remarks :
1371 *****************************************************************************
1373 res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
1375 int restag;
1376 int rootblocksizetag;
1377 int valsizetag;
1378 int tag;
1379 res_t *res;
1380 string_t vsvi;
1381 ver_block_t *blk;
1383 assert(name != NULL);
1384 assert(ver != NULL);
1386 vsvi.type = str_char;
1387 vsvi.str.cstr = "VS_VERSION_INFO";
1388 vsvi.size = 15; /* Excl. termination */
1390 res = new_res();
1391 restag = put_res_header(res, WRC_RT_VERSION, NULL, name, WRC_MO_MOVEABLE | WRC_MO_PURE, NULL);
1392 rootblocksizetag = res->size;
1393 put_word(res, 0); /* BlockSize filled in later */
1394 valsizetag = res->size;
1395 put_word(res, 0); /* ValueSize filled in later*/
1396 if(win32)
1397 put_word(res, 0); /* Tree-level ? */
1398 put_string(res, &vsvi, win32 ? str_unicode : str_char, TRUE);
1399 if(win32)
1400 put_pad(res);
1401 tag = res->size;
1402 put_dword(res, VS_FFI_SIGNATURE);
1403 put_dword(res, VS_FFI_STRUCVERSION);
1404 put_dword(res, (ver->filever_maj1 << 16) + (ver->filever_maj2 & 0xffff));
1405 put_dword(res, (ver->filever_min1 << 16) + (ver->filever_min2 & 0xffff));
1406 put_dword(res, (ver->prodver_maj1 << 16) + (ver->prodver_maj2 & 0xffff));
1407 put_dword(res, (ver->prodver_min1 << 16) + (ver->prodver_min2 & 0xffff));
1408 put_dword(res, ver->fileflagsmask);
1409 put_dword(res, ver->fileflags);
1410 put_dword(res, ver->fileos);
1411 put_dword(res, ver->filetype);
1412 put_dword(res, ver->filesubtype);
1413 put_dword(res, 0); /* FileDateMS */
1414 put_dword(res, 0); /* FileDateLS */
1415 /* Set ValueSize */
1416 *(WORD *)&(res->data[valsizetag]) = (WORD)(res->size - tag);
1417 /* Descend into the blocks */
1418 for(blk = ver->blocks; blk; blk = blk->next)
1419 versionblock2res(res, blk, 0);
1420 /* Set root block's size */
1421 *(WORD *)&(res->data[rootblocksizetag]) = (WORD)(res->size - rootblocksizetag);
1423 SetResSize(res, restag);
1424 if(win32)
1425 put_pad(res);
1427 return res;
1431 *****************************************************************************
1432 * Function : toolbaritem2res
1433 * Syntax : void toolbaritem2res(res_t *res, toolbar_item_t *tbitem)
1434 * Input :
1435 * Output : nop
1436 * Description :
1437 * Remarks : Self recursive
1438 *****************************************************************************
1440 void toolbaritem2res(res_t *res, toolbar_item_t *tbitem)
1442 toolbar_item_t *itm = tbitem;
1443 assert(win32 != 0);
1444 while(itm)
1446 put_word(res, itm->id);
1447 itm = itm->next;
1453 *****************************************************************************
1454 * Function : toolbar2res
1455 * Syntax : res_t *toolbar2res(name_id_t *name, toolbar_t *toolbar)
1456 * Input :
1457 * name - Name/ordinal of the resource
1458 * toolbar - The toolbar descriptor
1459 * Output : New .res format structure
1460 * Description :
1461 * Remarks :
1462 *****************************************************************************
1464 res_t *toolbar2res(name_id_t *name, toolbar_t *toolbar)
1466 int restag;
1467 res_t *res;
1468 assert(name != NULL);
1469 assert(toolbar != NULL);
1471 res = new_res();
1472 if(win32)
1474 restag = put_res_header(res, WRC_RT_TOOLBAR, NULL, name, toolbar->memopt, &(toolbar->lvc));
1476 put_word(res, 1); /* Menuheader: Version */
1477 put_word(res, toolbar->button_width); /* (in pixels?) */
1478 put_word(res, toolbar->button_height); /* (in pixels?) */
1479 put_word(res, toolbar->nitems);
1480 put_pad(res);
1481 toolbaritem2res(res, toolbar->items);
1482 /* Set ResourceSize */
1483 SetResSize(res, restag);
1484 put_pad(res);
1486 else /* win16 */
1488 /* Do not generate anything in 16-bit mode */
1489 free(res->data);
1490 free(res);
1491 return NULL;
1493 return res;
1497 *****************************************************************************
1498 * Function : dlginit2res
1499 * Syntax : res_t *dlginit2res(name_id_t *name, dlginit_t *dit)
1500 * Input :
1501 * name - Name/ordinal of the resource
1502 * rdt - The dlginit descriptor
1503 * Output : New .res format structure
1504 * Description :
1505 * Remarks :
1506 *****************************************************************************
1508 res_t *dlginit2res(name_id_t *name, dlginit_t *dit)
1510 int restag;
1511 res_t *res;
1512 assert(name != NULL);
1513 assert(dit != NULL);
1515 res = new_res();
1516 restag = put_res_header(res, WRC_RT_DLGINIT, NULL, name, dit->memopt, &(dit->lvc));
1517 put_raw_data(res, dit->data, 0);
1518 /* Set ResourceSize */
1519 SetResSize(res, restag);
1520 if(win32)
1521 put_pad(res);
1522 return res;
1526 *****************************************************************************
1527 * Function : prep_nid_for_label
1528 * Syntax : char *prep_nid_for_label(name_id_t *nid)
1529 * Input :
1530 * Output :
1531 * Description : Converts a resource name into the first 32 (or less)
1532 * characters of the name with conversions.
1533 * Remarks :
1534 *****************************************************************************
1536 #define MAXNAMELEN 32
1537 char *prep_nid_for_label(name_id_t *nid)
1539 static char buf[MAXNAMELEN+1];
1541 assert(nid != NULL);
1543 if(nid->type == name_str && nid->name.s_name->type == str_unicode)
1545 short *sptr;
1546 int i;
1547 sptr = nid->name.s_name->str.wstr;
1548 buf[0] = '\0';
1549 for(i = 0; *sptr && i < MAXNAMELEN; i++)
1551 if((unsigned)*sptr < 0x80 && isprint((char)*sptr))
1552 buf[i] = *sptr++;
1553 else
1554 warning("Resourcename (str_unicode) contain unprintable characters or invalid translation, ignored");
1556 buf[i] = '\0';
1558 else if(nid->type == name_str && nid->name.s_name->type == str_char)
1560 char *cptr;
1561 int i;
1562 cptr = nid->name.s_name->str.cstr;
1563 buf[0] = '\0';
1564 for(i = 0; *cptr && i < MAXNAMELEN; i++)
1566 if((unsigned)*cptr < 0x80 && isprint(*cptr))
1567 buf[i] = *cptr++;
1568 else
1569 warning("Resourcename (str_char) contain unprintable characters, ignored");
1571 buf[i] = '\0';
1573 else if(nid->type == name_ord)
1575 sprintf(buf, "%u", nid->name.i_name);
1577 else
1579 internal_error(__FILE__, __LINE__, "Resource name_id with invalid type %d", nid->type);
1581 return buf;
1583 #undef MAXNAMELEN
1586 *****************************************************************************
1587 * Function : make_c_name
1588 * Syntax : char *make_c_name(char *base, name_id_t *nid, language_t *lan)
1589 * Input :
1590 * Output :
1591 * Description : Converts a resource name into a valid c-identifier in the
1592 * form "_base_nid".
1593 * Remarks :
1594 *****************************************************************************
1596 char *make_c_name(char *base, name_id_t *nid, language_t *lan)
1598 int nlen;
1599 char *buf;
1600 char *ret;
1601 char lanbuf[6];
1603 sprintf(lanbuf, "%d", lan ? MAKELANGID(lan->id, lan->sub) : 0);
1604 buf = prep_nid_for_label(nid);
1605 nlen = strlen(buf) + strlen(lanbuf);
1606 nlen += strlen(base) + 4; /* three time '_' and '\0' */
1607 ret = (char *)xmalloc(nlen);
1608 strcpy(ret, "_");
1609 strcat(ret, base);
1610 strcat(ret, "_");
1611 strcat(ret, buf);
1612 strcat(ret, "_");
1613 strcat(ret, lanbuf);
1614 return ret;
1618 *****************************************************************************
1619 * Function : get_c_typename
1620 * Syntax : char *get_c_typename(enum res_e type)
1621 * Input :
1622 * Output :
1623 * Description : Convert resource enum to char string to be used in c-name
1624 * creation.
1625 * Remarks :
1626 *****************************************************************************
1628 char *get_c_typename(enum res_e type)
1630 switch(type)
1632 case res_acc: return "Acc";
1633 case res_bmp: return "Bmp";
1634 case res_cur: return "Cur";
1635 case res_curg: return "CurGrp";
1636 case res_dlg:
1637 case res_dlgex: return "Dlg";
1638 case res_fnt: return "Fnt";
1639 case res_ico: return "Ico";
1640 case res_icog: return "IcoGrp";
1641 case res_men:
1642 case res_menex: return "Men";
1643 case res_rdt: return "RCDat";
1644 case res_stt: return "StrTab";
1645 case res_usr: return "Usr";
1646 case res_msg: return "MsgTab";
1647 case res_ver: return "VerInf";
1648 case res_toolbar: return "TlBr";
1649 case res_dlginit: return "DlgInit";
1650 default: return "Oops";
1655 *****************************************************************************
1656 * Function : resources2res
1657 * Syntax : void resources2res(resource_t *top)
1658 * Input :
1659 * top - The resource-tree to convert
1660 * Output :
1661 * Description : Convert logical resource descriptors into binary data
1662 * Remarks :
1663 *****************************************************************************
1665 void resources2res(resource_t *top)
1667 while(top)
1669 switch(top->type)
1671 case res_acc:
1672 if(!top->binres)
1673 top->binres = accelerator2res(top->name, top->res.acc);
1674 break;
1675 case res_bmp:
1676 if(!top->binres)
1677 top->binres = bitmap2res(top->name, top->res.bmp);
1678 break;
1679 case res_cur:
1680 if(!top->binres)
1681 top->binres = cursor2res(top->res.cur);
1682 break;
1683 case res_curg:
1684 if(!top->binres)
1685 top->binres = cursorgroup2res(top->name, top->res.curg);
1686 break;
1687 case res_dlg:
1688 if(!top->binres)
1689 top->binres = dialog2res(top->name, top->res.dlg);
1690 break;
1691 case res_dlgex:
1692 if(!top->binres)
1693 top->binres = dialogex2res(top->name, top->res.dlgex);
1694 break;
1695 case res_fnt:
1696 if(!top->binres)
1697 top->binres = font2res(top->name, top->res.fnt);
1698 break;
1699 case res_ico:
1700 if(!top->binres)
1701 top->binres = icon2res(top->res.ico);
1702 break;
1703 case res_icog:
1704 if(!top->binres)
1705 top->binres = icongroup2res(top->name, top->res.icog);
1706 break;
1707 case res_men:
1708 if(!top->binres)
1709 top->binres = menu2res(top->name, top->res.men);
1710 break;
1711 case res_menex:
1712 if(!top->binres)
1713 top->binres = menuex2res(top->name, top->res.menex);
1714 break;
1715 case res_rdt:
1716 if(!top->binres)
1717 top->binres = rcdata2res(top->name, top->res.rdt);
1718 break;
1719 case res_stt:
1720 if(!top->binres)
1721 top->binres = stringtable2res(top->res.stt);
1722 break;
1723 case res_usr:
1724 if(!top->binres)
1725 top->binres = user2res(top->name, top->res.usr);
1726 break;
1727 case res_msg:
1728 if(!top->binres)
1729 top->binres = messagetable2res(top->name, top->res.msg);
1730 break;
1731 case res_ver:
1732 if(!top->binres)
1733 top->binres = versioninfo2res(top->name, top->res.ver);
1734 break;
1735 case res_toolbar:
1736 if(!top->binres)
1737 top->binres = toolbar2res(top->name, top->res.tbt);
1738 break;
1739 case res_dlginit:
1740 if(!top->binres)
1741 top->binres = dlginit2res(top->name, top->res.dlgi);
1742 break;
1744 default:
1745 internal_error(__FILE__, __LINE__, "Unknown resource type encountered %d in binary res generation", top->type);
1747 top->c_name = make_c_name(get_c_typename(top->type), top->name, top->lan);
1748 top = top->next;