3 * Keith Bostic. All rights reserved.
5 * See the LICENSE file for redistribution information.
11 static const char sccsid
[] = "$Id: ip_funcs.c,v 8.22 2000/07/19 18:31:55 skimo Exp $ (Berkeley) $Date: 2000/07/19 18:31:55 $";
14 #include <sys/types.h>
15 #include <sys/queue.h>
18 #include <bitstring.h>
23 #include "../common/common.h"
25 #include "../ipc/ip.h"
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));
35 ip_waddstr(sp
, str
, len
)
46 ipb
.code
= SI_WADDSTR
;
47 ipb
.len1
= len
* sizeof(CHAR_T
);
48 ipb
.str1
= (char *)str
;
49 rval
= vi_send(ipp
->o_fd
, "a", &ipb
);
58 * Add len bytes from the string at the cursor, advancing the cursor.
60 * PUBLIC: int ip_addstr __P((SCR *, const char *, size_t));
63 ip_addstr(sp
, str
, len
)
75 * If ex isn't in control, it's the last line of the screen and
76 * it's a split screen, use inverse video.
79 if (!F_ISSET(sp
, SC_SCR_EXWROTE
) &&
80 ipp
->row
== LASTLINE(sp
) && IS_SPLIT(sp
)) {
82 ip_attr(sp
, SA_INVERSE
, 1);
87 rval
= vi_send(ipp
->o_fd
, "a", &ipb
);
92 ip_attr(sp
, SA_INVERSE
, 0);
98 * Toggle a screen attribute on/off.
100 * PUBLIC: int ip_attr __P((SCR *, scr_attr_t, int));
103 ip_attr(sp
, attribute
, on
)
105 scr_attr_t attribute
;
109 IP_PRIVATE
*ipp
= IPP(sp
);
111 if (attribute
== SA_ALTERNATE
) {
112 if (on
) F_SET(ipp
, IP_ON_ALTERNATE
);
113 else F_CLR(ipp
, IP_ON_ALTERNATE
);
116 ipb
.code
= SI_ATTRIBUTE
;
117 ipb
.val1
= attribute
;
120 return (vi_send(ipp
->o_fd
, "12", &ipb
));
125 * Return the baud rate.
127 * PUBLIC: int ip_baud __P((SCR *, u_long *));
134 *ratep
= 9600; /* XXX: Translation: fast. */
140 * Ring the bell/flash the screen.
142 * PUBLIC: int ip_bell __P((SCR *));
149 IP_PRIVATE
*ipp
= IPP(sp
);
153 return (vi_send(ipp
->o_fd
, NULL
, &ipb
));
158 * Display a busy message.
160 * PUBLIC: void ip_busy __P((SCR *, const char *, busy_t));
163 ip_busy(sp
, str
, bval
)
169 IP_PRIVATE
*ipp
= IPP(sp
);
173 ipb
.code
= SI_BUSY_ON
;
175 ipb
.len1
= strlen(str
);
176 (void)vi_send(ipp
->o_fd
, "a", &ipb
);
179 ipb
.code
= SI_BUSY_OFF
;
180 (void)vi_send(ipp
->o_fd
, NULL
, &ipb
);
192 * PUBLIC: int ip_child __P((SCR *));
198 IP_PRIVATE
*ipp
= IPP(sp
);
200 if (ipp
->t_fd
!= -1) {
211 * Clear from the current cursor to the end of the line.
213 * PUBLIC: int ip_clrtoeol __P((SCR *));
220 IP_PRIVATE
*ipp
= IPP(sp
);
222 /* Temporary hack until we can pass screen pointers
234 for (spcnt
= sp
->cols
- x
;
235 spcnt
> 0 && ! error
; --spcnt
)
236 error
= ip_addstr(sp
, " ", 1);
238 error
|= ip_addstr(sp
, "|", 1);
239 error
|= ip_move(sp
, y
, x
);
243 ipb
.code
= SI_CLRTOEOL
;
245 return (vi_send(ipp
->o_fd
, NULL
, &ipb
));
250 * Return the current cursor position.
252 * PUBLIC: int ip_cursor __P((SCR *, size_t *, size_t *));
255 ip_cursor(sp
, yp
, xp
)
269 * Delete the current line, scrolling all lines below it.
271 * PUBLIC: int ip_deleteln __P((SCR *));
278 IP_PRIVATE
*ipp
= IPP(sp
);
281 * This clause is required because the curses screen uses reverse
282 * video to delimit split screens. If the screen does not do this,
283 * this code won't be necessary.
285 * If the bottom line was in reverse video, rewrite it in normal
286 * video before it's scrolled.
288 if (!F_ISSET(sp
, SC_SCR_EXWROTE
) && IS_SPLIT(sp
)) {
289 ipb
.code
= SI_REWRITE
;
290 ipb
.val1
= RLNO(sp
, LASTLINE(sp
));
291 if (vi_send(ipp
->o_fd
, "1", &ipb
))
296 * The bottom line is expected to be blank after this operation,
297 * and other screens must support that semantic.
299 ipb
.code
= SI_DELETELN
;
300 return (vi_send(ipp
->o_fd
, NULL
, &ipb
));
307 * PUBLIC: int ip_discard __P((SCR *, SCR **));
310 ip_discard(discardp
, acquirep
)
311 SCR
*discardp
, **acquirep
;
318 * Adjust the screen for ex.
320 * PUBLIC: int ip_ex_adjust __P((SCR *, exadj_t));
323 ip_ex_adjust(sp
, action
)
333 * Push down the current line, discarding the bottom line.
335 * PUBLIC: int ip_insertln __P((SCR *));
342 IP_PRIVATE
*ipp
= IPP(sp
);
344 ipb
.code
= SI_INSERTLN
;
346 return (vi_send(ipp
->o_fd
, NULL
, &ipb
));
351 * Return the value for a special key.
353 * PUBLIC: int ip_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
356 ip_keyval(sp
, val
, chp
, dnep
)
363 * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
364 * VWERASE is a 4BSD extension.
368 *dnep
= '\004'; /* ^D */
371 *dnep
= '\b'; /* ^H */
374 *dnep
= '\025'; /* ^U */
378 *dnep
= '\027'; /* ^W */
392 * PUBLIC: int ip_move __P((SCR *, size_t, size_t));
395 ip_move(sp
, lno
, cno
)
407 ipb
.val1
= RLNO(sp
, lno
);
408 ipb
.val2
= RCNO(sp
, cno
);
409 return (vi_send(ipp
->o_fd
, "12", &ipb
));
413 * PUBLIC: void ip_msg __P((SCR *, mtype_t, char *, size_t));
416 ip_msg(sp
, mtype
, line
, len
)
422 IP_PRIVATE
*ipp
= IPP(sp
);
424 if (F_ISSET(ipp
, IP_ON_ALTERNATE
))
425 vs_msg(sp
, mtype
, line
, len
);
427 write(ipp
->t_fd
, line
, len
);
428 F_CLR(sp
, SC_EX_WAIT_NO
);
434 * Refresh the screen.
436 * PUBLIC: int ip_refresh __P((SCR *, int));
439 ip_refresh(sp
, repaint
)
450 * If the scroll bar information has changed since we last sent
451 * it, resend it. Currently, we send three values:
453 * top The line number of the first line in the screen.
454 * num The number of lines visible on the screen.
455 * total The number of lines in the file.
458 * This is a gross violation of layering... we're looking at data
459 * structures at which we have absolutely no business whatsoever
462 ipb
.val1
= HMAP
->lno
;
463 ipb
.val2
= TMAP
->lno
- HMAP
->lno
;
464 if (sp
->ep
!= NULL
&& sp
->ep
->db
!= NULL
)
465 (void)db_last(sp
, &total
);
466 ipb
.val3
= total
== 0 ? 1 : total
;
467 if (ipb
.val1
!= ipp
->sb_top
||
468 ipb
.val2
!= ipp
->sb_num
|| ipb
.val3
!= ipp
->sb_total
) {
469 ipb
.code
= SI_SCROLLBAR
;
470 (void)vi_send(ipp
->o_fd
, "123", &ipb
);
471 ipp
->sb_top
= ipb
.val1
;
472 ipp
->sb_num
= ipb
.val2
;
473 ipp
->sb_total
= ipb
.val3
;
476 /* Refresh/repaint the screen. */
477 ipb
.code
= repaint
? SI_REDRAW
: SI_REFRESH
;
478 return (vi_send(ipp
->o_fd
, NULL
, &ipb
));
485 * PUBLIC: int ip_rename __P((SCR *, char *, int));
488 ip_rename(sp
, name
, on
)
494 IP_PRIVATE
*ipp
= IPP(sp
);
496 ipb
.code
= SI_RENAME
;
498 ipb
.len1
= name
? strlen(name
) : 0;
499 return (vi_send(ipp
->o_fd
, "a", &ipb
));
504 * Reply to a message.
506 * PUBLIC: int ip_reply __P((SCR *, int, char *));
509 ip_reply(sp
, status
, msg
)
515 IP_PRIVATE
*ipp
= IPP(sp
);
519 ipb
.str1
= msg
== NULL
? "" : msg
;
520 ipb
.len1
= strlen(ipb
.str1
);
521 return (vi_send(ipp
->o_fd
, "1a", &ipb
));
528 * PUBLIC: int ip_split __P((SCR *, SCR *));
531 ip_split(origp
, newp
)
541 * PUBLIC: int ip_suspend __P((SCR *, int *));
544 ip_suspend(sp
, allowedp
)
554 * Print out the ip usage messages.
556 * PUBLIC: void ip_usage __P((void));
562 usage: vi [-eFlRrSv] [-c command] [-I ifd.ofd] [-t tag] [-w size] [file ...]\n"
563 (void)fprintf(stderr
, "%s", USAGE
);