1 /******************************************************************
2 Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts,
6 Permission to use, copy, modify, and distribute this software and its
7 documentation for any purpose and without fee is hereby granted,
8 provided that the above copyright notice appear in all copies and that
9 both that copyright notice and this permission notice appear in
10 supporting documentation, and that the names of Digital or MIT not be
11 used in advertising or publicity pertaining to distribution of the
12 software without specific, written prior permission.
14 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
22 Author: Hiroyuki Miyamoto Digital Equipment Corporation
25 This version tidied and debugged by Steve Underwood May 1999
27 ******************************************************************/
29 #include <X11/Xlibint.h>
33 /* Convenient macro */
35 #define _UNIT(n) ((int)(n) & 0xFF)
36 #define _NUMBER(n) (((int)(n) >> 8) & 0xFF)
38 /* For byte swapping */
40 #define Swap16(p, n) ((p)->byte_swap ? \
41 (((n) << 8 & 0xFF00) | \
44 #define Swap32(p, n) ((p)->byte_swap ? \
45 (((n) << 24 & 0xFF000000) | \
46 ((n) << 8 & 0xFF0000) | \
47 ((n) >> 8 & 0xFF00) | \
50 #define Swap64(p, n) ((p)->byte_swap ? \
51 (((n) << 56 & 0xFF00000000000000) | \
52 ((n) << 40 & 0xFF000000000000) | \
53 ((n) << 24 & 0xFF0000000000) | \
54 ((n) << 8 & 0xFF00000000) | \
55 ((n) >> 8 & 0xFF000000) | \
56 ((n) >> 24 & 0xFF0000) | \
57 ((n) >> 40 & 0xFF00) | \
63 typedef struct _Iter *Iter;
65 typedef struct _FrameInst *FrameInst;
69 int num; /* For BARRAY */
70 FrameInst fi; /* For POINTER */
71 Iter iter; /* For ITER */
72 } ExtraDataRec, *ExtraData;
81 typedef struct _ChainMgr
85 } ChainMgrRec, *ChainMgr;
87 typedef struct _ChainIter
90 } ChainIterRec, *ChainIter;
92 typedef struct _FrameIter
98 struct _FrameIter* next;
99 } FrameIterRec, *FrameIter;
101 typedef struct _FrameInst
108 typedef void (*IterStartWatchProc) (Iter it, void *client_data);
114 Bool allow_expansion;
117 IterStartWatchProc start_watch_proc;
122 typedef struct _FrameMgr
135 int num; /* For BARRAY and PAD */
137 { /* For COUNTER_* */
141 } XimFrameTypeInfoRec, *XimFrameTypeInfo;
145 #define NO_VALID_FIELD -2
147 static FrameInst FrameInstInit(XimFrame frame);
148 static void FrameInstFree(FrameInst fi);
149 static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info);
150 static XimFrameType FrameInstPeekNextType(FrameInst fi, XimFrameTypeInfo info);
151 static FmStatus FrameInstSetSize(FrameInst fi, int num);
152 static FmStatus FrameInstSetIterCount(FrameInst fi, int num);
153 static int FrameInstGetTotalSize(FrameInst fi);
154 static void FrameInstReset(FrameInst fi);
156 static Iter IterInit(XimFrame frame, int count);
157 static void IterFree(Iter it);
158 static int FrameInstGetSize(FrameInst fi);
159 static int IterGetSize(Iter it);
160 static XimFrameType IterGetNextType(Iter it, XimFrameTypeInfo info);
161 static XimFrameType IterPeekNextType(Iter it, XimFrameTypeInfo info);
162 static FmStatus IterSetSize(Iter it, int num);
163 static FmStatus IterSetIterCount(Iter it, int num);
164 static int IterGetTotalSize(Iter it);
165 static void IterReset(Iter it);
166 static Bool IterIsLoopEnd(Iter it, Bool* myself);
167 static void IterSetStartWatch(Iter it, IterStartWatchProc proc, void* client_data);
168 static void _IterStartWatch(Iter it, void* client_data);
170 static ExtraData ChainMgrGetExtraData(ChainMgr cm, int frame_no);
171 static ExtraData ChainMgrSetData(ChainMgr cm, int frame_no,
173 static Bool ChainIterGetNext(ChainIter ci, int* frame_no, ExtraData d);
174 static int _FrameInstIncrement(XimFrame frame, int count);
175 static int _FrameInstDecrement(XimFrame frame, int count);
176 static int _FrameInstGetItemSize(FrameInst fi, int cur_no);
177 static Bool FrameInstIsIterLoopEnd(FrameInst fi);
179 static FrameIter _FrameMgrAppendIter(FrameMgr fm, Iter it, int end);
180 static FrameIter _FrameIterCounterIncr(FrameIter fitr, int i);
181 static void _FrameMgrRemoveIter(FrameMgr fm, FrameIter it);
182 static Bool _FrameMgrIsIterLoopEnd(FrameMgr fm);
183 static Bool _FrameMgrProcessPadding(FrameMgr fm, FmStatus* status);
185 #define IterGetIterCount(it) ((it)->allow_expansion ? \
186 NO_VALUE : (it)->max_count)
188 #define IterFixIteration(it) ((it)->allow_expansion = False)
190 #define IterSetStarter(it) ((it)->start_counter = True)
192 #define ChainMgrInit(cm) (cm)->top = (cm)->tail = NULL
193 #define ChainMgrFree(cm) \
196 Chain cur = (cm)->top; \
206 #define ChainIterInit(ci, cm) \
208 (ci)->cur = (cm)->top; \
211 /* ChainIterFree has nothing to do. */
212 #define ChainIterFree(ci)
214 #define FrameInstIsEnd(fi) ((fi)->template[(fi)->cur_no].type == EOL)
216 FrameMgr FrameMgrInit (XimFrame frame, char* area, Bool byte_swap)
220 fm = (FrameMgr) Xmalloc (sizeof (FrameMgrRec));
223 fm->fi = FrameInstInit (frame);
224 fm->area = (char *) area;
226 fm->byte_swap = byte_swap;
227 fm->total_size = NO_VALUE;
233 void FrameMgrInitWithData (FrameMgr fm,
239 fm->fi = FrameInstInit (frame);
240 fm->area = (char *) area;
242 fm->byte_swap = byte_swap;
243 fm->total_size = NO_VALUE;
246 void FrameMgrFree (FrameMgr fm)
261 FrameInstFree (fm->fi);
265 FmStatus FrameMgrSetBuffer (FrameMgr fm, void* area)
269 fm->area = (char *) area;
273 FmStatus _FrameMgrPutToken (FrameMgr fm, void *data, int data_size)
276 XimFrameTypeInfoRec info;
278 if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
282 type = FrameInstGetNextType(fm->fi, &info);
284 if (type & COUNTER_MASK)
286 unsigned long input_length;
288 if (info.counter.is_byte_len)
290 if ((input_length = IterGetTotalSize (info.counter.iter))
299 if ((input_length = IterGetIterCount (info.counter.iter))
310 *(CARD8 *) (fm->area + fm->idx) = input_length;
315 *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, input_length);
320 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, input_length);
324 #if defined(_NEED64BIT)
326 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, input_length);
334 _FrameMgrPutToken(fm, data, data_size);
342 if (data_size == sizeof (unsigned char))
344 unsigned long num = *(unsigned char *) data;
345 *(CARD8 *) (fm->area + fm->idx) = num;
347 else if (data_size == sizeof (unsigned short))
349 unsigned long num = *(unsigned short *) data;
350 *(CARD8 *) (fm->area + fm->idx) = num;
352 else if (data_size == sizeof (unsigned int))
354 unsigned long num = *(unsigned int *) data;
355 *(CARD8 *) (fm->area + fm->idx) = num;
357 else if (data_size == sizeof (unsigned long))
359 unsigned long num = *(unsigned long *) data;
360 *(CARD8 *) (fm->area + fm->idx) = num;
364 ; /* Should never be reached */
371 if (data_size == sizeof (unsigned char))
373 unsigned long num = *(unsigned char *) data;
374 *(CARD16*)(fm->area + fm->idx) = Swap16 (fm, num);
376 else if (data_size == sizeof (unsigned short))
378 unsigned long num = *(unsigned short *) data;
379 *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num);
381 else if (data_size == sizeof (unsigned int))
383 unsigned long num = *(unsigned int *) data;
384 *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num);
386 else if (data_size == sizeof (unsigned long))
388 unsigned long num = *(unsigned long *) data;
389 *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num);
393 ; /* Should never reached */
400 if (data_size == sizeof (unsigned char))
402 unsigned long num = *(unsigned char *) data;
403 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num);
405 else if (data_size == sizeof (unsigned short))
407 unsigned long num = *(unsigned short *) data;
408 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num);
410 else if (data_size == sizeof (unsigned int))
412 unsigned long num = *(unsigned int *) data;
413 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num);
415 else if (data_size == sizeof (unsigned long))
417 unsigned long num = *(unsigned long *) data;
418 *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num);
422 ; /* Should never reached */
428 #if defined(_NEED64BIT)
430 if (data_size == sizeof (unsigned char))
432 unsigned long num = *(unsigned char *) data;
433 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num);
435 else if (data_size == sizeof (unsigned short))
437 unsigned long num = *(unsigned short *) data;
438 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num);
440 else if (data_size == sizeof (unsigned int))
442 unsigned long num = *(unsigned int *) data;
443 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num);
445 else if (data_size == sizeof (unsigned long))
447 unsigned long num = *(unsigned long *) data;
448 *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num);
452 ; /* Should never reached */
460 if (info.num == NO_VALUE)
461 return FmInvalidCall;
465 bcopy (*(char **) data, fm->area + fm->idx, info.num);
472 if (info.num == NO_VALUE)
473 return FmInvalidCall;
476 return _FrameMgrPutToken(fm, data, data_size);
479 return FmInvalidCall;
487 return (FmStatus) NULL; /* Should never be reached */
490 FmStatus _FrameMgrGetToken (FrameMgr fm , void* data, int data_size)
493 static XimFrameTypeInfoRec info; /* memory */
496 if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
500 type = FrameInstGetNextType(fm->fi, &info);
502 if (type & COUNTER_MASK)
505 FrameIter client_data;
507 type &= ~COUNTER_MASK;
511 end = *(CARD8 *) (fm->area + fm->idx);
515 end = Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
519 end = Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
522 #if defined(_NEED64BIT)
524 end = Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
532 if ((client_data = _FrameMgrAppendIter (fm, info.counter.iter, end)))
534 IterSetStarter (info.counter.iter);
535 IterSetStartWatch (info.counter.iter,
537 (void *) client_data);
543 type &= ~COUNTER_MASK;
547 if (data_size == sizeof (unsigned char))
549 *(unsigned char*) data = *(CARD8 *) (fm->area + fm->idx);
551 else if (data_size == sizeof (unsigned short))
553 *(unsigned short *) data = *(CARD8 *) (fm->area + fm->idx);
555 else if (data_size == sizeof (unsigned int))
557 *(unsigned int *) data = *(CARD8 *) (fm->area + fm->idx);
559 else if (data_size == sizeof (unsigned long))
561 *(unsigned long *) data = *(CARD8 *) (fm->area + fm->idx);
565 ; /* Should never reached */
569 if ((fitr = _FrameIterCounterIncr (fm->iters, 1/*BIT8*/)))
570 _FrameMgrRemoveIter (fm, fitr);
575 if (data_size == sizeof (unsigned char))
577 *(unsigned char *) data =
578 Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
580 else if (data_size == sizeof (unsigned short))
582 *(unsigned short *) data =
583 Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
585 else if (data_size == sizeof (unsigned int))
587 *(unsigned int *) data =
588 Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
590 else if (data_size == sizeof (unsigned long))
592 *(unsigned long *) data =
593 Swap16 (fm, *(CARD16 *) (fm->area + fm->idx));
597 ; /* Should never reached */
601 if ((fitr = _FrameIterCounterIncr (fm->iters, 2/*BIT16*/)))
602 _FrameMgrRemoveIter(fm, fitr);
607 if (data_size == sizeof (unsigned char))
609 *(unsigned char *) data =
610 Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
612 else if (data_size == sizeof (unsigned short))
614 *(unsigned short *) data =
615 Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
617 else if (data_size == sizeof (unsigned int))
619 *(unsigned int *) data =
620 Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
622 else if (data_size == sizeof (unsigned long))
624 *(unsigned long *) data =
625 Swap32 (fm, *(CARD32 *) (fm->area + fm->idx));
629 ; /* Should never reached */
633 if ((fitr = _FrameIterCounterIncr (fm->iters, 4/*BIT32*/)))
634 _FrameMgrRemoveIter (fm, fitr);
638 #if defined(_NEED64BIT)
640 if (data_size == sizeof (unsigned char))
642 *(unsigned char *) data =
643 Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
645 else if (data_size == sizeof (unsigned short))
647 *(unsigned short *) data =
648 Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
650 else if (data_size == sizeof (unsigned int))
652 *(unsigned int *) data =
653 Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
655 else if (data_size == sizeof (unsigned long))
657 *(unsigned long *) data =
658 Swap64 (fm, *(CARD64 *) (fm->area + fm->idx));
662 ; /* Should never reached */
666 if ((fitr = _FrameIterCounterIncr (fm->iters, 8/*BIT64*/)))
667 _FrameMgrRemoveIter (fm, fitr);
673 if (info.num == NO_VALUE)
674 return FmInvalidCall;
678 *(char **) data = fm->area + fm->idx;
681 if ((fitr = _FrameIterCounterIncr (fm->iters, info.num)))
682 _FrameMgrRemoveIter (fm, fitr);
687 *(char **) data = NULL;
693 if (info.num == NO_VALUE)
694 return FmInvalidCall;
697 if ((fitr = _FrameIterCounterIncr (fm->iters, info.num)))
698 _FrameMgrRemoveIter (fm, fitr);
700 return _FrameMgrGetToken (fm, data, data_size);
703 return FmInvalidCall; /* if comes here, it's a bug! */
711 return (FmStatus) NULL; /* Should never be reached */
714 FmStatus FrameMgrSetSize (FrameMgr fm, int barray_size)
716 if (FrameInstSetSize (fm->fi, barray_size) == FmSuccess)
722 FmStatus FrameMgrSetIterCount (FrameMgr fm, int count)
724 if (FrameInstSetIterCount (fm->fi, count) == FmSuccess)
730 FmStatus FrameMgrSetTotalSize (FrameMgr fm, int total_size)
732 fm->total_size = total_size;
736 int FrameMgrGetTotalSize (FrameMgr fm)
738 return FrameInstGetTotalSize (fm->fi);
741 int FrameMgrGetSize (FrameMgr fm)
743 register int ret_size;
745 ret_size = FrameInstGetSize (fm->fi);
746 if (ret_size == NO_VALID_FIELD)
752 FmStatus FrameMgrSkipToken (FrameMgr fm, int skip_count)
755 XimFrameTypeInfoRec info;
758 if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size)
761 for (i = 0; i < skip_count; i++)
763 type = FrameInstGetNextType (fm->fi, &info);
764 type &= ~COUNTER_MASK;
785 if (info.num == NO_VALUE)
786 return FmInvalidCall;
792 if (info.num == NO_VALUE)
793 return FmInvalidCall;
796 return FrameMgrSkipToken (fm, skip_count);
799 return FmInvalidCall;
812 void FrameMgrReset (FrameMgr fm)
815 FrameInstReset (fm->fi);
818 Bool FrameMgrIsIterLoopEnd (FrameMgr fm, FmStatus* status)
822 if (_FrameMgrIsIterLoopEnd (fm))
826 while (_FrameMgrProcessPadding (fm, status));
832 /* Internal routines */
834 static Bool _FrameMgrIsIterLoopEnd (FrameMgr fm)
836 return FrameInstIsIterLoopEnd (fm->fi);
839 static Bool _FrameMgrProcessPadding (FrameMgr fm, FmStatus* status)
841 XimFrameTypeInfoRec info;
842 XimFrameType next_type = FrameInstPeekNextType (fm->fi, &info);
845 if (next_type == PADDING)
847 if (info.num == NO_VALUE)
849 *status = FmInvalidCall;
853 next_type = FrameInstGetNextType (fm->fi, &info);
855 if ((fitr = _FrameIterCounterIncr (fm->iters, info.num)))
856 _FrameMgrRemoveIter (fm, fitr);
866 static FrameInst FrameInstInit (XimFrame frame)
870 fi = (FrameInst) Xmalloc (sizeof (FrameInstRec));
872 fi->template = frame;
874 ChainMgrInit (&fi->cm);
878 static void FrameInstFree (FrameInst fi)
884 ChainIterInit (&ci, &fi->cm);
886 while (ChainIterGetNext (&ci, &frame_no, &d))
888 register XimFrameType type;
889 type = fi->template[frame_no].type;
896 else if (type == POINTER)
899 FrameInstFree (d.fi);
906 ChainMgrFree (&fi->cm);
910 static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
912 XimFrameType ret_type;
914 ret_type = fi->template[fi->cur_no].type;
923 fi->cur_no = _FrameInstIncrement(fi->template, fi->cur_no);
932 register int offset, iter_idx;
934 info->counter.is_byte_len =
935 (((long) fi->template[fi->cur_no].data & 0xFF)) == FmCounterByte;
936 offset = ((long) fi->template[fi->cur_no].data) >> 8;
937 iter_idx = fi->cur_no + offset;
938 if (fi->template[iter_idx].type == ITER)
943 if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL)
945 dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE);
946 d = ChainMgrSetData (&fi->cm, iter_idx, dr);
949 info->counter.iter = d->iter;
953 /* Should never reach here */
958 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
966 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
967 info->num = NO_VALUE;
973 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
984 unit = _UNIT ((long) fi->template[fi->cur_no].data);
985 number = _NUMBER ((long) fi->template[fi->cur_no].data);
991 i = _FrameInstDecrement (fi->template, i);
992 size += _FrameInstGetItemSize (fi, i);
996 info->num = (unit - (size%unit))%unit;
999 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
1006 XimFrameType sub_type;
1009 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1011 dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE);
1012 d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
1015 sub_type = IterGetNextType (d->iter, info);
1016 if (sub_type == EOL)
1018 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
1019 ret_type = FrameInstGetNextType (fi, info);
1023 ret_type = sub_type;
1033 XimFrameType sub_type;
1035 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1037 dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data);
1038 d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
1041 sub_type = FrameInstGetNextType (d->fi, info);
1042 if (sub_type == EOL)
1044 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
1045 ret_type = FrameInstGetNextType (fi, info);
1049 ret_type = sub_type;
1061 static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info)
1063 XimFrameType ret_type;
1065 ret_type = fi->template[fi->cur_no].type;
1082 register int offset;
1083 register int iter_idx;
1085 info->counter.is_byte_len =
1086 (((long) fi->template[fi->cur_no].data) & 0xFF) == FmCounterByte;
1087 offset = ((long)fi->template[fi->cur_no].data) >> 8;
1088 iter_idx = fi->cur_no + offset;
1089 if (fi->template[iter_idx].type == ITER)
1094 if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL)
1096 dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE);
1097 d = ChainMgrSetData (&fi->cm, iter_idx, dr);
1100 info->counter.iter = d->iter;
1104 /* Should not be reached here */
1116 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1117 info->num = NO_VALUE;
1129 register int number;
1133 unit = _UNIT ((long) fi->template[fi->cur_no].data);
1134 number = _NUMBER ((long) fi->template[fi->cur_no].data);
1140 i = _FrameInstDecrement (fi->template, i);
1141 size += _FrameInstGetItemSize (fi, i);
1145 info->num = (unit - (size%unit))%unit;
1154 XimFrameType sub_type;
1156 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1158 dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE);
1159 d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
1162 sub_type = IterPeekNextType (d->iter, info);
1163 if (sub_type == EOL)
1164 ret_type = FrameInstPeekNextType (fi, info);
1166 ret_type = sub_type;
1175 XimFrameType sub_type;
1177 if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
1179 dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data);
1180 d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
1183 sub_type = FrameInstPeekNextType (d->fi, info);
1184 if (sub_type == EOL)
1185 ret_type = FrameInstPeekNextType (fi, info);
1187 ret_type = sub_type;
1198 static Bool FrameInstIsIterLoopEnd (FrameInst fi)
1202 if (fi->template[fi->cur_no].type == ITER)
1204 ExtraData d = ChainMgrGetExtraData (&fi->cm, fi->cur_no);
1209 ret = IterIsLoopEnd (d->iter, &yourself);
1210 if (ret && yourself)
1211 fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
1220 static FrameIter _FrameMgrAppendIter (FrameMgr fm, Iter it, int end)
1222 FrameIter p = fm->iters;
1224 while (p && p->next)
1231 p = (FrameIter) Xmalloc (sizeof (FrameIterRec));
1235 p->next = (FrameIter) Xmalloc (sizeof (FrameIterRec));
1242 p->counting = False;
1251 static void _FrameMgrRemoveIter (FrameMgr fm, FrameIter it)
1263 prev->next = p->next;
1265 fm->iters = p->next;
1277 static FrameIter _FrameIterCounterIncr (FrameIter fitr, int i)
1286 if (p->counter >= p->end)
1288 IterFixIteration (p->iter);
1300 static void _IterStartWatch (Iter it, void *client_data)
1302 FrameIter p = (FrameIter) client_data;
1306 static FmStatus FrameInstSetSize (FrameInst fi, int num)
1314 while ((type = fi->template[i].type) != EOL)
1319 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1322 d = ChainMgrSetData (&fi->cm, i, dr);
1325 if (d->num == NO_VALUE)
1333 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1335 dr.iter = IterInit (&fi->template[i + 1], NO_VALUE);
1336 d = ChainMgrSetData (&fi->cm, i, dr);
1339 if (IterSetSize (d->iter, num) == FmSuccess)
1345 if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL)
1347 dr.fi = FrameInstInit(fi->template[i + 1].data);
1348 d = ChainMgrSetData(&fi->cm, i, dr);
1351 if (FrameInstSetSize(d->fi, num) == FmSuccess)
1359 i = _FrameInstIncrement(fi->template, i);
1362 return FmNoMoreData;
1365 static int FrameInstGetSize (FrameInst fi)
1374 while ((type = fi->template[i].type) != EOL)
1379 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1385 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1387 dr.iter = IterInit (&fi->template[i + 1], NO_VALUE);
1388 d = ChainMgrSetData (&fi->cm, i, dr);
1391 ret_size = IterGetSize(d->iter);
1392 if (ret_size != NO_VALID_FIELD)
1398 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1400 dr.fi = FrameInstInit (fi->template[i + 1].data);
1401 d = ChainMgrSetData (&fi->cm, i, dr);
1404 ret_size = FrameInstGetSize (d->fi);
1405 if (ret_size != NO_VALID_FIELD)
1413 i = _FrameInstIncrement (fi->template, i);
1416 return NO_VALID_FIELD;
1419 static FmStatus FrameInstSetIterCount (FrameInst fi, int num)
1427 while ((type = fi->template[i].type) != EOL)
1432 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1434 dr.iter = IterInit (&fi->template[i + 1], num);
1435 (void)ChainMgrSetData (&fi->cm, i, dr);
1439 if (IterSetIterCount (d->iter, num) == FmSuccess)
1445 if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
1447 dr.fi = FrameInstInit (fi->template[i + 1].data);
1448 d = ChainMgrSetData (&fi->cm, i, dr);
1451 if (FrameInstSetIterCount (d->fi, num) == FmSuccess)
1460 i = _FrameInstIncrement (fi->template, i);
1463 return FmNoMoreData;
1466 static int FrameInstGetTotalSize (FrameInst fi)
1474 while (fi->template[i].type != EOL)
1476 size += _FrameInstGetItemSize (fi, i);
1477 i = _FrameInstIncrement (fi->template, i);
1483 static void FrameInstReset (FrameInst fi)
1489 ChainIterInit (&ci, &fi->cm);
1491 while (ChainIterGetNext (&ci, &frame_no, &d))
1493 register XimFrameType type;
1494 type = fi->template[frame_no].type;
1501 else if (type == POINTER)
1504 FrameInstReset (d.fi);
1510 ChainIterFree (&ci);
1515 static Iter IterInit (XimFrame frame, int count)
1518 register XimFrameType type;
1520 it = (Iter) Xmalloc (sizeof (IterRec));
1521 it->template = frame;
1522 it->max_count = (count == NO_VALUE) ? 0 : count;
1523 it->allow_expansion = (count == NO_VALUE);
1525 it->start_watch_proc = NULL;
1526 it->client_data = NULL;
1527 it->start_counter = False;
1530 if (type & COUNTER_MASK)
1532 /* COUNTER_XXX cannot be an item of a ITER */
1550 ChainMgrInit (&it->cm);
1555 return NULL; /* This should never occur */
1561 static void IterFree (Iter it)
1563 switch (it->template->type)
1566 ChainMgrFree (&it->cm);
1575 ChainIterInit (&ci, &it->cm);
1576 while (ChainIterGetNext (&ci, &count, &d))
1579 ChainIterFree (&ci);
1580 ChainMgrFree (&it->cm);
1590 ChainIterInit (&ci, &it->cm);
1591 while (ChainIterGetNext (&ci, &count, &dr))
1592 FrameInstFree (dr.fi);
1594 ChainIterFree (&ci);
1595 ChainMgrFree (&it->cm);
1606 static Bool IterIsLoopEnd (Iter it, Bool *myself)
1611 if (!it->allow_expansion && (it->cur_no == it->max_count))
1618 if (it->template->type == POINTER)
1620 ExtraData d = ChainMgrGetExtraData (&it->cm, it->cur_no);
1623 if (FrameInstIsIterLoopEnd (d->fi))
1629 if (FrameInstIsEnd (d->fi))
1632 if (!it->allow_expansion && it->cur_no == it->max_count)
1645 else if (it->template->type == ITER)
1647 ExtraData d = ChainMgrGetExtraData (&it->cm, it->cur_no);
1652 if (IterIsLoopEnd (d->iter, &yourself))
1663 static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info)
1665 XimFrameType type = it->template->type;
1667 if (it->start_counter)
1669 (*it->start_watch_proc) (it, it->client_data);
1670 it->start_counter = False;
1673 if (it->cur_no >= it->max_count)
1675 if (it->allow_expansion)
1676 it->max_count = it->cur_no + 1;
1697 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1698 info->num = NO_VALUE;
1709 XimFrameType ret_type;
1713 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1715 dr.iter = IterInit (it->template + 1, NO_VALUE);
1716 d = ChainMgrSetData (&it->cm, it->cur_no, dr);
1720 ret_type = IterGetNextType (d->iter, info);
1721 if (ret_type == EOL)
1724 ret_type = IterGetNextType (it, info);
1732 XimFrameType ret_type;
1736 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1738 dr.fi = FrameInstInit (it->template[1].data);
1739 d = ChainMgrSetData (&it->cm, it->cur_no, dr);
1743 ret_type = FrameInstGetNextType (d->fi, info);
1744 if (ret_type == EOL)
1747 ret_type = IterGetNextType (it, info);
1754 return (XimFrameType) NULL;
1757 return (XimFrameType) NULL; /* This should never occur */
1760 static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info)
1762 XimFrameType type = it->template->type;
1764 if (!it->allow_expansion && it->cur_no >= it->max_count)
1781 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1782 info->num = NO_VALUE;
1792 XimFrameType ret_type;
1796 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1798 dr.iter = IterInit (it->template + 1, NO_VALUE);
1799 d = ChainMgrSetData (&it->cm, it->cur_no, dr);
1803 ret_type = IterPeekNextType (d->iter, info);
1804 if (ret_type == EOL)
1805 ret_type = IterPeekNextType (it, info);
1812 XimFrameType ret_type;
1816 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1818 dr.fi = FrameInstInit (it->template[1].data);
1819 d = ChainMgrSetData (&it->cm, it->cur_no, dr);
1823 ret_type = FrameInstPeekNextType (d->fi, info);
1824 if (ret_type == EOL)
1825 ret_type = IterPeekNextType (it, info);
1834 /* Reaching here is a bug! */
1835 return (XimFrameType) NULL;
1838 static FmStatus IterSetSize (Iter it, int num)
1843 if (!it->allow_expansion && it->max_count == 0)
1844 return FmNoMoreData;
1847 type = it->template->type;
1855 for (i = 0; i < it->max_count; i++)
1857 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
1860 d = ChainMgrSetData (&it->cm, i, dr);
1863 if (d->num == NO_VALUE)
1871 if (it->allow_expansion)
1876 ChainMgrSetData (&it->cm, it->max_count, dr);
1883 return FmNoMoreData;
1890 for (i = 0; i < it->max_count; i++)
1892 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
1894 dr.iter = IterInit (it->template + 1, NO_VALUE);
1895 d = ChainMgrSetData (&it->cm, i, dr);
1898 if (IterSetSize (d->iter, num) == FmSuccess)
1903 if (it->allow_expansion)
1907 dr.iter = IterInit (it->template + 1, NO_VALUE);
1908 ChainMgrSetData (&it->cm, it->max_count, dr);
1911 if (IterSetSize(dr.iter, num) == FmSuccess)
1917 return FmNoMoreData;
1924 for (i = 0; i < it->max_count; i++)
1926 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
1928 dr.fi = FrameInstInit (it->template[1].data);
1929 d = ChainMgrSetData (&it->cm, i, dr);
1932 if (FrameInstSetSize (d->fi, num) == FmSuccess)
1937 if (it->allow_expansion)
1941 dr.fi = FrameInstInit (it->template[1].data);
1942 ChainMgrSetData (&it->cm, it->max_count, dr);
1945 if (FrameInstSetSize (dr.fi, num) == FmSuccess)
1951 return FmNoMoreData;
1957 return FmNoMoreData;
1960 static int IterGetSize (Iter it)
1966 if (it->cur_no >= it->max_count)
1967 return NO_VALID_FIELD;
1970 switch (it->template->type)
1973 if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
1979 for (i = it->cur_no; i < it->max_count; i++)
1983 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
1985 dr.iter = IterInit (it->template + 1, NO_VALUE);
1986 d = ChainMgrSetData (&it->cm, i, dr);
1989 ret_size = IterGetSize (d->iter);
1990 if (ret_size != NO_VALID_FIELD)
1995 return NO_VALID_FIELD;
1998 for (i = it->cur_no; i < it->max_count; i++)
2002 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2004 dr.fi = FrameInstInit (it->template[1].data);
2005 d = ChainMgrSetData (&it->cm, i, dr);
2008 ret_size = FrameInstGetSize (d->fi);
2009 if (ret_size != NO_VALID_FIELD)
2014 return NO_VALID_FIELD;
2020 return NO_VALID_FIELD;
2023 static FmStatus IterSetIterCount (Iter it, int num)
2027 if (it->allow_expansion)
2029 it->max_count = num;
2030 it->allow_expansion = False;
2035 if (it->max_count == 0)
2036 return FmNoMoreData;
2039 switch (it->template->type)
2042 for (i = 0; i < it->max_count; i++)
2047 if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL)
2049 dr.iter = IterInit(it->template + 1, num);
2050 (void)ChainMgrSetData(&it->cm, i, dr);
2054 if (IterSetIterCount(d->iter, num) == FmSuccess)
2059 if (it->allow_expansion)
2063 dr.iter = IterInit (it->template + 1, num);
2064 ChainMgrSetData (&it->cm, it->max_count, dr);
2073 for (i = 0; i < it->max_count; i++)
2078 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2080 dr.fi = FrameInstInit (it->template[1].data);
2081 d = ChainMgrSetData (&it->cm, i, dr);
2084 if (FrameInstSetIterCount (d->fi, num) == FmSuccess)
2089 if (it->allow_expansion)
2093 dr.fi = FrameInstInit (it->template[1].data);
2094 ChainMgrSetData (&it->cm, it->max_count, dr);
2097 if (FrameInstSetIterCount (dr.fi, num) == FmSuccess)
2108 return FmNoMoreData;
2111 static int IterGetTotalSize (Iter it)
2113 register int size, i;
2116 if (it->allow_expansion)
2119 if (it->max_count == 0)
2124 type = it->template->type;
2129 size = it->max_count;
2133 size = it->max_count*2;
2137 size = it->max_count*4;
2141 size = it->max_count*8;
2145 for (i = 0; i < it->max_count; i++)
2150 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2153 if ((num = d->num) == NO_VALUE)
2162 for (i = 0; i < it->max_count; i++)
2167 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2170 if ((num = IterGetTotalSize (d->iter)) == NO_VALUE)
2179 for (i = 0; i < it->max_count; i++)
2185 if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
2187 dr.fi = FrameInstInit (it->template[1].data);
2188 d = ChainMgrSetData (&it->cm, i, dr);
2191 if ((num = FrameInstGetTotalSize (d->fi)) == NO_VALUE)
2206 static void IterReset (Iter it)
2212 switch (it->template->type)
2215 ChainIterInit (&ci, &it->cm);
2216 while (ChainIterGetNext (&ci, &count, &d))
2219 ChainIterFree (&ci);
2223 ChainIterInit (&ci, &it->cm);
2224 while (ChainIterGetNext (&ci, &count, &d))
2225 FrameInstReset (d.fi);
2227 ChainIterFree (&ci);
2237 static void IterSetStartWatch (Iter it,
2238 IterStartWatchProc proc,
2241 it->start_watch_proc = proc;
2242 it->client_data = client_data;
2245 static ExtraData ChainMgrSetData (ChainMgr cm,
2249 Chain cur = (Chain) Xmalloc (sizeof (ChainRec));
2251 cur->frame_no = frame_no;
2255 if (cm->top == NULL)
2257 cm->top = cm->tail = cur;
2261 cm->tail->next = cur;
2268 static ExtraData ChainMgrGetExtraData (ChainMgr cm, int frame_no)
2276 if (cur->frame_no == frame_no)
2285 static Bool ChainIterGetNext (ChainIter ci, int *frame_no, ExtraData d)
2287 if (ci->cur == NULL)
2291 *frame_no = ci->cur->frame_no;
2294 ci->cur = ci->cur->next;
2299 static int _FrameInstIncrement (XimFrame frame, int count)
2303 type = frame[count].type;
2304 type &= ~COUNTER_MASK;
2320 return _FrameInstIncrement (frame, count + 1);
2325 return - 1; /* Error */
2328 static int _FrameInstDecrement (XimFrame frame, int count)
2334 return - 1; /* cannot decrement */
2338 return 0; /* BOGUS - It should check the contents of data */
2341 type = frame[count - 2].type;
2342 type &= ~COUNTER_MASK;
2360 if (frame[i].type != ITER)
2371 return - 1; /* Error */
2374 static int _FrameInstGetItemSize (FrameInst fi, int cur_no)
2378 type = fi->template[cur_no].type;
2379 type &= ~COUNTER_MASK;
2399 if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL)
2402 if (d->num == NO_VALUE)
2411 register int number;
2415 unit = _UNIT ((long) fi->template[cur_no].data);
2416 number = _NUMBER ((long) fi->template[cur_no].data);
2422 i = _FrameInstDecrement (fi->template, i);
2423 size += _FrameInstGetItemSize (fi, i);
2427 size = (unit - (size%unit))%unit;
2436 if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL)
2439 sub_size = IterGetTotalSize (d->iter);
2440 if (sub_size == NO_VALUE)
2451 if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL)
2454 sub_size = FrameInstGetTotalSize (d->fi);
2455 if (sub_size == NO_VALUE)