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 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 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 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 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 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 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 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 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 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 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