1 /*****************************************************************************/
2 /* XStarRoll - Letters fly to far, far, far away. */
3 /* */
4 /* XStarRoll Copyright (c) 1998 Sakai Hiroaki. */
5 /* All Rights Reserved. */
6 /* */
7 /* XStarRoll is a simple demonstration program for X11. Letters and pixmaps */
8 /* fly to far, far, far away. You can fly optional letters and pixmaps, and */
9 /* use XStarRoll as a background picture. */
10 /* */
11 /* XStarRoll is a free software. You may copy or distribute the original */
12 /* XStarRoll freely. But, you may not modify or distribute the original */
13 /* XStarRoll without permission of the author. */
14 /*****************************************************************************/
15
16 /*****************************************************************************/
17 /* Include Header Files. */
18 /*****************************************************************************/
19
20 #include<stdio.h>
21 #include<stdlib.h>
22 #include<X11/Xlib.h>
23 #include<X11/Intrinsic.h>
24 #include<X11/StringDefs.h>
25 #include<X11/keysym.h>
26 #include<X11/xpm.h>
27 #include<X11/Xaw/Label.h>
28
29 /*****************************************************************************/
30 /* XStarRoll's version. */
31 /*****************************************************************************/
32
33 #ifndef VERSION
34 #define VERSION "XStarRoll-unknown-version"
35 #endif
36
37 /*****************************************************************************/
38 /* If you DEBUG, define below definition. */
39 /*****************************************************************************/
40
41 /*
42 #define DEBUG
43 */
44
45 /*****************************************************************************/
46 /* Font. */
47 /*****************************************************************************/
48
49 #define DEFAULT_FONT_NAME "8x16"
50
51 /*****************************************************************************/
52 /* Icon. */
53 /*****************************************************************************/
54
55 #include"xstarroll_icon.xpm"
56 #define XSTARROLL_ICON xstarroll_icon
57
58 /*****************************************************************************/
59 /* Others. */
60 /*****************************************************************************/
61
62 #define OFF 0
63 #define ON 1
64 #define FILL 2
65 #define READ_FROM_STRING 0
66 #define READ_FROM_FILE 1
67
68 /*****************************************************************************/
69 /* Default values. */
70 /*****************************************************************************/
71
72 #define DEFAULT_CANVAS_WIDTH 640
73 #define DEFAULT_CANVAS_HEIGHT 480
74 #define DEFAULT_SOURCE_WIDTH 0
75 #define DEFAULT_WIDTH 40
76 #define DEFAULT_LENGTH_X 0
77 #define DEFAULT_LENGTH_Y 100
78 #define DEFAULT_SPACE 1
79 #define DEFAULT_SCROLL 1
80 #define DEFAULT_START 0
81 #define DEFAULT_WAIT 0
82 #define DEFAULT_TITLE_NAME "XStarRoll"
83
84 /*****************************************************************************/
85 /* Default flags. */
86 /*****************************************************************************/
87
88 #define DEFAULT_ROOT_FLAG 0
89 #define DEFAULT_DRAW_FLAG 1
90 #define DEFAULT_QUIT_FLAG 0
91 #define DEFAULT_BLUR_FLAG 1
92
93 /*****************************************************************************/
94 /* Buffer. */
95 /*****************************************************************************/
96
97 #define TMP_BUFFER_SIZE 2048
98 static char tmp_buffer[TMP_BUFFER_SIZE];
99
100 /*****************************************************************************/
101 /* Structures. */
102 /*****************************************************************************/
103
104 typedef struct GCBuffer {
105 GC gc;
106 unsigned long int pixel;
107 struct GCBuffer * prev;
108 struct GCBuffer * next;
109 } GCBuffer;
110
111 typedef struct GCBufferList {
112 GCBuffer * start;
113 GCBuffer * end;
114 } GCBufferList;
115
116 typedef struct SourceData {
117 short int length;
118 GCBuffer * gc_buffer;
119 short int x;
120 short int y;
121 struct SourceData * prev;
122 struct SourceData * next;
123 } SourceData;
124
125 typedef struct SourceDataList {
126 SourceData * start;
127 SourceData * end;
128 } SourceDataList;
129
130 typedef struct FontDataList {
131 unsigned char pixel;
132 unsigned char length;
133 struct FontDataList * next;
134 } FontDataList;
135
136 typedef struct FontData {
137 short int width;
138 FontDataList ** list_array;
139 } FontData;
140
141 /*****************************************************************************/
142 /* Structure of XStarRoll. */
143 /*****************************************************************************/
144
145 typedef struct XStarRoll {
146 XtAppContext app_context;
147 Display * display;
148 int screen, depth;
149 Colormap colormap;
150 Widget toplevel, canvas;
151 Window toplevel_window, root_window, canvas_window;
152 Pixmap canvas_pixmap, icon_pixmap;
153 Atom atom_1, atom_2;
154 unsigned long int foreground_color;
155 unsigned long int background_color;
156 unsigned long int foreground_pixel;
157 unsigned long int background_pixel;
158 GC gc_foreground, gc_background, gc_copy;
159 char * font_name;
160 Font font;
161 XFontStruct * font_struct;
162 char * title_name;
163 int canvas_width, canvas_height, source_width, width;
164 int icon_width, icon_height, font_height;
165 int root_flag, draw_flag, quit_flag, blur_flag;
166 int length_x, length_y, space, scroll, wait;
167 long int start;
168 GCBufferList * gc_buffer;
169 SourceDataList * source_data;
170 FontData * font_data;
171 } XStarRoll;
172
173 /*****************************************************************************/
174 /* Help Message. */
175 /*****************************************************************************/
176
177 char * help_string =
178 "\n\t" VERSION "\n"
179 "\tLetters fly to far, far, far away.\n"
180 "\n"
181 "\tDESCRIPTION\n"
182 "\n"
183 " XStarRoll is a simple demonstration program for X11. Letters and pixmaps fly to far, far, far away. You can fly optional letters and pixmaps, and use XStarRoll as a background picture.\n"
184 "\n"
185 "\tSYNOPSIS\n"
186 "\n"
187 "\txstarroll [parameter1] [parameter2] ...\n"
188 "\n"
189 " If a parameter is a pixmap filename, XStarRoll reads it and flies the pixmap, or, if the parameter is a text filename, XStarRoll reads it and flies letters in it, or else, xstarroll flies the parameter as it is.\n"
190 " You can send letters to XStarRoll through the standard input.\n"
191 "\n"
192 "\tOPTIONS\n"
193 "\n"
194 "(X-ToolKit Options) -display, -geometry, -name, -font, -fg and -bg are available.\n"
195 "-- End of options. XStarRoll ignores following options.\n"
196 "- Read letters from the standard input.\n"
197 "-help, -h Output this Message.\n"
198 "-root, -r Draw the picture on the root window of the display.\n"
199 "-noroot, -nr Open a new window and draw the picture on it. (Default)\n"
200 "-quit, -q Draw the picture and exit.\n"
201 "-noquit, -nq XStarRoll does not exit. (Default)\n"
202 "-blur, -b Letters fly to the farther, become the more blurred. (Default)\n"
203 "-noblur, -nb Letters do not become blurred.\n"
204 "-fill Fill all dots entirely.\n"
205 "-source-width [x], -sw [x] Specify the width of the source picture for a pixel.\n"
206 "-width [x], -w [x] Specify the width of the source picture for a letter. Default value is 40.\n"
207 "-length-x [x], -lx [x] Specify the length parameter of X-direction for drawing. Default value is same as the size of the source picture.\n"
208 "-length-y [x], -ly [x] Specify the length parameter of Y-direction for drawing. Default value is 100.\n"
209 "-space [x], -sp [x] Specify the space between lines. Default value is 1.\n"
210 "-scroll [x], -sc [x] Specify the speed and direction of the scroll. Default value is 1.\n"
211 "-start [x], -st [x] Specify the start point. Default value is 0.\n"
212 "-wait [x], -wt [x] Specify the wait time for a micro second. Default value is 0.\n"
213 "\n"
214 "\tKEY OPERATIONS\n"
215 "\n"
216 "[Up], [Down], [Right], [Left] Change the length parameters for drawing.\n"
217 "[a], [d] Change the speed of the scroll.\n"
218 "[p], [n], [PageUp], [PageDown] Scroll the picture.\n"
219 "[s] Return to the start point.\n"
220 "[q] Quit.\n"
221 "\n"
222 "\tEXAMPLES\n"
223 "\n"
224 "% ls -l | xstarroll\n"
225 " - XStarRoll flies the output of ls.\n"
226 "% echo \"This is XStarRoll.\" | xstarroll\n"
227 "% xstarroll \"This is XStarRoll.\"\n"
228 " - XStarRoll flies \"This is XStarRoll.\".\n"
229 "% echo \"is\" | xstarroll \"This\" - \"XStarRoll.\"\n"
230 " - XStarRoll flies \"This\", \"is\" and \"XStarRoll.\".\n"
231 "% xstarroll sample.txt\n"
232 " - XStarRoll flies letters in a file \"sample.txt\".\n"
233 "% xstarroll sample.xpm\n"
234 " - XStarRoll flies a pixmap \"sample.xpm\".\n"
235 "% xstarroll \"This is XStarRoll.\" sample1.txt sample1.xpm sample2.txt sample2.xpm ...\n"
236 " - XStarRoll flies \"This is XStarRoll.\", flies letters in a file sample1.txt, flies a pixmap sample1.xpm, flies letters in a file sample2.txt, flies a pixmap sample2.xpm ...\n"
237 "\n"
238 " If the head of letters is a Tab code or \"#center\", XStarRoll flies letters at the center of the screen.\n"
239 "\n"
240 "\tSEE ALSO\n"
241 "\tX(1)\n"
242 "\n"
243 "\tAUTHOR\n"
244 "\tProgramed by Sakai Hiroaki.\n"
245 "\tE-Mail:sakai@miya.ee.kagu.sut.ac.jp\n"
246 "\thttp://wwwmiya.ee.kagu.sut.ac.jp/~sakai/myfreesoft.html\n"
247 "\n"
248 "\tCOPYRIGHT\n"
249 "\n"
250 "\tXStarRoll Copyright (c) 1998 Sakai Hiroaki.\n"
251 "\tAll Rights Reserved.\n"
252 "\n"
253 " XStarRoll is a free software. You may copy or distribute the original XStarRoll freely. But, you may not modify or distribute the original XStarRoll without permission of the author.\n"
254 "\n";
255
256 /*****************************************************************************/
257 /* Functions. */
258 /*****************************************************************************/
259
260 /*****************************************************************************/
261 /* Operations of list structures. */
262 /*****************************************************************************/
263
264 /*****************************************************************************/
265 /* GCBuffer. */
266 /*****************************************************************************/
267
CreateGCBuffer(Display * display,Window window,unsigned long int pixel)268 GCBuffer * CreateGCBuffer(Display * display, Window window,
269 unsigned long int pixel)
270 {
271 GCBuffer * p;
272
273 p = (GCBuffer *)malloc(sizeof(GCBuffer));
274 p->gc = XCreateGC(display, window, 0, NULL);
275 XSetForeground(display, p->gc, pixel);
276 XSetFillRule(display, p->gc, WindingRule);
277 XSetLineAttributes(display, p->gc, 0, LineSolid, CapNotLast ,JoinMiter);
278 p->pixel = pixel;
279 p->prev = (GCBuffer *)NULL;
280 p->next = (GCBuffer *)NULL;
281 return (p);
282 }
283
FreeGCBuffer(Display * display,GCBuffer * p)284 void FreeGCBuffer(Display * display, GCBuffer * p)
285 {
286 XFreeGC(display, p->gc);
287 free(p);
288 }
289
InitializeGCBufferList()290 GCBufferList * InitializeGCBufferList()
291 {
292 GCBufferList * p;
293
294 p = (GCBufferList *)malloc(sizeof(GCBufferList));
295 p->start = (GCBuffer *)NULL;
296 p->end = (GCBuffer *)NULL;
297 return (p);
298 }
299
FreeGCBufferList(Display * display,GCBufferList * p)300 void FreeGCBufferList(Display * display, GCBufferList * p)
301 {
302 GCBuffer * q;
303
304 while (p->start != (GCBuffer *)NULL) {
305 q = p->start->next;
306 FreeGCBuffer(display, p->start);
307 p->start = q;
308 }
309 free(p);
310 }
311
GetGCBufferFromTop(GCBufferList * p)312 GCBuffer * GetGCBufferFromTop(GCBufferList * p)
313 {
314 return (p->start);
315 }
316
GetGCBufferFromBottom(GCBufferList * p)317 GCBuffer * GetGCBufferFromBottom(GCBufferList * p)
318 {
319 return (p->end);
320 }
321
AddGCBufferToTop(GCBufferList * p,GCBuffer * d)322 GCBuffer * AddGCBufferToTop(GCBufferList * p, GCBuffer * d)
323 {
324 if (d == (GCBuffer *)NULL) return (GCBuffer *)NULL;
325 if (p->start == (GCBuffer *)NULL) {
326 d->prev = (GCBuffer *)NULL;
327 d->next = (GCBuffer *)NULL;
328 p->start = d;
329 p->end = d;
330 } else {
331 d->prev = (GCBuffer *)NULL;
332 d->next = p->start;
333 p->start->prev = d;
334 p->start = d;
335 }
336 return (p->start);
337 }
338
AddGCBufferToBottom(GCBufferList * p,GCBuffer * d)339 GCBuffer * AddGCBufferToBottom(GCBufferList * p, GCBuffer * d)
340 {
341 if (d == (GCBuffer *)NULL) return (GCBuffer *)NULL;
342 if (p->start == (GCBuffer *)NULL) {
343 d->prev = (GCBuffer *)NULL;
344 d->next = (GCBuffer *)NULL;
345 p->start = d;
346 p->end = d;
347 } else {
348 d->next = (GCBuffer *)NULL;
349 d->prev = p->end;
350 p->end->next = d;
351 p->end = d;
352 }
353 return (p->end);
354 }
355
DeleteGCBufferFromTop(GCBufferList * p)356 GCBuffer * DeleteGCBufferFromTop(GCBufferList * p)
357 {
358 GCBuffer * q;
359
360 if (p->start == (GCBuffer *)NULL) return ((GCBuffer *)NULL);
361 q = p->start;
362 p->start = p->start->next;
363 if (p->start == (GCBuffer *)NULL) p->end = (GCBuffer *)NULL;
364 else p->start->prev = (GCBuffer *)NULL;
365 q->prev = (GCBuffer *)NULL;
366 q->next = (GCBuffer *)NULL;
367 return (q);
368 }
369
DeleteGCBufferFromBottom(GCBufferList * p)370 GCBuffer * DeleteGCBufferFromBottom(GCBufferList * p)
371 {
372 GCBuffer * q;
373
374 if (p->start == (GCBuffer *)NULL) return ((GCBuffer *)NULL);
375 q = p->end;
376 p->end = p->end->prev;
377 if (p->end == (GCBuffer *)NULL) p->start = (GCBuffer *)NULL;
378 else p->end->next = (GCBuffer *)NULL;
379 q->prev = (GCBuffer *)NULL;
380 q->next = (GCBuffer *)NULL;
381 return (q);
382 }
383
DeleteGCBuffer(GCBufferList * p,GCBuffer * d)384 GCBuffer * DeleteGCBuffer(GCBufferList * p, GCBuffer * d)
385 {
386 if (p->start == (GCBuffer *)NULL) return ((GCBuffer *)NULL);
387 else if (d == (GCBuffer *)NULL) return ((GCBuffer *)NULL);
388 else if (d->prev == (GCBuffer *)NULL)
389 return (DeleteGCBufferFromTop(p));
390 else if (d->next == (GCBuffer *)NULL)
391 return (DeleteGCBufferFromBottom(p));
392 else {
393 d->prev->next = d->next;
394 d->next->prev = d->prev;
395 d->prev = (GCBuffer *)NULL;
396 d->next = (GCBuffer *)NULL;
397 return (d);
398 }
399 }
400
MoveGCBufferFromBottomToTop(GCBufferList * p)401 GCBuffer * MoveGCBufferFromBottomToTop(GCBufferList * p)
402 {
403 GCBuffer * q;
404
405 q = DeleteGCBufferFromBottom(p);
406 return (AddGCBufferToTop(p, q));
407 }
408
MoveGCBufferFromTopToBottom(GCBufferList * p)409 GCBuffer * MoveGCBufferFromTopToBottom(GCBufferList * p)
410 {
411 GCBuffer * q;
412
413 q = DeleteGCBufferFromTop(p);
414 return (AddGCBufferToBottom(p, q));
415 }
416
MoveGCBufferToTop(GCBufferList * p,GCBuffer * d)417 GCBuffer * MoveGCBufferToTop(GCBufferList * p, GCBuffer * d)
418 {
419 GCBuffer * q;
420
421 q = DeleteGCBuffer(p, d);
422 return (AddGCBufferToTop(p, q));
423 }
424
MoveGCBufferToBottom(GCBufferList * p,GCBuffer * d)425 GCBuffer * MoveGCBufferToBottom(GCBufferList * p, GCBuffer * d)
426 {
427 GCBuffer * q;
428
429 q = DeleteGCBuffer(p, d);
430 return (AddGCBufferToBottom(p, q));
431 }
432
433 /*****************************************************************************/
434 /* SourceData. */
435 /*****************************************************************************/
436
CreateSourceData(int length,GCBuffer * gc_buffer,int x,int y)437 SourceData * CreateSourceData(int length, GCBuffer * gc_buffer, int x, int y)
438 {
439 SourceData * p;
440
441 p = (SourceData *)malloc(sizeof(SourceData));
442 p->length = (short int)length;
443 p->gc_buffer = gc_buffer;
444 p->x = (short int)x;
445 p->y = (short int)y;
446 p->prev = (SourceData *)NULL;
447 p->next = (SourceData *)NULL;
448 return (p);
449 }
450
FreeSourceData(SourceData * p)451 void FreeSourceData(SourceData * p)
452 {
453 free(p);
454 }
455
InitializeSourceDataList()456 SourceDataList * InitializeSourceDataList()
457 {
458 SourceDataList * p;
459
460 p = (SourceDataList *)malloc(sizeof(SourceDataList));
461 p->start = (SourceData *)NULL;
462 p->end = (SourceData *)NULL;
463 return (p);
464 }
465
FreeSourceDataList(SourceDataList * p)466 void FreeSourceDataList(SourceDataList * p)
467 {
468 SourceData * q;
469
470 while (p->start != (SourceData *)NULL) {
471 q = p->start->next;
472 FreeSourceData(p->start);
473 p->start = q;
474 }
475 free(p);
476 }
477
GetSourceDataFromTop(SourceDataList * p)478 SourceData * GetSourceDataFromTop(SourceDataList * p)
479 {
480 return (p->start);
481 }
482
GetSourceDataFromBottom(SourceDataList * p)483 SourceData * GetSourceDataFromBottom(SourceDataList * p)
484 {
485 return (p->end);
486 }
487
AddSourceDataToTop(SourceDataList * p,SourceData * d)488 SourceData * AddSourceDataToTop(SourceDataList * p, SourceData * d)
489 {
490 if (d == (SourceData *)NULL) return (SourceData *)NULL;
491 if (p->start == (SourceData *)NULL) {
492 d->prev = (SourceData *)NULL;
493 d->next = (SourceData *)NULL;
494 p->start = d;
495 p->end = d;
496 } else {
497 d->prev = (SourceData *)NULL;
498 d->next = p->start;
499 p->start->prev = d;
500 p->start = d;
501 }
502 return (p->start);
503 }
504
AddSourceDataToBottom(SourceDataList * p,SourceData * d)505 SourceData * AddSourceDataToBottom(SourceDataList * p, SourceData * d)
506 {
507 if (d == (SourceData *)NULL) return (SourceData *)NULL;
508 if (p->start == (SourceData *)NULL) {
509 d->prev = (SourceData *)NULL;
510 d->next = (SourceData *)NULL;
511 p->start = d;
512 p->end = d;
513 } else {
514 d->next = (SourceData *)NULL;
515 d->prev = p->end;
516 p->end->next = d;
517 p->end = d;
518 }
519 return (p->end);
520 }
521
DeleteSourceDataFromTop(SourceDataList * p)522 SourceData * DeleteSourceDataFromTop(SourceDataList * p)
523 {
524 SourceData * q;
525
526 if (p->start == (SourceData *)NULL) return ((SourceData *)NULL);
527 q = p->start;
528 p->start = p->start->next;
529 if (p->start == (SourceData *)NULL) p->end = (SourceData *)NULL;
530 else p->start->prev = (SourceData *)NULL;
531 q->prev = (SourceData *)NULL;
532 q->next = (SourceData *)NULL;
533 return (q);
534 }
535
DeleteSourceDataFromBottom(SourceDataList * p)536 SourceData * DeleteSourceDataFromBottom(SourceDataList * p)
537 {
538 SourceData * q;
539
540 if (p->start == (SourceData *)NULL) return ((SourceData *)NULL);
541 q = p->end;
542 p->end = p->end->prev;
543 if (p->end == (SourceData *)NULL) p->start = (SourceData *)NULL;
544 else p->end->next = (SourceData *)NULL;
545 q->prev = (SourceData *)NULL;
546 q->next = (SourceData *)NULL;
547 return (q);
548 }
549
DeleteSourceData(SourceDataList * p,SourceData * d)550 SourceData * DeleteSourceData(SourceDataList * p, SourceData * d)
551 {
552 if (p->start == (SourceData *)NULL) return ((SourceData *)NULL);
553 else if (d == (SourceData *)NULL) return ((SourceData *)NULL);
554 else if (d->prev == (SourceData *)NULL)
555 return (DeleteSourceDataFromTop(p));
556 else if (d->next == (SourceData *)NULL)
557 return (DeleteSourceDataFromBottom(p));
558 else {
559 d->prev->next = d->next;
560 d->next->prev = d->prev;
561 d->prev = (SourceData *)NULL;
562 d->next = (SourceData *)NULL;
563 return (d);
564 }
565 }
566
MoveSourceDataFromBottomToTop(SourceDataList * p)567 SourceData * MoveSourceDataFromBottomToTop(SourceDataList * p)
568 {
569 SourceData * q;
570
571 q = DeleteSourceDataFromBottom(p);
572 return (AddSourceDataToTop(p, q));
573 }
574
MoveSourceDataFromTopToBottom(SourceDataList * p)575 SourceData * MoveSourceDataFromTopToBottom(SourceDataList * p)
576 {
577 SourceData * q;
578
579 q = DeleteSourceDataFromTop(p);
580 return (AddSourceDataToBottom(p, q));
581 }
582
MoveSourceDataToTop(SourceDataList * p,SourceData * d)583 SourceData * MoveSourceDataToTop(SourceDataList * p, SourceData * d)
584 {
585 SourceData * q;
586
587 q = DeleteSourceData(p, d);
588 return (AddSourceDataToTop(p, q));
589 }
590
MoveSourceDataToBottom(SourceDataList * p,SourceData * d)591 SourceData * MoveSourceDataToBottom(SourceDataList * p, SourceData * d)
592 {
593 SourceData * q;
594
595 q = DeleteSourceData(p, d);
596 return (AddSourceDataToBottom(p, q));
597 }
598
599 /*****************************************************************************/
600 /* Graphic. */
601 /*****************************************************************************/
602
MakePixmapFromFile(XStarRoll * p,char * filename,int * w,int * h)603 Pixmap MakePixmapFromFile(XStarRoll * p, char * filename, int * w, int * h)
604 {
605 XpmAttributes attr;
606 Pixmap pix, mask;
607
608 attr.colormap = p->colormap;
609 attr.closeness = 40000;
610 attr.valuemask = XpmSize | XpmReturnPixels | XpmColormap | XpmCloseness;
611 XpmReadFileToPixmap(p->display, p->toplevel_window, filename,
612 &pix, &mask, &attr);
613 *w = attr.width;
614 *h = attr.height;
615 return (pix);
616 }
617
MakePixmapFromData(XStarRoll * p,char ** string,int * w,int * h)618 Pixmap MakePixmapFromData(XStarRoll * p, char ** string, int * w, int * h)
619 {
620 XpmAttributes attr;
621 Pixmap pix, mask;
622
623 attr.colormap = p->colormap;
624 attr.closeness = 40000;
625 attr.valuemask = XpmSize | XpmReturnPixels | XpmColormap | XpmCloseness;
626 XpmCreatePixmapFromData(p->display, p->toplevel_window, string,
627 &pix, &mask, &attr);
628 *w = attr.width;
629 *h = attr.height;
630 return (pix);
631 }
632
633 /*****************************************************************************/
634 /* Functions for XStarRoll. */
635 /*****************************************************************************/
636
SetDefaultValues(XStarRoll * p)637 void SetDefaultValues(XStarRoll * p)
638 {
639 p->canvas_width = DEFAULT_CANVAS_WIDTH;
640 p->canvas_height = DEFAULT_CANVAS_HEIGHT;
641 p->source_width = DEFAULT_SOURCE_WIDTH;
642 p->width = DEFAULT_WIDTH;
643 p->length_x = DEFAULT_LENGTH_X;
644 p->length_y = DEFAULT_LENGTH_Y;
645 p->space = DEFAULT_SPACE;
646 p->scroll = DEFAULT_SCROLL;
647 p->start = DEFAULT_START;
648 p->wait = DEFAULT_WAIT;
649 p->root_flag = DEFAULT_ROOT_FLAG;
650 p->draw_flag = DEFAULT_DRAW_FLAG;
651 p->quit_flag = DEFAULT_QUIT_FLAG;
652 p->blur_flag = DEFAULT_BLUR_FLAG;
653 p->font_name = DEFAULT_FONT_NAME;
654 p->title_name = DEFAULT_TITLE_NAME;
655 }
656
ConnectDisplay(XStarRoll * p,int * argc,char ** argv)657 void ConnectDisplay(XStarRoll * p, int * argc, char ** argv)
658 {
659 int n;
660 Arg args[10];
661
662 n = 0;
663 XtSetArg(args[n], XtNwidth, p->canvas_width); n++;
664 XtSetArg(args[n], XtNheight, p->canvas_height); n++;
665 p->toplevel = XtAppInitialize(&(p->app_context), "XStarRoll",
666 NULL, 0, argc, argv, NULL, args, n);
667 }
668
Help()669 void Help()
670 {
671 printf("%s", help_string);
672 exit (0);
673 }
674
DeleteParameter(int * c,char ** v,int i)675 void DeleteParameter(int * c, char ** v, int i)
676 {
677 (*c)--;
678 for (; i < (*c); i++)
679 v[i] = v[i + 1];
680 }
681
SetFlagOn(int * c,char ** v,int i)682 int SetFlagOn(int * c, char ** v, int i)
683 {
684 DeleteParameter(c, v, i);
685 return (ON);
686 }
687
SetFlagOff(int * c,char ** v,int i)688 int SetFlagOff(int * c, char ** v, int i)
689 {
690 DeleteParameter(c, v, i);
691 return (OFF);
692 }
693
SetFlag(int * c,char ** v,int i,int f)694 int SetFlag(int * c, char ** v, int i, int f)
695 {
696 DeleteParameter(c, v, i);
697 return (f);
698 }
699
GetIntValueFromParameter(int * c,char ** v,int i,int value)700 int GetIntValueFromParameter(int * c, char ** v, int i, int value)
701 {
702 int a;
703
704 DeleteParameter(c, v, i);
705 if (i < *c) {
706 a = atoi(v[i]);
707 DeleteParameter(c, v, i);
708 return (a);
709 }
710 return (value);
711 }
712
GetStringValueFromParameter(int * c,char ** v,int i,char * value)713 char * GetStringValueFromParameter(int * c, char ** v, int i, char * value)
714 {
715 char * a;
716
717 DeleteParameter(c, v, i);
718 if (i < *c) {
719 a = v[i];
720 DeleteParameter(c, v, i);
721 return (a);
722 }
723 return (value);
724 }
725
ReadParameters(XStarRoll * p,int * c,char ** v)726 void ReadParameters(XStarRoll * p, int * c, char ** v)
727 {
728 int i = 1;
729
730 while (i < *c) {
731 if (!strcmp(v[i], "--")) while (i < *c) DeleteParameter(c, v, i);
732 else if ( (!strcmp(v[i], "-help")) || (!strcmp(v[i], "-h")) ) Help();
733 else if ( (!strcmp(v[i], "-root")) || (!strcmp(v[i], "-r")) )
734 p->root_flag = SetFlagOn(c, v, i);
735 else if ( (!strcmp(v[i], "-noroot")) || (!strcmp(v[i], "-nr")) )
736 p->root_flag = SetFlagOff(c, v, i);
737 else if ( (!strcmp(v[i], "-quit")) || (!strcmp(v[i], "-q")) )
738 p->quit_flag = SetFlagOn(c, v, i);
739 else if ( (!strcmp(v[i], "-noquit")) || (!strcmp(v[i], "-nq")) )
740 p->quit_flag = SetFlagOff(c, v, i);
741 else if ( (!strcmp(v[i], "-blur")) || (!strcmp(v[i], "-b")) )
742 p->blur_flag = SetFlagOn(c, v, i);
743 else if ( (!strcmp(v[i], "-noblur")) || (!strcmp(v[i], "-nb")) )
744 p->blur_flag = SetFlagOff(c, v, i);
745 else if (!strcmp(v[i], "-fill"))
746 p->blur_flag = SetFlag(c, v, i, 2);
747 else if ( (!strcmp(v[i], "-source-width")) || (!strcmp(v[i], "-sw")) )
748 p->source_width = GetIntValueFromParameter(c, v, i, p->source_width);
749 else if ( (!strcmp(v[i], "-width")) || (!strcmp(v[i], "-w")) )
750 p->width = GetIntValueFromParameter(c, v, i, p->width);
751 else if ( (!strcmp(v[i], "-length-x")) || (!strcmp(v[i], "-lx")) )
752 p->length_x = GetIntValueFromParameter(c, v, i, p->length_x);
753 else if ( (!strcmp(v[i], "-length-y")) || (!strcmp(v[i], "-ly")) )
754 p->length_y = GetIntValueFromParameter(c, v, i, p->length_y);
755 else if ( (!strcmp(v[i], "-space")) || (!strcmp(v[i], "-sp")) )
756 p->space = GetIntValueFromParameter(c, v, i, p->space);
757 else if ( (!strcmp(v[i], "-scroll")) || (!strcmp(v[i], "-sc")) )
758 p->scroll = GetIntValueFromParameter(c, v, i, p->scroll);
759 else if ( (!strcmp(v[i], "-start")) || (!strcmp(v[i], "-st")) )
760 p->start = (long int)GetIntValueFromParameter(c, v, i, (int)(p->start));
761 else if ( (!strcmp(v[i], "-wait")) || (!strcmp(v[i], "-wt")) )
762 p->wait = GetIntValueFromParameter(c, v, i, p->wait);
763 else if ( (!strcmp(v[i], "-font")) || (!strcmp(v[i], "-fn")) )
764 p->font_name = GetStringValueFromParameter(c, v, i, p->font_name);
765 else if ( (!strcmp(v[i], "-name")) || (!strcmp(v[i], "-title")) )
766 p->title_name = GetStringValueFromParameter(c, v, i, p->title_name);
767 else i++;
768 }
769 }
770
InitializeParameters(XStarRoll * p,int * argc,char ** argv)771 void InitializeParameters(XStarRoll * p, int * argc, char ** argv)
772 {
773 SetDefaultValues(p);
774 ReadParameters(p, argc, argv);
775 ConnectDisplay(p, argc, argv);
776 }
777
InitializeDisplay(XStarRoll * p)778 void InitializeDisplay(XStarRoll * p)
779 {
780 int n;
781 Arg args[10];
782
783 p->display = XtDisplay(p->toplevel);
784 p->screen = DefaultScreen(p->display);
785 p->colormap = XDefaultColormap(p->display, p->screen);
786 p->root_window = RootWindow(p->display, p->screen);
787 p->depth = DefaultDepth(p->display, p->screen);
788 p->canvas = XtCreateManagedWidget("", labelWidgetClass, p->toplevel,
789 NULL, 0);
790 n = 0;
791 XtSetArg(args[n], XtNforeground, &(p->foreground_color)); n++;
792 XtSetArg(args[n], XtNbackground, &(p->background_color)); n++;
793 XtGetValues(p->canvas, args, n);
794 if (p->root_flag == ON) {
795 p->toplevel_window = p->root_window;
796 p->canvas_window = p->root_window;
797 p->canvas_width = DisplayWidth(p->display, p->screen);
798 p->canvas_height = DisplayHeight(p->display, p->screen);
799 } else {
800 XtRealizeWidget(p->toplevel);
801 p->toplevel_window = XtWindow(p->toplevel);
802 p->canvas_window = XtWindow(p->canvas);
803 n = 0;
804 XtSetArg(args[n], XtNwidth, &(p->canvas_width)); n++;
805 XtSetArg(args[n], XtNheight, &(p->canvas_height)); n++;
806 XtGetValues(p->toplevel, args, n);
807 }
808 p->canvas_pixmap = XCreatePixmap(p->display, p->toplevel_window,
809 p->canvas_width, p->canvas_height,
810 p->depth);
811 p->font = XLoadFont(p->display, p->font_name);
812 p->font_struct = XQueryFont(p->display, p->font);
813 if (p->source_width == 0)
814 p->source_width = p->width *
815 ((p->font_struct->max_bounds.width +
816 p->font_struct->min_bounds.width) / 2);
817 if (p->length_x < 1) p->length_x = p->source_width;
818 XFlush(p->display);
819 }
820
InitializeGC(XStarRoll * p)821 void InitializeGC(XStarRoll * p)
822 {
823 p->gc_foreground = XCreateGC(p->display, p->toplevel_window, 0, NULL);
824 p->gc_background = XCreateGC(p->display, p->toplevel_window, 0, NULL);
825 p->gc_copy = XCreateGC(p->display, p->toplevel_window, 0, NULL);
826 XSetForeground(p->display, p->gc_foreground, p->foreground_color);
827 XSetBackground(p->display, p->gc_foreground, p->background_color);
828 XSetForeground(p->display, p->gc_background, p->background_color);
829 XSetBackground(p->display, p->gc_background, p->background_color);
830 XSetFont(p->display, p->gc_foreground, p->font);
831 XSetFunction(p->display, p->gc_copy, GXcopy);
832 XSetFillRule(p->display, p->gc_foreground, WindingRule);
833 XSetFillRule(p->display, p->gc_background, WindingRule);
834 XSetLineAttributes(p->display, p->gc_foreground, 0,
835 LineSolid, CapNotLast ,JoinMiter);
836 }
837
GetCharFromPointer(void ** pp,int flag)838 int GetCharFromPointer(void ** pp, int flag)
839 {
840 int c;
841 char ** cpp;
842 FILE ** fpp;
843
844 if (flag == READ_FROM_STRING) {
845 cpp = (char **)pp;
846 c = **cpp;
847 if (c == '\0') c = EOF;
848 else (*cpp)++;
849 } else if (flag == READ_FROM_FILE) {
850 fpp = (FILE **)pp;
851 c = fgetc(*fpp);
852 }
853 return (c);
854 }
855
SearchGCBufferFromPixel(XStarRoll * p,unsigned long int pixel)856 GCBuffer * SearchGCBufferFromPixel(XStarRoll * p, unsigned long int pixel)
857 {
858 GCBuffer * gp;
859
860 gp = p->gc_buffer->start;
861 while (gp != (GCBuffer *)NULL)
862 if (gp->pixel == pixel) return (gp);
863 else gp = gp->next;
864 return ((GCBuffer *)NULL);
865 }
866
GetGCBufferFromPixel(XStarRoll * p,unsigned long int pixel)867 GCBuffer * GetGCBufferFromPixel(XStarRoll * p, unsigned long int pixel)
868 {
869 GCBuffer * gp;
870
871 gp = SearchGCBufferFromPixel(p, pixel);
872 if (gp == (GCBuffer *)NULL) {
873 gp = CreateGCBuffer(p->display, p->toplevel_window, pixel);
874 gp = AddGCBufferToTop(p->gc_buffer, gp);
875 } else
876 gp = MoveGCBufferToTop(p->gc_buffer, gp);
877 return (gp);
878 }
879
MakeSourceDataFromPixmap(XStarRoll * p,Pixmap pixmap,int w,int h)880 void MakeSourceDataFromPixmap(XStarRoll * p, Pixmap pixmap, int w, int h)
881 {
882 XImage * image;
883 SourceData * sp;
884 GCBuffer * gp;
885 int x, y;
886 unsigned long int pixel;
887
888 image = XGetImage(p->display, pixmap, 0, 0, w, h, AllPlanes, XYPixmap);
889 for (y = 0; y < h; y++) {
890 for (x = 0; x < w; x++) {
891 pixel = XGetPixel(image, x, y);
892 if ( (x == 0) || (pixel != sp->gc_buffer->pixel) ) {
893 gp = GetGCBufferFromPixel(p, pixel);
894 sp = CreateSourceData(1, gp, 1, 0);
895 sp = AddSourceDataToBottom(p->source_data, sp);
896 } else {
897 (sp->length)++;
898 (sp->x)++;
899 }
900 }
901 sp->x -= w;
902 (sp->y)++;
903 }
904 XDestroyImage(image);
905 }
906
MakeSourceDataFromFontData(XStarRoll * p,char * str,int n,int f)907 void MakeSourceDataFromFontData(XStarRoll * p, char * str, int n, int f)
908 {
909 SourceData * sp;
910 GCBuffer * fore_gp;
911 GCBuffer * back_gp;
912 GCBuffer * gp;
913 FontDataList * fp;
914 int i, j, off, len;
915 unsigned char * string;
916 unsigned char pixel;
917
918 string = (unsigned char *)str;
919 fore_gp = GetGCBufferFromPixel(p, p->foreground_pixel);
920 back_gp = GetGCBufferFromPixel(p, p->background_pixel);
921
922 if (f == ON) {
923 off = (p->source_width - XTextWidth(p->font_struct, str, n)) / 2;
924 sp = CreateSourceData(0, back_gp, off, 0);
925 sp = AddSourceDataToBottom(p->source_data, sp);
926 }
927
928 if (n == 0) {
929 sp = CreateSourceData(0, back_gp, 0, p->font_height);
930 sp = AddSourceDataToBottom(p->source_data, sp);
931 } else {
932 for (i = 0; i < p->font_height; i++) {
933 len = 0;
934 sp = (SourceData *)NULL;
935 for (j = 0; j < n; j++) {
936 fp = p->font_data[(int)(string[j])].list_array[i];
937 if ( (sp != (SourceData *)NULL) && (fp->pixel == pixel) ) {
938 sp->x += fp->length;
939 sp->length += fp->length;
940 len += fp->length;
941 fp = fp->next;
942 }
943 while (fp != (FontDataList *)NULL) {
944 pixel = fp->pixel;
945 if (pixel == ON) gp = fore_gp;
946 else gp = back_gp;
947 sp = CreateSourceData((int)(fp->length), gp, (int)(fp->length), 0);
948 sp = AddSourceDataToBottom(p->source_data, sp);
949 len += fp->length;
950 fp = fp->next;
951 }
952 }
953 sp = CreateSourceData(0, back_gp, - len, 1);
954 sp = AddSourceDataToBottom(p->source_data, sp);
955 }
956 }
957
958 if (f == ON) {
959 sp = CreateSourceData(0, back_gp, - off, p->space);
960 sp = AddSourceDataToBottom(p->source_data, sp);
961 } else if (p->space != 0) {
962 sp = CreateSourceData(0, back_gp, 0, p->space);
963 sp = AddSourceDataToBottom(p->source_data, sp);
964 }
965 }
966
MakeFontData(XStarRoll * p,int c)967 void MakeFontData(XStarRoll * p, int c)
968 {
969 int x, y, w, h;
970 char string[10];
971 Pixmap pixmap;
972 XImage * image;
973 unsigned char pixel;
974 FontDataList * fp;
975
976 string[0] = (char)c;
977 string[1] = '\0';
978 p->font_data[c].width = w = XTextWidth(p->font_struct, string, 1);
979 h = p->font_height;
980 p->font_data[c].list_array =
981 (FontDataList **)malloc(sizeof(FontDataList *) * h);
982 pixmap = XCreatePixmap(p->display, p->toplevel_window, w, h, p->depth);
983 XFillRectangle(p->display, pixmap, p->gc_background, 0, 0, w, h);
984 XDrawString(p->display, pixmap, p->gc_foreground, 0, p->font_struct->ascent,
985 string, 1);
986 image = XGetImage(p->display, pixmap, 0, 0, w, h, AllPlanes, XYPixmap);
987 for (y = 0; y < h; y++) {
988 for (x = 0; x < w; x++) {
989 if (XGetPixel(image, x, y) == p->background_pixel) pixel = OFF;
990 else pixel = ON;
991 if ( (x == 0) || (pixel != fp->pixel) ) {
992 if (x == 0)
993 fp = p->font_data[c].list_array[y] =
994 (FontDataList *)malloc(sizeof(FontDataList));
995 else {
996 fp->next = (FontDataList *)malloc(sizeof(FontDataList));
997 fp = fp->next;
998 }
999 fp->pixel = pixel;
1000 fp->length = 1;
1001 fp->next = (FontDataList *)NULL;
1002 } else (fp->length)++;
1003 }
1004 }
1005 XDestroyImage(image);
1006 XFreePixmap(p->display, pixmap);
1007 }
1008
WriteLetters(XStarRoll * p,void * pointer,int flag)1009 void WriteLetters(XStarRoll * p, void * pointer, int flag)
1010 {
1011 int i, c;
1012 int center_flag = OFF;
1013
1014 tmp_buffer[i = 0] = '\0';
1015 while ((c = GetCharFromPointer(&pointer, flag)) != EOF) {
1016 if (c == '\n') {
1017 MakeSourceDataFromFontData(p, tmp_buffer, i, center_flag);
1018 tmp_buffer[i = 0] = '\0';
1019 center_flag = OFF;
1020 }
1021 else if ( (c == '\t') && (i == 0) ) center_flag = ON;
1022 else if ( (c == '\b') && (i > 0) ) tmp_buffer[--i] = '\0';
1023 else if (c == 0x1B)
1024 while ( (((c = GetCharFromPointer(&pointer, flag)) < 'A') || (c > 'Z'))
1025 && ((c < 'a') || (c > 'z')) && (c != EOF) );
1026 else if (c < ' ');
1027 else {
1028 if (p->font_data[c].list_array == (FontDataList **)NULL)
1029 MakeFontData(p, c);
1030 if (i < TMP_BUFFER_SIZE - 1) {
1031 tmp_buffer[i++] = (char)c;
1032 tmp_buffer[i] = '\0';
1033 }
1034 if (!strcmp(tmp_buffer, "#center")) {
1035 tmp_buffer[i = 0] = '\0';
1036 center_flag = ON;
1037 } else if (XTextWidth(p->font_struct, tmp_buffer, i) > p->source_width) {
1038 tmp_buffer[--i] = '\0';
1039 MakeSourceDataFromFontData(p, tmp_buffer, i, center_flag);
1040 tmp_buffer[i = 0] = (char)c;
1041 tmp_buffer[++i] = '\0';
1042 }
1043 }
1044 }
1045 if (i > 0) MakeSourceDataFromFontData(p, tmp_buffer, i, center_flag);
1046 }
1047
DrawPixmap(XStarRoll * p,char * filename)1048 void DrawPixmap(XStarRoll * p, char * filename)
1049 {
1050 int w, h, off;
1051 Pixmap pixmap;
1052 SourceData * sp;
1053 GCBuffer * back_gp;
1054
1055 pixmap = MakePixmapFromFile(p, filename, &w, &h);
1056 off = (p->source_width - w) / 2;
1057 back_gp = GetGCBufferFromPixel(p, p->background_pixel);
1058 sp = CreateSourceData(0, back_gp, (short int)off, 0);
1059 sp = AddSourceDataToBottom(p->source_data, sp);
1060 MakeSourceDataFromPixmap(p, pixmap, w, h);
1061 sp = CreateSourceData(0, back_gp, (short int)(- off), 0);
1062 sp = AddSourceDataToBottom(p->source_data, sp);
1063 XFreePixmap(p->display, pixmap);
1064 }
1065
OutputMessage(XStarRoll * p,char * string)1066 void OutputMessage(XStarRoll * p, char * string)
1067 {
1068 static y = 0;
1069
1070 y += p->font_struct->ascent + p->font_struct->descent + p->space;
1071 XDrawString(p->display, p->canvas_pixmap, p->gc_foreground,
1072 p->font_struct->max_bounds.width, y, string, strlen(string));
1073 XCopyArea(p->display, p->canvas_pixmap, p->canvas_window, p->gc_copy,
1074 0, 0, p->canvas_width, p->canvas_height, 0, 0);
1075 XFlush(p->display);
1076 }
1077
FreeFontData(XStarRoll * p)1078 void FreeFontData(XStarRoll * p)
1079 {
1080 int i, j;
1081 FontDataList * fp;
1082 FontDataList * fp_next;
1083
1084 for (i = 0; i < 256; i++) {
1085 if (p->font_data[i].list_array != (FontDataList **)NULL) {
1086 for (j = 0; j < p->font_height; j++) {
1087 fp = p->font_data[i].list_array[j];
1088 while (fp != (FontDataList *)NULL) {
1089 fp_next = fp->next;
1090 free(fp);
1091 fp = fp_next;
1092 }
1093 }
1094 free(p->font_data[i].list_array);
1095 }
1096 }
1097 free(p->font_data);
1098 }
1099
GetBlackAndWhitePixel(XStarRoll * p)1100 void GetBlackAndWhitePixel(XStarRoll * p)
1101 {
1102 Pixmap pix;
1103 XImage * image;
1104
1105 pix = XCreatePixmap(p->display, p->toplevel_window, 2, 1, p->depth);
1106 XDrawPoint(p->display, pix, p->gc_foreground, 0, 0);
1107 XDrawPoint(p->display, pix, p->gc_background, 1, 0);
1108 image = XGetImage(p->display, pix, 0, 0, 2, 1, AllPlanes, XYPixmap);
1109 p->foreground_pixel = XGetPixel(image, 0, 0);
1110 p->background_pixel = XGetPixel(image, 1, 0);
1111 XDestroyImage(image);
1112 XFreePixmap(p->display, pix);
1113 }
1114
InitializeStarRoll(XStarRoll * p,int * argc,char ** argv)1115 void InitializeStarRoll(XStarRoll * p, int * argc, char ** argv)
1116 {
1117 FILE * fp;
1118 int i;
1119
1120 p->gc_buffer = InitializeGCBufferList();
1121 p->source_data = InitializeSourceDataList();
1122 p->font_data = (FontData *)malloc(sizeof(FontData) * 256);
1123 for (i = 0; i < 256; i++) p->font_data[i].list_array = (FontDataList **)NULL;
1124 p->font_height = p->font_struct->ascent + p->font_struct->descent;
1125
1126 GetBlackAndWhitePixel(p);
1127
1128 XFillRectangle(p->display, p->canvas_pixmap, p->gc_background, 0, 0,
1129 p->canvas_width, p->canvas_height);
1130 OutputMessage(p, "Now initializing XStarRoll and making data.");
1131 OutputMessage(p, "Please wait for some minutes...");
1132
1133 while (*argc > 1) {
1134 if (!strcmp(argv[1], "-")) {
1135 OutputMessage(p, "Writing letters from the standard input.");
1136 if (isatty(fileno(stdin)) != 0)
1137 OutputMessage(p, "Please input letters and hit Ctrl-D.");
1138 WriteLetters(p, stdin, READ_FROM_FILE);
1139 OutputMessage(p, "Done.");
1140 DeleteParameter(argc, argv, 1);
1141 } else if ((fp = fopen(argv[1], "rt")) == NULL) {
1142 OutputMessage(p, "Writing letters.");
1143 WriteLetters(p, argv[1], READ_FROM_STRING);
1144 OutputMessage(p, "Done.");
1145 DeleteParameter(argc, argv, 1);
1146 } else {
1147 if ( (fgets(tmp_buffer, 10, fp) != NULL) &&
1148 (!strcmp(tmp_buffer, "/* XPM */")) ) {
1149 fclose(fp);
1150 strcpy(tmp_buffer, "Drawing a pixmap \"");
1151 strncat(tmp_buffer, argv[1], TMP_BUFFER_SIZE - 100);
1152 strcat(tmp_buffer, "\".");
1153 OutputMessage(p, tmp_buffer);
1154 DrawPixmap(p, argv[1]);
1155 OutputMessage(p, "Done.");
1156 DeleteParameter(argc, argv, 1);
1157 } else {
1158 fclose(fp);
1159 strcpy(tmp_buffer, "Writing letters in a file \"");
1160 strncat(tmp_buffer, argv[1], TMP_BUFFER_SIZE - 100);
1161 strcat(tmp_buffer, "\".");
1162 OutputMessage(p, tmp_buffer);
1163 fp = fopen(argv[1], "rt");
1164 WriteLetters(p, fp, READ_FROM_FILE);
1165 OutputMessage(p, "Done.");
1166 fclose(fp);
1167 DeleteParameter(argc, argv, 1);
1168 }
1169 }
1170 }
1171
1172 if ( (isatty(fileno(stdin)) == 0) && (feof(stdin) == 0) ){
1173 OutputMessage(p, "Writing letters from the standard input.");
1174 WriteLetters(p, stdin, READ_FROM_FILE);
1175 OutputMessage(p, "Done.");
1176 }
1177 if (p->source_data->start == (SourceData *)NULL) {
1178 OutputMessage(p, "Writing default letters.");
1179 WriteLetters(p, help_string, READ_FROM_STRING);
1180 OutputMessage(p, "Done.");
1181 }
1182 FreeFontData(p);
1183 OutputMessage(p, "Now starting XStarRoll!");
1184 sleep(1);
1185 }
1186
Quit(XStarRoll * p)1187 void Quit(XStarRoll * p)
1188 {
1189 FreeSourceDataList(p->source_data);
1190 FreeGCBufferList(p->display, p->gc_buffer);
1191 XFreeGC(p->display, p->gc_foreground);
1192 XFreeGC(p->display, p->gc_background);
1193 XFreeGC(p->display, p->gc_copy);
1194 XFreePixmap(p->display, p->canvas_pixmap);
1195 XFreePixmap(p->display, p->icon_pixmap);
1196 XtUnmanageChild(p->canvas);
1197 XtDestroyWidget(p->canvas);
1198 XtDestroyWidget(p->toplevel);
1199 exit (0);
1200 }
1201
PushKey(Widget w,XtPointer pp,XEvent * event,Boolean * dispatch)1202 void PushKey(Widget w, XtPointer pp, XEvent * event, Boolean * dispatch)
1203 {
1204 XStarRoll * p;
1205 KeySym ks;
1206
1207 p = (XStarRoll *)pp;
1208 if (event->type == KeyPress) {
1209 ks = XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 0);
1210 if (ks == XK_q ) Quit(p);
1211 else if (ks == XK_s ) p->start = 0;
1212 else if (ks == XK_n ) (p->start)++;
1213 else if (ks == XK_p ) (p->start)--;
1214 else if (ks == XK_Page_Down) (p->start) += 10;
1215 else if (ks == XK_Page_Up ) (p->start) -= 10;
1216 else if (ks == XK_a ) (p->scroll)++;
1217 else if (ks == XK_d ) (p->scroll)--;
1218 else if (ks == XK_Down ) (p->length_y)++;
1219 else if (ks == XK_Up ) {if (p->length_y > 1) (p->length_y)--;}
1220 else if (ks == XK_Right ) (p->length_x)++;
1221 else if (ks == XK_Left ) {if (p->length_x > 1) (p->length_x)--;}
1222 p->draw_flag = ON;
1223 }
1224 }
1225
ExposeCanvas(Widget w,XtPointer pp,XEvent * event,Boolean * dispatch)1226 void ExposeCanvas(Widget w, XtPointer pp, XEvent * event, Boolean * dispatch)
1227 {
1228 XStarRoll * p;
1229
1230 p = (XStarRoll *)pp;
1231 if (event->type == Expose)
1232 XSetWindowBackgroundPixmap(p->display, p->canvas_window, p->canvas_pixmap);
1233 XClearWindow(p->display, p->canvas_window);
1234 /*
1235 XCopyArea(p->display, p->canvas_pixmap, p->canvas_window, p->gc_copy,
1236 event->xexpose.x, event->xexpose.y,
1237 event->xexpose.width, event->xexpose.height,
1238 event->xexpose.x, event->xexpose.y);
1239 */
1240 }
1241
ResizeCanvas(XStarRoll * p)1242 void ResizeCanvas(XStarRoll * p)
1243 {
1244 int i, n;
1245 Arg args[10];
1246
1247 n = 0;
1248 XtSetArg(args[n], XtNwidth, &(p->canvas_width)); n++;
1249 XtSetArg(args[n], XtNheight, &(p->canvas_height)); n++;
1250 XtGetValues(p->toplevel, args, n);
1251 XResizeWindow(p->display, p->canvas_window,
1252 p->canvas_width, p->canvas_height);
1253 XFreePixmap(p->display, p->canvas_pixmap);
1254 p->canvas_pixmap = XCreatePixmap(p->display, p->toplevel_window,
1255 p->canvas_width, p->canvas_height,
1256 p->depth);
1257 p->draw_flag = ON;
1258 }
1259
CanvasEvent(Widget w,XtPointer pp,XEvent * event,Boolean * dispatch)1260 void CanvasEvent(Widget w, XtPointer pp, XEvent * event, Boolean * dispatch)
1261 {
1262 XStarRoll * p;
1263
1264 p = (XStarRoll *)pp;
1265 if (event->type == ConfigureNotify) ResizeCanvas(p);
1266 else if (event->type == ClientMessage) {
1267 if ( (event->xclient.message_type == p->atom_1) &&
1268 (event->xclient.data.l[0] == p->atom_2) ) Quit(p);
1269 }
1270 }
1271
AddEvents(XStarRoll * p)1272 void AddEvents(XStarRoll * p)
1273 {
1274 XtAddEventHandler(p->toplevel, ExposureMask, False, ExposeCanvas, p);
1275 if (p->root_flag == OFF) {
1276 XtAddEventHandler(p->toplevel, KeyPressMask, False, PushKey, p);
1277 XtAddEventHandler(p->toplevel, StructureNotifyMask, True, CanvasEvent, p);
1278 }
1279 }
1280
SetIcon(XStarRoll * p)1281 void SetIcon(XStarRoll * p)
1282 {
1283 XWMHints wmh;
1284
1285 if (p->root_flag == OFF) {
1286 p->icon_pixmap = MakePixmapFromData(p, XSTARROLL_ICON,
1287 &(p->icon_width), &(p->icon_height));
1288 wmh.flags = IconPixmapHint;
1289 wmh.icon_pixmap = p->icon_pixmap;
1290 XSetWMHints(p->display, p->toplevel_window, &wmh);
1291 }
1292 }
1293
SetWindowAttributes(XStarRoll * p)1294 void SetWindowAttributes(XStarRoll * p)
1295 {
1296 XWMHints wmhints;
1297
1298 if (p->root_flag == OFF) {
1299 XtSetSensitive(p->toplevel, True);
1300 XtSetSensitive(p->canvas, True);
1301
1302 /*
1303 XSelectInput(p->display, p->canvas_window,
1304 KeyPressMask | ExposureMask);
1305 XSelectInput(p->display, p->toplevel_window, StructureNotifyMask);
1306 */
1307
1308 wmhints.input = True;
1309 XSetWMHints(p->display, p->toplevel_window, &wmhints);
1310 p->atom_1 = XInternAtom(p->display, "WM_PROTOCOLS", False);
1311 p->atom_2 = XInternAtom(p->display, "WM_DELETE_WINDOW", False);
1312 XSetWMProtocols(p->display, p->toplevel_window, &(p->atom_2), 1);
1313 XStoreName(p->display, p->toplevel_window, p->title_name);
1314 XSetIconName(p->display, p->toplevel_window, p->title_name);
1315 SetIcon(p);
1316 }
1317 }
1318
GetCanvasPointY(XStarRoll * p,long int y)1319 double GetCanvasPointY(XStarRoll * p, long int y)
1320 {
1321 return (((double)(p->length_y) * p->canvas_height) / (y + p->length_y));
1322 }
1323
GetCanvasPointX(XStarRoll * p,long int x,double canvas_y)1324 double GetCanvasPointX(XStarRoll * p, long int x, double canvas_y)
1325 {
1326 return (canvas_y * (x - p->source_width / 2) * p->canvas_width /
1327 (p->canvas_height * p->length_x) + p->canvas_width / 2);
1328 }
1329
DrawCanvasBlurred(XStarRoll * p)1330 void DrawCanvasBlurred(XStarRoll * p)
1331 {
1332 long int x, y;
1333 short int canvas_iy0, canvas_iy1;
1334 double canvas_dy0, canvas_dy1;
1335 XPoint points[4];
1336 SourceData * sp;
1337
1338 x = y = 0;
1339 sp = p->source_data->start;
1340 canvas_dy0 = GetCanvasPointY(p, p->start - y);
1341 canvas_dy1 = GetCanvasPointY(p, p->start - y + 1);
1342 canvas_iy0 = (short int)(canvas_dy0 + 0.5);
1343 canvas_iy1 = (short int)(canvas_dy1 + 0.5);
1344
1345 while ( (y <= p->start) && (sp != (SourceData *)NULL) ) {
1346 if (sp->gc_buffer->pixel != p->background_pixel) {
1347 if (canvas_iy0 == canvas_iy1);
1348 else if (canvas_iy0 == canvas_iy1 + 1) {
1349 points[0].x = (short int)(GetCanvasPointX(p, x, canvas_dy0) + 0.5);
1350 points[3].x = (short int)(GetCanvasPointX(p, x + sp->length,
1351 canvas_dy0) + 0.5);
1352 if (points[0].x == points[3].x);
1353 else {
1354 points[1].x = (short int)
1355 (GetCanvasPointX(p, x, canvas_dy1) + 0.5);
1356 points[2].x = (short int)
1357 (GetCanvasPointX(p, x + sp->length, canvas_dy1) + 0.5);
1358 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1359 points[1].x, canvas_iy1, points[2].x, canvas_iy1);
1360 }
1361 } else {
1362 points[0].x = (short int)(GetCanvasPointX(p, x, canvas_dy0) + 0.5);
1363 points[3].x = (short int)(GetCanvasPointX(p, x + sp->length,
1364 canvas_dy0) + 0.5);
1365 if (points[0].x == points[3].x);
1366 else {
1367 points[1].x = (short int)
1368 (GetCanvasPointX(p, x, canvas_dy1) + 0.5);
1369 points[2].x = (short int)
1370 (GetCanvasPointX(p, x + sp->length, canvas_dy1) + 0.5);
1371 if (points[1].x == points[2].x) {
1372 points[0].y = canvas_iy0;
1373 points[1].y = canvas_iy1;
1374 points[2].x = points[3].x;
1375 points[2].y = canvas_iy0;
1376 XFillPolygon(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1377 points, 3, Convex, CoordModeOrigin);
1378 } else {
1379 points[0].y = points[3].y = canvas_iy0;
1380 points[1].y = points[2].y = canvas_iy1;
1381 XFillPolygon(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1382 points, 4, Convex, CoordModeOrigin);
1383 }
1384 }
1385 }
1386 }
1387 x += sp->x;
1388 if (sp->y != 0) {
1389 y += sp->y;
1390 if (y <= p->start) {
1391 canvas_dy0 = GetCanvasPointY(p, p->start - y);
1392 canvas_dy1 = GetCanvasPointY(p, p->start - y + 1);
1393 canvas_iy0 = (short int)(canvas_dy0 + 0.5);
1394 canvas_iy1 = (short int)(canvas_dy1 + 0.5);
1395 }
1396 }
1397 sp = sp->next;
1398 }
1399 }
1400
DrawCanvasNoBlurred(XStarRoll * p)1401 void DrawCanvasNoBlurred(XStarRoll * p)
1402 {
1403 long int x, y;
1404 short int canvas_iy0, canvas_iy1;
1405 double canvas_dy0, canvas_dy1;
1406 XPoint points[4];
1407 SourceData * sp;
1408
1409 x = y = 0;
1410 sp = p->source_data->start;
1411 canvas_dy0 = GetCanvasPointY(p, p->start - y);
1412 canvas_dy1 = GetCanvasPointY(p, p->start - y + 1);
1413 canvas_iy0 = (short int)(canvas_dy0 + 0.5);
1414 canvas_iy1 = (short int)(canvas_dy1 + 0.5);
1415
1416 while ( (y <= p->start) && (sp != (SourceData *)NULL) ) {
1417 if (sp->gc_buffer->pixel != p->background_pixel) {
1418 if (canvas_iy0 == canvas_iy1) {
1419 points[0].x = (short int)(GetCanvasPointX(p, x, canvas_dy0) + 0.5);
1420 points[1].x = (short int)(GetCanvasPointX(p, x, canvas_dy1) + 0.5);
1421 points[3].x = (short int)(GetCanvasPointX(p, x + sp->length,
1422 canvas_dy0) + 0.5);
1423 if (points[0].x == points[3].x)
1424 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1425 points[1].x, canvas_iy1);
1426 else if (points[0].x == points[3].x - 1)
1427 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1428 points[1].x, canvas_iy1);
1429 else {
1430 points[2].x = (short int)(GetCanvasPointX(p, x + sp->length,
1431 canvas_dy1) + 0.5);
1432 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1433 points[1].x, canvas_iy1, points[2].x, canvas_iy1);
1434 }
1435 } else if (canvas_iy0 == canvas_iy1 + 1) {
1436 points[0].x = (short int)(GetCanvasPointX(p, x, canvas_dy0) + 0.5);
1437 points[1].x = (short int)(GetCanvasPointX(p, x, canvas_dy1) + 0.5);
1438 points[3].x = (short int)(GetCanvasPointX(p, x + sp->length,
1439 canvas_dy0) + 0.5);
1440 if (points[0].x == points[3].x)
1441 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1442 points[1].x, canvas_iy1);
1443 else {
1444 points[2].x = (short int)(GetCanvasPointX(p, x + sp->length,
1445 canvas_dy1) + 0.5);
1446 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1447 points[1].x, canvas_iy1, points[2].x, canvas_iy1);
1448 }
1449 } else {
1450 points[0].x = (short int)(GetCanvasPointX(p, x, canvas_dy0) + 0.5);
1451 points[1].x = (short int)(GetCanvasPointX(p, x, canvas_dy1) + 0.5);
1452 points[3].x = (short int)(GetCanvasPointX(p, x + sp->length,
1453 canvas_dy0) + 0.5);
1454 if (points[0].x == points[3].x)
1455 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1456 points[1].x, canvas_iy1, points[0].x, canvas_iy0);
1457 else {
1458 points[2].x = (short int)(GetCanvasPointX(p, x + sp->length,
1459 canvas_dy1) + 0.5);
1460 if (points[1].x == points[2].x) {
1461 points[0].y = canvas_iy0;
1462 points[1].y = canvas_iy1;
1463 points[2].x = points[3].x;
1464 points[2].y = canvas_iy0;
1465 XFillPolygon(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1466 points, 3, Convex, CoordModeOrigin);
1467 } else {
1468 points[0].y = points[3].y = canvas_iy0;
1469 points[1].y = points[2].y = canvas_iy1;
1470 XFillPolygon(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1471 points, 4, Convex, CoordModeOrigin);
1472 }
1473 }
1474 }
1475 }
1476 x += sp->x;
1477 if (sp->y != 0) {
1478 y += sp->y;
1479 if (y <= p->start) {
1480 canvas_dy0 = GetCanvasPointY(p, p->start - y);
1481 canvas_dy1 = GetCanvasPointY(p, p->start - y + 1);
1482 canvas_iy0 = (short int)(canvas_dy0 + 0.5);
1483 canvas_iy1 = (short int)(canvas_dy1 + 0.5);
1484 }
1485 }
1486 sp = sp->next;
1487 }
1488 }
1489
DrawCanvasFilled(XStarRoll * p)1490 void DrawCanvasFilled(XStarRoll * p)
1491 {
1492 long int x, y;
1493 short int canvas_iy0, canvas_iy1;
1494 double canvas_dy0, canvas_dy1;
1495 XPoint points[4];
1496 SourceData * sp;
1497
1498 x = y = 0;
1499 sp = p->source_data->start;
1500 canvas_dy0 = GetCanvasPointY(p, p->start - y);
1501 canvas_dy1 = GetCanvasPointY(p, p->start - y + 1);
1502 canvas_iy0 = (short int)(canvas_dy0 + 0.5);
1503 canvas_iy1 = (short int)(canvas_dy1 + 0.5);
1504
1505 while ( (y <= p->start) && (sp != (SourceData *)NULL) ) {
1506 if (sp->gc_buffer->pixel != p->background_pixel) {
1507 if (canvas_iy0 == canvas_iy1) {
1508 points[0].x = (short int)(GetCanvasPointX(p, x, canvas_dy0) + 0.5);
1509 points[1].x = (short int)(GetCanvasPointX(p, x, canvas_dy1) + 0.5);
1510 points[2].x = (short int)(GetCanvasPointX(p, x + sp->length,
1511 canvas_dy1) + 0.5);
1512 points[3].x = (short int)(GetCanvasPointX(p, x + sp->length,
1513 canvas_dy0) + 0.5);
1514 if (points[0].x == points[3].x) {
1515 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1516 points[0].x, canvas_iy0);
1517 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1518 points[1].x, canvas_iy1);
1519 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1520 points[2].x, canvas_iy1);
1521 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1522 points[3].x, canvas_iy0);
1523 } else {
1524 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1525 points[1].x, canvas_iy1, points[2].x, canvas_iy1);
1526 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1527 points[0].x, canvas_iy0, points[3].x, canvas_iy0);
1528 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1529 points[2].x, canvas_iy1);
1530 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1531 points[3].x, canvas_iy0);
1532 }
1533 } else if (canvas_iy0 == canvas_iy1 + 1) {
1534 points[0].x = (short int)(GetCanvasPointX(p, x, canvas_dy0) + 0.5);
1535 points[1].x = (short int)(GetCanvasPointX(p, x, canvas_dy1) + 0.5);
1536 points[2].x = (short int)(GetCanvasPointX(p, x + sp->length,
1537 canvas_dy1) + 0.5);
1538 points[3].x = (short int)(GetCanvasPointX(p, x + sp->length,
1539 canvas_dy0) + 0.5);
1540 if (points[0].x == points[3].x) {
1541 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1542 points[0].x, canvas_iy0);
1543 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1544 points[1].x, canvas_iy1);
1545 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1546 points[2].x, canvas_iy1);
1547 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1548 points[3].x, canvas_iy0);
1549 } else {
1550 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1551 points[1].x, canvas_iy1, points[2].x, canvas_iy1);
1552 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1553 points[0].x, canvas_iy0, points[3].x, canvas_iy0);
1554 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1555 points[2].x, canvas_iy1);
1556 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1557 points[3].x, canvas_iy0);
1558 }
1559 } else {
1560 points[0].x = (short int)(GetCanvasPointX(p, x, canvas_dy0) + 0.5);
1561 points[1].x = (short int)(GetCanvasPointX(p, x, canvas_dy1) + 0.5);
1562 points[2].x = (short int)(GetCanvasPointX(p, x + sp->length,
1563 canvas_dy1) + 0.5);
1564 points[3].x = (short int)(GetCanvasPointX(p, x + sp->length,
1565 canvas_dy0) + 0.5);
1566 if (points[0].x == points[3].x) {
1567 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1568 points[1].x, canvas_iy1, points[0].x, canvas_iy0);
1569 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1570 points[2].x, canvas_iy1, points[3].x, canvas_iy0);
1571 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1572 points[0].x, canvas_iy0);
1573 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1574 points[3].x, canvas_iy0);
1575 } else {
1576 if (points[1].x == points[2].x) {
1577 points[0].y = canvas_iy0;
1578 points[1].y = canvas_iy1;
1579 points[2].x = points[3].x;
1580 points[2].y = canvas_iy0;
1581 XFillPolygon(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1582 points, 3, Convex, CoordModeOrigin);
1583 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1584 points[0].x, canvas_iy0, points[2].x, canvas_iy0);
1585 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1586 points[1].x, canvas_iy1, points[2].x, canvas_iy0);
1587 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1588 points[2].x, canvas_iy0);
1589 } else {
1590 points[0].y = points[3].y = canvas_iy0;
1591 points[1].y = points[2].y = canvas_iy1;
1592 XFillPolygon(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1593 points, 4, Convex, CoordModeOrigin);
1594 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1595 points[0].x, canvas_iy0, points[3].x, canvas_iy0);
1596 XDrawLine(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1597 points[2].x, canvas_iy1, points[3].x, canvas_iy0);
1598 XDrawPoint(p->display, p->canvas_pixmap, sp->gc_buffer->gc,
1599 points[3].x, canvas_iy0);
1600 }
1601 }
1602 }
1603 }
1604 x += sp->x;
1605 if (sp->y != 0) {
1606 y += sp->y;
1607 if (y <= p->start) {
1608 canvas_dy0 = GetCanvasPointY(p, p->start - y);
1609 canvas_dy1 = GetCanvasPointY(p, p->start - y + 1);
1610 canvas_iy0 = (short int)(canvas_dy0 + 0.5);
1611 canvas_iy1 = (short int)(canvas_dy1 + 0.5);
1612 }
1613 }
1614 sp = sp->next;
1615 }
1616 }
1617
MainStarRoll(caddr_t pp)1618 Boolean MainStarRoll(caddr_t pp)
1619 {
1620 XStarRoll * p;
1621
1622 p = (XStarRoll *)pp;
1623 if (p->draw_flag == OFF) {
1624 usleep(100000);
1625 if (p->root_flag == ON) {
1626 sleep(5);
1627 p->draw_flag = ON;
1628 }
1629 } else {
1630 XFillRectangle(p->display, p->canvas_pixmap, p->gc_background, 0, 0,
1631 p->canvas_width, p->canvas_height);
1632 if (p->blur_flag == ON) DrawCanvasBlurred(p);
1633 else if (p->blur_flag == OFF) DrawCanvasNoBlurred(p);
1634 else DrawCanvasFilled(p);
1635 XSetWindowBackgroundPixmap(p->display, p->canvas_window, p->canvas_pixmap);
1636 XClearWindow(p->display, p->canvas_window);
1637 /*
1638 XCopyArea(p->display, p->canvas_pixmap, p->canvas_window, p->gc_copy,
1639 0, 0, p->canvas_width, p->canvas_height, 0, 0);
1640 */
1641 XFlush(p->display);
1642 p->draw_flag = OFF;
1643 if (p->quit_flag == ON) Quit(p);
1644 }
1645 if (p->scroll != 0) {
1646 p->start += p->scroll;
1647 p->draw_flag = ON;
1648 }
1649 usleep(100);
1650 usleep(p->wait);
1651 }
1652
main(int argc,char ** argv)1653 int main(int argc, char ** argv)
1654 {
1655 XStarRoll xstarroll;
1656
1657 InitializeParameters(&xstarroll, &argc, argv);
1658 InitializeDisplay(&xstarroll);
1659 InitializeGC(&xstarroll);
1660 SetWindowAttributes(&xstarroll);
1661 AddEvents(&xstarroll);
1662 InitializeStarRoll(&xstarroll, &argc, argv);
1663 XtAppAddWorkProc(xstarroll.app_context,(XtWorkProc)MainStarRoll,&xstarroll);
1664 XtAppMainLoop(xstarroll.app_context);
1665 }
1666
1667 /*****************************************************************************/
1668 /* End of Program. */
1669 /*****************************************************************************/
1670