aboutsummaryrefslogtreecommitdiffstats
path: root/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'screen.c')
-rw-r--r--screen.c375
1 files changed, 236 insertions, 139 deletions
diff --git a/screen.c b/screen.c
index b5d038831748..398a85835681 100644
--- a/screen.c
+++ b/screen.c
@@ -1,12 +1,38 @@
/*
+ * Copyright (c) 1984 through 2008, William LeFebvre
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of William LeFebvre nor the names of other
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
* Top users/processes display for Unix
* Version 3
- *
- * This program may be freely redistributed,
- * but this entire comment MUST remain intact.
- *
- * Copyright (c) 1984, 1989, William LeFebvre, Rice University
- * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
*/
/* This file contains the routines that interface to termcap and stty/gtty.
@@ -21,20 +47,52 @@
#include "os.h"
#include "top.h"
+#if HAVE_CURSES_H && HAVE_TERM_H
+#include <curses.h>
+#include <term.h>
+#else
+#if HAVE_TERMCAP_H
+#include <termcap.h>
+#else
+#if HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+#endif
+
+#if !HAVE_DECL_TPUTS
+int tputs(const char *, int, int (*)(int));
+#endif
+#if !HAVE_DECL_TGOTO
+char *tgoto(const char *, int, int);
+#endif
+#if !HAVE_DECL_TGETENT
+int tgetent(const char *, char *);
+#endif
+#if !HAVE_DECL_TGETFLAG
+int tgetflag(const char *);
+#endif
+#if !HAVE_DECL_TGETNUM
+int tgetnum(const char *);
+#endif
+#if !HAVE_DECL_TGETSTR
+char *tgetstr(const char *, char **);
+#endif
+
#include <sys/ioctl.h>
#ifdef CBREAK
# include <sgtty.h>
-# define SGTTY
+# define USE_SGTTY
#else
# ifdef TCGETA
-# define TERMIO
+# define USE_TERMIO
# include <termio.h>
# else
-# define TERMIOS
+# define USE_TERMIOS
# include <termios.h>
# endif
#endif
-#if defined(TERMIO) || defined(TERMIOS)
+#if defined(USE_TERMIO) || defined(USE_TERMIOS)
# ifndef TAB3
# ifdef OXTABS
# define TAB3 OXTABS
@@ -43,45 +101,46 @@
# endif
# endif
#endif
+
#include "screen.h"
#include "boolean.h"
-extern char *myname;
+#define putcap(str) (void)((str) != NULL ? tputs(str, 1, putstdout) : 0)
-int putstdout();
+extern char *myname;
-int overstrike;
-int screen_length;
-int screen_width;
char ch_erase;
char ch_kill;
+char ch_werase;
char smart_terminal;
+int screen_length;
+int screen_width;
+
char PC;
-char *tgetstr();
-char *tgoto();
-char termcap_buf[1024];
-char string_buffer[1024];
-char home[15];
-char lower_left[15];
-char *clear_line;
-char *clear_screen;
-char *clear_to_end;
-char *cursor_motion;
-char *start_standout;
-char *end_standout;
-char *terminal_init;
-char *terminal_end;
-short ospeed;
-
-#ifdef SGTTY
+
+static int tc_overstrike;
+static char termcap_buf[1024];
+static char string_buffer[1024];
+static char home[15];
+static char lower_left[15];
+static char *tc_clear_line;
+static char *tc_clear_screen;
+static char *tc_clear_to_end;
+static char *tc_cursor_motion;
+static char *tc_start_standout;
+static char *tc_end_standout;
+static char *terminal_init;
+static char *terminal_end;
+
+#ifdef USE_SGTTY
static struct sgttyb old_settings;
static struct sgttyb new_settings;
#endif
-#ifdef TERMIO
+#ifdef USE_TERMIO
static struct termio old_settings;
static struct termio new_settings;
#endif
-#ifdef TERMIOS
+#ifdef USE_TERMIOS
static struct termios old_settings;
static struct termios new_settings;
#endif
@@ -95,9 +154,61 @@ static int new_lword;
#define STDOUT 1
#define STDERR 2
-init_termcap(interactive)
+/* This has to be defined as a subroutine for tputs (instead of a macro) */
+
+static int
+putstdout(TPUTS_PUTC_ARGTYPE ch)
-int interactive;
+{
+ return putchar((int)ch);
+}
+
+void
+screen_getsize()
+
+{
+
+#ifdef TIOCGWINSZ
+
+ struct winsize ws;
+
+ if (ioctl (1, TIOCGWINSZ, &ws) != -1)
+ {
+ if (ws.ws_row != 0)
+ {
+ screen_length = ws.ws_row;
+ }
+ if (ws.ws_col != 0)
+ {
+ screen_width = ws.ws_col - 1;
+ }
+ }
+
+#else
+#ifdef TIOCGSIZE
+
+ struct ttysize ts;
+
+ if (ioctl (1, TIOCGSIZE, &ts) != -1)
+ {
+ if (ts.ts_lines != 0)
+ {
+ screen_length = ts.ts_lines;
+ }
+ if (ts.ts_cols != 0)
+ {
+ screen_width = ts.ts_cols - 1;
+ }
+ }
+
+#endif /* TIOCGSIZE */
+#endif /* TIOCGWINSZ */
+
+ (void) strcpy(lower_left, tgoto(tc_cursor_motion, 0, screen_length - 1));
+}
+
+int
+screen_readtermcap(int interactive)
{
char *bufptr;
@@ -110,11 +221,11 @@ int interactive;
screen_width = MAX_COLS;
screen_length = 0;
- if (!interactive)
+ if (interactive == No)
{
/* pretend we have a dumb terminal */
smart_terminal = No;
- return;
+ return No;
}
/* assume we have a smart terminal until proven otherwise */
@@ -128,7 +239,7 @@ int interactive;
if (term_name == NULL)
{
smart_terminal = No;
- return;
+ return No;
}
/* now get the termcap entry */
@@ -146,21 +257,21 @@ int interactive;
/* pretend it's dumb and proceed */
smart_terminal = No;
- return;
+ return No;
}
/* "hardcopy" immediately indicates a very stupid terminal */
if (tgetflag("hc"))
{
smart_terminal = No;
- return;
+ return No;
}
/* set up common terminal capabilities */
if ((screen_length = tgetnum("li")) <= 0)
{
screen_length = smart_terminal = 0;
- return;
+ return No;
}
/* screen_width is a little different */
@@ -174,70 +285,73 @@ int interactive;
}
/* terminals that overstrike need special attention */
- overstrike = tgetflag("os");
+ tc_overstrike = tgetflag("os");
/* initialize the pointer into the termcap string buffer */
bufptr = string_buffer;
/* get "ce", clear to end */
- if (!overstrike)
+ if (!tc_overstrike)
{
- clear_line = tgetstr("ce", &bufptr);
+ tc_clear_line = tgetstr("ce", &bufptr);
}
/* get necessary capabilities */
- if ((clear_screen = tgetstr("cl", &bufptr)) == NULL ||
- (cursor_motion = tgetstr("cm", &bufptr)) == NULL)
+ if ((tc_clear_screen = tgetstr("cl", &bufptr)) == NULL ||
+ (tc_cursor_motion = tgetstr("cm", &bufptr)) == NULL)
{
smart_terminal = No;
- return;
+ return No;
}
/* get some more sophisticated stuff -- these are optional */
- clear_to_end = tgetstr("cd", &bufptr);
+ tc_clear_to_end = tgetstr("cd", &bufptr);
terminal_init = tgetstr("ti", &bufptr);
terminal_end = tgetstr("te", &bufptr);
- start_standout = tgetstr("so", &bufptr);
- end_standout = tgetstr("se", &bufptr);
+ tc_start_standout = tgetstr("so", &bufptr);
+ tc_end_standout = tgetstr("se", &bufptr);
/* pad character */
PC = (PCptr = tgetstr("pc", &bufptr)) ? *PCptr : 0;
/* set convenience strings */
- (void) strcpy(home, tgoto(cursor_motion, 0, 0));
- /* (lower_left is set in get_screensize) */
+ (void) strcpy(home, tgoto(tc_cursor_motion, 0, 0));
+ /* (lower_left is set in screen_getsize) */
/* get the actual screen size with an ioctl, if needed */
/* This may change screen_width and screen_length, and it always
sets lower_left. */
- get_screensize();
+ screen_getsize();
/* if stdout is not a terminal, pretend we are a dumb terminal */
-#ifdef SGTTY
+#ifdef USE_SGTTY
if (ioctl(STDOUT, TIOCGETP, &old_settings) == -1)
{
smart_terminal = No;
}
#endif
-#ifdef TERMIO
+#ifdef USE_TERMIO
if (ioctl(STDOUT, TCGETA, &old_settings) == -1)
{
smart_terminal = No;
}
#endif
-#ifdef TERMIOS
+#ifdef USE_TERMIOS
if (tcgetattr(STDOUT, &old_settings) == -1)
{
smart_terminal = No;
}
#endif
+
+ return smart_terminal;
}
-init_screen()
+void
+screen_init()
{
/* get the old settings for safe keeping */
-#ifdef SGTTY
+#ifdef USE_SGTTY
if (ioctl(STDOUT, TIOCGETP, &old_settings) != -1)
{
/* copy the settings so we can modify them */
@@ -251,6 +365,7 @@ init_screen()
/* remember the erase and kill characters */
ch_erase = old_settings.sg_erase;
ch_kill = old_settings.sg_kill;
+ ch_werase = old_settings.sg_werase;
#ifdef TOStop
/* get the local mode word */
@@ -267,7 +382,7 @@ init_screen()
putcap(terminal_init);
}
#endif
-#ifdef TERMIO
+#ifdef USE_TERMIO
if (ioctl(STDOUT, TCGETA, &old_settings) != -1)
{
/* copy the settings so we can modify them */
@@ -281,8 +396,9 @@ init_screen()
(void) ioctl(STDOUT, TCSETA, &new_settings);
/* remember the erase and kill characters */
- ch_erase = old_settings.c_cc[VERASE];
- ch_kill = old_settings.c_cc[VKILL];
+ ch_erase = old_settings.c_cc[VERASE];
+ ch_kill = old_settings.c_cc[VKILL];
+ ch_werase = old_settings.c_cc[VWERASE];
/* remember that it really is a terminal */
is_a_terminal = Yes;
@@ -291,7 +407,7 @@ init_screen()
putcap(terminal_init);
}
#endif
-#ifdef TERMIOS
+#ifdef USE_TERMIOS
if (tcgetattr(STDOUT, &old_settings) != -1)
{
/* copy the settings so we can modify them */
@@ -305,8 +421,9 @@ init_screen()
(void) tcsetattr(STDOUT, TCSADRAIN, &new_settings);
/* remember the erase and kill characters */
- ch_erase = old_settings.c_cc[VERASE];
- ch_kill = old_settings.c_cc[VKILL];
+ ch_erase = old_settings.c_cc[VERASE];
+ ch_kill = old_settings.c_cc[VKILL];
+ ch_werase = old_settings.c_cc[VWERASE];
/* remember that it really is a terminal */
is_a_terminal = Yes;
@@ -323,14 +440,15 @@ init_screen()
}
}
-end_screen()
+void
+screen_end()
{
/* move to the lower left, clear the line and send "te" */
if (smart_terminal)
{
putcap(lower_left);
- putcap(clear_line);
+ putcap(tc_clear_line);
fflush(stdout);
putcap(terminal_end);
}
@@ -338,37 +456,38 @@ end_screen()
/* if we have settings to reset, then do so */
if (is_a_terminal)
{
-#ifdef SGTTY
+#ifdef USE_SGTTY
(void) ioctl(STDOUT, TIOCSETP, &old_settings);
#ifdef TOStop
(void) ioctl(STDOUT, TIOCLSET, &old_lword);
#endif
#endif
-#ifdef TERMIO
+#ifdef USE_TERMIO
(void) ioctl(STDOUT, TCSETA, &old_settings);
#endif
-#ifdef TERMIOS
+#ifdef USE_TERMIOS
(void) tcsetattr(STDOUT, TCSADRAIN, &old_settings);
#endif
}
}
-reinit_screen()
+void
+screen_reinit()
{
/* install our settings if it is a terminal */
if (is_a_terminal)
{
-#ifdef SGTTY
+#ifdef USE_SGTTY
(void) ioctl(STDOUT, TIOCSETP, &new_settings);
#ifdef TOStop
(void) ioctl(STDOUT, TIOCLSET, &new_lword);
#endif
#endif
-#ifdef TERMIO
+#ifdef USE_TERMIO
(void) ioctl(STDOUT, TCSETA, &new_settings);
#endif
-#ifdef TERMIOS
+#ifdef USE_TERMIOS
(void) tcsetattr(STDOUT, TCSADRAIN, &new_settings);
#endif
}
@@ -380,59 +499,22 @@ reinit_screen()
}
}
-get_screensize()
+void
+screen_move(int x, int y)
{
-
-#ifdef TIOCGWINSZ
-
- struct winsize ws;
-
- if (ioctl (1, TIOCGWINSZ, &ws) != -1)
- {
- if (ws.ws_row != 0)
- {
- screen_length = ws.ws_row;
- }
- if (ws.ws_col != 0)
- {
- screen_width = ws.ws_col - 1;
- }
- }
-
-#else
-#ifdef TIOCGSIZE
-
- struct ttysize ts;
-
- if (ioctl (1, TIOCGSIZE, &ts) != -1)
- {
- if (ts.ts_lines != 0)
- {
- screen_length = ts.ts_lines;
- }
- if (ts.ts_cols != 0)
- {
- screen_width = ts.ts_cols - 1;
- }
- }
-
-#endif /* TIOCGSIZE */
-#endif /* TIOCGWINSZ */
-
- (void) strcpy(lower_left, tgoto(cursor_motion, 0, screen_length - 1));
+ tputs(tgoto(tc_cursor_motion, x, y), 1, putstdout);
}
-standout(msg)
-
-char *msg;
+void
+screen_standout(char *msg)
{
if (smart_terminal)
{
- putcap(start_standout);
+ putcap(tc_start_standout);
fputs(msg, stdout);
- putcap(end_standout);
+ putcap(tc_end_standout);
}
else
{
@@ -440,40 +522,64 @@ char *msg;
}
}
-clear()
+void
+screen_clear()
{
if (smart_terminal)
{
- putcap(clear_screen);
+ putcap(tc_clear_screen);
}
}
-clear_eol(len)
+int
+screen_cte()
+
+{
+ if (smart_terminal)
+ {
+ if (tc_clear_to_end)
+ {
+ putcap(tc_clear_to_end);
+ return(Yes);
+ }
+ }
+ return(No);
+}
-int len;
+void
+screen_cleareol(int len)
{
- if (smart_terminal && !overstrike && len > 0)
+ int i;
+
+ if (smart_terminal && !tc_overstrike && len > 0)
{
- if (clear_line)
+ if (tc_clear_line)
{
- putcap(clear_line);
- return(0);
+ putcap(tc_clear_line);
+ return;
}
else
{
- while (len-- > 0)
+ i = 0;
+ while (i++ < 0)
{
putchar(' ');
}
- return(1);
+ i = 0;
+ while (i++ < 0)
+ {
+ putchar('\b');
+ }
+ return;
}
}
- return(-1);
+ return;
}
-go_home()
+void
+screen_home()
{
if (smart_terminal)
@@ -482,13 +588,4 @@ go_home()
}
}
-/* This has to be defined as a subroutine for tputs (instead of a macro) */
-
-putstdout(ch)
-
-char ch;
-
-{
- putchar(ch);
-}