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