1 /*
2 * @(#)main.c 1.2 01/03/85
3 *
4 * Main program for the SUN Gremlin picture editor.
5 *
6 * Many of the routines in SUN Gremlin are direct descendants of
7 * their counterparts in the original Gremlin written for the AED
8 * by Barry Roitblat.
9 *
10 * Mark Opperman (opcode@monet.BERKELEY)
11 *
12 */
13
14 #include <suntool/tool_hs.h>
15 #include <suntool/fullscreen.h>
16 #include <suntool/menu.h>
17 #include <suntool/wmgr.h>
18 #include <sunwindow/cms.h>
19 #include <sunwindow/win_ioctl.h>
20 #include <sun/fbio.h>
21 #include <sys/file.h>
22 #include <sys/ioctl.h>
23 #include <errno.h>
24 #include "gremlin.h"
25 #include "icondata.h"
26
27 #define RETAIN TRUE /* use retained subwindow for pix_sw */
28
29 #ifdef maybefaster
30 char *_image;
31 int _bytesperline, _maxx, _maxy;
32 #endif
33
34 /* database imports */
35
36 extern ELT *DBRead();
37 extern POINT *PTMakePoint();
38 extern FILE *POpen();
39
40 /* imports from startup.c */
41
42 extern STERROR;
43 extern STgremlinrc();
44
45 /* imports from menu.c */
46
47 extern MNDisplayMenu();
48 extern MNInitMenu();
49
50 /* graphics imports */
51
52 extern GRBlankGrid();
53 extern GRCurrentSet();
54 extern GRCurrentSetOn();
55 extern GRDisplayGrid();
56 extern GRFontInit();
57
58 /* imports from undodb.c */
59
60 extern UNForget();
61 extern UNELT *unlist;
62 extern UNELT *unback;
63
64 /* imports from long.c */
65
66 extern SHOWPOINTS;
67 extern char *Editfile;
68 extern CP();
69 extern LGQuit();
70 extern nop();
71
72 /* imports from short.c */
73
74 extern SHCommand();
75 extern SHUpdate();
76
77 /* imports from C */
78
79 extern char *malloc();
80 extern char *sprintf();
81 extern char *strcat();
82 extern char *strcpy();
83
84 /* imports from strings.c */
85
86 extern char version[];
87 extern char GLibrary[];
88
89 /* Declaration of Globals */
90
91 ELT arhead;
92 ELT *cset;
93 ELT *MEN[NUSER];
94 ELT *PICTURE;
95
96 POINT *BACKPOINT;
97 POINT MENPOINT[NUSER];
98 POINT *POINTLIST;
99
100 int Artmode = FALSE;
101 int Adjustment = NOADJ;
102 int Alignment = 4;
103 int CBRUSH = 5;
104 int CFONT = 1;
105 int CJUST = 0;
106 int CSIZE = 1;
107 int CSTIPPLE = 1;
108 int GravityOn = FALSE;
109 int Gridon = FALSE;
110 int Gridsize = 32;
111 int Orientation;
112 int SEQ = 0;
113 int CHANGED = FALSE;
114 int SEARCH = TRUE;
115 int SymbolicLines = 0;
116 int newfileformat = 1; /* 1=sungremlinfile, 0=gremlinfile */
117 int TOOLINSTALLED = 0;
118 int (*lastcommand)(); /* last command's routine pointer */
119 int lasttext = FALSE; /* TRUE if last command uses text */
120
121 float PX, PY; /* user point coordinate */
122 float Lastx, Lasty; /* last user point coordinate */
123
124 long timeon_ms = 580; /* current set flash on period */
125 long timeon_s = 0;
126 long timeoff_ms = 180; /* current set flash off period */
127 long timeoff_s = 0;
128
129 int FLASH_READY = 0; /* TRUE if time to flash current set */
130 int CsetOn = 1; /* TRUE if current set displayed */
131 static struct itimerval itime; /* for ALARM signals */
132 static alrm_sighandler();
133
134 int SUN_XORIGIN = 0; /* top left corner in gremlin coords */
135 int SUN_YORIGIN = 511;
136
137 static char SccsId [] = "@(#)main.c 1.2 (Berkeley) 01/03/85";
138
139 /* imports from menu.c */
140
141 extern menu_left();
142 extern menu_middle();
143 extern menu_right();
144 extern menu_winexit();
145 extern mouse_move();
146
147
148 /* imports from pix.c */
149
150 extern pix_left();
151 extern pix_middle();
152 extern pix_right();
153 extern pix_winexit();
154
155
156 /* imports from suntext.c */
157
158 extern text_left();
159 extern text_middle();
160 extern text_right();
161 extern text_winexit();
162 extern text_putvalue();
163 extern text_output();
164 extern TxInit();
165 extern TxPutMsg();
166
167 struct cursor kbd_cursor = {
168 4, 8, PIX_SRC^PIX_DST, &kbdcursor_pr
169 };
170
171 struct cursor main_cursor = {
172 0, 0, PIX_SRC^PIX_DST, &uparrow_pr
173 };
174
175 static struct cursor menu_cursor = {
176 3, 3, PIX_SRC^PIX_DST, &diamond_pr
177 };
178
179 static struct icon gremlin_icon = {
180 TOOL_ICONWIDTH, TOOL_ICONHEIGHT, NULL,
181 {0, 0, TOOL_ICONWIDTH, TOOL_ICONHEIGHT},
182 &gremlin_icon_pr, {0, 0, 0, 0}, NULL, NULL, 0
183 };
184
185 /* tool window stuff */
186
187 #define DEV_FB "/dev/fb"
188 struct tool *tool;
189 struct rect tool_size;
190 int tool_fd;
191 int rootfd;
192 char namestripe[256];
193 static tool_selected();
194 static init_tool();
195 static sigwinched();
196
197 /* for handling tool manager menu */
198
199 extern struct menu *wmgr_toolmenu;
200 extern struct menuitem *menu_display();
201
202 /* text subwindow */
203
204 struct toolsw *text_sw;
205 struct pixwin *text_pw;
206 struct rect text_size;
207 int text_fd;
208 struct pixfont *text_pf;
209 static init_text();
210 static text_selected();
211 static text_sighandler();
212
213 /* menu subwindow */
214
215 struct toolsw *menu_sw;
216 struct pixwin *menu_pw;
217 struct rect menu_size;
218 int menu_fd;
219 static init_menu();
220 static menu_selected();
221 static menu_sighandler();
222
223 /* pix subwindow */
224
225 struct toolsw *pix_sw;
226 struct pixwin *pix_pw;
227 struct rect pix_size;
228 int pix_fd;
229 static init_pix();
230 static pix_selected();
231 static pix_sighandler();
232 struct pixrect *cset_pr;
233 struct pixrect *scratch_pr;
234 struct pixrect *retained_pr;
235
236 /*
237 * This routine prints an error message in the text subwindow.
238 */
error(s)239 error(s)
240 char *s;
241 {
242 TxPutMsg(s);
243 }
244
245
main(argc,argv)246 main(argc, argv)
247 int argc;
248 char *argv[];
249 {
250 char *arg, *file, *gremlinrc, *usage;
251
252 file = "";
253 gremlinrc = "";
254 usage = "usage: gremlin [-o] [-s <.gremlinrc>] [file]\n";
255
256 while (--argc > 0) {
257 arg = *++argv;
258 if (*arg != '-')
259 file = arg;
260 else {
261 switch (*++arg) {
262 case 's':
263 if (*++arg == '\0')
264 if (--argc > 0)
265 arg = *++argv;
266 if (argc < 0) {
267 printf("%s", usage);
268 exit(1);
269 }
270 gremlinrc = arg;
271 break;
272 case 'o':
273 newfileformat = 0;
274 break;
275 default:
276 printf("%s", usage);
277 exit(1);
278 }
279 }
280 }
281
282 strcpy(namestripe, version);
283 tool = tool_create(namestripe, TOOL_NAMESTRIPE, (struct rect *) NULL,
284 &gremlin_icon /*(struct icon *) NULL*/);
285 if (tool == (struct tool *) NULL)
286 exit(1);
287
288 text_sw = tool_createsubwindow(tool, "text_sw", TOOL_SWEXTENDTOEDGE,
289 TEXTSW_HEIGHT);
290
291 menu_sw = tool_createsubwindow(tool, "menu_sw",
292 MENUSW_WIDTH, TOOL_SWEXTENDTOEDGE);
293
294 pix_sw = tool_createsubwindow(tool, "pix_sw", TOOL_SWEXTENDTOEDGE,
295 TOOL_SWEXTENDTOEDGE);
296
297 if ((text_sw == (struct toolsw *)NULL) ||
298 (menu_sw == (struct toolsw *)NULL) ||
299 (pix_sw == (struct toolsw *)NULL)) {
300 printf("error creating subwindows\n");
301 exit(1);
302 }
303
304 init_tool();
305 init_text();
306 init_menu();
307 init_pix();
308
309 /* set up gremlin variables */
310 main_init(file, gremlinrc);
311
312 /* install tool in tree of windows */
313 signal(SIGWINCH, sigwinched);
314 tool_install(tool);
315 TOOLINSTALLED = 1;
316
317 /* if current set flash off period non-zero, set up SIGALRM */
318 if ((timeoff_ms != 0l) || (timeoff_s != 0l)) {
319 signal(SIGALRM, alrm_sighandler);
320 itime.it_interval.tv_sec = itime.it_value.tv_sec = timeon_s;
321 itime.it_interval.tv_usec = itime.it_value.tv_usec = timeon_ms * 1000;
322 setitimer(ITIMER_REAL, &itime, (struct itimerval *) NULL);
323 }
324
325 /* handle input */
326 tool_select(tool, 0);
327
328 /* cleanup */
329 tool_destroy(tool);
330 exit(0);
331 }
332
333
334 /*
335 * Set input mask for the tool border.
336 */
337 static
set_tool_input()338 set_tool_input()
339 {
340 struct inputmask im;
341
342 input_imnull(&im);
343 win_setinputcodebit(&im, MS_LEFT);
344 win_setinputcodebit(&im, MS_MIDDLE);
345 win_setinputcodebit(&im, MS_RIGHT);
346 win_setinputcodebit(&im, LOC_STILL);
347
348 win_setinputmask(tool_fd, &im, NULL, WIN_NULLLINK);
349 }
350
351
352 static
init_tool()353 init_tool()
354 {
355 tool_fd = tool->tl_windowfd;
356 tool->tl_io.tio_selected = tool_selected;
357
358 set_tool_input();
359
360 if ((rootfd = open("/dev/win0", 0)) == -1) {
361 printf("can't open root window\n");
362 exit(1);
363 }
364
365 fix_tool_size();
366 }
367
368
369 /*
370 * Set the size of the entire gremlin window.
371 */
fix_tool_size()372 fix_tool_size()
373 {
374 struct rect icon_rect;
375
376 if (wmgr_iswindowopen(tool_fd))
377 win_getrect(tool_fd, &tool_size);
378 else
379 win_getsavedrect(tool_fd, &tool_size);
380
381 tool_size.r_width = 2 * tool_borderwidth(tool) +
382 tool_subwindowspacing(tool) +
383 MENUSW_WIDTH + PIXSW_WIDTH;
384 tool_size.r_height = tool_stripeheight(tool) + tool_borderwidth(tool) +
385 tool_subwindowspacing(tool) +
386 2 + /* don't know why */
387 TEXTSW_HEIGHT + PIXSW_HEIGHT;
388
389 /* don't allow window to open in lower left corner */
390 if (tool_size.r_left < 100)
391 tool_size.r_left = 100;
392 if (rect_bottom(&tool_size) >= 700)
393 tool_size.r_top -= rect_bottom(&tool_size) - 699;
394
395 /* land icon near upper left corner */
396 icon_rect.r_left = 0;
397 icon_rect.r_top = 64;
398 icon_rect.r_width = 64;
399 icon_rect.r_height = 64;
400
401 if (wmgr_iswindowopen(tool_fd)) {
402 win_setrect(tool_fd, &tool_size);
403 win_setsavedrect(tool_fd, &icon_rect);
404 }
405 else {
406 win_setrect(tool_fd, &icon_rect);
407 win_setsavedrect(tool_fd, &tool_size);
408 }
409 }
410
411
412 static
init_text()413 init_text()
414 {
415 struct inputmask im;
416
417 text_fd = text_sw->ts_windowfd;
418 text_pw = pw_open(text_fd);
419
420 text_sw->ts_io.tio_handlesigwinch = text_sighandler;
421 text_sw->ts_io.tio_selected = text_selected;
422
423 win_setcursor(text_fd, &kbd_cursor);
424
425 input_imnull(&im);
426 win_setinputcodebit(&im, MS_LEFT);
427 win_setinputcodebit(&im, MS_MIDDLE);
428 win_setinputcodebit(&im, MS_RIGHT);
429 win_setinputcodebit(&im, LOC_STILL);
430 win_setinputcodebit(&im, LOC_WINEXIT);
431
432 im.im_flags |= IM_ASCII;
433 win_setinputmask(text_fd, &im, NULL, WIN_NULLLINK);
434 }
435
436
437 static
init_menu()438 init_menu()
439 {
440 struct inputmask im;
441
442 menu_fd = menu_sw->ts_windowfd;
443 menu_pw = pw_open(menu_fd);
444
445 menu_sw->ts_io.tio_handlesigwinch = menu_sighandler;
446 menu_sw->ts_io.tio_selected = menu_selected;
447
448 win_setcursor(menu_fd, &menu_cursor);
449
450 input_imnull(&im);
451 win_setinputcodebit(&im, MS_LEFT);
452 win_setinputcodebit(&im, MS_MIDDLE);
453 win_setinputcodebit(&im, MS_RIGHT);
454 win_setinputcodebit(&im, LOC_MOVE);
455 win_setinputcodebit(&im, LOC_WINEXIT);
456 win_setinputcodebit(&im, LOC_STILL);
457
458 im.im_flags |= IM_ASCII;
459 win_setinputmask(menu_fd, &im, NULL, WIN_NULLLINK);
460 }
461
462
463 static
init_pix()464 init_pix()
465 {
466 struct inputmask im;
467 struct fbtype fb;
468 struct mpr_data *md;
469 int height, width;
470 int fd;
471
472 pix_fd = pix_sw->ts_windowfd;
473 pix_pw = pw_open(pix_fd);
474
475 pix_sw->ts_io.tio_handlesigwinch = pix_sighandler;
476 pix_sw->ts_io.tio_selected = pix_selected;
477
478 win_setcursor(pix_fd, &main_cursor);
479
480 input_imnull(&im);
481 win_setinputcodebit(&im, MS_LEFT);
482 win_setinputcodebit(&im, MS_MIDDLE);
483 win_setinputcodebit(&im, MS_RIGHT);
484 win_setinputcodebit(&im, LOC_STILL);
485 win_setinputcodebit(&im, LOC_WINEXIT);
486
487 im.im_flags |= IM_ASCII;
488 win_setinputmask(pix_fd, &im, NULL, WIN_NULLLINK);
489
490 /* determine screen physical dimensions */
491 if ((fd = open(DEV_FB, 1)) < 0) { /* must be open for writing */
492 printf("init_pix: can't open %s\n", DEV_FB);
493 exit(1);
494 }
495
496 /* get frame buffer characteristics */
497 if (ioctl(fd, FBIOGTYPE, (char *) &fb) < 0) {
498 printf("init_pix: ioctl (FBIOGTYPE)\n");
499 exit(1);
500 }
501 close(fd);
502
503 /* determine maximum physical size of picture subwindow */
504 height = fb.fb_height - TEXTSW_HEIGHT -
505 tool_stripeheight(tool) -
506 tool_borderwidth(tool) -
507 tool_subwindowspacing(tool);
508 width = fb.fb_width - MENUSW_WIDTH -
509 tool_subwindowspacing(tool) -
510 tool_borderwidth(tool) * 2;
511
512 /* create pixrect for retaining image of current set */
513 cset_pr = mem_create(width, height, 1);
514 if (cset_pr == NULL) {
515 printf("can't create cset_pr\n");
516 exit(1);
517 }
518
519 /* create pixrect to do all element drawing in memory (faster) */
520 scratch_pr = mem_create(width, height, 1);
521 if (scratch_pr == NULL) {
522 printf("can't create scratch_pr\n");
523 exit(1);
524 }
525
526 #ifdef RETAIN
527 /* create retained pixrect for picture subwindow */
528 retained_pr = mem_create(width, height, 1);
529 if (retained_pr == (struct pixrect *) NULL) {
530 printf("can't create retained_pr\n");
531 exit(1);
532 }
533
534 /* add retained pixrect to the pix subwindow pixwin */
535 pix_pw->pw_prretained = retained_pr;
536
537 /*
538 * The pix subwindow width and height MUST be initialized before
539 * any drawing can take place when using a retained pixrect.
540 * The display routine DISScreenAdd() uses these dimensions to
541 * minimize the area of the mem_pixrect (scratch_pr) which must
542 * be cleared prior to drawing an element and is called via
543 * SHUpdate() at the end of main_init().
544 */
545 pix_size.r_width = PIXSW_WIDTH;
546 pix_size.r_height = PIXSW_HEIGHT;
547 #endif
548
549 #ifdef maybefaster
550 md = (struct mpr_data *) scratch_pr->pr_data;
551 _image = (char *) md->md_image;
552 _bytesperline = md->md_linebytes;
553 _maxx = _bytesperline << 3;
554 _maxy = scratch_pr->pr_size.y;
555 #endif
556 }
557
558
559 /*
560 * This routine catches the normal tool manager quit menuitem
561 * and handles it slightly differently if no write has occurred
562 * since the last change to the picture.
563 * WARNING: this routine depends upon menu_display() returning
564 * mi->mi_data = 2 for the QUIT menuitem and
565 * mi->mi_data = 1 for the REDISPLAY menuitem.
566 */
567 static
tool_selected(nullsw,ibits,obits,ebits,timer)568 tool_selected(nullsw, ibits, obits, ebits, timer)
569 caddr_t *nullsw;
570 int *ibits, *obits, *ebits;
571 struct timeval **timer;
572 {
573 struct inputevent ie;
574 struct inputmask im;
575 struct menuitem *mi;
576
577 if (input_readevent(tool_fd, &ie) < 0) {
578 printf("error: tool_selected()\n");
579 return;
580 }
581
582 switch (ie.ie_code) {
583 case LOC_STILL:
584 /* GRCurrentSetOn(); */
585 break;
586 case MS_LEFT:
587 if (wmgr_iswindowopen(tool_fd))
588 wmgr_top(tool_fd, rootfd);
589 else
590 wmgr_open(tool_fd, rootfd);
591 break;
592 case MS_MIDDLE:
593 wmgr_changerect(tool_fd, tool_fd, &ie, 1, 1);
594 break;
595 case MS_RIGHT:
596 /* force mouse button input only for pop-up menu */
597 input_imnull(&im);
598 win_setinputcodebit(&im, MS_LEFT);
599 win_setinputcodebit(&im, MS_MIDDLE);
600 win_setinputcodebit(&im, MS_RIGHT);
601 win_setinputmask(tool_fd, &im, NULL, WIN_NULLLINK);
602
603 wmgr_setupmenu(tool_fd);
604 mi = menu_display(&wmgr_toolmenu, &ie, tool_fd);
605 if (mi == (struct menuitem *) NULL)
606 break;
607
608 if (((int) mi->mi_data == 1) /* REDISPLAY !! */
609 && wmgr_iswindowopen(tool_fd))
610 SHUpdate();
611 else if ((int) mi->mi_data == 2) /* QUIT !! */
612 LGQuit();
613 else
614 wmgr_handletoolmenuitem(wmgr_toolmenu, mi, tool_fd, rootfd);
615
616 set_tool_input(); /* reset tool input */
617 break;
618 }
619
620 *ibits = *obits = *ebits = 0;
621 }
622
623
624 static
text_selected(nullsw,ibits,obits,ebits,timer)625 text_selected(nullsw, ibits, obits, ebits, timer)
626 caddr_t *nullsw;
627 int *ibits, *obits, *ebits;
628 struct timeval **timer;
629 {
630 struct inputevent ie;
631
632 if (input_readevent(text_fd, &ie) < 0) {
633 printf("error: text_selected()\n");
634 return;
635 }
636
637 switch (ie.ie_code) {
638 case LOC_STILL:
639 check_cset();
640 break;
641 case MS_LEFT:
642 text_left(&ie);
643 break;
644 case MS_MIDDLE:
645 text_middle(&ie);
646 break;
647 case MS_RIGHT:
648 text_right(&ie);
649 break;
650 case LOC_WINEXIT:
651 text_winexit(&ie);
652 break;
653 default:
654 if ((ie.ie_code <= ASCII_LAST) && (ie.ie_code >= ASCII_FIRST))
655 text_output(ie.ie_code);
656 break;
657 }
658
659 *ibits = *obits = *ebits = 0;
660 }
661
662
663 static
menu_selected(nullsw,ibits,obits,ebits,timer)664 menu_selected(nullsw, ibits, obits, ebits, timer)
665 caddr_t *nullsw;
666 int *ibits, *obits, *ebits;
667 struct timeval **timer;
668 {
669 struct inputevent ie;
670 char shcmd[2];
671
672 if (input_readevent(menu_fd, &ie) < 0) {
673 printf("error: menu_selected()\n");
674 return;
675 }
676
677 switch (ie.ie_code) {
678 case LOC_MOVE:
679 mouse_move(&ie);
680 break;
681 case LOC_STILL:
682 check_cset();
683 break;
684 case MS_LEFT:
685 menu_left(&ie);
686 break;
687 case MS_MIDDLE:
688 menu_middle(&ie);
689 break;
690 case MS_RIGHT:
691 menu_right(&ie);
692 break;
693 case LOC_WINEXIT:
694 menu_winexit(&ie);
695 break;
696 default:
697 if ((ie.ie_code <= ASCII_LAST) && (ie.ie_code >= ASCII_FIRST)) {
698 if ((shcmd[0] = ie.ie_code) != '.')
699 lasttext = FALSE;
700 shcmd[1] = '\0';
701 SHCommand(shcmd);
702 }
703 break;
704 }
705
706 *ibits = *obits = *ebits = 0;
707 }
708
709
710 static
pix_selected(nullsw,ibits,obits,ebits,timer)711 pix_selected(nullsw, ibits, obits, ebits, timer)
712 caddr_t *nullsw;
713 int *ibits, *obits, *ebits;
714 struct timeval **timer;
715 {
716 struct inputevent ie;
717 char shcmd[2];
718
719 if (input_readevent(pix_fd, &ie) < 0) {
720 printf("error: pix_selected()\n");
721 return;
722 }
723
724 switch (ie.ie_code) {
725 case LOC_STILL:
726 check_cset();
727 break;
728 case MS_LEFT:
729 pix_left(&ie);
730 break;
731 case MS_MIDDLE:
732 pix_middle(&ie);
733 break;
734 case MS_RIGHT:
735 pix_right(&ie);
736 break;
737 case LOC_WINEXIT:
738 pix_winexit(&ie);
739 break;
740 default:
741 if ((ie.ie_code <= ASCII_LAST) && (ie.ie_code >= ASCII_FIRST)) {
742 if ((shcmd[0] = ie.ie_code) != '.')
743 lasttext = FALSE;
744 shcmd[1] = '\0';
745 SHCommand(shcmd);
746 }
747 break;
748 }
749
750 *ibits = *obits = *ebits = 0;
751 }
752
753
754 static
sigwinched()755 sigwinched()
756 {
757 tool_sigwinch(tool);
758
759 win_getrect(tool_fd, &tool_size);
760 /*
761 printf("tool: left %d, top %d, width %d, height %d\n", tool_size.r_left,
762 tool_size.r_top, tool_size.r_width, tool_size.r_height);
763 */
764 }
765
766
767 static
text_sighandler()768 text_sighandler()
769 {
770 pw_damaged(text_pw);
771
772 win_getrect(text_fd, &text_size);
773 pw_writebackground(text_pw, 0, 0, 1024, 1024, PIX_SRC);
774 text_putvalue();
775
776 pw_donedamaged(text_pw);
777 }
778
779
780 static
menu_sighandler()781 menu_sighandler()
782 {
783 pw_damaged(menu_pw);
784
785 win_getrect(menu_fd, &menu_size);
786 pw_writebackground(menu_pw, 0, 0, 1024, 1024, PIX_SRC);
787 MNDisplayMenu();
788 /*
789 printf("menu: left %d, top %d, width %d, height %d\n", menu_size.r_left,
790 menu_size.r_top, menu_size.r_width, menu_size.r_height);
791 */
792
793 pw_donedamaged(menu_pw);
794 }
795
796
797 static
pix_sighandler()798 pix_sighandler()
799 {
800 GRCurrentSetOn(); /* make current set on */
801 pw_damaged(pix_pw);
802
803 if (STERROR) { /* check for startup error reading .gremlinrc */
804 TxPutMsg("error in .gremlinrc");
805 STERROR = 0;
806 }
807
808 win_getrect(pix_fd, &pix_size);
809
810 #ifdef RETAIN
811 pw_repairretained(pix_pw);
812 #else
813 SHUpdate();
814 #endif
815
816 pw_donedamaged(pix_pw);
817 }
818
819
820 /*
821 * One time only start-up initialization.
822 */
main_init(file,gremlinrc)823 main_init(file, gremlinrc)
824 char *file;
825 char *gremlinrc;
826 {
827 FILE *fp;
828 POINT *pos;
829 int i, fd;
830 char *prealname;
831
832 signal(SIGINT, SIG_IGN); /* ignore interrupts */
833 TxInit(); /* text subwindow init */
834 MNInitMenu(); /* menu subwindow init */
835 PSetPath("."); /* file search path */
836 Editfile = malloc(128); /* current picture name */
837
838 POINTLIST = PTInit(); /* drawing points */
839 BACKPOINT = PTInit(); /* backup point list */
840
841 PICTURE = DBInit(); /* picture database */
842 cset = DBInit(); /* current set */
843 for (i=0; i<4; ++i) /* set buffers */
844 MEN[i] = DBInit();
845
846 unlist = unback = NULL; /* undo pointers */
847 make_arrowhead(); /* for > command */
848 lastcommand = nop; /* no last command yet */
849
850 STgremlinrc(gremlinrc); /* .gremlinrc processing */
851 GRFontInit(); /* must be called after CSIZE & CFONT set */
852
853 strcpy(Editfile, file); /* find edit file */
854 if (*file != '\0') {
855 fp = POpen(Editfile, &prealname, SEARCH);
856
857 if (fp == NULL) {
858 strcat(namestripe, file);
859 error("creating new file");
860 }
861 else {
862 fclose(fp);
863 strcat(namestripe, prealname);
864 PICTURE = DBRead(Editfile, &Orientation, &pos);
865 if ((fd = open(prealname, O_WRONLY | O_APPEND)) < 0)
866 strcat(namestripe, " (read only)");
867 else
868 close(fd);
869 }
870 }
871 else {
872 strcat(namestripe, "new file");
873 }
874
875 #ifdef RETAIN
876 /*
877 * Update pix subwindow now so that the retained pixrect is set before
878 * the first SIGWINCH.
879 */
880 SHUpdate();
881 #endif
882 } /* end main_init */
883
884
885 /*
886 * Make arrowhead element for later drawing.
887 */
make_arrowhead()888 make_arrowhead()
889 {
890 POINT *pos;
891
892 pos = PTInit(); /* initialize arrowhead template */
893 (void) PTMakePoint(0.0, 0.0, &pos);
894 (void) PTMakePoint(-5.51, 3.51, &pos);
895 (void) PTMakePoint(-3.51, 0.0, &pos);
896 (void) PTMakePoint(-5.51, -3.51, &pos);
897 (void) PTMakePoint(0.0, 0.0, &pos);
898 arhead.type = VECTOR;
899 arhead.ptlist = pos;
900 arhead.brushf = 0; /* brush filled in when used */
901 arhead.size = 0;
902 arhead.textpt = malloc(1);
903 *(arhead.textpt) = '\0';
904 }
905
906
907 /*
908 * Nothing has happened for a while, so check to see if its time
909 * to flash the current set. If so, set the SIGALRM timer for the
910 * appropriate period.
911 */
check_cset()912 check_cset()
913 {
914 if (FLASH_READY /*&& wmgr_iswindowopen(tool_fd) */) {
915 GRCurrentSet(); /* XOR current set */
916
917 if (CsetOn) { /* set off period */
918 itime.it_interval.tv_sec =
919 itime.it_value.tv_sec = timeon_s;
920 itime.it_interval.tv_usec =
921 itime.it_value.tv_usec = timeon_ms * 1000;
922 }
923 else { /* set on period */
924 itime.it_interval.tv_sec =
925 itime.it_value.tv_sec = timeoff_s;
926 itime.it_interval.tv_usec =
927 itime.it_value.tv_usec = timeoff_ms * 1000;
928 }
929
930 setitimer(ITIMER_REAL, &itime, NULL);
931 FLASH_READY = 0;
932 }
933 }
934
935
936 /*
937 * This routine handles the timer signals indicating that it is time
938 * to flash the current set. Since the screen may not be in a consistent
939 * state, we simply set the FLASH_READY flag and return. When a LOC_STILL
940 * input event arrives later, this flag will be checked and the current
941 * set flashed then.
942 */
943 static
alrm_sighandler()944 alrm_sighandler()
945 {
946 FLASH_READY = 1;
947 }
948