1 /* wvWare
2 * Copyright (C) Caolan McNamara, Dom Lachowicz, and others
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 * 02111-1307, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <errno.h>
28 #include "wv.h"
29
30
31 void
wvReleaseEscher(escherstruct * item)32 wvReleaseEscher (escherstruct * item)
33 {
34 wvReleaseDggContainer (&item->dggcontainer);
35 wvReleaseDgContainer (&item->dgcontainer);
36 }
37
38 void
wvInitEscher(escherstruct * item)39 wvInitEscher (escherstruct * item)
40 {
41 wvInitDggContainer (&item->dggcontainer);
42 wvInitDgContainer (&item->dgcontainer);
43 }
44
45 void
wvGetEscher(escherstruct * item,U32 offset,U32 len,wvStream * fd,wvStream * delay)46 wvGetEscher (escherstruct * item, U32 offset, U32 len, wvStream * fd,
47 wvStream * delay)
48 {
49 U32 count = 0;
50 MSOFBH amsofbh;
51
52 wvStream_goto (fd, offset);
53 wvTrace (("offset %x, len %d\n", offset, len));
54 wvInitEscher (item);
55 while (count < len)
56 {
57 count += wvGetMSOFBH (&amsofbh, fd);
58 wvTrace (
59 ("count is %x,len is %x, next len is %x\n", count, len,
60 amsofbh.cbLength));
61 wvTrace (("type is %x\n ", amsofbh.fbt));
62 switch (amsofbh.fbt)
63 {
64 case msofbtDggContainer:
65 count +=
66 wvGetDggContainer (&item->dggcontainer, &amsofbh, fd,
67 delay);
68 break;
69 case msofbtDgContainer:
70 count += wvGetDgContainer (&item->dgcontainer, &amsofbh, fd);
71 break;
72 default:
73 wvError (("Not a container, panic (%x)\n", amsofbh.fbt));
74 return;
75 break;
76 }
77 }
78 wvTrace (("offset %x, len %d (pos %x)\n", offset, len, wvStream_tell (fd)));
79 }
80
81 void
wvReleaseDggContainer(DggContainer * item)82 wvReleaseDggContainer (DggContainer * item)
83 {
84 wvReleaseSplitMenuColors (&item->splitmenucolors);
85 wvReleaseDgg (&item->dgg);
86 wvReleaseBstoreContainer (&item->bstorecontainer);
87 }
88
89 void
wvInitDggContainer(DggContainer * item)90 wvInitDggContainer (DggContainer * item)
91 {
92 wvInitSplitMenuColors (&item->splitmenucolors);
93 wvInitDgg (&item->dgg);
94 wvInitBstoreContainer (&item->bstorecontainer);
95 }
96
97 U32
wvGetDggContainer(DggContainer * item,MSOFBH * msofbh,wvStream * fd,wvStream * delay)98 wvGetDggContainer (DggContainer * item, MSOFBH * msofbh, wvStream * fd,
99 wvStream * delay)
100 {
101 MSOFBH amsofbh;
102 U32 count = 0;
103
104 while (count < msofbh->cbLength)
105 {
106 count += wvGetMSOFBH (&amsofbh, fd);
107 wvTrace (
108 ("len is %x, type is %x, count %x,fullen %x\n",
109 amsofbh.cbLength, amsofbh.fbt, count, msofbh->cbLength));
110 wvTrace (("type is %x\n ", amsofbh.fbt));
111 switch (amsofbh.fbt)
112 {
113 case msofbtDgg:
114 count += wvGetDgg (&item->dgg, &amsofbh, fd);
115 break;
116 case msofbtSplitMenuColors:
117 count +=
118 wvGetSplitMenuColors (&item->splitmenucolors, &amsofbh, fd);
119 break;
120 case msofbtBstoreContainer:
121 count +=
122 wvGetBstoreContainer (&item->bstorecontainer, &amsofbh,
123 fd, delay);
124 wvTrace (
125 ("type is %d (number is %d\n",
126 item->bstorecontainer.blip[item->bstorecontainer.
127 no_fbse - 1].type,
128 item->bstorecontainer.no_fbse));
129 break;
130 default:
131 count += wvEatmsofbt (&amsofbh, fd);
132 wvError (("Eating type 0x%x\n", amsofbh.fbt));
133 break;
134 }
135 }
136 /*
137 For some reason I appear to have an extra byte associated either with
138 this or its wrapper, I will investigate further.
139 */
140 read_8ubit (fd);
141 count++;
142
143 return (count);
144 }
145
146 void
wvReleaseDgContainer(DgContainer * item)147 wvReleaseDgContainer (DgContainer * item)
148 {
149 U32 i;
150 for (i = 0; i < item->no_spgrcontainer; i++)
151 wvReleaseSpgrContainer (&(item->spgrcontainer[i]));
152 wvFree (item->spgrcontainer);
153
154 for (i = 0; i < item->no_spcontainer; i++)
155 wvReleaseFSPContainer (&(item->spcontainer[i]));
156 wvFree (item->spcontainer);
157 }
158
159 void
wvInitDgContainer(DgContainer * item)160 wvInitDgContainer (DgContainer * item)
161 {
162 item->no_spgrcontainer = 0;
163 item->spgrcontainer = NULL;
164 }
165
166 void
wvReleaseBstoreContainer(BstoreContainer * item)167 wvReleaseBstoreContainer (BstoreContainer * item)
168 {
169 U32 i;
170 for (i = 0; i < item->no_fbse; i++)
171 wvReleaseBlip (&item->blip[i]);
172 wvFree (item->blip);
173 }
174
175 void
wvInitBstoreContainer(BstoreContainer * item)176 wvInitBstoreContainer (BstoreContainer * item)
177 {
178 item->no_fbse = 0;
179 item->blip = NULL;
180 }
181
182 U32
wvGetBstoreContainer(BstoreContainer * item,MSOFBH * msofbh,wvStream * fd,wvStream * delay)183 wvGetBstoreContainer (BstoreContainer * item, MSOFBH * msofbh, wvStream * fd,
184 wvStream * delay)
185 {
186 MSOFBH amsofbh;
187 U32 count = 0;
188 while (count < msofbh->cbLength)
189 {
190 count += wvGetMSOFBH (&amsofbh, fd);
191 wvTrace (("type is %x\n ", amsofbh.fbt));
192 switch (amsofbh.fbt)
193 {
194 case msofbtBSE:
195 wvTrace (("Blip at %x\n", wvStream_tell (fd)));
196 item->no_fbse++;
197 item->blip =
198 (Blip *) realloc (item->blip,
199 sizeof (Blip) * item->no_fbse);
200 count +=
201 wvGetBlip ((&item->blip[item->no_fbse - 1]), fd, delay);
202 wvTrace (
203 ("type is %d (number is %d\n",
204 item->blip[item->no_fbse - 1].type, item->no_fbse));
205 break;
206 default:
207 count += wvEatmsofbt (&amsofbh, fd);
208 wvError (("Eating type 0x%x\n", amsofbh.fbt));
209 break;
210 }
211 }
212 return (count);
213 }
214
215 U32
wvGetDgContainer(DgContainer * item,MSOFBH * msofbh,wvStream * fd)216 wvGetDgContainer (DgContainer * item, MSOFBH * msofbh, wvStream * fd)
217 {
218 MSOFBH amsofbh;
219 U32 count = 0;
220
221 item->spcontainer = NULL;
222 item->no_spcontainer = 0;
223
224 while (count < msofbh->cbLength)
225 {
226 count += wvGetMSOFBH (&amsofbh, fd);
227 wvTrace (
228 ("len is %x, type is %x, count %x,fullen %x\n",
229 amsofbh.cbLength, amsofbh.fbt, count, msofbh->cbLength));
230 wvTrace (("type is %x\n ", amsofbh.fbt));
231 switch (amsofbh.fbt)
232 {
233 case msofbtDg:
234 count += wvGetFDG (&item->fdg, fd);
235 break;
236 case msofbtSpgrContainer:
237 item->no_spgrcontainer++;
238 item->spgrcontainer =
239 (SpgrContainer *) realloc (item->spgrcontainer,
240 sizeof (SpgrContainer) *
241 item->no_spgrcontainer);
242 count +=
243 wvGetSpgrContainer (&
244 (item->spgrcontainer
245 [item->no_spgrcontainer - 1]), &amsofbh, fd);
246 break;
247 case msofbtSpContainer:
248 item->no_spcontainer++;
249 item->spcontainer =
250 (FSPContainer *) realloc (item->spcontainer,
251 sizeof (FSPContainer) *
252 item->no_spcontainer);
253 count +=
254 wvGetFSPContainer (&
255 (item->spcontainer
256 [item->no_spcontainer - 1]), &amsofbh, fd);
257 break;
258 default:
259 count += wvEatmsofbt (&amsofbh, fd);
260 wvError (("Eating type 0x%x\n", amsofbh.fbt));
261 break;
262 }
263 }
264 return (count);
265 }
266
267 FSPContainer *
wvFindSPID(SpgrContainer * item,S32 spid)268 wvFindSPID (SpgrContainer * item, S32 spid)
269 {
270 U32 i;
271 FSPContainer *t;
272 for (i = 0; i < item->no_spcontainer; i++)
273 {
274 /* FIXME: Cast below is to avoid compiler warnings, but having
275 to have it could be a sign of something wrong. */
276 if (item->spcontainer[i].fsp.spid == (U32) spid)
277 {
278 wvTrace (("FOUND IT\n"));
279 return (&(item->spcontainer[i]));
280 }
281 }
282 for (i = 0; i < item->no_spgrcontainer; i++)
283 {
284 t = wvFindSPID (&(item->spgrcontainer[i]), spid);
285 if (t)
286 return (t);
287 }
288 return (NULL);
289 }
290
291
292 void
wvReleaseSpgrContainer(SpgrContainer * item)293 wvReleaseSpgrContainer (SpgrContainer * item)
294 {
295 U32 i;
296 for (i = 0; i < item->no_spcontainer; i++)
297 wvReleaseFSPContainer (&(item->spcontainer[i]));
298 wvFree (item->spcontainer);
299 for (i = 0; i < item->no_spgrcontainer; i++)
300 wvReleaseSpgrContainer (&(item->spgrcontainer[i]));
301 wvFree (item->spgrcontainer);
302 }
303
304
305 U32
wvGetSpgrContainer(SpgrContainer * item,MSOFBH * msofbh,wvStream * fd)306 wvGetSpgrContainer (SpgrContainer * item, MSOFBH * msofbh, wvStream * fd)
307 {
308 MSOFBH amsofbh;
309 U32 count = 0;
310
311 item->spgrcontainer = NULL;
312 item->no_spgrcontainer = 0;
313 item->spcontainer = NULL;
314 item->no_spcontainer = 0;
315
316 while (count < msofbh->cbLength)
317 {
318 count += wvGetMSOFBH (&amsofbh, fd);
319 wvTrace (
320 ("len is %x, type is %x, count %x,fullen %x\n",
321 amsofbh.cbLength, amsofbh.fbt, count, msofbh->cbLength));
322 wvTrace (("type is %x\n ", amsofbh.fbt));
323 switch (amsofbh.fbt)
324 {
325 case msofbtSpContainer:
326 item->no_spcontainer++;
327 item->spcontainer =
328 realloc (item->spcontainer,
329 sizeof (FSPContainer) * item->no_spcontainer);
330 count +=
331 wvGetFSPContainer (&
332 (item->spcontainer[item->no_spcontainer -
333 1]), &amsofbh, fd);
334 break;
335 case msofbtSpgrContainer:
336 item->no_spgrcontainer++;
337 item->spgrcontainer =
338 realloc (item->spgrcontainer,
339 sizeof (SpgrContainer) * item->no_spgrcontainer);
340 count +=
341 wvGetSpgrContainer (&
342 (item->spgrcontainer
343 [item->no_spgrcontainer - 1]), &amsofbh, fd);
344 break;
345 default:
346 count += wvEatmsofbt (&amsofbh, fd);
347 wvError (("Eating type 0x%x\n", amsofbh.fbt));
348 break;
349 }
350 }
351 return (count);
352 }
353
354
355 U32
wvGetFDG(FDG * afdg,wvStream * fd)356 wvGetFDG (FDG * afdg, wvStream * fd)
357 {
358 afdg->csp = read_32ubit (fd);
359 afdg->spidCur = read_32ubit (fd);
360 wvTrace (
361 ("there are %d shapes here, the last is %x\n", afdg->csp,
362 afdg->spidCur));
363 return (8);
364 }
365
366
367 void
wvInitSplitMenuColors(SplitMenuColors * splitmenucolors)368 wvInitSplitMenuColors (SplitMenuColors * splitmenucolors)
369 {
370 splitmenucolors->noofcolors = 0;
371 splitmenucolors->colors = NULL;
372 }
373
374 void
wvReleaseSplitMenuColors(SplitMenuColors * splitmenucolors)375 wvReleaseSplitMenuColors (SplitMenuColors * splitmenucolors)
376 {
377 wvFree (splitmenucolors->colors);
378 }
379
380 U32
wvGetSplitMenuColors(SplitMenuColors * splitmenucolors,MSOFBH * amsofbh,wvStream * fd)381 wvGetSplitMenuColors (SplitMenuColors * splitmenucolors, MSOFBH * amsofbh,
382 wvStream * fd)
383 {
384 U32 i = 0;
385 splitmenucolors->noofcolors = amsofbh->cbLength / 4;
386 if (splitmenucolors->noofcolors)
387 {
388 splitmenucolors->colors =
389 (U32 *) wvMalloc (sizeof (U32) * splitmenucolors->noofcolors);
390 for (i = 0; i < splitmenucolors->noofcolors; i++)
391 splitmenucolors->colors[i] = read_32ubit (fd);
392 }
393 return (i * 4);
394 }
395
396 void
wvReleaseDgg(Dgg * dgg)397 wvReleaseDgg (Dgg * dgg)
398 {
399 wvFree (dgg->fidcl);
400 }
401
402 void
wvInitDgg(Dgg * dgg)403 wvInitDgg (Dgg * dgg)
404 {
405 dgg->fidcl = NULL;
406 }
407
408 U32
wvGetDgg(Dgg * dgg,MSOFBH * amsofbh,wvStream * fd)409 wvGetDgg (Dgg * dgg, MSOFBH * amsofbh, wvStream * fd)
410 {
411 U32 count = 0;
412 U32 no;
413 U32 i;
414 count += wvGetFDGG (&dgg->fdgg, fd);
415 if (dgg->fdgg.cidcl != 0)
416 {
417 wvTrace (("There are %d bytes left\n", amsofbh->cbLength - count));
418 no = (amsofbh->cbLength - count) / 8;
419 if (no != dgg->fdgg.cidcl)
420 {
421 wvWarning
422 ("Must be %d, not %d as specs, test algor gives %d\n", no,
423 dgg->fdgg.cidcl, dgg->fdgg.cspSaved - dgg->fdgg.cidcl);
424 }
425 if (no)
426 {
427 dgg->fidcl = (FIDCL *) wvMalloc (sizeof (FIDCL) * no);
428 for (i = 0; i < no; i++)
429 count += wvGetFIDCL (&(dgg->fidcl[i]), fd);
430 }
431 }
432 return (count);
433 }
434
435 U32
wvGetFIDCL(FIDCL * afidcl,wvStream * fd)436 wvGetFIDCL (FIDCL * afidcl, wvStream * fd)
437 {
438 afidcl->dgid = read_32ubit (fd);
439 afidcl->cspidCur = read_32ubit (fd);
440 wvTrace (("dgid %d cspidCur %d\n", afidcl->dgid, afidcl->cspidCur));
441 return (8);
442 }
443
444
445 U32
wvGetFDGG(FDGG * afdgg,wvStream * fd)446 wvGetFDGG (FDGG * afdgg, wvStream * fd)
447 {
448 afdgg->spidMax = read_32ubit (fd);
449 afdgg->cidcl = read_32ubit (fd);
450 afdgg->cspSaved = read_32ubit (fd);
451 afdgg->cdgSaved = read_32ubit (fd);
452 wvTrace (
453 ("spidMax %d cidcl %d cspSaved %d cdgSaved %d\n", afdgg->spidMax,
454 afdgg->cidcl, afdgg->cspSaved, afdgg->cdgSaved));
455 return (16);
456 }
457
458
459 int
wv0x08(Blip * blip,S32 spid,wvParseStruct * ps)460 wv0x08 (Blip * blip, S32 spid, wvParseStruct * ps)
461 {
462 int ret = 0;
463 U32 i;
464 escherstruct item;
465 FSPContainer *answer = NULL;
466 wvTrace (("spid is %x\n", spid));
467 wvGetEscher (&item, ps->fib.fcDggInfo, ps->fib.lcbDggInfo, ps->tablefd,
468 ps->mainfd);
469
470 for (i = 0; i < item.dgcontainer.no_spgrcontainer; i++)
471 {
472 answer = wvFindSPID (&(item.dgcontainer.spgrcontainer[i]), spid);
473 if (answer)
474 break;
475 }
476
477 i = 0;
478 if (answer == NULL)
479 wvError (("Damn found nothing\n"));
480 else if (answer->fopte)
481 {
482 while (answer->fopte[i].pid != 0)
483 {
484 if (answer->fopte[i].pid == 260)
485 {
486 wvTrace (
487 ("has a blip reference of %d\n",
488 answer->fopte[i].op));
489 wvTrace (
490 ("no blips is %d\n",
491 item.dggcontainer.bstorecontainer.no_fbse));
492 wvTrace (
493 ("type is %d (number is %d\n",
494 item.dggcontainer.bstorecontainer.blip[item.
495 dggcontainer.
496 bstorecontainer.
497 no_fbse -
498 1].type,
499 item.dggcontainer.bstorecontainer.no_fbse));
500 if (answer->fopte[i].op <=
501 item.dggcontainer.bstorecontainer.no_fbse)
502 {
503 wvTrace (("Copied Blip\n"));
504 wvCopyBlip (blip,
505 &(item.dggcontainer.bstorecontainer.
506 blip[answer->fopte[i].op - 1]));
507 wvTrace (("type is %d\n", blip->type));
508 ret = 1;
509 break;
510 }
511 }
512 i++;
513 }
514 }
515 wvTrace (("spid is %x\n", spid));
516 wvReleaseEscher (&item);
517 return (ret);
518 }
519
520 int
wv0x01(Blip * blip,wvStream * fd,U32 len)521 wv0x01 (Blip * blip, wvStream * fd, U32 len)
522 {
523 MSOFBH amsofbh;
524 FSPContainer item;
525 U32 count = 0;
526 /* char test[3];*/
527 int ret = 0;
528
529
530 if (fd == NULL)
531 return (0);
532
533 /*lvm007@aha.ru fix hack as outdated look picf*/
534 /*
535 temp hack to test older included bmps in word 6 and 7,
536 should be wrapped in a modern escher strucure before getting
537 to here, and then handled as normal
538 */
539 /*test[2] = '\0';
540 test[0] = read_8ubit (fd);
541 test[1] = read_8ubit (fd);
542 wvStream_rewind (fd);
543 if (!(strcmp (test, "BM")))
544 {
545 blip->blip.bitmap.m_pvBits = fd;
546 blip->type = msoblipDIB;
547 return (1);
548 }
549 */
550 while (count < len)
551 {
552 wvTrace (("count is %x,len is %x\n", count, len));
553 count += wvGetMSOFBH (&amsofbh, fd);
554 wvTrace (("type is %x\n ", amsofbh.fbt));
555 switch (amsofbh.fbt)
556 {
557 case msofbtSpContainer:
558 wvTrace (("Container at %x\n", wvStream_tell (fd)));
559 count += wvGetFSPContainer (&item, &amsofbh, fd);
560 wvReleaseFSPContainer (&item);
561 break;
562 case msofbtBSE:
563 wvTrace (("Blip at %x\n", wvStream_tell (fd)));
564 count += wvGetBlip (blip, fd, NULL);
565 ret = 1;
566 break;
567 default:
568 wvError (("Not a shape container\n"));
569 return (0);
570 break;
571 }
572 }
573 return (ret);
574 }
575
576 U32
wvGetFSP(FSP * fsp,wvStream * fd)577 wvGetFSP (FSP * fsp, wvStream * fd)
578 {
579 fsp->spid = read_32ubit (fd);
580 wvTrace (("SPID is %x\n", fsp->spid));
581 fsp->grfPersistent = read_32ubit (fd);
582 return (8);
583 }
584
585
586 U32
wvGetFSPGR(FSPGR * item,wvStream * fd)587 wvGetFSPGR (FSPGR * item, wvStream * fd)
588 {
589 /* It is supposed to be a RECT, but its only 4 long so... */
590 item->rcgBounds.left = read_32ubit (fd);
591 item->rcgBounds.right = read_32ubit (fd);
592 item->rcgBounds.top = read_32ubit (fd);
593 item->rcgBounds.bottom = read_32ubit (fd);
594 return (16);
595 }
596
597 void
wvReleaseFSPContainer(FSPContainer * item)598 wvReleaseFSPContainer (FSPContainer * item)
599 {
600 wvReleaseClientTextbox (&item->clienttextbox);
601 wvReleaseClientData (&item->clientdata);
602 wvReleaseFOPTEArray (&item->fopte);
603 }
604
605 void
wvInitFSPContainer(FSPContainer * item)606 wvInitFSPContainer (FSPContainer * item)
607 {
608 wvInitFOPTEArray (&item->fopte);
609 wvInitClientData (&item->clientdata);
610 wvInitClientTextbox (&item->clienttextbox);
611 }
612
613 U32
wvGetFSPContainer(FSPContainer * item,MSOFBH * msofbh,wvStream * fd)614 wvGetFSPContainer (FSPContainer * item, MSOFBH * msofbh, wvStream * fd)
615 {
616 MSOFBH amsofbh;
617 U32 count = 0;
618 wvInitFSPContainer (item);
619 while (count < msofbh->cbLength)
620 {
621 count += wvGetMSOFBH (&amsofbh, fd);
622 wvTrace (
623 ("len is %x, type is %x, count %x,fullen %x\n",
624 amsofbh.cbLength, amsofbh.fbt, count, msofbh->cbLength));
625 wvTrace (("type is %x\n ", amsofbh.fbt));
626 switch (amsofbh.fbt)
627 {
628 case msofbtSpgr:
629 count += wvGetFSPGR (&item->fspgr, fd);
630 break;
631
632 case msofbtSp:
633 wvTrace (("Getting an fsp\n"));
634 count += wvGetFSP (&item->fsp, fd);
635 break;
636
637 case msofbtOPT:
638 count += wvGetFOPTEArray (&item->fopte, &amsofbh, fd);
639 break;
640
641 case msofbtAnchor:
642 case msofbtChildAnchor:
643 case msofbtClientAnchor:
644 count += wvGetFAnchor (&item->fanchor, fd);
645 break;
646
647 case msofbtClientData:
648 count += wvGetClientData (&item->clientdata, &amsofbh, fd);
649 break;
650 case msofbtClientTextbox:
651 count +=
652 wvGetClientTextbox (&item->clienttextbox, &amsofbh, fd);
653 break;
654
655 case msofbtTextbox:
656 wvError (("unimp\n"));
657 break;
658 case msofbtOleObject:
659 wvError (("unimp\n"));
660 break;
661
662 case msofbtDeletedPspl:
663 wvError (("unimp\n"));
664 break;
665
666 default:
667 count += wvEatmsofbt (&amsofbh, fd);
668 wvError (("Eating type 0x%x\n", amsofbh.fbt));
669 break;
670 }
671 }
672 return (count);
673 }
674
675 void
wvInitClientData(ClientData * item)676 wvInitClientData (ClientData * item)
677 {
678 item->data = NULL;
679 }
680
681 void
wvReleaseClientData(ClientData * item)682 wvReleaseClientData (ClientData * item)
683 {
684 wvFree (item->data);
685 }
686
687 U32
wvGetClientData(ClientData * item,MSOFBH * msofbh,wvStream * fd)688 wvGetClientData (ClientData * item, MSOFBH * msofbh, wvStream * fd)
689 {
690 U32 i;
691 if (msofbh->cbLength)
692 {
693 item->data = (U8 *) wvMalloc (msofbh->cbLength);
694 for (i = 0; i < msofbh->cbLength; i++)
695 item->data[i] = read_8ubit (fd);
696 }
697 else
698 item->data = NULL;
699 return (msofbh->cbLength);
700 }
701
702 U32
wvGetMSOFBH(MSOFBH * amsofbh,wvStream * fd)703 wvGetMSOFBH (MSOFBH * amsofbh, wvStream * fd)
704 {
705 U16 dtemp = 0;
706 dtemp = read_16ubit (fd);
707
708 #ifdef PURIFY
709 amsofbh->ver = 0;
710 amsofbh->inst = 0;
711 #endif
712
713 amsofbh->ver = dtemp & 0x000F;
714 amsofbh->inst = dtemp >> 4;
715 amsofbh->fbt = read_16ubit (fd);
716 amsofbh->cbLength = read_32ubit (fd);
717 return (8);
718 }
719
720
721 U32
wvEatmsofbt(MSOFBH * amsofbh,wvStream * fd)722 wvEatmsofbt (MSOFBH * amsofbh, wvStream * fd)
723 {
724 wvStream_offset(fd, amsofbh->cbLength);
725 return amsofbh->cbLength;
726 }
727
728 void
wvInitClientTextbox(ClientTextbox * item)729 wvInitClientTextbox (ClientTextbox * item)
730 {
731 item->textid = NULL;
732 }
733
734 void
wvReleaseClientTextbox(ClientTextbox * item)735 wvReleaseClientTextbox (ClientTextbox * item)
736 {
737 wvFree (item->textid);
738 }
739
740 U32
wvGetClientTextbox(ClientTextbox * item,MSOFBH * amsofbh,wvStream * fd)741 wvGetClientTextbox (ClientTextbox * item, MSOFBH * amsofbh, wvStream * fd)
742 {
743 item->textid = (U32 *) wvMalloc (amsofbh->cbLength);
744 *item->textid = read_32ubit (fd);
745 return (amsofbh->cbLength);
746 }
747