[9] | 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*/
|
---|