1*17243Sopcode /* @(#)main.c 1.7 10/10/84
211956Sslatteng *
311956Sslatteng * Copyright -C- 1982 Barry S. Roitblat
411956Sslatteng *
511956Sslatteng *
611956Sslatteng * This is the main routine for the gremlin picture editor.
711956Sslatteng */
811956Sslatteng
911956Sslatteng
1011956Sslatteng #include "gremlin.h"
1111956Sslatteng #include "grem2.h"
1211956Sslatteng #include <signal.h>
1311956Sslatteng #include <sgtty.h>
1411956Sslatteng #include <sys/types.h>
1511956Sslatteng #include <sys/stat.h>
1616552Sslatteng #include <sys/time.h>
1711956Sslatteng
1811956Sslatteng /* imports from config.c */
1911956Sslatteng
2011956Sslatteng extern char GMapFile[];
2111956Sslatteng
2211956Sslatteng /* database imports */
2311956Sslatteng
2411956Sslatteng extern ELT *DBInit(), *DBRead();
2511956Sslatteng extern POINT *PTInit(), *PTMakePoint();
2611956Sslatteng
2711956Sslatteng /* imports from menu.c */
2811956Sslatteng
2911956Sslatteng extern MNInterpretCursor();
3011956Sslatteng extern MNIcon(), MNInitMenu(), MNDisplayMenu();
3111956Sslatteng
3211956Sslatteng /* graphics imports */
3311956Sslatteng extern GRInit(), GRClose();
3411956Sslatteng extern GRSetGrid(), GRDisplayGrid(), GRBlankGrid();
3511956Sslatteng extern GRDisableTablet(), GREnableTablet();
3611956Sslatteng extern GRSetMap(), GRsetwmask();
3711956Sslatteng extern artmode;
3811956Sslatteng
3911956Sslatteng /* imports from undodb.c */
4011956Sslatteng
4111956Sslatteng extern UNForget();
4211956Sslatteng extern UNELT *unlist, *unback;
4311956Sslatteng
4411956Sslatteng /* imports from long.c */
4511956Sslatteng
4611956Sslatteng extern char *Editfile;
4711956Sslatteng extern CP(), LGCommand();
4811956Sslatteng extern LGQuit();
4911956Sslatteng
5011956Sslatteng /* imports from short.c */
5111956Sslatteng
5211956Sslatteng extern SHCommand();
5311956Sslatteng extern SHRedis();
5411956Sslatteng extern SHUpdate();
5511956Sslatteng
5611956Sslatteng /* other */
5711956Sslatteng
5811956Sslatteng extern char *FindAED();
5911956Sslatteng
6011956Sslatteng /* Forward references within this file: */
6111956Sslatteng
6211956Sslatteng extern OnStop(), OnCommand();
6311956Sslatteng
6411956Sslatteng /* Imports from textio.c: */
6511956Sslatteng
6611956Sslatteng extern TxInit(), TxRedisplay(), TxClose(), TxPutMsg(), TxMsgOK();
6711956Sslatteng extern TxLine(), TxPutString();
6811956Sslatteng extern char TxGetChar();
6911956Sslatteng extern short inline;
7011956Sslatteng extern TxPutString();
7111956Sslatteng extern TXFIELD TAlign, TAdjust, TBrush, TFont, TGravity, TCSize;
7211956Sslatteng extern TXFIELD TEdit, TJustmode;
7311956Sslatteng
7411956Sslatteng
7511956Sslatteng /* Library routines: */
7611956Sslatteng
7711956Sslatteng extern char *malloc(), *sprintf(), *strcat(), *strcpy();
7811956Sslatteng
7911989Sslatteng /* Version number */
8011989Sslatteng
81*17243Sopcode char SccsId [] = "@(#)main.c 1.7 (Berkeley) 10/10/84";
8211989Sslatteng
8311956Sslatteng #ifdef SIGTINT
8411956Sslatteng static int lintrup = LINTRUP; /* Constant for local mode bit */
8511956Sslatteng #endif SIGTINT
8611956Sslatteng
8711956Sslatteng /* Declaration of Globals */
8811956Sslatteng
8911956Sslatteng ELT *PICTURE, *cset, arhead;
9011956Sslatteng int CBRUSH, CFONT, CSIZE, CJUST, Gridsize, Gridon, Orientation;
9111956Sslatteng int Alignment, SEQ, Adjustment, GravityOn, Consume, CHANGED;
9211956Sslatteng float PX, PY, Lastx, Lasty;
9311956Sslatteng POINT *POINTLIST, *BACKPOINT, MENPOINT[NUSER];
9411956Sslatteng ELT *MEN[NUSER];
9511956Sslatteng char cmdbuf[400];
9611956Sslatteng int SEARCH = TRUE;
9711956Sslatteng int jmodes = 16;
9811956Sslatteng char *textpos[] = {"bl", "bc", "br", "cl", "cc", "cr", "tl", "tc", "tr",
9911956Sslatteng "lb", "cb", "rb", "lc", "rc", "lt", "ct", "rt" };
10011956Sslatteng char *dispmode[] = {"BL", "BR", "CC", "XX", "XX", "XX", "XX", "XX",
10111956Sslatteng "XX", "XX", "TL", "TC", "TR", "CL", "CR", "BC" };
10211956Sslatteng int textmode[] = { 0, 15, 1, 13, 2, 14, 10, 11, 12,
10311956Sslatteng 0, 15, 1, 13, 14, 10, 11, 12 };
10411956Sslatteng
10511956Sslatteng /* symbolic types, brushes, etc. */
10611956Sslatteng
10711956Sslatteng char *lines[] = { "broken", "dashed", "dotted",
10811956Sslatteng "medium", "narrow", "thick", NULL };
10911956Sslatteng int lnum[] = { 2, 4, 1, 6, 5, 3 };
11011956Sslatteng char types[] = { 'l', 'r', 'c', 'v', 'a', 'u', '\0' };
11111956Sslatteng char *fonts[] = { "Bold", "Italics", "Roman", "Special",
11211956Sslatteng "bold", "italics", "roman", "special", NULL };
11311956Sslatteng int fnum[] = { 3, 2, 1, 4, 3, 2, 1, 4 };
11411956Sslatteng
error(s)11511956Sslatteng error(s)
11611956Sslatteng char *s;
11711956Sslatteng /*
11811956Sslatteng * This routine prints an error message and sets the Consume flag
11911956Sslatteng * so that points are not cleared.
12011956Sslatteng */
12111956Sslatteng {
12211956Sslatteng putchar('\7');
12311956Sslatteng TxPutMsg(s);
12411956Sslatteng Consume = FALSE;
12511956Sslatteng }
12611956Sslatteng
12711981Sslatteng
main(argc,argv)12811956Sslatteng main(argc, argv)
12911956Sslatteng int argc;
13011956Sslatteng char *argv[];
13111956Sslatteng {
13211956Sslatteng FILE *fp, *POpen(), *fopen(),*grtty, *tablet, *map, *startup;
13311956Sslatteng POINT *p1, pos;
13411956Sslatteng int x1, y1, x2, y2, i, j;
13511956Sslatteng int button, cux, cuy;
13611956Sslatteng char colours[768], msg[50], sw, *arg, *file;
13711956Sslatteng char *ptr, *display, *type, *getenv(), home[100];
13811956Sslatteng char *path = ".";
13911956Sslatteng struct stat buf;
14011956Sslatteng ino_t inode;
14111956Sslatteng
14211956Sslatteng display = FindAED();
14311956Sslatteng if (display == NULL) display = "/dev/null";
14411956Sslatteng Orientation = 1;
14511956Sslatteng file = NULL;
14611956Sslatteng
14711956Sslatteng /* Parse the command line. */
14811956Sslatteng
14911956Sslatteng argc -= 1; argv++; /* Skip program name. */
15011956Sslatteng while (argc > 0)
15111956Sslatteng {
15211956Sslatteng argc -= 1;
15311956Sslatteng arg = *argv++;
15411956Sslatteng if (arg[0] != '-') file = arg;
15511956Sslatteng else
15611956Sslatteng {
15711956Sslatteng sw = *++arg;
15811956Sslatteng switch (sw)
15911956Sslatteng {
16011956Sslatteng case 'g':
16111956Sslatteng if (*++arg == '\0')
16211956Sslatteng if (argc-- > 0) arg = *argv++;
16311956Sslatteng if (argc < 0) error("usage: gremlin -g <display name>");
16411956Sslatteng display = arg;
16511956Sslatteng if (*display != '/') display = strcat("/dev/", arg);
16611956Sslatteng break;
16711956Sslatteng case 'p':
16811956Sslatteng if (*++arg == '\0')
16911956Sslatteng if (argc-- > 0) arg = *argv++;
17012239Sslatteng if (argc < 0) error("usage: gremlin -p <path>");
17111956Sslatteng path = arg;
17211956Sslatteng SEARCH = TRUE;
17311956Sslatteng break;
17411956Sslatteng case 'h':
17511956Sslatteng Orientation = 0;
17611956Sslatteng break;
17711956Sslatteng case 'v':
17811956Sslatteng Orientation = 1;
17911956Sslatteng break;
18011956Sslatteng default:
18111956Sslatteng (void) sprintf(msg, "unknown switch: %c", sw);
18211956Sslatteng error(msg);
18311956Sslatteng }
18411956Sslatteng }
18511956Sslatteng }
18611956Sslatteng
18711956Sslatteng PSetPath(path);
18816552Sslatteng if ((map = fopen(GMapFile, "r")) == NULL) {
18916552Sslatteng error ("can't open color map");
19016552Sslatteng } else
19116552Sslatteng for (i=0; i<768; ++i) /* read in color map */
19216552Sslatteng {
19316552Sslatteng (void) fscanf(map,"%o",&j);
19416552Sslatteng colours[i] = j&0377;
19516552Sslatteng }
19611956Sslatteng
19711956Sslatteng /* Open the display, and call all of the initialization routines.
19811956Sslatteng * Initialize all of the globals defined in this file.
19911956Sslatteng */
20011956Sslatteng type = getenv("TERM");
20111956Sslatteng TxInit(type);
20211956Sslatteng
20311956Sslatteng /* Ignore quit signals, catch interrupts and stops. */
20411956Sslatteng
20513813Sslatteng signal(SIGINT, SIG_IGN);
20613813Sslatteng signal(SIGTSTP, OnStop);
20713813Sslatteng signal(SIGTTIN, OnStop);
20813813Sslatteng signal(SIGTTOU, OnStop);
20911956Sslatteng
21011956Sslatteng #ifdef SIGTINT
21113813Sslatteng signal(SIGTINT, OnCommand);
21211956Sslatteng sighold(SIGTINT);
21311956Sslatteng #endif SIGTINT
21411956Sslatteng
21511956Sslatteng grtty = fopen(display,"w");
21611956Sslatteng if (grtty == NULL)
21711956Sslatteng {
21811956Sslatteng error("couldn't open display");
21911956Sslatteng LGQuit(display);
22011956Sslatteng };
22111956Sslatteng tablet = fopen(display,"r");
22211956Sslatteng if (tablet == NULL) tablet = fopen("/dev/null", "r");
22311956Sslatteng GRInit(grtty,0);
22411956Sslatteng GRSetMap(colours);
22511956Sslatteng
22611956Sslatteng #ifdef SIGTINT
22711956Sslatteng (void) ioctl(fileno(stdin), TIOCLBIS, (char *) &lintrup);
22811956Sslatteng #endif SIGTINT
22911956Sslatteng
23011956Sslatteng TxRedisplay(); /* display text screen */
23111956Sslatteng
23211956Sslatteng CBRUSH = 6;
23311956Sslatteng CFONT = 1;
23411956Sslatteng CSIZE = 1;
23511956Sslatteng CJUST = 0;
23611956Sslatteng Gridon = FALSE;
23711956Sslatteng Adjustment = NOADJ;
23811956Sslatteng Alignment = 4;
23911956Sslatteng artmode = FALSE;
24011956Sslatteng SEQ = 0;
24111956Sslatteng GravityOn = FALSE;
24211956Sslatteng CHANGED = FALSE;
24311956Sslatteng POINTLIST = PTInit();
24411956Sslatteng BACKPOINT = PTInit();
24511956Sslatteng unlist = unback = nullun;
24611956Sslatteng p1 = PTInit(); /* initialize arrowhead template */
24711956Sslatteng (void) PTMakePoint(0.0, 0.0, &p1);
24811956Sslatteng (void) PTMakePoint(-5.0, 3.0, &p1);
24911956Sslatteng (void) PTMakePoint(-3.0, 0.0, &p1);
25011956Sslatteng (void) PTMakePoint(-5.0, -3.0, &p1);
25111956Sslatteng (void) PTMakePoint(0.0, 0.0, &p1);
25211956Sslatteng arhead.type = VECTOR;
25311956Sslatteng arhead.ptlist = p1;
25411956Sslatteng arhead.brushf = 0; /* brush filled in when used */
25511956Sslatteng arhead.size = 0;
25611956Sslatteng arhead.textpt = malloc(1);
25711956Sslatteng *(arhead.textpt) = '\0';
25811956Sslatteng
25911956Sslatteng PICTURE = DBInit(); /* initialize picture databse */
26011956Sslatteng cset = DBInit(); /* and current set */
26111956Sslatteng for (i=0; i<4; ++i) /* and user symbols */
26211956Sslatteng MEN[i] = DBInit();
26311956Sslatteng Editfile = malloc(100);
26411956Sslatteng if (file == NULL)
26511956Sslatteng *Editfile = '\0';
26611956Sslatteng else
26711956Sslatteng {
26811956Sslatteng (void) strcpy(Editfile, file);
26911956Sslatteng fp = POpen(Editfile, (char **) NULL, SEARCH);
27011956Sslatteng if (fp == NULL) error("(creating new file)");
27111956Sslatteng else PICTURE = DBRead(Editfile,&Orientation, &pos);
27211956Sslatteng }
27311956Sslatteng unlist = unback = nullun;
27411956Sslatteng TxPutString(&TEdit, Editfile);
27511956Sslatteng TxPutMsg(" Gremlin - Version 2.3 (1982)");
27611956Sslatteng MNIcon();
27711956Sslatteng MNInitMenu(Orientation); /* Initialize Menu */
27811956Sslatteng SHUpdate(); /* Display menu and picture, if any */
27911956Sslatteng
28011956Sslatteng if (Orientation == 0) /* initialize grid */
28111956Sslatteng {
28211956Sslatteng x1 = y1 = 0;
28311956Sslatteng x2 = 511;
28411956Sslatteng y2 = 395;
28511956Sslatteng }
28611956Sslatteng else
28711956Sslatteng {
28811956Sslatteng x1 = 116;
28911956Sslatteng y1 = 0;
29011956Sslatteng x2 = 511;
29111956Sslatteng y2 = 483;
29211956Sslatteng };
29311956Sslatteng Gridsize = 16;
29411956Sslatteng GRSetGrid(x1, y1, x2, y2, Gridsize);
29511956Sslatteng
29611956Sslatteng /* read start-up file */
29711956Sslatteng /* look in home directory */
29811956Sslatteng sprintf(home,"%s/.gremlinrc",getenv("HOME"));
29911956Sslatteng startup = fopen(home, "r");
30011956Sslatteng if (startup != NULL)
30111956Sslatteng {
30211956Sslatteng fstat(startup, &buf);
30311956Sslatteng inode = buf.st_ino;
30411956Sslatteng ptr = fgets(cmdbuf, 400, startup);
30511956Sslatteng while (ptr != NULL)
30611956Sslatteng {
30711956Sslatteng for (i=0; (cmdbuf[i] != '\n'); ++i)
30811956Sslatteng if (i > 399) break;
30911956Sslatteng cmdbuf[i] = '\0'; /* remove trailing carriage return */
31011956Sslatteng if (cmdbuf[0] == ':') LGCommand(&(cmdbuf[1]));
31111956Sslatteng else SHCommand(&(cmdbuf[0]));
31211956Sslatteng ptr = fgets(cmdbuf, 400, startup);
31311956Sslatteng } /* end while */
31411956Sslatteng } /* end if startup */
31511956Sslatteng else inode = 0;
31611956Sslatteng
31711956Sslatteng /* look in current directory */
31811956Sslatteng startup = fopen(".gremlinrc", "r");
31911956Sslatteng if (startup != NULL)
32011956Sslatteng {
32111956Sslatteng fstat(startup, &buf);
32211956Sslatteng if (buf.st_ino != inode) /* This isn't the same file as above */
32311956Sslatteng {
32411956Sslatteng ptr = fgets(cmdbuf, 400, startup);
32511956Sslatteng while (ptr != NULL)
32611956Sslatteng {
32711956Sslatteng for (i=0; (cmdbuf[i] != '\n'); ++i)
32811956Sslatteng if (i > 399) break;
32911956Sslatteng cmdbuf[i] = '\0'; /* remove trailing carriage return */
33011956Sslatteng if (cmdbuf[0] == ':') LGCommand(&(cmdbuf[1]));
33111956Sslatteng else SHCommand(&(cmdbuf[0]));
33211956Sslatteng ptr = fgets(cmdbuf, 400, startup);
33311956Sslatteng } /* end while */
33411956Sslatteng } /* end if buf */
33511956Sslatteng } /* end if startup */
33611956Sslatteng
33711956Sslatteng while ( TRUE ) /* Exits through the 'quit' command */
33811956Sslatteng {
33911956Sslatteng Consume = TRUE;
34011956Sslatteng UNForget();
34111956Sslatteng
34211956Sslatteng #ifdef SIGTINT
34311956Sslatteng GREnableTablet();
34411956Sslatteng /* Allow keyboard interrupts while waiting
34511956Sslatteng * for cursor input.
34611956Sslatteng */
34711956Sslatteng sigrelse(SIGTINT);
34811956Sslatteng button = GRGetButton(tablet, &cux, &cuy);
34911956Sslatteng /* Ignore keyboard interrupts while processing commands.
35011956Sslatteng */
35111956Sslatteng sighold(SIGTINT);
35211956Sslatteng GRDisableTablet();
35311956Sslatteng TxMsgOK();
35411956Sslatteng MNInterpretCursor(button, cux, cuy);
35511956Sslatteng if (Consume) CP();
35611956Sslatteng #else SIGTINT
35711956Sslatteng i = 1 << fileno(stdin);
35811956Sslatteng GREnableTablet();
35911956Sslatteng i |= (1 << fileno(tablet));
36011989Sslatteng (void) select(20, &i, 0, 0, 0);
36111956Sslatteng if (i & (1 << fileno(stdin)))
36211956Sslatteng {
36311956Sslatteng TxMsgOK();
36411956Sslatteng OnCommand();
36511956Sslatteng }
36611956Sslatteng else
36711956Sslatteng {
36811956Sslatteng if ((button = GRGetButton(tablet, &cux, &cuy)) != -4)
36911956Sslatteng {
37011956Sslatteng GRDisableTablet();
37111956Sslatteng TxMsgOK();
37211956Sslatteng MNInterpretCursor(button, cux, cuy);
37311956Sslatteng if (Consume) CP();
37411956Sslatteng }
37511956Sslatteng }
37611956Sslatteng #endif SIGTINT
37711956Sslatteng
37811956Sslatteng } /* end while */
37911956Sslatteng
38011956Sslatteng } /* end main */
38111956Sslatteng
38211981Sslatteng
OnStop(signo)38311956Sslatteng OnStop(signo)
38411956Sslatteng int signo;
38511956Sslatteng
38611956Sslatteng /*-----------------------------------------------------------------------------
38711956Sslatteng * This procedure handles stop signals.
38811956Sslatteng *
38911956Sslatteng * Results: None.
39011956Sslatteng *
39111956Sslatteng * Side Effects:
39211956Sslatteng * The text display is reset, we wait to get restarted, then
39311956Sslatteng * redisplay text.
39411956Sslatteng *-----------------------------------------------------------------------------
39511956Sslatteng */
39611956Sslatteng
39711956Sslatteng {
39811956Sslatteng TxClose();
39913813Sslatteng signal(signo, SIG_DFL);
40013813Sslatteng sigsetmask(0);
40111956Sslatteng (void) kill(0, signo);
40213813Sslatteng signal(signo, OnStop);
40311956Sslatteng SHRedis();
40411956Sslatteng }
40511956Sslatteng
40611981Sslatteng
OnCommand()40711956Sslatteng OnCommand()
40811956Sslatteng
40911956Sslatteng /*-----------------------------------------------------------------------------
41011956Sslatteng * This routine responds to interrupts from the command terminal and
41111956Sslatteng * then processes commands as long as there is input.
41211956Sslatteng *
41311956Sslatteng * Results: None.
41411956Sslatteng *
41511956Sslatteng * Side Effects:
41611956Sslatteng * Whatever is done by the commands.
41711956Sslatteng *-----------------------------------------------------------------------------
41811956Sslatteng */
41911956Sslatteng
42011956Sslatteng {
42111956Sslatteng
42211956Sslatteng #ifdef SIGTINT
42311956Sslatteng long charcount;
42411956Sslatteng #else SIGTINT
42511956Sslatteng int i;
42611989Sslatteng struct timeval selectpoll;
42711956Sslatteng #endif SIGTINT
42811956Sslatteng
42911956Sslatteng static char cmd, lastcmd;
43011956Sslatteng int repeat;
43111956Sslatteng
43211956Sslatteng GRDisableTablet();
43311956Sslatteng
43411956Sslatteng #ifdef SIGTINT
43511956Sslatteng (void) ioctl(fileno(stdin), TIOCLBIC, (char *) &lintrup);
43611956Sslatteng #endif SIGTINT
43711956Sslatteng
43811956Sslatteng
43911956Sslatteng while (TRUE)
44011956Sslatteng {
44111956Sslatteng
44211956Sslatteng /* If there is no more input, then reenable the signal and return */
44311956Sslatteng
44411956Sslatteng
44511956Sslatteng #ifdef SIGTINT
44611956Sslatteng (void) ioctl(fileno(stdin), FIONREAD, (char *) &charcount);
44711956Sslatteng if (charcount == 0)
44811956Sslatteng {
44911956Sslatteng GREnableTablet();
45011956Sslatteng (void) ioctl(fileno(stdin), TIOCLBIS, (char *) &lintrup);
45111956Sslatteng return;
45211956Sslatteng }
45311956Sslatteng #else SIGTINT
45411956Sslatteng i = 1 << fileno(stdin);
45511989Sslatteng selectpoll.tv_sec = 0l;
45611989Sslatteng selectpoll.tv_usec = 0l;
45711989Sslatteng if (select(20, &i, 0, 0, &selectpoll) <= 0)
45811956Sslatteng {
45911956Sslatteng GREnableTablet();
46011956Sslatteng return;
46111956Sslatteng }
46211956Sslatteng #endif SIGTINT
46311956Sslatteng
46411956Sslatteng
46511956Sslatteng /* Read the command and call the long or short command routine */
46611956Sslatteng
46711956Sslatteng cmd = TxGetChar();
46811956Sslatteng if (cmd == '.')
46911956Sslatteng {
47011956Sslatteng repeat = TRUE;
47111956Sslatteng cmd = lastcmd;
47211956Sslatteng }
47311956Sslatteng else
47411956Sslatteng {
47511956Sslatteng repeat = FALSE;
47611956Sslatteng lastcmd = cmd;
47711956Sslatteng }
47811956Sslatteng if (cmd == ':')
47911956Sslatteng {
48011956Sslatteng if (!repeat) TxGetLine(":",cmdbuf,400);
48111956Sslatteng LGCommand(cmdbuf);
48211956Sslatteng }
48311956Sslatteng else
48411956Sslatteng {
48511956Sslatteng TxLine(inline);
48611989Sslatteng if (cmd != '\') putchar(cmd);
48711956Sslatteng (void) fflush(stdout);
48811956Sslatteng SHCommand(&cmd);
48911956Sslatteng }
49011956Sslatteng TxLine(inline);
49111956Sslatteng printf(" ");
49211956Sslatteng TxLine(inline);
49311956Sslatteng if (Consume) CP();
49411956Sslatteng Consume = TRUE;
49511956Sslatteng UNForget();
49611956Sslatteng }
49711956Sslatteng }
49811956Sslatteng
499