1c80476e4SDavid E. O'Brien /*
2c80476e4SDavid E. O'Brien * ed.screen.c: Editor/termcap-curses interface
3c80476e4SDavid E. O'Brien */
4c80476e4SDavid E. O'Brien /*-
5c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California.
6c80476e4SDavid E. O'Brien * All rights reserved.
7c80476e4SDavid E. O'Brien *
8c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without
9c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions
10c80476e4SDavid E. O'Brien * are met:
11c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright
12c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer.
13c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright
14c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the
15c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution.
1629301572SMark Peek * 3. Neither the name of the University nor the names of its contributors
17c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software
18c80476e4SDavid E. O'Brien * without specific prior written permission.
19c80476e4SDavid E. O'Brien *
20c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c80476e4SDavid E. O'Brien * SUCH DAMAGE.
31c80476e4SDavid E. O'Brien */
32c80476e4SDavid E. O'Brien #include "sh.h"
33c80476e4SDavid E. O'Brien #include "ed.h"
34c80476e4SDavid E. O'Brien #include "tc.h"
35c80476e4SDavid E. O'Brien #include "ed.defns.h"
36c80476e4SDavid E. O'Brien
37c80476e4SDavid E. O'Brien /* #define DEBUG_LITERAL */
38c80476e4SDavid E. O'Brien
39c80476e4SDavid E. O'Brien /*
40c80476e4SDavid E. O'Brien * IMPORTANT NOTE: these routines are allowed to look at the current screen
41c80476e4SDavid E. O'Brien * and the current possition assuming that it is correct. If this is not
42c80476e4SDavid E. O'Brien * true, then the update will be WRONG! This is (should be) a valid
43c80476e4SDavid E. O'Brien * assumption...
44c80476e4SDavid E. O'Brien */
45c80476e4SDavid E. O'Brien
46c80476e4SDavid E. O'Brien #define TC_BUFSIZE 2048
47c80476e4SDavid E. O'Brien
48c80476e4SDavid E. O'Brien #define GoodStr(a) (tstr[a].str != NULL && tstr[a].str[0] != '\0')
49c80476e4SDavid E. O'Brien #define Str(a) tstr[a].str
50c80476e4SDavid E. O'Brien #define Val(a) tval[a].val
51c80476e4SDavid E. O'Brien
5245e5710bSMark Peek static const struct {
5323338178SMark Peek const char *b_name;
5423338178SMark Peek speed_t b_rate;
55c80476e4SDavid E. O'Brien } baud_rate[] = {
56c80476e4SDavid E. O'Brien
57c80476e4SDavid E. O'Brien #ifdef B0
58c80476e4SDavid E. O'Brien { "0", B0 },
59c80476e4SDavid E. O'Brien #endif
60c80476e4SDavid E. O'Brien #ifdef B50
61c80476e4SDavid E. O'Brien { "50", B50 },
62c80476e4SDavid E. O'Brien #endif
63c80476e4SDavid E. O'Brien #ifdef B75
64c80476e4SDavid E. O'Brien { "75", B75 },
65c80476e4SDavid E. O'Brien #endif
66c80476e4SDavid E. O'Brien #ifdef B110
67c80476e4SDavid E. O'Brien { "110", B110 },
68c80476e4SDavid E. O'Brien #endif
69c80476e4SDavid E. O'Brien #ifdef B134
70c80476e4SDavid E. O'Brien { "134", B134 },
71c80476e4SDavid E. O'Brien #endif
72c80476e4SDavid E. O'Brien #ifdef B150
73c80476e4SDavid E. O'Brien { "150", B150 },
74c80476e4SDavid E. O'Brien #endif
75c80476e4SDavid E. O'Brien #ifdef B200
76c80476e4SDavid E. O'Brien { "200", B200 },
77c80476e4SDavid E. O'Brien #endif
78c80476e4SDavid E. O'Brien #ifdef B300
79c80476e4SDavid E. O'Brien { "300", B300 },
80c80476e4SDavid E. O'Brien #endif
81c80476e4SDavid E. O'Brien #ifdef B600
82c80476e4SDavid E. O'Brien { "600", B600 },
83c80476e4SDavid E. O'Brien #endif
84c80476e4SDavid E. O'Brien #ifdef B900
85c80476e4SDavid E. O'Brien { "900", B900 },
86c80476e4SDavid E. O'Brien #endif
87c80476e4SDavid E. O'Brien #ifdef B1200
88c80476e4SDavid E. O'Brien { "1200", B1200 },
89c80476e4SDavid E. O'Brien #endif
90c80476e4SDavid E. O'Brien #ifdef B1800
91c80476e4SDavid E. O'Brien { "1800", B1800 },
92c80476e4SDavid E. O'Brien #endif
93c80476e4SDavid E. O'Brien #ifdef B2400
94c80476e4SDavid E. O'Brien { "2400", B2400 },
95c80476e4SDavid E. O'Brien #endif
96c80476e4SDavid E. O'Brien #ifdef B3600
97c80476e4SDavid E. O'Brien { "3600", B3600 },
98c80476e4SDavid E. O'Brien #endif
99c80476e4SDavid E. O'Brien #ifdef B4800
100c80476e4SDavid E. O'Brien { "4800", B4800 },
101c80476e4SDavid E. O'Brien #endif
102c80476e4SDavid E. O'Brien #ifdef B7200
103c80476e4SDavid E. O'Brien { "7200", B7200 },
104c80476e4SDavid E. O'Brien #endif
105c80476e4SDavid E. O'Brien #ifdef B9600
106c80476e4SDavid E. O'Brien { "9600", B9600 },
107c80476e4SDavid E. O'Brien #endif
108c80476e4SDavid E. O'Brien #ifdef EXTA
109c80476e4SDavid E. O'Brien { "19200", EXTA },
110c80476e4SDavid E. O'Brien #endif
111c80476e4SDavid E. O'Brien #ifdef B19200
112c80476e4SDavid E. O'Brien { "19200", B19200 },
113c80476e4SDavid E. O'Brien #endif
114c80476e4SDavid E. O'Brien #ifdef EXTB
115c80476e4SDavid E. O'Brien { "38400", EXTB },
116c80476e4SDavid E. O'Brien #endif
117c80476e4SDavid E. O'Brien #ifdef B38400
118c80476e4SDavid E. O'Brien { "38400", B38400 },
119c80476e4SDavid E. O'Brien #endif
120c80476e4SDavid E. O'Brien { NULL, 0 }
121c80476e4SDavid E. O'Brien };
122c80476e4SDavid E. O'Brien
12345e5710bSMark Peek #define T_at7 0
12445e5710bSMark Peek #define T_al 1
12545e5710bSMark Peek #define T_bl 2
12645e5710bSMark Peek #define T_cd 3
12745e5710bSMark Peek #define T_ce 4
12845e5710bSMark Peek #define T_ch 5
12945e5710bSMark Peek #define T_cl 6
13045e5710bSMark Peek #define T_dc 7
13145e5710bSMark Peek #define T_dl 8
13245e5710bSMark Peek #define T_dm 9
13345e5710bSMark Peek #define T_ed 10
13445e5710bSMark Peek #define T_ei 11
13545e5710bSMark Peek #define T_fs 12
13645e5710bSMark Peek #define T_ho 13
13745e5710bSMark Peek #define T_ic 14
13845e5710bSMark Peek #define T_im 15
13945e5710bSMark Peek #define T_ip 16
14045e5710bSMark Peek #define T_kd 17
14145e5710bSMark Peek #define T_kh 18
14245e5710bSMark Peek #define T_kl 19
14345e5710bSMark Peek #define T_kr 20
14445e5710bSMark Peek #define T_ku 21
14545e5710bSMark Peek #define T_md 22
14645e5710bSMark Peek #define T_me 23
14745e5710bSMark Peek #define T_mr 24
14845e5710bSMark Peek #define T_nd 25
14945e5710bSMark Peek #define T_se 26
15045e5710bSMark Peek #define T_so 27
15145e5710bSMark Peek #define T_ts 28
15245e5710bSMark Peek #define T_up 29
15345e5710bSMark Peek #define T_us 30
15445e5710bSMark Peek #define T_ue 31
15545e5710bSMark Peek #define T_vb 32
15645e5710bSMark Peek #define T_DC 33
15745e5710bSMark Peek #define T_DO 34
15845e5710bSMark Peek #define T_IC 35
15945e5710bSMark Peek #define T_LE 36
16045e5710bSMark Peek #define T_RI 37
16145e5710bSMark Peek #define T_UP 38
16245e5710bSMark Peek #define T_str 39
16345e5710bSMark Peek
164c80476e4SDavid E. O'Brien static struct termcapstr {
16523338178SMark Peek const char *name;
16623338178SMark Peek const char *long_name;
167c80476e4SDavid E. O'Brien char *str;
168c80476e4SDavid E. O'Brien } tstr[T_str + 1];
169c80476e4SDavid E. O'Brien
170c80476e4SDavid E. O'Brien
171c80476e4SDavid E. O'Brien #define T_am 0
172c80476e4SDavid E. O'Brien #define T_pt 1
173c80476e4SDavid E. O'Brien #define T_li 2
174c80476e4SDavid E. O'Brien #define T_co 3
175c80476e4SDavid E. O'Brien #define T_km 4
176c80476e4SDavid E. O'Brien #define T_xn 5
177c80476e4SDavid E. O'Brien #define T_val 6
178c80476e4SDavid E. O'Brien static struct termcapval {
17923338178SMark Peek const char *name;
18023338178SMark Peek const char *long_name;
181c80476e4SDavid E. O'Brien int val;
182c80476e4SDavid E. O'Brien } tval[T_val + 1];
183c80476e4SDavid E. O'Brien
184c80476e4SDavid E. O'Brien void
terminit(void)18545e5710bSMark Peek terminit(void)
186c80476e4SDavid E. O'Brien {
187c80476e4SDavid E. O'Brien #ifdef NLS_CATALOGS
188c80476e4SDavid E. O'Brien int i;
189c80476e4SDavid E. O'Brien
190c80476e4SDavid E. O'Brien for (i = 0; i < T_str + 1; i++)
19145e5710bSMark Peek xfree((ptr_t)(intptr_t)tstr[i].long_name);
192c80476e4SDavid E. O'Brien
193c80476e4SDavid E. O'Brien for (i = 0; i < T_val + 1; i++)
19445e5710bSMark Peek xfree((ptr_t)(intptr_t)tval[i].long_name);
195c80476e4SDavid E. O'Brien #endif
196c80476e4SDavid E. O'Brien
197c80476e4SDavid E. O'Brien tstr[T_al].name = "al";
198c80476e4SDavid E. O'Brien tstr[T_al].long_name = CSAVS(4, 1, "add new blank line");
199c80476e4SDavid E. O'Brien
200c80476e4SDavid E. O'Brien tstr[T_bl].name = "bl";
201c80476e4SDavid E. O'Brien tstr[T_bl].long_name = CSAVS(4, 2, "audible bell");
202c80476e4SDavid E. O'Brien
203c80476e4SDavid E. O'Brien tstr[T_cd].name = "cd";
204c80476e4SDavid E. O'Brien tstr[T_cd].long_name = CSAVS(4, 3, "clear to bottom");
205c80476e4SDavid E. O'Brien
206c80476e4SDavid E. O'Brien tstr[T_ce].name = "ce";
207c80476e4SDavid E. O'Brien tstr[T_ce].long_name = CSAVS(4, 4, "clear to end of line");
208c80476e4SDavid E. O'Brien
209c80476e4SDavid E. O'Brien tstr[T_ch].name = "ch";
210c80476e4SDavid E. O'Brien tstr[T_ch].long_name = CSAVS(4, 5, "cursor to horiz pos");
211c80476e4SDavid E. O'Brien
212c80476e4SDavid E. O'Brien tstr[T_cl].name = "cl";
213c80476e4SDavid E. O'Brien tstr[T_cl].long_name = CSAVS(4, 6, "clear screen");
214c80476e4SDavid E. O'Brien
215c80476e4SDavid E. O'Brien tstr[T_dc].name = "dc";
216c80476e4SDavid E. O'Brien tstr[T_dc].long_name = CSAVS(4, 7, "delete a character");
217c80476e4SDavid E. O'Brien
218c80476e4SDavid E. O'Brien tstr[T_dl].name = "dl";
219c80476e4SDavid E. O'Brien tstr[T_dl].long_name = CSAVS(4, 8, "delete a line");
220c80476e4SDavid E. O'Brien
221c80476e4SDavid E. O'Brien tstr[T_dm].name = "dm";
222c80476e4SDavid E. O'Brien tstr[T_dm].long_name = CSAVS(4, 9, "start delete mode");
223c80476e4SDavid E. O'Brien
224c80476e4SDavid E. O'Brien tstr[T_ed].name = "ed";
225c80476e4SDavid E. O'Brien tstr[T_ed].long_name = CSAVS(4, 10, "end delete mode");
226c80476e4SDavid E. O'Brien
227c80476e4SDavid E. O'Brien tstr[T_ei].name = "ei";
228c80476e4SDavid E. O'Brien tstr[T_ei].long_name = CSAVS(4, 11, "end insert mode");
229c80476e4SDavid E. O'Brien
230c80476e4SDavid E. O'Brien tstr[T_fs].name = "fs";
231c80476e4SDavid E. O'Brien tstr[T_fs].long_name = CSAVS(4, 12, "cursor from status line");
232c80476e4SDavid E. O'Brien
233c80476e4SDavid E. O'Brien tstr[T_ho].name = "ho";
234c80476e4SDavid E. O'Brien tstr[T_ho].long_name = CSAVS(4, 13, "home cursor");
235c80476e4SDavid E. O'Brien
236c80476e4SDavid E. O'Brien tstr[T_ic].name = "ic";
237c80476e4SDavid E. O'Brien tstr[T_ic].long_name = CSAVS(4, 14, "insert character");
238c80476e4SDavid E. O'Brien
239c80476e4SDavid E. O'Brien tstr[T_im].name = "im";
240c80476e4SDavid E. O'Brien tstr[T_im].long_name = CSAVS(4, 15, "start insert mode");
241c80476e4SDavid E. O'Brien
242c80476e4SDavid E. O'Brien tstr[T_ip].name = "ip";
243c80476e4SDavid E. O'Brien tstr[T_ip].long_name = CSAVS(4, 16, "insert padding");
244c80476e4SDavid E. O'Brien
245c80476e4SDavid E. O'Brien tstr[T_kd].name = "kd";
246c80476e4SDavid E. O'Brien tstr[T_kd].long_name = CSAVS(4, 17, "sends cursor down");
247c80476e4SDavid E. O'Brien
248c80476e4SDavid E. O'Brien tstr[T_kl].name = "kl";
249c80476e4SDavid E. O'Brien tstr[T_kl].long_name = CSAVS(4, 18, "sends cursor left");
250c80476e4SDavid E. O'Brien
251c80476e4SDavid E. O'Brien tstr[T_kr].name = "kr";
252c80476e4SDavid E. O'Brien tstr[T_kr].long_name = CSAVS(4, 19, "sends cursor right");
253c80476e4SDavid E. O'Brien
254c80476e4SDavid E. O'Brien tstr[T_ku].name = "ku";
255c80476e4SDavid E. O'Brien tstr[T_ku].long_name = CSAVS(4, 20, "sends cursor up");
256c80476e4SDavid E. O'Brien
257c80476e4SDavid E. O'Brien tstr[T_md].name = "md";
258c80476e4SDavid E. O'Brien tstr[T_md].long_name = CSAVS(4, 21, "begin bold");
259c80476e4SDavid E. O'Brien
260c80476e4SDavid E. O'Brien tstr[T_me].name = "me";
261c80476e4SDavid E. O'Brien tstr[T_me].long_name = CSAVS(4, 22, "end attributes");
262c80476e4SDavid E. O'Brien
263c80476e4SDavid E. O'Brien tstr[T_nd].name = "nd";
264c80476e4SDavid E. O'Brien tstr[T_nd].long_name = CSAVS(4, 23, "non destructive space");
265c80476e4SDavid E. O'Brien
266c80476e4SDavid E. O'Brien tstr[T_se].name = "se";
267c80476e4SDavid E. O'Brien tstr[T_se].long_name = CSAVS(4, 24, "end standout");
268c80476e4SDavid E. O'Brien
269c80476e4SDavid E. O'Brien tstr[T_so].name = "so";
270c80476e4SDavid E. O'Brien tstr[T_so].long_name = CSAVS(4, 25, "begin standout");
271c80476e4SDavid E. O'Brien
272c80476e4SDavid E. O'Brien tstr[T_ts].name = "ts";
273c80476e4SDavid E. O'Brien tstr[T_ts].long_name = CSAVS(4, 26, "cursor to status line");
274c80476e4SDavid E. O'Brien
275c80476e4SDavid E. O'Brien tstr[T_up].name = "up";
276c80476e4SDavid E. O'Brien tstr[T_up].long_name = CSAVS(4, 27, "cursor up one");
277c80476e4SDavid E. O'Brien
278c80476e4SDavid E. O'Brien tstr[T_us].name = "us";
279c80476e4SDavid E. O'Brien tstr[T_us].long_name = CSAVS(4, 28, "begin underline");
280c80476e4SDavid E. O'Brien
281c80476e4SDavid E. O'Brien tstr[T_ue].name = "ue";
282c80476e4SDavid E. O'Brien tstr[T_ue].long_name = CSAVS(4, 29, "end underline");
283c80476e4SDavid E. O'Brien
284c80476e4SDavid E. O'Brien tstr[T_vb].name = "vb";
285c80476e4SDavid E. O'Brien tstr[T_vb].long_name = CSAVS(4, 30, "visible bell");
286c80476e4SDavid E. O'Brien
287c80476e4SDavid E. O'Brien tstr[T_DC].name = "DC";
288c80476e4SDavid E. O'Brien tstr[T_DC].long_name = CSAVS(4, 31, "delete multiple chars");
289c80476e4SDavid E. O'Brien
290c80476e4SDavid E. O'Brien tstr[T_DO].name = "DO";
291c80476e4SDavid E. O'Brien tstr[T_DO].long_name = CSAVS(4, 32, "cursor down multiple");
292c80476e4SDavid E. O'Brien
293c80476e4SDavid E. O'Brien tstr[T_IC].name = "IC";
294c80476e4SDavid E. O'Brien tstr[T_IC].long_name = CSAVS(4, 33, "insert multiple chars");
295c80476e4SDavid E. O'Brien
296c80476e4SDavid E. O'Brien tstr[T_LE].name = "LE";
297c80476e4SDavid E. O'Brien tstr[T_LE].long_name = CSAVS(4, 34, "cursor left multiple");
298c80476e4SDavid E. O'Brien
299c80476e4SDavid E. O'Brien tstr[T_RI].name = "RI";
300c80476e4SDavid E. O'Brien tstr[T_RI].long_name = CSAVS(4, 35, "cursor right multiple");
301c80476e4SDavid E. O'Brien
302c80476e4SDavid E. O'Brien tstr[T_UP].name = "UP";
303c80476e4SDavid E. O'Brien tstr[T_UP].long_name = CSAVS(4, 36, "cursor up multiple");
304c80476e4SDavid E. O'Brien
3053b6eaa7bSAndrey A. Chernov tstr[T_kh].name = "kh";
30645e5710bSMark Peek tstr[T_kh].long_name = CSAVS(4, 43, "send cursor home");
3073b6eaa7bSAndrey A. Chernov
3083b6eaa7bSAndrey A. Chernov tstr[T_at7].name = "@7";
30945e5710bSMark Peek tstr[T_at7].long_name = CSAVS(4, 44, "send cursor end");
31045e5710bSMark Peek
31145e5710bSMark Peek tstr[T_mr].name = "mr";
31245e5710bSMark Peek tstr[T_mr].long_name = CSAVS(4, 45, "begin reverse video");
3133b6eaa7bSAndrey A. Chernov
314c80476e4SDavid E. O'Brien tstr[T_str].name = NULL;
315c80476e4SDavid E. O'Brien tstr[T_str].long_name = NULL;
316c80476e4SDavid E. O'Brien
317c80476e4SDavid E. O'Brien
318c80476e4SDavid E. O'Brien tval[T_am].name = "am";
319c80476e4SDavid E. O'Brien tval[T_am].long_name = CSAVS(4, 37, "Has automatic margins");
320c80476e4SDavid E. O'Brien
321c80476e4SDavid E. O'Brien tval[T_pt].name = "pt";
322c80476e4SDavid E. O'Brien tval[T_pt].long_name = CSAVS(4, 38, "Can use physical tabs");
323c80476e4SDavid E. O'Brien
324c80476e4SDavid E. O'Brien tval[T_li].name = "li";
325c80476e4SDavid E. O'Brien tval[T_li].long_name = CSAVS(4, 39, "Number of lines");
326c80476e4SDavid E. O'Brien
327c80476e4SDavid E. O'Brien tval[T_co].name = "co";
328c80476e4SDavid E. O'Brien tval[T_co].long_name = CSAVS(4, 40, "Number of columns");
329c80476e4SDavid E. O'Brien
330c80476e4SDavid E. O'Brien tval[T_km].name = "km";
331c80476e4SDavid E. O'Brien tval[T_km].long_name = CSAVS(4, 41, "Has meta key");
332c80476e4SDavid E. O'Brien
333c80476e4SDavid E. O'Brien tval[T_xn].name = "xn";
334c80476e4SDavid E. O'Brien tval[T_xn].long_name = CSAVS(4, 42, "Newline ignored at right margin");
335c80476e4SDavid E. O'Brien
336c80476e4SDavid E. O'Brien tval[T_val].name = NULL;
337c80476e4SDavid E. O'Brien tval[T_val].long_name = NULL;
338c80476e4SDavid E. O'Brien }
339c80476e4SDavid E. O'Brien
340c80476e4SDavid E. O'Brien /*
341c80476e4SDavid E. O'Brien * A very useful table from justin@crim.ca (Justin Bur) :-)
342c80476e4SDavid E. O'Brien * (Modified by per@erix.ericsson.se (Per Hedeland)
343c80476e4SDavid E. O'Brien * - first (and second:-) case fixed)
344c80476e4SDavid E. O'Brien *
345c80476e4SDavid E. O'Brien * Description Termcap variables tcsh behavior
346c80476e4SDavid E. O'Brien * am xn UseRightmost SendCRLF
347c80476e4SDavid E. O'Brien * -------------- ------- ------- ------------ ------------
348c80476e4SDavid E. O'Brien * Automargins yes no yes no
349c80476e4SDavid E. O'Brien * Magic Margins yes yes yes no
350c80476e4SDavid E. O'Brien * No Wrap no -- yes yes
351c80476e4SDavid E. O'Brien */
352c80476e4SDavid E. O'Brien
35323338178SMark Peek static int me_all = 0; /* does two or more of the attributes use me */
354c80476e4SDavid E. O'Brien
35545e5710bSMark Peek static void ReBufferDisplay (void);
35645e5710bSMark Peek static void TCset (struct termcapstr *, const char *);
357c80476e4SDavid E. O'Brien
358c80476e4SDavid E. O'Brien
359c80476e4SDavid E. O'Brien static void
TCset(struct termcapstr * t,const char * cap)36045e5710bSMark Peek TCset(struct termcapstr *t, const char *cap)
361c80476e4SDavid E. O'Brien {
362c80476e4SDavid E. O'Brien if (cap == NULL || *cap == '\0') {
36345e5710bSMark Peek xfree(t->str);
364c80476e4SDavid E. O'Brien t->str = NULL;
36545e5710bSMark Peek } else {
36645e5710bSMark Peek size_t size;
367c80476e4SDavid E. O'Brien
36845e5710bSMark Peek size = strlen(cap) + 1;
36945e5710bSMark Peek t->str = xrealloc(t->str, size);
37045e5710bSMark Peek memcpy(t->str, cap, size);
371c80476e4SDavid E. O'Brien }
372c80476e4SDavid E. O'Brien }
373c80476e4SDavid E. O'Brien
374c80476e4SDavid E. O'Brien
375c80476e4SDavid E. O'Brien /*ARGSUSED*/
376c80476e4SDavid E. O'Brien void
TellTC(void)37745e5710bSMark Peek TellTC(void)
378c80476e4SDavid E. O'Brien {
379c80476e4SDavid E. O'Brien struct termcapstr *t;
38045e5710bSMark Peek char *first, *s;
381c80476e4SDavid E. O'Brien
382a15e6f9aSMark Peek xprintf("%s", CGETS(7, 1, "\n\tTcsh thinks your terminal has the\n"));
383a15e6f9aSMark Peek xprintf("%s", CGETS(7, 2, "\tfollowing characteristics:\n\n"));
384c80476e4SDavid E. O'Brien xprintf(CGETS(7, 3, "\tIt has %d columns and %d lines\n"),
385c80476e4SDavid E. O'Brien Val(T_co), Val(T_li));
38623338178SMark Peek s = strsave(T_HasMeta ? CGETS(7, 5, "a") : CGETS(7, 6, "no"));
38745e5710bSMark Peek cleanup_push(s, xfree);
38845e5710bSMark Peek first = s;
38923338178SMark Peek xprintf(CGETS(7, 4, "\tIt has %s meta key\n"), s);
39023338178SMark Peek s = strsave(T_Tabs ? "" : CGETS(7, 8, " not"));
39145e5710bSMark Peek cleanup_push(s, xfree);
39223338178SMark Peek xprintf(CGETS(7, 7, "\tIt can%s use tabs\n"), s);
39323338178SMark Peek s = strsave((T_Margin&MARGIN_AUTO) ?
39423338178SMark Peek CGETS(7, 10, "has") : CGETS(7, 11, "does not have"));
39545e5710bSMark Peek cleanup_push(s, xfree);
39623338178SMark Peek xprintf(CGETS(7, 9, "\tIt %s automatic margins\n"), s);
39723338178SMark Peek if (T_Margin & MARGIN_AUTO) {
39823338178SMark Peek s = strsave((T_Margin & MARGIN_MAGIC) ?
39923338178SMark Peek CGETS(7, 10, "has") : CGETS(7, 11, "does not have"));
40045e5710bSMark Peek cleanup_push(s, xfree);
40123338178SMark Peek xprintf(CGETS(7, 12, "\tIt %s magic margins\n"), s);
40223338178SMark Peek }
40323338178SMark Peek for (t = tstr; t->name != NULL; t++) {
40423338178SMark Peek s = strsave(t->str && *t->str ? t->str : CGETS(7, 13, "(empty)"));
40545e5710bSMark Peek cleanup_push(s, xfree);
40623338178SMark Peek xprintf("\t%36s (%s) == %s\n", t->long_name, t->name, s);
40745e5710bSMark Peek cleanup_until(s);
40823338178SMark Peek }
409c80476e4SDavid E. O'Brien xputchar('\n');
41045e5710bSMark Peek cleanup_until(first);
411c80476e4SDavid E. O'Brien }
412c80476e4SDavid E. O'Brien
413c80476e4SDavid E. O'Brien
414c80476e4SDavid E. O'Brien static void
ReBufferDisplay(void)41545e5710bSMark Peek ReBufferDisplay(void)
416c80476e4SDavid E. O'Brien {
41723338178SMark Peek int i;
418c80476e4SDavid E. O'Brien Char **b;
419c80476e4SDavid E. O'Brien
420c80476e4SDavid E. O'Brien b = Display;
421c80476e4SDavid E. O'Brien Display = NULL;
42245e5710bSMark Peek blkfree(b);
423c80476e4SDavid E. O'Brien b = Vdisplay;
424c80476e4SDavid E. O'Brien Vdisplay = NULL;
42545e5710bSMark Peek blkfree(b);
426c80476e4SDavid E. O'Brien TermH = Val(T_co);
42745e5710bSMark Peek TermV = (INBUFSIZE * 4) / TermH + 1;/*FIXBUF*/
42845e5710bSMark Peek b = xmalloc(sizeof(*b) * (TermV + 1));
429c80476e4SDavid E. O'Brien for (i = 0; i < TermV; i++)
43045e5710bSMark Peek b[i] = xmalloc(sizeof(*b[i]) * (TermH + 1));
431c80476e4SDavid E. O'Brien b[TermV] = NULL;
432c80476e4SDavid E. O'Brien Display = b;
43345e5710bSMark Peek b = xmalloc(sizeof(*b) * (TermV + 1));
434c80476e4SDavid E. O'Brien for (i = 0; i < TermV; i++)
43545e5710bSMark Peek b[i] = xmalloc(sizeof(*b[i]) * (TermH + 1));
436c80476e4SDavid E. O'Brien b[TermV] = NULL;
437c80476e4SDavid E. O'Brien Vdisplay = b;
438c80476e4SDavid E. O'Brien }
439c80476e4SDavid E. O'Brien
440c80476e4SDavid E. O'Brien void
SetTC(char * what,char * how)44145e5710bSMark Peek SetTC(char *what, char *how)
442c80476e4SDavid E. O'Brien {
443c80476e4SDavid E. O'Brien struct termcapstr *ts;
444c80476e4SDavid E. O'Brien struct termcapval *tv;
445c80476e4SDavid E. O'Brien
446c80476e4SDavid E. O'Brien /*
447c80476e4SDavid E. O'Brien * Do the strings first
448c80476e4SDavid E. O'Brien */
449c80476e4SDavid E. O'Brien setname("settc");
450c80476e4SDavid E. O'Brien for (ts = tstr; ts->name != NULL; ts++)
451c80476e4SDavid E. O'Brien if (strcmp(ts->name, what) == 0)
452c80476e4SDavid E. O'Brien break;
453c80476e4SDavid E. O'Brien if (ts->name != NULL) {
45445e5710bSMark Peek TCset(ts, how);
455c80476e4SDavid E. O'Brien /*
456c80476e4SDavid E. O'Brien * Reset variables
457c80476e4SDavid E. O'Brien */
458c80476e4SDavid E. O'Brien if (GoodStr(T_me) && GoodStr(T_ue))
459c80476e4SDavid E. O'Brien me_all = (strcmp(Str(T_me), Str(T_ue)) == 0);
460c80476e4SDavid E. O'Brien else
461c80476e4SDavid E. O'Brien me_all = 0;
462c80476e4SDavid E. O'Brien if (GoodStr(T_me) && GoodStr(T_se))
463c80476e4SDavid E. O'Brien me_all |= (strcmp(Str(T_me), Str(T_se)) == 0);
464c80476e4SDavid E. O'Brien
465c80476e4SDavid E. O'Brien T_CanCEOL = GoodStr(T_ce);
466c80476e4SDavid E. O'Brien T_CanDel = GoodStr(T_dc) || GoodStr(T_DC);
467c80476e4SDavid E. O'Brien T_CanIns = GoodStr(T_im) || GoodStr(T_ic) || GoodStr(T_IC);
468c80476e4SDavid E. O'Brien T_CanUP = GoodStr(T_up) || GoodStr(T_UP);
469c80476e4SDavid E. O'Brien return;
470c80476e4SDavid E. O'Brien }
471c80476e4SDavid E. O'Brien
472c80476e4SDavid E. O'Brien /*
473c80476e4SDavid E. O'Brien * Do the numeric ones second
474c80476e4SDavid E. O'Brien */
475c80476e4SDavid E. O'Brien for (tv = tval; tv->name != NULL; tv++)
476c80476e4SDavid E. O'Brien if (strcmp(tv->name, what) == 0)
477c80476e4SDavid E. O'Brien break;
478c80476e4SDavid E. O'Brien
479c80476e4SDavid E. O'Brien if (tv->name != NULL) {
480c80476e4SDavid E. O'Brien if (tv == &tval[T_pt] || tv == &tval[T_km] ||
481c80476e4SDavid E. O'Brien tv == &tval[T_am] || tv == &tval[T_xn]) {
482c80476e4SDavid E. O'Brien if (strcmp(how, "yes") == 0)
483c80476e4SDavid E. O'Brien tv->val = 1;
484c80476e4SDavid E. O'Brien else if (strcmp(how, "no") == 0)
485c80476e4SDavid E. O'Brien tv->val = 0;
486c80476e4SDavid E. O'Brien else {
487c80476e4SDavid E. O'Brien stderror(ERR_SETTCUS, tv->name);
488c80476e4SDavid E. O'Brien return;
489c80476e4SDavid E. O'Brien }
49045e5710bSMark Peek T_Tabs = Val(T_pt);
49145e5710bSMark Peek T_HasMeta = Val(T_km);
49245e5710bSMark Peek T_Margin = Val(T_am) ? MARGIN_AUTO : 0;
49345e5710bSMark Peek T_Margin |= Val(T_xn) ? MARGIN_MAGIC : 0;
494c80476e4SDavid E. O'Brien if (tv == &tval[T_am] || tv == &tval[T_xn])
495c80476e4SDavid E. O'Brien ChangeSize(Val(T_li), Val(T_co));
496c80476e4SDavid E. O'Brien return;
497c80476e4SDavid E. O'Brien }
498c80476e4SDavid E. O'Brien else {
499c80476e4SDavid E. O'Brien tv->val = atoi(how);
500c80476e4SDavid E. O'Brien T_Cols = (Char) Val(T_co);
501c80476e4SDavid E. O'Brien T_Lines = (Char) Val(T_li);
502c80476e4SDavid E. O'Brien if (tv == &tval[T_co] || tv == &tval[T_li])
503c80476e4SDavid E. O'Brien ChangeSize(Val(T_li), Val(T_co));
504c80476e4SDavid E. O'Brien return;
505c80476e4SDavid E. O'Brien }
506c80476e4SDavid E. O'Brien }
507c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCCAP, what);
508c80476e4SDavid E. O'Brien return;
509c80476e4SDavid E. O'Brien }
510c80476e4SDavid E. O'Brien
511c80476e4SDavid E. O'Brien
512c80476e4SDavid E. O'Brien /*
513c80476e4SDavid E. O'Brien * Print the termcap string out with variable substitution
514c80476e4SDavid E. O'Brien */
515c80476e4SDavid E. O'Brien void
EchoTC(Char ** v)51645e5710bSMark Peek EchoTC(Char **v)
517c80476e4SDavid E. O'Brien {
51845e5710bSMark Peek char *cap, *scap, *cv;
519c80476e4SDavid E. O'Brien int arg_need, arg_cols, arg_rows;
520c80476e4SDavid E. O'Brien int verbose = 0, silent = 0;
521c80476e4SDavid E. O'Brien char *area;
52245e5710bSMark Peek static const char fmts[] = "%s\n", fmtd[] = "%d\n";
523c80476e4SDavid E. O'Brien struct termcapstr *t;
524c80476e4SDavid E. O'Brien char buf[TC_BUFSIZE];
52545e5710bSMark Peek Char **globbed;
526c80476e4SDavid E. O'Brien
527c80476e4SDavid E. O'Brien area = buf;
528c80476e4SDavid E. O'Brien
529c80476e4SDavid E. O'Brien setname("echotc");
530c80476e4SDavid E. O'Brien
53145e5710bSMark Peek v = glob_all_or_error(v);
53245e5710bSMark Peek globbed = v;
53345e5710bSMark Peek cleanup_push(globbed, blk_cleanup);
534c80476e4SDavid E. O'Brien
535c80476e4SDavid E. O'Brien if (!*v || *v[0] == '\0')
53645e5710bSMark Peek goto end;
537c80476e4SDavid E. O'Brien if (v[0][0] == '-') {
538c80476e4SDavid E. O'Brien switch (v[0][1]) {
539c80476e4SDavid E. O'Brien case 'v':
540c80476e4SDavid E. O'Brien verbose = 1;
541c80476e4SDavid E. O'Brien break;
542c80476e4SDavid E. O'Brien case 's':
543c80476e4SDavid E. O'Brien silent = 1;
544c80476e4SDavid E. O'Brien break;
545c80476e4SDavid E. O'Brien default:
546c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCUSAGE);
547c80476e4SDavid E. O'Brien break;
548c80476e4SDavid E. O'Brien }
549c80476e4SDavid E. O'Brien v++;
550c80476e4SDavid E. O'Brien }
551c80476e4SDavid E. O'Brien if (!*v || *v[0] == '\0')
55245e5710bSMark Peek goto end;
55345e5710bSMark Peek cv = strsave(short2str(*v));
55445e5710bSMark Peek cleanup_push(cv, xfree);
555c80476e4SDavid E. O'Brien if (strcmp(cv, "tabs") == 0) {
556c80476e4SDavid E. O'Brien xprintf(fmts, T_Tabs ? CGETS(7, 14, "yes") :
557c80476e4SDavid E. O'Brien CGETS(7, 15, "no"));
55845e5710bSMark Peek goto end_flush;
559c80476e4SDavid E. O'Brien }
560c80476e4SDavid E. O'Brien else if (strcmp(cv, "meta") == 0) {
561c80476e4SDavid E. O'Brien xprintf(fmts, Val(T_km) ? CGETS(7, 14, "yes") :
562c80476e4SDavid E. O'Brien CGETS(7, 15, "no"));
56345e5710bSMark Peek goto end_flush;
564c80476e4SDavid E. O'Brien }
565c80476e4SDavid E. O'Brien else if (strcmp(cv, "xn") == 0) {
566c80476e4SDavid E. O'Brien xprintf(fmts, T_Margin & MARGIN_MAGIC ? CGETS(7, 14, "yes") :
567c80476e4SDavid E. O'Brien CGETS(7, 15, "no"));
56845e5710bSMark Peek goto end_flush;
569c80476e4SDavid E. O'Brien }
570c80476e4SDavid E. O'Brien else if (strcmp(cv, "am") == 0) {
571c80476e4SDavid E. O'Brien xprintf(fmts, T_Margin & MARGIN_AUTO ? CGETS(7, 14, "yes") :
572c80476e4SDavid E. O'Brien CGETS(7, 15, "no"));
57345e5710bSMark Peek goto end_flush;
574c80476e4SDavid E. O'Brien }
575c80476e4SDavid E. O'Brien else if (strcmp(cv, "baud") == 0) {
576c80476e4SDavid E. O'Brien int i;
577c80476e4SDavid E. O'Brien
578c80476e4SDavid E. O'Brien for (i = 0; baud_rate[i].b_name != NULL; i++)
579c80476e4SDavid E. O'Brien if (T_Speed == baud_rate[i].b_rate) {
580c80476e4SDavid E. O'Brien xprintf(fmts, baud_rate[i].b_name);
58145e5710bSMark Peek goto end_flush;
582c80476e4SDavid E. O'Brien }
583c80476e4SDavid E. O'Brien xprintf(fmtd, 0);
58445e5710bSMark Peek goto end_flush;
585c80476e4SDavid E. O'Brien }
58645e5710bSMark Peek else if (strcmp(cv, "rows") == 0 || strcmp(cv, "lines") == 0 ||
58745e5710bSMark Peek strcmp(cv, "li") == 0) {
588c80476e4SDavid E. O'Brien xprintf(fmtd, Val(T_li));
58945e5710bSMark Peek goto end_flush;
590c80476e4SDavid E. O'Brien }
59145e5710bSMark Peek else if (strcmp(cv, "cols") == 0 || strcmp(cv, "co") == 0) {
592c80476e4SDavid E. O'Brien xprintf(fmtd, Val(T_co));
59345e5710bSMark Peek goto end_flush;
594c80476e4SDavid E. O'Brien }
595c80476e4SDavid E. O'Brien
596c80476e4SDavid E. O'Brien /*
597c80476e4SDavid E. O'Brien * Try to use our local definition first
598c80476e4SDavid E. O'Brien */
599c80476e4SDavid E. O'Brien scap = NULL;
600c80476e4SDavid E. O'Brien for (t = tstr; t->name != NULL; t++)
601c80476e4SDavid E. O'Brien if (strcmp(t->name, cv) == 0) {
602c80476e4SDavid E. O'Brien scap = t->str;
603c80476e4SDavid E. O'Brien break;
604c80476e4SDavid E. O'Brien }
605c80476e4SDavid E. O'Brien if (t->name == NULL)
606c80476e4SDavid E. O'Brien scap = tgetstr(cv, &area);
607c80476e4SDavid E. O'Brien if (!scap || scap[0] == '\0') {
608c80476e4SDavid E. O'Brien if (tgetflag(cv)) {
609a15e6f9aSMark Peek xprintf("%s", CGETS(7, 14, "yes\n"));
61045e5710bSMark Peek goto end;
611c80476e4SDavid E. O'Brien }
612c80476e4SDavid E. O'Brien if (silent)
61345e5710bSMark Peek goto end;
614c80476e4SDavid E. O'Brien else
615c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCCAP, cv);
616c80476e4SDavid E. O'Brien }
617c80476e4SDavid E. O'Brien
618c80476e4SDavid E. O'Brien /*
619c80476e4SDavid E. O'Brien * Count home many values we need for this capability.
620c80476e4SDavid E. O'Brien */
621c80476e4SDavid E. O'Brien for (cap = scap, arg_need = 0; *cap; cap++)
622c80476e4SDavid E. O'Brien if (*cap == '%')
623c80476e4SDavid E. O'Brien switch (*++cap) {
624c80476e4SDavid E. O'Brien case 'd':
625c80476e4SDavid E. O'Brien case '2':
626c80476e4SDavid E. O'Brien case '3':
627c80476e4SDavid E. O'Brien case '.':
628c80476e4SDavid E. O'Brien case '+':
629c80476e4SDavid E. O'Brien arg_need++;
630c80476e4SDavid E. O'Brien break;
631c80476e4SDavid E. O'Brien case '%':
632c80476e4SDavid E. O'Brien case '>':
633c80476e4SDavid E. O'Brien case 'i':
634c80476e4SDavid E. O'Brien case 'r':
635c80476e4SDavid E. O'Brien case 'n':
636c80476e4SDavid E. O'Brien case 'B':
637c80476e4SDavid E. O'Brien case 'D':
638c80476e4SDavid E. O'Brien break;
639c80476e4SDavid E. O'Brien default:
640c80476e4SDavid E. O'Brien /*
641c80476e4SDavid E. O'Brien * hpux has lot's of them...
642c80476e4SDavid E. O'Brien */
643c80476e4SDavid E. O'Brien if (verbose)
644c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCPARM, *cap);
645c80476e4SDavid E. O'Brien /* This is bad, but I won't complain */
646c80476e4SDavid E. O'Brien break;
647c80476e4SDavid E. O'Brien }
648c80476e4SDavid E. O'Brien
649c80476e4SDavid E. O'Brien switch (arg_need) {
650c80476e4SDavid E. O'Brien case 0:
651c80476e4SDavid E. O'Brien v++;
652c80476e4SDavid E. O'Brien if (*v && *v[0]) {
653c80476e4SDavid E. O'Brien if (silent)
65445e5710bSMark Peek goto end;
655c80476e4SDavid E. O'Brien else
656c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCARGS, cv, arg_need);
657c80476e4SDavid E. O'Brien }
658c80476e4SDavid E. O'Brien (void) tputs(scap, 1, PUTRAW);
659c80476e4SDavid E. O'Brien break;
660c80476e4SDavid E. O'Brien case 1:
661c80476e4SDavid E. O'Brien v++;
662c80476e4SDavid E. O'Brien if (!*v || *v[0] == '\0')
663c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCNARGS, cv, 1);
664c80476e4SDavid E. O'Brien arg_cols = 0;
665c80476e4SDavid E. O'Brien arg_rows = atoi(short2str(*v));
666c80476e4SDavid E. O'Brien v++;
667c80476e4SDavid E. O'Brien if (*v && *v[0]) {
668c80476e4SDavid E. O'Brien if (silent)
66945e5710bSMark Peek goto end;
670c80476e4SDavid E. O'Brien else
671c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCARGS, cv, arg_need);
672c80476e4SDavid E. O'Brien }
673c80476e4SDavid E. O'Brien (void) tputs(tgoto(scap, arg_cols, arg_rows), 1, PUTRAW);
674c80476e4SDavid E. O'Brien break;
675c80476e4SDavid E. O'Brien default:
676c80476e4SDavid E. O'Brien /* This is wrong, but I will ignore it... */
677c80476e4SDavid E. O'Brien if (verbose)
678c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCARGS, cv, arg_need);
679c80476e4SDavid E. O'Brien /*FALLTHROUGH*/
680c80476e4SDavid E. O'Brien case 2:
681c80476e4SDavid E. O'Brien v++;
682c80476e4SDavid E. O'Brien if (!*v || *v[0] == '\0') {
683c80476e4SDavid E. O'Brien if (silent)
68445e5710bSMark Peek goto end;
685c80476e4SDavid E. O'Brien else
686c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCNARGS, cv, 2);
687c80476e4SDavid E. O'Brien }
688c80476e4SDavid E. O'Brien arg_cols = atoi(short2str(*v));
689c80476e4SDavid E. O'Brien v++;
690c80476e4SDavid E. O'Brien if (!*v || *v[0] == '\0') {
691c80476e4SDavid E. O'Brien if (silent)
69245e5710bSMark Peek goto end;
693c80476e4SDavid E. O'Brien else
694c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCNARGS, cv, 2);
695c80476e4SDavid E. O'Brien }
696c80476e4SDavid E. O'Brien arg_rows = atoi(short2str(*v));
697c80476e4SDavid E. O'Brien v++;
698c80476e4SDavid E. O'Brien if (*v && *v[0]) {
699c80476e4SDavid E. O'Brien if (silent)
70045e5710bSMark Peek goto end;
701c80476e4SDavid E. O'Brien else
702c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_TCARGS, cv, arg_need);
703c80476e4SDavid E. O'Brien }
704c80476e4SDavid E. O'Brien (void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows, PUTRAW);
705c80476e4SDavid E. O'Brien break;
706c80476e4SDavid E. O'Brien }
70745e5710bSMark Peek end_flush:
708c80476e4SDavid E. O'Brien flush();
70945e5710bSMark Peek end:
71045e5710bSMark Peek cleanup_until(globbed);
711c80476e4SDavid E. O'Brien }
712c80476e4SDavid E. O'Brien
71323338178SMark Peek int GotTermCaps = 0;
714c80476e4SDavid E. O'Brien
715c80476e4SDavid E. O'Brien static struct {
716c80476e4SDavid E. O'Brien Char *name;
717c80476e4SDavid E. O'Brien int key;
718c80476e4SDavid E. O'Brien XmapVal fun;
719c80476e4SDavid E. O'Brien int type;
720c80476e4SDavid E. O'Brien } arrow[] = {
721c80476e4SDavid E. O'Brien #define A_K_DN 0
72223338178SMark Peek { STRdown, T_kd, { 0 }, 0 },
723c80476e4SDavid E. O'Brien #define A_K_UP 1
72423338178SMark Peek { STRup, T_ku, { 0 }, 0 },
725c80476e4SDavid E. O'Brien #define A_K_LT 2
72623338178SMark Peek { STRleft, T_kl, { 0 }, 0 },
727c80476e4SDavid E. O'Brien #define A_K_RT 3
72823338178SMark Peek { STRright, T_kr, { 0 }, 0 },
7293b6eaa7bSAndrey A. Chernov #define A_K_HO 4
73023338178SMark Peek { STRhome, T_kh, { 0 }, 0 },
7313b6eaa7bSAndrey A. Chernov #define A_K_EN 5
73223338178SMark Peek { STRend, T_at7, { 0 }, 0}
733c80476e4SDavid E. O'Brien };
7343b6eaa7bSAndrey A. Chernov #define A_K_NKEYS 6
735c80476e4SDavid E. O'Brien
736c80476e4SDavid E. O'Brien void
ResetArrowKeys(void)73745e5710bSMark Peek ResetArrowKeys(void)
738c80476e4SDavid E. O'Brien {
739c80476e4SDavid E. O'Brien arrow[A_K_DN].fun.cmd = F_DOWN_HIST;
740c80476e4SDavid E. O'Brien arrow[A_K_DN].type = XK_CMD;
741c80476e4SDavid E. O'Brien
742c80476e4SDavid E. O'Brien arrow[A_K_UP].fun.cmd = F_UP_HIST;
743c80476e4SDavid E. O'Brien arrow[A_K_UP].type = XK_CMD;
744c80476e4SDavid E. O'Brien
745c80476e4SDavid E. O'Brien arrow[A_K_LT].fun.cmd = F_CHARBACK;
746c80476e4SDavid E. O'Brien arrow[A_K_LT].type = XK_CMD;
747c80476e4SDavid E. O'Brien
748c80476e4SDavid E. O'Brien arrow[A_K_RT].fun.cmd = F_CHARFWD;
749c80476e4SDavid E. O'Brien arrow[A_K_RT].type = XK_CMD;
750c80476e4SDavid E. O'Brien
7513b6eaa7bSAndrey A. Chernov arrow[A_K_HO].fun.cmd = F_TOBEG;
7523b6eaa7bSAndrey A. Chernov arrow[A_K_HO].type = XK_CMD;
7533b6eaa7bSAndrey A. Chernov
7543b6eaa7bSAndrey A. Chernov arrow[A_K_EN].fun.cmd = F_TOEND;
7553b6eaa7bSAndrey A. Chernov arrow[A_K_EN].type = XK_CMD;
756c80476e4SDavid E. O'Brien }
757c80476e4SDavid E. O'Brien
758c80476e4SDavid E. O'Brien void
DefaultArrowKeys(void)75945e5710bSMark Peek DefaultArrowKeys(void)
760c80476e4SDavid E. O'Brien {
761c80476e4SDavid E. O'Brien static Char strA[] = {033, '[', 'A', '\0'};
762c80476e4SDavid E. O'Brien static Char strB[] = {033, '[', 'B', '\0'};
763c80476e4SDavid E. O'Brien static Char strC[] = {033, '[', 'C', '\0'};
764c80476e4SDavid E. O'Brien static Char strD[] = {033, '[', 'D', '\0'};
7653b6eaa7bSAndrey A. Chernov static Char strH[] = {033, '[', 'H', '\0'};
7663b6eaa7bSAndrey A. Chernov static Char strF[] = {033, '[', 'F', '\0'};
767c80476e4SDavid E. O'Brien static Char stOA[] = {033, 'O', 'A', '\0'};
768c80476e4SDavid E. O'Brien static Char stOB[] = {033, 'O', 'B', '\0'};
769c80476e4SDavid E. O'Brien static Char stOC[] = {033, 'O', 'C', '\0'};
770c80476e4SDavid E. O'Brien static Char stOD[] = {033, 'O', 'D', '\0'};
7713b6eaa7bSAndrey A. Chernov static Char stOH[] = {033, 'O', 'H', '\0'};
7723b6eaa7bSAndrey A. Chernov static Char stOF[] = {033, 'O', 'F', '\0'};
773c80476e4SDavid E. O'Brien
774c80476e4SDavid E. O'Brien CStr cs;
7753b6eaa7bSAndrey A. Chernov #ifndef IS_ASCII
776c80476e4SDavid E. O'Brien if (strA[0] == 033)
777c80476e4SDavid E. O'Brien {
778c80476e4SDavid E. O'Brien strA[0] = CTL_ESC('\033');
779c80476e4SDavid E. O'Brien strB[0] = CTL_ESC('\033');
780c80476e4SDavid E. O'Brien strC[0] = CTL_ESC('\033');
781c80476e4SDavid E. O'Brien strD[0] = CTL_ESC('\033');
7823b6eaa7bSAndrey A. Chernov strH[0] = CTL_ESC('\033');
7833b6eaa7bSAndrey A. Chernov strF[0] = CTL_ESC('\033');
784c80476e4SDavid E. O'Brien stOA[0] = CTL_ESC('\033');
785c80476e4SDavid E. O'Brien stOB[0] = CTL_ESC('\033');
786c80476e4SDavid E. O'Brien stOC[0] = CTL_ESC('\033');
787c80476e4SDavid E. O'Brien stOD[0] = CTL_ESC('\033');
7883b6eaa7bSAndrey A. Chernov stOH[0] = CTL_ESC('\033');
7893b6eaa7bSAndrey A. Chernov stOF[0] = CTL_ESC('\033');
790c80476e4SDavid E. O'Brien }
791c80476e4SDavid E. O'Brien #endif
792c80476e4SDavid E. O'Brien
793c80476e4SDavid E. O'Brien cs.len = 3;
794c80476e4SDavid E. O'Brien
795c80476e4SDavid E. O'Brien cs.buf = strA; AddXkey(&cs, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
796c80476e4SDavid E. O'Brien cs.buf = strB; AddXkey(&cs, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
797c80476e4SDavid E. O'Brien cs.buf = strC; AddXkey(&cs, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
798c80476e4SDavid E. O'Brien cs.buf = strD; AddXkey(&cs, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
7993b6eaa7bSAndrey A. Chernov cs.buf = strH; AddXkey(&cs, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
8003b6eaa7bSAndrey A. Chernov cs.buf = strF; AddXkey(&cs, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
801c80476e4SDavid E. O'Brien cs.buf = stOA; AddXkey(&cs, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
802c80476e4SDavid E. O'Brien cs.buf = stOB; AddXkey(&cs, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
803c80476e4SDavid E. O'Brien cs.buf = stOC; AddXkey(&cs, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
804c80476e4SDavid E. O'Brien cs.buf = stOD; AddXkey(&cs, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
8053b6eaa7bSAndrey A. Chernov cs.buf = stOH; AddXkey(&cs, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
8063b6eaa7bSAndrey A. Chernov cs.buf = stOF; AddXkey(&cs, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
807c80476e4SDavid E. O'Brien
808c80476e4SDavid E. O'Brien if (VImode) {
809c80476e4SDavid E. O'Brien cs.len = 2;
810c80476e4SDavid E. O'Brien cs.buf = &strA[1]; AddXkey(&cs, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
811c80476e4SDavid E. O'Brien cs.buf = &strB[1]; AddXkey(&cs, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
812c80476e4SDavid E. O'Brien cs.buf = &strC[1]; AddXkey(&cs, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
813c80476e4SDavid E. O'Brien cs.buf = &strD[1]; AddXkey(&cs, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
8143b6eaa7bSAndrey A. Chernov cs.buf = &strH[1]; AddXkey(&cs, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
8153b6eaa7bSAndrey A. Chernov cs.buf = &strF[1]; AddXkey(&cs, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
816c80476e4SDavid E. O'Brien cs.buf = &stOA[1]; AddXkey(&cs, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
817c80476e4SDavid E. O'Brien cs.buf = &stOB[1]; AddXkey(&cs, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
818c80476e4SDavid E. O'Brien cs.buf = &stOC[1]; AddXkey(&cs, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
819c80476e4SDavid E. O'Brien cs.buf = &stOD[1]; AddXkey(&cs, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
8203b6eaa7bSAndrey A. Chernov cs.buf = &stOH[1]; AddXkey(&cs, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
8213b6eaa7bSAndrey A. Chernov cs.buf = &stOF[1]; AddXkey(&cs, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
822c80476e4SDavid E. O'Brien }
823c80476e4SDavid E. O'Brien }
824c80476e4SDavid E. O'Brien
825c80476e4SDavid E. O'Brien
826c80476e4SDavid E. O'Brien int
SetArrowKeys(const CStr * name,XmapVal * fun,int type)82745e5710bSMark Peek SetArrowKeys(const CStr *name, XmapVal *fun, int type)
828c80476e4SDavid E. O'Brien {
829c80476e4SDavid E. O'Brien int i;
8303b6eaa7bSAndrey A. Chernov for (i = 0; i < A_K_NKEYS; i++)
831c80476e4SDavid E. O'Brien if (Strcmp(name->buf, arrow[i].name) == 0) {
832c80476e4SDavid E. O'Brien arrow[i].fun = *fun;
833c80476e4SDavid E. O'Brien arrow[i].type = type;
834c80476e4SDavid E. O'Brien return 0;
835c80476e4SDavid E. O'Brien }
836c80476e4SDavid E. O'Brien return -1;
837c80476e4SDavid E. O'Brien }
838c80476e4SDavid E. O'Brien
839c80476e4SDavid E. O'Brien int
IsArrowKey(Char * name)84045e5710bSMark Peek IsArrowKey(Char *name)
841c80476e4SDavid E. O'Brien {
842c80476e4SDavid E. O'Brien int i;
8433b6eaa7bSAndrey A. Chernov for (i = 0; i < A_K_NKEYS; i++)
844c80476e4SDavid E. O'Brien if (Strcmp(name, arrow[i].name) == 0)
845c80476e4SDavid E. O'Brien return 1;
846c80476e4SDavid E. O'Brien return 0;
847c80476e4SDavid E. O'Brien }
848c80476e4SDavid E. O'Brien
849c80476e4SDavid E. O'Brien int
ClearArrowKeys(const CStr * name)85045e5710bSMark Peek ClearArrowKeys(const CStr *name)
851c80476e4SDavid E. O'Brien {
852c80476e4SDavid E. O'Brien int i;
8533b6eaa7bSAndrey A. Chernov for (i = 0; i < A_K_NKEYS; i++)
854c80476e4SDavid E. O'Brien if (Strcmp(name->buf, arrow[i].name) == 0) {
855c80476e4SDavid E. O'Brien arrow[i].type = XK_NOD;
856c80476e4SDavid E. O'Brien return 0;
857c80476e4SDavid E. O'Brien }
858c80476e4SDavid E. O'Brien return -1;
859c80476e4SDavid E. O'Brien }
860c80476e4SDavid E. O'Brien
861c80476e4SDavid E. O'Brien void
PrintArrowKeys(const CStr * name)86245e5710bSMark Peek PrintArrowKeys(const CStr *name)
863c80476e4SDavid E. O'Brien {
864c80476e4SDavid E. O'Brien int i;
865c80476e4SDavid E. O'Brien
8663b6eaa7bSAndrey A. Chernov for (i = 0; i < A_K_NKEYS; i++)
867c80476e4SDavid E. O'Brien if (name->len == 0 || Strcmp(name->buf, arrow[i].name) == 0)
86845e5710bSMark Peek if (arrow[i].type != XK_NOD)
86945e5710bSMark Peek printOne(arrow[i].name, &arrow[i].fun, arrow[i].type);
870c80476e4SDavid E. O'Brien }
871c80476e4SDavid E. O'Brien
872c80476e4SDavid E. O'Brien
873c80476e4SDavid E. O'Brien void
BindArrowKeys(void)87445e5710bSMark Peek BindArrowKeys(void)
875c80476e4SDavid E. O'Brien {
876c80476e4SDavid E. O'Brien KEYCMD *map, *dmap;
877c80476e4SDavid E. O'Brien int i, j;
878c80476e4SDavid E. O'Brien char *p;
879c80476e4SDavid E. O'Brien CStr cs;
880c80476e4SDavid E. O'Brien
881c80476e4SDavid E. O'Brien if (!GotTermCaps)
882c80476e4SDavid E. O'Brien return;
883c80476e4SDavid E. O'Brien map = VImode ? CcAltMap : CcKeyMap;
884c80476e4SDavid E. O'Brien dmap = VImode ? CcViCmdMap : CcEmacsMap;
885c80476e4SDavid E. O'Brien
886c80476e4SDavid E. O'Brien DefaultArrowKeys();
887c80476e4SDavid E. O'Brien
8883b6eaa7bSAndrey A. Chernov for (i = 0; i < A_K_NKEYS; i++) {
889c80476e4SDavid E. O'Brien p = tstr[arrow[i].key].str;
890c80476e4SDavid E. O'Brien if (p && *p) {
891c80476e4SDavid E. O'Brien j = (unsigned char) *p;
892c80476e4SDavid E. O'Brien cs.buf = str2short(p);
893c80476e4SDavid E. O'Brien cs.len = Strlen(cs.buf);
894c80476e4SDavid E. O'Brien /*
895c80476e4SDavid E. O'Brien * Assign the arrow keys only if:
896c80476e4SDavid E. O'Brien *
897c80476e4SDavid E. O'Brien * 1. They are multi-character arrow keys and the user
898c80476e4SDavid E. O'Brien * has not re-assigned the leading character, or
899c80476e4SDavid E. O'Brien * has re-assigned the leading character to be F_XKEY
900c80476e4SDavid E. O'Brien * 2. They are single arrow keys pointing to an unassigned key.
901c80476e4SDavid E. O'Brien */
902c80476e4SDavid E. O'Brien if (arrow[i].type == XK_NOD) {
903c80476e4SDavid E. O'Brien ClearXkey(map, &cs);
904c80476e4SDavid E. O'Brien }
905c80476e4SDavid E. O'Brien else {
906c80476e4SDavid E. O'Brien if (p[1] && (dmap[j] == map[j] || map[j] == F_XKEY)) {
907c80476e4SDavid E. O'Brien AddXkey(&cs, &arrow[i].fun, arrow[i].type);
908c80476e4SDavid E. O'Brien map[j] = F_XKEY;
909c80476e4SDavid E. O'Brien }
910c80476e4SDavid E. O'Brien else if (map[j] == F_UNASSIGNED) {
911c80476e4SDavid E. O'Brien ClearXkey(map, &cs);
912c80476e4SDavid E. O'Brien if (arrow[i].type == XK_CMD)
913c80476e4SDavid E. O'Brien map[j] = arrow[i].fun.cmd;
914c80476e4SDavid E. O'Brien else
915c80476e4SDavid E. O'Brien AddXkey(&cs, &arrow[i].fun, arrow[i].type);
916c80476e4SDavid E. O'Brien }
917c80476e4SDavid E. O'Brien }
918c80476e4SDavid E. O'Brien }
919c80476e4SDavid E. O'Brien }
920c80476e4SDavid E. O'Brien }
921c80476e4SDavid E. O'Brien
922c80476e4SDavid E. O'Brien static Char cur_atr = 0; /* current attributes */
923c80476e4SDavid E. O'Brien
924c80476e4SDavid E. O'Brien void
SetAttributes(Char atr)92545e5710bSMark Peek SetAttributes(Char atr)
926c80476e4SDavid E. O'Brien {
927c80476e4SDavid E. O'Brien atr &= ATTRIBUTES;
928c80476e4SDavid E. O'Brien if (atr != cur_atr) {
929c80476e4SDavid E. O'Brien if (me_all && GoodStr(T_me)) {
930c80476e4SDavid E. O'Brien if (((cur_atr & BOLD) && !(atr & BOLD)) ||
931c80476e4SDavid E. O'Brien ((cur_atr & UNDER) && !(atr & UNDER)) ||
932c80476e4SDavid E. O'Brien ((cur_atr & STANDOUT) && !(atr & STANDOUT))) {
933c80476e4SDavid E. O'Brien (void) tputs(Str(T_me), 1, PUTPURE);
934c80476e4SDavid E. O'Brien cur_atr = 0;
935c80476e4SDavid E. O'Brien }
936c80476e4SDavid E. O'Brien }
937c80476e4SDavid E. O'Brien if ((atr & BOLD) != (cur_atr & BOLD)) {
938c80476e4SDavid E. O'Brien if (atr & BOLD) {
939c80476e4SDavid E. O'Brien if (GoodStr(T_md) && GoodStr(T_me)) {
940c80476e4SDavid E. O'Brien (void) tputs(Str(T_md), 1, PUTPURE);
941c80476e4SDavid E. O'Brien cur_atr |= BOLD;
942c80476e4SDavid E. O'Brien }
943c80476e4SDavid E. O'Brien }
944c80476e4SDavid E. O'Brien else {
945c80476e4SDavid E. O'Brien if (GoodStr(T_md) && GoodStr(T_me)) {
946c80476e4SDavid E. O'Brien (void) tputs(Str(T_me), 1, PUTPURE);
947c80476e4SDavid E. O'Brien if ((cur_atr & STANDOUT) && GoodStr(T_se)) {
948c80476e4SDavid E. O'Brien (void) tputs(Str(T_se), 1, PUTPURE);
949c80476e4SDavid E. O'Brien cur_atr &= ~STANDOUT;
950c80476e4SDavid E. O'Brien }
951c80476e4SDavid E. O'Brien if ((cur_atr & UNDER) && GoodStr(T_ue)) {
952c80476e4SDavid E. O'Brien (void) tputs(Str(T_ue), 1, PUTPURE);
953c80476e4SDavid E. O'Brien cur_atr &= ~UNDER;
954c80476e4SDavid E. O'Brien }
955c80476e4SDavid E. O'Brien cur_atr &= ~BOLD;
956c80476e4SDavid E. O'Brien }
957c80476e4SDavid E. O'Brien }
958c80476e4SDavid E. O'Brien }
959c80476e4SDavid E. O'Brien if ((atr & STANDOUT) != (cur_atr & STANDOUT)) {
960c80476e4SDavid E. O'Brien if (atr & STANDOUT) {
961c80476e4SDavid E. O'Brien if (GoodStr(T_so) && GoodStr(T_se)) {
962c80476e4SDavid E. O'Brien (void) tputs(Str(T_so), 1, PUTPURE);
963c80476e4SDavid E. O'Brien cur_atr |= STANDOUT;
964c80476e4SDavid E. O'Brien }
965c80476e4SDavid E. O'Brien }
966c80476e4SDavid E. O'Brien else {
967c80476e4SDavid E. O'Brien if (GoodStr(T_se)) {
968c80476e4SDavid E. O'Brien (void) tputs(Str(T_se), 1, PUTPURE);
969c80476e4SDavid E. O'Brien cur_atr &= ~STANDOUT;
970c80476e4SDavid E. O'Brien }
971c80476e4SDavid E. O'Brien }
972c80476e4SDavid E. O'Brien }
973c80476e4SDavid E. O'Brien if ((atr & UNDER) != (cur_atr & UNDER)) {
974c80476e4SDavid E. O'Brien if (atr & UNDER) {
975c80476e4SDavid E. O'Brien if (GoodStr(T_us) && GoodStr(T_ue)) {
976c80476e4SDavid E. O'Brien (void) tputs(Str(T_us), 1, PUTPURE);
977c80476e4SDavid E. O'Brien cur_atr |= UNDER;
978c80476e4SDavid E. O'Brien }
979c80476e4SDavid E. O'Brien }
980c80476e4SDavid E. O'Brien else {
981c80476e4SDavid E. O'Brien if (GoodStr(T_ue)) {
982c80476e4SDavid E. O'Brien (void) tputs(Str(T_ue), 1, PUTPURE);
983c80476e4SDavid E. O'Brien cur_atr &= ~UNDER;
984c80476e4SDavid E. O'Brien }
985c80476e4SDavid E. O'Brien }
986c80476e4SDavid E. O'Brien }
987c80476e4SDavid E. O'Brien }
988c80476e4SDavid E. O'Brien }
989c80476e4SDavid E. O'Brien
99045e5710bSMark Peek int highlighting = 0;
99145e5710bSMark Peek
99245e5710bSMark Peek void
StartHighlight(void)993*19d2e3deSDmitry Chagin StartHighlight(void)
99445e5710bSMark Peek {
99545e5710bSMark Peek (void) tputs(Str(T_mr), 1, PUTPURE);
99645e5710bSMark Peek highlighting = 1;
99745e5710bSMark Peek }
99845e5710bSMark Peek
99945e5710bSMark Peek void
StopHighlight(void)1000*19d2e3deSDmitry Chagin StopHighlight(void)
100145e5710bSMark Peek {
100245e5710bSMark Peek (void) tputs(Str(T_me), 1, PUTPURE);
100345e5710bSMark Peek highlighting = 0;
100445e5710bSMark Peek }
100545e5710bSMark Peek
1006c80476e4SDavid E. O'Brien /* PWP 6-27-88 -- if the tty driver thinks that we can tab, we ask termcap */
1007c80476e4SDavid E. O'Brien int
CanWeTab(void)100845e5710bSMark Peek CanWeTab(void)
1009c80476e4SDavid E. O'Brien {
1010c80476e4SDavid E. O'Brien return (Val(T_pt));
1011c80476e4SDavid E. O'Brien }
1012c80476e4SDavid E. O'Brien
101345e5710bSMark Peek /* move to line <where> (first line == 0) as efficiently as possible; */
1014c80476e4SDavid E. O'Brien void
MoveToLine(int where)101545e5710bSMark Peek MoveToLine(int where)
1016c80476e4SDavid E. O'Brien {
1017c80476e4SDavid E. O'Brien int del;
1018c80476e4SDavid E. O'Brien
1019c80476e4SDavid E. O'Brien if (where == CursorV)
1020c80476e4SDavid E. O'Brien return;
1021c80476e4SDavid E. O'Brien
1022c80476e4SDavid E. O'Brien if (where > TermV) {
1023c80476e4SDavid E. O'Brien #ifdef DEBUG_SCREEN
1024c80476e4SDavid E. O'Brien xprintf("MoveToLine: where is ridiculous: %d\r\n", where);
1025c80476e4SDavid E. O'Brien flush();
1026c80476e4SDavid E. O'Brien #endif /* DEBUG_SCREEN */
1027c80476e4SDavid E. O'Brien return;
1028c80476e4SDavid E. O'Brien }
1029c80476e4SDavid E. O'Brien
1030c80476e4SDavid E. O'Brien del = where - CursorV;
1031c80476e4SDavid E. O'Brien
1032c80476e4SDavid E. O'Brien if (del > 0) {
1033c80476e4SDavid E. O'Brien while (del > 0) {
1034c80476e4SDavid E. O'Brien if ((T_Margin & MARGIN_AUTO) && Display[CursorV][0] != '\0') {
103523338178SMark Peek size_t h;
103623338178SMark Peek
103723338178SMark Peek for (h = TermH - 1; h > 0 && Display[CursorV][h] == CHAR_DBWIDTH;
103823338178SMark Peek h--)
103923338178SMark Peek ;
1040c80476e4SDavid E. O'Brien /* move without newline */
104123338178SMark Peek MoveToChar(h);
104223338178SMark Peek so_write(&Display[CursorV][CursorH], TermH - CursorH); /* updates CursorH/V*/
1043c80476e4SDavid E. O'Brien del--;
1044c80476e4SDavid E. O'Brien }
1045c80476e4SDavid E. O'Brien else {
1046c80476e4SDavid E. O'Brien if ((del > 1) && GoodStr(T_DO)) {
1047c80476e4SDavid E. O'Brien (void) tputs(tgoto(Str(T_DO), del, del), del, PUTPURE);
1048c80476e4SDavid E. O'Brien del = 0;
1049c80476e4SDavid E. O'Brien }
1050c80476e4SDavid E. O'Brien else {
1051c80476e4SDavid E. O'Brien for ( ; del > 0; del--)
1052c80476e4SDavid E. O'Brien (void) putraw('\n');
1053c80476e4SDavid E. O'Brien CursorH = 0; /* because the \n will become \r\n */
1054c80476e4SDavid E. O'Brien }
1055c80476e4SDavid E. O'Brien }
1056c80476e4SDavid E. O'Brien }
1057c80476e4SDavid E. O'Brien }
1058c80476e4SDavid E. O'Brien else { /* del < 0 */
1059c80476e4SDavid E. O'Brien if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
1060c80476e4SDavid E. O'Brien (void) tputs(tgoto(Str(T_UP), -del, -del), -del, PUTPURE);
1061c80476e4SDavid E. O'Brien else {
1062c80476e4SDavid E. O'Brien int i;
1063c80476e4SDavid E. O'Brien if (GoodStr(T_up))
1064c80476e4SDavid E. O'Brien for (i = 0; i < -del; i++)
1065c80476e4SDavid E. O'Brien (void) tputs(Str(T_up), 1, PUTPURE);
1066c80476e4SDavid E. O'Brien }
1067c80476e4SDavid E. O'Brien }
1068c80476e4SDavid E. O'Brien CursorV = where; /* now where is here */
1069c80476e4SDavid E. O'Brien }
1070c80476e4SDavid E. O'Brien
1071c80476e4SDavid E. O'Brien void
MoveToChar(int where)107245e5710bSMark Peek MoveToChar(int where) /* move to character position (where) */
1073c80476e4SDavid E. O'Brien { /* as efficiently as possible */
1074c80476e4SDavid E. O'Brien int del;
1075c80476e4SDavid E. O'Brien
1076c80476e4SDavid E. O'Brien mc_again:
1077c80476e4SDavid E. O'Brien if (where == CursorH)
1078c80476e4SDavid E. O'Brien return;
1079c80476e4SDavid E. O'Brien
1080c80476e4SDavid E. O'Brien if (where >= TermH) {
1081c80476e4SDavid E. O'Brien #ifdef DEBUG_SCREEN
1082c80476e4SDavid E. O'Brien xprintf("MoveToChar: where is riduculous: %d\r\n", where);
1083c80476e4SDavid E. O'Brien flush();
1084c80476e4SDavid E. O'Brien #endif /* DEBUG_SCREEN */
1085c80476e4SDavid E. O'Brien return;
1086c80476e4SDavid E. O'Brien }
1087c80476e4SDavid E. O'Brien
1088c80476e4SDavid E. O'Brien if (!where) { /* if where is first column */
1089c80476e4SDavid E. O'Brien (void) putraw('\r'); /* do a CR */
1090c80476e4SDavid E. O'Brien CursorH = 0;
1091c80476e4SDavid E. O'Brien return;
1092c80476e4SDavid E. O'Brien }
1093c80476e4SDavid E. O'Brien
1094c80476e4SDavid E. O'Brien del = where - CursorH;
1095c80476e4SDavid E. O'Brien
1096c80476e4SDavid E. O'Brien if ((del < -4 || del > 4) && GoodStr(T_ch))
1097c80476e4SDavid E. O'Brien /* go there directly */
1098c80476e4SDavid E. O'Brien (void) tputs(tgoto(Str(T_ch), where, where), where, PUTPURE);
1099c80476e4SDavid E. O'Brien else {
1100c80476e4SDavid E. O'Brien int i;
1101c80476e4SDavid E. O'Brien if (del > 0) { /* moving forward */
1102c80476e4SDavid E. O'Brien if ((del > 4) && GoodStr(T_RI))
1103c80476e4SDavid E. O'Brien (void) tputs(tgoto(Str(T_RI), del, del), del, PUTPURE);
1104c80476e4SDavid E. O'Brien else {
11053b6eaa7bSAndrey A. Chernov /* if I can do tabs, use them */
110623338178SMark Peek if (T_Tabs) {
110723338178SMark Peek if ((CursorH & 0370) != (where & ~0x7)
110823338178SMark Peek && Display[CursorV][where & ~0x7] != CHAR_DBWIDTH) {
1109c80476e4SDavid E. O'Brien /* if not within tab stop */
111023338178SMark Peek for (i = (CursorH & 0370); i < (where & ~0x7); i += 8)
1111c80476e4SDavid E. O'Brien (void) putraw('\t'); /* then tab over */
111223338178SMark Peek CursorH = where & ~0x7;
1113c80476e4SDavid E. O'Brien /* Note: considering that we often want to go to
1114c80476e4SDavid E. O'Brien TermH - 1 for the wrapping, it would be nice to
1115c80476e4SDavid E. O'Brien optimize this case by tabbing to the last column
1116c80476e4SDavid E. O'Brien - but this doesn't work for all terminals! */
1117c80476e4SDavid E. O'Brien }
1118c80476e4SDavid E. O'Brien }
1119c80476e4SDavid E. O'Brien /* it's usually cheaper to just write the chars, so we do. */
1120c80476e4SDavid E. O'Brien
1121c80476e4SDavid E. O'Brien /* NOTE THAT so_write() WILL CHANGE CursorH!!! */
1122c80476e4SDavid E. O'Brien so_write(&Display[CursorV][CursorH], where - CursorH);
1123c80476e4SDavid E. O'Brien
1124c80476e4SDavid E. O'Brien }
1125c80476e4SDavid E. O'Brien }
1126c80476e4SDavid E. O'Brien else { /* del < 0 := moving backward */
1127c80476e4SDavid E. O'Brien if ((-del > 4) && GoodStr(T_LE))
1128c80476e4SDavid E. O'Brien (void) tputs(tgoto(Str(T_LE), -del, -del), -del, PUTPURE);
1129c80476e4SDavid E. O'Brien else { /* can't go directly there */
1130c80476e4SDavid E. O'Brien /* if the "cost" is greater than the "cost" from col 0 */
1131c80476e4SDavid E. O'Brien if (T_Tabs ? (-del > ((where >> 3) + (where & 07)))
1132c80476e4SDavid E. O'Brien : (-del > where)) {
1133c80476e4SDavid E. O'Brien (void) putraw('\r'); /* do a CR */
1134c80476e4SDavid E. O'Brien CursorH = 0;
1135c80476e4SDavid E. O'Brien goto mc_again; /* and try again */
1136c80476e4SDavid E. O'Brien }
1137c80476e4SDavid E. O'Brien for (i = 0; i < -del; i++)
1138c80476e4SDavid E. O'Brien (void) putraw('\b');
1139c80476e4SDavid E. O'Brien }
1140c80476e4SDavid E. O'Brien }
1141c80476e4SDavid E. O'Brien }
1142c80476e4SDavid E. O'Brien CursorH = where; /* now where is here */
1143c80476e4SDavid E. O'Brien }
1144c80476e4SDavid E. O'Brien
1145c80476e4SDavid E. O'Brien void
so_write(Char * cp,int n)114645e5710bSMark Peek so_write(Char *cp, int n)
1147c80476e4SDavid E. O'Brien {
114845e5710bSMark Peek int cur_pos, prompt_len = 0, region_start = 0, region_end = 0;
114945e5710bSMark Peek
1150c80476e4SDavid E. O'Brien if (n <= 0)
1151c80476e4SDavid E. O'Brien return; /* catch bugs */
1152c80476e4SDavid E. O'Brien
1153c80476e4SDavid E. O'Brien if (n > TermH) {
1154c80476e4SDavid E. O'Brien #ifdef DEBUG_SCREEN
1155c80476e4SDavid E. O'Brien xprintf("so_write: n is riduculous: %d\r\n", n);
1156c80476e4SDavid E. O'Brien flush();
1157c80476e4SDavid E. O'Brien #endif /* DEBUG_SCREEN */
1158c80476e4SDavid E. O'Brien return;
1159c80476e4SDavid E. O'Brien }
1160c80476e4SDavid E. O'Brien
116145e5710bSMark Peek if (adrof(STRhighlight)) {
116245e5710bSMark Peek /* find length of prompt */
116345e5710bSMark Peek Char *promptc;
116445e5710bSMark Peek for (promptc = Prompt; *promptc; promptc++);
116545e5710bSMark Peek prompt_len = promptc - Prompt;
116645e5710bSMark Peek
116745e5710bSMark Peek /* find region start and end points */
116845e5710bSMark Peek if (IncMatchLen) {
116945e5710bSMark Peek region_start = (Cursor - InputBuf) + prompt_len;
117045e5710bSMark Peek region_end = region_start + IncMatchLen;
117145e5710bSMark Peek } else if (MarkIsSet) {
117245e5710bSMark Peek region_start = (min(Cursor, Mark) - InputBuf) + prompt_len;
117345e5710bSMark Peek region_end = (max(Cursor, Mark) - InputBuf) + prompt_len;
117445e5710bSMark Peek }
117545e5710bSMark Peek }
117645e5710bSMark Peek
1177c80476e4SDavid E. O'Brien do {
117845e5710bSMark Peek if (adrof(STRhighlight)) {
117945e5710bSMark Peek cur_pos = CursorV * TermH + CursorH;
118045e5710bSMark Peek if (!highlighting &&
118145e5710bSMark Peek cur_pos >= region_start && cur_pos < region_end)
118245e5710bSMark Peek StartHighlight();
118345e5710bSMark Peek else if (highlighting && cur_pos >= region_end)
118445e5710bSMark Peek StopHighlight();
118545e5710bSMark Peek
118645e5710bSMark Peek /* don't highlight over the cursor. the highlighting's reverse
118745e5710bSMark Peek * video would cancel it out. :P */
118845e5710bSMark Peek if (highlighting && cur_pos == (Cursor - InputBuf) + prompt_len)
118945e5710bSMark Peek StopHighlight();
119045e5710bSMark Peek }
119145e5710bSMark Peek
119223338178SMark Peek if (*cp != CHAR_DBWIDTH) {
1193c80476e4SDavid E. O'Brien if (*cp & LITERAL) {
1194c80476e4SDavid E. O'Brien Char *d;
1195c80476e4SDavid E. O'Brien #ifdef DEBUG_LITERAL
119623338178SMark Peek xprintf("so: litnum %d\r\n", (int)(*cp & ~LITERAL));
1197c80476e4SDavid E. O'Brien #endif /* DEBUG_LITERAL */
119823338178SMark Peek for (d = litptr + (*cp & ~LITERAL) * LIT_FACTOR; *d; d++)
119923338178SMark Peek (void) putwraw(*d);
1200c80476e4SDavid E. O'Brien }
1201c80476e4SDavid E. O'Brien else
120223338178SMark Peek (void) putwraw(*cp);
120323338178SMark Peek }
120423338178SMark Peek cp++;
1205c80476e4SDavid E. O'Brien CursorH++;
1206c80476e4SDavid E. O'Brien } while (--n);
1207c80476e4SDavid E. O'Brien
120845e5710bSMark Peek if (adrof(STRhighlight) && highlighting)
120945e5710bSMark Peek StopHighlight();
121045e5710bSMark Peek
1211c80476e4SDavid E. O'Brien if (CursorH >= TermH) { /* wrap? */
1212c80476e4SDavid E. O'Brien if (T_Margin & MARGIN_AUTO) { /* yes */
1213c80476e4SDavid E. O'Brien CursorH = 0;
1214c80476e4SDavid E. O'Brien CursorV++;
1215c80476e4SDavid E. O'Brien if (T_Margin & MARGIN_MAGIC) {
1216c80476e4SDavid E. O'Brien /* force the wrap to avoid the "magic" situation */
121745e5710bSMark Peek Char xc;
121845e5710bSMark Peek if ((xc = Display[CursorV][CursorH]) != '\0') {
121945e5710bSMark Peek so_write(&xc, 1);
122023338178SMark Peek while (Display[CursorV][CursorH] == CHAR_DBWIDTH)
122123338178SMark Peek CursorH++;
122223338178SMark Peek }
122323338178SMark Peek else {
1224c80476e4SDavid E. O'Brien (void) putraw(' ');
1225c80476e4SDavid E. O'Brien CursorH = 1;
1226c80476e4SDavid E. O'Brien }
1227c80476e4SDavid E. O'Brien }
122823338178SMark Peek }
1229c80476e4SDavid E. O'Brien else /* no wrap, but cursor stays on screen */
1230c80476e4SDavid E. O'Brien CursorH = TermH - 1;
1231c80476e4SDavid E. O'Brien }
1232c80476e4SDavid E. O'Brien }
1233c80476e4SDavid E. O'Brien
1234c80476e4SDavid E. O'Brien
1235c80476e4SDavid E. O'Brien void
DeleteChars(int num)123645e5710bSMark Peek DeleteChars(int num) /* deletes <num> characters */
1237c80476e4SDavid E. O'Brien {
1238c80476e4SDavid E. O'Brien if (num <= 0)
1239c80476e4SDavid E. O'Brien return;
1240c80476e4SDavid E. O'Brien
1241c80476e4SDavid E. O'Brien if (!T_CanDel) {
1242c80476e4SDavid E. O'Brien #ifdef DEBUG_EDIT
1243c80476e4SDavid E. O'Brien xprintf(CGETS(7, 16, "ERROR: cannot delete\r\n"));
1244c80476e4SDavid E. O'Brien #endif /* DEBUG_EDIT */
1245c80476e4SDavid E. O'Brien flush();
1246c80476e4SDavid E. O'Brien return;
1247c80476e4SDavid E. O'Brien }
1248c80476e4SDavid E. O'Brien
1249c80476e4SDavid E. O'Brien if (num > TermH) {
1250c80476e4SDavid E. O'Brien #ifdef DEBUG_SCREEN
1251c80476e4SDavid E. O'Brien xprintf(CGETS(7, 17, "DeleteChars: num is riduculous: %d\r\n"), num);
1252c80476e4SDavid E. O'Brien flush();
1253c80476e4SDavid E. O'Brien #endif /* DEBUG_SCREEN */
1254c80476e4SDavid E. O'Brien return;
1255c80476e4SDavid E. O'Brien }
1256c80476e4SDavid E. O'Brien
1257c80476e4SDavid E. O'Brien if (GoodStr(T_DC)) /* if I have multiple delete */
1258c80476e4SDavid E. O'Brien if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more expen. */
1259c80476e4SDavid E. O'Brien (void) tputs(tgoto(Str(T_DC), num, num), num, PUTPURE);
1260c80476e4SDavid E. O'Brien return;
1261c80476e4SDavid E. O'Brien }
1262c80476e4SDavid E. O'Brien
1263c80476e4SDavid E. O'Brien if (GoodStr(T_dm)) /* if I have delete mode */
1264c80476e4SDavid E. O'Brien (void) tputs(Str(T_dm), 1, PUTPURE);
1265c80476e4SDavid E. O'Brien
1266c80476e4SDavid E. O'Brien if (GoodStr(T_dc)) /* else do one at a time */
1267c80476e4SDavid E. O'Brien while (num--)
1268c80476e4SDavid E. O'Brien (void) tputs(Str(T_dc), 1, PUTPURE);
1269c80476e4SDavid E. O'Brien
1270c80476e4SDavid E. O'Brien if (GoodStr(T_ed)) /* if I have delete mode */
1271c80476e4SDavid E. O'Brien (void) tputs(Str(T_ed), 1, PUTPURE);
1272c80476e4SDavid E. O'Brien }
1273c80476e4SDavid E. O'Brien
127445e5710bSMark Peek /* Puts terminal in insert character mode, or inserts num characters in the
127545e5710bSMark Peek line */
1276c80476e4SDavid E. O'Brien void
Insert_write(Char * cp,int num)127745e5710bSMark Peek Insert_write(Char *cp, int num)
1278c80476e4SDavid E. O'Brien {
1279c80476e4SDavid E. O'Brien if (num <= 0)
1280c80476e4SDavid E. O'Brien return;
1281c80476e4SDavid E. O'Brien if (!T_CanIns) {
1282c80476e4SDavid E. O'Brien #ifdef DEBUG_EDIT
1283c80476e4SDavid E. O'Brien xprintf(CGETS(7, 18, "ERROR: cannot insert\r\n"));
1284c80476e4SDavid E. O'Brien #endif /* DEBUG_EDIT */
1285c80476e4SDavid E. O'Brien flush();
1286c80476e4SDavid E. O'Brien return;
1287c80476e4SDavid E. O'Brien }
1288c80476e4SDavid E. O'Brien
1289c80476e4SDavid E. O'Brien if (num > TermH) {
1290c80476e4SDavid E. O'Brien #ifdef DEBUG_SCREEN
1291c80476e4SDavid E. O'Brien xprintf(CGETS(7, 19, "StartInsert: num is riduculous: %d\r\n"), num);
1292c80476e4SDavid E. O'Brien flush();
1293c80476e4SDavid E. O'Brien #endif /* DEBUG_SCREEN */
1294c80476e4SDavid E. O'Brien return;
1295c80476e4SDavid E. O'Brien }
1296c80476e4SDavid E. O'Brien
1297c80476e4SDavid E. O'Brien if (GoodStr(T_IC)) /* if I have multiple insert */
1298c80476e4SDavid E. O'Brien if ((num > 1) || !GoodStr(T_ic)) { /* if ic would be more expen. */
1299c80476e4SDavid E. O'Brien (void) tputs(tgoto(Str(T_IC), num, num), num, PUTPURE);
1300c80476e4SDavid E. O'Brien so_write(cp, num); /* this updates CursorH/V */
1301c80476e4SDavid E. O'Brien return;
1302c80476e4SDavid E. O'Brien }
1303c80476e4SDavid E. O'Brien
1304c80476e4SDavid E. O'Brien if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */
1305c80476e4SDavid E. O'Brien (void) tputs(Str(T_im), 1, PUTPURE);
1306c80476e4SDavid E. O'Brien
130723338178SMark Peek so_write(cp, num); /* this updates CursorH/V */
1308c80476e4SDavid E. O'Brien
1309c80476e4SDavid E. O'Brien if (GoodStr(T_ip)) /* have to make num chars insert */
1310c80476e4SDavid E. O'Brien (void) tputs(Str(T_ip), 1, PUTPURE);
1311c80476e4SDavid E. O'Brien
1312c80476e4SDavid E. O'Brien (void) tputs(Str(T_ei), 1, PUTPURE);
1313c80476e4SDavid E. O'Brien return;
1314c80476e4SDavid E. O'Brien }
1315c80476e4SDavid E. O'Brien
1316c80476e4SDavid E. O'Brien do {
1317c80476e4SDavid E. O'Brien if (GoodStr(T_ic)) /* have to make num chars insert */
1318c80476e4SDavid E. O'Brien (void) tputs(Str(T_ic), 1, PUTPURE); /* insert a char */
1319c80476e4SDavid E. O'Brien
132023338178SMark Peek so_write(cp++, 1); /* this updates CursorH/V */
1321c80476e4SDavid E. O'Brien
1322c80476e4SDavid E. O'Brien if (GoodStr(T_ip)) /* have to make num chars insert */
1323c80476e4SDavid E. O'Brien (void) tputs(Str(T_ip), 1, PUTPURE);/* pad the inserted char */
1324c80476e4SDavid E. O'Brien
1325c80476e4SDavid E. O'Brien } while (--num);
1326c80476e4SDavid E. O'Brien
1327c80476e4SDavid E. O'Brien }
1328c80476e4SDavid E. O'Brien
132945e5710bSMark Peek /* clear to end of line. There are num characters to clear */
1330c80476e4SDavid E. O'Brien void
ClearEOL(int num)133145e5710bSMark Peek ClearEOL(int num)
1332c80476e4SDavid E. O'Brien {
133323338178SMark Peek int i;
1334c80476e4SDavid E. O'Brien
1335c80476e4SDavid E. O'Brien if (num <= 0)
1336c80476e4SDavid E. O'Brien return;
1337c80476e4SDavid E. O'Brien
1338c80476e4SDavid E. O'Brien if (T_CanCEOL && GoodStr(T_ce))
1339c80476e4SDavid E. O'Brien (void) tputs(Str(T_ce), 1, PUTPURE);
1340c80476e4SDavid E. O'Brien else {
1341c80476e4SDavid E. O'Brien for (i = 0; i < num; i++)
1342c80476e4SDavid E. O'Brien (void) putraw(' ');
1343c80476e4SDavid E. O'Brien CursorH += num; /* have written num spaces */
1344c80476e4SDavid E. O'Brien }
1345c80476e4SDavid E. O'Brien }
1346c80476e4SDavid E. O'Brien
1347c80476e4SDavid E. O'Brien void
ClearScreen(void)134845e5710bSMark Peek ClearScreen(void)
1349c80476e4SDavid E. O'Brien { /* clear the whole screen and home */
1350c80476e4SDavid E. O'Brien if (GoodStr(T_cl))
1351c80476e4SDavid E. O'Brien /* send the clear screen code */
1352c80476e4SDavid E. O'Brien (void) tputs(Str(T_cl), Val(T_li), PUTPURE);
1353c80476e4SDavid E. O'Brien else if (GoodStr(T_ho) && GoodStr(T_cd)) {
1354c80476e4SDavid E. O'Brien (void) tputs(Str(T_ho), Val(T_li), PUTPURE); /* home */
1355c80476e4SDavid E. O'Brien /* clear to bottom of screen */
1356c80476e4SDavid E. O'Brien (void) tputs(Str(T_cd), Val(T_li), PUTPURE);
1357c80476e4SDavid E. O'Brien }
1358c80476e4SDavid E. O'Brien else {
1359c80476e4SDavid E. O'Brien (void) putraw('\r');
1360c80476e4SDavid E. O'Brien (void) putraw('\n');
1361c80476e4SDavid E. O'Brien }
1362c80476e4SDavid E. O'Brien }
1363c80476e4SDavid E. O'Brien
1364c80476e4SDavid E. O'Brien void
SoundBeep(void)136545e5710bSMark Peek SoundBeep(void)
1366c80476e4SDavid E. O'Brien { /* produce a sound */
1367c80476e4SDavid E. O'Brien beep_cmd ();
1368c80476e4SDavid E. O'Brien if (adrof(STRnobeep))
1369c80476e4SDavid E. O'Brien return;
1370c80476e4SDavid E. O'Brien
1371c80476e4SDavid E. O'Brien if (GoodStr(T_vb) && adrof(STRvisiblebell))
1372c80476e4SDavid E. O'Brien (void) tputs(Str(T_vb), 1, PUTPURE); /* visible bell */
1373c80476e4SDavid E. O'Brien else if (GoodStr(T_bl))
1374c80476e4SDavid E. O'Brien /* what termcap says we should use */
1375c80476e4SDavid E. O'Brien (void) tputs(Str(T_bl), 1, PUTPURE);
1376c80476e4SDavid E. O'Brien else
1377c80476e4SDavid E. O'Brien (void) putraw(CTL_ESC('\007')); /* an ASCII bell; ^G */
1378c80476e4SDavid E. O'Brien }
1379c80476e4SDavid E. O'Brien
1380c80476e4SDavid E. O'Brien void
ClearToBottom(void)138145e5710bSMark Peek ClearToBottom(void)
1382c80476e4SDavid E. O'Brien { /* clear to the bottom of the screen */
1383c80476e4SDavid E. O'Brien if (GoodStr(T_cd))
1384c80476e4SDavid E. O'Brien (void) tputs(Str(T_cd), Val(T_li), PUTPURE);
1385c80476e4SDavid E. O'Brien else if (GoodStr(T_ce))
1386c80476e4SDavid E. O'Brien (void) tputs(Str(T_ce), Val(T_li), PUTPURE);
1387c80476e4SDavid E. O'Brien }
1388c80476e4SDavid E. O'Brien
1389c80476e4SDavid E. O'Brien void
GetTermCaps(void)139045e5710bSMark Peek GetTermCaps(void)
1391c80476e4SDavid E. O'Brien { /* read in the needed terminal capabilites */
139223338178SMark Peek int i;
139323338178SMark Peek const char *ptr;
1394c80476e4SDavid E. O'Brien char buf[TC_BUFSIZE];
1395c80476e4SDavid E. O'Brien static char bp[TC_BUFSIZE];
1396c80476e4SDavid E. O'Brien char *area;
1397c80476e4SDavid E. O'Brien struct termcapstr *t;
1398c80476e4SDavid E. O'Brien
1399c80476e4SDavid E. O'Brien
1400c80476e4SDavid E. O'Brien #ifdef SIG_WINDOW
140145e5710bSMark Peek sigset_t oset, set;
1402c80476e4SDavid E. O'Brien int lins, cols;
1403c80476e4SDavid E. O'Brien
1404c80476e4SDavid E. O'Brien /* don't want to confuse things here */
140545e5710bSMark Peek sigemptyset(&set);
140645e5710bSMark Peek sigaddset(&set, SIG_WINDOW);
140745e5710bSMark Peek (void)sigprocmask(SIG_BLOCK, &set, &oset);
140845e5710bSMark Peek cleanup_push(&oset, sigprocmask_cleanup);
1409c80476e4SDavid E. O'Brien #endif /* SIG_WINDOW */
1410c80476e4SDavid E. O'Brien area = buf;
1411c80476e4SDavid E. O'Brien
1412c80476e4SDavid E. O'Brien GotTermCaps = 1;
1413c80476e4SDavid E. O'Brien
1414c80476e4SDavid E. O'Brien setname("gettermcaps");
1415c80476e4SDavid E. O'Brien ptr = getenv("TERM");
1416c80476e4SDavid E. O'Brien
1417c80476e4SDavid E. O'Brien #ifdef apollo
1418c80476e4SDavid E. O'Brien /*
1419c80476e4SDavid E. O'Brien * If we are on a pad, we pretend that we are dumb. Otherwise the termcap
1420c80476e4SDavid E. O'Brien * library will put us in a weird screen mode, thinking that we are going
1421c80476e4SDavid E. O'Brien * to use curses
1422c80476e4SDavid E. O'Brien */
1423c80476e4SDavid E. O'Brien if (isapad())
1424c80476e4SDavid E. O'Brien ptr = "dumb";
1425c80476e4SDavid E. O'Brien #endif /* apollo */
1426c80476e4SDavid E. O'Brien
1427c80476e4SDavid E. O'Brien if (!ptr || !ptr[0] || !strcmp(ptr, "wm") || !strcmp(ptr,"dmx"))
1428c80476e4SDavid E. O'Brien ptr = "dumb";
1429c80476e4SDavid E. O'Brien
1430c80476e4SDavid E. O'Brien setzero(bp, TC_BUFSIZE);
1431c80476e4SDavid E. O'Brien
1432c80476e4SDavid E. O'Brien i = tgetent(bp, ptr);
1433c80476e4SDavid E. O'Brien if (i <= 0) {
1434c80476e4SDavid E. O'Brien if (i == -1) {
1435c80476e4SDavid E. O'Brien #if (SYSVREL == 0) || defined(IRIS3D)
1436*19d2e3deSDmitry Chagin xprintf(CGETS(7, 20,
1437*19d2e3deSDmitry Chagin "%s: The terminal database could not be opened.\n"), progname);
1438c80476e4SDavid E. O'Brien }
1439c80476e4SDavid E. O'Brien else if (i == 0) {
1440c80476e4SDavid E. O'Brien #endif /* SYSVREL */
1441c80476e4SDavid E. O'Brien xprintf(CGETS(7, 21,
1442c80476e4SDavid E. O'Brien "%s: No entry for terminal type \"%s\"\n"), progname,
1443c80476e4SDavid E. O'Brien getenv("TERM"));
1444c80476e4SDavid E. O'Brien }
1445c80476e4SDavid E. O'Brien xprintf(CGETS(7, 22, "%s: using dumb terminal settings.\n"), progname);
1446c80476e4SDavid E. O'Brien Val(T_co) = 80; /* do a dumb terminal */
1447c80476e4SDavid E. O'Brien Val(T_pt) = Val(T_km) = Val(T_li) = 0;
1448c80476e4SDavid E. O'Brien for (t = tstr; t->name != NULL; t++)
144945e5710bSMark Peek TCset(t, NULL);
1450c80476e4SDavid E. O'Brien }
1451c80476e4SDavid E. O'Brien else {
1452c80476e4SDavid E. O'Brien /* Can we tab */
1453c80476e4SDavid E. O'Brien Val(T_pt) = tgetflag("pt") && !tgetflag("xt");
1454c80476e4SDavid E. O'Brien /* do we have a meta? */
1455c80476e4SDavid E. O'Brien Val(T_km) = (tgetflag("km") || tgetflag("MT"));
1456c80476e4SDavid E. O'Brien Val(T_am) = tgetflag("am");
1457c80476e4SDavid E. O'Brien Val(T_xn) = tgetflag("xn");
1458c80476e4SDavid E. O'Brien Val(T_co) = tgetnum("co");
1459c80476e4SDavid E. O'Brien Val(T_li) = tgetnum("li");
1460c80476e4SDavid E. O'Brien for (t = tstr; t->name != NULL; t++)
146145e5710bSMark Peek TCset(t, tgetstr(t->name, &area));
1462c80476e4SDavid E. O'Brien }
1463c80476e4SDavid E. O'Brien if (Val(T_co) < 2)
1464c80476e4SDavid E. O'Brien Val(T_co) = 80; /* just in case */
1465c80476e4SDavid E. O'Brien if (Val(T_li) < 1)
1466c80476e4SDavid E. O'Brien Val(T_li) = 24;
1467c80476e4SDavid E. O'Brien
1468c80476e4SDavid E. O'Brien T_Cols = (Char) Val(T_co);
1469c80476e4SDavid E. O'Brien T_Lines = (Char) Val(T_li);
1470c80476e4SDavid E. O'Brien if (T_Tabs)
147145e5710bSMark Peek T_Tabs = Val(T_pt);
147245e5710bSMark Peek T_HasMeta = Val(T_km);
147345e5710bSMark Peek T_Margin = Val(T_am) ? MARGIN_AUTO : 0;
147445e5710bSMark Peek T_Margin |= Val(T_xn) ? MARGIN_MAGIC : 0;
1475c80476e4SDavid E. O'Brien T_CanCEOL = GoodStr(T_ce);
1476c80476e4SDavid E. O'Brien T_CanDel = GoodStr(T_dc) || GoodStr(T_DC);
1477c80476e4SDavid E. O'Brien T_CanIns = GoodStr(T_im) || GoodStr(T_ic) || GoodStr(T_IC);
1478c80476e4SDavid E. O'Brien T_CanUP = GoodStr(T_up) || GoodStr(T_UP);
1479c80476e4SDavid E. O'Brien if (GoodStr(T_me) && GoodStr(T_ue))
1480c80476e4SDavid E. O'Brien me_all = (strcmp(Str(T_me), Str(T_ue)) == 0);
1481c80476e4SDavid E. O'Brien else
1482c80476e4SDavid E. O'Brien me_all = 0;
1483c80476e4SDavid E. O'Brien if (GoodStr(T_me) && GoodStr(T_se))
1484c80476e4SDavid E. O'Brien me_all |= (strcmp(Str(T_me), Str(T_se)) == 0);
1485c80476e4SDavid E. O'Brien
1486c80476e4SDavid E. O'Brien
1487c80476e4SDavid E. O'Brien #ifdef DEBUG_SCREEN
1488c80476e4SDavid E. O'Brien if (!T_CanUP) {
1489c80476e4SDavid E. O'Brien xprintf(CGETS(7, 23, "%s: WARNING: Your terminal cannot move up.\n",
1490c80476e4SDavid E. O'Brien progname));
1491c80476e4SDavid E. O'Brien xprintf(CGETS(7, 24, "Editing may be odd for long lines.\n"));
1492c80476e4SDavid E. O'Brien }
1493c80476e4SDavid E. O'Brien if (!T_CanCEOL)
1494c80476e4SDavid E. O'Brien xprintf(CGETS(7, 25, "no clear EOL capability.\n"));
1495c80476e4SDavid E. O'Brien if (!T_CanDel)
1496c80476e4SDavid E. O'Brien xprintf(CGETS(7, 26, "no delete char capability.\n"));
1497c80476e4SDavid E. O'Brien if (!T_CanIns)
1498c80476e4SDavid E. O'Brien xprintf(CGETS(7, 27, "no insert char capability.\n"));
1499c80476e4SDavid E. O'Brien #endif /* DEBUG_SCREEN */
1500c80476e4SDavid E. O'Brien
1501c80476e4SDavid E. O'Brien
1502c80476e4SDavid E. O'Brien
1503c80476e4SDavid E. O'Brien #ifdef SIG_WINDOW
1504c80476e4SDavid E. O'Brien (void) GetSize(&lins, &cols); /* get the correct window size */
1505c80476e4SDavid E. O'Brien ChangeSize(lins, cols);
1506c80476e4SDavid E. O'Brien
150745e5710bSMark Peek cleanup_until(&oset); /* can change it again */
1508c80476e4SDavid E. O'Brien #else /* SIG_WINDOW */
1509c80476e4SDavid E. O'Brien ChangeSize(Val(T_li), Val(T_co));
1510c80476e4SDavid E. O'Brien #endif /* SIG_WINDOW */
1511c80476e4SDavid E. O'Brien
1512c80476e4SDavid E. O'Brien BindArrowKeys();
1513c80476e4SDavid E. O'Brien }
1514c80476e4SDavid E. O'Brien
1515c80476e4SDavid E. O'Brien #ifdef SIG_WINDOW
1516c80476e4SDavid E. O'Brien /* GetSize():
1517c80476e4SDavid E. O'Brien * Return the new window size in lines and cols, and
1518c80476e4SDavid E. O'Brien * true if the size was changed. This can fail if SHIN
1519c80476e4SDavid E. O'Brien * is not a tty, but it will work in most cases.
1520c80476e4SDavid E. O'Brien */
1521c80476e4SDavid E. O'Brien int
GetSize(int * lins,int * cols)152245e5710bSMark Peek GetSize(int *lins, int *cols)
1523c80476e4SDavid E. O'Brien {
1524c80476e4SDavid E. O'Brien *cols = Val(T_co);
1525c80476e4SDavid E. O'Brien *lins = Val(T_li);
1526c80476e4SDavid E. O'Brien
1527c80476e4SDavid E. O'Brien #ifdef TIOCGWINSZ
1528c80476e4SDavid E. O'Brien # define KNOWsize
1529c80476e4SDavid E. O'Brien # ifndef lint
1530c80476e4SDavid E. O'Brien {
1531c80476e4SDavid E. O'Brien struct winsize ws; /* from 4.3 */
1532c80476e4SDavid E. O'Brien
1533c80476e4SDavid E. O'Brien if (ioctl(SHIN, TIOCGWINSZ, (ioctl_t) &ws) != -1) {
1534c80476e4SDavid E. O'Brien if (ws.ws_col)
1535c80476e4SDavid E. O'Brien *cols = ws.ws_col;
1536c80476e4SDavid E. O'Brien if (ws.ws_row)
1537c80476e4SDavid E. O'Brien *lins = ws.ws_row;
1538c80476e4SDavid E. O'Brien }
1539c80476e4SDavid E. O'Brien }
1540c80476e4SDavid E. O'Brien # endif /* !lint */
1541c80476e4SDavid E. O'Brien #else /* TIOCGWINSZ */
1542c80476e4SDavid E. O'Brien # ifdef TIOCGSIZE
1543c80476e4SDavid E. O'Brien # define KNOWsize
1544c80476e4SDavid E. O'Brien {
1545c80476e4SDavid E. O'Brien struct ttysize ts; /* from Sun */
1546c80476e4SDavid E. O'Brien
1547c80476e4SDavid E. O'Brien if (ioctl(SHIN, TIOCGSIZE, (ioctl_t) &ts) != -1) {
1548c80476e4SDavid E. O'Brien if (ts.ts_cols)
1549c80476e4SDavid E. O'Brien *cols = ts.ts_cols;
1550c80476e4SDavid E. O'Brien if (ts.ts_lines)
1551c80476e4SDavid E. O'Brien *lins = ts.ts_lines;
1552c80476e4SDavid E. O'Brien }
1553c80476e4SDavid E. O'Brien }
1554c80476e4SDavid E. O'Brien # endif /* TIOCGSIZE */
1555c80476e4SDavid E. O'Brien #endif /* TIOCGWINSZ */
1556c80476e4SDavid E. O'Brien
1557c80476e4SDavid E. O'Brien return (Val(T_co) != *cols || Val(T_li) != *lins);
1558c80476e4SDavid E. O'Brien }
1559c80476e4SDavid E. O'Brien
156045e5710bSMark Peek #endif /* SIG_WINDOW */
1561c80476e4SDavid E. O'Brien
15629ccc37e3SMark Peek #ifdef KNOWsize
1563*19d2e3deSDmitry Chagin static int
UpdateVal(const Char * tag,int value,Char * termcap,Char * backup)15649ccc37e3SMark Peek UpdateVal(const Char *tag, int value, Char *termcap, Char *backup)
15659ccc37e3SMark Peek {
15669ccc37e3SMark Peek Char *ptr, *p;
15679ccc37e3SMark Peek if ((ptr = Strstr(termcap, tag)) == NULL) {
15689ccc37e3SMark Peek (void)Strcpy(backup, termcap);
1569*19d2e3deSDmitry Chagin return 0;
15709ccc37e3SMark Peek } else {
15719ccc37e3SMark Peek size_t len = (ptr - termcap) + Strlen(tag);
15729ccc37e3SMark Peek (void)Strncpy(backup, termcap, len);
15739ccc37e3SMark Peek backup[len] = '\0';
15749ccc37e3SMark Peek p = Itoa(value, 0, 0);
15759ccc37e3SMark Peek (void) Strcat(backup + len, p);
15769ccc37e3SMark Peek xfree(p);
15779ccc37e3SMark Peek ptr = Strchr(ptr, ':');
15789ccc37e3SMark Peek if (ptr)
15799ccc37e3SMark Peek (void) Strcat(backup, ptr);
1580*19d2e3deSDmitry Chagin return 1;
15819ccc37e3SMark Peek }
15829ccc37e3SMark Peek }
15839ccc37e3SMark Peek #endif
15849ccc37e3SMark Peek
1585c80476e4SDavid E. O'Brien void
ChangeSize(int lins,int cols)158645e5710bSMark Peek ChangeSize(int lins, int cols)
1587c80476e4SDavid E. O'Brien {
1588c80476e4SDavid E. O'Brien /*
1589c80476e4SDavid E. O'Brien * Just in case
1590c80476e4SDavid E. O'Brien */
1591c80476e4SDavid E. O'Brien Val(T_co) = (cols < 2) ? 80 : cols;
1592c80476e4SDavid E. O'Brien Val(T_li) = (lins < 1) ? 24 : lins;
1593c80476e4SDavid E. O'Brien
1594c80476e4SDavid E. O'Brien #ifdef KNOWsize
1595c80476e4SDavid E. O'Brien /*
1596c80476e4SDavid E. O'Brien * We want to affect the environment only when we have a valid
1597c80476e4SDavid E. O'Brien * setup, not when we get bad settings. Consider the following scenario:
1598c80476e4SDavid E. O'Brien * We just logged in, and we have not initialized the editor yet.
1599c80476e4SDavid E. O'Brien * We reset termcap with tset, and not $TERMCAP has the right
1600c80476e4SDavid E. O'Brien * terminal size. But since the editor is not initialized yet, and
1601c80476e4SDavid E. O'Brien * the kernel's notion of the terminal size might be wrong we arrive
1602c80476e4SDavid E. O'Brien * here with lines = columns = 0. If we reset the environment we lose
1603c80476e4SDavid E. O'Brien * our only chance to get the window size right.
1604c80476e4SDavid E. O'Brien */
1605c80476e4SDavid E. O'Brien if (Val(T_co) == cols && Val(T_li) == lins) {
160645e5710bSMark Peek Char *p;
1607c80476e4SDavid E. O'Brien char *tptr;
1608c80476e4SDavid E. O'Brien
1609c80476e4SDavid E. O'Brien if (getenv("COLUMNS")) {
161045e5710bSMark Peek p = Itoa(Val(T_co), 0, 0);
161145e5710bSMark Peek cleanup_push(p, xfree);
161245e5710bSMark Peek tsetenv(STRCOLUMNS, p);
161345e5710bSMark Peek cleanup_until(p);
1614c80476e4SDavid E. O'Brien }
1615c80476e4SDavid E. O'Brien
1616c80476e4SDavid E. O'Brien if (getenv("LINES")) {
161745e5710bSMark Peek p = Itoa(Val(T_li), 0, 0);
161845e5710bSMark Peek cleanup_push(p, xfree);
161945e5710bSMark Peek tsetenv(STRLINES, p);
162045e5710bSMark Peek cleanup_until(p);
1621c80476e4SDavid E. O'Brien }
1622c80476e4SDavid E. O'Brien
1623c80476e4SDavid E. O'Brien if ((tptr = getenv("TERMCAP")) != NULL) {
1624c80476e4SDavid E. O'Brien /* Leave 64 characters slop in case we enlarge the termcap string */
162545e5710bSMark Peek Char termcap[TC_BUFSIZE+64], backup[TC_BUFSIZE+64], *ptr;
1626*19d2e3deSDmitry Chagin int changed;
1627c80476e4SDavid E. O'Brien
1628c80476e4SDavid E. O'Brien ptr = str2short(tptr);
162945e5710bSMark Peek (void) Strncpy(termcap, ptr, TC_BUFSIZE);
163045e5710bSMark Peek termcap[TC_BUFSIZE-1] = '\0';
1631c80476e4SDavid E. O'Brien
1632*19d2e3deSDmitry Chagin changed = UpdateVal(STRco, Val(T_co), termcap, backup);
1633*19d2e3deSDmitry Chagin changed |= UpdateVal(STRli, Val(T_li), termcap, backup);
1634c80476e4SDavid E. O'Brien
1635*19d2e3deSDmitry Chagin if (changed) {
1636c80476e4SDavid E. O'Brien /*
163745e5710bSMark Peek * Chop the termcap string at TC_BUFSIZE-1 characters to avoid
163845e5710bSMark Peek * core-dumps in the termcap routines
1639c80476e4SDavid E. O'Brien */
164045e5710bSMark Peek termcap[TC_BUFSIZE - 1] = '\0';
1641c80476e4SDavid E. O'Brien tsetenv(STRTERMCAP, termcap);
1642c80476e4SDavid E. O'Brien }
1643c80476e4SDavid E. O'Brien }
1644*19d2e3deSDmitry Chagin }
1645c80476e4SDavid E. O'Brien #endif /* KNOWsize */
1646c80476e4SDavid E. O'Brien
1647c80476e4SDavid E. O'Brien ReBufferDisplay(); /* re-make display buffers */
1648c80476e4SDavid E. O'Brien ClearDisp();
1649c80476e4SDavid E. O'Brien }
1650