source: trunk/minix/commands/elle/eeques.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 9.2 KB
Line 
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
29int chg_win();
30struct window *make_mode();
31
32static int ask_lin; /* Saved cursor location when ask is done */
33static int ask_blen; /* Non-zero if buffer contains something */
34static int ask_cnt; /* Incremented by ask(), cleared by askclr() */
35
36/* Table of allowed functions during ASK */
37static 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
47char *
48ask (string, arg1, arg2, arg3)
49char *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;
73asklp: 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*/
180askclr()
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
201say(str) char *str; { sayall(str, 0); }
202saynow(str) char *str; { sayall(str, SAY_NOW); }
203saytoo(str) char *str; { sayall(str, SAY_TOO); }
204sayntoo(str) char *str; { sayall(str, SAY_NOW|SAY_TOO); }
205ding(str) char *str; { sayall(str, SAY_NOW|SAY_BEL); }
206dingtoo(str) char *str; { sayall(str, SAY_NOW|SAY_TOO|SAY_BEL); }
207saylntoo(str,n) char *str; { sayall(str, SAY_NOW|SAY_TOO|SAY_LEN, n); }
208sayclr() { sayall((char *)0, 0); }
209
210sayall(str,flags,len)
211char *str;
212int 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
255yellat(str, line)
256char *str;
257register 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*/
274yelltoo(str)
275char *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
296errbarf(str)
297char *str;
298{
299 barf("\007ELLE Internal Error: ");
300 tputz(str);
301 tbufls();
302}
303
304barf(str)
305char *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 */
317barf2(str)
318char *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*/
Note: See TracBrowser for help on using the repository browser.