|
|
1.1 root 1: /*-----------------------------------------------------------------------------
2: Talking BIOS device driver for the AT&T PC6300.
3: Copyright (C) Karl Dahlke 1987
4: This software may be freely used and distributed
5: for any non-profit purpose.
6: *-----------------------------------------------------------------------------
7: */
8:
9: /* cmd.c: interpret and execute talking commands */
10:
11: #include "speech.h"
12:
13: /* the available speech commands */
14: struct SDCMD sdcmds[] = {
15: {0,"",0,0,0,0,0,0}, /* 0 is not a function */
16: /* 1: read characters */
17: {"reed the preivious karecter","pchar",1,0,0,1,0,0},
18: {"reed the current karecter","cchar",1,0,0,1,0,0},
19: {"reed the next karecter","nchar",1,0,0,1,0,0},
20: {"upper or lower case","case",1,0,0,0,0,0},
21: {"reed the current karecter as a word","asword",1,0,0,1,0,0},
22: {"preivious row","prow",1,0,0,1,0,0},
23: {"next row","nrow",1,0,0,1,0,0},
24: {"current cohllumm number","colnum",1,0,0,0,0,0},
25: /* 9: read words */
26: {"reed the preivious word","pword",1,0,1,0,0,0},
27: {"reed the current word","cword",1,0,1,0,0,0},
28: {"reed the next word","nword",1,0,1,0,0,0},
29: /* 12: read lines */
30: {"reed the preivious line","pline",1,1,0,0,0,0},
31: {"reed the current line","cline",1,1,0,0,0,0},
32: {"reed the next line","nline",1,1,0,0,0,0},
33: {"reed the line after next","nline2",1,1,0,0,0,0},
34: {"reed the last cohmpleit line","lline",1,1,0,0,0,0},
35: /* 17: cursor position */
36: {"start of buffer","top",1,0,0,0,0,0},
37: {"end of buffer","bottom",1,0,0,0,0,0},
38: {"stop speaking","shutup",0,0,0,0,0,0},
39: /* 20: modes */
40: {"announce the function of the next key entered","explain",0,0,0,0,1,0},
41: {"pass next karecter threw","bypass",0,0,0,0,1,0},
42: {"reed one line at a time","oneline",0,0,0,0,0,0},
43: {"toggle bighnary mode","toggle",0,0,0,0,1,0},
44: /* 24: search, configure, bind */
45: {"serch down","search2",0,0,0,0,0,1},
46: {"serch up","search1",0,0,0,0,0,1},
47: {"set volume level","volume",0,0,0,0,1,0},
48: {"set speed","speed",0,0,0,0,1,0},
49: {"key binding","bind",0,0,0,0,0,1},
50: {"set pronounciation","setpro",0,0,0,0,0,1},
51: /* 30: user-defined key macros */
52: {"select macroes","selmac",0,0,0,0,0,0},
53: {"set macroe","setmac",0,0,0,0,0,1},
54: {0,"",0,0,0,0,0,0}
55: };
56:
57: static int keycmd_on;
58:
59: keycmd_start(session, rdwait)
60: short session;
61: char rdwait; /* wait for read flags */
62: {
63: struct SDCONTROL *o = sdcontrol[session];
64: short istate;
65:
66: /* need not use the semaphore under coherent,
67: * code already synchronized. */
68: #ifdef MSDOS
69: istate = sphi();
70: if(!keycmd_on) { /* no function running or deferred */
71: #endif
72: if(!rdwait || !(o->onesymb | o->rdflag|draincheck(o))) {
73: /* ok to run/schedule this command */
74: #ifdef MSDOS
75: keycmd_on = 1;
76: spl(istate);
77: #endif
78:
79: /* set up static state variables for the deferred speech function,
80: * according to the session */
81: sdsession = session;
82: sdc = o;
83: return 1;
84: }
85: #ifdef MSDOS
86: }
87: spl(istate);
88: #endif
89: return 0;
90: } /* keycmd_start */
91:
92: keycmd_end() { keycmd_on = 0; }
93:
94: /* translate an entered key into a talking command.
95: * return nonzero if the key represents a talking command. */
96: transkey(key)
97: short key;
98: {
99: short low;
100:
101: low = key & 0xff;
102: if(low > 26) return 0;
103:
104: /* control or alt or function key */
105: if(low == 0) low = key>>8;
106: else low += 119;
107:
108: return low;
109: } /* transkey */
110:
111: /* execute the talking command */
112: keycmd(packed)
113: short packed;
114: {
115: char cmd = packed & 0x7f;
116: struct SDCMD *cmdp = &sdcmds[cmd];
117: struct MULTIKEY *a = packed&128 ? &sdc->indata : &sdc->outdata;
118: char *suptext = a->text;
119: short support = a->support;
120: short i, n;
121: char asword, c;
122: extern char *submlookup();
123:
124: if(support & 0xff) support &= 0xff;
125:
126: /* some comands are meaningless when the buffer is empty */
127: if(cmdp->nonempty && bufempty()) goto error_bound;
128:
129: /* The following code is added to fix a bug.
130: * The bug occurs when the user issues many (read symbol) commands in sequence
131: * (e.g. holds down a repeat key to constantly read the next symbol).
132: * Reading a mixed token (containing digits and lettters) requires multiple
133: * "reads", during which onesym is set to 1.
134: * If another command comes in the middle, the last half of the symbol
135: * willl not be read. Thus, "1a 2b 3c 4d" might be heard as "1 2 3 4".
136: * Just eat the command. */
137: if(cmdp->rdsymb && sdc->onesymb) return;
138:
139: /* perform the requested action */
140: asword = 0;
141: cursor_copy();
142:
143: switch(cmd) {
144: #ifdef NEVER
145: I don't like this feature any more, too confusing
146: case 30: /* macro set selection */
147: if(!isdigit(support)) goto error_bell;
148: sdc->macsel = support - '0';
149: break;
150: #endif
151:
152: case 31: /* macro definition */
153: asword = 1;
154: case 28: /* key binding */
155: c = keybind(suptext, asword);
156: if(!sdsession) sdsound(c);
157: break;
158:
159: case 19: /* shutup, may be called via output characters */
160: stopread();
161: drainset(sdc);
162: break;
163:
164: case 29: /* set pronunciation */
165: c = addword(suptext);
166: if(!sdsession) sdsound(c);
167: break;
168:
169: case 22: /* toggle reading mode, one line, or to the end */
170: sdonoff(sdc->oneline ^= 1);
171: break;
172:
173: case 21: /* enable bypass */
174: (*sdc->dev_in)(support);
175: break;
176:
177: case 3: /* speak next character */
178: if(incptr()) goto error_bound;
179: break;
180:
181: case 1: /* speak previous character */
182: if(decptr()) goto error_bound;
183: break;
184:
185: case 5: /* speak word for the current character */
186: asword = 1;
187: case 2: /* speak current character */
188: break;
189:
190: case 17: /* move cursor to top of buffer */
191: buftop();
192: break;
193:
194: case 18: /* mov cursor to bottom of buffer */
195: bufbot();
196: break;
197:
198: case 12: /* read previous line */
199: backnl();
200: if(decptr()) goto error_bound;
201: case 13: /* start reading at current line */
202: break;
203:
204: case 15: /* read line after next */
205: if(nextnl()) goto error_bound;
206: case 14: /* read next line */
207: if(nextnl()) goto error_bound;
208: break;
209:
210: case 8: /* read column number */
211: n = backnl();
212: sdw[5] = 0;
213: for(i=4; i>=0; --i) {
214: sdw[i] = n%10 + '0';
215: n /= 10;
216: }
217: for(i=0; i<4; ++i)
218: if(sdw[i] != '0') break;
219: memcpy(sdw, sdw+i, 5);
220: sdtextw();
221: break;
222:
223: case 4: /* indicate case */
224: c = getc();
225: if(!islower(c|0x20)) goto error_bell;
226: sdonoff(!(c&0x20));
227: break;
228:
229: case 11: /* speak next symbol */
230: nextsym();
231: do
232: if(incptr()) goto error_bound;
233: while(getc() == ' ');
234: break;
235:
236: case 10: /* speak current symbol */
237: if(getc() == ' ')
238: cmdp = &sdcmds[2]; /* just speak the character */
239: break;
240:
241: case 9: /* speak previous symbol */
242: backsym();
243: do { if(decptr()) goto error_bound; } while(getc() == ' ');
244: break;
245:
246: case 6: /* up a row */
247: n = backnl();
248: if(decptr()) goto error_bound;
249: backnl();
250: for(i=1; i<n; ++i) {
251: if(getc() == '\r') goto error_bell;
252: incptr();
253: }
254: break;
255:
256: case 7: /* down a row */
257: n = backnl();
258: if(nextnl()) goto error_bound;
259: for(i=1; i<n; ++i) {
260: if(getc() == '\r') goto error_bell;
261: if(incptr()) goto error_bound;
262: }
263: break;
264:
265: case 16: /* read last complete line */
266: bufbot_temp();
267: backnl();
268: while(!(c = decptr()))
269: if(getc() != '\r') break;
270: if(c) incptr();
271: break;
272:
273: case 20: /* announce the function of the next key entered */
274: /* translate support */
275: i = transkey(support);
276: if(!i) goto error_bell;
277: n = sdc->keymap[i];
278: if(n) sdtext(sdcmds[n].desc);
279: else if(submlookup(sdsession*10, i))
280: sdtext("macro set");
281: else
282: sdtext("no speech function");
283: break;
284:
285: case 23: /* binary mode */
286: if(binmode(support)) goto error_bell;
287: break;
288:
289: case 24:
290: case 25:
291: if(*suptext)
292: memcpy(a->lasttext, suptext, LINELEN);
293: suptext = a->lasttext;
294: if(!*suptext) goto error_bell;
295: if(bufsearch(cmd-24, suptext)) goto error_bound;
296: cursor_set();
297: if(sdc->oneline) cmdp = &sdcmds[13];
298: else sdtext("o k");
299: break;
300:
301: default:
302: if(!sdsession) sdsound(3);
303: error_bell:
304: if(!sdsession) sdsound(3);
305: return;
306:
307: error_bound:
308: if(!sdsession) sdsound(4);
309: return;
310: } /* end switch on function */
311:
312: /* begin reading? */
313: if(cmdp->rdline) {
314: backnl();
315: cursor_set();
316: sdc->rdflag = 1;
317: reading(0);
318: return;
319: }
320:
321: if(cmdp->rdsymb) {
322: backsym();
323: cursor_set();
324: sdc->onesymb = 1;
325: reading(0);
326: return;
327: }
328:
329: if(cmdp->rdchar)
330: curchar(1, asword);
331: } /* keycmd */
332:
333: static binmode(c)
334: char c;
335: {
336: char onoff = 0;
337:
338: switch(c) {
339: case 'a': /* audio feedback */
340: if(sdsession) return 1;
341: if(sdnoises^=1) onoff = 1;
342: break;
343: case 'e': /* empty buffer */
344: if(sdscreenmode) return 1; /* always text in screen memory */
345: bufclear();
346: break;
347: case 'n': /* notes for keys */
348: if(sdsession) return 1;
349: if(sdtones^=1) onoff = 1;
350: break;
351: case 's': /* screen memory */
352: if(sdsession) return 1;
353: if(sdscreenmode ^= 1) onoff = 1;
354: break;
355: case 'c': /* control characters */
356: if(sdc->ctrl_ok^=1) onoff = 1;
357: break;
358: case 'b': /* buffered input */
359: if(sdc->buf_ok^=1) onoff = 1;
360: break;
361: case 't': /* output tty */
362: if(sdc->dev_ok^=1) onoff = 1;
363: break;
364: case 'O': /* override bad signals from the speech unit */
365: if(sdsession) return 1;
366: if(sdoverride^=1) onoff = 1;
367: break;
368: case 'u': /* unload buffered text into a file, via stdin */
369: buftop();
370: cursor_copy();
371: sdc->dumping = 1;
372: break;
373: default: return 1;
374: } /* end switch */
375:
376: sdonoff(onoff);
377: return 0;
378: } /* binmode */
379:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.