Home | History | Annotate | Line # | Download | only in ip
ip_funcs.c revision 1.4.4.2
      1 /*	$NetBSD: ip_funcs.c,v 1.4.4.2 2014/05/22 15:50:35 yamt Exp $	*/
      2 /*-
      3  * Copyright (c) 1996
      4  *	Keith Bostic.  All rights reserved.
      5  *
      6  * See the LICENSE file for redistribution information.
      7  */
      8 
      9 #include "config.h"
     10 
     11 #include <sys/cdefs.h>
     12 #if 0
     13 #ifndef lint
     14 static const char sccsid[] = "Id: ip_funcs.c,v 8.23 2001/06/25 15:19:23 skimo Exp  (Berkeley) Date: 2001/06/25 15:19:23 ";
     15 #endif /* not lint */
     16 #else
     17 __RCSID("$NetBSD: ip_funcs.c,v 1.4.4.2 2014/05/22 15:50:35 yamt Exp $");
     18 #endif
     19 
     20 #include <sys/types.h>
     21 #include <sys/queue.h>
     22 #include <sys/time.h>
     23 
     24 #include <bitstring.h>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <unistd.h>
     28 #include <string.h>
     29 
     30 #include "../common/common.h"
     31 #include "../vi/vi.h"
     32 #include "../ipc/ip.h"
     33 
     34 /*
     35  * ip_addstr --
     36  *	Add len bytes from the string at the cursor, advancing the cursor.
     37  *
     38  * PUBLIC: int ip_waddstr __P((SCR *, const CHAR_T *, size_t));
     39  */
     40 int
     41 ip_waddstr(SCR *sp, const CHAR_T *str, size_t len)
     42 {
     43 	IP_BUF ipb;
     44 	IP_PRIVATE *ipp;
     45 	int rval;
     46 
     47 	ipp = IPP(sp);
     48 
     49 	memset(&ipb, 0, sizeof(ipb));
     50 	ipb.code = SI_WADDSTR;
     51 	ipb.len1 = len * sizeof(CHAR_T);
     52 	ipb.str1 = __UNCONST(str);
     53 	rval = vi_send(ipp->o_fd, "a", &ipb);
     54 	/* XXXX */
     55 	ipp->col += len;
     56 
     57 	return (rval);
     58 }
     59 
     60 /*
     61  * ip_addstr --
     62  *	Add len bytes from the string at the cursor, advancing the cursor.
     63  *
     64  * PUBLIC: int ip_addstr __P((SCR *, const char *, size_t));
     65  */
     66 int
     67 ip_addstr(SCR *sp, const char *str, size_t len)
     68 {
     69 	IP_BUF ipb;
     70 	IP_PRIVATE *ipp;
     71 	int iv, rval;
     72 
     73 	ipp = IPP(sp);
     74 
     75 	/*
     76 	 * If ex isn't in control, it's the last line of the screen and
     77 	 * it's a split screen, use inverse video.
     78 	 */
     79 	memset(&ipb, 0, sizeof(ipb));
     80 	iv = 0;
     81 	if (!F_ISSET(sp, SC_SCR_EXWROTE) &&
     82 	    ipp->row == LASTLINE(sp) && IS_SPLIT(sp)) {
     83 		iv = 1;
     84 		ip_attr(sp, SA_INVERSE, 1);
     85 	}
     86 	ipb.code = SI_ADDSTR;
     87 	ipb.len1 = len;
     88 	ipb.str1 = str;
     89 	rval = vi_send(ipp->o_fd, "a", &ipb);
     90 	/* XXXX */
     91 	ipp->col += len;
     92 
     93 	if (iv)
     94 		ip_attr(sp, SA_INVERSE, 0);
     95 	return (rval);
     96 }
     97 
     98 /*
     99  * ip_attr --
    100  *	Toggle a screen attribute on/off.
    101  *
    102  * PUBLIC: int ip_attr __P((SCR *, scr_attr_t, int));
    103  */
    104 int
    105 ip_attr(SCR *sp, scr_attr_t attribute, int on)
    106 {
    107 	IP_BUF ipb;
    108 	IP_PRIVATE *ipp = IPP(sp);
    109 
    110 	memset(&ipb, 0, sizeof(ipb));
    111 	if (attribute == SA_ALTERNATE) {
    112 		if (on) F_SET(ipp, IP_ON_ALTERNATE);
    113 		else F_CLR(ipp, IP_ON_ALTERNATE);
    114 	}
    115 
    116 	ipb.code = SI_ATTRIBUTE;
    117 	ipb.val1 = attribute;
    118 	ipb.val2 = on;
    119 
    120 	return (vi_send(ipp->o_fd, "12", &ipb));
    121 }
    122 
    123 /*
    124  * ip_baud --
    125  *	Return the baud rate.
    126  *
    127  * PUBLIC: int ip_baud __P((SCR *, u_long *));
    128  */
    129 int
    130 ip_baud(SCR *sp, u_long *ratep)
    131 {
    132 	*ratep = 9600;		/* XXX: Translation: fast. */
    133 	return (0);
    134 }
    135 
    136 /*
    137  * ip_bell --
    138  *	Ring the bell/flash the screen.
    139  *
    140  * PUBLIC: int ip_bell __P((SCR *));
    141  */
    142 int
    143 ip_bell(SCR *sp)
    144 {
    145 	IP_BUF ipb;
    146 	IP_PRIVATE *ipp = IPP(sp);
    147 
    148 	memset(&ipb, 0, sizeof(ipb));
    149 	ipb.code = SI_BELL;
    150 
    151 	return (vi_send(ipp->o_fd, NULL, &ipb));
    152 }
    153 
    154 /*
    155  * ip_busy --
    156  *	Display a busy message.
    157  *
    158  * PUBLIC: void ip_busy __P((SCR *, const char *, busy_t));
    159  */
    160 void
    161 ip_busy(SCR *sp, const char *str, busy_t bval)
    162 {
    163 	IP_BUF ipb;
    164 	IP_PRIVATE *ipp = IPP(sp);
    165 
    166 	memset(&ipb, 0, sizeof(ipb));
    167 	switch (bval) {
    168 	case BUSY_ON:
    169 		ipb.code = SI_BUSY_ON;
    170 		ipb.str1 = str;
    171 		ipb.len1 = strlen(str);
    172 		(void)vi_send(ipp->o_fd, "a", &ipb);
    173 		break;
    174 	case BUSY_OFF:
    175 		ipb.code = SI_BUSY_OFF;
    176 		(void)vi_send(ipp->o_fd, NULL, &ipb);
    177 		break;
    178 	case BUSY_UPDATE:
    179 		break;
    180 	}
    181 	return;
    182 }
    183 
    184 /*
    185  * ip_child --
    186  *	Prepare child.
    187  *
    188  * PUBLIC: int ip_child __P((SCR *));
    189  */
    190 int
    191 ip_child(SCR *sp)
    192 {
    193 	IP_PRIVATE *ipp = IPP(sp);
    194 
    195 	if (ipp->t_fd != -1) {
    196 	    dup2(ipp->t_fd, 0);
    197 	    dup2(ipp->t_fd, 1);
    198 	    dup2(ipp->t_fd, 2);
    199 	    close(ipp->t_fd);
    200 	}
    201 	return 0;
    202 }
    203 
    204 /*
    205  * ip_clrtoeol --
    206  *	Clear from the current cursor to the end of the line.
    207  *
    208  * PUBLIC: int ip_clrtoeol __P((SCR *));
    209  */
    210 int
    211 ip_clrtoeol(SCR *sp)
    212 {
    213 	IP_BUF ipb;
    214  	IP_PRIVATE *ipp = IPP(sp);
    215 
    216  	/* Temporary hack until we can pass screen pointers
    217  	 * or name screens
    218  	 */
    219 	memset(&ipb, 0, sizeof(ipb));
    220  	if (IS_VSPLIT(sp)) {
    221  		size_t x, y, spcnt;
    222  		int error;
    223 
    224  		y = ipp->row;
    225  		x = ipp->col;
    226  		error = 0;
    227  		for (spcnt = sp->cols - x;
    228  		     spcnt > 0 && ! error; --spcnt)
    229  			error = ip_addstr(sp, " ", 1);
    230  		if (sp->coff == 0)
    231  			error |= ip_addstr(sp, "|", 1);
    232  		error |= ip_move(sp, y, x);
    233  		return error;
    234  	}
    235 
    236 	ipb.code = SI_CLRTOEOL;
    237 
    238 	return (vi_send(ipp->o_fd, NULL, &ipb));
    239 }
    240 
    241 /*
    242  * ip_cursor --
    243  *	Return the current cursor position.
    244  *
    245  * PUBLIC: int ip_cursor __P((SCR *, size_t *, size_t *));
    246  */
    247 int
    248 ip_cursor(SCR *sp, size_t *yp, size_t *xp)
    249 {
    250 	IP_PRIVATE *ipp;
    251 
    252 	ipp = IPP(sp);
    253 	*yp = ipp->row;
    254 	*xp = ipp->col;
    255 	return (0);
    256 }
    257 
    258 /*
    259  * ip_deleteln --
    260  *	Delete the current line, scrolling all lines below it.
    261  *
    262  * PUBLIC: int ip_deleteln __P((SCR *));
    263  */
    264 int
    265 ip_deleteln(SCR *sp)
    266 {
    267 	IP_BUF ipb;
    268 	IP_PRIVATE *ipp = IPP(sp);
    269 
    270 	/*
    271 	 * This clause is required because the curses screen uses reverse
    272 	 * video to delimit split screens.  If the screen does not do this,
    273 	 * this code won't be necessary.
    274 	 *
    275 	 * If the bottom line was in reverse video, rewrite it in normal
    276 	 * video before it's scrolled.
    277 	 */
    278 	memset(&ipb, 0, sizeof(ipb));
    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);
    284 	}
    285 
    286 	/*
    287 	 * The bottom line is expected to be blank after this operation,
    288 	 * and other screens must support that semantic.
    289 	 */
    290 	ipb.code = SI_DELETELN;
    291 	return (vi_send(ipp->o_fd, NULL, &ipb));
    292 }
    293 
    294 /*
    295  * ip_discard --
    296  *	Discard a screen.
    297  *
    298  * PUBLIC: int ip_discard __P((SCR *, SCR **));
    299  */
    300 int
    301 ip_discard(SCR *discardp, SCR **acquirep)
    302 {
    303 	return (0);
    304 }
    305 
    306 /*
    307  * ip_ex_adjust --
    308  *	Adjust the screen for ex.
    309  *
    310  * PUBLIC: int ip_ex_adjust __P((SCR *, exadj_t));
    311  */
    312 int
    313 ip_ex_adjust(SCR *sp, exadj_t action)
    314 {
    315 	abort();
    316 	/* NOTREACHED */
    317 }
    318 
    319 /*
    320  * ip_insertln --
    321  *	Push down the current line, discarding the bottom line.
    322  *
    323  * PUBLIC: int ip_insertln __P((SCR *));
    324  */
    325 int
    326 ip_insertln(SCR *sp)
    327 {
    328 	IP_BUF ipb;
    329 	IP_PRIVATE *ipp = IPP(sp);
    330 
    331 	memset(&ipb, 0, sizeof(ipb));
    332 	ipb.code = SI_INSERTLN;
    333 
    334 	return (vi_send(ipp->o_fd, NULL, &ipb));
    335 }
    336 
    337 /*
    338  * ip_keyval --
    339  *	Return the value for a special key.
    340  *
    341  * PUBLIC: int ip_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
    342  */
    343 int
    344 ip_keyval(SCR *sp, scr_keyval_t val, CHAR_T *chp, int *dnep)
    345 {
    346 	/*
    347 	 * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
    348 	 * VWERASE is a 4BSD extension.
    349 	 */
    350 	switch (val) {
    351 	case KEY_VEOF:
    352 		*dnep = '\004';		/* ^D */
    353 		break;
    354 	case KEY_VERASE:
    355 		*dnep = '\b';		/* ^H */
    356 		break;
    357 	case KEY_VKILL:
    358 		*dnep = '\025';		/* ^U */
    359 		break;
    360 #ifdef VWERASE
    361 	case KEY_VWERASE:
    362 		*dnep = '\027';		/* ^W */
    363 		break;
    364 #endif
    365 	default:
    366 		*dnep = 1;
    367 		break;
    368 	}
    369 	return (0);
    370 }
    371 
    372 /*
    373  * ip_move --
    374  *	Move the cursor.
    375  *
    376  * PUBLIC: int ip_move __P((SCR *, size_t, size_t));
    377  */
    378 int
    379 ip_move(SCR *sp, size_t lno, size_t cno)
    380 {
    381 	IP_PRIVATE *ipp;
    382 	IP_BUF ipb;
    383 
    384 	ipp = IPP(sp);
    385 	ipp->row = lno;
    386 	ipp->col = cno;
    387 
    388 	memset(&ipb, 0, sizeof(ipb));
    389 	ipb.code = SI_MOVE;
    390 	ipb.val1 = RLNO(sp, lno);
    391 	ipb.val2 = RCNO(sp, cno);
    392 	return (vi_send(ipp->o_fd, "12", &ipb));
    393 }
    394 
    395 /*
    396  * PUBLIC: void ip_msg __P((SCR *, mtype_t, char *, size_t));
    397  */
    398 void
    399 ip_msg(SCR *sp, mtype_t mtype, char *line, size_t len)
    400 {
    401 	IP_PRIVATE *ipp = IPP(sp);
    402 
    403 	if (F_ISSET(ipp, IP_ON_ALTERNATE))
    404 		vs_msg(sp, mtype, line, len);
    405 	else {
    406 		write(ipp->t_fd, line, len);
    407 		F_CLR(sp, SC_EX_WAIT_NO);
    408 	}
    409 }
    410 
    411 /*
    412  * ip_refresh --
    413  *	Refresh the screen.
    414  *
    415  * PUBLIC: int ip_refresh __P((SCR *, int));
    416  */
    417 int
    418 ip_refresh(SCR *sp, int repaint)
    419 {
    420 	IP_BUF ipb;
    421 	IP_PRIVATE *ipp;
    422 	db_recno_t total;
    423 
    424 	ipp = IPP(sp);
    425 
    426 	/*
    427 	 * If the scroll bar information has changed since we last sent
    428 	 * it, resend it.  Currently, we send three values:
    429 	 *
    430 	 * top		The line number of the first line in the screen.
    431 	 * num		The number of lines visible on the screen.
    432 	 * total	The number of lines in the file.
    433 	 *
    434 	 * XXX
    435 	 * This is a gross violation of layering... we're looking at data
    436 	 * structures at which we have absolutely no business whatsoever
    437 	 * looking...
    438 	 */
    439 	memset(&ipb, 0, sizeof(ipb));
    440 	ipb.val1 = HMAP->lno;
    441 	ipb.val2 = TMAP->lno - HMAP->lno;
    442 	if (sp->ep != NULL && sp->ep->db != NULL)
    443 		(void)db_last(sp, &total);
    444 	ipb.val3 = total == 0 ? 1 : total;
    445 	if (ipb.val1 != ipp->sb_top ||
    446 	    ipb.val2 != ipp->sb_num || ipb.val3 != ipp->sb_total) {
    447 		ipb.code = SI_SCROLLBAR;
    448 		(void)vi_send(ipp->o_fd, "123", &ipb);
    449 		ipp->sb_top = ipb.val1;
    450 		ipp->sb_num = ipb.val2;
    451 		ipp->sb_total = ipb.val3;
    452 	}
    453 
    454 	/* Refresh/repaint the screen. */
    455 	ipb.code = repaint ? SI_REDRAW : SI_REFRESH;
    456 	return (vi_send(ipp->o_fd, NULL, &ipb));
    457 }
    458 
    459 /*
    460  * ip_rename --
    461  *	Rename the file.
    462  *
    463  * PUBLIC: int ip_rename __P((SCR *, char *, int));
    464  */
    465 int
    466 ip_rename(SCR *sp, char *name, int on)
    467 {
    468 	IP_BUF ipb;
    469 	IP_PRIVATE *ipp = IPP(sp);
    470 
    471 	memset(&ipb, 0, sizeof(ipb));
    472 	ipb.code = SI_RENAME;
    473 	ipb.str1 = name;
    474 	ipb.len1 = name ? strlen(name) : 0;
    475 	return (vi_send(ipp->o_fd, "a", &ipb));
    476 }
    477 
    478 /*
    479  * ip_reply --
    480  *	Reply to a message.
    481  *
    482  * PUBLIC: int ip_reply __P((SCR *, int, char *));
    483  */
    484 int
    485 ip_reply(SCR *sp, int status, char *msg)
    486 {
    487 	IP_BUF ipb;
    488 	IP_PRIVATE *ipp = IPP(sp);
    489 
    490 	memset(&ipb, 0, sizeof(ipb));
    491 	ipb.code = SI_REPLY;
    492 	ipb.val1 = status;
    493 	ipb.str1 = msg == NULL ? "" : msg;
    494 	ipb.len1 = strlen(ipb.str1);
    495 	return (vi_send(ipp->o_fd, "1a", &ipb));
    496 }
    497 
    498 /*
    499  * ip_split --
    500  *	Split a screen.
    501  *
    502  * PUBLIC: int ip_split __P((SCR *, SCR *));
    503  */
    504 int
    505 ip_split(SCR *origp, SCR *newp)
    506 {
    507 	return (0);
    508 }
    509 
    510 /*
    511  * ip_suspend --
    512  *	Suspend a screen.
    513  *
    514  * PUBLIC: int ip_suspend __P((SCR *, int *));
    515  */
    516 int
    517 ip_suspend(SCR *sp, int *allowedp)
    518 {
    519 	*allowedp = 0;
    520 	return (0);
    521 }
    522 
    523 /*
    524  * ip_usage --
    525  *      Print out the ip usage messages.
    526  *
    527  * PUBLIC: void ip_usage __P((void));
    528  */
    529 void
    530 ip_usage(void)
    531 {
    532 #define USAGE "\
    533 usage: vi [-eFlRrSv] [-c command] [-I ifd.ofd] [-t tag] [-w size] [file ...]\n"
    534         (void)fprintf(stderr, "%s", USAGE);
    535 #undef  USAGE
    536 }
    537