newstruc.c 14 KB

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