Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/tools/wrc/newstruc.c
4388 views
1
/*
2
* Create dynamic new structures of various types
3
* and some utils in that trend.
4
*
5
* Copyright 1998 Bertho A. Stultiens
6
*
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.
11
*
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.
16
*
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
20
*/
21
22
#include "config.h"
23
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <assert.h>
28
#include <ctype.h>
29
30
#include "../tools.h"
31
#include "wrc.h"
32
#include "newstruc.h"
33
#include "utils.h"
34
#include "parser.h"
35
36
#include "wingdi.h" /* for BITMAPINFOHEADER */
37
38
#pragma pack(push,2)
39
typedef struct
40
{
41
unsigned int biSize;
42
unsigned short biWidth;
43
unsigned short biHeight;
44
unsigned short biPlanes;
45
unsigned short biBitCount;
46
} BITMAPOS2HEADER;
47
#pragma pack(pop)
48
49
/* New instances for all types of structures */
50
/* Very inefficient (in size), but very functional :-]
51
* Especially for type-checking.
52
*/
53
54
dialog_t *new_dialog(void)
55
{
56
dialog_t *ret = xmalloc( sizeof(*ret) );
57
memset( ret, 0, sizeof(*ret) );
58
return ret;
59
}
60
61
name_id_t *new_name_id(void)
62
{
63
name_id_t *ret = xmalloc( sizeof(*ret) );
64
memset( ret, 0, sizeof(*ret) );
65
return ret;
66
}
67
68
menu_t *new_menu(void)
69
{
70
menu_t *ret = xmalloc( sizeof(*ret) );
71
memset( ret, 0, sizeof(*ret) );
72
return ret;
73
}
74
75
menu_item_t *new_menu_item(void)
76
{
77
menu_item_t *ret = xmalloc( sizeof(*ret) );
78
memset( ret, 0, sizeof(*ret) );
79
return ret;
80
}
81
82
control_t *new_control(void)
83
{
84
control_t *ret = xmalloc( sizeof(*ret) );
85
memset( ret, 0, sizeof(*ret) );
86
return ret;
87
}
88
89
icon_t *new_icon(void)
90
{
91
icon_t *ret = xmalloc( sizeof(*ret) );
92
memset( ret, 0, sizeof(*ret) );
93
return ret;
94
}
95
96
cursor_t *new_cursor(void)
97
{
98
cursor_t *ret = xmalloc( sizeof(*ret) );
99
memset( ret, 0, sizeof(*ret) );
100
return ret;
101
}
102
103
versioninfo_t *new_versioninfo(void)
104
{
105
versioninfo_t *ret = xmalloc( sizeof(*ret) );
106
memset( ret, 0, sizeof(*ret) );
107
return ret;
108
}
109
110
ver_value_t *new_ver_value(void)
111
{
112
ver_value_t *ret = xmalloc( sizeof(*ret) );
113
memset( ret, 0, sizeof(*ret) );
114
return ret;
115
}
116
117
ver_block_t *new_ver_block(void)
118
{
119
ver_block_t *ret = xmalloc( sizeof(*ret) );
120
memset( ret, 0, sizeof(*ret) );
121
return ret;
122
}
123
124
stt_entry_t *new_stt_entry(void)
125
{
126
stt_entry_t *ret = xmalloc( sizeof(*ret) );
127
memset( ret, 0, sizeof(*ret) );
128
return ret;
129
}
130
131
accelerator_t *new_accelerator(void)
132
{
133
accelerator_t *ret = xmalloc( sizeof(*ret) );
134
memset( ret, 0, sizeof(*ret) );
135
return ret;
136
}
137
138
event_t *new_event(void)
139
{
140
event_t *ret = xmalloc( sizeof(*ret) );
141
memset( ret, 0, sizeof(*ret) );
142
return ret;
143
}
144
145
raw_data_t *new_raw_data(void)
146
{
147
raw_data_t *ret = xmalloc( sizeof(*ret) );
148
memset( ret, 0, sizeof(*ret) );
149
return ret;
150
}
151
152
lvc_t *new_lvc(void)
153
{
154
lvc_t *ret = xmalloc( sizeof(*ret) );
155
memset( ret, 0, sizeof(*ret) );
156
return ret;
157
}
158
159
string_t *new_string(void)
160
{
161
string_t *ret = xmalloc( sizeof(*ret) );
162
memset( ret, 0, sizeof(*ret) );
163
set_location( &ret->loc );
164
return ret;
165
}
166
167
toolbar_item_t *new_toolbar_item(void)
168
{
169
toolbar_item_t *ret = xmalloc( sizeof(*ret) );
170
memset( ret, 0, sizeof(*ret) );
171
return ret;
172
}
173
174
ani_any_t *new_ani_any(void)
175
{
176
ani_any_t *ret = xmalloc( sizeof(*ret) );
177
memset( ret, 0, sizeof(*ret) );
178
return ret;
179
}
180
181
resource_t *new_resource(enum res_e t, void *res, int memopt, language_t lan)
182
{
183
resource_t *r = xmalloc(sizeof(resource_t));
184
memset( r, 0, sizeof(*r) );
185
r->type = t;
186
r->res.overlay = res;
187
r->memopt = memopt;
188
r->lan = lan;
189
return r;
190
}
191
192
html_t *new_html(raw_data_t *rd, int *memopt)
193
{
194
html_t *html = xmalloc(sizeof(html_t));
195
html->data = rd;
196
if(memopt)
197
{
198
html->memopt = *memopt;
199
free(memopt);
200
}
201
else
202
html->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
203
return html;
204
}
205
206
rcdata_t *new_rcdata(raw_data_t *rd, int *memopt)
207
{
208
rcdata_t *rc = xmalloc(sizeof(rcdata_t));
209
rc->data = rd;
210
if(memopt)
211
{
212
rc->memopt = *memopt;
213
free(memopt);
214
}
215
else
216
rc->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
217
return rc;
218
}
219
220
font_id_t *new_font_id(int size, string_t *face, int weight, int italic)
221
{
222
font_id_t *fid = xmalloc(sizeof(font_id_t));
223
fid->name = face;
224
fid->size = size;
225
fid->weight = weight;
226
fid->italic = italic;
227
return fid;
228
}
229
230
user_t *new_user(name_id_t *type, raw_data_t *rd, int *memopt)
231
{
232
user_t *usr = xmalloc(sizeof(user_t));
233
usr->data = rd;
234
if(memopt)
235
{
236
usr->memopt = *memopt;
237
free(memopt);
238
}
239
else
240
usr->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
241
usr->type = type;
242
return usr;
243
}
244
245
font_t *new_font(raw_data_t *rd, int *memopt)
246
{
247
font_t *fnt = xmalloc(sizeof(font_t));
248
fnt->data = rd;
249
if(memopt)
250
{
251
fnt->memopt = *memopt;
252
free(memopt);
253
}
254
else
255
fnt->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
256
return fnt;
257
}
258
259
fontdir_t *new_fontdir(raw_data_t *rd, int *memopt)
260
{
261
fontdir_t *fnd = xmalloc(sizeof(fontdir_t));
262
fnd->data = rd;
263
if(memopt)
264
{
265
fnd->memopt = *memopt;
266
free(memopt);
267
}
268
else
269
fnd->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
270
return fnd;
271
}
272
273
274
static int convert_bitmap(char *data, int size)
275
{
276
if (size > sizeof(BITMAPFILEHEADER) && data[0] == 'B' && data[1] == 'M')
277
{
278
memmove(data, data+sizeof(BITMAPFILEHEADER), size - sizeof(BITMAPFILEHEADER));
279
return sizeof(BITMAPFILEHEADER);
280
}
281
return 0;
282
}
283
284
/*
285
* Cursor and icon splitter functions used when allocating
286
* cursor- and icon-groups.
287
*/
288
typedef struct {
289
language_t lan;
290
int id;
291
} id_alloc_t;
292
293
static int get_new_id(id_alloc_t **list, int *n, language_t lan)
294
{
295
int i;
296
assert(list != NULL);
297
assert(n != NULL);
298
299
if(!*list)
300
{
301
*list = xmalloc(sizeof(id_alloc_t));
302
*n = 1;
303
(*list)[0].lan = lan;
304
(*list)[0].id = 1;
305
return 1;
306
}
307
308
for(i = 0; i < *n; i++)
309
{
310
if((*list)[i].lan == lan)
311
return ++((*list)[i].id);
312
}
313
314
*list = xrealloc(*list, sizeof(id_alloc_t) * (*n+1));
315
(*list)[*n].lan = lan;
316
(*list)[*n].id = 1;
317
*n += 1;
318
return 1;
319
}
320
321
static int alloc_icon_id(language_t lan)
322
{
323
static id_alloc_t *idlist = NULL;
324
static int nid = 0;
325
326
return get_new_id(&idlist, &nid, lan);
327
}
328
329
static int alloc_cursor_id(language_t lan)
330
{
331
static id_alloc_t *idlist = NULL;
332
static int nid = 0;
333
334
return get_new_id(&idlist, &nid, lan);
335
}
336
337
static void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico)
338
{
339
int cnt;
340
int i;
341
icon_t *ico;
342
icon_t *list = NULL;
343
icon_header_t *ih = (icon_header_t *)rd->data;
344
345
if(GET_WORD(&ih->type) != 1)
346
parser_error("Icon resource data has invalid type id %d", ih->type);
347
348
cnt = GET_WORD(&ih->count);
349
for(i = 0; i < cnt; i++)
350
{
351
icon_dir_entry_t ide;
352
int offset, size;
353
BITMAPINFOHEADER info;
354
memcpy(&ide, rd->data + sizeof(icon_header_t)
355
+ i*sizeof(icon_dir_entry_t), sizeof(ide));
356
357
ico = new_icon();
358
ico->id = alloc_icon_id(icog->lvc.language);
359
ico->lvc = icog->lvc;
360
offset = GET_DWORD(&ide.offset);
361
size = GET_DWORD(&ide.ressize);
362
if(offset > rd->size || offset + size > rd->size)
363
parser_error("Icon resource data corrupt");
364
ico->width = ide.width;
365
ico->height = ide.height;
366
ico->nclr = ide.nclr;
367
ico->planes = GET_WORD(&ide.planes);
368
ico->bits = GET_WORD(&ide.bits);
369
memcpy(&info, rd->data + offset, sizeof(info));
370
convert_bitmap((char *) &info, 0);
371
memcpy(rd->data + offset, &info, sizeof(info));
372
if(!ico->planes) ico->planes = GET_WORD(&info.biPlanes);
373
if(!ico->bits) ico->bits = GET_WORD(&info.biBitCount);
374
ico->data = new_raw_data();
375
copy_raw_data(ico->data, rd, offset, size);
376
if(!list)
377
{
378
list = ico;
379
}
380
else
381
{
382
ico->next = list;
383
list->prev = ico;
384
list = ico;
385
}
386
}
387
icog->iconlist = list;
388
*nico = cnt;
389
}
390
391
static void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur)
392
{
393
int cnt;
394
int i;
395
cursor_t *cur;
396
cursor_t *list = NULL;
397
cursor_header_t *ch = (cursor_header_t *)rd->data;
398
399
if(GET_WORD(&ch->type) != 2) parser_error("Cursor resource data has invalid type id %d", ch->type);
400
cnt = GET_WORD(&ch->count);
401
for(i = 0; i < cnt; i++)
402
{
403
cursor_dir_entry_t cde;
404
int offset, size;
405
BITMAPINFOHEADER info;
406
memcpy(&cde, rd->data + sizeof(cursor_header_t)
407
+ i*sizeof(cursor_dir_entry_t), sizeof(cde));
408
409
cur = new_cursor();
410
cur->id = alloc_cursor_id(curg->lvc.language);
411
cur->lvc = curg->lvc;
412
offset = GET_DWORD(&cde.offset);
413
size = GET_DWORD(&cde.ressize);
414
if(offset > rd->size || offset + size > rd->size)
415
parser_error("Cursor resource data corrupt");
416
cur->width = cde.width;
417
cur->height = cde.height;
418
cur->nclr = cde.nclr;
419
memcpy(&info, rd->data + offset, sizeof(info));
420
convert_bitmap((char *)&info, 0);
421
memcpy(rd->data + offset, &info, sizeof(info));
422
cur->planes = GET_WORD(&info.biPlanes);
423
cur->bits = GET_WORD(&info.biBitCount);
424
if(!win32 && (cur->planes != 1 || cur->bits != 1))
425
parser_warning("Win16 cursor contains colors\n");
426
cur->xhot = GET_WORD(&cde.xhot);
427
cur->yhot = GET_WORD(&cde.yhot);
428
cur->data = new_raw_data();
429
copy_raw_data(cur->data, rd, offset, size);
430
if(!list)
431
{
432
list = cur;
433
}
434
else
435
{
436
cur->next = list;
437
list->prev = cur;
438
list = cur;
439
}
440
}
441
curg->cursorlist = list;
442
*ncur = cnt;
443
}
444
445
446
icon_group_t *new_icon_group(raw_data_t *rd, int *memopt)
447
{
448
icon_group_t *icog = xmalloc(sizeof(icon_group_t));
449
if(memopt)
450
{
451
icog->memopt = *memopt;
452
free(memopt);
453
}
454
else
455
icog->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
456
icog->lvc = rd->lvc;
457
split_icons(rd, icog, &(icog->nicon));
458
free(rd->data);
459
free(rd);
460
return icog;
461
}
462
463
cursor_group_t *new_cursor_group(raw_data_t *rd, int *memopt)
464
{
465
cursor_group_t *curg = xmalloc(sizeof(cursor_group_t));
466
if(memopt)
467
{
468
curg->memopt = *memopt;
469
free(memopt);
470
}
471
else
472
curg->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
473
curg->lvc = rd->lvc;
474
split_cursors(rd, curg, &(curg->ncursor));
475
free(rd->data);
476
free(rd);
477
return curg;
478
}
479
480
ani_curico_t *new_ani_curico(enum res_e type, raw_data_t *rd, int *memopt)
481
{
482
ani_curico_t *ani = xmalloc(sizeof(ani_curico_t));
483
484
assert(type == res_anicur || type == res_aniico);
485
486
ani->data = rd;
487
if(memopt)
488
{
489
ani->memopt = *memopt;
490
free(memopt);
491
}
492
else
493
ani->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE;
494
return ani;
495
}
496
497
/* Bitmaps */
498
bitmap_t *new_bitmap(raw_data_t *rd, int *memopt)
499
{
500
bitmap_t *bmp = xmalloc(sizeof(bitmap_t));
501
502
bmp->data = rd;
503
if(memopt)
504
{
505
bmp->memopt = *memopt;
506
free(memopt);
507
}
508
else
509
bmp->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
510
rd->size -= convert_bitmap(rd->data, rd->size);
511
return bmp;
512
}
513
514
ver_words_t *new_ver_words(int i)
515
{
516
ver_words_t *w = xmalloc(sizeof(ver_words_t));
517
w->words = xmalloc(sizeof(unsigned short));
518
w->words[0] = i;
519
w->nwords = 1;
520
return w;
521
}
522
523
ver_words_t *add_ver_words(ver_words_t *w, int i)
524
{
525
w->words = xrealloc(w->words, (w->nwords+1) * sizeof(unsigned short));
526
w->words[w->nwords] = i;
527
w->nwords++;
528
return w;
529
}
530
531
#define MSGTAB_BAD_PTR(p, b, l, r) (((l) - ((char *)(p) - (char *)(b))) > (r))
532
messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
533
{
534
messagetable_t *msg = xmalloc(sizeof(messagetable_t));
535
536
msg->data = rd;
537
if(memopt)
538
{
539
msg->memopt = *memopt;
540
free(memopt);
541
}
542
else
543
msg->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
544
545
if(rd->size < sizeof(unsigned int))
546
parser_error("Invalid messagetable, size too small");
547
548
return msg;
549
}
550
#undef MSGTAB_BAD_PTR
551
552
void copy_raw_data(raw_data_t *dst, raw_data_t *src, unsigned int offs, int len)
553
{
554
assert(offs <= src->size);
555
assert(offs + len <= src->size);
556
if(!dst->data)
557
{
558
dst->data = xmalloc(len);
559
dst->size = 0;
560
}
561
else
562
dst->data = xrealloc(dst->data, dst->size + len);
563
/* dst->size holds the offset to copy to */
564
memcpy(dst->data + dst->size, src->data + offs, len);
565
dst->size += len;
566
}
567
568
int *new_int(int i)
569
{
570
int *ip = xmalloc(sizeof(int));
571
*ip = i;
572
return ip;
573
}
574
575
stringtable_t *new_stringtable(lvc_t *lvc)
576
{
577
stringtable_t *stt = xmalloc(sizeof(stringtable_t));
578
579
memset( stt, 0, sizeof(*stt) );
580
if(lvc)
581
stt->lvc = *lvc;
582
583
return stt;
584
}
585
586
toolbar_t *new_toolbar(int button_width, int button_height, toolbar_item_t *items, int nitems)
587
{
588
toolbar_t *tb = xmalloc(sizeof(toolbar_t));
589
memset( tb, 0, sizeof(*tb) );
590
tb->button_width = button_width;
591
tb->button_height = button_height;
592
tb->nitems = nitems;
593
tb->items = items;
594
return tb;
595
}
596
597
dlginit_t *new_dlginit(raw_data_t *rd, int *memopt)
598
{
599
dlginit_t *di = xmalloc(sizeof(dlginit_t));
600
di->data = rd;
601
if(memopt)
602
{
603
di->memopt = *memopt;
604
free(memopt);
605
}
606
else
607
di->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE | WRC_MO_DISCARDABLE;
608
609
return di;
610
}
611
612
style_pair_t *new_style_pair(style_t *style, style_t *exstyle)
613
{
614
style_pair_t *sp = xmalloc(sizeof(style_pair_t));
615
sp->style = style;
616
sp->exstyle = exstyle;
617
return sp;
618
}
619
620
style_t *new_style(unsigned int or_mask, unsigned int and_mask)
621
{
622
style_t *st = xmalloc(sizeof(style_t));
623
st->or_mask = or_mask;
624
st->and_mask = and_mask;
625
return st;
626
}
627
628