update from From: Sven Verdoolaege <skimo@breughel.ufsia.ac.be>
[nvi.git] / ip / ip_funcs.c
blob62d8efbb2f024e9fa2a6f279df51e2422b0b84f8
1 /*-
2 * Copyright (c) 1996
3 * Keith Bostic. All rights reserved.
5 * See the LICENSE file for redistribution information.
6 */
8 #include "config.h"
10 #ifndef lint
11 static const char sccsid[] = "$Id: ip_funcs.c,v 8.13 1997/08/02 16:48:59 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:48:59 $";
12 #endif /* not lint */
14 #include <sys/types.h>
15 #include <sys/queue.h>
16 #include <sys/time.h>
18 #include <bitstring.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
23 #include "../common/common.h"
24 #include "../vi/vi.h"
25 #include "../ipc/ip.h"
26 #include "extern.h"
29 * ip_addstr --
30 * Add len bytes from the string at the cursor, advancing the cursor.
32 * PUBLIC: int ip_addstr __P((SCR *, const char *, size_t));
34 int
35 ip_addstr(sp, str, len)
36 SCR *sp;
37 const char *str;
38 size_t len;
40 IP_BUF ipb;
41 IP_PRIVATE *ipp;
42 int iv, rval;
44 ipp = IPP(sp);
47 * If ex isn't in control, it's the last line of the screen and
48 * it's a split screen, use inverse video.
50 iv = 0;
51 if (!F_ISSET(sp, SC_SCR_EXWROTE) &&
52 ipp->row == LASTLINE(sp) && IS_SPLIT(sp)) {
53 iv = 1;
54 ip_attr(sp, SA_INVERSE, 1);
56 ipb.code = SI_ADDSTR;
57 ipb.len1 = len;
58 ipb.str1 = str;
59 rval = vi_send("a", &ipb);
61 if (iv)
62 ip_attr(sp, SA_INVERSE, 0);
63 return (rval);
67 * ip_attr --
68 * Toggle a screen attribute on/off.
70 * PUBLIC: int ip_attr __P((SCR *, scr_attr_t, int));
72 int
73 ip_attr(sp, attribute, on)
74 SCR *sp;
75 scr_attr_t attribute;
76 int on;
78 IP_BUF ipb;
80 ipb.code = SI_ATTRIBUTE;
81 ipb.val1 = attribute;
82 ipb.val2 = on;
84 return (vi_send("12", &ipb));
88 * ip_baud --
89 * Return the baud rate.
91 * PUBLIC: int ip_baud __P((SCR *, u_long *));
93 int
94 ip_baud(sp, ratep)
95 SCR *sp;
96 u_long *ratep;
98 *ratep = 9600; /* XXX: Translation: fast. */
99 return (0);
103 * ip_bell --
104 * Ring the bell/flash the screen.
106 * PUBLIC: int ip_bell __P((SCR *));
109 ip_bell(sp)
110 SCR *sp;
112 IP_BUF ipb;
114 ipb.code = SI_BELL;
116 return (vi_send(NULL, &ipb));
120 * ip_busy --
121 * Display a busy message.
123 * PUBLIC: void ip_busy __P((SCR *, const char *, busy_t));
125 void
126 ip_busy(sp, str, bval)
127 SCR *sp;
128 const char *str;
129 busy_t bval;
131 IP_BUF ipb;
133 switch (bval) {
134 case BUSY_ON:
135 ipb.code = SI_BUSY_ON;
136 ipb.str1 = str;
137 ipb.len1 = strlen(str);
138 (void)vi_send("a", &ipb);
139 break;
140 case BUSY_OFF:
141 ipb.code = SI_BUSY_OFF;
142 (void)vi_send(NULL, &ipb);
143 break;
144 case BUSY_UPDATE:
145 break;
147 return;
151 * ip_clrtoeol --
152 * Clear from the current cursor to the end of the line.
154 * PUBLIC: int ip_clrtoeol __P((SCR *));
157 ip_clrtoeol(sp)
158 SCR *sp;
160 IP_BUF ipb;
162 ipb.code = SI_CLRTOEOL;
164 return (vi_send(NULL, &ipb));
168 * ip_cursor --
169 * Return the current cursor position.
171 * PUBLIC: int ip_cursor __P((SCR *, size_t *, size_t *));
174 ip_cursor(sp, yp, xp)
175 SCR *sp;
176 size_t *yp, *xp;
178 IP_PRIVATE *ipp;
180 ipp = IPP(sp);
181 *yp = ipp->row;
182 *xp = ipp->col;
183 return (0);
187 * ip_deleteln --
188 * Delete the current line, scrolling all lines below it.
190 * PUBLIC: int ip_deleteln __P((SCR *));
193 ip_deleteln(sp)
194 SCR *sp;
196 IP_BUF ipb;
199 * This clause is required because the curses screen uses reverse
200 * video to delimit split screens. If the screen does not do this,
201 * this code won't be necessary.
203 * If the bottom line was in reverse video, rewrite it in normal
204 * video before it's scrolled.
206 if (!F_ISSET(sp, SC_SCR_EXWROTE) && IS_SPLIT(sp)) {
207 ipb.code = SI_REWRITE;
208 ipb.val1 = RLNO(sp, LASTLINE(sp));
209 if (vi_send("1", &ipb))
210 return (1);
214 * The bottom line is expected to be blank after this operation,
215 * and other screens must support that semantic.
217 ipb.code = SI_DELETELN;
218 return (vi_send(NULL, &ipb));
222 * ip_discard --
223 * Discard a screen.
225 * PUBLIC: int ip_discard __P((SCR *, SCR *));
228 ip_discard(discardp, acquirep)
229 SCR *discardp, *acquirep;
231 return (0);
235 * ip_ex_adjust --
236 * Adjust the screen for ex.
238 * PUBLIC: int ip_ex_adjust __P((SCR *, exadj_t));
241 ip_ex_adjust(sp, action)
242 SCR *sp;
243 exadj_t action;
245 abort();
246 /* NOTREACHED */
250 * ip_insertln --
251 * Push down the current line, discarding the bottom line.
253 * PUBLIC: int ip_insertln __P((SCR *));
256 ip_insertln(sp)
257 SCR *sp;
259 IP_BUF ipb;
261 ipb.code = SI_INSERTLN;
263 return (vi_send(NULL, &ipb));
267 * ip_keyval --
268 * Return the value for a special key.
270 * PUBLIC: int ip_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
273 ip_keyval(sp, val, chp, dnep)
274 SCR *sp;
275 scr_keyval_t val;
276 CHAR_T *chp;
277 int *dnep;
280 * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
281 * VWERASE is a 4BSD extension.
283 switch (val) {
284 case KEY_VEOF:
285 *dnep = '\004'; /* ^D */
286 break;
287 case KEY_VERASE:
288 *dnep = '\b'; /* ^H */
289 break;
290 case KEY_VKILL:
291 *dnep = '\025'; /* ^U */
292 break;
293 #ifdef VWERASE
294 case KEY_VWERASE:
295 *dnep = '\027'; /* ^W */
296 break;
297 #endif
298 default:
299 *dnep = 1;
300 break;
302 return (0);
306 * ip_move --
307 * Move the cursor.
309 * PUBLIC: int ip_move __P((SCR *, size_t, size_t));
312 ip_move(sp, lno, cno)
313 SCR *sp;
314 size_t lno, cno;
316 IP_PRIVATE *ipp;
317 IP_BUF ipb;
319 ipp = IPP(sp);
320 ipp->row = lno;
321 ipp->col = cno;
323 ipb.code = SI_MOVE;
324 ipb.val1 = RLNO(sp, lno);
325 ipb.val2 = cno;
326 return (vi_send("12", &ipb));
330 * ip_refresh --
331 * Refresh the screen.
333 * PUBLIC: int ip_refresh __P((SCR *, int));
336 ip_refresh(sp, repaint)
337 SCR *sp;
338 int repaint;
340 IP_BUF ipb;
341 IP_PRIVATE *ipp;
342 recno_t total;
344 ipp = IPP(sp);
347 * If the scroll bar information has changed since we last sent
348 * it, resend it. Currently, we send three values:
350 * top The line number of the first line in the screen.
351 * num The number of lines visible on the screen.
352 * total The number of lines in the file.
354 * XXX
355 * This is a gross violation of layering... we're looking at data
356 * structures at which we have absolutely no business whatsoever
357 * looking...
359 ipb.val1 = HMAP->lno;
360 ipb.val2 = TMAP->lno - HMAP->lno;
361 (void)db_last(sp, &total);
362 ipb.val3 = total == 0 ? 1 : total;
363 if (ipb.val1 != ipp->sb_top ||
364 ipb.val2 != ipp->sb_num || ipb.val3 != ipp->sb_total) {
365 ipb.code = SI_SCROLLBAR;
366 (void)vi_send("123", &ipb);
367 ipp->sb_top = ipb.val1;
368 ipp->sb_num = ipb.val2;
369 ipp->sb_total = ipb.val3;
372 /* Refresh/repaint the screen. */
373 ipb.code = repaint ? SI_REDRAW : SI_REFRESH;
374 return (vi_send(NULL, &ipb));
378 * ip_rename --
379 * Rename the file.
381 * PUBLIC: int ip_rename __P((SCR *, char *, int));
384 ip_rename(sp, name, on)
385 SCR *sp;
386 char *name;
387 int on;
389 IP_BUF ipb;
391 ipb.code = SI_RENAME;
392 ipb.str1 = name;
393 ipb.len1 = strlen(name);
394 return (vi_send("a", &ipb));
398 * ip_reply --
399 * Reply to a message.
401 * PUBLIC: int ip_reply __P((SCR *, int, char *));
404 ip_reply(sp, status, msg)
405 SCR *sp;
406 int status;
407 char *msg;
409 IP_BUF ipb;
411 ipb.code = SI_REPLY;
412 ipb.val1 = status;
413 ipb.str1 = msg == NULL ? "" : msg;
414 ipb.len1 = strlen(ipb.str1);
415 return (vi_send("1a", &ipb));
419 * ip_split --
420 * Split a screen.
422 * PUBLIC: int ip_split __P((SCR *, SCR *));
425 ip_split(origp, newp)
426 SCR *origp, *newp;
428 return (0);
432 * ip_suspend --
433 * Suspend a screen.
435 * PUBLIC: int ip_suspend __P((SCR *, int *));
438 ip_suspend(sp, allowedp)
439 SCR *sp;
440 int *allowedp;
442 *allowedp = 0;
443 return (0);
447 * ip_usage --
448 * Print out the ip usage messages.
450 * PUBLIC: void ip_usage __P((void));
452 void
453 ip_usage()
455 #define USAGE "\
456 usage: vi [-eFlRrSv] [-c command] [-I ifd.ofd] [-t tag] [-w size] [file ...]\n"
457 (void)fprintf(stderr, "%s", USAGE);
458 #undef USAGE