Annotation of src/usr.bin/top/screen.c, Revision 1.17
1.17 ! otto 1: /* $OpenBSD: screen.c,v 1.16 2007/04/04 19:12:15 otto Exp $ */
1.1 downsj 2:
3: /*
4: * Top users/processes display for Unix
5: * Version 3
6: *
1.8 deraadt 7: * Copyright (c) 1984, 1989, William LeFebvre, Rice University
8: * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
1.1 downsj 9: *
1.8 deraadt 10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22: * IN NO EVENT SHALL THE AUTHOR OR HIS EMPLOYER BE LIABLE FOR ANY DIRECT, INDIRECT,
23: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.1 downsj 29: */
30:
1.10 deraadt 31: /*
32: * This file contains the routines that interface to termcap and stty/gtty.
1.14 deraadt 33: *
1.10 deraadt 34: * Paul Vixie, February 1987: converted to use ioctl() instead of stty/gtty.
1.14 deraadt 35: *
1.10 deraadt 36: * I put in code to turn on the TOSTOP bit while top was running, but I didn't
37: * really like the results. If you desire it, turn on the preprocessor
38: * variable "TOStop". --wnl
1.1 downsj 39: */
40:
1.2 downsj 41: #include <sys/types.h>
42: #include <sys/ioctl.h>
1.17 ! otto 43: #include <curses.h>
1.13 millert 44: #include <err.h>
1.2 downsj 45: #include <stdio.h>
46: #include <stdlib.h>
47: #include <term.h>
48: #include <unistd.h>
49:
1.1 downsj 50: #include "top.h"
51: #include "screen.h"
52: #include "boolean.h"
53:
1.17 ! otto 54: int screen_length, screen_width;
! 55: char ch_erase, ch_kill, smart_terminal;
1.1 downsj 56:
1.12 deraadt 57: static struct termios old_settings, new_settings;
1.17 ! otto 58: static char is_a_terminal = No;
1.1 downsj 59:
1.9 pvalchev 60: void
61: init_termcap(int interactive)
1.1 downsj 62: {
1.17 ! otto 63: char *term_name;
1.10 deraadt 64: int status;
65:
66: /* set defaults in case we aren't smart */
67: screen_width = MAX_COLS;
68: screen_length = 0;
69:
70: if (!interactive) {
71: /* pretend we have a dumb terminal */
72: smart_terminal = No;
73: return;
74: }
75: /* assume we have a smart terminal until proven otherwise */
76: smart_terminal = Yes;
77:
78: /* get the terminal name */
79: term_name = getenv("TERM");
80:
81: /* if there is no TERM, assume it's a dumb terminal */
82: /* patch courtesy of Sam Horrocks at telegraph.ics.uci.edu */
83: if (term_name == NULL) {
84: smart_terminal = No;
85: return;
86: }
87:
88: /* now get the termcap entry */
89: if ((status = tgetent(NULL, term_name)) != 1) {
90: if (status == -1)
1.12 deraadt 91: warnx("can't open termcap file");
1.10 deraadt 92: else
1.12 deraadt 93: warnx("no termcap entry for a `%s' terminal", term_name);
1.10 deraadt 94:
95: /* pretend it's dumb and proceed */
96: smart_terminal = No;
97: return;
1.1 downsj 98: }
1.10 deraadt 99:
100: /* "hardcopy" immediately indicates a very stupid terminal */
101: if (tgetflag("hc")) {
102: smart_terminal = No;
103: return;
104: }
1.17 ! otto 105:
1.10 deraadt 106: /* set up common terminal capabilities */
107: if ((screen_length = tgetnum("li")) <= Header_lines) {
108: screen_length = smart_terminal = 0;
109: return;
110: }
111:
112: /* screen_width is a little different */
113: if ((screen_width = tgetnum("co")) == -1)
114: screen_width = 79;
1.1 downsj 115: else
1.10 deraadt 116: screen_width -= 1;
117:
1.17 ! otto 118: /* get necessary capabilities */
! 119: if (tgetstr("cl", NULL) == NULL || tgetstr("cm", NULL) == NULL) {
! 120: smart_terminal = No;
! 121: return;
! 122: }
1.10 deraadt 123:
124: /* get the actual screen size with an ioctl, if needed */
125: /*
126: * This may change screen_width and screen_length, and it always sets
127: * lower_left.
128: */
129: get_screensize();
130:
131: /* if stdout is not a terminal, pretend we are a dumb terminal */
132: if (tcgetattr(STDOUT_FILENO, &old_settings) == -1)
133: smart_terminal = No;
1.1 downsj 134: }
135:
1.9 pvalchev 136: void
137: init_screen(void)
1.1 downsj 138: {
1.10 deraadt 139: /* get the old settings for safe keeping */
140: if (tcgetattr(STDOUT_FILENO, &old_settings) != -1) {
141: /* copy the settings so we can modify them */
142: new_settings = old_settings;
143: /* turn off ICANON, character echo and tab expansion */
144: new_settings.c_lflag &= ~(ICANON | ECHO);
145: new_settings.c_oflag &= ~(OXTABS);
146: new_settings.c_cc[VMIN] = 1;
147: new_settings.c_cc[VTIME] = 0;
1.17 ! otto 148:
1.10 deraadt 149: (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
150: /* remember the erase and kill characters */
151: ch_erase = old_settings.c_cc[VERASE];
152: ch_kill = old_settings.c_cc[VKILL];
153:
154: is_a_terminal = Yes;
1.17 ! otto 155: #if 0
1.10 deraadt 156: /* send the termcap initialization string */
157: putcap(terminal_init);
1.17 ! otto 158: #endif
1.10 deraadt 159: }
160: if (!is_a_terminal) {
161: /* not a terminal at all---consider it dumb */
162: smart_terminal = No;
163: }
1.17 ! otto 164:
! 165: if (smart_terminal)
! 166: initscr();
1.1 downsj 167: }
168:
1.9 pvalchev 169: void
170: end_screen(void)
1.1 downsj 171: {
1.17 ! otto 172: if (smart_terminal)
! 173: endwin();
1.10 deraadt 174: if (is_a_terminal)
175: (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &old_settings);
1.1 downsj 176: }
177:
1.9 pvalchev 178: void
179: reinit_screen(void)
1.1 downsj 180: {
1.17 ! otto 181: #if 0
1.10 deraadt 182: /* install our settings if it is a terminal */
183: if (is_a_terminal)
184: (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
185:
186: /* send init string */
187: if (smart_terminal)
188: putcap(terminal_init);
1.17 ! otto 189: #endif
1.1 downsj 190: }
191:
1.9 pvalchev 192: void
193: get_screensize(void)
1.1 downsj 194: {
1.10 deraadt 195: struct winsize ws;
1.1 downsj 196:
1.10 deraadt 197: if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
198: if (ws.ws_row != 0)
199: screen_length = ws.ws_row;
200: if (ws.ws_col != 0)
201: screen_width = ws.ws_col - 1;
202: }
1.1 downsj 203: }
204:
1.9 pvalchev 205: void
1.17 ! otto 206: go_home(void)
1.1 downsj 207: {
1.10 deraadt 208: if (smart_terminal) {
1.17 ! otto 209: move(0, 0);
! 210: refresh();
1.10 deraadt 211: }
1.1 downsj 212: }
213:
214: /* This has to be defined as a subroutine for tputs (instead of a macro) */
1.9 pvalchev 215: int
216: putstdout(int ch)
1.1 downsj 217: {
1.10 deraadt 218: int ret;
1.7 deraadt 219:
1.10 deraadt 220: ret = putchar(ch);
221: if (ret == EOF)
222: exit(1);
223: return (ret);
1.1 downsj 224: }