Another CHAR_T patch.
[nvi.git] / ip / ip_funcs.c
blob7f51b0474cf64510f44433ea01c416403b58da20
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.20 2000/07/14 14:29:22 skimo Exp $ (Berkeley) $Date: 2000/07/14 14:29:22 $";
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_waddstr __P((SCR *, const CHAR_T *, size_t));
34 int
35 ip_waddstr(sp, str, len)
36 SCR *sp;
37 const CHAR_T *str;
38 size_t len;
40 CONST char *np;
41 size_t nlen;
43 INT2CHAR(sp, str, len, np, nlen);
44 ip_addstr(sp, np, nlen);
48 * ip_addstr --
49 * Add len bytes from the string at the cursor, advancing the cursor.
51 * PUBLIC: int ip_addstr __P((SCR *, const char *, size_t));
53 int
54 ip_addstr(sp, str, len)
55 SCR *sp;
56 const char *str;
57 size_t len;
59 IP_BUF ipb;
60 IP_PRIVATE *ipp;
61 int iv, rval;
63 ipp = IPP(sp);
66 * If ex isn't in control, it's the last line of the screen and
67 * it's a split screen, use inverse video.
69 iv = 0;
70 if (!F_ISSET(sp, SC_SCR_EXWROTE) &&
71 ipp->row == LASTLINE(sp) && IS_SPLIT(sp)) {
72 iv = 1;
73 ip_attr(sp, SA_INVERSE, 1);
75 ipb.code = SI_ADDSTR;
76 ipb.len1 = len;
77 ipb.str1 = str;
78 rval = vi_send(ipp->o_fd, "a", &ipb);
79 /* XXXX */
80 ipp->col += len;
82 if (iv)
83 ip_attr(sp, SA_INVERSE, 0);
84 return (rval);
88 * ip_attr --
89 * Toggle a screen attribute on/off.
91 * PUBLIC: int ip_attr __P((SCR *, scr_attr_t, int));
93 int
94 ip_attr(sp, attribute, on)
95 SCR *sp;
96 scr_attr_t attribute;
97 int on;
99 IP_BUF ipb;
100 IP_PRIVATE *ipp = IPP(sp);
102 if (attribute == SA_ALTERNATE) {
103 if (on) F_SET(ipp, IP_ON_ALTERNATE);
104 else F_CLR(ipp, IP_ON_ALTERNATE);
107 ipb.code = SI_ATTRIBUTE;
108 ipb.val1 = attribute;
109 ipb.val2 = on;
111 return (vi_send(ipp->o_fd, "12", &ipb));
115 * ip_baud --
116 * Return the baud rate.
118 * PUBLIC: int ip_baud __P((SCR *, u_long *));
121 ip_baud(sp, ratep)
122 SCR *sp;
123 u_long *ratep;
125 *ratep = 9600; /* XXX: Translation: fast. */
126 return (0);
130 * ip_bell --
131 * Ring the bell/flash the screen.
133 * PUBLIC: int ip_bell __P((SCR *));
136 ip_bell(sp)
137 SCR *sp;
139 IP_BUF ipb;
140 IP_PRIVATE *ipp = IPP(sp);
142 ipb.code = SI_BELL;
144 return (vi_send(ipp->o_fd, NULL, &ipb));
148 * ip_busy --
149 * Display a busy message.
151 * PUBLIC: void ip_busy __P((SCR *, const char *, busy_t));
153 void
154 ip_busy(sp, str, bval)
155 SCR *sp;
156 const char *str;
157 busy_t bval;
159 IP_BUF ipb;
160 IP_PRIVATE *ipp = IPP(sp);
162 switch (bval) {
163 case BUSY_ON:
164 ipb.code = SI_BUSY_ON;
165 ipb.str1 = str;
166 ipb.len1 = strlen(str);
167 (void)vi_send(ipp->o_fd, "a", &ipb);
168 break;
169 case BUSY_OFF:
170 ipb.code = SI_BUSY_OFF;
171 (void)vi_send(ipp->o_fd, NULL, &ipb);
172 break;
173 case BUSY_UPDATE:
174 break;
176 return;
180 * ip_child --
181 * Prepare child.
183 * PUBLIC: int ip_child __P((SCR *));
186 ip_child(sp)
187 SCR *sp;
189 IP_PRIVATE *ipp = IPP(sp);
191 if (ipp->t_fd != -1) {
192 dup2(ipp->t_fd, 0);
193 dup2(ipp->t_fd, 1);
194 dup2(ipp->t_fd, 2);
195 close(ipp->t_fd);
197 return 0;
201 * ip_clrtoeol --
202 * Clear from the current cursor to the end of the line.
204 * PUBLIC: int ip_clrtoeol __P((SCR *));
207 ip_clrtoeol(sp)
208 SCR *sp;
210 IP_BUF ipb;
211 IP_PRIVATE *ipp = IPP(sp);
213 /* Temporary hack until we can pass screen pointers
214 * or name screens
216 if (IS_VSPLIT(sp)) {
217 size_t x, y, spcnt;
218 IP_PRIVATE *ipp;
219 int error;
221 ipp = IPP(sp);
222 y = ipp->row;
223 x = ipp->col;
224 error = 0;
225 for (spcnt = sp->cols - x;
226 spcnt > 0 && ! error; --spcnt)
227 error = ip_addstr(sp, " ", 1);
228 if (sp->coff == 0)
229 error |= ip_addstr(sp, "|", 1);
230 error |= ip_move(sp, y, x);
231 return error;
234 ipb.code = SI_CLRTOEOL;
236 return (vi_send(ipp->o_fd, NULL, &ipb));
240 * ip_cursor --
241 * Return the current cursor position.
243 * PUBLIC: int ip_cursor __P((SCR *, size_t *, size_t *));
246 ip_cursor(sp, yp, xp)
247 SCR *sp;
248 size_t *yp, *xp;
250 IP_PRIVATE *ipp;
252 ipp = IPP(sp);
253 *yp = ipp->row;
254 *xp = ipp->col;
255 return (0);
259 * ip_deleteln --
260 * Delete the current line, scrolling all lines below it.
262 * PUBLIC: int ip_deleteln __P((SCR *));
265 ip_deleteln(sp)
266 SCR *sp;
268 IP_BUF ipb;
269 IP_PRIVATE *ipp = IPP(sp);
272 * This clause is required because the curses screen uses reverse
273 * video to delimit split screens. If the screen does not do this,
274 * this code won't be necessary.
276 * If the bottom line was in reverse video, rewrite it in normal
277 * video before it's scrolled.
279 if (!F_ISSET(sp, SC_SCR_EXWROTE) && IS_SPLIT(sp)) {
280 ipb.code = SI_REWRITE;
281 ipb.val1 = RLNO(sp, LASTLINE(sp));
282 if (vi_send(ipp->o_fd, "1", &ipb))
283 return (1);
287 * The bottom line is expected to be blank after this operation,
288 * and other screens must support that semantic.
290 ipb.code = SI_DELETELN;
291 return (vi_send(ipp->o_fd, NULL, &ipb));
295 * ip_discard --
296 * Discard a screen.
298 * PUBLIC: int ip_discard __P((SCR *, SCR **));
301 ip_discard(discardp, acquirep)
302 SCR *discardp, **acquirep;
304 return (0);
308 * ip_ex_adjust --
309 * Adjust the screen for ex.
311 * PUBLIC: int ip_ex_adjust __P((SCR *, exadj_t));
314 ip_ex_adjust(sp, action)
315 SCR *sp;
316 exadj_t action;
318 abort();
319 /* NOTREACHED */
323 * ip_insertln --
324 * Push down the current line, discarding the bottom line.
326 * PUBLIC: int ip_insertln __P((SCR *));
329 ip_insertln(sp)
330 SCR *sp;
332 IP_BUF ipb;
333 IP_PRIVATE *ipp = IPP(sp);
335 ipb.code = SI_INSERTLN;
337 return (vi_send(ipp->o_fd, NULL, &ipb));
341 * ip_keyval --
342 * Return the value for a special key.
344 * PUBLIC: int ip_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
347 ip_keyval(sp, val, chp, dnep)
348 SCR *sp;
349 scr_keyval_t val;
350 CHAR_T *chp;
351 int *dnep;
354 * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
355 * VWERASE is a 4BSD extension.
357 switch (val) {
358 case KEY_VEOF:
359 *dnep = '\004'; /* ^D */
360 break;
361 case KEY_VERASE:
362 *dnep = '\b'; /* ^H */
363 break;
364 case KEY_VKILL:
365 *dnep = '\025'; /* ^U */
366 break;
367 #ifdef VWERASE
368 case KEY_VWERASE:
369 *dnep = '\027'; /* ^W */
370 break;
371 #endif
372 default:
373 *dnep = 1;
374 break;
376 return (0);
380 * ip_move --
381 * Move the cursor.
383 * PUBLIC: int ip_move __P((SCR *, size_t, size_t));
386 ip_move(sp, lno, cno)
387 SCR *sp;
388 size_t lno, cno;
390 IP_PRIVATE *ipp;
391 IP_BUF ipb;
393 ipp = IPP(sp);
394 ipp->row = lno;
395 ipp->col = cno;
397 ipb.code = SI_MOVE;
398 ipb.val1 = RLNO(sp, lno);
399 ipb.val2 = RCNO(sp, cno);
400 return (vi_send(ipp->o_fd, "12", &ipb));
404 * PUBLIC: void ip_msg __P((SCR *, mtype_t, char *, size_t));
406 void
407 ip_msg(sp, mtype, line, len)
408 SCR *sp;
409 mtype_t mtype;
410 char *line;
411 size_t len;
413 IP_PRIVATE *ipp = IPP(sp);
415 if (F_ISSET(ipp, IP_ON_ALTERNATE))
416 vs_msg(sp, mtype, line, len);
417 else {
418 write(ipp->t_fd, line, len);
419 F_CLR(sp, SC_EX_WAIT_NO);
424 * ip_refresh --
425 * Refresh the screen.
427 * PUBLIC: int ip_refresh __P((SCR *, int));
430 ip_refresh(sp, repaint)
431 SCR *sp;
432 int repaint;
434 IP_BUF ipb;
435 IP_PRIVATE *ipp;
436 db_recno_t total;
438 ipp = IPP(sp);
441 * If the scroll bar information has changed since we last sent
442 * it, resend it. Currently, we send three values:
444 * top The line number of the first line in the screen.
445 * num The number of lines visible on the screen.
446 * total The number of lines in the file.
448 * XXX
449 * This is a gross violation of layering... we're looking at data
450 * structures at which we have absolutely no business whatsoever
451 * looking...
453 ipb.val1 = HMAP->lno;
454 ipb.val2 = TMAP->lno - HMAP->lno;
455 (void)db_last(sp, &total);
456 ipb.val3 = total == 0 ? 1 : total;
457 if (ipb.val1 != ipp->sb_top ||
458 ipb.val2 != ipp->sb_num || ipb.val3 != ipp->sb_total) {
459 ipb.code = SI_SCROLLBAR;
460 (void)vi_send(ipp->o_fd, "123", &ipb);
461 ipp->sb_top = ipb.val1;
462 ipp->sb_num = ipb.val2;
463 ipp->sb_total = ipb.val3;
466 /* Refresh/repaint the screen. */
467 ipb.code = repaint ? SI_REDRAW : SI_REFRESH;
468 return (vi_send(ipp->o_fd, NULL, &ipb));
472 * ip_rename --
473 * Rename the file.
475 * PUBLIC: int ip_rename __P((SCR *, char *, int));
478 ip_rename(sp, name, on)
479 SCR *sp;
480 char *name;
481 int on;
483 IP_BUF ipb;
484 IP_PRIVATE *ipp = IPP(sp);
486 ipb.code = SI_RENAME;
487 ipb.str1 = name;
488 ipb.len1 = name ? strlen(name) : 0;
489 return (vi_send(ipp->o_fd, "a", &ipb));
493 * ip_reply --
494 * Reply to a message.
496 * PUBLIC: int ip_reply __P((SCR *, int, char *));
499 ip_reply(sp, status, msg)
500 SCR *sp;
501 int status;
502 char *msg;
504 IP_BUF ipb;
505 IP_PRIVATE *ipp = IPP(sp);
507 ipb.code = SI_REPLY;
508 ipb.val1 = status;
509 ipb.str1 = msg == NULL ? "" : msg;
510 ipb.len1 = strlen(ipb.str1);
511 return (vi_send(ipp->o_fd, "1a", &ipb));
515 * ip_split --
516 * Split a screen.
518 * PUBLIC: int ip_split __P((SCR *, SCR *));
521 ip_split(origp, newp)
522 SCR *origp, *newp;
524 return (0);
528 * ip_suspend --
529 * Suspend a screen.
531 * PUBLIC: int ip_suspend __P((SCR *, int *));
534 ip_suspend(sp, allowedp)
535 SCR *sp;
536 int *allowedp;
538 *allowedp = 0;
539 return (0);
543 * ip_usage --
544 * Print out the ip usage messages.
546 * PUBLIC: void ip_usage __P((void));
548 void
549 ip_usage()
551 #define USAGE "\
552 usage: vi [-eFlRrSv] [-c command] [-I ifd.ofd] [-t tag] [-w size] [file ...]\n"
553 (void)fprintf(stderr, "%s", USAGE);
554 #undef USAGE