1 /* @(#)textio.c 1.2 04/18/83
2 *
3 * Copyright -C- 1982 Barry S. Roitblat
4 *
5 *
6 * This file contains functions that manipulate the text interface
7 *
8 * (Modified from software written by John Ousterhout for the caesar
9 * program)
10 */
11
12 #include "gremlin.h"
13 #include <sgtty.h>
14
15 /* Library routines: */
16
17 char *tgetstr(), *sprintf(), *tgoto(), *strcpy(), *strcat();
18
19 /* The following definitions are used by the termlib routines
20 */
21
22 char PC;
23 char *BC, *UP, *cm, *ce, *vs, *cl;
24 short ospeed, lastline=23,msgline=23,inline=22;
25
26 static char bp[1024]; /* Holds the termcap entry for the tty */
27 static char buf[256]; /* Holds selected strings from bp */
28 static struct sgttyb sttybuf; /* Holds stty information for resetting tty */
29 static int sttyflags; /* Flag word from sttybuf */
30 static struct tchars tchars; /* Holds tchars information for resetting */
31 static char brkc, eofc; /* Fields from tchars, saved for resetting */
32 static int c100; /* TRUE means text display is c100 */
33 static putmsg; /* TRUE means TxPutMsg has been called
34 * since last character input.
35 */
36
37
38 /* The following structures define the various fields that are available
39 * on the terminal screen.
40 */
41
42 TXFIELD
43 TAlign = {56, 1, 3},
44 TAdjust = {63, 1, 13},
45 TBrush = {30, 1, 1},
46 TEdit = {10, 2, 32},
47 TJustmode = {76, 2, 2},
48 TFont = {10, 1, 1},
49 TGravity = {43, 1, 4},
50 TCSize = {19, 1, 1};
51
52
OutChar(val)53 OutChar(val)
54 char val; /* The character to be output */
55
56 /*-----------------------------------------------------------------------------
57 * OutChar merely outputs a character on the file being used for
58 * text I/O. This routine is passed as a parameter to the tputs
59 * pad-generating routine.
60 *
61 * Results: None.
62 * Side Effects: The character is output.
63 * Errors: None.
64 *-----------------------------------------------------------------------------
65 */
66
67 {
68 putc(val, stdout);
69 }
70
71
TxInit(ttytype)72 TxInit(ttytype)
73 char *ttytype; /* The name of the terminal type, as returned
74 * by getenv("TERM") */
75
76 /*-----------------------------------------------------------------------------
77 * TxInit initializes the text terminal and saves state information
78 * so that we can restore its characteristics later.
79 *
80 * Results: None.
81 * Side Effects: Terminal characteristics are saved.
82 *-----------------------------------------------------------------------------
83 */
84
85 {
86 char *p1, *p2, *pcap;
87 int i;
88
89 /* Turn off buffering. This is necessary to avoid mess-ups during
90 * the constant mode changes.
91 */
92
93 setbuf(stdin, NULL);
94
95 /* Find the termcap entry, and set up the strings and constants
96 * required by the termlib routines.
97 */
98
99 if (tgetent(bp, ttytype) != 1)
100 error("Cannot find terminal characteristics");
101 (void) gtty(fileno(stdout), &sttybuf);
102 ospeed = sttybuf.sg_ospeed;
103 pcap = buf;
104 p1 = tgetstr("pc", &pcap); if (p1 == NULL) PC = 0; else PC = *p1;
105 pcap = buf;
106 BC = tgetstr("bc", &pcap);
107 UP = tgetstr("up", &pcap);
108 cm = tgetstr("cm", &pcap);
109 ce = tgetstr("ce", &pcap);
110 vs = tgetstr("vs", &pcap);
111 cl = tgetstr("cl", &pcap);
112 (void) gtty(fileno(stdin), &sttybuf);
113 sttyflags = sttybuf.sg_flags;
114 (void) ioctl(fileno(stdin), TIOCGETC, (char *) &tchars);
115 eofc = tchars.t_eofc;
116 brkc = tchars.t_brkc;
117 p1 = "c100";
118 p2 = ttytype;
119 c100 = FALSE;
120 putmsg = FALSE;
121 for (i = 4; i; i = i-1)
122 {
123 if (*p1 != *p2) break;
124 if (i=1) c100 = TRUE;
125 }
126 }
127
128
TxRedisplay()129 TxRedisplay()
130
131 /*-----------------------------------------------------------------------------
132 * This routine merely redisplays the command menu on the text screen,
133 * and modifies text display parameters for menu processing.
134 *
135 * Results: None.
136 *
137 * Side Effects:
138 * The text display is cleared, menu information is reprinted, and
139 * terminal characteristics are set for menu processing.
140 *-----------------------------------------------------------------------------
141 */
142
143 {
144 static char initstring1[] = "\n\
145 font 1 size 1 brush 6 gravi\
146 ty OFF align 4 NO ADJUSTMENT \n\
147 Editing: \
148 Justification: BL \n\
149 ----------------------------------------\
150 ---------------------------------------\n\
151 Long Commands: |\
152 Short Commands:\n\
153 |\n\
154 Align MSize |\
155 a - draw arc ! - shell escape\n\
156 BRush MText |\
157 b - draw curve . - repeat last command\n\
158 BUffer Orient |\
159 c - copy set ^L - redraw picture\n\
160 Clearpoints PAth |\
161 d - define set l - redisplay text screen\n\
162 ";
163 static char initstring2[] = "\
164 Deletepoint POint |\
165 e - erase 1,2,3,4 - store set buffer\n\
166 Edit<!> Quit<!> |\
167 f - define area \n\
168 Font Read |\
169 g - gravity\n\
170 Gripe SAveset<!>|\
171 q - grid\n\
172 Hadjust SHowpoints|\
173 r - rotate set\n\
174 Includeset SIze |\
175 s - scale set\n\
176 Justify Text |\
177 t - translate set\n\
178 Littlepoint Undo |\
179 v - draw vectors\n\
180 MBrush Vadjust |\
181 w - draw arrow \n\
182 MFont Write<!> |\
183 x - draw box\n\
184 MIrror |\
185 z - manhattan adjust\n\
186 MPoint |\
187 \n\
188 ";
189
190 /* Clear the terminal screen and output the gremlin menu. The
191 * TxClose call is necessary to put the terminal back into its standard
192 * operating mode; otherwise this stuff will appear as garbage!
193 * However, turn off echoing to keep type-ahead from appearing
194 * in the middle of the screen.
195 */
196
197 TxClose();
198 sttybuf.sg_flags &= ~ECHO;
199 (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
200 fputs(vs, stdout);
201 tputs(cl, tgetnum("li"), OutChar);
202 fputs(tgoto(cm, 0, 0), stdout);
203 fputs(initstring1, stdout);
204 fputs(initstring2, stdout);
205
206 /* If the terminal is a Concept 100, then output special characters
207 * for the border lines between the three screen areas.
208 */
209
210 if (c100)
211 {
212 fputs(tgoto(cm, 0, 3), stdout);
213 fputs("\33U\33r\1p", stdout);
214 putchar(0);
215 putchar(0);
216 putchar(0);
217 putchar(0);
218 fputs(tgoto(cm, 28, 4), stdout);
219 putchar('\0');
220 putchar('\0');
221 fputs("\33R", stdout);
222 putchar('\0');
223 putchar('2');
224 }
225
226 /* Place the cursor in the lower-left corner, save terminal
227 * characteristics so we can restore them later, then make ^M
228 * into a break character, put the terminal into CBREAK mode,
229 * and turn off echoing.
230 */
231
232 fputs(tgoto(cm, 0, lastline), stdout);
233 sttybuf.sg_flags |= CBREAK;
234 sttybuf.sg_flags &= ~(ECHO|CRMOD);
235 (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
236 tchars.t_eofc = -1;
237 tchars.t_brkc = '\r';
238 (void) ioctl(fileno(stdin), TIOCSETC, (char *) &tchars);
239 (void) fflush(stdout);
240 putmsg = FALSE;
241 }
242
243
TxClose()244 TxClose()
245
246 /*-----------------------------------------------------------------------------
247 * TxClose resets the terminal to the way we found it.
248 *
249 * Results: None.
250 * Side Effects: None.
251 * Errors: None.
252 *-----------------------------------------------------------------------------
253 */
254
255 {
256 char *dummy, buf [100];
257 sttybuf.sg_flags = sttyflags;
258 (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
259 tchars.t_eofc = eofc;
260 tchars.t_brkc = brkc;
261 (void) ioctl(fileno(stdin), TIOCSETC, (char *) &tchars);
262 fputs(tgoto(cm, 0, tgetnum("li")-1), stdout);
263 dummy = buf;
264 fputs(tgetstr("ve", &dummy), stdout);
265 fputs("\n", stdout);
266 (void) fflush(stdout);
267 }
268
269
TxPutString(field,string)270 TxPutString(field, string)
271 TXFIELD *field; /* The screen field to be overwritten */
272 char *string; /* The character string to be written */
273
274 /*-----------------------------------------------------------------------------
275 * TxPutString displays a string in a given field of the text display.
276 *
277 * Results: None.
278 *
279 * Side Effects:
280 * The given text screen field is overwritten with the given text
281 * string, blank filled and left justified.
282 *
283 * Errors: None.
284 *-----------------------------------------------------------------------------
285 */
286
287 {
288 char format[20];
289 (void) sprintf(format, "%%s%%-%d.%ds", field->tx_size, field->tx_size);
290 (void) printf(format, tgoto(cm, field->tx_x, field->tx_y), string);
291 (void) fflush(stdout);
292 }
293
294
295 char
TxGetChar()296 TxGetChar()
297
298 /*-----------------------------------------------------------------------------
299 * TxGetChar gets the next character from the text keyboard.
300 *
301 * Results: The next character.
302 * Side Effects: None.
303 *-----------------------------------------------------------------------------
304 */
305
306 {
307 putmsg = FALSE;
308 return getchar();
309 }
310
311
TxMsgOK()312 TxMsgOK()
313
314 /*-----------------------------------------------------------------------------
315 * This routine marks it OK to output messages again, just as if text
316 * had been input.
317 *
318 * Results: None.
319 * Side Effects: As above.
320 *-----------------------------------------------------------------------------
321 */
322
323 {
324 if (putmsg) /* message on the screen to be blanked */
325 {
326 TxLine(msgline);
327 printf(" ");
328 TxLine(msgline);
329 }
330 putmsg = FALSE;
331 }
332
333
TxGetLine(prompt,ptr,maxsize)334 TxGetLine(prompt, ptr, maxsize)
335 char *prompt; /* Prompt to be output at beginning of line */
336 char *ptr; /* Place to store the input line */
337 int maxsize; /* Maximum number of characters to be read */
338
339 /*-----------------------------------------------------------------------------
340 * TxGetLine reads a line of text from the terminal. It does so
341 * by positioning the cursor at the bottom of the screen and enabling
342 * echoes again. When the line has been read, echoes etc. are turned
343 * off once more.
344 *
345 * Results: None.
346 * Side Effects: The last line of the text screen is destroyed.
347 * Errors: None.
348 *-----------------------------------------------------------------------------
349 */
350
351 {
352 int i, j;
353
354 putmsg = FALSE;
355 fputs(tgoto(cm, 0, inline), stdout);
356 tputs(ce, 1, OutChar);
357 fputs(prompt, stdout);
358 sttybuf.sg_flags |= ECHO;
359 sttybuf.sg_flags &= ~CBREAK;
360 (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
361
362 /* Input characters until a carriage return is found. Then
363 * erase the control character from the screen.
364 */
365
366 for (i=0; i<maxsize; i++)
367 {
368 ptr[i] = getchar();
369 if (ptr[i] == '\r') break;
370 }
371 for (j=i; j<maxsize; j++)
372 ptr[j] = '\0';
373 fputs("\b\b \b\b", stdout);
374 (void) fflush(stdout);
375
376 /* Reset the terminal into no-echo mode */
377
378 sttybuf.sg_flags |= CBREAK;
379 sttybuf.sg_flags &= ~ECHO;
380 (void) ioctl(fileno(stdin), TIOCSETN, (char *) &sttybuf);
381 }
382
383
TxPutMsg(msg)384 TxPutMsg(msg)
385 char *msg; /* A message (not containing \r or \n) to
386 * be output on the text screen. It must
387 * fit on a single line. /*
388
389 /*-----------------------------------------------------------------------------
390 * TPutMsg outputs a one-line message onto the text screen.
391 *
392 * Results: None.
393 *
394 * Side Effects:
395 * The string in msg is output on the last line of the text display.
396 * If TxPutMsg is called twice between calls to TxGetLine or TxGetChar
397 * then we output the message "More" at the end of the line and
398 * wait for a space to be typed. This is to protect against
399 * multiple error messages overwriting each other.
400 *
401 * Errors: None.
402 *-----------------------------------------------------------------------------
403 */
404
405 {
406 if (putmsg)
407 {
408 fputs(tgoto(cm, 50, msgline), stdout);
409 if (msg[0] == '\7')
410 {
411 putchar ('\7');
412 msg++;
413 }
414 fputs("--More--", stdout);
415 (void) fflush(stdout);
416 while (getchar() != ' ');
417 }
418 putmsg = TRUE;
419 fputs(tgoto(cm, 0, msgline), stdout);
420 tputs(ce, 1, OutChar);
421 fputs(msg, stdout);
422 (void) fflush(stdout);
423 }
424
TxLine(line)425 TxLine(line)
426 short line;
427
428 /*-----------------------------------------------------------------------------
429 * TxLastLine moves the cursor to the first character of the specified
430 * line of the text display.
431 *
432 * Results: None.
433 * Side Effects: None.
434 *-----------------------------------------------------------------------------
435 */
436
437 {
438 fputs(tgoto(cm, 0, line), stdout);
439 (void) fflush(stdout);
440 }
441