1 /*
2    XMascot Ver 2.6
3    Copyright(c) 1996,1997 Go Watanabe     go@cclub.tutcc.tut.ac.jp
4                           Tsuyoshi IIda   iida@cclub.tutcc.tut.ac.jp
5 */
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <math.h>
10 #include "xmascot.h"
11 
12 extern XtAppContext app;
13 extern Atom wm_protocols[2];
14 
15 extern Widget top, mascot, *chain;
16 
17 #ifdef BIFF
18 extern Widget biff;
19 extern int mbox_flag;
20 #endif
21 
22 extern AppData  adat;		/* �꥽������ */
23 
24 #ifdef USE_DOUBLE
25 extern double   th;		/* ����           */
26 extern double   om;		/* ��®��         */
27 #else
28 extern int      th;		/* ����           */
29 extern int      om;		/* ��®��         */
30 #endif
31 
32 
33 /* �ޥ����åȤ��ѹ� */
34 void
change_mascot(Widget w,XtPointer dat,XtPointer call)35 change_mascot(Widget w, XtPointer dat, XtPointer call)
36 {
37 	adat.menu_no = (int) dat >> 8;
38 	adat.mascot_number = (int) dat & 0xff;
39 	set_mas(&adat);
40 	set_sim_param();
41 	reset_pos();		/* ������ */
42 	set_pos();
43 }
44 
45 /* �����Ĥ��ޥ����å��ѹ� */
46 void
change_mascot_with_sound(Widget w,XtPointer dat,XtPointer call)47 change_mascot_with_sound(Widget w, XtPointer dat, XtPointer call)
48 {
49 	change_mascot(w, dat, call);
50 #ifdef SOUND
51 	xmascot_sound(&adat, SOUND_START);
52 #endif
53 }
54 
55 /* ���Τ� raise ���� */
56 void
RaiseAll(void)57 RaiseAll(void)
58 {
59 	int             i;
60 	for (i = 0; i < adat.chain_num; i++)
61 		XRaiseWindow(XtDisplay(chain[i]), XtWindow(chain[i]));
62 	XRaiseWindow(XtDisplay(top), XtWindow(top));
63 	XRaiseWindow(XtDisplay(mascot), XtWindow(mascot));
64 #ifdef BIFF
65 	if (mbox_flag)
66 		XRaiseWindow(XtDisplay(biff), XtWindow(biff));
67 #endif
68 }
69 
70 /* ��λ���� */
71 void
ExitApp(void)72 ExitApp(void)
73 {
74 #ifdef SOUND
75 	xmascot_sound(&adat, SOUND_END);
76 #endif
77 	put_rcfile();
78 	exit(0);
79 }
80 
81 /* ��λ���� */
82 void
Quit(Widget w,XEvent * e,String * p,Cardinal * n)83 Quit(Widget w, XEvent * e, String * p, Cardinal * n)
84 {
85 	ExitApp();
86 }
87 
88 /* ��λ��å������μ��� */
89 void
QuitMsg(Widget w,XEvent * e,String * p,Cardinal * n)90 QuitMsg(Widget w, XEvent * e, String * p, Cardinal * n)
91 {
92 	if (e->xclient.data.l[0] == wm_protocols[0] ||
93 	    e->xclient.data.l[0] == wm_protocols[1]) {
94 		ExitApp();
95 	}
96 }
97 
98 int             map_fl = 0;	/* ���ߥޥ����åȤϥޥåפ���Ƥ��뤫�� */
99 
100 /* �ޥåԥ� */
101 void
MapWin(Widget w,XEvent * e,String * p,Cardinal * n)102 MapWin(Widget w, XEvent * e, String * p, Cardinal * n)
103 {
104 #ifdef SOUND
105 	static int      firstmap = 0;
106 #endif
107 	int             i;
108 	set_sim_param();
109 	reset_pos();
110 	set_pos();
111 	for (i = 0; i < adat.chain_disp_num; i++)
112 		XtMapWidget(chain[i]);
113 	XtMapWidget(mascot);
114 #ifdef BIFF
115 	if (mbox_flag) {
116 		XtMapWidget(biff);
117 	}
118 #endif
119 	start_timer();
120 	RaiseAll();
121 #ifdef SOUND
122 	if (firstmap == 0) {
123 		firstmap = 1;
124 		xmascot_sound(&adat, SOUND_START);
125 	}
126 #endif
127 	map_fl = 1;
128 }
129 
130 /* ����ޥå� */
131 void
UnMapWin(Widget w,XEvent * e,String * p,Cardinal * n)132 UnMapWin(Widget w, XEvent * e, String * p, Cardinal * n)
133 {
134 	int             i;
135 	stop_timer();
136 	for (i = 0; i < adat.chain_num; i++)
137 		XtUnmapWidget(chain[i]);
138 	XtUnmapWidget(mascot);
139 #ifdef BIFF
140 	XtUnmapWidget(biff);
141 #endif
142 	map_fl = 0;
143 }
144 
145 int             px, py;		/* pin �� geometry */
146 
147 /* ���ΰ�ư */
148 void
ConfigWin(Widget w,XEvent * e,String * p,Cardinal * n)149 ConfigWin(Widget w, XEvent * e, String * p, Cardinal * n)
150 {
151 	Window          dmy;
152 	Dimension       pin_w, pin_h;
153 	Display        *dpy = XtDisplay(w);
154 
155 	XtVaGetValues(w, XtNwidth, &pin_w, XtNheight, &pin_h, NULL);
156 	XTranslateCoordinates(dpy, XtWindow(w), RootWindowOfScreen(XtScreen(w)),
157 			      0, 0, &px, &py, &dmy);
158 	px += pin_w / 2;
159 	py += pin_h / 2;
160 	set_pos();
161 }
162 
163 static int      motion_fl;	/* �ɥ�å�������?             */
164 
165 /* �ܥ�������� */
166 void
Press(Widget w,XEvent * e,String * p,Cardinal * n)167 Press(Widget w, XEvent * e, String * p, Cardinal * n)
168 {
169 	stop_timer();		/* ���ҤΥ��ߥ�졼��������� */
170 	motion_fl = 0;
171 
172 	XDefineCursor(XtDisplay(w), XtWindow(w), adat.cursor_click);
173 	RaiseAll();
174 }
175 
176 /* �ޥ����å� �ܥ����Υ���� */
177 void
ReleaseMascot(Widget w,XEvent * e,String * p,Cardinal * n)178 ReleaseMascot(Widget w, XEvent * e, String * p, Cardinal * n)
179 {
180 #ifdef USE_DOUBLE
181 	om = (motion_fl) ? 0 : om + ((om < 0) ? -1 : 1) * M_PI;
182 #else
183 	om = (motion_fl) ? 0 : om + ((om < 0) ? -1 : 1) * M_PI * 256;
184 #endif
185 	XtUngrabPointer(w, CurrentTime);
186 
187 	XDefineCursor(XtDisplay(w), XtWindow(w), adat.cursor_normal);
188 	restart_timer();	/* ���ҤΥ��ߥ�졼�����κƳ� */
189 }
190 
191 /* Pin �ܥ����Υ���� */
192 void
ReleasePin(Widget w,XEvent * e,String * p,Cardinal * n)193 ReleasePin(Widget w, XEvent * e, String * p, Cardinal * n)
194 {
195 	XtUngrabPointer(w, CurrentTime);
196 	XDefineCursor(XtDisplay(w), XtWindow(w), adat.cursor_normal);
197 	restart_timer();	/* ���ҤΥ��ߥ�졼�����κƳ� */
198 }
199 
200 /* Mascot �ΰ�ư */
201 void
MotionMascot(Widget w,XEvent * e,String * p,Cardinal * n)202 MotionMascot(Widget w, XEvent * e, String * p, Cardinal * n)
203 {
204 	XEvent          ev;
205 	Window          root, child;
206 	int             rx, ry, x, y;
207 	u_int           key;
208 
209 	if (!motion_fl) {
210 		XtGrabPointer(w, False, ButtonReleaseMask | Button1MotionMask,
211 					  GrabModeAsync, GrabModeAsync,
212 					  None, adat.cursor_drag, CurrentTime);
213 		motion_fl = 1;
214 	}
215 	while (XCheckMaskEvent(XtDisplay(w), Button1MotionMask, &ev));
216 	if (!XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child,
217 			   &rx, &ry, &x, &y, &key))
218 		return;
219 	x = rx - px;
220 	y = ry - py;
221 	th = atan2(x, y) / RAD;
222 	adat.chain_len = sqrt((double) (x * x + y * y));
223 	set_sim_param();
224 	set_pos();
225 }
226 
227 /* PIN �ΰ�ư */
228 void
MotionPin(Widget w,XEvent * e,String * p,Cardinal * n)229 MotionPin(Widget w, XEvent * e, String * p, Cardinal * n)
230 {
231 	XEvent          ev;
232 	Window          root, child;
233 	Display        *dpy = XtDisplay(w);
234 	int             rx, ry, x, y;
235 	u_int           key;
236 	Dimension       pin_w, pin_h;
237 
238 	if (!motion_fl) {
239 		XtGrabPointer(w, False, ButtonReleaseMask | Button1MotionMask,
240 					  GrabModeAsync, GrabModeAsync,
241 					  None, adat.cursor_drag, CurrentTime);
242 		motion_fl = 1;
243 	}
244 	while (XCheckMaskEvent(dpy, Button1MotionMask, &ev));
245 	if (!XQueryPointer(dpy, XtWindow(top), &root, &child,
246 					   &rx, &ry, &x, &y, &key))
247 		return;
248 	XtVaGetValues(w, XtNwidth, &pin_w, XtNheight, &pin_h, NULL);
249 	XtMoveWidget(w, rx - pin_w / 2, ry - pin_h / 2);
250 }
251 
252 
253 /* ��������� �ޥ����åȤ��ѹ� ���ꤷ���ֹ� */
254 void
ChangeMascot(Widget w,XEvent * e,String * p,Cardinal * n)255 ChangeMascot(Widget w, XEvent * e, String * p, Cardinal * n)
256 {
257 	long            m, i;
258 	if (*n == 1) {
259 		i = atoi(p[0]);
260 		if (i >= 0 && i < adat.mascot_menus[0].n_mascots)
261 			change_mascot(w, (XtPointer) i, NULL);
262 	} else if (*n == 2) {
263 		i = atoi(p[0]);
264 		m = atoi(p[1]);
265 		if (i >= 0 && i < adat.mascot_menus[m].n_mascots)
266 			change_mascot(w, (XtPointer) ((m << 8) + i), NULL);
267 	}
268 }
269 
270 /* ��������� �ޥ����åȤ��ѹ� �ե�������ɤ߹��� */
271 void
ChangeMascotFile(Widget w,XEvent * e,String * p,Cardinal * n)272 ChangeMascotFile(Widget w, XEvent * e, String * p, Cardinal * n)
273 {
274 	if (*n > 0) {
275 		MascotMenu *m = &adat.mascot_menus[0];
276 		m->mascots[m->n_mascots].fname = p[0];
277 		m->mascots[m->n_mascots].title = (*n > 2) ? p[1] : p[0];
278 		change_mascot(w, I2P(m->n_mascots), NULL);
279 	}
280 }
281 
282 /* ��������� �ޥ����åȤ��ѹ� ���Υ���ȥ� */
283 void
ChangeMascotNext(Widget w,XEvent * e,String * p,Cardinal * n)284 ChangeMascotNext(Widget w, XEvent * e, String * p, Cardinal * n)
285 {
286 	MascotMenu *m = &adat.mascot_menus[adat.menu_no];
287 	long i = adat.mascot_number + 1;
288 	if (i >= m->n_mascots)
289 		i = 0;
290 	change_mascot(w, (XtPointer) ((adat.menu_no << 8) + i), NULL);
291 }
292 
293 /*
294  * ��������� �ޥ����åȤ��ѹ� ���Υ���ȥ�
295  * (����˥塼)
296  */
297 void
ChangeMascotNextAll(Widget w,XEvent * e,String * p,Cardinal * n)298 ChangeMascotNextAll(Widget w, XEvent * e, String * p, Cardinal * n)
299 {
300 	MascotMenu *m = &adat.mascot_menus[adat.menu_no];
301 	long mn = adat.menu_no;
302 	long i = adat.mascot_number + 1;
303 	if (i >= m->n_mascots) {
304 		i = 0;
305 		mn++;
306 		if (mn >= adat.menus_num) {
307 			mn = 0;
308 		}
309 	}
310 	change_mascot(w, (XtPointer) ((mn << 8) + i), NULL);
311 }
312 
313 /* ��������� �ޥ����åȤ��ѹ� ������ */
314 void
ChangeMascotRandom(Widget w,XEvent * e,String * p,Cardinal * n)315 ChangeMascotRandom(Widget w, XEvent * e, String * p, Cardinal * n)
316 {
317 	MascotMenu *m = &adat.mascot_menus[adat.menu_no];
318 	long i = rand() % m->n_mascots;
319 	change_mascot(w, (XtPointer) ((adat.menu_no << 8) + i), NULL);
320 }
321 
322 /* ��������� �ޥ����åȤ��ѹ� ������ ����˥塼 */
323 void
ChangeMascotRandomAll(Widget w,XEvent * e,String * p,Cardinal * n)324 ChangeMascotRandomAll(Widget w, XEvent * e, String * p, Cardinal * n)
325 {
326 	long            m = rand() % adat.menus_num;
327 	long            i = rand() % adat.mascot_menus[m].n_mascots;
328 	change_mascot(w, (XtPointer) ((m << 8) + i), NULL);
329 }
330 
331 /* ��������� �ɤ�� */
332 void
StartMove(Widget w,XEvent * e,String * p,Cardinal * n)333 StartMove(Widget w, XEvent * e, String * p, Cardinal * n)
334 {
335 #ifdef USE_DOUBLE
336 	om = om + ((om < 0) ? -1 : 1) * M_PI;
337 #else
338 	om = om + ((om < 0) ? -1 : 1) * M_PI * 256;
339 #endif
340 	restart_timer();
341 }
342 
343 /* ��������� �����κ��� */
344 void
Sound(Widget w,XEvent * e,String * p,Cardinal * n)345 Sound(Widget w, XEvent * e, String * p, Cardinal * n)
346 {
347 #ifdef SOUND
348 	sounds_play(p, *n);
349 #endif
350 }
351 
352 /* ��������� ���ϻ����� */
353 void
SoundStart(Widget w,XEvent * e,String * p,Cardinal * n)354 SoundStart(Widget w, XEvent * e, String * p, Cardinal * n)
355 {
356 #ifdef SOUND
357 	xmascot_sound(&adat, SOUND_START);
358 #endif
359 }
360 
361 /* ��������� ����å������� */
362 void
SoundClick(Widget w,XEvent * e,String * p,Cardinal * n)363 SoundClick(Widget w, XEvent * e, String * p, Cardinal * n)
364 {
365 #ifdef SOUND
366 	xmascot_sound(&adat, SOUND_CLICK);
367 #endif
368 }
369 
370 /* ��������� ��λ������ */
371 void
SoundEnd(Widget w,XEvent * e,String * p,Cardinal * n)372 SoundEnd(Widget w, XEvent * e, String * p, Cardinal * n)
373 {
374 #ifdef SOUND
375 	xmascot_sound(&adat, SOUND_END);
376 #endif
377 }
378 
379 /* ��������� �᡼�벻�� */
380 void
SoundMail(Widget w,XEvent * e,String * p,Cardinal * n)381 SoundMail(Widget w, XEvent * e, String * p, Cardinal * n)
382 {
383 #if defined(BIFF) && defined(SOUND)
384 	xmascot_sound(&adat, SOUND_MAIL);
385 #endif
386 }
387 
388 /* ��������� �������ޥ�ɸƤӤ��� */
389 void
System(Widget w,XEvent * e,String * p,Cardinal * n)390 System(Widget w, XEvent * e, String * p, Cardinal * n)
391 {
392 	if (*n > 0)
393 		system(p[0]);
394 }
395 
396 /* ��������� �ѥ�᡼���ѹ� */
397 void
ChangeParam(Widget w,XEvent * e,String * p,Cardinal * n)398 ChangeParam(Widget w, XEvent * e, String * p, Cardinal * n)
399 {
400 	int             i;
401 	for (i = 0; i < *n; i += 2) {
402 		if (!strcmp(p[i], "clen")) {
403 			adat.chain_len = atoi(p[i + 1]);
404 			set_sim_param();
405 			reset_pos();
406 			set_pos();
407 		} else if (!strcmp(p[i], "damp")) {
408 			adat.damping = atof(p[i + 1]);
409 			if (adat.damping < 0)
410 				adat.damping = 0;
411 			if (adat.damping > 1)
412 				adat.damping = 1;
413 		} else if (!strcmp(p[i], "mag")) {
414 			adat.magnify = atof(p[i + 1]);
415 			if (adat.magnify < 0.01)
416 				adat.magnify = 0.01;
417 			change_mascot(w, (XtPointer) ((long)adat.mascot_number), NULL);
418 		} else if (!strcmp(p[i], "grav")) {
419 			adat.grav = atoi(p[i + 1]);
420 			set_sim_param();
421 		}
422 	}
423 }
424 
425 /* ��������� �٥��ʤ餹 */
426 void
Bell(Widget w,XEvent * e,String * p,Cardinal * n)427 Bell(Widget w, XEvent * e, String * p, Cardinal * n)
428 {
429 	int             i;
430 	if (*n > 0) {
431 		i = atoi(p[0]);
432 		if (i < -100)
433 			i = -100;
434 		if (i > 100)
435 			i = 100;
436 		XBell(XtDisplay(w), i);
437 	} else
438 		XBell(XtDisplay(w), 100);
439 }
440