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