Home | History | Annotate | Line # | Download | only in ip
ip_funcs.c revision 1.5
      1 /*	$NetBSD: ip_funcs.c,v 1.5 2018/08/07 08:05:47 rin 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.5 2018/08/07 08:05:47 rin 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 #ifdef IMCTRL
    320 /*
    321  * ip_imctrl --
    322  *	XXX not implemented yet.
    323  *
    324  * PUBLIC: #ifdef IMCTRL
    325  * PUBLIC: void ip_imctrl __P((SCR *, imctrl_t));
    326  * PUBLIC: #endif
    327  */
    328 void
    329 ip_imctrl(SCR *sp, imctrl_t action)
    330 {
    331 
    332 	return;
    333 }
    334 #endif
    335 
    336 /*
    337  * ip_insertln --
    338  *	Push down the current line, discarding the bottom line.
    339  *
    340  * PUBLIC: int ip_insertln __P((SCR *));
    341  */
    342 int
    343 ip_insertln(SCR *sp)
    344 {
    345 	IP_BUF ipb;
    346 	IP_PRIVATE *ipp = IPP(sp);
    347 
    348 	memset(&ipb, 0, sizeof(ipb));
    349 	ipb.code = SI_INSERTLN;
    350 
    351 	return (vi_send(ipp->o_fd, NULL, &ipb));
    352 }
    353 
    354 /*
    355  * ip_keyval --
    356  *	Return the value for a special key.
    357  *
    358  * PUBLIC: int ip_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
    359  */
    360 int
    361 ip_keyval(SCR *sp, scr_keyval_t val, CHAR_T *chp, int *dnep)
    362 {
    363 	/*
    364 	 * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
    365 	 * VWERASE is a 4BSD extension.
    366 	 */
    367 	switch (val) {
    368 	case KEY_VEOF:
    369 		*dnep = '\004';		/* ^D */
    370 		break;
    371 	case KEY_VERASE:
    372 		*dnep = '\b';		/* ^H */
    373 		break;
    374 	case KEY_VKILL:
    375 		*dnep = '\025';		/* ^U */
    376 		break;
    377 #ifdef VWERASE
    378 	case KEY_VWERASE:
    379 		*dnep = '\027';		/* ^W */
    380 		break;
    381 #endif
    382 	default:
    383 		*dnep = 1;
    384 		break;
    385 	}
    386 	return (0);
    387 }
    388 
    389 /*
    390  * ip_move --
    391  *	Move the cursor.
    392  *
    393  * PUBLIC: int ip_move __P((SCR *, size_t, size_t));
    394  */
    395 int
    396 ip_move(SCR *sp, size_t lno, size_t cno)
    397 {
    398 	IP_PRIVATE *ipp;
    399 	IP_BUF ipb;
    400 
    401 	ipp = IPP(sp);
    402 	ipp->row = lno;
    403 	ipp->col = cno;
    404 
    405 	memset(&ipb, 0, sizeof(ipb));
    406 	ipb.code = SI_MOVE;
    407 	ipb.val1 = RLNO(sp, lno);
    408 	ipb.val2 = RCNO(sp, cno);
    409 	return (vi_send(ipp->o_fd, "12", &ipb));
    410 }
    411 
    412 /*
    413  * PUBLIC: void ip_msg __P((SCR *, mtype_t, char *, size_t));
    414  */
    415 void
    416 ip_msg(SCR *sp, mtype_t mtype, char *line, size_t len)
    417 {
    418 	IP_PRIVATE *ipp = IPP(sp);
    419 
    420 	if (F_ISSET(ipp, IP_ON_ALTERNATE))
    421 		vs_msg(sp, mtype, line, len);
    422 	else {
    423 		write(ipp->t_fd, line, len);
    424 		F_CLR(sp, SC_EX_WAIT_NO);
    425 	}
    426 }
    427 
    428 /*
    429  * ip_refresh --
    430  *	Refresh the screen.
    431  *
    432  * PUBLIC: int ip_refresh __P((SCR *, int));
    433  */
    434 int
    435 ip_refresh(SCR *sp, int repaint)
    436 {
    437 	IP_BUF ipb;
    438 	IP_PRIVATE *ipp;
    439 	db_recno_t total;
    440 
    441 	ipp = IPP(sp);
    442 
    443 	/*
    444 	 * If the scroll bar information has changed since we last sent
    445 	 * it, resend it.  Currently, we send three values:
    446 	 *
    447 	 * top		The line number of the first line in the screen.
    448 	 * num		The number of lines visible on the screen.
    449 	 * total	The number of lines in the file.
    450 	 *
    451 	 * XXX
    452 	 * This is a gross violation of layering... we're looking at data
    453 	 * structures at which we have absolutely no business whatsoever
    454 	 * looking...
    455 	 */
    456 	memset(&ipb, 0, sizeof(ipb));
    457 	ipb.val1 = HMAP->lno;
    458 	ipb.val2 = TMAP->lno - HMAP->lno;
    459 	if (sp->ep != NULL && sp->ep->db != NULL)
    460 		(void)db_last(sp, &total);
    461 	ipb.val3 = total == 0 ? 1 : total;
    462 	if (ipb.val1 != ipp->sb_top ||
    463 	    ipb.val2 != ipp->sb_num || ipb.val3 != ipp->sb_total) {
    464 		ipb.code = SI_SCROLLBAR;
    465 		(void)vi_send(ipp->o_fd, "123", &ipb);
    466 		ipp->sb_top = ipb.val1;
    467 		ipp->sb_num = ipb.val2;
    468 		ipp->sb_total = ipb.val3;
    469 	}
    470 
    471 	/* Refresh/repaint the screen. */
    472 	ipb.code = repaint ? SI_REDRAW : SI_REFRESH;
    473 	return (vi_send(ipp->o_fd, NULL, &ipb));
    474 }
    475 
    476 /*
    477  * ip_rename --
    478  *	Rename the file.
    479  *
    480  * PUBLIC: int ip_rename __P((SCR *, char *, int));
    481  */
    482 int
    483 ip_rename(SCR *sp, char *name, int on)
    484 {
    485 	IP_BUF ipb;
    486 	IP_PRIVATE *ipp = IPP(sp);
    487 
    488 	memset(&ipb, 0, sizeof(ipb));
    489 	ipb.code = SI_RENAME;
    490 	ipb.str1 = name;
    491 	ipb.len1 = name ? strlen(name) : 0;
    492 	return (vi_send(ipp->o_fd, "a", &ipb));
    493 }
    494 
    495 /*
    496  * ip_reply --
    497  *	Reply to a message.
    498  *
    499  * PUBLIC: int ip_reply __P((SCR *, int, char *));
    500  */
    501 int
    502 ip_reply(SCR *sp, int status, char *msg)
    503 {
    504 	IP_BUF ipb;
    505 	IP_PRIVATE *ipp = IPP(sp);
    506 
    507 	memset(&ipb, 0, sizeof(ipb));
    508 	ipb.code = SI_REPLY;
    509 	ipb.val1 = status;
    510 	ipb.str1 = msg == NULL ? "" : msg;
    511 	ipb.len1 = strlen(ipb.str1);
    512 	return (vi_send(ipp->o_fd, "1a", &ipb));
    513 }
    514 
    515 /*
    516  * ip_split --
    517  *	Split a screen.
    518  *
    519  * PUBLIC: int ip_split __P((SCR *, SCR *));
    520  */
    521 int
    522 ip_split(SCR *origp, SCR *newp)
    523 {
    524 	return (0);
    525 }
    526 
    527 /*
    528  * ip_suspend --
    529  *	Suspend a screen.
    530  *
    531  * PUBLIC: int ip_suspend __P((SCR *, int *));
    532  */
    533 int
    534 ip_suspend(SCR *sp, int *allowedp)
    535 {
    536 	*allowedp = 0;
    537 	return (0);
    538 }
    539 
    540 /*
    541  * ip_usage --
    542  *      Print out the ip usage messages.
    543  *
    544  * PUBLIC: void ip_usage __P((void));
    545  */
    546 void
    547 ip_usage(void)
    548 {
    549 #define USAGE "\
    550 usage: vi [-eFlRrSv] [-c command] [-I ifd.ofd] [-t tag] [-w size] [file ...]\n"
    551         (void)fprintf(stderr, "%s", USAGE);
    552 #undef  USAGE
    553 }
    554