1 /* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
2 * This software is quasi-public; it may be used freely with
3 * like software, but may NOT be sold or made part of licensed
4 * products without permission of the author.
6 /* EEQUES - Handle queries and status displays
11 * Ask -- ask the user for some input on the lowest line of the screen
13 * The arg is a string in printf form, followed by up to three args
14 * for the printf string
16 * The string is read into a sort of mini buffer, only the
17 * last line of which is visible on the screen. All editing
18 * features are available to the user to edit the input string.
19 * When the delim character is typed, input is terminated and
20 * The input string is passed back to the caller.
21 * The delim is either an escape or a cr.
22 * IT IS UP TO THE CALLER TO FREE THIS MEMORY.
24 * Note that the actual length of the returned string can be found
25 * in the global variable ask_len. This is a crock but allows
26 * callers to hack nulls in arg strings if they want to.
30 struct window
*make_mode();
32 static int ask_lin
; /* Saved cursor location when ask is done */
33 static int ask_blen
; /* Non-zero if buffer contains something */
34 static int ask_cnt
; /* Incremented by ask(), cleared by askclr() */
36 /* Table of allowed functions during ASK */
37 static char askftab
[] = {
38 FN_PFXMETA
, FN_INSSELF
, FN_BEGLINE
, FN_ENDLINE
, FN_BCHAR
, FN_FCHAR
,
39 FN_DCHAR
, FN_BDCHAR
, FN_TCHARS
, FN_QUOTINS
, FN_UARG
, FN_BKPT
,
41 FN_GOBEG
, FN_GOEND
, FN_FWORD
, FN_BWORD
, FN_KWORD
, FN_BKWORD
,
42 FN_UCWORD
, FN_LCWORD
, FN_UCIWORD
, FN_ARGDIG
, FN_NEWWIN
, FN_KLINE
,
48 ask (string
, arg1
, arg2
, arg3
)
49 char *string
, *arg1
, *arg2
, *arg3
;
53 struct window
*oldwin
;
54 char *newline
; /* where output line goes */
55 char cbuf
[200]; /* For prompt string creation */
56 int p_length
; /* length of prompt */
57 chroff anslen
; /* Length of answer */
58 int funnum
; /* Crock stuff */
61 int ofillmode
= fill_mode
; /* Gotta turn this one off */
63 #endif /*FX_FILLMODE*/
67 ed_reset(); /* Flush contents & request redisp */
68 ask_lin
= cur_win
->w_pos
; /* Set here in case never redisp */
69 ask_cnt
++; /* Bump # of times called */
71 /* copy 'string' into line */
73 asklp
: sprintf (&cbuf
[strlen(cbuf
)], string
, arg1
, arg2
, arg3
);
74 p_length
= strlen(cbuf
); /* Find how long it is */
76 /* now let the user type in */
79 if ((rd_type
& (RDS_WINFLGS
|RD_MODE
)) && tinwait () == 0)
81 e_gobob(); /* Gross crock: insert prompt */
82 e_sputz(cbuf
); /* Ugh, bletch */
83 cur_dot
+= p_length
; /* Temporarily update loc */
84 redp(RD_WINRES
); /* Do complete re-crunch */
85 upd_wind((struct window
*)0); /* Don't interrupt */
86 /* Ensure mode line is spiffy too. This should
87 ** only have to be invoked the first time ask_win
88 ** redisplay is done, and never thereafter.
90 if(rd_type
&RD_MODE
) /* If mode also needs it, */
91 fupd_wind(make_mode(user_win
)); /* do it */
94 rd_type
&= ~(RDS_WINFLGS
|RD_MODE
);
95 ask_lin
= curs_lin
; /* Remember line cursor on */
98 e_gobob(); /* More crock: Remove prompt */
99 sb_deln((SBBUF
*)cur_buf
,(chroff
)p_length
); /* Ugh etc. */
100 cur_dot
-= p_length
; /* Restore loc */
111 #endif /*-ICONOGRAPHICS*/
114 if (c
== BELL
) /* ^G means punt.. */
116 ask_blen
= 1; /* Assume buffer has something */
117 ding((char *)0); /* Clear echo window */
118 ask_cnt
= 0; /* Nothing for askclr to do */
123 fill_mode
= ofillmode
;
124 #endif /*FX_FILLMODE*/
125 return(0); /* Return 0 to indicate we quit */
127 /* This censoring section is a real crock! */
128 funnum
= cmd_idx(c
); /* Map key to command */
129 while(funnum
== FN_PFXMETA
) /* Allow META prefix */
130 funnum
= cmd_idx(c
= CB_META
|cmd_read());
131 for(s
= askftab
; (i
= *s
&0377); ++s
)
132 if(funnum
== i
) break;
134 { default: /* Permissible function */
137 case FN_NEWWIN
: /* Wants redisplay, do specially */
140 case 0: /* Illegal function */
147 if(this_cmd
== ARGCMD
)
151 if((anslen
= e_blen()) > 255) /* Ridiculously long? */
152 { strcpy(cbuf
,"Huh? Try again - ");
159 e_gobob(); /* Go to start of buffer */
160 e_sputz(cbuf
); /* Re-insert prompt so buffer == screen */
161 ask_blen
= i
+ 1; /* Say buffer has something in it */
163 s
= memalloc((SBMO
)(i
+ 1)); /* Allocate fixed loc for answer */
164 newline
= s
; /* Return ptr to allocated string */
165 ask_len
= i
; /* And return (via global) length of string */
166 if(i
) do { *s
++ = e_getc(); }
168 *s
= '\0'; /* make sure string terminated */
171 fill_mode
= ofillmode
;
172 #endif /*FX_FILLMODE*/
173 return (newline
); /* return pointer to data */
176 /* ASKCLR - Clears the echo area (but not immediately) if the last thing
177 ** done to it was an ask() call. Note that invoking a SAY routine
178 ** specifically causes this to be a no-op; SAYCLR must be done instead.
182 if(ask_cnt
) sayclr(); /* Zap if need be */
185 /* SAY - put up some text on bottom line.
186 * Does this intelligently; text stays up until next SAY or
188 * SAYNOW - like SAY but forces display right away
189 * SAYTOO - adds to existing stuff
190 * SAYNTOO - ditto but forces output right away.
191 * DING - Ring_bell then SAYNOW
192 * DINGTOO - is to DING as SAYNTOO is to SAYNOW.
193 * SAYCLR - Clears echo area (but not immediately)
195 #define SAY_NOW 01 /* Force display immediately */
196 #define SAY_TOO 02 /* Add to existing stuff */
197 #define SAY_BEL 04 /* Ding bell prior to text */
198 #define SAY_LEN 010 /* String length specified by 3rd arg */
200 say(str
) char *str
; { sayall(str
, 0); }
201 saynow(str
) char *str
; { sayall(str
, SAY_NOW
); }
202 saytoo(str
) char *str
; { sayall(str
, SAY_TOO
); }
203 sayntoo(str
) char *str
; { sayall(str
, SAY_NOW
|SAY_TOO
); }
204 ding(str
) char *str
; { sayall(str
, SAY_NOW
|SAY_BEL
); }
205 dingtoo(str
) char *str
; { sayall(str
, SAY_NOW
|SAY_TOO
|SAY_BEL
); }
206 saylntoo(str
,n
) char *str
; { sayall(str
, SAY_NOW
|SAY_TOO
|SAY_LEN
, n
); }
207 sayclr() { sayall((char *)0, 0); }
209 sayall(str
,flags
,len
)
212 { register struct window
*w
;
218 ask_cnt
= 0; /* Always reset this */
219 if(str
== 0 && ask_blen
== 0) /* If clearing, and buff empty */
220 return; /* nothing to do. */
223 e_goeob(); /* Add to end of existing stuff */
224 else e_reset(); /* Flush previous stuff if any */
226 { if(f
&SAY_LEN
) /* Insert string to post up */
230 ask_blen
= e_dot(); /* Remember whether buffer has something */
232 e_setcur(); /* and remember to set dot */
237 upd_wind((struct window
*)0);
240 else redp(RD_WINRES
); /* Set for this window */
241 chg_win(w
); /* Back to previous window */
243 /* redisplay() does a special check for ask_win->w_redp, so we
244 ** don't need to set a global flag like RD_CHKALL.
248 /* YELLAT -- post string on specified line of screen, immediately.
249 * Differs from SAYNOW and SAYNTOO in that NO buffer
250 * manipulation is done; screen image is hacked directly.
256 { register struct scr_line
*s
;
259 strncpy(s
->sl_nlin
, str
, scr_wd0
);
260 s
->sl_ncol
= strlen(str
);
262 s
->sl_flg
|= SL_REDO
;
268 /* YELLTOO -- Append string to previous echo line of screen, immediately.
269 ** Uses the ask_lin variable which is set by ask().
270 ** Currently this function is only needed for srchint() in EESRCH.
275 register struct scr_line
*s
;
281 strncat(strncat(nstr
, s
->sl_line
, i
), /* Make new string */
283 yellat(nstr
, ask_lin
); /* Post it */
286 /* BARF - output a message on the bottom line of the screen,
287 ** bypassing everything (window, buffer, screen image).
288 ** Does NOT know about SAY's stuff and does not update it!
289 ** Use only in dire straits...
290 ** ERRBARF - same but uses a standard error-message prefix.
296 barf("\007ELLE Internal Error: ");
304 ask_cnt
= 0; /* Ensure askclr() disabled */
305 t_curpos(scr_ht
- ECHOLINES
, 0); /* goto echo area */
309 curs_col
= -1000; /* Say we dunno where cursor is now */
313 /* Same, but do it far from harm's way */
317 t_curpos (scr_ht
- 1, scr_wid
- strlen(str
) - 8);
322 tgetc(); /* Read any char & discard */
323 curs_col
= -1000; /* Say we dunno where cursor is now */