1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <sys/types.h>
5 #include <unistd.h>
6
7 #include <X11/Xlib.h>
8 #include <X11/Xutil.h>
9 #include <X11/Intrinsic.h>
10 #include <X11/StringDefs.h>
11 #include <X11/Shell.h>
12
13 #include "image.h"
14 #include "animate.h"
15 #include "namelist.h"
16
17 Atom wm_protocols[2];
18 XtAppContext app;
19
20 Animate *anim = NULL;
21
22 void
QuitMsg(Widget w,XEvent * e,String * p,Cardinal * n)23 QuitMsg(Widget w, XEvent *e, String *p, Cardinal *n)
24 {
25 if (e->xclient.data.l[0] == wm_protocols[0] ||
26 e->xclient.data.l[0] == wm_protocols[1]) {
27 exit(1);
28 /* XtDestroyWidget(w); */
29 }
30 }
31
32 /* bad function */
33 void
expose(Widget w,XEvent * e,String * p,Cardinal * n)34 expose(Widget w, XEvent *e, String *p, Cardinal *n)
35 {
36 XExposeEvent *ee = (XExposeEvent*)e;
37 if (anim->dpy == ee->display && anim->win == ee->window)
38 animate_expose(anim,ee->x, ee->y, ee->width, ee->height);
39 }
40
41 /* command-line options */
42 static XrmOptionDescRec options[] = {};
43
44 /* actions */
45 static XtActionsRec actions[] = {
46 {"quitmsg", QuitMsg},
47 {"expose", expose}
48 };
49
50 /* translations */
51 String trans_top =
52 "<Message>WM_PROTOCOLS: quitmsg()\n"
53 "<Expose>: expose()\n";
54
55 extern int verbose;
56
57 void
set_animate(char * name)58 set_animate(char *name)
59 {
60 FILE *fp;
61 anim = animate_new();
62 if ((fp = animate_fopen(name)) == NULL) {
63 perror("animate_fopen");
64 exit(1);
65 }
66 if (animate_parse(anim,fp)) {
67 fprintf(stderr,"animate file load error.\n");
68 exit(1);
69 }
70 }
71
72 typedef struct TimerDat {
73 struct TimerDat *next;
74 Animate *animate;
75 u_int interval;
76 } TimerDat, *TimerDatList;
77
78 TimerDat*
timer_new(void)79 timer_new(void)
80 {
81 TimerDat *p;
82 if ((p = malloc(sizeof(*p))) == NULL) {
83 perror("timer_new");
84 exit(1);
85 }
86 p->next = NULL;
87 p->animate = NULL;
88 p->interval = 0;
89 return p;
90 }
91
92 void
timer_delete(TimerDat * p)93 timer_delete(TimerDat *p)
94 {
95 if (p)
96 free(p);
97 }
98
99 void
timer_reentry(TimerDatList list,Animate * animate,TimerDat * new,int interval)100 timer_reentry(TimerDatList list, Animate *animate,
101 TimerDat *new, int interval)
102 {
103 TimerDat *t = list->next;
104
105 if (t != NULL) {
106 /* search entry point */
107 while (t->next != NULL) {
108 if (t->interval > interval)
109 break;
110 interval -= t->interval;
111 t = t->next;
112 }
113 /* $B%j%9%H$KDI2C(B */
114 new->animate = animate;
115 new->next = t->next;
116 new->interval = interval;
117 t->next->interval -= interval;
118 t->next = new;
119 } else {
120 new->animate = animate;
121 new->next = NULL;
122 new->interval = interval;
123 list->next = new;
124 }
125 }
126
127 void
timer_entry(TimerDatList list,Animate * animate)128 timer_entry(TimerDatList list, Animate *animate)
129 {
130 TimerDat *new = timer_new();
131 timer_reentry(list, animate, new, 0);
132 }
133
134 static void timer_go(TimerDatList list);
135
136 static volatile XtIntervalId id;
137
138 static void
TimerHand(XtPointer cl,XtIntervalId * id)139 TimerHand(XtPointer cl, XtIntervalId *id)
140 {
141 timer_go((TimerDatList)cl);
142 }
143
144 static void
timer_go(TimerDatList list)145 timer_go(TimerDatList list)
146 {
147 TimerDat *p = list->next;
148 int interval;
149
150 if (list != NULL && (p = list->next) != NULL) {
151 interval = p->animate->point->interval;
152 fprintf(stderr,"interval:[%d]\n",interval);
153 list->next = p->next;
154 if (animate_go(p->animate)) {
155 timer_reentry(list, p->animate, p, interval);
156 } else {
157 timer_delete(p);
158 }
159
160 if (list->next)
161 id = XtAppAddTimeOut(app, list->next->interval, TimerHand, list);
162 }
163 }
164
165 int
main(int argc,char ** argv)166 main(int argc, char **argv)
167 {
168 Widget top;
169 TimerDatList tlist = timer_new();
170 verbose = 1;
171
172 top = XtVaOpenApplication(&app, "AnimTest", options, XtNumber(options),
173 &argc, argv, NULL,
174 sessionShellWidgetClass, NULL);
175
176 if (argv[1]) {
177
178 wm_protocols[0] =
179 XInternAtom(XtDisplay(top), "WM_DELETE_WINDOW", False);
180 wm_protocols[1] =
181 XInternAtom(XtDisplay(top), "WM_SAVEYOURSELF", False);
182
183 XtAppAddActions(app, actions, XtNumber(actions));
184 XtOverrideTranslations(top, XtParseTranslationTable(trans_top));
185 XtVaSetValues(top, XtNwidth,(Dimension)100,
186 XtNheight,(Dimension)100, NULL);
187
188 XtRealizeWidget(top);
189 XSetWMProtocols(XtDisplay(top), XtWindow(top), wm_protocols, 2);
190
191 set_animate(argv[1]);
192 animate_attach_win(anim, XtDisplay(top), XtWindow(top));
193 animate_realize(anim);
194 animate_init_all(anim);
195
196 fprintf(stderr,"timer\n");
197
198 timer_entry(tlist,anim);
199 timer_go(tlist);
200
201 XtAppMainLoop(app);
202 } else {
203 fprintf(stderr, "usage: %s filename\n", argv[0]);
204 exit(1);
205 }
206 exit(0);
207 }
208
209