1 /* 2 * Copyright (c) 1988 Mark Nudleman 3 * Copyright (c) 1988 Regents of the University of California. 4 * All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)output.c 5.10 (Berkeley) 07/24/91"; 11 #endif /* not lint */ 12 13 /* 14 * High level routines dealing with the output to the screen. 15 */ 16 17 #include <stdio.h> 18 #include <less.h> 19 20 int errmsgs; /* Count of messages displayed by error() */ 21 22 extern int sigs; 23 extern int sc_width, sc_height; 24 extern int ul_width, ue_width; 25 extern int so_width, se_width; 26 extern int bo_width, be_width; 27 extern int tabstop; 28 extern int screen_trashed; 29 extern int any_display; 30 extern char *line; 31 32 /* display the line which is in the line buffer. */ 33 put_line() 34 { 35 register char *p; 36 register int c; 37 register int column; 38 extern int auto_wrap, ignaw; 39 40 if (sigs) 41 { 42 /* 43 * Don't output if a signal is pending. 44 */ 45 screen_trashed = 1; 46 return; 47 } 48 49 if (line == NULL) 50 line = ""; 51 52 column = 0; 53 for (p = line; *p != '\0'; p++) 54 { 55 switch (c = *p) 56 { 57 case UL_CHAR: 58 ul_enter(); 59 column += ul_width +1; 60 break; 61 case UE_CHAR: 62 ul_exit(); 63 column += ue_width; 64 break; 65 case BO_CHAR: 66 bo_enter(); 67 column += bo_width +1; 68 break; 69 case BE_CHAR: 70 bo_exit(); 71 column += be_width; 72 break; 73 case '\t': 74 do 75 { 76 putchr(' '); 77 column++; 78 } while ((column % tabstop) != 0); 79 break; 80 case '\b': 81 putbs(); 82 column--; 83 break; 84 default: 85 if (c & 0200) 86 { 87 /* 88 * Control characters arrive here as the 89 * normal character [CARAT_CHAR(c)] with 90 * the 0200 bit set. See pappend(). 91 */ 92 putchr('^'); 93 putchr(c & 0177); 94 column += 2; 95 } else 96 { 97 putchr(c); 98 column++; 99 } 100 } 101 } 102 if (column < sc_width || !auto_wrap || ignaw) 103 putchr('\n'); 104 } 105 106 static char obuf[1024]; 107 static char *ob = obuf; 108 109 /* 110 * Flush buffered output. 111 */ 112 flush() 113 { 114 register int n; 115 116 n = ob - obuf; 117 if (n == 0) 118 return; 119 if (write(1, obuf, n) != n) 120 screen_trashed = 1; 121 ob = obuf; 122 } 123 124 /* 125 * Purge any pending output. 126 */ 127 purge() 128 { 129 130 ob = obuf; 131 } 132 133 /* 134 * Output a character. 135 */ 136 putchr(c) 137 int c; 138 { 139 if (ob >= &obuf[sizeof(obuf)]) 140 flush(); 141 *ob++ = c; 142 } 143 144 /* 145 * Output a string. 146 */ 147 putstr(s) 148 register char *s; 149 { 150 while (*s != '\0') 151 putchr(*s++); 152 } 153 154 int cmdstack; 155 static char return_to_continue[] = "(press RETURN)"; 156 157 /* 158 * Output a message in the lower left corner of the screen 159 * and wait for carriage return. 160 */ 161 error(s) 162 char *s; 163 { 164 int ch; 165 166 ++errmsgs; 167 if (!any_display) { 168 /* 169 * Nothing has been displayed yet. Output this message on 170 * error output (file descriptor 2) and don't wait for a 171 * keystroke to continue. 172 * 173 * This has the desirable effect of producing all error 174 * messages on error output if standard output is directed 175 * to a file. It also does the same if we never produce 176 * any real output; for example, if the input file(s) cannot 177 * be opened. If we do eventually produce output, code in 178 * edit() makes sure these messages can be seen before they 179 * are overwritten or scrolled away. 180 */ 181 (void)write(2, s, strlen(s)); 182 (void)write(2, "\n", 1); 183 return; 184 } 185 186 lower_left(); 187 clear_eol(); 188 so_enter(); 189 if (s) { 190 putstr(s); 191 putstr(" "); 192 } 193 putstr(return_to_continue); 194 so_exit(); 195 196 if ((ch = getchr()) != '\n') { 197 if (ch == 'q') 198 quit(); 199 cmdstack = ch; 200 } 201 lower_left(); 202 203 if (strlen(s) + sizeof(return_to_continue) + 204 so_width + se_width + 1 > sc_width) 205 /* 206 * Printing the message has probably scrolled the screen. 207 * {{ Unless the terminal doesn't have auto margins, 208 * in which case we just hammered on the right margin. }} 209 */ 210 repaint(); 211 flush(); 212 } 213 214 static char intr_to_abort[] = "... (interrupt to abort)"; 215 216 ierror(s) 217 char *s; 218 { 219 lower_left(); 220 clear_eol(); 221 so_enter(); 222 putstr(s); 223 putstr(intr_to_abort); 224 so_exit(); 225 flush(); 226 } 227