2 * Copyright (C) 1984-2000 Mark Nudelman
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Less License, as specified in the README file.
7 * For more information about less, or for information on how to
8 * contact the author, see the README file.
13 * High level routines dealing with the output to the screen.
17 #if MSDOS_COMPILER==WIN32C
21 public int errmsgs; /* Count of messages displayed by error() */
23 public int final_attr;
27 extern int so_s_width, so_e_width;
28 extern int screen_trashed;
29 extern int any_display;
33 * Display the line which is in the line buffer.
46 * Don't output if a signal is pending.
52 curr_attr = AT_NORMAL;
54 for (i = 0; (c = gline(i, &a)) != '\0'; i++)
59 * Changing attributes.
60 * Display the exit sequence for the old attribute
61 * and the enter sequence for the new one.
65 case AT_UNDERLINE: ul_exit(); break;
66 case AT_BOLD: bo_exit(); break;
67 case AT_BLINK: bl_exit(); break;
68 case AT_STANDOUT: so_exit(); break;
72 case AT_UNDERLINE: ul_enter(); break;
73 case AT_BOLD: bo_enter(); break;
74 case AT_BLINK: bl_enter(); break;
75 case AT_STANDOUT: so_enter(); break;
79 if (curr_attr == AT_INVIS)
89 case AT_UNDERLINE: ul_exit(); break;
90 case AT_BOLD: bo_exit(); break;
91 case AT_BLINK: bl_exit(); break;
92 case AT_STANDOUT: so_exit(); break;
94 final_attr = curr_attr;
97 static char obuf[OUTBUF_SIZE];
98 static char *ob = obuf;
101 * Flush buffered output.
103 * If we haven't displayed any file data yet,
104 * output messages on error output (file descriptor 2),
105 * otherwise output on standard output (file descriptor 1).
107 * This has the desirable effect of producing all
108 * error messages on error output if standard output
109 * is directed to a file. It also does the same if
110 * we never produce any real output; for example, if
111 * the input file(s) cannot be opened. If we do
112 * eventually produce output, code in edit() makes
113 * sure these messages can be seen before they are
114 * overwritten or scrolled away.
125 #if MSDOS_COMPILER==WIN32C
126 if (is_tty && any_display)
130 CONSOLE_SCREEN_BUFFER_INFO scr;
134 extern HANDLE con_out;
138 * There is a bug in Win32 WriteConsole() if we're
139 * writing in the last cell with a different color.
140 * To avoid color problems in the bottom line,
141 * we scroll the screen manually, before writing.
143 GetConsoleScreenBufferInfo(con_out, &scr);
144 col = scr.dwCursorPosition.X;
145 row = scr.dwCursorPosition.Y;
146 for (op = obuf; op < obuf + olen; op++)
162 if (row > scr.srWindow.Bottom)
163 win32_scroll_up(row - scr.srWindow.Bottom);
164 WriteConsole(con_out, obuf, olen, &nwritten, NULL);
169 #if MSDOS_COMPILER==MSOFTC
170 if (is_tty && any_display)
178 #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
179 if (is_tty && any_display)
189 fd = (any_display) ? 1 : 2;
190 if (write(fd, obuf, n) != n)
196 * Output a character.
208 if (c == '\n' && is_tty)
215 if (c == '\n' && is_tty) /* In OS-9, '\n' == 0x0D */
220 * Some versions of flush() write to *ob, so we must flush
221 * when we are still one char from the end of obuf.
223 if (ob >= &obuf[sizeof(obuf)-1])
242 * Output an integer in a given radix.
245 iprintnum(num, radix)
252 char buf[INT_STRLEN_BOUND(num)];
261 *s++ = (num % radix) + '0';
262 } while ((num /= radix) != 0);
274 * This function implements printf-like functionality
275 * using a more portable argument list mechanism than printf's.
278 less_printf(fmt, parg)
309 col += iprintnum(n, 10);
319 * If some other non-trivial char is pressed, unget it, so it will
320 * become the next command.
328 while ((c = getchr()) != '\n' && c != '\r')
332 if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
338 * Output a message in the lower left corner of the screen
339 * and wait for carriage return.
347 static char return_to_continue[] = " (press RETURN)";
351 if (any_display && is_tty)
358 col += less_printf(fmt, parg);
360 if (!(any_display && is_tty))
366 putstr(return_to_continue);
368 col += sizeof(return_to_continue) + so_e_width;
375 * Printing the message has probably scrolled the screen.
376 * {{ Unless the terminal doesn't have auto margins,
377 * in which case we just hammered on the right margin. }}
384 static char intr_to_abort[] = "... (interrupt to abort)";
387 * Output a message in the lower left corner of the screen
388 * and don't wait for carriage return.
389 * Usually used to warn that we are beginning a potentially
390 * time-consuming operation.
399 (void) less_printf(fmt, parg);
400 putstr(intr_to_abort);
407 * Output a message in the lower left corner of the screen
408 * and return a single-character response.
418 if (any_display && is_tty)
421 (void) less_printf(fmt, parg);
424 if (!(any_display && is_tty))