winepulse: Move AudioClient's GetService into mmdevapi.
[wine.git] / tools / wrc / newstruc.c
blob9602cdfbf92f642d844dc189436b6f2f9af65d49
1 /*
2 * Create dynamic new structures of various types
3 * and some utils in that trend.
5 * Copyright 1998 Bertho A. Stultiens
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <ctype.h>
30 #include "../tools.h"
31 #include "wrc.h"
32 #include "newstruc.h"
33 #include "utils.h"
34 #include "parser.h"
36 #include "wingdi.h" /* for BITMAPINFOHEADER */
38 #include <pshpack2.h>
39 typedef struct
41 unsigned int biSize;
42 unsigned short biWidth;
43 unsigned short biHeight;
44 unsigned short biPlanes;
45 unsigned short biBitCount;
46 } BITMAPOS2HEADER;
47 #include <poppack.h>
49 /* New instances for all types of structures */
50 /* Very inefficient (in size), but very functional :-]
51 * Especially for type-checking.
54 dialog_t *new_dialog(void)
56 dialog_t *ret = xmalloc( sizeof(*ret) );
57 memset( ret, 0, sizeof(*ret) );
58 return ret;
61 name_id_t *new_name_id(void)
63 name_id_t *ret = xmalloc( sizeof(*ret) );
64 memset( ret, 0, sizeof(*ret) );
65 return ret;
68 menu_t *new_menu(void)
70 menu_t *ret = xmalloc( sizeof(*ret) );
71 memset( ret, 0, sizeof(*ret) );
72 return ret;
75 menu_item_t *new_menu_item(void)
77 menu_item_t *ret = xmalloc( sizeof(*ret) );
78 memset( ret, 0, sizeof(*ret) );
79 return ret;
82 control_t *new_control(void)
84 control_t *ret = xmalloc( sizeof(*ret) );
85 memset( ret, 0, sizeof(*ret) );
86 return ret;
89 icon_t *new_icon(void)
91 icon_t *ret = xmalloc( sizeof(*ret) );
92 memset( ret, 0, sizeof(*ret) );
93 return ret;
96 cursor_t *new_cursor(void)
98 cursor_t *ret = xmalloc( sizeof(*ret) );
99 memset( ret, 0, sizeof(*ret) );
100 return ret;
103 versioninfo_t *new_versioninfo(void)
105 versioninfo_t *ret = xmalloc( sizeof(*ret) );
106 memset( ret, 0, sizeof(*ret) );
107 return ret;
110 ver_value_t *new_ver_value(void)
112 ver_value_t *ret = xmalloc( sizeof(*ret) );
113 memset( ret, 0, sizeof(*ret) );
114 return ret;
117 ver_block_t *new_ver_block(void)
119 ver_block_t *ret = xmalloc( sizeof(*ret) );
120 memset( ret, 0, sizeof(*ret) );
121 return ret;
124 stt_entry_t *new_stt_entry(void)
126 stt_entry_t *ret = xmalloc( sizeof(*ret) );
127 memset( ret, 0, sizeof(*ret) );
128 return ret;
131 accelerator_t *new_accelerator(void)
133 accelerator_t *ret = xmalloc( sizeof(*ret) );
134 memset( ret, 0, sizeof(*ret) );
135 return ret;
138 event_t *new_event(void)
140 event_t *ret = xmalloc( sizeof(*ret) );
141 memset( ret, 0, sizeof(*ret) );
142 return ret;
145 raw_data_t *new_raw_data(void)
147 raw_data_t *ret = xmalloc( sizeof(*ret) );
148 memset( ret, 0, sizeof(*ret) );
149 return ret;
152 lvc_t *new_lvc(void)
154 lvc_t *ret = xmalloc( sizeof(*ret) );
155 memset( ret, 0, sizeof(*ret) );
156 return ret;
159 res_count_t *new_res_count(void)
161 res_count_t *ret = xmalloc( sizeof(*ret) );
162 memset( ret, 0, sizeof(*ret) );
163 return ret;
166 string_t *new_string(void)
168 string_t *ret = xmalloc( sizeof(*ret) );
169 memset( ret, 0, sizeof(*ret) );
170 set_location( &ret->loc );
171 return ret;
174 toolbar_item_t *new_toolbar_item(void)
176 toolbar_item_t *ret = xmalloc( sizeof(*ret) );
177 memset( ret, 0, sizeof(*ret) );
178 return ret;
181 ani_any_t *new_ani_any(void)
183 ani_any_t *ret = xmalloc( sizeof(*ret) );
184 memset( ret, 0, sizeof(*ret) );
185 return ret;
188 resource_t *new_resource(enum res_e t, void *res, int memopt, language_t lan)
190 resource_t *r = xmalloc(sizeof(resource_t));
191 memset( r, 0, sizeof(*r) );
192 r->type = t;
193 r->res.overlay = res;
194 r->memopt = memopt;
195 r->lan = lan;
196 return r;
199 html_t *new_html(raw_data_t *rd, int *memopt)
201 html_t *html = xmalloc(sizeof(html_t));
202 html->data = rd;
203 if(memopt)
205 html->memopt = *memopt;
206 free(memopt);
208 else
209 html->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
210 return html;
213 rcdata_t *new_rcdata(raw_data_t *rd, int *memopt)
215 rcdata_t *rc = xmalloc(sizeof(rcdata_t));
216 rc->data = rd;
217 if(memopt)
219 rc->memopt = *memopt;
220 free(memopt);
222 else
223 rc->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
224 return rc;
227 font_id_t *new_font_id(int size, string_t *face, int weight, int italic)
229 font_id_t *fid = xmalloc(sizeof(font_id_t));
230 fid->name = face;
231 fid->size = size;
232 fid->weight = weight;
233 fid->italic = italic;
234 return fid;
237 user_t *new_user(name_id_t *type, raw_data_t *rd, int *memopt)
239 user_t *usr = xmalloc(sizeof(user_t));
240 usr->data = rd;
241 if(memopt)
243 usr->memopt = *memopt;
244 free(memopt);
246 else
247 usr->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
248 usr->type = type;
249 return usr;
252 font_t *new_font(raw_data_t *rd, int *memopt)
254 font_t *fnt = xmalloc(sizeof(font_t));
255 fnt->data = rd;
256 if(memopt)
258 fnt->memopt = *memopt;
259 free(memopt);
261 else
262 fnt->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
263 return fnt;
266 fontdir_t *new_fontdir(raw_data_t *rd, int *memopt)
268 fontdir_t *fnd = xmalloc(sizeof(fontdir_t));
269 fnd->data = rd;
270 if(memopt)
272 fnd->memopt = *memopt;
273 free(memopt);
275 else
276 fnd->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
277 return fnd;
281 static int convert_bitmap(char *data, int size)
283 if (size > sizeof(BITMAPFILEHEADER) && data[0] == 'B' && data[1] == 'M')
285 memmove(data, data+sizeof(BITMAPFILEHEADER), size - sizeof(BITMAPFILEHEADER));
286 return sizeof(BITMAPFILEHEADER);
288 return 0;
292 * Cursor and icon splitter functions used when allocating
293 * cursor- and icon-groups.
295 typedef struct {
296 language_t lan;
297 int id;
298 } id_alloc_t;
300 static int get_new_id(id_alloc_t **list, int *n, language_t lan)
302 int i;
303 assert(list != NULL);
304 assert(n != NULL);
306 if(!*list)
308 *list = xmalloc(sizeof(id_alloc_t));
309 *n = 1;
310 (*list)[0].lan = lan;
311 (*list)[0].id = 1;
312 return 1;
315 for(i = 0; i < *n; i++)
317 if((*list)[i].lan == lan)
318 return ++((*list)[i].id);
321 *list = xrealloc(*list, sizeof(id_alloc_t) * (*n+1));
322 (*list)[*n].lan = lan;
323 (*list)[*n].id = 1;
324 *n += 1;
325 return 1;
328 static int alloc_icon_id(language_t lan)
330 static id_alloc_t *idlist = NULL;
331 static int nid = 0;
333 return get_new_id(&idlist, &nid, lan);
336 static int alloc_cursor_id(language_t lan)
338 static id_alloc_t *idlist = NULL;
339 static int nid = 0;
341 return get_new_id(&idlist, &nid, lan);
344 static void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico)
346 int cnt;
347 int i;
348 icon_t *ico;
349 icon_t *list = NULL;
350 icon_header_t *ih = (icon_header_t *)rd->data;
352 if(GET_WORD(&ih->type) != 1)
353 parser_error("Icon resource data has invalid type id %d", ih->type);
355 cnt = GET_WORD(&ih->count);
356 for(i = 0; i < cnt; i++)
358 icon_dir_entry_t ide;
359 int offset, size;
360 BITMAPINFOHEADER info;
361 memcpy(&ide, rd->data + sizeof(icon_header_t)
362 + i*sizeof(icon_dir_entry_t), sizeof(ide));
364 ico = new_icon();
365 ico->id = alloc_icon_id(icog->lvc.language);
366 ico->lvc = icog->lvc;
367 offset = GET_DWORD(&ide.offset);
368 size = GET_DWORD(&ide.ressize);
369 if(offset > rd->size || offset + size > rd->size)
370 parser_error("Icon resource data corrupt");
371 ico->width = ide.width;
372 ico->height = ide.height;
373 ico->nclr = ide.nclr;
374 ico->planes = GET_WORD(&ide.planes);
375 ico->bits = GET_WORD(&ide.bits);
376 memcpy(&info, rd->data + offset, sizeof(info));
377 convert_bitmap((char *) &info, 0);
378 memcpy(rd->data + offset, &info, sizeof(info));
379 if(!ico->planes) ico->planes = GET_WORD(&info.biPlanes);
380 if(!ico->bits) ico->bits = GET_WORD(&info.biBitCount);
381 ico->data = new_raw_data();
382 copy_raw_data(ico->data, rd, offset, size);
383 if(!list)
385 list = ico;
387 else
389 ico->next = list;
390 list->prev = ico;
391 list = ico;
394 icog->iconlist = list;
395 *nico = cnt;
398 static void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur)
400 int cnt;
401 int i;
402 cursor_t *cur;
403 cursor_t *list = NULL;
404 cursor_header_t *ch = (cursor_header_t *)rd->data;
406 if(GET_WORD(&ch->type) != 2) parser_error("Cursor resource data has invalid type id %d", ch->type);
407 cnt = GET_WORD(&ch->count);
408 for(i = 0; i < cnt; i++)
410 cursor_dir_entry_t cde;
411 int offset, size;
412 BITMAPINFOHEADER info;
413 memcpy(&cde, rd->data + sizeof(cursor_header_t)
414 + i*sizeof(cursor_dir_entry_t), sizeof(cde));
416 cur = new_cursor();
417 cur->id = alloc_cursor_id(curg->lvc.language);
418 cur->lvc = curg->lvc;
419 offset = GET_DWORD(&cde.offset);
420 size = GET_DWORD(&cde.ressize);
421 if(offset > rd->size || offset + size > rd->size)
422 parser_error("Cursor resource data corrupt");
423 cur->width = cde.width;
424 cur->height = cde.height;
425 cur->nclr = cde.nclr;
426 memcpy(&info, rd->data + offset, sizeof(info));
427 convert_bitmap((char *)&info, 0);
428 memcpy(rd->data + offset, &info, sizeof(info));
429 cur->planes = GET_WORD(&info.biPlanes);
430 cur->bits = GET_WORD(&info.biBitCount);
431 if(!win32 && (cur->planes != 1 || cur->bits != 1))
432 parser_warning("Win16 cursor contains colors\n");
433 cur->xhot = GET_WORD(&cde.xhot);
434 cur->yhot = GET_WORD(&cde.yhot);
435 cur->data = new_raw_data();
436 copy_raw_data(cur->data, rd, offset, size);
437 if(!list)
439 list = cur;
441 else
443 cur->next = list;
444 list->prev = cur;
445 list = cur;
448 curg->cursorlist = list;
449 *ncur = cnt;
453 icon_group_t *new_icon_group(raw_data_t *rd, int *memopt)
455 icon_group_t *icog = xmalloc(sizeof(icon_group_t));
456 if(memopt)
458 icog->memopt = *memopt;
459 free(memopt);
461 else
462 icog->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
463 icog->lvc = rd->lvc;
464 split_icons(rd, icog, &(icog->nicon));
465 free(rd->data);
466 free(rd);
467 return icog;
470 cursor_group_t *new_cursor_group(raw_data_t *rd, int *memopt)
472 cursor_group_t *curg = xmalloc(sizeof(cursor_group_t));
473 if(memopt)
475 curg->memopt = *memopt;
476 free(memopt);
478 else
479 curg->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
480 curg->lvc = rd->lvc;
481 split_cursors(rd, curg, &(curg->ncursor));
482 free(rd->data);
483 free(rd);
484 return curg;
487 ani_curico_t *new_ani_curico(enum res_e type, raw_data_t *rd, int *memopt)
489 ani_curico_t *ani = xmalloc(sizeof(ani_curico_t));
491 assert(type == res_anicur || type == res_aniico);
493 ani->data = rd;
494 if(memopt)
496 ani->memopt = *memopt;
497 free(memopt);
499 else
500 ani->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
501 return ani;
504 /* Bitmaps */
505 bitmap_t *new_bitmap(raw_data_t *rd, int *memopt)
507 bitmap_t *bmp = xmalloc(sizeof(bitmap_t));
509 bmp->data = rd;
510 if(memopt)
512 bmp->memopt = *memopt;
513 free(memopt);
515 else
516 bmp->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
517 rd->size -= convert_bitmap(rd->data, rd->size);
518 return bmp;
521 ver_words_t *new_ver_words(int i)
523 ver_words_t *w = xmalloc(sizeof(ver_words_t));
524 w->words = xmalloc(sizeof(unsigned short));
525 w->words[0] = i;
526 w->nwords = 1;
527 return w;
530 ver_words_t *add_ver_words(ver_words_t *w, int i)
532 w->words = xrealloc(w->words, (w->nwords+1) * sizeof(unsigned short));
533 w->words[w->nwords] = i;
534 w->nwords++;
535 return w;
538 #define MSGTAB_BAD_PTR(p, b, l, r) (((l) - ((char *)(p) - (char *)(b))) > (r))
539 messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
541 messagetable_t *msg = xmalloc(sizeof(messagetable_t));
543 msg->data = rd;
544 if(memopt)
546 msg->memopt = *memopt;
547 free(memopt);
549 else
550 msg->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
552 if(rd->size < sizeof(unsigned int))
553 parser_error("Invalid messagetable, size too small");
555 return msg;
557 #undef MSGTAB_BAD_PTR
559 void copy_raw_data(raw_data_t *dst, raw_data_t *src, unsigned int offs, int len)
561 assert(offs <= src->size);
562 assert(offs + len <= src->size);
563 if(!dst->data)
565 dst->data = xmalloc(len);
566 dst->size = 0;
568 else
569 dst->data = xrealloc(dst->data, dst->size + len);
570 /* dst->size holds the offset to copy to */
571 memcpy(dst->data + dst->size, src->data + offs, len);
572 dst->size += len;
575 int *new_int(int i)
577 int *ip = xmalloc(sizeof(int));
578 *ip = i;
579 return ip;
582 stringtable_t *new_stringtable(lvc_t *lvc)
584 stringtable_t *stt = xmalloc(sizeof(stringtable_t));
586 memset( stt, 0, sizeof(*stt) );
587 if(lvc)
588 stt->lvc = *lvc;
590 return stt;
593 toolbar_t *new_toolbar(int button_width, int button_height, toolbar_item_t *items, int nitems)
595 toolbar_t *tb = xmalloc(sizeof(toolbar_t));
596 memset( tb, 0, sizeof(*tb) );
597 tb->button_width = button_width;
598 tb->button_height = button_height;
599 tb->nitems = nitems;
600 tb->items = items;
601 return tb;
604 dlginit_t *new_dlginit(raw_data_t *rd, int *memopt)
606 dlginit_t *di = xmalloc(sizeof(dlginit_t));
607 di->data = rd;
608 if(memopt)
610 di->memopt = *memopt;
611 free(memopt);
613 else
614 di->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
616 return di;
619 style_pair_t *new_style_pair(style_t *style, style_t *exstyle)
621 style_pair_t *sp = xmalloc(sizeof(style_pair_t));
622 sp->style = style;
623 sp->exstyle = exstyle;
624 return sp;
627 style_t *new_style(unsigned int or_mask, unsigned int and_mask)
629 style_t *st = xmalloc(sizeof(style_t));
630 st->or_mask = or_mask;
631 st->and_mask = and_mask;
632 return st;