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 */ 239 error(s) 240 char *s; 241 { 242 TxPutMsg(s); 243 } 244 245 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 */ 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 */ 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 944 alrm_sighandler() 945 { 946 FLASH_READY = 1; 947 } 948