1 /*-
2  * Copyright (c) 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1993, 1994, 1995, 1996
5  *	Keith Bostic.  All rights reserved.
6  *
7  * See the LICENSE file for redistribution information.
8  */
9 
10 #include "config.h"
11 
12 #ifndef lint
13 static const char sccsid[] = "@(#)tk_funcs.c	8.11 (Berkeley) 9/23/96";
14 #endif /* not lint */
15 
16 #include <sys/types.h>
17 #include <sys/queue.h>
18 #include <sys/time.h>
19 
20 #include <bitstring.h>
21 #include <ctype.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <termios.h>
27 #include <unistd.h>
28 
29 #include "../common/common.h"
30 #include "../vi/vi.h"
31 #include "tki.h"
32 
33 /*
34  * tk_addstr --
35  *	Add len bytes from the string at the cursor, advancing the cursor.
36  *
37  * PUBLIC: int tk_addstr __P((SCR *, const char *, size_t));
38  */
39 int
tk_addstr(sp,str,len)40 tk_addstr(sp, str, len)
41 	SCR *sp;
42 	const char *str;
43 	size_t len;
44 {
45 	TK_PRIVATE *tkp;
46 	int iv;
47 	char buf[20];
48 
49 	iv = 0;
50 
51 	tkp = TKP(sp);
52 	if (iv)
53 		(void)Tcl_Eval(tkp->interp, "tk_standout");
54 
55 	(void)snprintf(buf, sizeof(buf), "%d ", (int)len);
56 	if ((Tcl_VarEval(tkp->interp,
57 	    "tk_addstr ", buf, "{", str, "}", NULL) != TCL_OK))
58 		return (1);
59 
60 	if (iv)
61 		(void)Tcl_Eval(tkp->interp, "tk_standend");
62 	return (0);
63 }
64 
65 /*
66  * tk_attr --
67  *	Toggle a screen attribute on/off.
68  *
69  * PUBLIC: int tk_attr __P((SCR *, scr_attr_t, int));
70  */
71 int
tk_attr(sp,attribute,on)72 tk_attr(sp, attribute, on)
73 	SCR *sp;
74 	scr_attr_t attribute;
75 	int on;
76 {
77 	TK_PRIVATE *tkp;
78 
79 	tkp = TKP(sp);
80 	switch (attribute) {
81 	case SA_ALTERNATE:			/* No alternate screen. */
82 		break;
83 	case SA_INVERSE:
84 		if (on)
85 			(void)Tcl_Eval(tkp->interp, "tk_standout");
86 		else
87 			(void)Tcl_Eval(tkp->interp, "tk_standend");
88 		break;
89 	default:
90 		abort();
91 	}
92 	return (0);
93 }
94 
95 /*
96  * tk_baud --
97  *	Return the baud rate.
98  *
99  * PUBLIC: int tk_baud __P((SCR *, u_long *));
100  */
101 int
tk_baud(sp,ratep)102 tk_baud(sp, ratep)
103 	SCR *sp;
104 	u_long *ratep;
105 {
106 	*ratep = 9600;
107 	return (0);
108 }
109 
110 /*
111  * tk_bell --
112  *	Ring the bell/flash the screen.
113  *
114  * PUBLIC: int tk_bell __P((SCR *));
115  */
116 int
tk_bell(sp)117 tk_bell(sp)
118 	SCR *sp;
119 {
120 	TK_PRIVATE *tkp;
121 
122 	tkp = TKP(sp);
123 	return (Tcl_Eval(tkp->interp, "tk_flash") != TCL_OK);
124 }
125 
126 /*
127  * tk_clrtoeol --
128  *	Clear from the current cursor to the end of the line.
129  *
130  * PUBLIC: int tk_clrtoeol __P((SCR *));
131  */
132 int
tk_clrtoeol(sp)133 tk_clrtoeol(sp)
134 	SCR *sp;
135 {
136 	TK_PRIVATE *tkp;
137 
138 	tkp = TKP(sp);
139 	return (Tcl_Eval(tkp->interp, "tk_clrtoeol") != TCL_OK);
140 }
141 
142 /*
143  * tk_cursor --
144  *	Return the current cursor position.
145  *
146  * PUBLIC: int tk_cursor __P((SCR *, size_t *, size_t *));
147  */
148 int
tk_cursor(sp,yp,xp)149 tk_cursor(sp, yp, xp)
150 	SCR *sp;
151 	size_t *yp, *xp;
152 {
153 	TK_PRIVATE *tkp;
154 
155 	tkp = TKP(sp);
156 	*yp = (tkp->tk_cursor_row - 1) - sp->woff;
157 	*xp = tkp->tk_cursor_col;
158 	return (0);
159 }
160 
161 /*
162  * tk_deleteln --
163  *	Delete the current line, scrolling all lines below it.
164  *
165  * PUBLIC: int tk_deleteln __P((SCR *));
166  */
167 int
tk_deleteln(sp)168 tk_deleteln(sp)
169 	SCR *sp;
170 {
171 	TK_PRIVATE *tkp;
172 
173 	tkp = TKP(sp);
174 	return (Tcl_Eval(tkp->interp, "tk_deleteln") != TCL_OK);
175 }
176 
177 /*
178  * tk_ex_adjust --
179  *	Adjust the screen for ex.
180  *
181  * PUBLIC: int tk_ex_adjust __P((SCR *, exadj_t));
182  */
183 int
tk_ex_adjust(sp,action)184 tk_ex_adjust(sp, action)
185 	SCR *sp;
186 	exadj_t action;
187 {
188 	abort();
189 	/* NOTREACHED */
190 }
191 
192 /*
193  * tk_insertln --
194  *	Push down the current line, discarding the bottom line.
195  *
196  * PUBLIC: int tk_insertln __P((SCR *));
197  */
198 int
tk_insertln(sp)199 tk_insertln(sp)
200 	SCR *sp;
201 {
202 	TK_PRIVATE *tkp;
203 
204 	tkp = TKP(sp);
205 	return (Tcl_Eval(tkp->interp, "tk_insertln") != TCL_OK);
206 }
207 
208 /*
209  * tk_keyval --
210  *	Return the value for a special key.
211  *
212  * PUBLIC: int tk_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
213  */
214 int
tk_keyval(sp,val,chp,dnep)215 tk_keyval(sp, val, chp, dnep)
216 	SCR *sp;
217 	scr_keyval_t val;
218 	CHAR_T *chp;
219 	int *dnep;
220 {
221 	TK_PRIVATE *tkp;
222 
223 	/*
224 	 * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
225 	 * VWERASE is a 4BSD extension.
226 	 */
227 	tkp = TKP(sp);
228 	switch (val) {
229 	case KEY_VEOF:
230 		*dnep = (*chp = tkp->orig.c_cc[VEOF]) == _POSIX_VDISABLE;
231 		break;
232 	case KEY_VERASE:
233 		*dnep = (*chp = tkp->orig.c_cc[VERASE]) == _POSIX_VDISABLE;
234 		break;
235 	case KEY_VKILL:
236 		*dnep = (*chp = tkp->orig.c_cc[VKILL]) == _POSIX_VDISABLE;
237 		break;
238 #ifdef VWERASE
239 	case KEY_VWERASE:
240 		*dnep = (*chp = tkp->orig.c_cc[VWERASE]) == _POSIX_VDISABLE;
241 		break;
242 #endif
243 	default:
244 		*dnep = 1;
245 		break;
246 	}
247 	return (0);
248 }
249 
250 /*
251  * tk_move --
252  *	Move the cursor.
253  *
254  * PUBLIC: int tk_move __P((SCR *, size_t, size_t));
255  */
256 int
tk_move(sp,lno,cno)257 tk_move(sp, lno, cno)
258 	SCR *sp;
259 	size_t lno, cno;
260 {
261 	TK_PRIVATE *tkp;
262 	char buf[40];
263 
264 	(void)snprintf(buf, sizeof(buf), "%d %d", RLNO(sp, lno), cno);
265 
266 	tkp = TKP(sp);
267 	return (Tcl_VarEval(tkp->interp, "tk_move ", buf, NULL) != TCL_OK);
268 }
269 
270 /*
271  * tk_refresh --
272  *	Refresh the screen.
273  *
274  * PUBLIC: int tk_refresh __P((SCR *, int));
275  */
276 int
tk_refresh(sp,repaint)277 tk_refresh(sp, repaint)
278 	SCR *sp;
279 	int repaint;
280 {
281 	TK_PRIVATE *tkp;
282 
283 	/*
284 	 * If repaint is set, the editor is telling us that we don't know
285 	 * what's on the screen, so we have to repaint from scratch.
286 	 *
287 	 * XXX
288 	 * I have no idea how to do this in Tk.  My guess is that we have
289 	 * to delete all of the text and call the editor with an E_REPAINT
290 	 * event.
291 	 */
292 	if (repaint) {
293 	}
294 
295 	tkp = TKP(sp);
296 	return (Tcl_Eval(tkp->interp, "update idletasks") != TCL_OK);
297 }
298 
299 /*
300  * tk_rename --
301  *	Rename the file.
302  *
303  * PUBLIC: int tk_rename __P((SCR *));
304  */
305 int
tk_rename(sp)306 tk_rename(sp)
307 	SCR *sp;
308 {
309 	TK_PRIVATE *tkp;
310 
311 	tkp = TKP(sp);
312 	return (Tcl_VarEval(tkp->interp,
313 	    "tk_rename ", sp->frp->name, NULL) != TCL_OK);
314 }
315 
316 /*
317  * tk_suspend --
318  *	Suspend a screen.
319  *
320  * PUBLIC: int tk_suspend __P((SCR *, int *));
321  */
322 int
tk_suspend(sp,allowedp)323 tk_suspend(sp, allowedp)
324 	SCR *sp;
325 	int *allowedp;
326 {
327 	*allowedp = 0;
328 	return (0);
329 }
330 
331 /*
332  * tk_usage --
333  *	Print out the Tk/Tcl usage messages.
334  *
335  * PUBLIC: void tk_usage __P((void));
336  */
337 void
tk_usage()338 tk_usage()
339 {
340 #define	USAGE "\
341 usage: tkvi [-eFlRrSv] [-c command] [-bg color] [-fg color]\n\
342 	    [-geometry widthxheight+x+y] [-i script] [-t tag] [-w size]\n\
343 	    [file ...]\n"
344 	(void)fprintf(stderr, "%s", USAGE);
345 #undef	USAGE
346 }
347