From 757e4a7ffd8682c3b45a317b45afb643d503b602 Mon Sep 17 00:00:00 2001 From: bostic Date: Sat, 2 Aug 1997 16:48:14 +0000 Subject: [PATCH] add the scr_reply function --- cl/cl_main.c | 3 +- common/gs.h | 4 +- ip/ip_funcs.c | 27 ++++++++++-- ip/ip_main.c | 3 +- ipc/ip.h | 34 +++++--------- ipc/ip_run.c | 3 +- ipc/ip_send.c | 4 +- ipc/ip_trans.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++---- motif_l/TODO | 15 +++++++ motif_l/m_func.c | 3 +- motif_l/m_options.c | 18 +++++++- motif_l/m_vi.c | 59 +++---------------------- motif_l/vi_mextern.h | 4 +- vi/v_event.c | 10 +++-- 14 files changed, 207 insertions(+), 102 deletions(-) diff --git a/cl/cl_main.c b/cl/cl_main.c index 247b85a4..75b82e79 100644 --- a/cl/cl_main.c +++ b/cl/cl_main.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: cl_main.c,v 10.45 1996/12/18 17:06:41 bostic Exp $ (Berkeley) $Date: 1996/12/18 17:06:41 $"; +static const char sccsid[] = "$Id: cl_main.c,v 10.46 1997/08/02 16:48:14 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:48:14 $"; #endif /* not lint */ #include @@ -445,6 +445,7 @@ cl_func_std(gp) gp->scr_clrtoeol = cl_clrtoeol; gp->scr_cursor = cl_cursor; gp->scr_deleteln = cl_deleteln; + gp->scr_reply = NULL; gp->scr_discard = cl_discard; gp->scr_event = cl_event; gp->scr_ex_adjust = cl_ex_adjust; diff --git a/common/gs.h b/common/gs.h index c2c4cd17..30e6c448 100644 --- a/common/gs.h +++ b/common/gs.h @@ -6,7 +6,7 @@ * * See the LICENSE file for redistribution information. * - * $Id: gs.h,v 10.36 1996/11/22 09:03:14 bostic Exp $ (Berkeley) $Date: 1996/11/22 09:03:14 $ + * $Id: gs.h,v 10.37 1997/08/02 16:48:29 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:48:29 $ */ #define TEMPORARY_FILE_STRING "/tmp" /* Default temporary file name. */ @@ -185,6 +185,8 @@ struct _gs { int (*scr_refresh) __P((SCR *, int)); /* Rename the file. */ int (*scr_rename) __P((SCR *, char *, int)); + /* Reply to an event. */ + int (*scr_reply) __P((SCR *, int, char *)); /* Set the screen type. */ int (*scr_screen) __P((SCR *, u_int32_t)); /* Split the screen. */ diff --git a/ip/ip_funcs.c b/ip/ip_funcs.c index 6ec539ad..62d8efbb 100644 --- a/ip/ip_funcs.c +++ b/ip/ip_funcs.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: ip_funcs.c,v 8.12 1996/12/18 10:28:02 bostic Exp $ (Berkeley) $Date: 1996/12/18 10:28:02 $"; +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 $"; #endif /* not lint */ #include @@ -133,9 +133,9 @@ ip_busy(sp, str, bval) switch (bval) { case BUSY_ON: ipb.code = SI_BUSY_ON; - ipb.len1 = strlen(str); ipb.str1 = str; - (void)vi_send("a1", &ipb); + ipb.len1 = strlen(str); + (void)vi_send("a", &ipb); break; case BUSY_OFF: ipb.code = SI_BUSY_OFF; @@ -395,6 +395,27 @@ ip_rename(sp, name, on) } /* + * ip_reply -- + * Reply to a message. + * + * PUBLIC: int ip_reply __P((SCR *, int, char *)); + */ +int +ip_reply(sp, status, msg) + SCR *sp; + int status; + char *msg; +{ + IP_BUF ipb; + + ipb.code = SI_REPLY; + ipb.val1 = status; + ipb.str1 = msg == NULL ? "" : msg; + ipb.len1 = strlen(ipb.str1); + return (vi_send("1a", &ipb)); +} + +/* * ip_split -- * Split a screen. * diff --git a/ip/ip_main.c b/ip/ip_main.c index 8874414f..914b6de8 100644 --- a/ip/ip_main.c +++ b/ip/ip_main.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: ip_main.c,v 8.9 1996/12/18 10:28:03 bostic Exp $ (Berkeley) $Date: 1996/12/18 10:28:03 $"; +static const char sccsid[] = "$Id: ip_main.c,v 8.10 1997/08/02 16:48:59 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:48:59 $"; #endif /* not lint */ #include @@ -162,6 +162,7 @@ ip_func_std(gp) gp->scr_optchange = ip_optchange; gp->scr_refresh = ip_refresh; gp->scr_rename = ip_rename; + gp->scr_reply = ip_reply; gp->scr_screen = ip_screen; gp->scr_split = ip_split; gp->scr_suspend = ip_suspend; diff --git a/ipc/ip.h b/ipc/ip.h index 0adc2cd1..ad0aea4b 100644 --- a/ipc/ip.h +++ b/ipc/ip.h @@ -4,9 +4,10 @@ * * See the LICENSE file for redistribution information. * - * $Id: ip.h,v 8.17 1996/12/18 10:27:47 bostic Exp $ (Berkeley) $Date: 1996/12/18 10:27:47 $ + * $Id: ip.h,v 8.18 1997/08/02 16:49:32 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:49:32 $ */ +extern int vi_ifd; /* Input file descriptor. */ extern int vi_ofd; /* Output file descriptor. */ typedef struct _ip_private { @@ -33,21 +34,8 @@ typedef struct _ip_private { /* The screen line relative to a specific window. */ #define RLNO(sp, lno) (sp)->roff + (lno) -/* - * The IP protocol consists of frames, each containing: - * - * - * - * XXX - * We should have a marking byte, 0xaa to delimit frames. - * - */ -#define IPO_CODE 1 /* An event specification. */ -#define IPO_INT 2 /* 4-byte, network order integer. */ -#define IPO_STR 3 /* IPO_INT: followed by N bytes. */ - -#define IPO_CODE_LEN 1 -#define IPO_INT_LEN 4 +#define IPO_CODE_LEN 1 /* Length of a code value. */ +#define IPO_INT_LEN 4 /* Length of an integer. */ /* A structure that can hold the information for any frame. */ typedef struct _ip_buf { @@ -65,12 +53,13 @@ typedef struct _ip_buf { * Screen/editor IP_CODE's. * * The program structure depends on the event loop being able to return - * IPO_EOF/IPOE_ERR multiple times -- eventually enough things will end + * IPO_EOF/IPO_ERR multiple times -- eventually enough things will end * due to the events that vi will reach the command level for the screen, * at which point the exit flags will be set and vi will exit. * * IP events sent from the screen to vi. */ +#define CODE_OOB 0 /* Illegal code. */ #define VI_C_BOL 1 /* Cursor to start of line. */ #define VI_C_BOTTOM 2 /* Cursor to bottom. */ #define VI_C_DEL 3 /* Cursor delete. */ @@ -133,10 +122,11 @@ typedef struct _ip_buf { #define SI_REDRAW 13 /* Redraw the screen. */ #define SI_REFRESH 14 /* Refresh the screen. */ #define SI_RENAME 15 /* Rename the screen: IPO_STR. */ -#define SI_REWRITE 16 /* Rewrite a line: IPO_INT. */ -#define SI_SCROLLBAR 17 /* Reset the scrollbar: 3 * IPO_INT. */ -#define SI_SELECT 18 /* Select area: IPO_STR. */ -#define SI_SPLIT 19 /* Split the screen. */ -#define SI_EVENT_MAX 19 +#define SI_REPLY 16 /* Reply: IPO_INT (0/1), IPO_STR. */ +#define SI_REWRITE 17 /* Rewrite a line: IPO_INT. */ +#define SI_SCROLLBAR 18 /* Reset the scrollbar: 3 * IPO_INT. */ +#define SI_SELECT 19 /* Select area: IPO_STR. */ +#define SI_SPLIT 20 /* Split the screen. */ +#define SI_EVENT_MAX 20 #include "extern.h" diff --git a/ipc/ip_run.c b/ipc/ip_run.c index c0f8439a..c044ae29 100644 --- a/ipc/ip_run.c +++ b/ipc/ip_run.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: ip_run.c,v 8.11 1996/12/18 10:27:33 bostic Exp $ (Berkeley) $Date: 1996/12/18 10:27:33 $"; +static const char sccsid[] = "$Id: ip_run.c,v 8.12 1997/08/02 16:49:33 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:49:33 $"; #endif /* not lint */ #include @@ -35,6 +35,7 @@ static void fatal __P((void)); static void attach __P((void)); #endif +int vi_ifd = -1; /* Global: input fd. */ int vi_ofd = -1; /* Global: output fd. */ char *vi_progname = "vi"; /* Global: program name. */ diff --git a/ipc/ip_send.c b/ipc/ip_send.c index e8149f83..2f92e628 100644 --- a/ipc/ip_send.c +++ b/ipc/ip_send.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: ip_send.c,v 8.7 1996/12/18 10:27:39 bostic Exp $ (Berkeley) $Date: 1996/12/18 10:27:39 $"; +static const char sccsid[] = "$Id: ip_send.c,v 8.8 1997/08/02 16:49:33 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:49:33 $"; #endif /* not lint */ #include @@ -23,8 +23,6 @@ static const char sccsid[] = "$Id: ip_send.c,v 8.7 1996/12/18 10:27:39 bostic Ex #include "../common/common.h" #include "ip.h" -extern int vi_ofd; /* Output file descriptor. */ - /* * vi_send -- * Construct and send an IP buffer. diff --git a/ipc/ip_trans.c b/ipc/ip_trans.c index f1cd26e1..7354e8a9 100644 --- a/ipc/ip_trans.c +++ b/ipc/ip_trans.c @@ -8,11 +8,14 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: ip_trans.c,v 8.14 1996/12/18 10:27:44 bostic Exp $ (Berkeley) $Date: 1996/12/18 10:27:44 $"; +static const char sccsid[] = "$Id: ip_trans.c,v 8.15 1997/08/02 16:49:33 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:49:33 $"; #endif /* not lint */ #include #include +#ifdef HAVE_SYS_SELECT_H +#include +#endif #include #include @@ -27,27 +30,106 @@ static const char sccsid[] = "$Id: ip_trans.c,v 8.14 1996/12/18 10:27:44 bostic #include "../common/common.h" #include "ip.h" +static char ibuf[2048]; /* Input buffer. */ +static size_t ibuf_len; /* Length of current input. */ + +/* + * vi_input -- + * Read from the vi message queue. + * + * PUBLIC: int vi_input __P((int)); + */ +int +vi_input(fd) + int fd; +{ + ssize_t nr; + + /* Read waiting vi messages and translate to X calls. */ + switch (nr = read(fd, ibuf + ibuf_len, sizeof(ibuf) - ibuf_len)) { + case 0: + return (0); + case -1: + return (-1); + default: + break; + } + ibuf_len += nr; + + /* Parse to data end or partial message. */ + (void)vi_translate(ibuf, &ibuf_len, NULL); + + return (ibuf_len > 0); +} + +/* + * vi_wsend -- + * Construct and send an IP buffer, and wait for an answer. + * + * PUBLIC: int vi_wsend __P((char *, IP_BUF *)); + */ +int +vi_wsend(fmt, ipbp) + char *fmt; + IP_BUF *ipbp; +{ + fd_set rdfd; + ssize_t nr; + + if (vi_send(fmt, ipbp)) + return (1); + + FD_ZERO(&rdfd); + ipbp->code = CODE_OOB; + + for (;;) { + FD_SET(vi_ifd, &rdfd); + if (select(vi_ifd + 1, &rdfd, NULL, NULL, NULL) != 0) + return (-1); + + /* Read waiting vi messages and translate to X calls. */ + switch (nr = + read(vi_ifd, ibuf + ibuf_len, sizeof(ibuf) - ibuf_len)) { + case 0: + return (0); + case -1: + return (-1); + default: + break; + } + ibuf_len += nr; + + /* Parse to data end or partial message. */ + (void)vi_translate(ibuf, &ibuf_len, ipbp); + + if (ipbp->code != CODE_OOB) + break; + } + return (0); +} + /* * vi_translate -- * Translate vi messages into function calls. * - * PUBLIC: int vi_translate __P((char *, size_t *)); + * PUBLIC: int vi_translate __P((char *, size_t *, IP_BUF *)); */ int -vi_translate(bp, lenp) +vi_translate(bp, lenp, ipbp) char *bp; size_t *lenp; + IP_BUF *ipbp; { extern int (*__vi_iplist[SI_EVENT_MAX - 1]) __P((IP_BUF *)); IP_BUF ipb; size_t len, needlen; u_int32_t *vp; - int foff; char *fmt, *p, *s_bp, **vsp; for (s_bp = bp, len = *lenp; len > 0;) { - switch (foff = bp[0]) { + switch (ipb.code = bp[0]) { case SI_ADDSTR: + case SI_BUSY_ON: case SI_RENAME: case SI_SELECT: fmt = "a"; @@ -56,12 +138,12 @@ vi_translate(bp, lenp) case SI_MOVE: fmt = "12"; break; - case SI_BUSY_ON: - fmt = "a1"; - break; case SI_EDITOPT: fmt = "ab1"; break; + case SI_REPLY: + fmt = "1a"; + break; case SI_REWRITE: fmt = "1"; break; @@ -114,8 +196,30 @@ string: needlen += IPO_INT_LEN; bp += needlen; len -= needlen; + /* + * XXX + * Protocol error!?!? + */ + if (ipb.code > SI_EVENT_MAX) { + len = 0; + break; + } + + /* + * If we're waiting for a reply and we got it, return it, and + * leave any unprocessed data in the buffer. If we got a reply + * and we're not waiting for one, discard it -- callers wait + * for responses. + */ + if (ipb.code == SI_REPLY) { + if (ipbp == NULL) + continue; + *ipbp = ipb; + break; + } + /* Call the underlying routine. */ - if (foff <= SI_EVENT_MAX && __vi_iplist[foff - 1](&ipb)) + if (__vi_iplist[ipb.code - 1](&ipb)) break; } partial: diff --git a/motif_l/TODO b/motif_l/TODO index 2eb79b02..0dcd60a5 100644 --- a/motif_l/TODO +++ b/motif_l/TODO @@ -3,9 +3,24 @@ Top priority would be the mouse. We need to get cut&paste working. the correct mouse events for that, but I haven't tested it.) =-=-=-= +Find a tool to convert the reference doc to html, and just point a +browser at it for the help screen. Have "novice", "fast lookup" +and an "everything" version. + +=-=-=-= Disassociate scrollbar actions from the cursor, i.e. when you scroll the screen moves but the cursor doesn't. +>> However, it seems to me that the cursor should disappear from +>> the screen as soon as it's no longer positioned on a line that's +>> on the screen. Does that make sense? And, if so, how do we +>> make that happen? +> +> I'd add a message: +> IPO_DISPLAY_CARET( boolean ) +> since the caret is also used for the current drawing position, we +> really can't move it 'off the screen'. + =-=-=-= >> BTW, this may be a bug, I can't seem to erase characters in the >> colon command line. diff --git a/motif_l/m_func.c b/motif_l/m_func.c index 5628001a..446b17e2 100644 --- a/motif_l/m_func.c +++ b/motif_l/m_func.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: m_func.c,v 8.22 1996/12/18 14:55:54 bostic Exp $ (Berkeley) $Date: 1996/12/18 14:55:54 $"; +static const char sccsid[] = "$Id: m_func.c,v 8.23 1997/08/02 16:50:10 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:50:10 $"; #endif /* not lint */ #include @@ -388,6 +388,7 @@ int (*__vi_iplist[SI_EVENT_MAX]) __P((IP_BUF *)) = { vi_redraw, vi_refresh, vi_rename, + NULL, vi_rewrite, vi_scrollbar, vi_select, diff --git a/motif_l/m_options.c b/motif_l/m_options.c index 807be571..470f5be4 100644 --- a/motif_l/m_options.c +++ b/motif_l/m_options.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: m_options.c,v 8.17 1996/12/20 10:35:46 bostic Exp $ (Berkeley) $Date: 1996/12/20 10:35:46 $"; +static const char sccsid[] = "$Id: m_options.c,v 8.18 1997/08/02 16:50:10 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:50:10 $"; #endif /* not lint */ #include @@ -311,6 +311,19 @@ set_opt(w, closure, call_data) ipb.val1 = set; ipb.len2 = 0; + vi_wsend("ab1", &ipb); + if (ipb.val1) { + opt->value = (void *)!set; + /* + * RAZ: + * How do we turn off the button? We don't want to + * go recursive where we set it and it calls set_opt + * to tell the core. Is that possible? + */ + XtVaSetValues(w, XmNset, &set, 0); + break; + } + if (strcmp(opt->name, "ruler") == 0) if (set) __vi_show_text_ruler_dialog( @@ -322,16 +335,17 @@ set_opt(w, closure, call_data) str = XmTextFieldGetString(w); ipb.val1 = atoi(str); ipb.len2 = 0; + vi_send("ab1", &ipb); break; case optFile: case optString: ipb.str2 = XmTextFieldGetString(w); ipb.len2 = strlen(ipb.str2); + vi_send("ab1", &ipb); break; case optTerminator: abort(); } - vi_send("ab1", &ipb); } diff --git a/motif_l/m_vi.c b/motif_l/m_vi.c index c5714ff7..df2587c2 100644 --- a/motif_l/m_vi.c +++ b/motif_l/m_vi.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: m_vi.c,v 8.34 1997/04/13 10:28:26 bostic Exp $ (Berkeley) $Date: 1997/04/13 10:28:26 $"; +static const char sccsid[] = "$Id: m_vi.c,v 8.35 1997/08/02 16:50:11 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:50:11 $"; #endif /* not lint */ #include @@ -65,9 +65,6 @@ static int multi_click_length; void (*__vi_exitp)(); /* Exit function. */ -static char bp[ BufferSize ]; /* input buffer from pipe */ -static size_t len, blen = sizeof(bp); - /* hack for drag scrolling... * I'm not sure why, but the current protocol gets out of sync when @@ -237,33 +234,6 @@ static XutResource resource[] = { }; - -#if defined(__STDC__) -static Boolean process_pipe_input( XtPointer pread ) -#else -static Boolean process_pipe_input( pread ) - XtPointer pread; -#endif -{ - /* might have read more since the last call */ - len += (pread) ? *((int *)pread) : 0; - - /* Parse to data end or partial message. */ - (void)vi_translate(bp, &len); - - if (len > 0) { -#ifdef TRACE - vtrace("vi_input_func: abort with %d in the buffer\n", len); -#endif - /* call me again later */ - return False; - } - - /* do NOT call me again later */ - return True; -} - - /* * vi_input_func -- * We've received input on the pipe from vi. @@ -276,30 +246,13 @@ vi_input_func(client_data, source, id) int *source; XtInputId *id; { - int nr; + /* Parse and dispatch on commands in the queue. */ + (void)vi_input(*source); - /* Read waiting vi messags and translate to X calls. */ - switch (nr = read( *source, bp + len, blen - len)) { - case 0: -#ifdef TRACE - vtrace("vi_input_func: empty input from vi\n"); +#ifdef notdef + /* Check the pipe for unused events when not busy. */ + XtAppAddWorkProc(ctx, process_pipe_input, NULL); #endif - return; - case -1: - perror("ip_cl: read"); - exit (1); - default: -#ifdef TRACE - vtrace("input from vi, %d bytes read\n", nr); -#endif - break; - } - - /* parse and dispatch on commands in the queue */ - if ( ! process_pipe_input( &nr ) ) { - /* check the pipe for unused events when not busy */ - XtAppAddWorkProc( ctx, process_pipe_input, NULL ); - } } diff --git a/motif_l/vi_mextern.h b/motif_l/vi_mextern.h index 5062c09d..d31d568b 100644 --- a/motif_l/vi_mextern.h +++ b/motif_l/vi_mextern.h @@ -6,7 +6,7 @@ * * See the LICENSE file for redistribution information. * - * "$Id: vi_mextern.h,v 8.3 1996/12/18 10:27:19 bostic Exp $ (Berkeley) $Date: 1996/12/18 10:27:19 $"; + * "$Id: vi_mextern.h,v 8.4 1997/08/02 16:50:11 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:50:11 $"; */ /* @@ -28,7 +28,7 @@ Widget vi_create_menubar(Widget); void vi_input_func(XtPointer, int *, XtInputId *); int vi_run(int, char *[], int *, int *, pid_t *); int vi_send(char *, IP_BUF *); -int vi_translate(char *, size_t *); +int vi_translate(char *, size_t *, IP_BUF *); #else Widget vi_create_editor(); Widget vi_create_menubar(); diff --git a/vi/v_event.c b/vi/v_event.c index 66fd9010..d6d96a08 100644 --- a/vi/v_event.c +++ b/vi/v_event.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "$Id: v_event.c,v 8.14 1997/04/12 17:19:22 bostic Exp $ (Berkeley) $Date: 1997/04/12 17:19:22 $"; +static const char sccsid[] = "$Id: v_event.c,v 8.15 1997/08/02 16:48:39 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:48:39 $"; #endif /* not lint */ #include @@ -89,9 +89,13 @@ v_editopt(sp, vp) SCR *sp; VICMD *vp; { + int rval; - return (api_opts_set(sp, - vp->ev.e_str1, vp->ev.e_str2, vp->ev.e_val1, vp->ev.e_val1)); + rval = api_opts_set(sp, + vp->ev.e_str1, vp->ev.e_str2, vp->ev.e_val1, vp->ev.e_val1); + if (sp->gp->scr_reply != NULL) + (void)sp->gp->scr_reply(sp, rval, NULL); + return (rval); } /* -- 2.11.4.GIT