GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/top/screen.c Lines: 0 60 0.0 %
Date: 2017-11-07 Branches: 0 36 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: screen.c,v 1.21 2017/03/15 04:24:14 deraadt Exp $	 */
2
3
/*
4
 *  Top users/processes display for Unix
5
 *  Version 3
6
 *
7
 * Copyright (c) 1984, 1989, William LeFebvre, Rice University
8
 * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
9
 *
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.
29
 */
30
31
/*
32
 * This file contains the routines that interface to termcap and stty/gtty.
33
 *
34
 * Paul Vixie, February 1987: converted to use ioctl() instead of stty/gtty.
35
 *
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
39
 */
40
41
#include <sys/types.h>
42
#include <sys/ioctl.h>
43
#include <curses.h>
44
#include <err.h>
45
#include <stdio.h>
46
#include <stdlib.h>
47
#include <term.h>
48
#include <unistd.h>
49
50
#include "top.h"
51
#include "screen.h"
52
#include "layout.h"
53
#include "boolean.h"
54
55
int	screen_length, screen_width;
56
char	ch_erase, ch_kill, smart_terminal;
57
58
static struct termios old_settings, new_settings;
59
static char is_a_terminal = No;
60
61
void
62
init_termcap(int interactive)
63
{
64
	char *term_name;
65
	int status;
66
67
	/* set defaults in case we aren't smart */
68
	screen_width = MAX_COLS;
69
	screen_length = 0;
70
71
	if (!interactive) {
72
		/* pretend we have a dumb terminal */
73
		smart_terminal = No;
74
		return;
75
	}
76
	/* assume we have a smart terminal until proven otherwise */
77
	smart_terminal = Yes;
78
79
	/* get the terminal name */
80
	term_name = getenv("TERM");
81
82
	/* if there is no TERM, assume it's a dumb terminal */
83
	/* patch courtesy of Sam Horrocks at telegraph.ics.uci.edu */
84
	if (term_name == NULL) {
85
		smart_terminal = No;
86
		return;
87
	}
88
89
	/* now get the termcap entry */
90
	if ((status = tgetent(NULL, term_name)) != 1) {
91
		if (status == -1)
92
			warnx("can't open termcap file");
93
		else
94
			warnx("no termcap entry for a `%s' terminal", term_name);
95
96
		/* pretend it's dumb and proceed */
97
		smart_terminal = No;
98
		return;
99
	}
100
101
	/* "hardcopy" immediately indicates a very stupid terminal */
102
	if (tgetflag("hc")) {
103
		smart_terminal = No;
104
		return;
105
	}
106
107
	/* set up common terminal capabilities */
108
	if ((screen_length = tgetnum("li")) <= y_procs) {
109
		screen_length = smart_terminal = 0;
110
		return;
111
	}
112
113
	/* screen_width is a little different */
114
	if ((screen_width = tgetnum("co")) == -1)
115
		screen_width = 79;
116
	else
117
		screen_width -= 1;
118
119
	/* get necessary capabilities */
120
	if (tgetstr("cl", NULL) == NULL || tgetstr("cm", NULL) == NULL) {
121
		smart_terminal = No;
122
		return;
123
	}
124
125
	/* get the actual screen size with an ioctl, if needed */
126
	/*
127
	 * This may change screen_width and screen_length, and it always sets
128
	 * lower_left.
129
	 */
130
	get_screensize();
131
132
	/* if stdout is not a terminal, pretend we are a dumb terminal */
133
	if (tcgetattr(STDOUT_FILENO, &old_settings) == -1)
134
		smart_terminal = No;
135
}
136
137
void
138
init_screen(void)
139
{
140
	/* get the old settings for safe keeping */
141
	if (tcgetattr(STDOUT_FILENO, &old_settings) != -1) {
142
		/* copy the settings so we can modify them */
143
		new_settings = old_settings;
144
		/* turn off ICANON, character echo and tab expansion */
145
		new_settings.c_lflag &= ~(ICANON | ECHO);
146
		new_settings.c_oflag &= ~(OXTABS);
147
		new_settings.c_cc[VMIN] = 1;
148
		new_settings.c_cc[VTIME] = 0;
149
150
		(void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
151
		/* remember the erase and kill characters */
152
		ch_erase = old_settings.c_cc[VERASE];
153
		ch_kill = old_settings.c_cc[VKILL];
154
155
		is_a_terminal = Yes;
156
#if 0
157
		/* send the termcap initialization string */
158
		putcap(terminal_init);
159
#endif
160
	}
161
	if (!is_a_terminal) {
162
		/* not a terminal at all---consider it dumb */
163
		smart_terminal = No;
164
	}
165
166
	if (smart_terminal)
167
		initscr();
168
}
169
170
void
171
end_screen(void)
172
{
173
	if (smart_terminal) {
174
		move(screen_length-1, 0);
175
		clrtoeol();
176
		refresh();
177
		endwin();
178
	}
179
	if (is_a_terminal)
180
		(void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &old_settings);
181
}
182
183
void
184
reinit_screen(void)
185
{
186
#if 0
187
	/* install our settings if it is a terminal */
188
	if (is_a_terminal)
189
		(void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
190
191
	/* send init string */
192
	if (smart_terminal)
193
		putcap(terminal_init);
194
#endif
195
}
196
197
void
198
get_screensize(void)
199
{
200
	struct winsize ws;
201
202
	if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
203
		if (ws.ws_row != 0)
204
			screen_length = ws.ws_row;
205
		if (ws.ws_col != 0)
206
			screen_width = ws.ws_col - 1;
207
	}
208
}
209
210
void
211
go_home(void)
212
{
213
	if (smart_terminal) {
214
		move(0, 0);
215
		refresh();
216
	}
217
}