diff --git a/tools/wrc/genres.c b/tools/wrc/genres.c index ba848084ac9..173aff0c19a 100644 --- a/tools/wrc/genres.c +++ b/tools/wrc/genres.c @@ -42,140 +42,96 @@ #include "wingdi.h" #include "winuser.h" -static res_t *new_res(void) +static unsigned char *output_buffer; +static size_t output_buffer_pos; +static size_t output_buffer_size; + +static void check_output_buffer_space( size_t size ) { - res_t *r; - r = xmalloc(sizeof(res_t)); - r->allocsize = RES_BLOCKSIZE; - r->size = 0; - r->dataidx = 0; - r->data = xmalloc(RES_BLOCKSIZE); - return r; + if (output_buffer_pos + size >= output_buffer_size) + { + output_buffer_size = max( output_buffer_size * 2, output_buffer_pos + size ); + output_buffer = xrealloc( output_buffer, output_buffer_size ); + } } -static res_t *grow_res(res_t *r, unsigned int add) +static void init_output_buffer(void) { - r->allocsize += add; - r->data = xrealloc(r->data, r->allocsize); - return r; + output_buffer_size = 1024; + output_buffer_pos = 0; + output_buffer = xmalloc( output_buffer_size ); } -/* - ***************************************************************************** - * Function : put_byte - * put_word - * put_dword - * Syntax : void put_byte(res_t *res, unsigned c) - * void put_word(res_t *res, unsigned w) - * void put_dword(res_t *res, unsigned d) - * Input : - * res - Binary resource to put the data in - * c, w, d - Data to put - * Output : nop - * Description : Put primitives that put an item in the binary resource. - * The data array grows automatically. - * Remarks : - ***************************************************************************** -*/ -static void put_byte(res_t *res, unsigned c) +static void put_data( const void *data, size_t size ) { - if(res->allocsize - res->size < sizeof(char)) - grow_res(res, RES_BLOCKSIZE); - res->data[res->size] = (char)c; - res->size += sizeof(char); + check_output_buffer_space( size ); + memcpy( output_buffer + output_buffer_pos, data, size ); + output_buffer_pos += size; } -static void put_word(res_t *res, unsigned w) +static void put_byte( unsigned char val ) { - if(res->allocsize - res->size < sizeof(WORD)) - grow_res(res, RES_BLOCKSIZE); - res->data[res->size+0] = w; - res->data[res->size+1] = w >> 8; - res->size += sizeof(WORD); + check_output_buffer_space( 1 ); + output_buffer[output_buffer_pos++] = val; } -static void put_dword(res_t *res, unsigned d) +static void put_word( unsigned short val ) { - if(res->allocsize - res->size < sizeof(DWORD)) - grow_res(res, RES_BLOCKSIZE); - res->data[res->size+0] = d; - res->data[res->size+1] = d >> 8; - res->data[res->size+2] = d >> 16; - res->data[res->size+3] = d >> 24; - res->size += sizeof(DWORD); + check_output_buffer_space( 2 ); + output_buffer[output_buffer_pos++] = val; + output_buffer[output_buffer_pos++] = val >> 8; } -static void put_pad(res_t *res) +static void put_dword( unsigned int val ) { - while(res->size & 0x3) - put_byte(res, 0); + check_output_buffer_space( 4 ); + output_buffer[output_buffer_pos++] = val; + output_buffer[output_buffer_pos++] = val >> 8; + output_buffer[output_buffer_pos++] = val >> 16; + output_buffer[output_buffer_pos++] = val >> 24; } -/* - ***************************************************************************** - * Function : set_word - * set_dword - * Syntax : void set_word(res_t *res, int ofs, unsigned w) - * void set_dword(res_t *res, int ofs, unsigned d) - * Input : - * res - Binary resource to put the data in - * ofs - Byte offset in data-array - * w, d - Data to put - * Output : nop - * Description : Set the value of a binary resource data array to a - * specific value. - * Remarks : - ***************************************************************************** -*/ -static void set_word(res_t *res, int ofs, unsigned w) +static void align_output( unsigned int align ) { - res->data[ofs+0] = w; - res->data[ofs+1] = w >> 8; + size_t size = align - (output_buffer_pos % align); + + if (size == align) return; + check_output_buffer_space( size ); + memset( output_buffer + output_buffer_pos, 0, size ); + output_buffer_pos += size; } -static void set_dword(res_t *res, int ofs, unsigned d) +static void set_word(int ofs, unsigned int w) { - res->data[ofs+0] = d; - res->data[ofs+1] = d >> 8; - res->data[ofs+2] = d >> 16; - res->data[ofs+3] = d >> 24; + output_buffer[ofs+0] = w; + output_buffer[ofs+1] = w >> 8; } -/* - ***************************************************************************** - * Function : get_dword - * Input : - * res - Binary resource to put the data in - * ofs - Byte offset in data-array - * Output : The data in native endian - * Description : Get the value of a binary resource data array in native - * endian. - * Remarks : - ***************************************************************************** -*/ -static DWORD get_dword(res_t *res, int ofs) +static void set_dword(int ofs, unsigned int d) { - return (res->data[ofs+3] << 24) - | (res->data[ofs+2] << 16) - | (res->data[ofs+1] << 8) - | res->data[ofs+0]; + output_buffer[ofs+0] = d; + output_buffer[ofs+1] = d >> 8; + output_buffer[ofs+2] = d >> 16; + output_buffer[ofs+3] = d >> 24; } -static res_t *end_res(res_t *res, int ofs) +static unsigned int get_dword(int ofs) { - set_dword( res, ofs, res->size - get_dword( res, ofs )); - if (win32) put_pad( res ); - return res; + 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) - * Input : - * Output : - * Description : - * Remarks : FIXME: codepages... ***************************************************************************** */ static void string_to_upper(string_t *str) @@ -269,13 +225,12 @@ static int parse_accel_string( const string_t *key, int flags ) ***************************************************************************** * Function : put_string * Input : - * res - Binary resource to put the data in * str - String to put * isterm - The string is '\0' terminated (disregard the string's * size member) ***************************************************************************** */ -static void put_string(res_t *res, const string_t *str, int isterm, const language_t *lang) +static void put_string(const string_t *str, int isterm, const language_t *lang) { int cnt, codepage; @@ -294,55 +249,50 @@ static void put_string(res_t *res, const string_t *str, int isterm, const langua 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(res, newstr->size); + 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(res, c); + put_word(c); } - if (isterm) put_word(res, 0); + if (isterm) put_word(0); free_string(newstr); } else { assert( str->type == str_char ); - if (!isterm) put_byte(res, str->size); + 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(res, c); + put_byte(c); } - if (isterm) put_byte(res, 0); + if (isterm) put_byte(0); } } /* ***************************************************************************** * Function : put_name_id - * Syntax : void put_name_id(res_t *res, name_id_t *nid, int upcase, const language_t *lang) - * Input : - * Output : - * Description : - * Remarks : ***************************************************************************** */ -static void put_name_id(res_t *res, name_id_t *nid, int upcase, const language_t *lang) +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(res, 0xffff); + put_word(0xffff); else - put_byte(res, 0xff); - put_word(res, (WORD)nid->name.i_name); + 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(res, nid->name.s_name, TRUE, lang); + put_string(nid->name.s_name, TRUE, lang); break; } } @@ -350,192 +300,123 @@ static void put_name_id(res_t *res, name_id_t *nid, int upcase, const language_t /* ***************************************************************************** * Function : put_lvc - * Syntax : void put_lvc(res_t *res, lvc_t *lvc) - * Input : - * Output : - * Description : - * Remarks : ***************************************************************************** */ -static void put_lvc(res_t *res, lvc_t *lvc) +static void put_lvc(lvc_t *lvc) { if(lvc && lvc->language) - put_word(res, MAKELANGID(lvc->language->id, lvc->language->sub)); + put_word(MAKELANGID(lvc->language->id, lvc->language->sub)); else - put_word(res, 0); /* Neutral */ + put_word(0); /* Neutral */ if(lvc && lvc->version) - put_dword(res, *(lvc->version)); + put_dword(*lvc->version); else - put_dword(res, 0); + put_dword(0); if(lvc && lvc->characts) - put_dword(res, *(lvc->characts)); + put_dword(*lvc->characts); else - put_dword(res, 0); -} - -/* - ***************************************************************************** - * Function : put_raw_data - * Syntax : void put_raw_data(res_t *res, raw_data_t *raw, int offset) - * Input : - * Output : - * Description : - * Remarks : - ***************************************************************************** -*/ -static void put_raw_data(res_t *res, raw_data_t *raw, int offset) -{ - unsigned int wsize = raw->size - offset; - if(res->allocsize - res->size < wsize) - grow_res(res, wsize); - memcpy(&(res->data[res->size]), raw->data + offset, wsize); - res->size += wsize; + put_dword(0); } /* ***************************************************************************** * Function : put_res_header - * Syntax : input_res_header(res_t *res, int type, name_id_t *ntype, - * name_id_t *name, DWORD memopt, lvc_t *lvc) - * * Input : - * res - Binary resource descriptor to write to - * type - Resource identifier (if ntype == NULL) - * ntype - Name id of type + * 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. - * Description : - * Remarks : ***************************************************************************** */ -static int put_res_header(res_t *res, int type, name_id_t *ntype, name_id_t *name, - DWORD memopt, lvc_t *lvc) +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(res, 0); /* We will overwrite these later */ - put_dword(res, 0); - if(!ntype) - { - put_word(res, 0xffff); /* ResType */ - put_word(res, type); - } - else - put_name_id(res, ntype, TRUE, lvc->language); - put_name_id(res, name, TRUE, lvc->language); /* ResName */ - put_pad(res); - put_dword(res, 0); /* DataVersion */ - put_word(res, memopt); /* Memory options */ - put_lvc(res, lvc); /* Language, version and characts */ - set_dword(res, 0*sizeof(DWORD), res->size); /* Set preliminary resource */ - set_dword(res, 1*sizeof(DWORD), res->size); /* Set HeaderSize */ - res->dataidx = res->size; - return 0; + 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 */ { - int tag; - if(!ntype) - { - put_byte(res, 0xff); /* ResType */ - put_word(res, type); - } - else - put_name_id(res, ntype, TRUE, NULL); - put_name_id(res, name, TRUE, NULL); /* ResName */ - put_word(res, memopt); /* Memory options */ - tag = res->size; - put_dword(res, 0); /* ResSize overwritten later*/ - set_dword(res, tag, res->size); - res->dataidx = res->size; - return tag; + 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 - * Syntax : res_t *accelerator2res(name_id_t *name, accelerator_t *acc) * Input : * name - Name/ordinal of the resource * acc - The accelerator descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *accelerator2res(name_id_t *name, accelerator_t *acc) +static void accelerator2res(name_id_t *name, accelerator_t *acc) { int restag; - res_t *res; event_t *ev; - assert(name != NULL); - assert(acc != NULL); - ev = acc->events; - res = new_res(); + restag = put_res_header(WRC_RT_ACCELERATOR, name, acc->memopt, &acc->lvc); if(win32) { - restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, &(acc->lvc)); - while(ev) + 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(res, ev->flags | (ev->next ? 0 : 0x80)); - put_word(res, key); - put_word(res, ev->id); - put_word(res, 0); /* Padding */ - ev = ev->next; + put_word(ev->flags | (ev->next ? 0 : 0x80)); + put_word(key); + put_word(ev->id); + align_output(4); } - put_pad(res); } else /* win16 */ { - restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, NULL); - while(ev) + 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(res, ev->flags | (ev->next ? 0 : 0x80)); - put_word(res, key); - put_word(res, ev->id); - ev = ev->next; + put_byte(ev->flags | (ev->next ? 0 : 0x80)); + put_word(key); + put_word(ev->id); } } - return end_res(res, restag); + set_res_size(restag); } /* ***************************************************************************** * Function : dialog2res - * Syntax : res_t *dialog2res(name_id_t *name, dialog_t *dlg) * Input : * name - Name/ordinal of the resource * dlg - The dialog descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *dialog2res(name_id_t *name, dialog_t *dlg) +static void dialog2res(name_id_t *name, dialog_t *dlg) { int restag; - res_t *res; control_t *ctrl; - int tag_nctrl; - int nctrl = 0; - assert(name != NULL); - assert(dlg != NULL); + int nctrl; - ctrl = dlg->controls; - res = new_res(); + 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) { - restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlg->memopt, &(dlg->lvc)); - if (dlg->is_ex) { /* FIXME: MS doc says that the first word must contain 0xffff @@ -544,186 +425,171 @@ static res_t *dialog2res(name_id_t *name, dialog_t *dlg) * I don't know which one to choose, but I write it as Mr. B * writes it. */ - put_word(res, 1); /* Signature */ - put_word(res, 0xffff); /* DlgVer */ - put_dword(res, dlg->gothelpid ? dlg->helpid : 0); - put_dword(res, dlg->gotexstyle ? dlg->exstyle->or_mask : 0); - put_dword(res, dlg->gotstyle ? dlg->style->or_mask : WS_POPUPWINDOW); + 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(res, dlg->style->or_mask); - put_dword(res, dlg->gotexstyle ? dlg->exstyle->or_mask : 0); + put_dword(dlg->style->or_mask); + put_dword(dlg->gotexstyle ? dlg->exstyle->or_mask : 0); } - tag_nctrl = res->size; - put_word(res, 0); /* Number of controls */ - put_word(res, dlg->x); - put_word(res, dlg->y); - put_word(res, dlg->width); - put_word(res, dlg->height); + 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(res, dlg->menu, FALSE, dlg->lvc.language); + put_name_id(dlg->menu, FALSE, dlg->lvc.language); else - put_word(res, 0); + put_word(0); if(dlg->dlgclass) - put_name_id(res, dlg->dlgclass, FALSE, dlg->lvc.language); + put_name_id(dlg->dlgclass, FALSE, dlg->lvc.language); else - put_word(res, 0); + put_word(0); if(dlg->title) - put_string(res, dlg->title, TRUE, dlg->lvc.language); + put_string(dlg->title, TRUE, dlg->lvc.language); else - put_word(res, 0); + put_word(0); if(dlg->font) { - put_word(res, dlg->font->size); + put_word(dlg->font->size); if (dlg->is_ex) { - put_word(res, dlg->font->weight); + 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(res, dlg->font->italic ? 0x0101 : 0); + put_word(dlg->font->italic ? 0x0101 : 0); } - put_string(res, dlg->font->name, TRUE, dlg->lvc.language); + put_string(dlg->font->name, TRUE, dlg->lvc.language); } - else if (dlg->style->or_mask & DS_SETFONT) put_word( res, 0x7fff ); + else if (dlg->style->or_mask & DS_SETFONT) put_word( 0x7fff ); - put_pad(res); - while(ctrl) + align_output(4); + for (ctrl = dlg->controls; ctrl; ctrl = ctrl->next) { if (dlg->is_ex) { - put_dword(res, ctrl->gothelpid ? ctrl->helpid : 0); - put_dword(res, ctrl->gotexstyle ? ctrl->exstyle->or_mask : 0); + put_dword(ctrl->gothelpid ? ctrl->helpid : 0); + put_dword(ctrl->gotexstyle ? ctrl->exstyle->or_mask : 0); /* FIXME: what is default control style? */ - put_dword(res, ctrl->gotstyle ? ctrl->style->or_mask : WS_CHILD | WS_VISIBLE); + put_dword(ctrl->gotstyle ? ctrl->style->or_mask : WS_CHILD | WS_VISIBLE); } else { /* FIXME: what is default control style? */ - put_dword(res, ctrl->gotstyle ? ctrl->style->or_mask: WS_CHILD); - put_dword(res, ctrl->gotexstyle ? ctrl->exstyle->or_mask : 0); + put_dword(ctrl->gotstyle ? ctrl->style->or_mask: WS_CHILD); + put_dword(ctrl->gotexstyle ? ctrl->exstyle->or_mask : 0); } - put_word(res, ctrl->x); - put_word(res, ctrl->y); - put_word(res, ctrl->width); - put_word(res, ctrl->height); + put_word(ctrl->x); + put_word(ctrl->y); + put_word(ctrl->width); + put_word(ctrl->height); if (dlg->is_ex) - put_dword(res, ctrl->id); + put_dword(ctrl->id); else - put_word(res, ctrl->id); - put_name_id(res, ctrl->ctlclass, FALSE, dlg->lvc.language); + put_word(ctrl->id); + put_name_id(ctrl->ctlclass, FALSE, dlg->lvc.language); if(ctrl->title) - put_name_id(res, ctrl->title, FALSE, dlg->lvc.language); + put_name_id(ctrl->title, FALSE, dlg->lvc.language); else - put_word(res, 0); + put_word(0); if(ctrl->extra) { - put_word(res, ctrl->extra->size); - put_raw_data(res, ctrl->extra, 0); + put_word(ctrl->extra->size); + put_data(ctrl->extra->data, ctrl->extra->size); } else - put_word(res, 0); + put_word(0); if(ctrl->next) - put_pad(res); - nctrl++; - ctrl = ctrl->next; + align_output(4); } - /* Set number of controls */ - set_word(res, tag_nctrl, (WORD)nctrl); } else /* win16 */ { - restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlg->memopt, NULL); + restag = put_res_header(WRC_RT_DIALOG, name, dlg->memopt, NULL); - put_dword(res, dlg->gotstyle ? dlg->style->or_mask : WS_POPUPWINDOW); - tag_nctrl = res->size; - put_byte(res, 0); /* Number of controls */ - put_word(res, dlg->x); - put_word(res, dlg->y); - put_word(res, dlg->width); - put_word(res, dlg->height); + 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(res, dlg->menu, TRUE, NULL); + put_name_id(dlg->menu, TRUE, NULL); else - put_byte(res, 0); + put_byte(0); if(dlg->dlgclass) - put_name_id(res, dlg->dlgclass, TRUE, NULL); + put_name_id(dlg->dlgclass, TRUE, NULL); else - put_byte(res, 0); + put_byte(0); if(dlg->title) - put_string(res, dlg->title, TRUE, NULL); + put_string(dlg->title, TRUE, NULL); else - put_byte(res, 0); + put_byte(0); if(dlg->font) { - put_word(res, dlg->font->size); - put_string(res, dlg->font->name, TRUE, NULL); + put_word(dlg->font->size); + put_string(dlg->font->name, TRUE, NULL); } - while(ctrl) + for (ctrl = dlg->controls; ctrl; ctrl = ctrl->next) { - put_word(res, ctrl->x); - put_word(res, ctrl->y); - put_word(res, ctrl->width); - put_word(res, ctrl->height); - put_word(res, ctrl->id); - put_dword(res, ctrl->gotstyle ? ctrl->style->or_mask: WS_CHILD); + 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(res, ctrl->ctlclass->name.i_name); + put_byte(ctrl->ctlclass->name.i_name); else if(ctrl->ctlclass->type == name_str) - put_name_id(res, ctrl->ctlclass, FALSE, NULL); + 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(res, ctrl->title, FALSE, NULL); + put_name_id(ctrl->title, FALSE, NULL); else - put_byte(res, 0); + put_byte(0); /* FIXME: What is this extra byte doing here? */ - put_byte(res, 0); - - nctrl++; - ctrl = ctrl->next; + put_byte(0); } - /* Set number of controls */ - ((char *)res->data)[tag_nctrl] = (char)nctrl; } - return end_res(res, restag); + set_res_size(restag); } /* ***************************************************************************** * Function : menuitem2res - * Syntax : void menuitem2res(res_t *res, menu_item_t *item) - * Input : - * Output : - * Description : * Remarks : Self recursive ***************************************************************************** */ -static void menuitem2res(res_t *res, menu_item_t *menitem, const language_t *lang) +static void menuitem2res(menu_item_t *menitem, const language_t *lang) { menu_item_t *itm = menitem; while(itm) { - put_word(res, itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0)); + put_word(itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0)); if(!itm->popup) - put_word(res, itm->id); + put_word(itm->id); if(itm->name) - put_string(res, itm->name, TRUE, lang); + put_string(itm->name, TRUE, lang); else { - if (win32) put_word(res, 0); - else put_byte(res, 0); + if (win32) put_word(0); + else put_byte(0); } if(itm->popup) - menuitem2res(res, itm->popup, lang); + menuitem2res(itm->popup, lang); itm = itm->next; } } @@ -731,32 +597,28 @@ static void menuitem2res(res_t *res, menu_item_t *menitem, const language_t *lan /* ***************************************************************************** * Function : menuexitem2res - * Syntax : void menuexitem2res(res_t *res, menuex_item_t *item) - * Input : - * Output : nop - * Description : * Remarks : Self recursive ***************************************************************************** */ -static void menuexitem2res(res_t *res, menu_item_t *menitem, const language_t *lang) +static void menuexitem2res(menu_item_t *menitem, const language_t *lang) { menu_item_t *itm = menitem; assert(win32 != 0); while(itm) { - put_dword(res, itm->gottype ? itm->type : 0); - put_dword(res, itm->gotstate ? itm->state : 0); - put_dword(res, itm->gotid ? itm->id : 0); - put_word(res, (itm->popup ? 0x01 : 0) | (!itm->next ? MF_END : 0)); + 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(res, itm->name, TRUE, lang); + put_string(itm->name, TRUE, lang); else - put_word(res, 0); - put_pad(res); + put_word(0); + align_output(4); if(itm->popup) { - put_dword(res, itm->gothelpid ? itm->helpid : 0); - menuexitem2res(res, itm->popup, lang); + put_dword(itm->gothelpid ? itm->helpid : 0); + menuexitem2res(itm->popup, lang); } itm = itm->next; } @@ -766,80 +628,66 @@ static void menuexitem2res(res_t *res, menu_item_t *menitem, const language_t *l /* ***************************************************************************** * Function : menu2res - * Syntax : res_t *menu2res(name_id_t *name, menu_t *men) * Input : * name - Name/ordinal of the resource * menex - The menuex descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *menu2res(name_id_t *name, menu_t *men) +static void menu2res(name_id_t *name, menu_t *men) { int restag; - res_t *res; assert(name != NULL); assert(men != NULL); - res = new_res(); - restag = put_res_header(res, WRC_RT_MENU, NULL, name, men->memopt, &men->lvc); + restag = put_res_header(WRC_RT_MENU, name, men->memopt, &men->lvc); if(win32) { if (men->is_ex) { - put_word(res, 1); /* Menuheader: Version */ - put_word(res, 4); /* Offset */ - put_dword(res, 0); /* HelpId */ - put_pad(res); - menuexitem2res(res, men->items, men->lvc.language); + 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(res, 0); /* Menuheader: Version and HeaderSize */ - menuitem2res(res, men->items, men->lvc.language); + put_dword(0); /* Menuheader: Version and HeaderSize */ + menuitem2res(men->items, men->lvc.language); } } else /* win16 */ { - put_dword(res, 0); /* Menuheader: Version and HeaderSize */ - menuitem2res(res, men->items, NULL); + put_dword(0); /* Menuheader: Version and HeaderSize */ + menuitem2res(men->items, NULL); } - return end_res(res, restag); + set_res_size(restag); } /* ***************************************************************************** * Function : cursorgroup2res - * Syntax : res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg) * Input : * name - Name/ordinal of the resource * curg - The cursor descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg) +static void cursorgroup2res(name_id_t *name, cursor_group_t *curg) { - int restag; - res_t *res; - cursor_t *cur; - assert(name != NULL); - assert(curg != NULL); + int restag; + cursor_t *cur; - res = new_res(); - restag = put_res_header(res, WRC_RT_GROUP_CURSOR, NULL, name, curg->memopt, &(curg->lvc)); + restag = put_res_header(WRC_RT_GROUP_CURSOR, name, curg->memopt, &curg->lvc); - put_word(res, 0); /* Reserved */ + 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(res, 2); /* ResType */ - put_word(res, curg->ncursor); + put_word(2); /* ResType */ + put_word(curg->ncursor); #if 0 for(cur = curg->cursorlist; cur; cur = cur->next) #else @@ -849,351 +697,260 @@ static res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg) for(; cur; cur = cur->prev) #endif { - put_word(res, cur->width); + 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(res, cur->height); + 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(res, cur->planes); - put_word(res, cur->bits); + 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(res, cur->data->size +4); - put_word(res, cur->id); + put_dword(cur->data->size +4); + put_word(cur->id); } - return end_res(res, restag); + set_res_size(restag); } /* ***************************************************************************** * Function : cursor2res - * Syntax : res_t *cursor2res(cursor_t *cur) * Input : * cur - The cursor descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *cursor2res(cursor_t *cur) +static void cursor2res(cursor_t *cur) { int restag; - res_t *res; name_id_t name; - assert(cur != NULL); - - res = new_res(); name.type = name_ord; name.name.i_name = cur->id; - restag = put_res_header(res, WRC_RT_CURSOR, NULL, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, &(cur->lvc)); - put_word(res, cur->xhot); - put_word(res, cur->yhot); - put_raw_data(res, cur->data, 0); + 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); - return end_res(res, restag); + set_res_size(restag); } /* ***************************************************************************** * Function : icongroup2res - * Syntax : res_t *icongroup2res(name_id_t *name, icon_group_t *icog) * Input : * name - Name/ordinal of the resource * icog - The icon group descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *icongroup2res(name_id_t *name, icon_group_t *icog) +static void icongroup2res(name_id_t *name, icon_group_t *icog) { - int restag; - res_t *res; - icon_t *ico; - assert(name != NULL); - assert(icog != NULL); + int restag; + icon_t *ico; - res = new_res(); - restag = put_res_header(res, WRC_RT_GROUP_ICON, NULL, name, icog->memopt, &(icog->lvc)); + restag = put_res_header(WRC_RT_GROUP_ICON, name, icog->memopt, &icog->lvc); - put_word(res, 0); /* Reserved */ + 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(res, 1); /* ResType */ - put_word(res, icog->nicon); + put_word(1); /* ResType */ + put_word(icog->nicon); for(ico = icog->iconlist; ico; ico = ico->next) { - put_byte(res, ico->width); - put_byte(res, ico->height); - put_byte(res, ico->nclr); - put_byte(res, 0); /* Reserved */ - put_word(res, ico->planes); - put_word(res, ico->bits); - put_dword(res, ico->data->size); - put_word(res, ico->id); + 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); } - return end_res(res, restag); + set_res_size(restag); } /* ***************************************************************************** * Function : icon2res - * Syntax : res_t *icon2res(icon_t *ico) * Input : * ico - The icon descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *icon2res(icon_t *ico) +static void icon2res(icon_t *ico) { int restag; - res_t *res; name_id_t name; - assert(ico != NULL); - - res = new_res(); name.type = name_ord; name.name.i_name = ico->id; - restag = put_res_header(res, WRC_RT_ICON, NULL, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, &(ico->lvc)); - put_raw_data(res, ico->data, 0); - - return end_res(res, restag); + 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 - * Syntax : res_t *anicurico2res(name_id_t *name, ani_curico_t *ani) * Input : * name - Name/ordinal of the resource * ani - The animated object descriptor - * Output : New .res format structure - * Description : - * Remarks : The endian of the object's structures have been converted - * by the loader. - * There are rumors that win311 could handle animated stuff. + * Remarks : There are rumors that win311 could handle animated stuff. * That is why they are generated for both win16 and win32 * compile. ***************************************************************************** */ -static res_t *anicurico2res(name_id_t *name, ani_curico_t *ani, enum res_e type) +static void anicur2res(name_id_t *name, ani_curico_t *ani) { - int restag; - res_t *res; - assert(name != NULL); - assert(ani != NULL); + int restag = put_res_header(WRC_RT_ANICURSOR, name, ani->memopt, NULL); - res = new_res(); - restag = put_res_header(res, type == res_anicur ? WRC_RT_ANICURSOR : WRC_RT_ANIICON, - NULL, name, ani->memopt, NULL); - put_raw_data(res, ani->data, 0); - return end_res(res, restag); + 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 - * Syntax : res_t *bitmap2res(name_id_t *name, bitmap_t *bmp) * Input : * name - Name/ordinal of the resource * bmp - The bitmap descriptor - * Output : New .res format structure - * Description : - * Remarks : The endian of the bitmap structures have been converted - * by the loader. ***************************************************************************** */ -static res_t *bitmap2res(name_id_t *name, bitmap_t *bmp) +static void bitmap2res(name_id_t *name, bitmap_t *bmp) { - int restag; - res_t *res; - assert(name != NULL); - assert(bmp != NULL); + int restag = put_res_header(WRC_RT_BITMAP, name, bmp->memopt, &bmp->data->lvc); - res = new_res(); - restag = put_res_header(res, WRC_RT_BITMAP, NULL, 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_raw_data(res, bmp->data, sizeof(BITMAPFILEHEADER)); + put_data((BITMAPFILEHEADER *)bmp->data->data + 1, bmp->data->size - sizeof(BITMAPFILEHEADER)); } else { - put_raw_data(res, bmp->data, 0); + put_data(bmp->data->data, bmp->data->size); } - return end_res(res, restag); + set_res_size(restag); } /* ***************************************************************************** * Function : font2res - * Syntax : res_t *font2res(name_id_t *name, font_t *fnt) * Input : * name - Name/ordinal of the resource * fnt - The font descriptor - * Output : New .res format structure - * Description : * Remarks : The data has been prepared just after parsing. ***************************************************************************** */ -static res_t *font2res(name_id_t *name, font_t *fnt) +static void font2res(name_id_t *name, font_t *fnt) { - int restag; - res_t *res; - assert(name != NULL); - assert(fnt != NULL); + int restag = put_res_header(WRC_RT_FONT, name, fnt->memopt, &fnt->data->lvc); - res = new_res(); - restag = put_res_header(res, WRC_RT_FONT, NULL, name, fnt->memopt, &(fnt->data->lvc)); - put_raw_data(res, fnt->data, 0); - return end_res(res, restag); + put_data(fnt->data->data, fnt->data->size); + set_res_size(restag); } /* ***************************************************************************** * Function : fontdir2res - * Syntax : res_t *fontdir2res(name_id_t *name, fontdir_t *fnd) * Input : * name - Name/ordinal of the resource * fntdir - The fontdir descriptor - * Output : New .res format structure - * Description : * Remarks : The data has been prepared just after parsing. ***************************************************************************** */ -static res_t *fontdir2res(name_id_t *name, fontdir_t *fnd) +static void fontdir2res(name_id_t *name, fontdir_t *fnd) { - int restag; - res_t *res; - assert(name != NULL); - assert(fnd != NULL); + int restag = put_res_header(WRC_RT_FONTDIR, name, fnd->memopt, &fnd->data->lvc); - res = new_res(); - restag = put_res_header(res, WRC_RT_FONTDIR, NULL, name, fnd->memopt, &(fnd->data->lvc)); - put_raw_data(res, fnd->data, 0); - return end_res(res, restag); + put_data(fnd->data->data, fnd->data->size); + set_res_size(restag); } /* ***************************************************************************** * Function : html2res - * Syntax : res_t *html2res(name_id_t *name, html_t *html) * Input : * name - Name/ordinal of the resource * rdt - The html descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *html2res(name_id_t *name, html_t *html) +static void html2res(name_id_t *name, html_t *html) { - int restag; - res_t *res; - assert(name != NULL); - assert(html != NULL); + int restag = put_res_header(WRC_RT_HTML, name, html->memopt, &html->data->lvc); - res = new_res(); - restag = put_res_header(res, WRC_RT_HTML, NULL, name, html->memopt, &(html->data->lvc)); - put_raw_data(res, html->data, 0); - return end_res(res, restag); + put_data(html->data->data, html->data->size); + set_res_size(restag); } /* ***************************************************************************** * Function : rcdata2res - * Syntax : res_t *rcdata2res(name_id_t *name, rcdata_t *rdt) * Input : * name - Name/ordinal of the resource * rdt - The rcdata descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *rcdata2res(name_id_t *name, rcdata_t *rdt) +static void rcdata2res(name_id_t *name, rcdata_t *rdt) { - int restag; - res_t *res; - assert(name != NULL); - assert(rdt != NULL); + int restag = put_res_header(WRC_RT_RCDATA, name, rdt->memopt, &rdt->data->lvc); - res = new_res(); - restag = put_res_header(res, WRC_RT_RCDATA, NULL, name, rdt->memopt, &(rdt->data->lvc)); - put_raw_data(res, rdt->data, 0); - return end_res(res, restag); + put_data(rdt->data->data, rdt->data->size); + set_res_size(restag); } /* ***************************************************************************** * Function : messagetable2res - * Syntax : res_t *messagetable2res(name_id_t *name, messagetable_t *msg) * Input : * name - Name/ordinal of the resource * msg - The messagetable descriptor - * Output : New .res format structure - * Description : - * Remarks : The data has been converted to the appropriate endian - * after it was parsed. ***************************************************************************** */ -static res_t *messagetable2res(name_id_t *name, messagetable_t *msg) +static void messagetable2res(name_id_t *name, messagetable_t *msg) { - int restag; - res_t *res; - assert(name != NULL); - assert(msg != NULL); + int restag = put_res_header(WRC_RT_MESSAGETABLE, name, msg->memopt, &msg->data->lvc); - res = new_res(); - restag = put_res_header(res, WRC_RT_MESSAGETABLE, NULL, name, msg->memopt, &(msg->data->lvc)); - put_raw_data(res, msg->data, 0); - return end_res(res, restag); + put_data(msg->data->data, msg->data->size); + set_res_size(restag); } /* ***************************************************************************** * Function : stringtable2res - * Syntax : res_t *stringtable2res(stringtable_t *stt) * Input : * stt - The stringtable descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *stringtable2res(stringtable_t *stt) +static void stringtable2res(stringtable_t *stt) { - res_t *res; name_id_t name; int i; int restag; - DWORD lastsize = 0; - - assert(stt != NULL); - res = new_res(); for(; stt; stt = stt->next) { @@ -1204,65 +961,72 @@ static res_t *stringtable2res(stringtable_t *stt) } name.type = name_ord; name.name.i_name = (stt->idbase >> 4) + 1; - restag = put_res_header(res, WRC_RT_STRING, NULL, &name, stt->memopt, win32 ? &(stt->lvc) : NULL); + 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(res, stt->entries[i].str, FALSE, stt->lvc.language); + put_string(stt->entries[i].str, FALSE, stt->lvc.language); } else { if (win32) - put_word(res, 0); + put_word(0); else - put_byte(res, 0); + put_byte(0); } } - end_res(res, restag - lastsize); - lastsize = res->size; + set_res_size(restag); } - return res; } /* ***************************************************************************** * Function : user2res - * Syntax : res_t *user2res(name_id_t *name, user_t *usr) * Input : * name - Name/ordinal of the resource * usr - The userresource descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *user2res(name_id_t *name, user_t *usr) +static void user2res(name_id_t *name, user_t *usr) { - int restag; - res_t *res; - assert(name != NULL); - assert(usr != NULL); + int tag = output_buffer_pos; - res = new_res(); - restag = put_res_header(res, 0, usr->type, name, usr->memopt, &(usr->data->lvc)); - put_raw_data(res, usr->data, 0); - return end_res(res, restag); + 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 - * Syntax : void versionblock2res(res_t *res, ver_block_t *blk) * Input : - * res - Binary resource to write to * blk - The version block to be written - * Output : - * Description : * Remarks : Self recursive ***************************************************************************** */ -static void versionblock2res(res_t *res, ver_block_t *blk, int level, const language_t *lang) +static void versionblock2res(ver_block_t *blk, int level, const language_t *lang) { ver_value_t *val; int blksizetag; @@ -1271,309 +1035,160 @@ static void versionblock2res(res_t *res, ver_block_t *blk, int level, const lang int tag; int i; - blksizetag = res->size; - put_word(res, 0); /* Will be overwritten later */ - put_word(res, 0); + blksizetag = output_buffer_pos; + put_word(0); /* Will be overwritten later */ + put_word(0); if(win32) - put_word(res, 0); /* level ? */ - put_string(res, blk->name, TRUE, NULL); - put_pad(res); + 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 = res->size; - put_word(res, 0); /* Will be overwritten later */ - valvalsizetag = res->size; - put_word(res, 0); /* Will be overwritten later */ + 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(res, level); + put_word(level); } - put_string(res, val->key, TRUE, NULL); - put_pad(res); - tag = res->size; - put_string(res, val->value.str, TRUE, lang); + put_string(val->key, TRUE, NULL); + align_output(4); + tag = output_buffer_pos; + put_string(val->value.str, TRUE, lang); if(win32) - set_word(res, valvalsizetag, (WORD)((res->size - tag) >> 1)); + set_word(valvalsizetag, (output_buffer_pos - tag) >> 1); else - set_word(res, valvalsizetag, (WORD)(res->size - tag)); - set_word(res, valblksizetag, (WORD)(res->size - valblksizetag)); - put_pad(res); + set_word(valvalsizetag, output_buffer_pos - tag); + set_word(valblksizetag, output_buffer_pos - valblksizetag); + align_output(4); break; case val_words: - valblksizetag = res->size; - put_word(res, 0); /* Will be overwritten later */ - valvalsizetag = res->size; - put_word(res, 0); /* Will be overwritten later */ + 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(res, level); + put_word(level); } - put_string(res, val->key, TRUE, NULL); - put_pad(res); - tag = res->size; + put_string(val->key, TRUE, NULL); + align_output(4); + tag = output_buffer_pos; for(i = 0; i < val->value.words->nwords; i++) { - put_word(res, val->value.words->words[i]); + put_word(val->value.words->words[i]); } - set_word(res, valvalsizetag, (WORD)(res->size - tag)); - set_word(res, valblksizetag, (WORD)(res->size - valblksizetag)); - put_pad(res); + set_word(valvalsizetag, output_buffer_pos - tag); + set_word(valblksizetag, output_buffer_pos - valblksizetag); + align_output(4); break; case val_block: - versionblock2res(res, val->value.block, level+1, lang); + versionblock2res(val->value.block, level+1, lang); break; } } /* Set blocksize */ - set_word(res, blksizetag, (WORD)(res->size - blksizetag)); + set_word(blksizetag, output_buffer_pos - blksizetag); } /* ***************************************************************************** * Function : versioninfo2res - * Syntax : res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver) * Input : * name - Name/ordinal of the resource * ver - The versioninfo descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver) +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; - res_t *res; ver_block_t *blk; - assert(name != NULL); - assert(ver != NULL); - - res = new_res(); - restag = put_res_header(res, WRC_RT_VERSION, NULL, name, ver->memopt, &(ver->lvc)); - rootblocksizetag = res->size; - put_word(res, 0); /* BlockSize filled in later */ - valsizetag = res->size; - put_word(res, 0); /* ValueSize filled in later*/ + 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(res, 0); /* Tree-level ? */ - for (i = 0; i < sizeof(info); i++) put_word(res, info[i]); - put_pad(res); + 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(res, info[i]); + for (i = 0; i < sizeof(info); i++) put_byte(info[i]); } - tag = res->size; - put_dword(res, VS_FFI_SIGNATURE); - put_dword(res, VS_FFI_STRUCVERSION); - put_dword(res, (ver->filever_maj1 << 16) + (ver->filever_maj2 & 0xffff)); - put_dword(res, (ver->filever_min1 << 16) + (ver->filever_min2 & 0xffff)); - put_dword(res, (ver->prodver_maj1 << 16) + (ver->prodver_maj2 & 0xffff)); - put_dword(res, (ver->prodver_min1 << 16) + (ver->prodver_min2 & 0xffff)); - put_dword(res, ver->fileflagsmask); - put_dword(res, ver->fileflags); - put_dword(res, ver->fileos); - put_dword(res, ver->filetype); - put_dword(res, ver->filesubtype); - put_dword(res, 0); /* FileDateMS */ - put_dword(res, 0); /* FileDateLS */ + 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(res, valsizetag, (WORD)(res->size - tag)); + set_word(valsizetag, output_buffer_pos - tag); /* Descend into the blocks */ for(blk = ver->blocks; blk; blk = blk->next) - versionblock2res(res, blk, 0, win32 ? ver->lvc.language : NULL); + versionblock2res(blk, 0, win32 ? ver->lvc.language : NULL); /* Set root block's size */ - set_word(res, rootblocksizetag, (WORD)(res->size - rootblocksizetag)); - return end_res(res, restag); -} - -/* - ***************************************************************************** - * Function : toolbaritem2res - * Syntax : void toolbaritem2res(res_t *res, toolbar_item_t *tbitem) - * Input : - * Output : nop - * Description : - * Remarks : Self recursive - ***************************************************************************** -*/ -static void toolbaritem2res(res_t *res, toolbar_item_t *tbitem) -{ - toolbar_item_t *itm = tbitem; - assert(win32 != 0); - while(itm) - { - put_word(res, itm->id); - itm = itm->next; - } - + set_word(rootblocksizetag, output_buffer_pos - rootblocksizetag); + set_res_size(restag); } /* ***************************************************************************** * Function : toolbar2res - * Syntax : res_t *toolbar2res(name_id_t *name, toolbar_t *toolbar) * Input : * name - Name/ordinal of the resource * toolbar - The toolbar descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *toolbar2res(name_id_t *name, toolbar_t *toolbar) +static void toolbar2res(name_id_t *name, toolbar_t *toolbar) { + toolbar_item_t *itm; int restag; - res_t *res; - assert(name != NULL); - assert(toolbar != NULL); - if (!win32) return NULL; + if (!win32) return; - res = new_res(); - restag = put_res_header(res, WRC_RT_TOOLBAR, NULL, name, toolbar->memopt, &(toolbar->lvc)); - - put_word(res, 1); /* Menuheader: Version */ - put_word(res, toolbar->button_width); /* (in pixels?) */ - put_word(res, toolbar->button_height); /* (in pixels?) */ - put_word(res, toolbar->nitems); - put_pad(res); - toolbaritem2res(res, toolbar->items); - return end_res(res, restag); + 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 - * Syntax : res_t *dlginit2res(name_id_t *name, dlginit_t *dit) * Input : * name - Name/ordinal of the resource * rdt - The dlginit descriptor - * Output : New .res format structure - * Description : - * Remarks : ***************************************************************************** */ -static res_t *dlginit2res(name_id_t *name, dlginit_t *dit) +static void dlginit2res(name_id_t *name, dlginit_t *dit) { - int restag; - res_t *res; - assert(name != NULL); - assert(dit != NULL); + int restag = put_res_header(WRC_RT_DLGINIT, name, dit->memopt, &dit->data->lvc); - res = new_res(); - restag = put_res_header(res, WRC_RT_DLGINIT, NULL, name, dit->memopt, &(dit->data->lvc)); - put_raw_data(res, dit->data, 0); - return end_res(res, restag); -} - -/* - ***************************************************************************** - * Function : resources2res - * Syntax : void resources2res(resource_t *top) - * Input : - * top - The resource-tree to convert - * Output : - * Description : Convert logical resource descriptors into binary data - * Remarks : - ***************************************************************************** -*/ -static void resources2res(resource_t *top) -{ - while(top) - { - switch(top->type) - { - case res_acc: - if(!top->binres) - top->binres = accelerator2res(top->name, top->res.acc); - break; - case res_bmp: - if(!top->binres) - top->binres = bitmap2res(top->name, top->res.bmp); - break; - case res_cur: - if(!top->binres) - top->binres = cursor2res(top->res.cur); - break; - case res_curg: - if(!top->binres) - top->binres = cursorgroup2res(top->name, top->res.curg); - break; - case res_dlg: - if(!top->binres) - top->binres = dialog2res(top->name, top->res.dlg); - break; - case res_fnt: - if(!top->binres) - top->binres = font2res(top->name, top->res.fnt); - break; - case res_fntdir: - if(!top->binres) - top->binres = fontdir2res(top->name, top->res.fnd); - break; - case res_ico: - if(!top->binres) - top->binres = icon2res(top->res.ico); - break; - case res_icog: - if(!top->binres) - top->binres = icongroup2res(top->name, top->res.icog); - break; - case res_men: - if(!top->binres) - top->binres = menu2res(top->name, top->res.men); - break; - case res_html: - if(!top->binres) - top->binres = html2res(top->name, top->res.html); - break; - case res_rdt: - if(!top->binres) - top->binres = rcdata2res(top->name, top->res.rdt); - break; - case res_stt: - if(!top->binres) - top->binres = stringtable2res(top->res.stt); - break; - case res_usr: - if(!top->binres) - top->binres = user2res(top->name, top->res.usr); - break; - case res_msg: - if(!top->binres) - top->binres = messagetable2res(top->name, top->res.msg); - break; - case res_ver: - if(!top->binres) - top->binres = versioninfo2res(top->name, top->res.ver); - break; - case res_toolbar: - if(!top->binres) - top->binres = toolbar2res(top->name, top->res.tbt); - break; - case res_dlginit: - if(!top->binres) - top->binres = dlginit2res(top->name, top->res.dlgi); - break; - case res_anicur: - case res_aniico: - if(!top->binres) - top->binres = anicurico2res(top->name, top->res.ani, top->type); - break; - default: - assert(0); - } - top = top->next; - } + put_data(dit->data->data, dit->data->size); + set_res_size(restag); } /* @@ -1583,69 +1198,69 @@ static void resources2res(resource_t *top) * Input : * outname - Filename to write to * top - The resource-tree to convert - * Output : - * Description : - * Remarks : ***************************************************************************** */ void write_resfile(char *outname, resource_t *top) { FILE *fo; unsigned int ret; - char zeros[3] = {0, 0, 0}; - - /* Convert the internal lists to binary data */ - resources2res(resource_top); fo = fopen(outname, "wb"); if(!fo) fatal_perror("Could not open %s", outname); + init_output_buffer(); + if(win32) { /* Put an empty resource first to signal win32 format */ - res_t *res = new_res(); - put_dword(res, 0); /* ResSize */ - put_dword(res, 0x00000020); /* HeaderSize */ - put_word(res, 0xffff); /* ResType */ - put_word(res, 0); - put_word(res, 0xffff); /* ResName */ - put_word(res, 0); - put_dword(res, 0); /* DataVersion */ - put_word(res, 0); /* Memory options */ - put_word(res, 0); /* Language */ - put_dword(res, 0); /* Version */ - put_dword(res, 0); /* Characteristics */ - ret = fwrite(res->data, 1, res->size, fo); - if(ret != res->size) - { - fclose(fo); - error("Error writing %s\n", outname); - } - free(res); + 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) + for ( ; top; top = top->next) { - if(!top->binres) - continue; + 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 ); + } - ret = fwrite(top->binres->data, 1, top->binres->size, fo); - if(ret != top->binres->size) - { - fclose(fo); - error("Error writing %s\n", outname); - } - if(win32 && (top->binres->size & 0x03)) - { - /* Write padding */ - ret = fwrite(zeros, 1, 4 - (top->binres->size & 0x03), fo); - if(ret != 4 - (top->binres->size & 0x03)) - { - fclose(fo); - error("Error writing %s\n", outname); - } - } + ret = fwrite(output_buffer, 1, output_buffer_pos, fo); + if(ret != output_buffer_pos) + { + fclose(fo); + error("Error writing %s\n", outname); } if (fclose(fo)) fatal_perror("Error writing %s", outname); diff --git a/tools/wrc/wrctypes.h b/tools/wrc/wrctypes.h index 565b8066483..fa9715b8ffd 100644 --- a/tools/wrc/wrctypes.h +++ b/tools/wrc/wrctypes.h @@ -78,16 +78,6 @@ typedef struct int col; } location_t; -/* Binary resource structure */ -#define RES_BLOCKSIZE 512 - -typedef struct res { - unsigned int allocsize; /* Allocated datablock size */ - unsigned int size; /* Actual size of data */ - unsigned int dataidx; /* Tag behind the resource-header */ - unsigned char *data; -} res_t; - /* Resource strings are slightly more complex because they include '\0' */ enum str_e {str_char, str_unicode}; @@ -588,7 +578,6 @@ typedef struct resource { versioninfo_t *ver; void *overlay; /* To catch all types at once... */ } res; - res_t *binres; /* To binary converted resource */ DWORD memopt; } resource_t;