1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198 |
- /*
- * Generate .res format from a resource-tree
- *
- * Copyright 1998 Bertho A. Stultiens
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * History:
- * 05-May-2000 BS - Added code to support endian conversions. The
- * extra functions also aid unaligned access, but
- * this is not yet implemented.
- * 25-May-1998 BS - Added simple unicode -> char conversion for resource
- * names in .s and .h files.
- */
- #include "config.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <assert.h>
- #include <ctype.h>
- #include "../tools.h"
- #include "wrc.h"
- #include "utils.h"
- #include "windef.h"
- #include "winbase.h"
- #include "wingdi.h"
- #include "winuser.h"
- unsigned char *output_buffer = NULL;
- size_t output_buffer_pos = 0;
- size_t output_buffer_size = 0;
- static void set_word(int ofs, unsigned int w)
- {
- output_buffer[ofs+0] = w;
- output_buffer[ofs+1] = w >> 8;
- }
- static void set_dword(int ofs, unsigned int d)
- {
- output_buffer[ofs+0] = d;
- output_buffer[ofs+1] = d >> 8;
- output_buffer[ofs+2] = d >> 16;
- output_buffer[ofs+3] = d >> 24;
- }
- static unsigned int get_dword(int ofs)
- {
- return (output_buffer[ofs+3] << 24)
- | (output_buffer[ofs+2] << 16)
- | (output_buffer[ofs+1] << 8)
- | output_buffer[ofs+0];
- }
- static void set_res_size(int tag)
- {
- set_dword( tag, output_buffer_pos - tag - get_dword(tag) );
- }
- /*
- *****************************************************************************
- * Function : string_to_upper
- * Syntax : void string_to_upper(string_t *str)
- *****************************************************************************
- */
- static void string_to_upper(string_t *str)
- {
- int i;
- switch (str->type)
- {
- case str_char:
- for (i = 0; i < str->size; i++)
- if (str->str.cstr[i] >= 'a' && str->str.cstr[i] <= 'z') str->str.cstr[i] -= 32;
- break;
- case str_unicode:
- for (i = 0; i < str->size; i++)
- if (str->str.wstr[i] >= 'a' && str->str.wstr[i] <= 'z') str->str.wstr[i] -= 32;
- break;
- }
- }
- static int parse_accel_string( const string_t *key, int flags )
- {
- int keycode = 0;
- switch (key->type)
- {
- case str_char:
- if (key->str.cstr[0] == '#') return 0; /* ignore message contexts */
- if((flags & WRC_AF_VIRTKEY) &&
- !((key->str.cstr[0] >= 'A' && key->str.cstr[0] <= 'Z') ||
- (key->str.cstr[0] >= '0' && key->str.cstr[0] <= '9')))
- {
- print_location( &key->loc );
- error("VIRTKEY code is not equal to ascii value\n");
- }
- if(key->str.cstr[0] == '^' && (flags & WRC_AF_CONTROL) != 0)
- {
- print_location( &key->loc );
- error("Cannot use both '^' and CONTROL modifier\n");
- }
- else if(key->str.cstr[0] == '^')
- {
- if (key->str.cstr[1] >= 'a' && key->str.cstr[1] <= 'z')
- keycode = key->str.cstr[1] - 'a' + 1;
- else if (key->str.cstr[1] >= 'A' && key->str.cstr[1] <= 'Z')
- keycode = key->str.cstr[1] - 'A' + 1;
- else
- {
- print_location( &key->loc );
- error("Control-code out of range\n");
- }
- }
- else
- keycode = key->str.cstr[0];
- break;
- case str_unicode:
- if (key->str.wstr[0] == '#') return 0; /* ignore message contexts */
- if((flags & WRC_AF_VIRTKEY) &&
- !((key->str.wstr[0] >= 'A' && key->str.wstr[0] <= 'Z') ||
- (key->str.wstr[0] >= '0' && key->str.wstr[0] <= '9')))
- {
- print_location( &key->loc );
- error("VIRTKEY code is not equal to ascii value\n");
- }
- if(key->str.wstr[0] == '^' && (flags & WRC_AF_CONTROL) != 0)
- {
- print_location( &key->loc );
- error("Cannot use both '^' and CONTROL modifier\n");
- }
- else if(key->str.wstr[0] == '^')
- {
- if (key->str.wstr[1] >= 'a' && key->str.wstr[1] <= 'z')
- keycode = key->str.wstr[1] - 'a' + 1;
- else if (key->str.wstr[1] >= 'A' && key->str.wstr[1] <= 'Z')
- keycode = key->str.wstr[1] - 'A' + 1;
- else
- {
- print_location( &key->loc );
- error("Control-code out of range\n");
- }
- }
- else
- keycode = key->str.wstr[0];
- break;
- }
- return keycode;
- }
- /*
- *****************************************************************************
- * Function : put_string
- * Input :
- * str - String to put
- * isterm - The string is '\0' terminated (disregard the string's
- * size member)
- *****************************************************************************
- */
- static void put_string(const string_t *str, int isterm, const language_t *lang)
- {
- int cnt, codepage;
- if (win32)
- {
- string_t *newstr;
- if (lang) codepage = get_language_codepage( lang->id, lang->sub );
- else codepage = get_language_codepage( 0, 0 );
- assert( codepage != -1 );
- newstr = convert_string_unicode( str, codepage );
- if (str->type == str_char && check_valid_utf8( str, codepage ))
- {
- print_location( &str->loc );
- warning( "string \"%s\" seems to be UTF-8 but codepage %u is in use, maybe use --utf8?\n",
- str->str.cstr, codepage );
- }
- if (!isterm) put_word(newstr->size);
- for(cnt = 0; cnt < newstr->size; cnt++)
- {
- WCHAR c = newstr->str.wstr[cnt];
- if (isterm && !c) break;
- put_word(c);
- }
- if (isterm) put_word(0);
- free_string(newstr);
- }
- else
- {
- assert( str->type == str_char );
- if (!isterm) put_byte(str->size);
- for(cnt = 0; cnt < str->size; cnt++)
- {
- char c = str->str.cstr[cnt];
- if (isterm && !c) break;
- put_byte(c);
- }
- if (isterm) put_byte(0);
- }
- }
- /*
- *****************************************************************************
- * Function : put_name_id
- *****************************************************************************
- */
- static void put_name_id(name_id_t *nid, int upcase, const language_t *lang)
- {
- switch (nid->type)
- {
- case name_ord:
- if(win32)
- put_word(0xffff);
- else
- put_byte(0xff);
- put_word((WORD)nid->name.i_name);
- break;
- case name_str:
- if(upcase)
- string_to_upper(nid->name.s_name);
- put_string(nid->name.s_name, TRUE, lang);
- break;
- }
- }
- /*
- *****************************************************************************
- * Function : put_lvc
- *****************************************************************************
- */
- static void put_lvc(lvc_t *lvc)
- {
- if(lvc && lvc->language)
- put_word(MAKELANGID(lvc->language->id, lvc->language->sub));
- else
- put_word(0); /* Neutral */
- if(lvc && lvc->version)
- put_dword(*lvc->version);
- else
- put_dword(0);
- if(lvc && lvc->characts)
- put_dword(*lvc->characts);
- else
- put_dword(0);
- }
- /*
- *****************************************************************************
- * Function : put_res_header
- * Input :
- * type - Resource identifier
- * name - Resource's name
- * memopt - Resource's memory options to write
- * lvc - Language, version and characteristics (win32 only)
- * Output : An index to the resource size field. The resource size field
- * contains the header size upon exit.
- *****************************************************************************
- */
- static int put_res_header(int type, name_id_t *name, DWORD memopt, lvc_t *lvc)
- {
- int tag = output_buffer_pos;
- if(win32)
- {
- put_dword(0); /* We will overwrite these later */
- put_dword(0);
- put_word(0xffff); /* ResType */
- put_word(type);
- put_name_id(name, TRUE, lvc->language); /* ResName */
- align_output(4);
- put_dword(0); /* DataVersion */
- put_word(memopt); /* Memory options */
- put_lvc(lvc); /* Language, version and characts */
- set_dword(tag + 0, output_buffer_pos - tag);
- set_dword(tag + 4, output_buffer_pos - tag); /* Set HeaderSize */
- }
- else /* win16 */
- {
- put_byte(0xff); /* ResType */
- put_word(type);
- put_name_id(name, TRUE, NULL); /* ResName */
- put_word(memopt); /* Memory options */
- tag = output_buffer_pos;
- put_dword(4); /* ResSize overwritten later*/
- }
- return tag;
- }
- /*
- *****************************************************************************
- * Function : accelerator2res
- * Input :
- * name - Name/ordinal of the resource
- * acc - The accelerator descriptor
- *****************************************************************************
- */
- static void accelerator2res(name_id_t *name, accelerator_t *acc)
- {
- int restag;
- event_t *ev;
- restag = put_res_header(WRC_RT_ACCELERATOR, name, acc->memopt, &acc->lvc);
- if(win32)
- {
- for (ev = acc->events; ev; ev = ev->next)
- {
- int key = ev->key;
- if (ev->str) key = parse_accel_string( ev->str, ev->flags );
- put_word(ev->flags | (ev->next ? 0 : 0x80));
- put_word(key);
- put_word(ev->id);
- align_output(4);
- }
- }
- else /* win16 */
- {
- for (ev = acc->events; ev; ev = ev->next)
- {
- int key = ev->key;
- if (ev->str) key = parse_accel_string( ev->str, ev->flags );
- put_byte(ev->flags | (ev->next ? 0 : 0x80));
- put_word(key);
- put_word(ev->id);
- }
- }
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : dialog2res
- * Input :
- * name - Name/ordinal of the resource
- * dlg - The dialog descriptor
- *****************************************************************************
- */
- static void dialog2res(name_id_t *name, dialog_t *dlg)
- {
- int restag;
- control_t *ctrl;
- int nctrl;
- restag = put_res_header(WRC_RT_DIALOG, name, dlg->memopt, &dlg->lvc);
- for (ctrl = dlg->controls, nctrl = 0; ctrl; ctrl = ctrl->next) nctrl++;
- if(win32)
- {
- if (dlg->is_ex)
- {
- /* FIXME: MS doc says that the first word must contain 0xffff
- * and the second 0x0001 to signal a DLGTEMPLATEEX. Borland's
- * compiler reverses the two words.
- * I don't know which one to choose, but I write it as Mr. B
- * writes it.
- */
- put_word(1); /* Signature */
- put_word(0xffff); /* DlgVer */
- put_dword(dlg->gothelpid ? dlg->helpid : 0);
- put_dword(dlg->gotexstyle ? dlg->exstyle->or_mask : 0);
- put_dword(dlg->gotstyle ? dlg->style->or_mask : WS_POPUPWINDOW);
- }
- else
- {
- put_dword(dlg->style->or_mask);
- put_dword(dlg->gotexstyle ? dlg->exstyle->or_mask : 0);
- }
- put_word(nctrl);
- put_word(dlg->x);
- put_word(dlg->y);
- put_word(dlg->width);
- put_word(dlg->height);
- if(dlg->menu)
- put_name_id(dlg->menu, FALSE, dlg->lvc.language);
- else
- put_word(0);
- if(dlg->dlgclass)
- put_name_id(dlg->dlgclass, FALSE, dlg->lvc.language);
- else
- put_word(0);
- if(dlg->title)
- put_string(dlg->title, TRUE, dlg->lvc.language);
- else
- put_word(0);
- if(dlg->font)
- {
- put_word(dlg->font->size);
- if (dlg->is_ex)
- {
- put_word(dlg->font->weight);
- /* FIXME: ? TRUE should be sufficient to say that it's
- * italic, but Borland's compiler says it's 0x0101.
- * I just copy it here, and hope for the best.
- */
- put_word(dlg->font->italic ? 0x0101 : 0);
- }
- put_string(dlg->font->name, TRUE, dlg->lvc.language);
- }
- else if (dlg->style->or_mask & DS_SETFONT) put_word( 0x7fff );
- align_output(4);
- for (ctrl = dlg->controls; ctrl; ctrl = ctrl->next)
- {
- if (dlg->is_ex)
- {
- put_dword(ctrl->gothelpid ? ctrl->helpid : 0);
- put_dword(ctrl->gotexstyle ? ctrl->exstyle->or_mask : 0);
- /* FIXME: what is default control style? */
- put_dword(ctrl->gotstyle ? ctrl->style->or_mask : WS_CHILD | WS_VISIBLE);
- }
- else
- {
- /* FIXME: what is default control style? */
- put_dword(ctrl->gotstyle ? ctrl->style->or_mask: WS_CHILD);
- put_dword(ctrl->gotexstyle ? ctrl->exstyle->or_mask : 0);
- }
- put_word(ctrl->x);
- put_word(ctrl->y);
- put_word(ctrl->width);
- put_word(ctrl->height);
- if (dlg->is_ex)
- put_dword(ctrl->id);
- else
- put_word(ctrl->id);
- put_name_id(ctrl->ctlclass, FALSE, dlg->lvc.language);
- if(ctrl->title)
- put_name_id(ctrl->title, FALSE, dlg->lvc.language);
- else
- put_word(0);
- if(ctrl->extra)
- {
- put_word(ctrl->extra->size);
- put_data(ctrl->extra->data, ctrl->extra->size);
- }
- else
- put_word(0);
- if(ctrl->next)
- align_output(4);
- }
- }
- else /* win16 */
- {
- restag = put_res_header(WRC_RT_DIALOG, name, dlg->memopt, NULL);
- put_dword(dlg->gotstyle ? dlg->style->or_mask : WS_POPUPWINDOW);
- put_byte(nctrl);
- put_word(dlg->x);
- put_word(dlg->y);
- put_word(dlg->width);
- put_word(dlg->height);
- if(dlg->menu)
- put_name_id(dlg->menu, TRUE, NULL);
- else
- put_byte(0);
- if(dlg->dlgclass)
- put_name_id(dlg->dlgclass, TRUE, NULL);
- else
- put_byte(0);
- if(dlg->title)
- put_string(dlg->title, TRUE, NULL);
- else
- put_byte(0);
- if(dlg->font)
- {
- put_word(dlg->font->size);
- put_string(dlg->font->name, TRUE, NULL);
- }
- for (ctrl = dlg->controls; ctrl; ctrl = ctrl->next)
- {
- put_word(ctrl->x);
- put_word(ctrl->y);
- put_word(ctrl->width);
- put_word(ctrl->height);
- put_word(ctrl->id);
- put_dword(ctrl->gotstyle ? ctrl->style->or_mask: WS_CHILD);
- if(ctrl->ctlclass->type == name_ord
- && ctrl->ctlclass->name.i_name >= 0x80
- && ctrl->ctlclass->name.i_name <= 0x85)
- put_byte(ctrl->ctlclass->name.i_name);
- else if(ctrl->ctlclass->type == name_str)
- put_name_id(ctrl->ctlclass, FALSE, NULL);
- else
- error("Unknown control-class %04x\n", ctrl->ctlclass->name.i_name);
- if(ctrl->title)
- put_name_id(ctrl->title, FALSE, NULL);
- else
- put_byte(0);
- /* FIXME: What is this extra byte doing here? */
- put_byte(0);
- }
- }
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : menuitem2res
- * Remarks : Self recursive
- *****************************************************************************
- */
- static void menuitem2res(menu_item_t *menitem, const language_t *lang)
- {
- menu_item_t *itm = menitem;
- while(itm)
- {
- put_word(itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0));
- if(!itm->popup)
- put_word(itm->id);
- if(itm->name)
- put_string(itm->name, TRUE, lang);
- else
- {
- if (win32) put_word(0);
- else put_byte(0);
- }
- if(itm->popup)
- menuitem2res(itm->popup, lang);
- itm = itm->next;
- }
- }
- /*
- *****************************************************************************
- * Function : menuexitem2res
- * Remarks : Self recursive
- *****************************************************************************
- */
- static void menuexitem2res(menu_item_t *menitem, const language_t *lang)
- {
- menu_item_t *itm = menitem;
- assert(win32 != 0);
- while(itm)
- {
- put_dword(itm->gottype ? itm->type : 0);
- put_dword(itm->gotstate ? itm->state : 0);
- put_dword(itm->gotid ? itm->id : 0);
- put_word((itm->popup ? 0x01 : 0) | (!itm->next ? MF_END : 0));
- if(itm->name)
- put_string(itm->name, TRUE, lang);
- else
- put_word(0);
- align_output(4);
- if(itm->popup)
- {
- put_dword(itm->gothelpid ? itm->helpid : 0);
- menuexitem2res(itm->popup, lang);
- }
- itm = itm->next;
- }
- }
- /*
- *****************************************************************************
- * Function : menu2res
- * Input :
- * name - Name/ordinal of the resource
- * menex - The menuex descriptor
- *****************************************************************************
- */
- static void menu2res(name_id_t *name, menu_t *men)
- {
- int restag;
- assert(name != NULL);
- assert(men != NULL);
- restag = put_res_header(WRC_RT_MENU, name, men->memopt, &men->lvc);
- if(win32)
- {
- if (men->is_ex)
- {
- put_word(1); /* Menuheader: Version */
- put_word(4); /* Offset */
- put_dword(0); /* HelpId */
- align_output(4);
- menuexitem2res(men->items, men->lvc.language);
- }
- else
- {
- put_dword(0); /* Menuheader: Version and HeaderSize */
- menuitem2res(men->items, men->lvc.language);
- }
- }
- else /* win16 */
- {
- put_dword(0); /* Menuheader: Version and HeaderSize */
- menuitem2res(men->items, NULL);
- }
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : cursorgroup2res
- * Input :
- * name - Name/ordinal of the resource
- * curg - The cursor descriptor
- *****************************************************************************
- */
- static void cursorgroup2res(name_id_t *name, cursor_group_t *curg)
- {
- int restag;
- cursor_t *cur;
- restag = put_res_header(WRC_RT_GROUP_CURSOR, name, curg->memopt, &curg->lvc);
- put_word(0); /* Reserved */
- /* FIXME: The ResType in the NEWHEADER structure should
- * contain 14 according to the MS win32 doc. This is
- * not the case with the BRC compiler and I really doubt
- * the latter. Putting one here is compliant to win16 spec,
- * but who knows the true value?
- */
- put_word(2); /* ResType */
- put_word(curg->ncursor);
- #if 0
- for(cur = curg->cursorlist; cur; cur = cur->next)
- #else
- cur = curg->cursorlist;
- while(cur->next)
- cur = cur->next;
- for(; cur; cur = cur->prev)
- #endif
- {
- put_word(cur->width);
- /* FIXME: The height of a cursor is half the size of
- * the bitmap's height. BRC puts the height from the
- * BITMAPINFOHEADER here instead of the cursorfile's
- * height. MS doesn't seem to care...
- */
- put_word(cur->height);
- /* FIXME: The next two are reversed in BRC and I don't
- * know why. Probably a bug. But, we can safely ignore
- * it because win16 does not support color cursors.
- * A warning should have been generated by the parser.
- */
- put_word(cur->planes);
- put_word(cur->bits);
- /* FIXME: The +4 is the hotspot in the cursor resource.
- * However, I could not find this in the documentation.
- * The hotspot bytes must either be included or MS
- * doesn't care.
- */
- put_dword(cur->data->size +4);
- put_word(cur->id);
- }
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : cursor2res
- * Input :
- * cur - The cursor descriptor
- *****************************************************************************
- */
- static void cursor2res(cursor_t *cur)
- {
- int restag;
- name_id_t name;
- name.type = name_ord;
- name.name.i_name = cur->id;
- restag = put_res_header(WRC_RT_CURSOR, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, &cur->lvc);
- put_word(cur->xhot);
- put_word(cur->yhot);
- put_data(cur->data->data, cur->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : icongroup2res
- * Input :
- * name - Name/ordinal of the resource
- * icog - The icon group descriptor
- *****************************************************************************
- */
- static void icongroup2res(name_id_t *name, icon_group_t *icog)
- {
- int restag;
- icon_t *ico;
- restag = put_res_header(WRC_RT_GROUP_ICON, name, icog->memopt, &icog->lvc);
- put_word(0); /* Reserved */
- /* FIXME: The ResType in the NEWHEADER structure should
- * contain 14 according to the MS win32 doc. This is
- * not the case with the BRC compiler and I really doubt
- * the latter. Putting one here is compliant to win16 spec,
- * but who knows the true value?
- */
- put_word(1); /* ResType */
- put_word(icog->nicon);
- for(ico = icog->iconlist; ico; ico = ico->next)
- {
- put_byte(ico->width);
- put_byte(ico->height);
- put_byte(ico->nclr);
- put_byte(0); /* Reserved */
- put_word(ico->planes);
- put_word(ico->bits);
- put_dword(ico->data->size);
- put_word(ico->id);
- }
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : icon2res
- * Input :
- * ico - The icon descriptor
- *****************************************************************************
- */
- static void icon2res(icon_t *ico)
- {
- int restag;
- name_id_t name;
- name.type = name_ord;
- name.name.i_name = ico->id;
- restag = put_res_header(WRC_RT_ICON, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, &ico->lvc);
- put_data(ico->data->data, ico->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : anicurico2res
- * Input :
- * name - Name/ordinal of the resource
- * ani - The animated object descriptor
- * Remarks : There are rumors that win311 could handle animated stuff.
- * That is why they are generated for both win16 and win32
- * compile.
- *****************************************************************************
- */
- static void anicur2res(name_id_t *name, ani_curico_t *ani)
- {
- int restag = put_res_header(WRC_RT_ANICURSOR, name, ani->memopt, NULL);
- put_data(ani->data->data, ani->data->size);
- set_res_size(restag);
- }
- static void aniico2res(name_id_t *name, ani_curico_t *ani)
- {
- int restag = put_res_header(WRC_RT_ANIICON, name, ani->memopt, NULL);
- put_data(ani->data->data, ani->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : bitmap2res
- * Input :
- * name - Name/ordinal of the resource
- * bmp - The bitmap descriptor
- *****************************************************************************
- */
- static void bitmap2res(name_id_t *name, bitmap_t *bmp)
- {
- int restag = put_res_header(WRC_RT_BITMAP, name, bmp->memopt, &bmp->data->lvc);
- if(bmp->data->data[0] == 'B'
- && bmp->data->data[1] == 'M'
- && ((BITMAPFILEHEADER *)bmp->data->data)->bfSize == bmp->data->size
- && bmp->data->size >= sizeof(BITMAPFILEHEADER))
- {
- /* The File header is still attached, don't write it */
- put_data((BITMAPFILEHEADER *)bmp->data->data + 1, bmp->data->size - sizeof(BITMAPFILEHEADER));
- }
- else
- {
- put_data(bmp->data->data, bmp->data->size);
- }
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : font2res
- * Input :
- * name - Name/ordinal of the resource
- * fnt - The font descriptor
- * Remarks : The data has been prepared just after parsing.
- *****************************************************************************
- */
- static void font2res(name_id_t *name, font_t *fnt)
- {
- int restag = put_res_header(WRC_RT_FONT, name, fnt->memopt, &fnt->data->lvc);
- put_data(fnt->data->data, fnt->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : fontdir2res
- * Input :
- * name - Name/ordinal of the resource
- * fntdir - The fontdir descriptor
- * Remarks : The data has been prepared just after parsing.
- *****************************************************************************
- */
- static void fontdir2res(name_id_t *name, fontdir_t *fnd)
- {
- int restag = put_res_header(WRC_RT_FONTDIR, name, fnd->memopt, &fnd->data->lvc);
- put_data(fnd->data->data, fnd->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : html2res
- * Input :
- * name - Name/ordinal of the resource
- * rdt - The html descriptor
- *****************************************************************************
- */
- static void html2res(name_id_t *name, html_t *html)
- {
- int restag = put_res_header(WRC_RT_HTML, name, html->memopt, &html->data->lvc);
- put_data(html->data->data, html->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : rcdata2res
- * Input :
- * name - Name/ordinal of the resource
- * rdt - The rcdata descriptor
- *****************************************************************************
- */
- static void rcdata2res(name_id_t *name, rcdata_t *rdt)
- {
- int restag = put_res_header(WRC_RT_RCDATA, name, rdt->memopt, &rdt->data->lvc);
- put_data(rdt->data->data, rdt->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : messagetable2res
- * Input :
- * name - Name/ordinal of the resource
- * msg - The messagetable descriptor
- *****************************************************************************
- */
- static void messagetable2res(name_id_t *name, messagetable_t *msg)
- {
- int restag = put_res_header(WRC_RT_MESSAGETABLE, name, msg->memopt, &msg->data->lvc);
- put_data(msg->data->data, msg->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : stringtable2res
- * Input :
- * stt - The stringtable descriptor
- *****************************************************************************
- */
- static void stringtable2res(stringtable_t *stt)
- {
- name_id_t name;
- int i;
- int restag;
- for(; stt; stt = stt->next)
- {
- if(!stt->nentries)
- {
- warning("Empty internal stringtable\n");
- continue;
- }
- name.type = name_ord;
- name.name.i_name = (stt->idbase >> 4) + 1;
- restag = put_res_header(WRC_RT_STRING, &name, stt->memopt, &stt->lvc);
- for(i = 0; i < stt->nentries; i++)
- {
- if(stt->entries[i].str && stt->entries[i].str->size)
- {
- put_string(stt->entries[i].str, FALSE, stt->lvc.language);
- }
- else
- {
- if (win32)
- put_word(0);
- else
- put_byte(0);
- }
- }
- set_res_size(restag);
- }
- }
- /*
- *****************************************************************************
- * Function : user2res
- * Input :
- * name - Name/ordinal of the resource
- * usr - The userresource descriptor
- *****************************************************************************
- */
- static void user2res(name_id_t *name, user_t *usr)
- {
- int tag = output_buffer_pos;
- if(win32)
- {
- put_dword(0); /* We will overwrite these later */
- put_dword(0);
- put_name_id(usr->type, TRUE, usr->data->lvc.language);
- put_name_id(name, TRUE, usr->data->lvc.language); /* ResName */
- align_output(4);
- put_dword(0); /* DataVersion */
- put_word(usr->memopt); /* Memory options */
- put_lvc(&usr->data->lvc); /* Language, version and characts */
- set_dword(tag + 0, output_buffer_pos - tag);
- set_dword(tag + 4, output_buffer_pos - tag); /* Set HeaderSize */
- }
- else /* win16 */
- {
- put_name_id(usr->type, TRUE, NULL);
- put_name_id(name, TRUE, NULL); /* ResName */
- put_word(usr->memopt); /* Memory options */
- tag = output_buffer_pos;
- put_dword(4); /* ResSize overwritten later*/
- }
- put_data(usr->data->data, usr->data->size);
- set_res_size(tag);
- }
- /*
- *****************************************************************************
- * Function : versionblock2res
- * Input :
- * blk - The version block to be written
- * Remarks : Self recursive
- *****************************************************************************
- */
- static void versionblock2res(ver_block_t *blk, int level, const language_t *lang)
- {
- ver_value_t *val;
- int blksizetag;
- int valblksizetag;
- int valvalsizetag;
- int tag;
- int i;
- blksizetag = output_buffer_pos;
- put_word(0); /* Will be overwritten later */
- put_word(0);
- if(win32)
- put_word(0); /* level ? */
- put_string(blk->name, TRUE, NULL);
- align_output(4);
- for(val = blk->values; val; val = val->next)
- {
- switch(val->type)
- {
- case val_str:
- valblksizetag = output_buffer_pos;
- put_word(0); /* Will be overwritten later */
- valvalsizetag = output_buffer_pos;
- put_word(0); /* Will be overwritten later */
- if(win32)
- {
- put_word(level);
- }
- put_string(val->key, TRUE, NULL);
- align_output(4);
- tag = output_buffer_pos;
- put_string(val->value.str, TRUE, lang);
- if(win32)
- set_word(valvalsizetag, (output_buffer_pos - tag) >> 1);
- else
- set_word(valvalsizetag, output_buffer_pos - tag);
- set_word(valblksizetag, output_buffer_pos - valblksizetag);
- align_output(4);
- break;
- case val_words:
- valblksizetag = output_buffer_pos;
- put_word(0); /* Will be overwritten later */
- valvalsizetag = output_buffer_pos;
- put_word(0); /* Will be overwritten later */
- if(win32)
- {
- put_word(level);
- }
- put_string(val->key, TRUE, NULL);
- align_output(4);
- tag = output_buffer_pos;
- for(i = 0; i < val->value.words->nwords; i++)
- {
- put_word(val->value.words->words[i]);
- }
- set_word(valvalsizetag, output_buffer_pos - tag);
- set_word(valblksizetag, output_buffer_pos - valblksizetag);
- align_output(4);
- break;
- case val_block:
- versionblock2res(val->value.block, level+1, lang);
- break;
- }
- }
- /* Set blocksize */
- set_word(blksizetag, output_buffer_pos - blksizetag);
- }
- /*
- *****************************************************************************
- * Function : versioninfo2res
- * Input :
- * name - Name/ordinal of the resource
- * ver - The versioninfo descriptor
- *****************************************************************************
- */
- static void versioninfo2res(name_id_t *name, versioninfo_t *ver)
- {
- static const char info[] = "VS_VERSION_INFO";
- unsigned int i;
- int restag, rootblocksizetag, valsizetag, tag;
- ver_block_t *blk;
- restag = put_res_header(WRC_RT_VERSION, name, ver->memopt, &ver->lvc);
- rootblocksizetag = output_buffer_pos;
- put_word(0); /* BlockSize filled in later */
- valsizetag = output_buffer_pos;
- put_word(0); /* ValueSize filled in later*/
- if(win32)
- {
- put_word(0); /* Tree-level ? */
- for (i = 0; i < sizeof(info); i++) put_word(info[i]);
- align_output(4);
- }
- else
- {
- for (i = 0; i < sizeof(info); i++) put_byte(info[i]);
- }
- tag = output_buffer_pos;
- put_dword(VS_FFI_SIGNATURE);
- put_dword(VS_FFI_STRUCVERSION);
- put_dword((ver->filever_maj1 << 16) + (ver->filever_maj2 & 0xffff));
- put_dword((ver->filever_min1 << 16) + (ver->filever_min2 & 0xffff));
- put_dword((ver->prodver_maj1 << 16) + (ver->prodver_maj2 & 0xffff));
- put_dword((ver->prodver_min1 << 16) + (ver->prodver_min2 & 0xffff));
- put_dword(ver->fileflagsmask);
- put_dword(ver->fileflags);
- put_dword(ver->fileos);
- put_dword(ver->filetype);
- put_dword(ver->filesubtype);
- put_dword(0); /* FileDateMS */
- put_dword(0); /* FileDateLS */
- /* Set ValueSize */
- set_word(valsizetag, output_buffer_pos - tag);
- /* Descend into the blocks */
- for(blk = ver->blocks; blk; blk = blk->next)
- versionblock2res(blk, 0, win32 ? ver->lvc.language : NULL);
- /* Set root block's size */
- set_word(rootblocksizetag, output_buffer_pos - rootblocksizetag);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : toolbar2res
- * Input :
- * name - Name/ordinal of the resource
- * toolbar - The toolbar descriptor
- *****************************************************************************
- */
- static void toolbar2res(name_id_t *name, toolbar_t *toolbar)
- {
- toolbar_item_t *itm;
- int restag;
- if (!win32) return;
- restag = put_res_header(WRC_RT_TOOLBAR, name, toolbar->memopt, &toolbar->lvc);
- put_word(1); /* Menuheader: Version */
- put_word(toolbar->button_width); /* (in pixels?) */
- put_word(toolbar->button_height); /* (in pixels?) */
- put_word(toolbar->nitems);
- align_output(4);
- for (itm = toolbar->items; itm; itm = itm->next) put_word(itm->id);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : dlginit2res
- * Input :
- * name - Name/ordinal of the resource
- * rdt - The dlginit descriptor
- *****************************************************************************
- */
- static void dlginit2res(name_id_t *name, dlginit_t *dit)
- {
- int restag = put_res_header(WRC_RT_DLGINIT, name, dit->memopt, &dit->data->lvc);
- put_data(dit->data->data, dit->data->size);
- set_res_size(restag);
- }
- /*
- *****************************************************************************
- * Function : write_resfile
- * Syntax : void write_resfile(char *outname, resource_t *top)
- * Input :
- * outname - Filename to write to
- * top - The resource-tree to convert
- *****************************************************************************
- */
- void write_resfile(char *outname, resource_t *top)
- {
- init_output_buffer();
- if(win32)
- {
- /* Put an empty resource first to signal win32 format */
- put_dword(0); /* ResSize */
- put_dword(0x00000020); /* HeaderSize */
- put_word(0xffff); /* ResType */
- put_word(0);
- put_word(0xffff); /* ResName */
- put_word(0);
- put_dword(0); /* DataVersion */
- put_word(0); /* Memory options */
- put_word(0); /* Language */
- put_dword(0); /* Version */
- put_dword(0); /* Characteristics */
- }
- for ( ; top; top = top->next)
- {
- switch(top->type)
- {
- case res_acc: accelerator2res(top->name, top->res.acc); break;
- case res_bmp: bitmap2res(top->name, top->res.bmp); break;
- case res_cur: cursor2res(top->res.cur); break;
- case res_curg: cursorgroup2res(top->name, top->res.curg); break;
- case res_dlg: dialog2res(top->name, top->res.dlg); break;
- case res_fnt: font2res(top->name, top->res.fnt); break;
- case res_fntdir: fontdir2res(top->name, top->res.fnd); break;
- case res_ico: icon2res(top->res.ico); break;
- case res_icog: icongroup2res(top->name, top->res.icog); break;
- case res_men: menu2res(top->name, top->res.men); break;
- case res_html: html2res(top->name, top->res.html); break;
- case res_rdt: rcdata2res(top->name, top->res.rdt); break;
- case res_stt: stringtable2res(top->res.stt); break;
- case res_usr: user2res(top->name, top->res.usr); break;
- case res_msg: messagetable2res(top->name, top->res.msg); break;
- case res_ver: versioninfo2res(top->name, top->res.ver); break;
- case res_toolbar: toolbar2res(top->name, top->res.tbt); break;
- case res_dlginit: dlginit2res(top->name, top->res.dlgi); break;
- case res_anicur: anicur2res(top->name, top->res.ani); break;
- case res_aniico: aniico2res(top->name, top->res.ani); break;
- default: assert(0);
- }
- if (win32) align_output( 4 );
- }
- flush_output_buffer( outname );
- }
|