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.
|
---|
5 | */
|
---|
6 | /* EEQUES - Handle queries and status displays
|
---|
7 | */
|
---|
8 | #include "elle.h"
|
---|
9 |
|
---|
10 | /*
|
---|
11 | * Ask -- ask the user for some input on the lowest line of the screen
|
---|
12 | *
|
---|
13 | * The arg is a string in printf form, followed by up to three args
|
---|
14 | * for the printf string
|
---|
15 | *
|
---|
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.
|
---|
23 | *
|
---|
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.
|
---|
27 | */
|
---|
28 |
|
---|
29 | int chg_win();
|
---|
30 | struct window *make_mode();
|
---|
31 |
|
---|
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() */
|
---|
35 |
|
---|
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,
|
---|
40 | FN_DEBUG,
|
---|
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,
|
---|
43 | FN_UNKILL, FN_BKLINE,
|
---|
44 | 0
|
---|
45 | };
|
---|
46 |
|
---|
47 | char *
|
---|
48 | ask (string, arg1, arg2, arg3)
|
---|
49 | char *string, *arg1, *arg2, *arg3;
|
---|
50 |
|
---|
51 | { register int i, c;
|
---|
52 | register char *s;
|
---|
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 */
|
---|
59 | #if FX_FILLMODE
|
---|
60 | extern int fill_mode;
|
---|
61 | int ofillmode = fill_mode; /* Gotta turn this one off */
|
---|
62 | fill_mode = 0;
|
---|
63 | #endif /*FX_FILLMODE*/
|
---|
64 |
|
---|
65 | oldwin = cur_win;
|
---|
66 | chg_win (ask_win);
|
---|
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 */
|
---|
70 |
|
---|
71 | /* copy 'string' into line */
|
---|
72 | cbuf[0] = 0;
|
---|
73 | asklp: sprintf (&cbuf[strlen(cbuf)], string, arg1, arg2, arg3);
|
---|
74 | p_length = strlen(cbuf); /* Find how long it is */
|
---|
75 |
|
---|
76 | /* now let the user type in */
|
---|
77 | for(;;)
|
---|
78 | {
|
---|
79 | if ((rd_type & (RDS_WINFLGS|RD_MODE)) && tinwait () == 0)
|
---|
80 | {
|
---|
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.
|
---|
89 | */
|
---|
90 | if(rd_type&RD_MODE) /* If mode also needs it, */
|
---|
91 | fupd_wind(make_mode(user_win)); /* do it */
|
---|
92 |
|
---|
93 | upd_curs(cur_dot);
|
---|
94 | rd_type &= ~(RDS_WINFLGS|RD_MODE);
|
---|
95 | ask_lin = curs_lin; /* Remember line cursor on */
|
---|
96 | tbufls();
|
---|
97 |
|
---|
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 */
|
---|
101 | e_gocur();
|
---|
102 | }
|
---|
103 | exp = 1;
|
---|
104 | exp_p = 0;
|
---|
105 | cont: this_cmd = 0;
|
---|
106 | c = cmd_read();
|
---|
107 |
|
---|
108 | if (
|
---|
109 | #if !(ICONOGRAPHICS)
|
---|
110 | c == ESC ||
|
---|
111 | #endif /*-ICONOGRAPHICS*/
|
---|
112 | c == LF || c == CR)
|
---|
113 | break;
|
---|
114 | if (c == BELL) /* ^G means punt.. */
|
---|
115 | { chg_win(oldwin);
|
---|
116 | ask_blen = 1; /* Assume buffer has something */
|
---|
117 | ding((char *)0); /* Clear echo window */
|
---|
118 | ask_cnt = 0; /* Nothing for askclr to do */
|
---|
119 | #if FX_SKMAC
|
---|
120 | km_abort();
|
---|
121 | #endif /*FX_SKMAC*/
|
---|
122 | #if FX_FILLMODE
|
---|
123 | fill_mode = ofillmode;
|
---|
124 | #endif /*FX_FILLMODE*/
|
---|
125 | return(0); /* Return 0 to indicate we quit */
|
---|
126 | }
|
---|
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;
|
---|
133 | switch(i)
|
---|
134 | { default: /* Permissible function */
|
---|
135 | cmd_xct(c);
|
---|
136 | break;
|
---|
137 | case FN_NEWWIN: /* Wants redisplay, do specially */
|
---|
138 | clear_wind(ask_win);
|
---|
139 | break;
|
---|
140 | case 0: /* Illegal function */
|
---|
141 | ring_bell();
|
---|
142 | #if FX_SKMAC
|
---|
143 | km_abort();
|
---|
144 | #endif /*FX_SKMAC*/
|
---|
145 | continue;
|
---|
146 | }
|
---|
147 | if(this_cmd == ARGCMD)
|
---|
148 | goto cont;
|
---|
149 | }
|
---|
150 |
|
---|
151 | if((anslen = e_blen()) > 255) /* Ridiculously long? */
|
---|
152 | { strcpy(cbuf,"Huh? Try again - ");
|
---|
153 | #if FX_SKMAC
|
---|
154 | km_abort();
|
---|
155 | #endif /*FX_SKMAC*/
|
---|
156 | goto asklp;
|
---|
157 | }
|
---|
158 | i = anslen;
|
---|
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 */
|
---|
162 |
|
---|
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(); }
|
---|
167 | while(--i);
|
---|
168 | *s = '\0'; /* make sure string terminated */
|
---|
169 | chg_win(oldwin);
|
---|
170 | #if FX_FILLMODE
|
---|
171 | fill_mode = ofillmode;
|
---|
172 | #endif /*FX_FILLMODE*/
|
---|
173 | return (newline); /* return pointer to data */
|
---|
174 | }
|
---|
175 |
|
---|
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.
|
---|
179 | */
|
---|
180 | askclr()
|
---|
181 | {
|
---|
182 | if(ask_cnt) sayclr(); /* Zap if need be */
|
---|
183 | }
|
---|
184 | |
---|
185 |
|
---|
186 | /* SAY - put up some text on bottom line.
|
---|
187 | * Does this intelligently; text stays up until next SAY or
|
---|
188 | * screen refresh.
|
---|
189 | * SAYNOW - like SAY but forces display right away
|
---|
190 | * SAYTOO - adds to existing stuff
|
---|
191 | * SAYNTOO - ditto but forces output right away.
|
---|
192 | * DING - Ring_bell then SAYNOW
|
---|
193 | * DINGTOO - is to DING as SAYNTOO is to SAYNOW.
|
---|
194 | * SAYCLR - Clears echo area (but not immediately)
|
---|
195 | */
|
---|
196 | #define SAY_NOW 01 /* Force display immediately */
|
---|
197 | #define SAY_TOO 02 /* Add to existing stuff */
|
---|
198 | #define SAY_BEL 04 /* Ding bell prior to text */
|
---|
199 | #define SAY_LEN 010 /* String length specified by 3rd arg */
|
---|
200 |
|
---|
201 | say(str) char *str; { sayall(str, 0); }
|
---|
202 | saynow(str) char *str; { sayall(str, SAY_NOW); }
|
---|
203 | saytoo(str) char *str; { sayall(str, SAY_TOO); }
|
---|
204 | sayntoo(str) char *str; { sayall(str, SAY_NOW|SAY_TOO); }
|
---|
205 | ding(str) char *str; { sayall(str, SAY_NOW|SAY_BEL); }
|
---|
206 | dingtoo(str) char *str; { sayall(str, SAY_NOW|SAY_TOO|SAY_BEL); }
|
---|
207 | saylntoo(str,n) char *str; { sayall(str, SAY_NOW|SAY_TOO|SAY_LEN, n); }
|
---|
208 | sayclr() { sayall((char *)0, 0); }
|
---|
209 |
|
---|
210 | sayall(str,flags,len)
|
---|
211 | char *str;
|
---|
212 | int flags, len;
|
---|
213 | { register struct window *w;
|
---|
214 | register f;
|
---|
215 |
|
---|
216 | f = flags;
|
---|
217 | w = cur_win;
|
---|
218 |
|
---|
219 | ask_cnt = 0; /* Always reset this */
|
---|
220 | if(str == 0 && ask_blen == 0) /* If clearing, and buff empty */
|
---|
221 | return; /* nothing to do. */
|
---|
222 | chg_win(ask_win);
|
---|
223 | if(f&SAY_TOO)
|
---|
224 | e_goeob(); /* Add to end of existing stuff */
|
---|
225 | else e_reset(); /* Flush previous stuff if any */
|
---|
226 | if(str)
|
---|
227 | { if(f&SAY_LEN) /* Insert string to post up */
|
---|
228 | ed_nsins(str,len);
|
---|
229 | else e_sputz(str);
|
---|
230 | }
|
---|
231 | ask_blen = e_dot(); /* Remember whether buffer has something */
|
---|
232 |
|
---|
233 | e_setcur(); /* and remember to set dot */
|
---|
234 | if(f&SAY_NOW)
|
---|
235 | { if(f&SAY_BEL)
|
---|
236 | ring_bell();
|
---|
237 | redp(RD_WINRES);
|
---|
238 | upd_wind((struct window *)0);
|
---|
239 | tbufls();
|
---|
240 | }
|
---|
241 | else redp(RD_WINRES); /* Set for this window */
|
---|
242 | chg_win(w); /* Back to previous window */
|
---|
243 |
|
---|
244 | /* redisplay() does a special check for ask_win->w_redp, so we
|
---|
245 | ** don't need to set a global flag like RD_CHKALL.
|
---|
246 | */
|
---|
247 | }
|
---|
248 | |
---|
249 |
|
---|
250 | /* YELLAT -- post string on specified line of screen, immediately.
|
---|
251 | * Differs from SAYNOW and SAYNTOO in that NO buffer
|
---|
252 | * manipulation is done; screen image is hacked directly.
|
---|
253 | */
|
---|
254 |
|
---|
255 | yellat(str, line)
|
---|
256 | char *str;
|
---|
257 | register int line;
|
---|
258 | { register struct scr_line *s;
|
---|
259 |
|
---|
260 | s = scr[line];
|
---|
261 | strncpy(s->sl_nlin, str, scr_wd0);
|
---|
262 | s->sl_ncol = strlen(str);
|
---|
263 | #if IMAGEN
|
---|
264 | s->sl_flg |= SL_REDO;
|
---|
265 | #endif
|
---|
266 | upd_line(line);
|
---|
267 | tbufls();
|
---|
268 | }
|
---|
269 |
|
---|
270 | /* YELLTOO -- Append string to previous echo line of screen, immediately.
|
---|
271 | ** Uses the ask_lin variable which is set by ask().
|
---|
272 | ** Currently this function is only needed for srchint() in EESRCH.
|
---|
273 | */
|
---|
274 | yelltoo(str)
|
---|
275 | char *str;
|
---|
276 | { register int i;
|
---|
277 | register struct scr_line *s;
|
---|
278 | char nstr[MAXLINE];
|
---|
279 |
|
---|
280 | s = scr[ask_lin];
|
---|
281 | i = s->sl_col;
|
---|
282 | nstr[0] = 0;
|
---|
283 | strncat(strncat(nstr, s->sl_line, i), /* Make new string */
|
---|
284 | str, MAXLINE - i);
|
---|
285 | yellat(nstr, ask_lin); /* Post it */
|
---|
286 | }
|
---|
287 | |
---|
288 |
|
---|
289 | /* BARF - output a message on the bottom line of the screen,
|
---|
290 | ** bypassing everything (window, buffer, screen image).
|
---|
291 | ** Does NOT know about SAY's stuff and does not update it!
|
---|
292 | ** Use only in dire straits...
|
---|
293 | ** ERRBARF - same but uses a standard error-message prefix.
|
---|
294 | */
|
---|
295 |
|
---|
296 | errbarf(str)
|
---|
297 | char *str;
|
---|
298 | {
|
---|
299 | barf("\007ELLE Internal Error: ");
|
---|
300 | tputz(str);
|
---|
301 | tbufls();
|
---|
302 | }
|
---|
303 |
|
---|
304 | barf(str)
|
---|
305 | char *str;
|
---|
306 | {
|
---|
307 | ask_cnt = 0; /* Ensure askclr() disabled */
|
---|
308 | t_curpos(scr_ht - ECHOLINES, 0); /* goto echo area */
|
---|
309 | t_cleol();
|
---|
310 | tputz(str);
|
---|
311 | tbufls();
|
---|
312 | curs_col = -1000; /* Say we dunno where cursor is now */
|
---|
313 | }
|
---|
314 |
|
---|
315 | #if IMAGEN
|
---|
316 | /* Same, but do it far from harm's way */
|
---|
317 | barf2(str)
|
---|
318 | char *str;
|
---|
319 | {
|
---|
320 | t_curpos (scr_ht - 1, scr_wid - strlen(str) - 8);
|
---|
321 | t_cleol ();
|
---|
322 | tputz(str);
|
---|
323 | tputz(" --M--");
|
---|
324 | tbufls();
|
---|
325 | tgetc(); /* Read any char & discard */
|
---|
326 | curs_col = -1000; /* Say we dunno where cursor is now */
|
---|
327 | }
|
---|
328 | #endif /*IMAGEN*/
|
---|