[9] | 1 | /* ELLE - Copyright 1982, 1984, 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 |
|
---|
| 7 | /* EECMDS Command table lookup and profile code
|
---|
| 8 | */
|
---|
| 9 |
|
---|
| 10 | #include "elle.h"
|
---|
| 11 |
|
---|
| 12 | /* Function table, see the included file for explanation. */
|
---|
| 13 |
|
---|
| 14 | /* First must pre-declare function addrs */
|
---|
| 15 | #define EFUN(rtn,rtnstr,name) int rtn();
|
---|
| 16 | #define EFUNHOLE
|
---|
| 17 | #include "eefdef.h"
|
---|
| 18 |
|
---|
| 19 | /* Now re-insert to define function table */
|
---|
| 20 | int (*funtab[])() =
|
---|
| 21 | {
|
---|
| 22 | #undef EFUN /* Avoid redefinition error message */
|
---|
| 23 | #undef EFUNHOLE
|
---|
| 24 | #define EFUN(rtn,rtnstr,name) rtn,
|
---|
| 25 | #define EFUNHOLE 0,
|
---|
| 26 | #include "eefdef.h"
|
---|
| 27 | };
|
---|
| 28 | int funmax = sizeof(funtab)/sizeof(funtab[0]); /* 1st illegal function # */
|
---|
| 29 |
|
---|
| 30 | /* Insert default command char map tables and profile structure */
|
---|
| 31 |
|
---|
| 32 | #include "defprf.c"
|
---|
| 33 | |
---|
| 34 |
|
---|
| 35 | /* EFUN: "Prefix Meta" */
|
---|
| 36 | /* Meta-prefix command.
|
---|
| 37 | * For now, very simple. Perhaps later try to hair up with
|
---|
| 38 | * time-out "M-" prompt?
|
---|
| 39 | */
|
---|
| 40 | f_pfxmeta()
|
---|
| 41 | { return(cmd_xct(cmd_read()|CB_META));
|
---|
| 42 | }
|
---|
| 43 |
|
---|
| 44 | /* EFUN: "Prefix Extend" */
|
---|
| 45 | /* Extended-prefix command.
|
---|
| 46 | * Likewise trivial; perhaps later hair up with timeout "^X-" prompt?
|
---|
| 47 | */
|
---|
| 48 | f_pfxext()
|
---|
| 49 | { return(cmd_xct(cmd_read()|CB_EXT));
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | /* EFUN: "Universal Arg" */
|
---|
| 53 | /* This routine is also called by "Argument Digit" with a special arg
|
---|
| 54 | * of -1 in order to share code. Since that invocation always sets unrchf,
|
---|
| 55 | * it should always complete at least one digit read loop.
|
---|
| 56 | * Note that exp and exp_p are set to 1 and 0 at the top-level command
|
---|
| 57 | * loop.
|
---|
| 58 | */
|
---|
| 59 | f_uarg(ch)
|
---|
| 60 | int ch;
|
---|
| 61 | { register int c, oc, i;
|
---|
| 62 |
|
---|
| 63 | /* Set distinguishing exp_p value depending on whether invoked
|
---|
| 64 | * by CTRL-U or another function (Argument Digit, Negative Argument)
|
---|
| 65 | */
|
---|
| 66 | exp_p = (ch < 0) ? 1 : 4;
|
---|
| 67 | i = 0; /* Read numerical arg if any follows */
|
---|
| 68 | for(;;)
|
---|
| 69 | { oc = cmd_read(); /* Get next input char */
|
---|
| 70 | c = oc & 0177;
|
---|
| 71 | if(c == '-' && !i)
|
---|
| 72 | { exp_p = -1;
|
---|
| 73 | exp = 1; /* Set in case no digits follow */
|
---|
| 74 | }
|
---|
| 75 | else if('0' <= c && c <= '9') /* If it's a digit too, */
|
---|
| 76 | { i = (i * 10) + c - '0'; /* add digit in. */
|
---|
| 77 | if(exp_p >= 0) exp_p = 1;
|
---|
| 78 | exp = i;
|
---|
| 79 | }
|
---|
| 80 | else break;
|
---|
| 81 | }
|
---|
| 82 | exp *= exp_p; /* Multiply arg appropriately */
|
---|
| 83 | unrchf = oc; /* Not a digit, re-read it next. */
|
---|
| 84 |
|
---|
| 85 | this_cmd = ARGCMD;
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | /* EFUN: "Negative Argument" */
|
---|
| 89 | f_negarg(ch)
|
---|
| 90 | int ch;
|
---|
| 91 | { f_uarg(-1); /* Invoke code from Universal Arg */
|
---|
| 92 | exp = -exp;
|
---|
| 93 | }
|
---|
| 94 |
|
---|
| 95 | /* EFUN: "Argument Digit" */
|
---|
| 96 | f_argdig(ch)
|
---|
| 97 | int ch;
|
---|
| 98 | { unrchf = ch; /* Re-read the digit */
|
---|
| 99 | f_uarg(-1); /* Invoke code from Universal Arg */
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | /* EFUN: "Set Profile" */
|
---|
| 103 | /* Asks for a profile file and sets profile from it.
|
---|
| 104 | */
|
---|
| 105 | f_setprof()
|
---|
| 106 | { int set_profile();
|
---|
| 107 | hack_file("Set Profile: ", set_profile);
|
---|
| 108 | }
|
---|
| 109 |
|
---|
| 110 | #if FX_VTBUTTONS
|
---|
| 111 | /* EFUN: "VT100 Button Hack" */
|
---|
| 112 | /* This must be bound to Meta-O if anything, because the VT100 sends
|
---|
| 113 | * an ESC O prefix when the function buttons are used.
|
---|
| 114 | */
|
---|
| 115 | f_vtbuttons () /* vt100 function buttons */
|
---|
| 116 | {
|
---|
| 117 | switch(cmd_read())
|
---|
| 118 | { case ('A'):
|
---|
| 119 | return (f_uprline ());
|
---|
| 120 | case ('B'):
|
---|
| 121 | return (f_dnrline ());
|
---|
| 122 | case ('C'):
|
---|
| 123 | return (f_fword ());
|
---|
| 124 | case ('D'):
|
---|
| 125 | return (f_bword ());
|
---|
| 126 | case ('Q'): /* PF1 */
|
---|
| 127 | return (f_kregion());
|
---|
| 128 | default:
|
---|
| 129 | ring_bell ();
|
---|
| 130 | break;
|
---|
| 131 | }
|
---|
| 132 | }
|
---|
| 133 | #endif /*FX_VTBUTTONS*/
|
---|
| 134 | |
---|
| 135 |
|
---|
| 136 | /* CMD_WAIT() - Return TRUE if any command input waiting.
|
---|
| 137 | */
|
---|
| 138 | cmd_wait()
|
---|
| 139 | { return(unrchf >= 0
|
---|
| 140 | #if FX_SKMAC
|
---|
| 141 | || km_inwait() /* Check for kbdmac input waiting */
|
---|
| 142 | #endif /*FX_SKMAC*/
|
---|
| 143 | || tinwait());
|
---|
| 144 | }
|
---|
| 145 |
|
---|
| 146 | /* CMD_READ() - Read a command (single char) from user, and return it.
|
---|
| 147 | */
|
---|
| 148 | cmd_read()
|
---|
| 149 | { register int c;
|
---|
| 150 |
|
---|
| 151 | if((c = unrchf) >= 0) /* Re-reading last char? */
|
---|
| 152 | { unrchf = -1;
|
---|
| 153 | return(c);
|
---|
| 154 | }
|
---|
| 155 | #if FX_SKMAC /* Hacking keyboard macros? */
|
---|
| 156 | return(km_getc()); /* Yes. This calls tgetc if no kbd macro */
|
---|
| 157 | #else
|
---|
| 158 | return(tgetc());
|
---|
| 159 | #endif /*-FX_SKMAC*/
|
---|
| 160 | }
|
---|
| 161 |
|
---|
| 162 | /* CMD_XCT(ch) - Command Execution dispatch routine.
|
---|
| 163 | ** Takes char and executes the function (efun) bound to that command key.
|
---|
| 164 | */
|
---|
| 165 | cmd_xct(ch)
|
---|
| 166 | int ch;
|
---|
| 167 | { register int (*funct) ();
|
---|
| 168 | register int c;
|
---|
| 169 | int (*(cmd_fun())) ();
|
---|
| 170 |
|
---|
| 171 | if(funct = cmd_fun(c = ch)) /* Get function to run */
|
---|
| 172 | return((*funct) (c&0177)); /* Invoke with char arg */
|
---|
| 173 | ring_bell(); /* Undefined command char, error. */
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | /* CMD_FUN(ch) - Return function for char, 0 if none
|
---|
| 177 | */
|
---|
| 178 | int (*cmd_fun(c))()
|
---|
| 179 | int c;
|
---|
| 180 | {
|
---|
| 181 | return(funtab[cmd_idx(c)]);
|
---|
| 182 | }
|
---|
| 183 |
|
---|
| 184 | /* CMD_IDX(ch) - Given command char, return function index for it
|
---|
| 185 | */
|
---|
| 186 | cmd_idx(c)
|
---|
| 187 | register int c;
|
---|
| 188 | { register char *cp;
|
---|
| 189 | register int i;
|
---|
| 190 |
|
---|
| 191 | if(c&CB_EXT)
|
---|
| 192 | { cp = def_prof.extvec;
|
---|
| 193 | i = def_prof.extvcnt;
|
---|
| 194 | goto inlup;
|
---|
| 195 | }
|
---|
| 196 | if(c&CB_META)
|
---|
| 197 | { cp = def_prof.metavec;
|
---|
| 198 | i = def_prof.metavcnt;
|
---|
| 199 | inlup: c = upcase(c);
|
---|
| 200 | do { if(*cp++ != c) cp++;
|
---|
| 201 | else
|
---|
| 202 | { i = *cp&0377;
|
---|
| 203 | break;
|
---|
| 204 | }
|
---|
| 205 | } while(--i); /* If counts out, will return 0! */
|
---|
| 206 | }
|
---|
| 207 | else i = def_prof.chrvec[c&0177]&0377;
|
---|
| 208 | if(i >= funmax)
|
---|
| 209 | return(0);
|
---|
| 210 | return(i);
|
---|
| 211 | }
|
---|
| 212 | |
---|
| 213 |
|
---|
| 214 | /* Profile hacking */
|
---|
| 215 |
|
---|
| 216 | #if TOPS20
|
---|
| 217 | #include <sys/file.h> /* for O_BINARY */
|
---|
| 218 | #endif
|
---|
| 219 |
|
---|
| 220 | set_profile(filename)
|
---|
| 221 | char *filename;
|
---|
| 222 | { char pfile[200];
|
---|
| 223 | char psfile[200];
|
---|
| 224 | register int pfd, len;
|
---|
| 225 | chroff sbx_fdlen();
|
---|
| 226 | register char *profptr;
|
---|
| 227 | struct stored_profile st_prof;
|
---|
| 228 |
|
---|
| 229 | if(filename) strcpy(pfile,filename);
|
---|
| 230 | else /* Check for user's profile */
|
---|
| 231 | {
|
---|
| 232 | strcat(strcat(strcpy(pfile,homedir),"/"),ev_profile);
|
---|
| 233 | }
|
---|
| 234 | if((pfd = open(pfile,
|
---|
| 235 | #if TOPS20
|
---|
| 236 | O_BINARY
|
---|
| 237 | #else
|
---|
| 238 | 0
|
---|
| 239 | #endif
|
---|
| 240 | )) < 0)
|
---|
| 241 | { if(filename)
|
---|
| 242 | { ding("Cannot open file");
|
---|
| 243 | }
|
---|
| 244 | return;
|
---|
| 245 | }
|
---|
| 246 | if((len = (int)sbx_fdlen(pfd)) < sizeof(struct stored_profile))
|
---|
| 247 | goto badfil;
|
---|
| 248 | profptr = memalloc((SBMO)len);
|
---|
| 249 | if(read(pfd,profptr,len) != len)
|
---|
| 250 | goto badfmt;
|
---|
| 251 |
|
---|
| 252 | /* Have read profile into memory, now set up ptrs etc */
|
---|
| 253 | bcopy((SBMA)profptr,(SBMA)&st_prof,sizeof(struct stored_profile));
|
---|
| 254 | def_prof.version = prof_upack(st_prof.version);
|
---|
| 255 | if(def_prof.version != 1)
|
---|
| 256 | goto badfmt;
|
---|
| 257 | def_prof.chrvcnt = prof_upack(st_prof.chrvcnt);
|
---|
| 258 | def_prof.chrvec = profptr + prof_upack(st_prof.chrvec);
|
---|
| 259 | def_prof.metavcnt = prof_upack(st_prof.metavcnt);
|
---|
| 260 | def_prof.metavec = profptr + prof_upack(st_prof.metavec);
|
---|
| 261 | def_prof.extvcnt = prof_upack(st_prof.extvcnt);
|
---|
| 262 | def_prof.extvec = profptr + prof_upack(st_prof.extvec);
|
---|
| 263 | #if SUN
|
---|
| 264 | def_prof.menuvcnt = prof_upack(st_prof.menuvcnt);
|
---|
| 265 | def_prof.menuvec = profptr + prof_upack(st_prof.menuvec);
|
---|
| 266 | #endif /*SUN*/
|
---|
| 267 | goto done;
|
---|
| 268 |
|
---|
| 269 | badfmt: chkfree(profptr);
|
---|
| 270 | badfil: ding("Bad profile format");
|
---|
| 271 | done: close(pfd);
|
---|
| 272 | }
|
---|
| 273 | |
---|
| 274 |
|
---|
| 275 | #if SUN
|
---|
| 276 | /* SUN Menu profile hacking.
|
---|
| 277 | * This is here, instead of e_sun.c, because
|
---|
| 278 | * the profile format is still evolving and for the time being I want to
|
---|
| 279 | * keep all profile-hacking code in one place. --KLH
|
---|
| 280 | */
|
---|
| 281 | #include "suntool/tool_hs.h"
|
---|
| 282 | #include "suntool/menu.h"
|
---|
| 283 |
|
---|
| 284 | #define MENUMAX 16
|
---|
| 285 |
|
---|
| 286 | /* Defined in eesun.c */
|
---|
| 287 | extern struct menu *menuptr;
|
---|
| 288 | extern struct menu menu;
|
---|
| 289 |
|
---|
| 290 | char *funamtab[] = {
|
---|
| 291 | #undef EFUN
|
---|
| 292 | #undef EFUNHOLE
|
---|
| 293 | #define EFUN(rtn,rtnstr,name) name,
|
---|
| 294 | #define EFUNHOLE 0,
|
---|
| 295 | #include "eefdef.h"
|
---|
| 296 | };
|
---|
| 297 |
|
---|
| 298 | init_menu() /* initialize the menu for elle from user profile */
|
---|
| 299 | {
|
---|
| 300 | register struct menuitem *mi;
|
---|
| 301 | register int n, i, fni;
|
---|
| 302 |
|
---|
| 303 | if((n = def_prof.menuvcnt) <= 0)
|
---|
| 304 | return;
|
---|
| 305 | if(n > MENUMAX) n = MENUMAX;
|
---|
| 306 | mi = menu.m_items = (struct menuitem *) calloc(n, sizeof *mi);
|
---|
| 307 |
|
---|
| 308 | menu.m_itemcount = 0;
|
---|
| 309 | for(i = 0; i < n; i++)
|
---|
| 310 | { fni = def_prof.menuvec[i]&0377;
|
---|
| 311 | if(fni >= funmax) continue;
|
---|
| 312 | if(funtab[fni] && funamtab[fni])
|
---|
| 313 | { mi->mi_data = (caddr_t) funtab[fni];
|
---|
| 314 | mi->mi_imagedata = (caddr_t) strdup(funamtab[fni]);
|
---|
| 315 | mi->mi_imagetype = MENU_IMAGESTRING;
|
---|
| 316 | mi++;
|
---|
| 317 | menu.m_itemcount++;
|
---|
| 318 | }
|
---|
| 319 | }
|
---|
| 320 | if(menu.m_itemcount)
|
---|
| 321 | menuptr = &menu;
|
---|
| 322 | }
|
---|
| 323 | #endif /*SUN*/
|
---|