1 /*	$OpenBSD: cmd.c,v 1.8 2003/07/18 23:11:43 david Exp $	*/
2 /*	$NetBSD: cmd.c,v 1.4 1996/02/08 20:44:57 mycroft Exp $	*/
3 
4 /*
5  * Copyright (c) 1983, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Edward Wang at The University of California, Berkeley.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)cmd.c	8.1 (Berkeley) 6/6/93";
39 #else
40 static char rcsid[] = "$OpenBSD: cmd.c,v 1.8 2003/07/18 23:11:43 david Exp $";
41 #endif
42 #endif /* not lint */
43 
44 #include "defs.h"
45 #include "char.h"
46 
47 #include <sys/types.h>
48 #include <unistd.h>
49 
docmd()50 docmd()
51 {
52 	int c;
53 	struct ww *w;
54 	char out = 0;
55 
56 	while (!out && !quit) {
57 		if ((c = wwgetc()) < 0) {
58 			if (terse)
59 				wwsetcursor(0, 0);
60 			else {
61 				wwputs("Command: ", cmdwin);
62 				wwcurtowin(cmdwin);
63 			}
64 			do
65 				wwiomux();
66 			while ((c = wwgetc()) < 0);
67 		}
68 		if (!terse)
69 			wwputc('\n', cmdwin);
70 		switch (c) {
71 		default:
72 			if (c != escapec)
73 				break;
74 		case 'h': case 'j': case 'k': case 'l':
75 		case 'y': case 'p':
76 		case ctrl('y'):
77 		case ctrl('e'):
78 		case ctrl('u'):
79 		case ctrl('d'):
80 		case ctrl('b'):
81 		case ctrl('f'):
82 		case ctrl('s'):
83 		case ctrl('q'):
84 		case ctrl('['):
85 			if (selwin == 0) {
86 				error("No window.");
87 				continue;
88 			}
89 		}
90 		switch (c) {
91 		case '1': case '2': case '3': case '4': case '5':
92 		case '6': case '7': case '8': case '9':
93 			if ((w = window[c - '1']) == 0) {
94 				error("%c: No such window.", c);
95 				break;
96 			}
97 			setselwin(w);
98 			if (checkproc(selwin) >= 0)
99 				 out = 1;
100 			break;
101 		case '%':
102 			if ((w = getwindow()) != 0)
103 				setselwin(w);
104 			break;
105 		case ctrl('^'):
106 			if (lastselwin != 0) {
107 				setselwin(lastselwin);
108 				if (checkproc(selwin) >= 0)
109 					out = 1;
110 			} else
111 				error("No previous window.");
112 			break;
113 		case 'c':
114 			if ((w = getwindow()) != 0)
115 				closewin(w);
116 			break;
117 		case 'w':
118 			c_window();
119 			break;
120 		case 'm':
121 			if ((w = getwindow()) != 0)
122 				c_move(w);
123 			break;
124 		case 'M':
125 			if ((w = getwindow()) != 0)
126 				movewin(w, w->ww_alt.t, w->ww_alt.l);
127 			break;
128 		case 's':
129 			if ((w = getwindow()) != 0)
130 				c_size(w);
131 			break;
132 		case 'S':
133 			if ((w = getwindow()) != 0)
134 				sizewin(w, w->ww_alt.nr, w->ww_alt.nc);
135 			break;
136 		case 'y':
137 			c_yank();
138 			break;
139 		case 'p':
140 			c_put();
141 			break;
142 		case ':':
143 			c_colon();
144 			break;
145 		case 'h':
146 			(void) wwwrite(selwin, "\b", 1);
147 			break;
148 		case 'j':
149 			(void) wwwrite(selwin, "\n", 1);
150 			break;
151 		case 'k':
152 			(void) wwwrite(selwin, "\033A", 2);
153 			break;
154 		case 'l':
155 			(void) wwwrite(selwin, "\033C", 2);
156 			break;
157 		case ctrl('e'):
158 			wwscroll(selwin, 1);
159 			break;
160 		case ctrl('y'):
161 			wwscroll(selwin, -1);
162 			break;
163 		case ctrl('d'):
164 			wwscroll(selwin, selwin->ww_w.nr / 2);
165 			break;
166 		case ctrl('u'):
167 			wwscroll(selwin, - selwin->ww_w.nr / 2);
168 			break;
169 		case ctrl('f'):
170 			wwscroll(selwin, selwin->ww_w.nr);
171 			break;
172 		case ctrl('b'):
173 			wwscroll(selwin, - selwin->ww_w.nr);
174 			break;
175 		case ctrl('s'):
176 			stopwin(selwin);
177 			break;
178 		case ctrl('q'):
179 			startwin(selwin);
180 			break;
181 		case ctrl('l'):
182 			wwredraw();
183 			break;
184 		case '?':
185 			c_help();
186 			break;
187 		case ctrl('['):
188 			if (checkproc(selwin) >= 0)
189 				out = 1;
190 			break;
191 		case ctrl('z'):
192 			wwsuspend();
193 			break;
194 		case 'q':
195 			c_quit();
196 			break;
197 		/* debugging stuff */
198 		case '&':
199 			if (debug) {
200 				c_debug();
201 				break;
202 			}
203 		default:
204 			if (c == escapec) {
205 				if (checkproc(selwin) >= 0) {
206 					(void) write(selwin->ww_pty,
207 						&escapec, 1);
208 					out = 1;
209 				}
210 			} else {
211 				if (!terse)
212 					wwbell();
213 				error("Type ? for help.");
214 			}
215 		}
216 	}
217 	if (!quit)
218 		setcmd(0);
219 }
220 
221 struct ww *
getwindow()222 getwindow()
223 {
224 	int c;
225 	struct ww *w = 0;
226 
227 	if (!terse)
228 		wwputs("Which window? ", cmdwin);
229 	wwcurtowin(cmdwin);
230 	while ((c = wwgetc()) < 0)
231 		wwiomux();
232 	if (debug && c == 'c')
233 		w = cmdwin;
234 	else if (debug && c == 'f')
235 		w = framewin;
236 	else if (debug && c == 'b')
237 		w = boxwin;
238 	else if (c >= '1' && c < NWINDOW + '1')
239 		w = window[c - '1'];
240 	else if (c == '+')
241 		w = selwin;
242 	else if (c == '-')
243 		w = lastselwin;
244 	if (w == 0)
245 		wwbell();
246 	if (!terse)
247 		wwputc('\n', cmdwin);
248 	return w;
249 }
250 
251 checkproc(w)
252 struct ww *w;
253 {
254 	if (w->ww_state != WWS_HASPROC) {
255 		error("No process in window.");
256 		return -1;
257 	}
258 	return 0;
259 }
260 
setcmd(new)261 setcmd(new)
262 char new;
263 {
264 	if (new && !incmd) {
265 		if (!terse)
266 			wwadd(cmdwin, &wwhead);
267 		if (selwin != 0)
268 			wwcursor(selwin, 1);
269 		wwcurwin = 0;
270 	} else if (!new && incmd) {
271 		if (!terse) {
272 			wwdelete(cmdwin);
273 			reframe();
274 		}
275 		if (selwin != 0)
276 			wwcursor(selwin, 0);
277 		wwcurwin = selwin;
278 	}
279 	incmd = new;
280 }
281 
setterse(new)282 setterse(new)
283 char new;
284 {
285 	if (incmd)
286 		if (new && !terse) {
287 			wwdelete(cmdwin);
288 			reframe();
289 		} else if (!new && terse)
290 			wwadd(cmdwin, &wwhead);
291 	terse = new;
292 }
293 
294 /*
295  * Set the current window.
296  */
297 setselwin(w)
298 struct ww *w;
299 {
300 	if (selwin == w)
301 		return;
302 	if (selwin != 0)
303 		lastselwin = selwin;
304 	if ((selwin = w) != 0)
305 		front(selwin, 1);
306 }
307