#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include "windows.h"
#endif
public int errmsgs;
public int need_clr;
extern int sigs;
extern int sc_width;
extern int so_s_width, so_e_width;
extern int screen_trashed;
extern int any_display;
extern int is_tty;
public void
put_line()
{
register int c;
register int i;
int a;
int curr_attr;
if (ABORT_SIGS())
{
screen_trashed = 1;
return;
}
curr_attr = AT_NORMAL;
for (i = 0; (c = gline(i, &a)) != '\0'; i++)
{
if (a != curr_attr)
{
switch (curr_attr)
{
case AT_UNDERLINE: ul_exit(); break;
case AT_BOLD: bo_exit(); break;
case AT_BLINK: bl_exit(); break;
case AT_STANDOUT: so_exit(); break;
}
switch (a)
{
case AT_UNDERLINE: ul_enter(); break;
case AT_BOLD: bo_enter(); break;
case AT_BLINK: bl_enter(); break;
case AT_STANDOUT: so_enter(); break;
}
curr_attr = a;
}
if (curr_attr == AT_INVIS)
continue;
if (c == '\b')
putbs();
else
putchr(c);
}
switch (curr_attr)
{
case AT_UNDERLINE: ul_exit(); break;
case AT_BOLD: bo_exit(); break;
case AT_BLINK: bl_exit(); break;
case AT_STANDOUT: so_exit(); break;
}
}
static char obuf[OUTBUF_SIZE];
static char *ob = obuf;
public void
flush()
{
register int n;
register int fd;
n = ob - obuf;
if (n == 0)
return;
#if MSDOS_COMPILER==WIN32C
if (is_tty && any_display)
{
char *p;
char *op;
DWORD nwritten = 0;
CONSOLE_SCREEN_BUFFER_INFO scr;
DWORD nchars;
COORD cpos;
WORD nm_attr;
int olen;
extern HANDLE con_out;
extern int nm_fg_color;
extern int nm_bg_color;
#define MAKEATTR(fg,bg) ((WORD)((fg)|((bg)<<4)))
*ob = '\0';
olen = ob - obuf;
nm_attr = MAKEATTR(nm_fg_color, nm_bg_color);
for (op = obuf; *op != '\0'; )
{
GetConsoleScreenBufferInfo(con_out, &scr);
p = strchr(op, '\n');
if (p == NULL &&
scr.dwCursorPosition.X + olen >= sc_width)
{
p = op + sc_width - scr.dwCursorPosition.X - 1;
}
if (scr.dwCursorPosition.Y != scr.srWindow.Bottom ||
p == NULL)
{
WriteConsole(con_out, op, olen,
&nwritten, NULL);
op += olen;
} else
{
WriteConsole(con_out, op, p - op + 1,
&nwritten, NULL);
cpos.X = 0;
cpos.Y = scr.dwCursorPosition.Y;
FillConsoleOutputAttribute(con_out, nm_attr,
sc_width, cpos, &nchars);
olen -= p - op + 1;
op = p + 1;
}
}
ob = obuf;
return;
}
#else
#if MSDOS_COMPILER==MSOFTC
if (is_tty && any_display)
{
*ob = '\0';
_outtext(obuf);
ob = obuf;
return;
}
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
if (is_tty && any_display)
{
*ob = '\0';
cputs(obuf);
ob = obuf;
return;
}
#endif
#endif
#endif
fd = (any_display) ? 1 : 2;
if (write(fd, obuf, n) != n)
screen_trashed = 1;
ob = obuf;
}
public int
putchr(c)
int c;
{
if (need_clr)
{
need_clr = 0;
clear_bot();
}
#if MSDOS_COMPILER
if (c == '\n' && is_tty)
{
putchr('\r');
}
#else
#ifdef _OSK
if (c == '\n' && is_tty)
putchr(0x0A);
#endif
#endif
if (ob >= &obuf[sizeof(obuf)-1])
flush();
*ob++ = c;
return (c);
}
public void
putstr(s)
register char *s;
{
while (*s != '\0')
putchr(*s++);
}
static int
iprintnum(num, radix)
int num;
int radix;
{
register char *s;
int r;
int neg;
char buf[10];
neg = (num < 0);
if (neg)
num = -num;
s = buf;
do
{
*s++ = (num % radix) + '0';
} while ((num /= radix) != 0);
if (neg)
*s++ = '-';
r = s - buf;
while (s > buf)
putchr(*--s);
return (r);
}
static int
iprintf(fmt, parg)
register char *fmt;
PARG *parg;
{
register char *s;
register int n;
register int col;
col = 0;
while (*fmt != '\0')
{
if (*fmt != '%')
{
putchr(*fmt++);
col++;
} else
{
++fmt;
switch (*fmt++) {
case 's':
s = parg->p_string;
parg++;
while (*s != '\0')
{
putchr(*s++);
col++;
}
break;
case 'd':
n = parg->p_int;
parg++;
col += iprintnum(n, 10);
break;
}
}
}
return (col);
}
public void
get_return()
{
int c;
#if ONLY_RETURN
while ((c = getchr()) != '\n' && c != '\r')
bell();
#else
c = getchr();
if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
ungetcc(c);
#endif
}
public void
error(fmt, parg)
char *fmt;
PARG *parg;
{
int col = 0;
static char return_to_continue[] = " (press RETURN)";
errmsgs++;
if (any_display && is_tty)
{
clear_bot();
so_enter();
col += so_s_width;
}
col += iprintf(fmt, parg);
if (!(any_display && is_tty))
{
putchr('\n');
return;
}
putstr(return_to_continue);
so_exit();
col += sizeof(return_to_continue) + so_e_width;
get_return();
lower_left();
if (col >= sc_width)
screen_trashed = 1;
flush();
}
static char intr_to_abort[] = "... (interrupt to abort)";
public void
ierror(fmt, parg)
char *fmt;
PARG *parg;
{
clear_bot();
so_enter();
(void) iprintf(fmt, parg);
putstr(intr_to_abort);
so_exit();
flush();
need_clr = 1;
}
public int
query(fmt, parg)
char *fmt;
PARG *parg;
{
register int c;
int col = 0;
if (any_display && is_tty)
clear_bot();
(void) iprintf(fmt, parg);
c = getchr();
if (!(any_display && is_tty))
{
putchr('\n');
return (c);
}
lower_left();
if (col >= sc_width)
screen_trashed = 1;
flush();
return (c);
}