/[linux-patches]/genpatches-2.6/tags/2.6.15-2/4900_speakup-20060103.patch
Gentoo

Contents of /genpatches-2.6/tags/2.6.15-2/4900_speakup-20060103.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 259 - (show annotations) (download)
Wed Jan 11 21:46:01 2006 UTC (8 years, 3 months ago) by dsd
File size: 361657 byte(s)
2.6.15-2 release
1 diff -urNpX dontdiff linux-2.6.15/arch/arm/Kconfig linux-dsd/arch/arm/Kconfig
2 --- linux-2.6.15/arch/arm/Kconfig 2006-01-03 17:42:26.000000000 +0000
3 +++ linux-dsd/arch/arm/Kconfig 2006-01-03 17:54:15.000000000 +0000
4 @@ -741,6 +741,7 @@ source "drivers/mfd/Kconfig"
5 source "drivers/media/Kconfig"
6
7 source "drivers/video/Kconfig"
8 +source "drivers/char/speakup/Kconfig"
9
10 source "sound/Kconfig"
11
12 diff -urNpX dontdiff linux-2.6.15/Documentation/speakup/DefaultKeyAssignments linux-dsd/Documentation/speakup/DefaultKeyAssignments
13 --- linux-2.6.15/Documentation/speakup/DefaultKeyAssignments 1970-01-01 01:00:00.000000000 +0100
14 +++ linux-dsd/Documentation/speakup/DefaultKeyAssignments 2006-01-03 17:54:15.000000000 +0000
15 @@ -0,0 +1,46 @@
16 +This file is intended to give you an overview of the default keys used
17 +by speakup for it's review functions. You may change them to be
18 +anything you want but that will take some familiarity with key
19 +mapping.
20 +
21 +We have remapped the insert or zero key on the keypad to act as a
22 +shift key. Well, actually as an altgr key. So in the following list
23 +InsKeyPad-period means hold down the insert key like a shift key and
24 +hit the keypad period.
25 +
26 +KeyPad-8 Say current Line
27 +InsKeyPad-8 say from top of screen to reading cursor.
28 +KeyPad-7 Say Previous Line (UP one line)
29 +KeyPad-9 Say Next Line (down one line)
30 +KeyPad-5 Say Current Word
31 +InsKeyPad-5 Spell Current Word
32 +KeyPad-4 Say Previous Word (left one word)
33 +InsKeyPad-4 say from left edge of line to reading cursor.
34 +KeyPad-6 Say Next Word (right one word)
35 +InsKeyPad-6 Say from reading cursor to right edge of line.
36 +KeyPad-2 Say Current Letter
37 +InsKeyPad-2 say current letter phonetically
38 +KeyPad-1 Say Previous Character (left one letter)
39 +KeyPad-3 Say Next Character (right one letter)
40 +KeyPad-plus Say Entire Screen
41 +InsKeyPad-plus Say from reading cursor line to bottom of screen.
42 +KeyPad-Minus Park reading cursor (toggle)
43 +InsKeyPad-minus Say character hex and decimal value.
44 +KeyPad-period Say Position (current line, position and console)
45 +InsKeyPad-period say colour attributes of current position.
46 +InsKeyPad-9 Move reading cursor to top of screen (insert pgup)
47 +InsKeyPad-3 Move reading cursor to bottom of screen (insert pgdn)
48 +InsKeyPad-7 Move reading cursor to left edge of screen (insert home)
49 +InsKeyPad-1 Move reading cursor to right edge of screen (insert end)
50 +ControlKeyPad-1 Move reading cursor to last character on current line.
51 +KeyPad-Enter Shut Up (until another key is hit) and sync reading cursor
52 +InsKeyPad-Enter Shut Up (until toggled back on).
53 +InsKeyPad-star n<x|y> go to line (y) or column (x). Where 'n' is any
54 + allowed value for the row or column for your current screen.
55 +KeyPad-/ Mark and Cut screen region.
56 +InsKeyPad-/ Paste screen region into any console.
57 +
58 +Hitting any key while speakup is outputting speech will quiet the
59 +synth until it has caught up with what is being printed on the
60 +console.
61 +
62 diff -urNpX dontdiff linux-2.6.15/Documentation/speakup/INSTALLATION linux-dsd/Documentation/speakup/INSTALLATION
63 --- linux-2.6.15/Documentation/speakup/INSTALLATION 1970-01-01 01:00:00.000000000 +0100
64 +++ linux-dsd/Documentation/speakup/INSTALLATION 2006-01-03 17:54:15.000000000 +0000
65 @@ -0,0 +1,108 @@
66 +This document assumes you have had some experience with kernel
67 +compilation and installation. If you have not, I recommend you get
68 +the kernel source and read the README and various documents in the
69 +linux/Documentation directory. In particular the Changes file to make
70 +sure you have the appropriate utilities needed for installing a 2.2.xx
71 +or 2.4xx kernel. It isn't as difficult as you might think. The
72 +kernel README is intimidating the first time but once you get the
73 +steps down, it's really pretty easy. Getting through the "make
74 +config" is the tedious bit.
75 +
76 +The first thing to do is to place a copy of the tarball in the /usr/src
77 +directory which is the directory the linux tree is located in as well.
78 +Next untar speakup by typing:
79 +
80 +tar zxf speakup-1.00.tar.gz
81 +cd speakup-1.00
82 +./install
83 +
84 +Note the dot-slash before the install. This will copy the speakup
85 +directory to the kernel tree and apply the various patches and
86 +components to the appropriate kernel files. Depending on how
87 +experienced you are with kernel compiling and hacking will determine
88 +whether you should bother looking at any failed patches. If this
89 +happens, you should probably write to the speakup mailing list for
90 +help or myself.
91 +
92 +If all of the patch hunks apply successfully then just continue with
93 +the standard steps to compile the kernel with:
94 +
95 +make mrproper
96 +make config
97 +
98 +When you get to the section console speech output, answer 'y' to the
99 +CONFIG_SPEAKUP prompt. You will be given a submenu with the list of
100 +synthesizers which are currently supported. You can include as many
101 +synths in the kernel as you wish but remember each one takes up kernel
102 +space. You can only choose one of the synths as the default or none,
103 +so just type dtlk or whatever is the correct string for the
104 +synthesizer you have. You will also be asked if you wish to build-in
105 +a speakup key map. If you do not say 'y' to this option you will need
106 +to load a speakup map at boot time with whichever mechanism your
107 +distribution uses for loading key maps.
108 +
109 +We have placed the speakup configuration options in make config just
110 +after the vga console choice. For the DoubleTalk PC driver included
111 +by Jim Van Zandt. I recommend you say no to that option. I have not
112 +tried configuring them both in, but I wouldn't be at all surprised if
113 +it didn't work.
114 +
115 +If all goes well up to this point you can continue with the compiling
116 +process by doing:
117 +
118 +make dep >dep.file 2>&1 &
119 +make bzImage >cc.file 2>&1 &
120 +make modules >mod.file 2>&1 &
121 +
122 +I always redirect output to the files dep.file and cc.file so I can
123 +look over the compilation record to make sure there are no errors and
124 +warnings.
125 +
126 +Okay, you are ready to install the newly compiled kernel. Make sure
127 +you make an linux.old entry in your lilo.conf file so you can recover
128 +if it blows up. next as root run "make modules_install" to install
129 +whatever modules you compiled and move the bzImage from
130 +/usr/src/linux/arch/i386/boot to wherever your kernel lives. Also
131 +move the System.map from /usr/src/linux to where your System.map
132 +lives. On our systems we use debian so we create an vmlinuz-speakup
133 +and System.map-speakup in our /boot directory and set the symbolic
134 +links vmlinuz and System.map in the root (/) directory to point to the
135 +images. Now type lilo to tell lilo to build the new booter file and
136 +install it.
137 +
138 +As of version 0.07, the keymap for speakup is automatically built in
139 +at compile time. If you have other keymaps installed at boot time,
140 +you might want to consider removing them before you reboot the system.
141 +
142 +If everything has gone OK up until now, cross your fingers and type:
143 +
144 +shutdown -r now
145 +
146 +Your system should start talking to you as soon as it starts booting.
147 +It will talk and talk and ... well, you might want to hit the
148 +keypad-enter key to tell it to shut up. You should also read the
149 +DefaultKeyAssignments file to learn the various review functions
150 +available.
151 +
152 +As of v-0.10 the speakup configuration options are in the
153 +/proc/speakup subtree. The individual options should be fairly
154 +obvious by their names such as rate, volume, punc_level and so forth.
155 +You can manipulate them by cat'ing or echoing new values to them such
156 +as:
157 +
158 +echo 9 >/proc/speakup/rate
159 +
160 +You can see what the current values are by cat'ing those files to the console:
161 +
162 +cat /proc/speakup/rate
163 +
164 +I have probably managed to overlook a whole whack of things because
165 +this is the, enter version number here, draft. Don't worry we'll get
166 +it right eventually. If you like the package you really should get on
167 +the mailing list and start participating in it's development.
168 +
169 + Kirk
170 +
171 +email: kirk@braille.uwo.ca
172 +phone: (519) 679-6845 (home)
173 +
174 diff -urNpX dontdiff linux-2.6.15/Documentation/speakup/keymap-tutorial linux-dsd/Documentation/speakup/keymap-tutorial
175 --- linux-2.6.15/Documentation/speakup/keymap-tutorial 1970-01-01 01:00:00.000000000 +0100
176 +++ linux-dsd/Documentation/speakup/keymap-tutorial 2006-01-03 17:54:15.000000000 +0000
177 @@ -0,0 +1,140 @@
178 + Speakup Keymap Tutorial
179 +
180 +This is meant to be a basic tutorial on how to change the Linux keymap
181 +file to assign speakup review functions to desired keys. It is not
182 +intended to be a replacement for the loadkeys(8) or keymap(5) man
183 +pages.
184 +
185 +The basic lay-out of the keymap file is a series of lines with the
186 +following fields. The keyword keycode indicates this is the start of
187 +a new key assignment. It is then followed by a number which
188 +represents the actual key on the keyboard. That number is followed by
189 +the equals '=' operator and finally a list of keywords representing
190 +key names such as keypad5. Each line can have quite a few key
191 +functions on it. They are interpreted by loadkeys in order and
192 +assigned to key shift states depending on the order they are
193 +encountered. So for example, the first value after the equals is the
194 +keys unshifted state, while the second is the keys shifted state. If
195 +you wish to learn the order they are interpreted in read the
196 +loadkeys(8) and keymap(5) man pages.
197 +
198 +You can have subsequent lines which are indented and start with
199 +another keyword for the various shifted states. This way you can
200 +assign some of the states without having to specify them all in order
201 +up until you get to the one you want to assign.
202 +
203 +In speakup, we have assigned the insert key on the number pad to the
204 +altgr keyword. This is not required; you could choose any other
205 +shifted state keyword. We used altgr because it typically represents
206 +the right hand alt key. In Linux each shift key is separate and
207 +independent, so the left shift and the right shift keys are not
208 +necessarily the same. The altgr key is not really used for anything
209 +important, so we steel it.
210 +
211 +Here are the default key assignments for the number eight on the
212 +keypad:
213 +
214 +keycode 72 = KP_8
215 + alt keycode 72 = Ascii_8
216 +
217 +As you can see, the first line starts with keycode followed by 72
218 +which is the actual number assigned to the key when the keyboard port
219 +is read. The KP_8 after the equal sign, is the symbolic representation
220 +of the function called when that key is hit.
221 +
222 +The second line is the same format except it starts with the keyword
223 +alt which is indented. That means that the function at the end of
224 +that line Ascii_8 is applied to the alt-shifted eight key.
225 +
226 +Now here are the speakup assignments for that key:
227 +
228 +keycode 72 = 0x0d0a
229 + altgr keycode 72 = 0x0d20
230 +#keycode 72 = KP_8
231 + alt keycode 72 = Ascii_8
232 +
233 +Notice that the only thing which has changed on the first line is the
234 +function called when the key is struck. It is a hexadecimal number
235 +identifying the function called in a look up table. It is not a
236 +symbolic representation yet because that means we need to change the
237 +loadkeys program to understand our symbolic names. We will do this in
238 +the future but for now it is more expedient to just use the table
239 +indices. You will find a table at the bottom of this document
240 +listing the review functions and their corresponding hex lookups.
241 +
242 +The 0x0d0a in the first line above is speakup's say line function.
243 +The second line ends with 0x0d20 which is speakup's read from top of
244 +screen to reading cursor line.
245 +
246 +The third line is the original key assignment commented out with a
247 +number-sign '#' at the beginning. I do that so I can easily find the
248 +keys I want to affect by symbolic name. Otherwise I would need to
249 +keep a look up table for all the keycodes. I recommend you do this as
250 +well or you'll be very sorry at some point in the future.
251 +
252 +The forth line is just the standard key assignment for the left hand
253 +alt key.
254 +
255 +Now let's say we want to design a different keyboard layout. I'll use
256 +an example for the JAWS style keypad because I've specifically been
257 +asked to help with that. JAWS uses the eight on the keypad to move up
258 +a line or the speakup function to read previous line. JAWS also uses
259 +the keypad_8 key in a shifted mode to read the current line. I
260 +apologize if these are not quite right. It has been a long time since
261 +I used JAWS. So we would have the following two lines:
262 +
263 +keycode 72 = 0x0d0b
264 + altgr keycode 72 = 0x0d0a
265 +
266 +The hex value 0x0d0b in the first line is speakup's SAY_PREVIOUS_LINE
267 +function. The 0x0d0a in the second line is the same say_line function
268 +as we had earlier. So when the number eight is hit on the keypad
269 +speakup will read the previous line and when the number eight is
270 +shifted with the insert key on the keypad it will read the current
271 +line.
272 +
273 +As you can tell, it is not really very difficult to reassign the keys
274 +to different review functions.
275 +
276 +Once you have carefully edited the keymap file, called default.map in
277 +the speakup distribution, you copy it into the /etc/kbd directory.
278 +Make sure you back up the original default.map from that directory
279 +first, if there is one. Then you run loadkeys to load the new map
280 +into the kernel:
281 +
282 +loadkeys /etc/kbd/default.map
283 +
284 +If you wish to build your new keyboard lay-out into the kernel, after
285 +testing it, copy the default.map file into the drivers/char directory,
286 +with the name defkeymap.map, of your Linux source tree. Then rm the
287 +defkeymap.c file and recompile the kernel. Because there is no
288 +defkeymap.c `make' will rebuild it on the next compile.
289 +
290 +Here is a list of the available speakup review functions at this point
291 +in time.
292 +
293 +SAY_CHAR 0x0d04 /* say this character */
294 +SAY_PREV_CHAR 0x0d05 /* say character left of this char */
295 +SAY_NEXT_CHAR 0x0d06 /* say char right of this char */
296 +SAY_WORD 0x0d07 /* say this word under reading cursor */
297 +SAY_PREV_WORD 0x0d08
298 +SAY_NEXT_WORD 0x0d09
299 +SAY_LINE 0x0d0a /* say this line */
300 +SAY_PREV_LINE 0x0d0b /* say line above this line */
301 +SAY_NEXT_LINE 0x0d0c
302 +TOP_EDGE 0x0d0d /* move to top edge of screen */
303 +BOTTOM_EDGE 0x0d0e
304 +LEFT_EDGE 0x0d0f
305 +RIGHT_EDGE 0x0d10
306 +SAY_PHONETIC_CHAR 0x0d11 /* say this character phonetically */
307 +SPELL_WORD 0x0d12 /* spell this word letter by letter */
308 +SAY_SCREEN 0x0d14
309 +SAY_POSITION 0x0d1b
310 +SPEECH_OFF 0x0d1c
311 +SAY_ATTRIBUTES 0x0d1d
312 +SPEAKUP_PARKED 0x0d1e
313 +SAY_FROM_TOP 0x0d20
314 +SAY_TO_BOTTOM 0x0d21
315 +SAY_FROM_LEFT 0x0d22
316 +SAY_TO_RIGHT 0x0d23
317 +
318 diff -urNpX dontdiff linux-2.6.15/Documentation/speakup/README linux-dsd/Documentation/speakup/README
319 --- linux-2.6.15/Documentation/speakup/README 1970-01-01 01:00:00.000000000 +0100
320 +++ linux-dsd/Documentation/speakup/README 2006-01-03 17:54:15.000000000 +0000
321 @@ -0,0 +1,98 @@
322 +Welcome to the speakup project for the Speakup speech package for Linux.
323 +
324 +Speakup is written by Kirk Reiser and Andy Berdan. It is licensed
325 +under the GPL. If you don't already know, the GPL stands for the GNU
326 +General Public License. Which basically states that this code is free to
327 +copy, modify and distribute to anyone interested in playing with it.
328 +The one thing you may not do is turn any part of it into proprietary
329 +or commercial code without the permission of the author. That's me.
330 +
331 +If you are interested in being involved with the development of speech
332 +output for Linux you can subscribe to the Speakup mailing list by
333 +sending a message to speakup-request@braille.uwo.ca with the line: subscribe. You can also subscribe by going to the speakup web page and following the links at http://www.linux-speakup.org.
334 +
335 +We are at a very early stage in the development of this package.
336 +Hopefully changes will happen often and many. The current files in
337 +this directory are:
338 +
339 +DefaultKeyAssignments # speakup's default review keys
340 +INSTALLATION # for installing speakup from the tar ball.
341 +README # this file
342 +keymap-tutorial # a tutorial on how to layout the keyboard
343 +
344 +Read the INSTALLATION file to learn how to apply the patches and the
345 +default.map for the keyboard. You should also read the Changes file.
346 +It really has any new things I've added since last time.
347 +
348 +There is no documentation in any of these files to instruct you what
349 +to do if something goes wrong with the patching or compilation. If
350 +you would like that information you will need to subscribe to the
351 +mailing list and ask for help, or write me kirk@braille.uwo.ca for
352 +help. I suggest the mailing list because I will probably tire quickly
353 +of answering the same questions over and over. You could always
354 +decide to dig-in and take on the task, and write documentation to help
355 +others.
356 +
357 +There also is a speakup reflector for the Speak Freely package, which
358 +many of us hang out on and discuss all sorts of topics from speakup
359 +problems to ALSA driver installation and just about anything else
360 +you'd like to talk about. The reflector is at lwl.braille.uwo.ca:4074
361 +with it's lwl page at lwl.braille.uwo.ca/speakup.html. Come and join
362 +us, it's fun!
363 +
364 +Acknowledgements:
365 +
366 +I am really very new at kernel hacking and screen review package
367 +writing, so I have depended heavily on other folks kindness to help me
368 +a long. No doubt I will continue to abuse them freely and others
369 +before this is a really good speech solution for Linux. (Oh Well!,
370 +somebody's got to do it.)
371 +
372 +Theodore Ts'o. He gave me a good discussion of unicode and UTF and
373 +the like. He doesn't even remember writing me about it.
374 +
375 +Alan Cox. He has answered many questions about scheduling and wait
376 +queues and timers along with code fragments and so on. I just wish I
377 +understood it all totally. He has also helped immensely in moving
378 +this package toward inclusion in the standard kernel tree. (Maybe next
379 +release!)
380 +
381 +Martin Mares. He pointed me in the right direction to figuring out
382 +the colour attributes and other useful tidbits.
383 +
384 +Paul McDermott. He really is the catalyst for me to actually get
385 +this all working. Besides I like seeing him bounce around and get all
386 +excited every time I have something new working.
387 +
388 +John Covici, He was the first person to actually attempt writing
389 +another synthesizer driver for speakup. It was the Speakout driver so
390 +it was also the first serial driver.
391 +
392 +Brian Borowski, he was the first person to actually write a speakup
393 +function other than Andy and I.
394 +
395 +Jim Danley, he has more or less become my main man in helping test
396 +code, add new features, bounce ideas off and generally become a good
397 +friend.
398 +
399 +Matt Campbell, he basically rewrote the drivers to be able to include
400 +all synths in the kernel at the same time. The distribution
401 +maintainers appreciate him a lot as well.
402 +
403 +Gene Collins, he was very helpful debugging the current release prior
404 +to its public showing. He has also worked hard educating others on
405 +the list and writing the ALSA mini howto.
406 +
407 +I would also like to really thank the folks that handle the
408 +distribution packages. I and many other people would not find access
409 +to speakup nearly so convenient without their efforts. They include
410 +Bill Acker, Tom Moore, Matt Campbell, Joe Norton and Joshua Lambert.
411 +
412 +There are probably many more I am forgetting right now. I guess I'll
413 +just have to add you all later.
414 +
415 +
416 +Happy Hacking!
417 +
418 + Kirk
419 +
420 diff -urNpX dontdiff linux-2.6.15/Documentation/speakup/spkguide.txt linux-dsd/Documentation/speakup/spkguide.txt
421 --- linux-2.6.15/Documentation/speakup/spkguide.txt 1970-01-01 01:00:00.000000000 +0100
422 +++ linux-dsd/Documentation/speakup/spkguide.txt 2006-01-03 17:54:15.000000000 +0000
423 @@ -0,0 +1,1279 @@
424 +
425 +The Speakup User's Guide
426 +For Speakup 2.0 and Later
427 +By Gene Collins
428 +Last modified on Tue Mar 29 10:54:19 2005
429 +Document version 1.0
430 +
431 +Copyright (c) 2005 Gene Collins
432 +
433 +Permission is granted to copy, distribute and/or modify this document
434 +under the terms of the GNU Free Documentation License, Version 1.2 or
435 +any later version published by the Free Software Foundation; with no
436 +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
437 +copy of the license is included in the section entitled "GNU Free
438 +Documentation License".
439 +
440 +Preface
441 +
442 +The purpose of this document is to familiarize users with the user
443 +interface to Speakup, a Linux Screen Reader. If you need instructions
444 +for installing or obtaining Speakup, visit the web site at
445 +http://linux-speakup.org/. Speakup is a set of patches to the standard
446 +Linux kernel source tree. It can be built as a series of modules, or as
447 +a part of a monolithic kernel. These details are beyond the scope of
448 +this manual, but the user may need to be aware of the module
449 +capabilities, depending on how your system administrator has installed
450 +Speakup. If Speakup is built as a part of a monolithic kernel, and the
451 +user is using a hardware synthesizer, then Speakup will be able to
452 +provide speech access from the time the kernel is loaded, until the time
453 +the system is shutdown. This means that if you have obtained Linux
454 +installation media for a distribution which includes Speakup as a part
455 +of its kernel, you will be able, as a blind person, to install Linux
456 +with speech access unaided by a sighted person. Again, these details
457 +are beyond the scope of this manual, but the user should be aware of
458 +them. See the web site mentioned above for further details.
459 +
460 +1. Starting Speakup
461 +
462 +If your system administrator has installed Speakup to work with your
463 +specific synthesizer by default, then all you need to do to use Speakup
464 +is to boot your system, and Speakup should come up talking. This
465 +assumes of course that your synthesizer is a supported hardware
466 +synthesizer, and that it is either installed in or connected to your
467 +system, and is if necessary powered on.
468 +
469 +It is possible, however, that Speakup may have been compiled into the
470 +kernel with no default synthesizer. It is even possible that your
471 +kernel has been compiled with support for some of the supported
472 +synthesizers and not others. If you find that this is the case, and
473 +your synthesizer is supported but not available, complain to the person
474 +who compiled and installed your kernel. Or better yet, go to the web
475 +site, and learn how to patch Speakup into your own kernel source, and
476 +build and install your own kernel.
477 +
478 +If your kernel has been compiled with Speakup, and has no default
479 +synthesizer set, or you would like to use a different synthesizer than
480 +the default one, then you may issue the following command at the boot
481 +prompt of your boot loader.
482 +
483 +linux speakup_synth=ltlk
484 +
485 +This command would tell Speakup to look for and use a LiteTalk or
486 +DoubleTalk LT at boot up. You may replace the ltlk synthesizer keyword
487 +with the keyword for whatever synthesizer you wish to use. The
488 +speakup_synth parameter will accept the following keywords, provided
489 +that support for the related synthesizers has been built into the
490 +kernel.
491 +
492 +acntsa -- Accent SA
493 +acntpc -- Accent PC
494 +apolo -- Apolo
495 +audptr -- Audapter
496 +bns -- Braille 'n Speak
497 +dectlk -- DecTalk Express (old and new, db9 serial only)
498 +decext -- DecTalk (old) External
499 +dtlk -- DoubleTalk PC
500 +keypc -- Keynote Gold PC
501 +ltlk -- DoubleTalk LT, LiteTalk, or external Tripletalk (db9 serial only)
502 +spkout -- Speak Out
503 +txprt -- Transport
504 +
505 +Note: Speakup does * NOT * support usb connections! Speakup also does *
506 +NOT * support the internal Tripletalk!
507 +
508 +Speakup does support two other synthesizers, but because they work in
509 +conjunction with other software, they must be loaded as modules after
510 +their related software is loaded, and so are not available at boot up.
511 +These are as follows:
512 +
513 +decpc -- DecTalk PC (not available at boot up)
514 +sftsyn -- One of several software synthesizers (not available at boot up)
515 +
516 +See the sections on loading modules and software synthesizers later in
517 +this manual for further details. It should be noted here that the
518 +speakup_synth boot parameter will have no effect if Speakup has been
519 +compiled as modules. In order for Speakup modules to be loaded during
520 +the boot process, such action must be configured by your system
521 +administrator. This will mean that you will hear some, but not all, of
522 +the bootup messages.
523 +
524 +2. Basic operation
525 +
526 +Once you have booted the system, and if necessary, have supplied the
527 +proper bootup parameter for your synthesizer, Speakup will begin
528 +talking as soon as the kernel is loaded. In fact, it will talk a lot!
529 +It will speak all the boot up messages that the kernel prints on the
530 +screen during the boot process. This is because Speakup is not a
531 +separate screen reader, but is actually built into the operating
532 +system. Since almost all console applications must print text on the
533 +screen using the kernel, and must get their keyboard input through the
534 +kernel, they are automatically handled properly by Speakup. There are a
535 +few exceptions, but we'll come to those later.
536 +
537 +Note: In this guide I will refer to the numeric keypad as the keypad.
538 +This is done because the speakupmap.map file referred to later in this
539 +manual uses the term keypad instead of numeric keypad. Also I'm lazy
540 +and would rather only type one word. So keypad it is. Got it? Good.
541 +
542 +Most of the Speakup review keys are located on the keypad at the far
543 +right of the keyboard. The numlock key should be off, in order for these
544 +to work. If you toggle the numlock on, the keypad will produce numbers,
545 +which is exactly what you want for spreadsheets and such. For the
546 +purposes of this guide, you should have the numlock turned off, which is
547 +its default state at bootup.
548 +
549 +You probably won't want to listen to all the bootup messages every time
550 +you start your system, though it's a good idea to listen to them at
551 +least once, just so you'll know what kind of information is available to
552 +you during the boot process. You can always review these messages after
553 +bootup with the command:
554 +
555 +dmesg | more
556 +
557 +In order to speed the boot process, and to silence the speaking of the
558 +bootup messages, just press the keypad enter key. This key is located
559 +in the bottom right corner of the keypad. Speakup will shut up and stay
560 +that way, until you press another key.
561 +
562 +You can check to see if the boot process has completed by pressing the 8
563 +key on the keypad, which reads the current line. This also has the
564 +effect of starting Speakup talking again, so you can press keypad enter
565 +to silence it again if the boot process has not completed.
566 +
567 +When the boot process is complete, you will arrive at a "login" prompt.
568 +At this point, you'll need to type in your user id and password, as
569 +provided by your system administrator. You will hear Speakup speak the
570 +letters of your user id as you type it, but not the password. This is
571 +because the password is not displayed on the screen for security
572 +reasons. This has nothing to do with Speakup, it's a Linux security
573 +feature.
574 +
575 +Once you've logged in, you can run any Linux command or program which is
576 +allowed by your user id. Normal users will not be able to run programs
577 +which require root privileges.
578 +
579 +When you are running a program or command, Speakup will automatically
580 +speak new text as it arrives on the screen. You can at any time silence
581 +the speech with keypad enter, or use any of the Speakup review keys.
582 +
583 +Here are some basic Speakup review keys, and a short description of what
584 +they do.
585 +
586 +keypad 1 -- read previous character
587 +keypad 2 -- read current character (pressing keypad 2 twice rapidly will speak
588 + the current character phonetically)
589 +keypad 3 -- read next character
590 +keypad 4 -- read previous word
591 +keypad 5 -- read current word (press twice rapidly to spell the current word)
592 +keypad 6 -- read next word
593 +keypad 7 -- read previous line
594 +keypad 8 -- read current line (press twice rapidly to hear how much the
595 + text on the current line is indented)
596 +keypad 9 -- read next line
597 +keypad period -- speak current cursor position and announce current
598 + virtual console
599 +
600 +It's also worth noting that the insert key on the keypad is mapped
601 +as the speakup key. Instead of pressing and releasing this key, as you
602 +do under DOS or Windows, you hold it like a shift key, and press other
603 +keys in combination with it. For example, repeatedly holding keypad
604 +insert, from now on called speakup, and keypad enter will toggle the
605 +speaking of new text on the screen on and off. This is not the same as
606 +just pressing keypad enter by itself, which just silences the speech
607 +until you hit another key. When you hit speakup plus keypad enter,
608 +Speakup will say, "You turned me off.", or "Hey, that's better." When
609 +Speakup is turned off, no new text on the screen will be spoken. You
610 +can still use the reading controls to review the screen however.
611 +
612 +3. Using the Speakup Help System
613 +
614 +Speakup has a help system, which is compiled as a module. It is loaded
615 +automatically whenever the Speakup help system is invoked for the first
616 +time, and remains loaded after that, until speakup is unloaded. Note
617 +that if speakup was compiled into a monolithic kernel on your system,
618 +you will not be able to unload Speakup from your kernel. If you try to
619 +use the help system, and find that it is unavailable, then your system
620 +administrator has not installed the Speakup help module, which is called
621 +speakup_help. Complain to your system administrator about this.
622 +
623 +In order to enter the Speakup help system, press and hold the speakup
624 +key (remember that this is the keypad insert key), and press the f1 key.
625 +You will hear the message:
626 +
627 +"Press space to leave help, cursor up or down to scroll, or a letter to
628 +go to commands in list."
629 +
630 +When you press the spacebar to leave the help system, you will hear:
631 +
632 +"Leaving help."
633 +
634 +While you are in the Speakup help system, you can scroll up or down
635 +through the list of available commands using the cursor keys. The list
636 +of commands is arranged in alphabetical order. If you wish to jump to
637 +commands in a specific part of the alphabet, you may press the letter of
638 +the alphabet you wish to jump to.
639 +
640 +You can also just explore by typing keyboard keys. Pressing keys will
641 +cause Speakup to speak the command associated with that key. For
642 +example, if you press the keypad 8 key, you will hear:
643 +
644 +"Keypad 8 is line, say current."
645 +
646 +You'll notice that some commands do not have keys assigned to them.
647 +This is because they are very infrequently used commands, and are also
648 +accessible through the proc system. We'll discuss the proc system later
649 +in this manual.
650 +
651 +You'll also notice that some commands have two keys assigned to them.
652 +This is because Speakup has a built in set of alternative key bindings
653 +for laptop users. The alternate speakup key is the caps lock key. You
654 +can press and hold the caps lock key, while pressing an alternate
655 +speakup command key to activate the command. On most laptops, the
656 +numeric keypad is defined as the keys in the j k l area of the keyboard.
657 +
658 +There is usually a function key which turns this keypad function on and
659 +off, and some other key which controls the numlock state. Toggling the
660 +keypad functionality on and off can become a royal pain. So, Speakup
661 +gives you a simple way to get at an alternative set of key mappings for
662 +your laptop. These are also available by default on desktop systems,
663 +because Speakup does not know whether it is running on a desktop or
664 +laptop. So you may choose which set of Speakup keys to use. Some
665 +system administrators may have chosen to compile Speakup for a desktop
666 +system without this set of alternate key bindings, but these details are
667 +beyond the scope of this manual. To use the caps lock for its normal
668 +purpose, hold the shift key while toggling the caps lock on and off. We
669 +should note here, that holding the caps lock key and pressing the z key
670 +will toggle the alternate j k l keypad on and off.
671 +
672 +4. Keys and Their Assigned Commands
673 +
674 +In this section, we'll go through a list of all the speakup keys and
675 +commands. You can also get a list of commands and assigned keys from
676 +the help system.
677 +
678 +The following list was taken from the speakupmap.map file. Key
679 +assignments are on the left of the equal sign, and the associated
680 +Speakup commands are on the right. The designation "spk" means to press
681 +and hold the speakup key, a.k.a. keypad insert, a.k.a. caps lock, while
682 +pressing the other specified key.
683 +
684 +spk key_f9 = punc_level_dec
685 +spk key_f10 = punc_level_inc
686 +spk key_f11 = reading_punc_dec
687 +spk key_f12 = reading_punc_inc
688 +spk key_1 = vol_dec
689 +spk key_2 = vol_inc
690 +spk key_3 = pitch_dec
691 +spk key_4 = pitch_inc
692 +spk key_5 = rate_dec
693 +spk key_6 = rate_inc
694 +key_kpasterisk = toggle_cursoring
695 +spk key_kpasterisk = speakup_goto
696 +spk key_f1 = speakup_help
697 +spk key_f2 = set_win
698 +spk key_f3 = clear_win
699 +spk key_f4 = enable_win
700 +spk key_f5 = edit_some
701 +spk key_f6 = edit_most
702 +spk key_f7 = edit_delim
703 +spk key_f8 = edit_repeat
704 +shift spk key_f9 = edit_exnum
705 + key_kp7 = say_prev_line
706 +spk key_kp7 = left_edge
707 + key_kp8 = say_line
708 +double key_kp8 = say_line_indent
709 +spk key_kp8 = say_from_top
710 + key_kp9 = say_next_line
711 +spk key_kp9 = top_edge
712 + key_kpminus = speakup_parked
713 +spk key_kpminus = say_char_num
714 + key_kp4 = say_prev_word
715 +spk key_kp4 = say_from_left
716 + key_kp5 = say_word
717 +double key_kp5 = spell_word
718 +spk key_kp5 = spell_phonetic
719 + key_kp6 = say_next_word
720 +spk key_kp6 = say_to_right
721 + key_kpplus = say_screen
722 +spk key_kpplus = say_win
723 + key_kp1 = say_prev_char
724 +spk key_kp1 = right_edge
725 + key_kp2 = say_char
726 +spk key_kp2 = say_to_bottom
727 +double key_kp2 = say_phonetic_char
728 + key_kp3 = say_next_char
729 +spk key_kp3 = bottom_edge
730 + key_kp0 = spk_key
731 + key_kpdot = say_position
732 +spk key_kpdot = say_attributes
733 +key_kpenter = speakup_quiet
734 +spk key_kpenter = speakup_off
735 +key_sysrq = speech_kill
736 + key_kpslash = speakup_cut
737 +spk key_kpslash = speakup_paste
738 +spk key_pageup = say_first_char
739 +spk key_pagedown = say_last_char
740 +key_capslock = spk_key
741 + spk key_z = spk_lock
742 +key_leftmeta = spk_key
743 +ctrl spk key_0 = speakup_goto
744 +spk key_u = say_prev_line
745 +spk key_i = say_line
746 +double spk key_i = say_line_indent
747 +spk key_o = say_next_line
748 +spk key_minus = speakup_parked
749 +shift spk key_minus = say_char_num
750 +spk key_j = say_prev_word
751 +spk key_k = say_word
752 +double spk key_k = spell_word
753 +spk key_l = say_next_word
754 +spk key_m = say_prev_char
755 +spk key_comma = say_char
756 +double spk key_comma = say_phonetic_char
757 +spk key_dot = say_next_char
758 +spk key_n = say_position
759 + ctrl spk key_m = left_edge
760 + ctrl spk key_y = top_edge
761 + ctrl spk key_dot = right_edge
762 +ctrl spk key_p = bottom_edge
763 +spk key_apostrophe = say_screen
764 +spk key_h = say_from_left
765 +spk key_y = say_from_top
766 +spk key_semicolon = say_to_right
767 +spk key_p = say_to_bottom
768 +spk key_slash = say_attributes
769 + spk key_enter = speakup_quiet
770 + ctrl spk key_enter = speakup_off
771 + spk key_9 = speakup_cut
772 +spk key_8 = speakup_paste
773 +shift spk key_m = say_first_char
774 + ctrl spk key_semicolon = say_last_char
775 +
776 +5. The Speakup Proc System
777 +
778 +The Speakup screen reader also creates a speakup subdirectory as a part
779 +of the proc system. You can see these entries by typing the command:
780 +
781 +ls -1 /proc/speakup/*
782 +
783 +If you issue the above ls command, you will get back something like
784 +this:
785 +
786 +/proc/speakup/attrib_bleep
787 +/proc/speakup/bell_pos
788 +/proc/speakup/bleep_time
789 +/proc/speakup/bleeps
790 +/proc/speakup/caps_start
791 +/proc/speakup/caps_stop
792 +/proc/speakup/characters
793 +/proc/speakup/cursor_time
794 +/proc/speakup/delay_time
795 +/proc/speakup/delimiters
796 +/proc/speakup/ex_num
797 +/proc/speakup/freq
798 +/proc/speakup/full_time
799 +/proc/speakup/jiffy_delta
800 +/proc/speakup/key_echo
801 +/proc/speakup/keymap
802 +/proc/speakup/no_interrupt
803 +/proc/speakup/pitch
804 +/proc/speakup/punc_all
805 +/proc/speakup/punc_level
806 +/proc/speakup/punc_most
807 +/proc/speakup/punc_some
808 +/proc/speakup/punct
809 +/proc/speakup/rate
810 +/proc/speakup/reading_punc
811 +/proc/speakup/repeats
812 +/proc/speakup/say_control
813 +/proc/speakup/say_word_ctl
814 +/proc/speakup/silent
815 +/proc/speakup/spell_delay
816 +/proc/speakup/synth_direct
817 +/proc/speakup/synth_name
818 +/proc/speakup/tone
819 +/proc/speakup/trigger_time
820 +/proc/speakup/version
821 +/proc/speakup/voice
822 +/proc/speakup/vol
823 +
824 +In addition to using the Speakup hot keys to change such things as
825 +volume, pitch, and rate, you can also echo values to the appropriate
826 +entry in the /proc/speakup directory. This is very useful, since it
827 +lets you control Speakup parameters from within a script. How you
828 +would write such scripts is somewhat beyond the scope of this manual,
829 +but I will include a couple of simple examples here to give you a
830 +general idea of what such scripts can do.
831 +
832 +Suppose for example, that you wanted to control both the punctuation
833 +level and the reading punctuation level at the same time. For
834 +simplicity, we'll call them punc0, punc1, punc2, and punc3. The scripts
835 +might look something like this:
836 +
837 +#!/bin/bash
838 +# punc0
839 +# set punc and reading punc levels to 0
840 +echo 0 >/proc/speakup/punc_level
841 +echo 0 >/proc/speakup/reading_punc
842 +echo Punctuation level set to 0.
843 +
844 +#!/bin/bash
845 +# punc1
846 +# set punc and reading punc levels to 1
847 +echo 1 >/proc/speakup/punc_level
848 +echo 1 >/proc/speakup/reading_punc
849 +echo Punctuation level set to 1.
850 +
851 +#!/bin/bash
852 +# punc2
853 +# set punc and reading punc levels to 2
854 +echo 2 >/proc/speakup/punc_level
855 +echo 2 >/proc/speakup/reading_punc
856 +echo Punctuation level set to 2.
857 +
858 +#!/bin/bash
859 +# punc3
860 +# set punc and reading punc levels to 3
861 +echo 3 >/proc/speakup/punc_level
862 +echo 3 >/proc/speakup/reading_punc
863 +echo Punctuation level set to 3.
864 +
865 +If you were to store these four small scripts in a directory in your
866 +path, perhaps /usr/local/bin, and set the permissions to 755 with the
867 +chmod command, then you could change the default reading punc and
868 +punctuation levels at the same time by issuing just one command. For
869 +example, if you were to execute the punc3 command at your shell prompt,
870 +then the reading punc and punc level would both get set to 3.
871 +
872 +I should note that the above scripts were written to work with bash, but
873 +regardless of which shell you use, you should be able to do something
874 +similar.
875 +
876 +The Speakup proc system also has another interesting use. You can echo
877 +Speakup parameters into the proc system in a script during system
878 +startup, and speakup will return to your preferred parameters every time
879 +the system is rebooted.
880 +
881 +Most of the Speakup proc parameters can be manipulated by a regular user
882 +on the system. However, there are a few parameters that are dangerous
883 +enough that they should only be manipulated by the root user on your
884 +system. There are even some parameters that are read only, and cannot
885 +be written to at all. For example, the version entry in the Speakup
886 +proc system is read only. This is because there is no reason for a user
887 +to tamper with the version number which is reported by Speakup. Doing
888 +an ls -l on /proc/speakup/version will return this:
889 +
890 +-r--r--r-- 1 root root 0 Mar 21 13:46 /proc/speakup/version
891 +
892 +As you can see, the version entry in the Speakup proc system is read
893 +only, is owned by root, and belongs to the root group. Doing a cat of
894 +/proc/speakup/version will display the Speakup version number, like
895 +this:
896 +
897 +cat /proc/speakup/version
898 +Speakup v-2.00 CVS: Thu Oct 21 10:38:21 EDT 2004
899 +synth dtlk version 1.1
900 +
901 +The display shows the Speakup version number, along with the version
902 +number of the driver for the current synthesizer.
903 +
904 +Looking at entries in the Speakup proc system can be useful in many
905 +ways. For example, you might wish to know what level your volume is set
906 +at. You could type:
907 +
908 +cat /proc/speakup/vol
909 +5
910 +
911 +The number five which comes back is the level at which the synthesizer
912 +volume is set at.
913 +
914 +All the entries in the Speakup proc system are readable, some are
915 +writable by root only, and some are writable by everyone. Unless you
916 +know what you are doing, you should probably leave the ones that are
917 +writable by root only alone. Most of the names are self explanatory.
918 +Vol for controlling volume, pitch for pitch, rate for controlling speaking
919 +rate, etc. If you find one you aren't sure about, you can post a query
920 +on the Speakup list.
921 +
922 +6. Changing Synthesizers
923 +
924 +It is possible to change to a different synthesizer while speakup is
925 +running. In other words, it is not necessary to reboot the system
926 +in order to use a different synthesizer. You can simply echo the
927 +synthesizer keyword to the /proc/speakup/synth_name proc entry.
928 +Depending on your situation, you may wish to echo none to the synth_name
929 +proc entry, to disable speech while one synthesizer is disconnected and
930 +a second one is connected in its place. Then echo the keyword for the
931 +new synthesizer into the synth_name proc entry in order to start speech
932 +with the newly connected synthesizer. See the list of synthesizer
933 +keywords in section 1 to find the keyword which matches your synth.
934 +
935 +7. Loading modules
936 +
937 +As mentioned earlier, Speakup can either be completely compiled into the
938 +kernel, with the exception of the help module, or it can be compiled as
939 +a series of modules. When compiled as modules, Speakup will only be
940 +able to speak some of the bootup messages if your system administrator
941 +has configured the system to load the modules at boo time. The modules
942 +can be loaded after the file systems have been checked and mounted, or
943 +from an initrd. There is a third possibility. Speakup can be compiled
944 +with some components built into the kernel, and others as modules. As
945 +we'll see in the next section, this is particularly useful when you are
946 +working with software synthesizers.
947 +
948 +If Speakup is completely compiled as modules, then you must use the
949 +modprobe command to load Speakup. You do this by loading the module for
950 +the synthesizer driver you wish to use. The driver modules are all
951 +named speakup_<keyword>, where <keyword> is the keyword for the
952 +synthesizer you want. So, in order to load the driver for the DecTalk
953 +Express, you would type the following command:
954 +
955 +modprobe speakup_dectlk
956 +
957 +Issuing this command would load the DecTalk Express driver and all other
958 +related Speakup modules necessary to get Speakup up and running.
959 +
960 +To completely unload Speakup, again presuming that it is entirely built
961 +as modules, you would give the command:
962 +
963 +modprobe -r speakup_dectlk
964 +
965 +The above command assumes you were running a DecTalk Express. If you
966 +were using a different synth, then you would substitute its keyword in
967 +place of dectlk.
968 +
969 +But now, suppose we have a situation where the main Speakup component
970 +is built into the kernel, and some or all of the drivers are built as
971 +modules. Since the main part of Speakup is compiled into the kernel, a
972 +partial Speakup proc system has been created which we can take advantage
973 +of by simply echoing the synthesizer keyword into the
974 +/proc/speakup/synth_name proc entry. This will cause the kernel to
975 +automatically load the appropriate driver module, and start Speakup
976 +talking. To switch to another synth, just echo a new keyword to the
977 +synth_name proc entry. For example, to load the DoubleTalk LT driver,
978 +you would type:
979 +
980 +echo ltlk >/proc/speakup/synth_name
981 +
982 +You can use the modprobe -r command to unload driver modules, regardless
983 +of whether the main part of Speakup has been built into the kernel or
984 +not.
985 +
986 +8. Using Software Synthesizers
987 +
988 +Using a software synthesizer requires that some other software be
989 +installed and running on your system. For this reason, software
990 +synthesizers are not available for use at bootup, or during a system
991 +installation process.
992 +
993 +In order to use a software synthesizer, you must have a package called
994 +Speech Dispatcher running on your system, and it must be configured to
995 +work with one of its supported software synthesizers.
996 +
997 +Two open source synthesizers you might use are Flite and Festival. You
998 +might also choose to purchase the Software DecTalk from Fonix Sales Inc.
999 +If you run a google search for Fonix, you'll find their web site.
1000 +
1001 +You can obtain a copy of Speech Dispatcher from free(b)soft at
1002 +http://www.freebsoft.org/. Follow the installation instructions that
1003 +come with Speech Dispatcher in order to install and configure Speech
1004 +Dispatcher. You can check out the web site for your Linux distribution
1005 +in order to get a copy of either Flite or Festival. Your Linux
1006 +distribution may also have a precompiled Speech Dispatcher package.
1007 +
1008 +Once you've installed, configured, and tested Speech Dispatcher with your
1009 +chosen software synthesizer, you still need one more piece of software
1010 +in order to make things work. You need a package called speechd-up.
1011 +You get it from the free(b)soft web site mentioned above. After you've
1012 +compiled and installed speechd-up, you are almost ready to begin using
1013 +your software synthesizer.
1014 +
1015 +Before you can use a software synthesizer, you must have created the
1016 +/dev/softsynth device. If you have not already done so, issue the
1017 +following commands as root:
1018 +
1019 +cd /dev
1020 +mknod softsynth c 10 26
1021 +
1022 +While we are at it, we might just as well create the /dev/synth device,
1023 +which can be used to let user space programs send information to your
1024 +synthesizer. To create /dev/synth, change to the /dev directory, and
1025 +issue the following command as root:
1026 +
1027 +mknod synth c 10 25
1028 +
1029 +Now you can begin using your software synthesizer. In order to do so,
1030 +echo the sftsyn keyword to the synth_name proc entry like this:
1031 +
1032 +echo sftsyn >/proc/speakup/synth_name
1033 +
1034 +Next run the speechd_up command like this:
1035 +
1036 +speechd_up &
1037 +
1038 +Your synth should now start talking, and you should be able to adjust
1039 +the pitch, rate, etc.
1040 +
1041 +In this section, we have assumed that your copy of Speakup was compiled
1042 +with the speakup_sftsyn component either built into the kernel, or
1043 +compiled as a module.
1044 +
1045 +9. Using The DecTalk PC Card
1046 +
1047 +The DecTalk PC card is an ISA card that is inserted into one of the ISA
1048 +slots in your computer. It requires that the DecTalk PC software be
1049 +installed on your computer, and that the software be loaded onto the
1050 +Dectalk PC card before it can be used.
1051 +
1052 +You can get the dec_pc.tgz file from the linux-speakup.org site. The
1053 +dec_pc.tgz file is in the ~ftp/pub/linux/speakup directory.
1054 +
1055 +After you have downloaded the dec_pc.tgz file, untar it in your home
1056 +directory, and read the Readme file in the newly created dec_pc
1057 +directory.
1058 +
1059 +The easiest way to get the software working is to copy the entire dec_pc
1060 +directory into /user/local/lib. To do this, su to root in your home
1061 +directory, and issue the command:
1062 +
1063 +cp dec_pc /usr/local/lib
1064 +
1065 +You will need to copy the dtload command from the dec_pc directory to a
1066 +directory in your path. Either /usr/bin or /usr/local/bin is a good
1067 +choice.
1068 +
1069 +You can now run the dtload command in order to load the DecTalk PC
1070 +software onto the card. After you have done this, echo the decpc
1071 +keyword to the synth_name entry in the proc system like this:
1072 +
1073 +echo decpc >/proc/speakup/synth_name
1074 +
1075 +Your DecTalk PC should start talking, and then you can adjust the pitch,
1076 +rate, volume, voice, etc. The voice entry in the Speakup proc system
1077 +will accept a number from 0 through 7 for the DecTalk PC synthesizer,
1078 +which will give you access to some of the DecTalk voices.
1079 +
1080 +10. Using Cursor Tracking
1081 +
1082 +In Speakup version 2.0 and later, cursor tracking is turned on by
1083 +default. This means that when you are using an editor, Speakup will
1084 +automatically speak characters as you move left and right with the
1085 +cursor keys, and lines as you move up and down with the cursor keys.
1086 +
1087 +This is extremely useful, and makes editing files a snap. But there are
1088 +times when cursor tracking can get in your way. So Speakup provides a
1089 +toggle to turn cursor tracking on and off. You do this with the keypad
1090 +asterisk key. Pressing this key repeatedly will toggle the cursor
1091 +tracking on and off, and you will hear Speakup say, "cursoring off", and
1092 +"cursoring on".
1093 +
1094 +Some folks like to turn cursor tracking off while they are using the
1095 +lynx web browser. You definitely want to turn cursor tracking off when
1096 +you are using the alsamixer application. Otherwise, you won't be able
1097 +to hear your mixer settings while you are using the arrow keys.
1098 +
1099 +11. Cut and Paste
1100 +
1101 +One of Speakup's more useful features is the ability to cut and paste
1102 +text on the screen. This means that you can capture information from a
1103 +program, and paste that captured text into a different place in the
1104 +program, or into an entirely different program, which may even be
1105 +running on a different console.
1106 +
1107 +For example, in this manual, we have made references to several web
1108 +sites. It would be nice if you could cut and paste these urls into your
1109 +web browser. Speakup does this quite nicely. Suppose you wanted to
1110 +past the following url into your browser:
1111 +
1112 +http://linux-speakup.org/
1113 +
1114 +Use the speakup review keys to position the reading cursor on the first
1115 +character of the above url. When the reading cursor is in position,
1116 +press the keypad slash key once. Speakup will say, "mark". Next,
1117 +position the reading cursor on the rightmost character of the above
1118 +url. Press the keypad slash key once again to actually cut the text
1119 +from the screen. Speakup will say, "cut". Although we call this
1120 +cutting, Speakup does not actually delete the cut text from the screen.
1121 +It makes a copy of the text in a special buffer for later pasting.
1122 +
1123 +Now that you have the url cut from the screen, you can paste it into
1124 +your browser, or even paste the url on a command line as an argument to
1125 +your browser.
1126 +
1127 +Suppose you want to start lynx and go to the Speakup site.
1128 +
1129 +You can switch to a different console with the alt left and right
1130 +arrows, or you can switch to a specific console by typing alt and a
1131 +function key. These are not Speakup commands, just standard Linux
1132 +console capabilities.
1133 +
1134 +Once you've changed to an appropriate console, and are at a shell prompt,
1135 +type the word lynx, followed by a space. Now press and hold the speakup
1136 +key, while you type the keypad slash character. The url will be pasted
1137 +onto the command line, just as though you had typed it in. Press the
1138 +enter key to execute the command.
1139 +
1140 +The paste buffer will continue to hold the cut information, until a new
1141 +mark and cut operation is carried out. This means you can paste the cut
1142 +information as many times as you like before doing another cut
1143 +operation.
1144 +
1145 +You are not limited to cutting and pasting only one line on the screen.
1146 +You can also cut and paste rectangular regions of the screen. Just
1147 +position the reading cursor at the top left corner of the text to be
1148 +cut, mark it with the keypad slash key, then position the reading cursor
1149 +at the bottom right corner of the region to be cut, and cut it with the
1150 +keypad slash key.
1151 +
1152 +12. Changing the Pronunciation of Characters
1153 +
1154 +Through the /proc/speakup/chars proc entry, Speakup gives you the
1155 +ability to change how Speakup pronounces a given character. You could,
1156 +for example, change how some punctuation characters are spoken. You can
1157 +even change how Speakup will pronounce certain letters.
1158 +
1159 +You may, for example, wish to change how Speakup pronounces the z
1160 +character. The author of Speakup, Kirk Reiser, is Canadian, and thus
1161 +believes that the z should be pronounced zed. If you are an American,
1162 +you might wish to use the zee pronunciation instead of zed. You can
1163 +change the pronunciation of both the upper and lower case z with the
1164 +following two commands:
1165 +
1166 +echo 90 zee >/proc/speakup/characters
1167 +echo 122 zee >/proc/speakup/characters
1168 +
1169 +Let's examine the parts of the two previous commands. They are issued
1170 +at the shell prompt, and could be placed in a startup script.
1171 +
1172 +The word echo tells the shell that you want to have it display the
1173 +string of characters that follow the word echo. If you were to just
1174 +type:
1175 +
1176 +echo hello.
1177 +
1178 +You would get the word hello printed on your screen as soon as you
1179 +pressed the enter key. In this case, we are echoing strings that we
1180 +want to be redirected into the proc system.
1181 +
1182 +The numbers 90 and 122 in the above echo commands are the ascii numeric
1183 +values for the upper and lower case z, the characters we wish to change.
1184 +
1185 +The string zee is the pronunciation that we want Speakup to use for the
1186 +upper and lower case z.
1187 +
1188 +The > symbol redirects the output of the echo command to a file, just
1189 +like in DOS, or at the Windows command prompt.
1190 +
1191 +And finally, /proc/speakup/chars is the file entry in the proc system
1192 +where we want the output to be directed. Speakup looks at the numeric
1193 +value of the character we want to change, and inserts the pronunciation
1194 +string into an internal table.
1195 +
1196 +You can look at the whole table with the following command:
1197 +
1198 +cat /proc/speakup/chars
1199 +
1200 +Speakup will then print out the entire character pronunciation table. I
1201 +won't display it here, but leave you to look at it at your convenience.
1202 +
1203 +13. Mapping Keys
1204 +
1205 +Speakup has the capability of allowing you to assign or "map" keys to
1206 +internal Speakup commands. This section necessarily assumes you have a
1207 +Linux kernel source tree installed, and that it has been patched and
1208 +configured with Speakup. How you do this is beyond the scope of this
1209 +manual. For this information, visit the Speakup web site at
1210 +http://linux-speakup.org/. The reason you'll need the kernel source
1211 +tree patched with Speakup is that the genmap utility you'll need for
1212 +processing keymaps is in the
1213 +/usr/src/linux-<version_number>/drivers/char/speakup directory. The
1214 +<version_number> in the above directory path is the version number of
1215 +the Linux source tree you are working with.
1216 +
1217 +So ok, you've gone off and gotten your kernel source tree, and patched
1218 +and configured it. Now you can start manipulating keymaps.
1219 +
1220 +You can either use the
1221 +/usr/src/linux-<version_number>/drivers/char/speakup/speakupmap.map file
1222 +included with the Speakup source, or you can cut and paste the copy in
1223 +section 4 into a separate file. If you use the one in the Speakup
1224 +source tree, make sure you make a backup of it before you start making
1225 +changes. You have been warned!
1226 +
1227 +Suppose that you want to swap the key assignments for the Speakup
1228 +say_last_char and the Speakup say_first_char commands. The
1229 +speakupmap.map lists the key mappings for these two commands as follows:
1230 +
1231 +spk key_pageup = say_first_char
1232 +spk key_pagedown = say_last_char
1233 +
1234 +You can edit your copy of the speakupmap.map file and swap the command
1235 +names on the right side of the = (equals) sign. You did make a backup,
1236 +right? The new keymap lines would look like this:
1237 +
1238 +spk key_pageup = say_last_char
1239 +spk key_pagedown = say_first_char
1240 +
1241 +After you edit your copy of the speakupmap.map file, save it under a new
1242 +file name, perhaps newmap.map. Then exit your editor and return to the
1243 +shell prompt.
1244 +
1245 +You are now ready to load your keymap with your swapped key assignments.
1246 + Assuming that you saved your new keymap as the file newmap.map, you
1247 +would load your keymap into the proc system like this:
1248 +
1249 +/usr/src/linux-<version_number>/drivers/char/speakup/genmap newmap.map
1250 +>/proc/speakup/keymap
1251 +
1252 +Remember to substitute your kernel version number for the
1253 +<version_number> in the above command. Also note that although the
1254 +above command wrapped onto two lines in this document, you should type
1255 +it all on one line.
1256 +
1257 +Your say first and say last characters should now be swapped. Pressing
1258 +speakup pagedown should read you the first non-whitespace character on
1259 +the line your reading cursor is in, and pressing speakup pageup should
1260 +read you the last character on the line your reading cursor is in.
1261 +
1262 +You should note that these new mappings will only stay in effect until
1263 +you reboot, or until you load another keymap.
1264 +
1265 +One final warning. If you try to load a partial map, you will quickly
1266 +find that all the mappings you didn't include in your file got deleted
1267 +from the working map. Be extremely careful, and always make a backup!
1268 +You have been warned!
1269 +
1270 +14. Using Speakup's Windowing Capability
1271 +
1272 +Speakup has the capability of defining and manipulating windows on the
1273 +screen. Speakup uses the term "Window", to mean a user defined area of
1274 +the screen. The key strokes for defining and manipulating Speakup
1275 +windows are as follows:
1276 +
1277 +speakup + f2 -- Set the bounds of the window.
1278 +Speakup + f3 -- clear the current window definition.
1279 +speakup + f4 -- Toggle window silence on and off.
1280 +speakup + keypad plus -- Say the currently defined window.
1281 +
1282 +These capabilities are useful for tracking a certain part of the screen
1283 +without rereading the whole screen, or for silencing a part of the
1284 +screen that is constantly changing, such as a clock or status line.
1285 +
1286 +There is no way to save these window settings, and you can only have one
1287 +window defined for each virtual console. There is also no way to have
1288 +windows automaticly defined for specific applications.
1289 +
1290 +In order to define a window, use the review keys to move your reading
1291 +cursor to the beginning of the area you want to define. Then press
1292 +speakup + f2. Speakup will tell you that the window starts at the
1293 +indicated row and column position. Then move the reading cursor to the
1294 +end of the area to be defined as a window, and press speakup + f2 again.
1295 + If there is more than one line in the window, Speakup will tell you
1296 +that the window ends at the indicated row and column position. If there
1297 +is only one line in the window, then Speakup will tell you that the
1298 +window is the specified line on the screen. If you are only defining a
1299 +one line window, you can just press speakup + f2 twice after placing the
1300 +reading cursor on the line you want to define as a window. It is not
1301 +necessary to position the reading cursor at the end of the line in order
1302 +to define the whole line as a window.
1303 +
1304 + GNU Free Documentation License
1305 + Version 1.2, November 2002
1306 +
1307 +
1308 + Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
1309 + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1310 + Everyone is permitted to copy and distribute verbatim copies
1311 + of this license document, but changing it is not allowed.
1312 +
1313 +
1314 +0. PREAMBLE
1315 +
1316 +The purpose of this License is to make a manual, textbook, or other
1317 +functional and useful document "free" in the sense of freedom: to
1318 +assure everyone the effective freedom to copy and redistribute it,
1319 +with or without modifying it, either commercially or noncommercially.
1320 +Secondarily, this License preserves for the author and publisher a way
1321 +to get credit for their work, while not being considered responsible
1322 +for modifications made by others.
1323 +
1324 +This License is a kind of "copyleft", which means that derivative
1325 +works of the document must themselves be free in the same sense. It
1326 +complements the GNU General Public License, which is a copyleft
1327 +license designed for free software.
1328 +
1329 +We have designed this License in order to use it for manuals for free
1330 +software, because free software needs free documentation: a free
1331 +program should come with manuals providing the same freedoms that the
1332 +software does. But this License is not limited to software manuals;
1333 +it can be used for any textual work, regardless of subject matter or
1334 +whether it is published as a printed book. We recommend this License
1335 +principally for works whose purpose is instruction or reference.
1336 +
1337 +
1338 +1. APPLICABILITY AND DEFINITIONS
1339 +
1340 +This License applies to any manual or other work, in any medium, that
1341 +contains a notice placed by the copyright holder saying it can be
1342 +distributed under the terms of this License. Such a notice grants a
1343 +world-wide, royalty-free license, unlimited in duration, to use that
1344 +work under the conditions stated herein. The "Document", below,
1345 +refers to any such manual or work. Any member of the public is a
1346 +licensee, and is addressed as "you". You accept the license if you
1347 +copy, modify or distribute the work in a way requiring permission
1348 +under copyright law.
1349 +
1350 +A "Modified Version" of the Document means any work containing the
1351 +Document or a portion of it, either copied verbatim, or with
1352 +modifications and/or translated into another language.
1353 +
1354 +A "Secondary Section" is a named appendix or a front-matter section of
1355 +the Document that deals exclusively with the relationship of the
1356 +publishers or authors of the Document to the Document's overall subject
1357 +(or to related matters) and contains nothing that could fall directly
1358 +within that overall subject. (Thus, if the Document is in part a
1359 +textbook of mathematics, a Secondary Section may not explain any
1360 +mathematics.) The relationship could be a matter of historical
1361 +connection with the subject or with related matters, or of legal,
1362 +commercial, philosophical, ethical or political position regarding
1363 +them.
1364 +
1365 +The "Invariant Sections" are certain Secondary Sections whose titles
1366 +are designated, as being those of Invariant Sections, in the notice
1367 +that says that the Document is released under this License. If a
1368 +section does not fit the above definition of Secondary then it is not
1369 +allowed to be designated as Invariant. The Document may contain zero
1370 +Invariant Sections. If the Document does not identify any Invariant
1371 +Sections then there are none.
1372 +
1373 +The "Cover Texts" are certain short passages of text that are listed,
1374 +as Front-Cover Texts or Back-Cover Texts, in the notice that says that
1375 +the Document is released under this License. A Front-Cover Text may
1376 +be at most 5 words, and a Back-Cover Text may be at most 25 words.
1377 +
1378 +A "Transparent" copy of the Document means a machine-readable copy,
1379 +represented in a format whose specification is available to the
1380 +general public, that is suitable for revising the document
1381 +straightforwardly with generic text editors or (for images composed of
1382 +pixels) generic paint programs or (for drawings) some widely available
1383 +drawing editor, and that is suitable for input to text formatters or
1384 +for automatic translation to a variety of formats suitable for input
1385 +to text formatters. A copy made in an otherwise Transparent file
1386 +format whose markup, or absence of markup, has been arranged to thwart
1387 +or discourage subsequent modification by readers is not Transparent.
1388 +An image format is not Transparent if used for any substantial amount
1389 +of text. A copy that is not "Transparent" is called "Opaque".
1390 +
1391 +Examples of suitable formats for Transparent copies include plain
1392 +ASCII without markup, Texinfo input format, LaTeX input format, SGML
1393 +or XML using a publicly available DTD, and standard-conforming simple
1394 +HTML, PostScript or PDF designed for human modification. Examples of
1395 +transparent image formats include PNG, XCF and JPG. Opaque formats
1396 +include proprietary formats that can be read and edited only by
1397 +proprietary word processors, SGML or XML for which the DTD and/or
1398 +processing tools are not generally available, and the
1399 +machine-generated HTML, PostScript or PDF produced by some word
1400 +processors for output purposes only.
1401 +
1402 +The "Title Page" means, for a printed book, the title page itself,
1403 +plus such following pages as are needed to hold, legibly, the material
1404 +this License requires to appear in the title page. For works in
1405 +formats which do not have any title page as such, "Title Page" means
1406 +the text near the most prominent appearance of the work's title,
1407 +preceding the beginning of the body of the text.
1408 +
1409 +A section "Entitled XYZ" means a named subunit of the Document whose
1410 +title either is precisely XYZ or contains XYZ in parentheses following
1411 +text that translates XYZ in another language. (Here XYZ stands for a
1412 +specific section name mentioned below, such as "Acknowledgements",
1413 +"Dedications", "Endorsements", or "History".) To "Preserve the Title"
1414 +of such a section when you modify the Document means that it remains a
1415 +section "Entitled XYZ" according to this definition.
1416 +
1417 +The Document may include Warranty Disclaimers next to the notice which
1418 +states that this License applies to the Document. These Warranty
1419 +Disclaimers are considered to be included by reference in this
1420 +License, but only as regards disclaiming warranties: any other
1421 +implication that these Warranty Disclaimers may have is void and has
1422 +no effect on the meaning of this License.
1423 +
1424 +
1425 +2. VERBATIM COPYING
1426 +
1427 +You may copy and distribute the Document in any medium, either
1428 +commercially or noncommercially, provided that this License, the
1429 +copyright notices, and the license notice saying this License applies
1430 +to the Document are reproduced in all copies, and that you add no other
1431 +conditions whatsoever to those of this License. You may not use
1432 +technical measures to obstruct or control the reading or further
1433 +copying of the copies you make or distribute. However, you may accept
1434 +compensation in exchange for copies. If you distribute a large enough
1435 +number of copies you must also follow the conditions in section 3.
1436 +
1437 +You may also lend copies, under the same conditions stated above, and
1438 +you may publicly display copies.
1439 +
1440 +
1441 +3. COPYING IN QUANTITY
1442 +
1443 +If you publish printed copies (or copies in media that commonly have
1444 +printed covers) of the Document, numbering more than 100, and the
1445 +Document's license notice requires Cover Texts, you must enclose the
1446 +copies in covers that carry, clearly and legibly, all these Cover
1447 +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
1448 +the back cover. Both covers must also clearly and legibly identify
1449 +you as the publisher of these copies. The front cover must present
1450 +the full title with all words of the title equally prominent and
1451 +visible. You may add other material on the covers in addition.
1452 +Copying with changes limited to the covers, as long as they preserve
1453 +the title of the Document and satisfy these conditions, can be treated
1454 +as verbatim copying in other respects.
1455 +
1456 +If the required texts for either cover are too voluminous to fit
1457 +legibly, you should put the first ones listed (as many as fit
1458 +reasonably) on the actual cover, and continue the rest onto adjacent
1459 +pages.
1460 +
1461 +If you publish or distribute Opaque copies of the Document numbering
1462 +more than 100, you must either include a machine-readable Transparent
1463 +copy along with each Opaque copy, or state in or with each Opaque copy
1464 +a computer-network location from which the general network-using
1465 +public has access to download using public-standard network protocols
1466 +a complete Transparent copy of the Document, free of added material.
1467 +If you use the latter option, you must take reasonably prudent steps,
1468 +when you begin distribution of Opaque copies in quantity, to ensure
1469 +that this Transparent copy will remain thus accessible at the stated
1470 +location until at least one year after the last time you distribute an
1471 +Opaque copy (directly or through your agents or retailers) of that
1472 +edition to the public.
1473 +
1474 +It is requested, but not required, that you contact the authors of the
1475 +Document well before redistributing any large number of copies, to give
1476 +them a chance to provide you with an updated version of the Document.
1477 +
1478 +
1479 +4. MODIFICATIONS
1480 +
1481 +You may copy and distribute a Modified Version of the Document under
1482 +the conditions of sections 2 and 3 above, provided that you release
1483 +the Modified Version under precisely this License, with the Modified
1484 +Version filling the role of the Document, thus licensing distribution
1485 +and modification of the Modified Version to whoever possesses a copy
1486 +of it. In addition, you must do these things in the Modified Version:
1487 +
1488 +A. Use in the Title Page (and on the covers, if any) a title distinct
1489 + from that of the Document, and from those of previous versions
1490 + (which should, if there were any, be listed in the History section
1491 + of the Document). You may use the same title as a previous version
1492 + if the original publisher of that version gives permission.
1493 +B. List on the Title Page, as authors, one or more persons or entities
1494 + responsible for authorship of the modifications in the Modified
1495 + Version, together with at least five of the principal authors of the
1496 + Document (all of its principal authors, if it has fewer than five),
1497 + unless they release you from this requirement.
1498 +C. State on the Title page the name of the publisher of the
1499 + Modified Version, as the publisher.
1500 +D. Preserve all the copyright notices of the Document.
1501 +E. Add an appropriate copyright notice for your modifications
1502 + adjacent to the other copyright notices.
1503 +F. Include, immediately after the copyright notices, a license notice
1504 + giving the public permission to use the Modified Version under the
1505 + terms of this License, in the form shown in the Addendum below.
1506 +G. Preserve in that license notice the full lists of Invariant Sections
1507 + and required Cover Texts given in the Document's license notice.
1508 +H. Include an unaltered copy of this License.
1509 +I. Preserve the section Entitled "History", Preserve its Title, and add
1510 + to it an item stating at least the title, year, new authors, and
1511 + publisher of the Modified Version as given on the Title Page. If
1512 + there is no section Entitled "History" in the Document, create one
1513 + stating the title, year, authors, and publisher of the Document as
1514 + given on its Title Page, then add an item describing the Modified
1515 + Version as stated in the previous sentence.
1516 +J. Preserve the network location, if any, given in the Document for
1517 + public access to a Transparent copy of the Document, and likewise
1518 + the network locations given in the Document for previous versions
1519 + it was based on. These may be placed in the "History" section.
1520 + You may omit a network location for a work that was published at
1521 + least four years before the Document itself, or if the original
1522 + publisher of the version it refers to gives permission.
1523 +K. For any section Entitled "Acknowledgements" or "Dedications",
1524 + Preserve the Title of the section, and preserve in the section all
1525 + the substance and tone of each of the contributor acknowledgements
1526 + and/or dedications given therein.
1527 +L. Preserve all the Invariant Sections of the Document,
1528 + unaltered in their text and in their titles. Section numbers
1529 + or the equivalent are not considered part of the section titles.
1530 +M. Delete any section Entitled "Endorsements". Such a section
1531 + may not be included in the Modified Version.
1532 +N. Do not retitle any existing section to be Entitled "Endorsements"
1533 + or to conflict in title with any Invariant Section.
1534 +O. Preserve any Warranty Disclaimers.
1535 +
1536 +If the Modified Version includes new front-matter sections or
1537 +appendices that qualify as Secondary Sections and contain no material
1538 +copied from the Document, you may at your option designate some or all
1539 +of these sections as invariant. To do this, add their titles to the
1540 +list of Invariant Sections in the Modified Version's license notice.
1541 +These titles must be distinct from any other section titles.
1542 +
1543 +You may add a section Entitled "Endorsements", provided it contains
1544 +nothing but endorsements of your Modified Version by various
1545 +parties--for example, statements of peer review or that the text has
1546 +been approved by an organization as the authoritative definition of a
1547 +standard.
1548 +
1549 +You may add a passage of up to five words as a Front-Cover Text, and a
1550 +passage of up to 25 words as a Back-Cover Text, to the end of the list
1551 +of Cover Texts in the Modified Version. Only one passage of
1552 +Front-Cover Text and one of Back-Cover Text may be added by (or
1553 +through arrangements made by) any one entity. If the Document already
1554 +includes a cover text for the same cover, previously added by you or
1555 +by arrangement made by the same entity you are acting on behalf of,
1556 +you may not add another; but you may replace the old one, on explicit
1557 +permission from the previous publisher that added the old one.
1558 +
1559 +The author(s) and publisher(s) of the Document do not by this License
1560 +give permission to use their names for publicity for or to assert or
1561 +imply endorsement of any Modified Version.
1562 +
1563 +
1564 +5. COMBINING DOCUMENTS
1565 +
1566 +You may combine the Document with other documents released under this
1567 +License, under the terms defined in section 4 above for modified
1568 +versions, provided that you include in the combination all of the
1569 +Invariant Sections of all of the original documents, unmodified, and
1570 +list them all as Invariant Sections of your combined work in its
1571 +license notice, and that you preserve all their Warranty Disclaimers.
1572 +
1573 +The combined work need only contain one copy of this License, and
1574 +multiple identical Invariant Sections may be replaced with a single
1575 +copy. If there are multiple Invariant Sections with the same name but
1576 +different contents, make the title of each such section unique by
1577 +adding at the end of it, in parentheses, the name of the original
1578 +author or publisher of that section if known, or else a unique number.
1579 +Make the same adjustment to the section titles in the list of
1580 +Invariant Sections in the license notice of the combined work.
1581 +
1582 +In the combination, you must combine any sections Entitled "History"
1583 +in the various original documents, forming one section Entitled
1584 +"History"; likewise combine any sections Entitled "Acknowledgements",
1585 +and any sections Entitled "Dedications". You must delete all sections
1586 +Entitled "Endorsements".
1587 +
1588 +
1589 +6. COLLECTIONS OF DOCUMENTS
1590 +
1591 +You may make a collection consisting of the Document and other documents
1592 +released under this License, and replace the individual copies of this
1593 +License in the various documents with a single copy that is included in
1594 +the collection, provided that you follow the rules of this License for
1595 +verbatim copying of each of the documents in all other respects.
1596 +
1597 +You may extract a single document from such a collection, and distribute
1598 +it individually under this License, provided you insert a copy of this
1599 +License into the extracted document, and follow this License in all
1600 +other respects regarding verbatim copying of that document.
1601 +
1602 +
1603 +7. AGGREGATION WITH INDEPENDENT WORKS
1604 +
1605 +A compilation of the Document or its derivatives with other separate
1606 +and independent documents or works, in or on a volume of a storage or
1607 +distribution medium, is called an "aggregate" if the copyright
1608 +resulting from the compilation is not used to limit the legal rights
1609 +of the compilation's users beyond what the individual works permit.
1610 +When the Document is included in an aggregate, this License does not
1611 +apply to the other works in the aggregate which are not themselves
1612 +derivative works of the Document.
1613 +
1614 +If the Cover Text requirement of section 3 is applicable to these
1615 +copies of the Document, then if the Document is less than one half of
1616 +the entire aggregate, the Document's Cover Texts may be placed on
1617 +covers that bracket the Document within the aggregate, or the
1618 +electronic equivalent of covers if the Document is in electronic form.
1619 +Otherwise they must appear on printed covers that bracket the whole
1620 +aggregate.
1621 +
1622 +
1623 +8. TRANSLATION
1624 +
1625 +Translation is considered a kind of modification, so you may
1626 +distribute translations of the Document under the terms of section 4.
1627 +Replacing Invariant Sections with translations requires special
1628 +permission from their copyright holders, but you may include
1629 +translations of some or all Invariant Sections in addition to the
1630 +original versions of these Invariant Sections. You may include a
1631 +translation of this License, and all the license notices in the
1632 +Document, and any Warranty Disclaimers, provided that you also include
1633 +the original English version of this License and the original versions
1634 +of those notices and disclaimers. In case of a disagreement between
1635 +the translation and the original version of this License or a notice
1636 +or disclaimer, the original version will prevail.
1637 +
1638 +If a section in the Document is Entitled "Acknowledgements",
1639 +"Dedications", or "History", the requirement (section 4) to Preserve
1640 +its Title (section 1) will typically require changing the actual
1641 +title.
1642 +
1643 +
1644 +9. TERMINATION
1645 +
1646 +You may not copy, modify, sublicense, or distribute the Document except
1647 +as expressly provided for under this License. Any other attempt to
1648 +copy, modify, sublicense or distribute the Document is void, and will
1649 +automatically terminate your rights under this License. However,
1650 +parties who have received copies, or rights, from you under this
1651 +License will not have their licenses terminated so long as such
1652 +parties remain in full compliance.
1653 +
1654 +
1655 +10. FUTURE REVISIONS OF THIS LICENSE
1656 +
1657 +The Free Software Foundation may publish new, revised versions
1658 +of the GNU Free Documentation License from time to time. Such new
1659 +versions will be similar in spirit to the present version, but may
1660 +differ in detail to address new problems or concerns. See
1661 +http://www.gnu.org/copyleft/.
1662 +
1663 +Each version of the License is given a distinguishing version number.
1664 +If the Document specifies that a particular numbered version of this
1665 +License "or any later version" applies to it, you have the option of
1666 +following the terms and conditions either of that specified version or
1667 +of any later version that has been published (not as a draft) by the
1668 +Free Software Foundation. If the Document does not specify a version
1669 +number of this License, you may choose any version ever published (not
1670 +as a draft) by the Free Software Foundation.
1671 +
1672 +
1673 +ADDENDUM: How to use this License for your documents
1674 +
1675 +To use this License in a document you have written, include a copy of
1676 +the License in the document and put the following copyright and
1677 +license notices just after the title page:
1678 +
1679 + Copyright (c) YEAR YOUR NAME.
1680 + Permission is granted to copy, distribute and/or modify this document
1681 + under the terms of the GNU Free Documentation License, Version 1.2
1682 + or any later version published by the Free Software Foundation;
1683 + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
1684 + A copy of the license is included in the section entitled "GNU
1685 + Free Documentation License".
1686 +
1687 +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
1688 +replace the "with...Texts." line with this:
1689 +
1690 + with the Invariant Sections being LIST THEIR TITLES, with the
1691 + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
1692 +
1693 +If you have Invariant Sections without Cover Texts, or some other
1694 +combination of the three, merge those two alternatives to suit the
1695 +situation.
1696 +
1697 +If your document contains nontrivial examples of program code, we
1698 +recommend releasing these examples in parallel under your choice of
1699 +free software license, such as the GNU General Public License,
1700 +to permit their use in free software.
1701 +
1702 +The End.
1703 diff -urNpX dontdiff linux-2.6.15/drivers/char/consolemap.c linux-dsd/drivers/char/consolemap.c
1704 --- linux-2.6.15/drivers/char/consolemap.c 2006-01-03 17:42:28.000000000 +0000
1705 +++ linux-dsd/drivers/char/consolemap.c 2006-01-03 17:54:15.000000000 +0000
1706 @@ -668,3 +668,4 @@ console_map_init(void)
1707 }
1708
1709 EXPORT_SYMBOL(con_copy_unimap);
1710 +EXPORT_SYMBOL(inverse_translate);
1711 diff -urNpX dontdiff linux-2.6.15/drivers/char/keyboard.c linux-dsd/drivers/char/keyboard.c
1712 --- linux-2.6.15/drivers/char/keyboard.c 2006-01-03 17:42:28.000000000 +0000
1713 +++ linux-dsd/drivers/char/keyboard.c 2006-01-03 17:54:15.000000000 +0000
1714 @@ -40,6 +40,13 @@
1715 #include <linux/sysrq.h>
1716 #include <linux/input.h>
1717
1718 +
1719 +#include <linux/speakup.h>
1720 +
1721 +#ifdef CONFIG_SPEAKUP_MODULE
1722 +spk_key_func addr_spk_key = NULL;
1723 +#endif
1724 +
1725 static void kbd_disconnect(struct input_handle *handle);
1726 extern void ctrl_alt_del(void);
1727
1728 @@ -64,6 +71,10 @@ extern void ctrl_alt_del(void);
1729
1730 #define KBD_DEFLOCK 0
1731
1732 +/* Key types processed even in raw modes */
1733 +
1734 +#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) | (1 << KT_SPKUP))
1735 +
1736 void compute_shiftstate(void);
1737
1738 /*
1739 @@ -79,7 +90,7 @@ void compute_shiftstate(void);
1740 typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
1741 char up_flag, struct pt_regs *regs);
1742 static k_handler_fn K_HANDLERS;
1743 -static k_handler_fn *k_handler[16] = { K_HANDLERS };
1744 +k_handler_fn *k_handler[16] = { K_HANDLERS };
1745
1746 #define FN_HANDLERS\
1747 fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
1748 @@ -100,15 +111,18 @@ static fn_handler_fn *fn_handler[] = { F
1749 const int max_vals[] = {
1750 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
1751 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
1752 - 255, NR_LOCK - 1, 255
1753 + 255, NR_LOCK - 1, 255, 255
1754 };
1755
1756 const int NR_TYPES = ARRAY_SIZE(max_vals);
1757
1758 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
1759 -static struct kbd_struct *kbd = kbd_table;
1760 +struct kbd_struct *kbd = kbd_table;
1761 static struct kbd_struct kbd0;
1762
1763 +EXPORT_SYMBOL(kbd);
1764 +EXPORT_SYMBOL(k_handler);
1765 +
1766 int spawnpid, spawnsig;
1767
1768 /*
1769 @@ -255,12 +269,14 @@ void kd_mksound(unsigned int hz, unsigne
1770 }
1771 }
1772 }
1773 - if (ticks)
1774 - mod_timer(&kd_mksound_timer, jiffies + ticks);
1775 + if (ticks)
1776 + mod_timer(&kd_mksound_timer, jiffies + ticks);
1777 } else
1778 kd_nosound(0);
1779 }
1780
1781 +EXPORT_SYMBOL(kd_mksound);
1782 +
1783 /*
1784 * Setting the keyboard rate.
1785 */
1786 @@ -602,6 +618,7 @@ static void k_spec(struct vc_data *vc, u
1787 if (up_flag)
1788 return;
1789 if (value >= ARRAY_SIZE(fn_handler))
1790 + if (up_flag || (value >= ARRAY_SIZE(fn_handler)))
1791 return;
1792 if ((kbd->kbdmode == VC_RAW ||
1793 kbd->kbdmode == VC_MEDIUMRAW) &&
1794 @@ -1119,6 +1136,13 @@ static void kbd_keycode(unsigned int key
1795 key_map = key_maps[shift_final];
1796
1797 if (!key_map) {
1798 +#ifdef CONFIG_SPEAKUP
1799 + if (speakup_key(vc, shift_final, keycode, K(KT_SHIFT,0), !down, regs ))
1800 + return;
1801 +#elif defined(CONFIG_SPEAKUP_MODULE)
1802 + if ( addr_spk_key && (*addr_spk_key)(vc, shift_final,
1803 + keycode, K(KT_SHIFT,0), !down, regs) ) return;
1804 +#endif
1805 compute_shiftstate();
1806 kbd->slockstate = 0;
1807 return;
1808 @@ -1137,10 +1161,17 @@ static void kbd_keycode(unsigned int key
1809 }
1810
1811 type -= 0xf0;
1812 -
1813 - if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
1814 +#ifdef CONFIG_SPEAKUP
1815 + if (speakup_key(vc, shift_final, keycode, keysym, !down, regs ))
1816 return;
1817 +#elif defined(CONFIG_SPEAKUP_MODULE)
1818 + if ( addr_spk_key && (*addr_spk_key)(vc, shift_final,
1819 + keycode, keysym, !down, regs) ) return;
1820 +#endif
1821
1822 + if (raw_mode && type != KT_SPEC && type != KT_SHIFT )
1823 + return;
1824 +
1825 if (type == KT_LETTER) {
1826 type = KT_LATIN;
1827 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
1828 @@ -1149,13 +1180,29 @@ static void kbd_keycode(unsigned int key
1829 keysym = key_map[keycode];
1830 }
1831 }
1832 -
1833 (*k_handler[type])(vc, keysym & 0xff, !down, regs);
1834
1835 if (type != KT_SLOCK)
1836 kbd->slockstate = 0;
1837 }
1838
1839 +struct input_dev *fakekeydev=NULL;
1840 +
1841 +/*void kbd_fakekey(unsigned int keycode)
1842 +{
1843 + if (fakekeydev==NULL)
1844 + return;
1845 + kbd_keycode(keycode, 0, HW_RAW(fakekeydev), fakekeydev->regs);
1846 + kbd_keycode(keycode, 1, HW_RAW(fakekeydev), fakekeydev->regs);
1847 +
1848 + tasklet_schedule(&keyboard_tasklet);
1849 + do_poke_blanked_console = 1;
1850 + schedule_console_callback();
1851 +}
1852 +
1853 +EXPORT_SYMBOL(kbd_fakekey);*/
1854 +EXPORT_SYMBOL(fakekeydev);
1855 +
1856 static void kbd_event(struct input_handle *handle, unsigned int event_type,
1857 unsigned int event_code, int value)
1858 {
1859 @@ -1193,6 +1240,7 @@ static struct input_handle *kbd_connect(
1860 memset(handle, 0, sizeof(struct input_handle));
1861
1862 handle->dev = dev;
1863 + fakekeydev=dev;
1864 handle->handler = handler;
1865 handle->name = "kbd";
1866
1867 diff -urNpX dontdiff linux-2.6.15/drivers/char/Makefile linux-dsd/drivers/char/Makefile
1868 --- linux-2.6.15/drivers/char/Makefile 2006-01-03 17:42:28.000000000 +0000
1869 +++ linux-dsd/drivers/char/Makefile 2006-01-03 17:54:15.000000000 +0000
1870 @@ -84,6 +84,7 @@ obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.
1871 obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
1872 obj-$(CONFIG_TELCLOCK) += tlclk.o
1873
1874 +obj-$(CONFIG_SPEAKUP) += speakup/
1875 obj-$(CONFIG_WATCHDOG) += watchdog/
1876 obj-$(CONFIG_MWAVE) += mwave/
1877 obj-$(CONFIG_AGP) += agp/
1878 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/Config.in linux-dsd/drivers/char/speakup/Config.in
1879 --- linux-2.6.15/drivers/char/speakup/Config.in 1970-01-01 01:00:00.000000000 +0100
1880 +++ linux-dsd/drivers/char/speakup/Config.in 2003-12-10 15:29:56.000000000 +0000
1881 @@ -0,0 +1,26 @@
1882 +tristate 'Speakup console speech' CONFIG_SPEAKUP
1883 +if [ "$CONFIG_SPEAKUP" != "n" ]; then
1884 + comment 'Type "y" for each synthesizer you want built into the kernel.'
1885 + dep_tristate "Accent SA, acntsa" CONFIG_SPEAKUP_ACNTSA $CONFIG_SPEAKUP
1886 + dep_tristate "Accent PC, acntpc" CONFIG_SPEAKUP_ACNTPC $CONFIG_SPEAKUP
1887 + dep_tristate "Apollo, apollo" CONFIG_SPEAKUP_APOLLO $CONFIG_SPEAKUP
1888 + dep_tristate "Audapter, audptr" CONFIG_SPEAKUP_AUDPTR $CONFIG_SPEAKUP
1889 + dep_tristate "Braille 'n' Speak, bns" CONFIG_SPEAKUP_BNS $CONFIG_SPEAKUP
1890 + dep_tristate "DECtalk Express, dectlk" CONFIG_SPEAKUP_DECTLK $CONFIG_SPEAKUP
1891 + dep_tristate "DECtalk External (old), decext" CONFIG_SPEAKUP_DECEXT $CONFIG_SPEAKUP
1892 + dep_tristate "DECtalk PC (big ISA card), decpc" CONFIG_SPEAKUP_DECPC $CONFIG_SPEAKUP
1893 + if [ "$CONFIG_SPEAKUP_DECPC" = "y" ] ;then
1894 + comment 'warning: decpc can only be built as a module'
1895 + fi
1896 + comment 'In order to use this you will need'
1897 + comment 'the dtload program and DECPC software files '
1898 + comment 'Read the accompanying DECPC documentation for more details'
1899 + dep_tristate "DoubleTalk PC, dtlk" CONFIG_SPEAKUP_DTLK $CONFIG_SPEAKUP
1900 + dep_tristate "Keynote Gold PC, keypc" CONFIG_SPEAKUP_KEYPC $CONFIG_SPEAKUP
1901 + dep_tristate "DoubleTalk LT or LiteTalk, ltlk" CONFIG_SPEAKUP_LTLK $CONFIG_SPEAKUP
1902 + dep_tristate "Software synthesizers /dev/sftsyn, sftsyn" CONFIG_SPEAKUP_SFTSYN $CONFIG_SPEAKUP
1903 + dep_tristate "Speak Out, spkout" CONFIG_SPEAKUP_SPKOUT $CONFIG_SPEAKUP
1904 + dep_tristate "Transport, txprt" CONFIG_SPEAKUP_TXPRT $CONFIG_SPEAKUP
1905 + comment 'Enter the three to six character synth string from above or none.'
1906 + string "Default synthesizer for Speakup" CONFIG_SPEAKUP_DEFAULT "none"
1907 +fi
1908 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/cvsversion.h linux-dsd/drivers/char/speakup/cvsversion.h
1909 --- linux-2.6.15/drivers/char/speakup/cvsversion.h 1970-01-01 01:00:00.000000000 +0100
1910 +++ linux-dsd/drivers/char/speakup/cvsversion.h 2005-12-21 19:37:03.000000000 +0000
1911 @@ -0,0 +1 @@
1912 +#define CVSVERSION " CVS: Wed Dec 21 14:36:03 EST 2005 "
1913 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/dtload.c linux-dsd/drivers/char/speakup/dtload.c
1914 --- linux-2.6.15/drivers/char/speakup/dtload.c 1970-01-01 01:00:00.000000000 +0100
1915 +++ linux-dsd/drivers/char/speakup/dtload.c 2003-08-08 19:15:12.000000000 +0100
1916 @@ -0,0 +1,554 @@
1917 +/*
1918 + * This is the DECtalk PC firmware loader for the Linux kernel, version 1.0
1919 + *
1920 + * Original 386BSD source:
1921 + * Copyright ( c ) 1996 Brian Buhrow <buhrow@lothlorien.nfbcal.org>
1922 + *
1923 + * Adapted for Linux:
1924 + * Copyright ( c ) 1997 Nicolas Pitre <nico@cam.org>
1925 + *
1926 + * Adapted for speakup:
1927 + * Copyright ( c ) 2003 David Borowski <david575@golden.net>
1928 + *
1929 + * All rights reserved.
1930 + *
1931 + * This program is free software; you can redistribute it and/or modify
1932 + * it under the terms of the GNU General Public License as published by
1933 + * the Free Software Foundation; either version 2 of the License, or
1934 + * ( at your option ) any later version.
1935 + *
1936 + * This program is distributed in the hope that it will be useful,
1937 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1938 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1939 + * GNU General Public License for more details.
1940 + *
1941 + * You should have received a copy of the GNU General Public License
1942 + * along with this program; if not, write to the Free Software
1943 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1944 + *
1945 + */
1946 +
1947 +#include <stdio.h>
1948 +#include <stdlib.h>
1949 +#include <unistd.h>
1950 +#include <string.h>
1951 +#include <sys/types.h>
1952 +#include <sys/stat.h>
1953 +#include <fcntl.h>
1954 +#include <malloc.h>
1955 +#include <sys/errno.h>
1956 +#include <asm/io.h>
1957 +#include "dtload.h"
1958 +#include "dtpc_reg.h"
1959 +
1960 +#define dt_delay(x) usleep(x)
1961 +int verbose = 0, intest = 0,infd = -1;
1962 +int image_len, total_paras;
1963 +int dt_stat, dma_state = 0, has_kernel = 0;
1964 +struct dos_reloc fixups[512];
1965 +char *read_buff = NULL;
1966 +struct dos_exe_header header;
1967 +u_short iobase = 0x350;
1968 +
1969 +static inline int dt_getstatus( )
1970 +{
1971 + dt_stat = inb_p( iobase )|(inb_p( iobase+1 )<<8);
1972 + return dt_stat;
1973 +}
1974 +
1975 +static void dt_sendcmd( u_int cmd )
1976 +{
1977 + outb_p( cmd & 0xFF, iobase );
1978 + outb_p( (cmd>>8) & 0xFF, iobase+1 );
1979 +}
1980 +
1981 +static int dt_waitbit( int bit )
1982 +{
1983 + int timeout = 100;
1984 + while ( --timeout > 0 ) {
1985 + if( (dt_getstatus( ) & bit ) == bit ) return 1;
1986 + usleep( 1000 );
1987 + }
1988 + return 0;
1989 +}
1990 +
1991 +static int dt_sendcmd_wait( u_int cmd, int bit )
1992 +{
1993 + int timeout = 1000;
1994 + outb_p( cmd & 0xFF, iobase );
1995 + outb_p( (cmd>>8) & 0xFF, iobase+1 );
1996 + while ( --timeout > 0 ) {
1997 + if( (dt_getstatus( ) & bit ) == bit ) return 1;
1998 + usleep( 1000 );
1999 + }
2000 + return 0;
2001 +}
2002 +
2003 +static int dt_waitmode( int pattern )
2004 +{
2005 + int timeout = 1000;
2006 + while ( --timeout > 0 ) {
2007 + if( dt_getstatus( ) == pattern ) return 1;
2008 + usleep( 1000 );
2009 + }
2010 + fprintf( stderr, "waitmode p=%x s = %x\n", pattern, dt_stat );
2011 + return 0;
2012 +}
2013 +
2014 +static int dt_wait_dma( )
2015 +{
2016 + int timeout = 1000, state = dma_state;
2017 + if( !has_kernel ){
2018 + dt_delay( 500 );
2019 + return( dt_waitbit( STAT_dma_ready ) );
2020 + }
2021 + if( ! dt_waitbit( STAT_dma_ready ) ) return 0;
2022 + while ( --timeout > 0 ) {
2023 + if( (dt_getstatus()&STAT_dma_state) == state ) return 1;
2024 + usleep( 1000 );
2025 + }
2026 + dma_state = dt_getstatus( ) & STAT_dma_state;
2027 + return 1;
2028 +}
2029 +
2030 +dt_ctrl( u_int cmd )
2031 +{
2032 + while ( ! dt_waitbit( STAT_cmd_ready ) ) dt_delay( 100 );
2033 + outb_p( 0, iobase+2 );
2034 + outb_p( 0, iobase+3 );
2035 + dt_getstatus( );
2036 + dt_sendcmd( CMD_control|cmd );
2037 + outb_p( 0, iobase+6 );
2038 + dt_delay( 100 );
2039 + dt_sendcmd( CMD_null );
2040 + while ( ! dt_waitbit( STAT_cmd_ready ) ) dt_delay( 100 );
2041 +}
2042 +
2043 +int dt_flush( void )
2044 +{
2045 + dt_ctrl( CTRL_flush );
2046 + dt_waitbit( STAT_dma_ready );
2047 + outb_p( DMA_sync, iobase+4 );
2048 + outb_p( 0, iobase+4 );
2049 + dma_state ^= STAT_dma_state;
2050 + while( dt_getstatus( ) & STAT_flushing ) dt_delay( 100 );
2051 + return 0;
2052 +}
2053 +
2054 +static int dt_sendbuff( char *src, int len )
2055 +{
2056 + while( len-- ){
2057 + if( ! dt_wait_dma( ) ) return -1;
2058 + if( ! (dt_getstatus( ) & STAT_rr_char) ) break;
2059 + outb_p( DMA_single_in, iobase+4 );
2060 + outb_p( *src++, iobase+4 );
2061 + dma_state ^= STAT_dma_state;
2062 + }
2063 + return 0;
2064 +}
2065 +
2066 +unsigned long dt_allocmem( unsigned long paras )
2067 +{
2068 + unsigned long addr;
2069 + if( ! dt_wait_dma( ) ) return 0;
2070 + outb_p( DMA_control, iobase+4 );
2071 + outb_p( DT_MEM_ALLOC, iobase+4 );
2072 + dma_state ^= STAT_dma_state;
2073 + if( ! dt_wait_dma( ) ) return 0;
2074 + outb_p( paras & 0xFF, iobase+4 );
2075 + outb_p( (paras>>8) & 0xFF, iobase+4 );
2076 + dma_state ^= STAT_dma_state;
2077 + if( ! dt_wait_dma( ) ) return 0;
2078 + addr = inb_p( iobase+4 );
2079 + addr |= (inb_p( iobase+4 )<<8);
2080 + addr += (inb_p( iobase+4 )<<4);
2081 + addr += (inb_p( iobase+4 )<<12);
2082 + dma_state ^= STAT_dma_state;
2083 + return addr;
2084 +}
2085 +
2086 +static int testkernel( void )
2087 +{
2088 + dt_sendcmd( CMD_sync );
2089 + if( ! dt_waitbit( STAT_cmd_ready ) ) return -10;
2090 + has_kernel = ( dt_stat&0x8000 ) ? 1 : 0;
2091 + if ( verbose ) printf( "testkernel got %x\n", dt_stat );
2092 + if ( has_kernel ) return 0;
2093 + dt_delay( 100 );
2094 + return 1;
2095 +}
2096 +
2097 +static int dt_loadmem( int addr, int len, char *src )
2098 +{
2099 + char c;
2100 + int l;
2101 + if ( verbose ) printf( "dt_loadmem: addr = %08X size = %d\n", addr, len );
2102 + do {
2103 + l = len;
2104 + if ( l >= 0xc000 ) l = 0xc000;
2105 + len -= l;
2106 + if( ! dt_wait_dma( ) ) return -1;
2107 + outb_p( DMA_control, iobase+4 );
2108 + outb_p( DT_LOAD_MEM, iobase+4 );
2109 + dma_state ^= STAT_dma_state;
2110 + if( ! dt_wait_dma( ) ) return -2;
2111 + outb_p( addr & 0xFF, iobase+4 );
2112 + outb_p( (addr>>8) & 0xFF, iobase+4 );
2113 + outb_p( (addr>>16) & 0xFF, iobase+4 );
2114 + outb_p( (addr>>24) & 0xFF, iobase+4 );
2115 + outb_p( l & 0xFF, iobase+4 );
2116 + outb_p( (l>>8) & 0xFF, iobase+4 );
2117 + dma_state ^= STAT_dma_state;
2118 + if( ! dt_wait_dma( ) ) return -3;
2119 + addr += l;
2120 + while( l-- ){
2121 + c = *src++;
2122 + outb_p( c, iobase+4 );
2123 + }
2124 + dma_state ^= STAT_dma_state;
2125 + } while ( len > 0 );
2126 + return 0;
2127 +}
2128 +
2129 +unsigned int loadfile ( char *filename )
2130 +{
2131 + int i, header_size;
2132 + unsigned int total_paras;
2133 + long fix;
2134 + infd = open ( filename, O_RDONLY );
2135 + if ( infd == -1 ) {
2136 + perror ( "Opening file: " );
2137 + return 0;
2138 + }
2139 + read ( infd, &header, sizeof ( struct dos_exe_header ) );
2140 + if ( header.id != 0x5a4d ) {
2141 + fprintf ( stderr, "Invalid header file format\n" );
2142 + fprintf ( stderr, "Want 0x5a4d, got 0x%x\n", header.id );
2143 + return 0;
2144 + }
2145 + if ( header.relen > MAX_FIXUPS ) {
2146 + fprintf ( stderr, "Too many fixups\n" );
2147 + return 0;
2148 + }
2149 + lseek ( infd, ( long ) header.reloc, SEEK_SET );
2150 + read ( infd, fixups, sizeof ( struct dos_reloc ) * header.relen );
2151 + header_size = header.hsize * 16;
2152 + lseek ( infd, ( long )header_size, SEEK_SET );
2153 + image_len = ( ( header.pages-1 )*512 ) + ( header.rem- header_size );
2154 + total_paras = ( image_len >> 4 ) + header.hmin + 16;
2155 + read ( infd, read_buff, image_len );
2156 + close( infd );
2157 + return total_paras;
2158 +}
2159 +
2160 +static int loadkernel( char *filename )
2161 +{
2162 + int segfix = 0x40, fix, i;
2163 + int ipval, csval;
2164 + if ( has_kernel ) return 0;
2165 + if ( !loadfile( filename ) ) return -1;
2166 + header.csval += segfix;
2167 + header.ssval += segfix;
2168 + if ( verbose ) {
2169 + printf ( "Loading kernel of %ld bytes ( %d relocs )\n",
2170 + image_len, header.relen );
2171 + printf ( " cs:ip == %04x:%04x ss:sp == %04x:%04x\n",
2172 + header.csval, header.ipval, header.ssval, header.spval );
2173 + }
2174 + for ( i = 0; i < header.relen; i++ ) {
2175 + fix = ( fixups[i].segment << 4 ) + fixups[i].offset;
2176 + ( *( unsigned int * ) &read_buff[fix] ) += segfix;
2177 + }
2178 + csval = header.csval;
2179 + ipval = header.ipval;
2180 + dt_sendcmd_wait( MODULE_reset, MODULE_init );
2181 + dt_sendcmd( CMD_reset );
2182 + if( dt_getstatus( ) == MODULE_self_test ){
2183 + if( ! dt_waitmode( MODULE_init ) ) return -1;
2184 + }
2185 + if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -2;
2186 + if ( !dt_sendcmd_wait( CMD_sync, MODE_error ) ) return -3;
2187 + if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -4;
2188 + if ( verbose ) printf( "card is ready\n" );
2189 + dt_sendcmd( CMD_dma );
2190 + if( ! dt_waitbit( STAT_dma_ready ) ) return -5;
2191 + if( ( i = dt_loadmem( 0x00000400, image_len, read_buff ) ) ) {
2192 + fprintf( stderr, "kernel load failed, status %d\n", i );
2193 + return -6;
2194 + }
2195 + dt_delay( 100 );
2196 + /* the kernel is loaded, start it */
2197 + if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -7;
2198 + dt_sendcmd( CMD_dma+1 ); /**xxx**/
2199 + dt_delay( 100 );
2200 + if( ! dt_waitbit( STAT_dma_ready ) ) return-8;
2201 + outb_p( DMA_control, iobase+4 );
2202 + outb_p( DT_START_TASK, iobase+4 );
2203 + dt_delay( 100 );
2204 + outb_p( ipval & 0xFF, iobase+4 );
2205 + outb_p( (ipval>>8) & 0xFF, iobase+4 );
2206 + outb_p( csval & 0xFF, iobase+4 );
2207 + outb_p( (csval>>8) & 0xFF, iobase+4 );
2208 + if( ! dt_waitmode( 0xc001 ) ) return -9;
2209 + if ( verbose ) {
2210 + printf( "done loading kernel\n" );
2211 + }
2212 + return testkernel( );
2213 +}
2214 +
2215 +int loaddict ( char *filename, char *name, int type )
2216 +{
2217 + int i, read_index, read_size, act_size;
2218 + unsigned short *index_fix, seg_fix;
2219 + unsigned long entries, index, dic_bytes, dic_addr;
2220 + unsigned int total_paras;
2221 + unsigned long param, l;
2222 + infd = open ( filename, O_RDONLY );
2223 + if ( infd == -1 ) {
2224 + perror ( filename );
2225 + return -1;
2226 + }
2227 +/* read in the entry count and the actual entry size excluding the
2228 + * index table ( which is entries * 4 ) ... */
2229 + read ( infd, &entries, 4 );
2230 + read ( infd, &dic_bytes, 4 );
2231 + if ( verbose )
2232 + printf ( "Loading %s dictionary of %lu entries, %lu bytes.\n",
2233 + name, entries, dic_bytes );
2234 + total_paras = ( ( ( entries * 4 ) + dic_bytes ) >> 4 ) + 2;
2235 + if ( verbose )
2236 + printf ( "Allocating %d paragraphs of free ram ...\n", total_paras );
2237 + l = dt_allocmem( total_paras );
2238 + if ( l == 0 ) {
2239 + perror ( "Error requesting memory from speech device" );
2240 + return -1;
2241 + }
2242 + seg_fix = ( l >> 4 ) & 0xffff;
2243 + dic_addr = l;
2244 + index = entries;
2245 + index_fix = ( unsigned short * ) &read_buff[0];
2246 + if ( verbose )
2247 + printf ( "Index table starts at %lx\n", l );
2248 + read_index = index*4;
2249 + act_size = read ( infd, read_buff, read_index );
2250 + if ( act_size != read_index ) {
2251 + fprintf ( stderr, "\nError reading indexes\n" );
2252 + fprintf ( stderr, " exp : %d act : %d\n", read_index * 4, act_size );
2253 + return -1;
2254 + }
2255 + for ( i = 1; i < index * 2; i += 2 )
2256 + index_fix[i] += seg_fix;
2257 + if( ( i = dt_loadmem( l, read_index, read_buff ) ) ) {
2258 + fprintf ( stderr, "\nError loading indexes at 0x%lX: i %d\n",
2259 + l, i );
2260 + return -1;
2261 + }
2262 + l += read_index;
2263 +/* now, load up the dictionary bytes ... */
2264 + if ( verbose )
2265 + printf ( "Dictionary text starts at %lx\n", l );
2266 + read_size = dic_bytes;
2267 + if ( ( act_size = read ( infd, read_buff, read_size ) ) != read_size ) {
2268 + fprintf ( stderr, "\nError reading dictionary text!\n" );
2269 + fprintf ( stderr, "asked : %d actual : %d\n", act_size, read_size );
2270 + return -1;
2271 + }
2272 + if( ( i = dt_loadmem( l, read_size, read_buff ) ) ) {
2273 + fprintf ( stderr, "\nError loading dictionary at 0x%lX: status %d\n",
2274 + l, i );
2275 + return -1;
2276 + }
2277 + if( ! dt_wait_dma( ) ) return -1;
2278 + outb_p( DMA_control, iobase+4 );
2279 + outb_p( DT_SET_DIC, iobase+4 );
2280 + dma_state ^= STAT_dma_state;
2281 + if( ! dt_wait_dma( ) ) return -1;
2282 + l = dic_addr;
2283 + l = ((l << 12) & 0xFFFF0000) + (l & 0x0000000F);
2284 + outb_p( l & 0xFF, iobase+4 );
2285 + outb_p( (l>>8) & 0xFF, iobase+4 );
2286 + outb_p( (l>>16) & 0xFF, iobase+4 );
2287 + outb_p( (l>>24) & 0xFF, iobase+4 );
2288 + l = entries;
2289 + outb_p( l & 0xFF, iobase+4 );
2290 + outb_p( (l>>8) & 0xFF, iobase+4 );
2291 + outb_p( (l>>16) & 0xFF, iobase+4 );
2292 + outb_p( (l>>24) & 0xFF, iobase+4 );
2293 + l = type;
2294 + outb_p( l & 0xFF, iobase+4 );
2295 + outb_p( (l>>8) & 0xFF, iobase+4 );
2296 + dma_state ^= STAT_dma_state;
2297 + close ( infd );
2298 + if ( verbose ) printf( "dictionary load complete\n" );
2299 + return 0;
2300 +}
2301 +
2302 +int loadexe ( char *filename )
2303 +{
2304 + unsigned int load_addr = 0, seg_fix;
2305 + int i, read_size;
2306 + int ipval, csval;
2307 + long fix;
2308 + unsigned long total_paras;
2309 + total_paras = loadfile ( filename );
2310 + if ( total_paras == 0 ) return -1;
2311 + load_addr = dt_allocmem( total_paras );
2312 + if ( load_addr == 0 ) {
2313 + fprintf ( stderr, "Error allocating memory on card: " );
2314 + return -1;
2315 + }
2316 + seg_fix = ( load_addr >> 4 ) & 0xffff;
2317 + if ( verbose ) {
2318 + printf ( "Loading %s %ld bytes ( %d relocs )\n",
2319 + filename, image_len, header.relen );
2320 + printf ( "Allocating %ld bytes of free ram at %05x\n",
2321 + ( long ) header.hmin * 16, load_addr );
2322 + printf ( "Total memory taken is %ld bytes\n", ( long ) total_paras * 16 );
2323 + printf ( " cs:ip == %04x:%04x ss:sp == %04x:%04x\n",
2324 + header.csval + seg_fix, header.ipval, header.ssval + seg_fix, header.spval );
2325 + }
2326 + for ( i = 0; i < header.relen; i++ ) {
2327 + fix = ( ( long ) fixups[i].segment << 4 ) + ( long ) fixups[i].offset;
2328 + ( *( unsigned int * ) &read_buff[fix] ) += seg_fix;
2329 + }
2330 + if( ( i = dt_loadmem( load_addr, image_len, read_buff ) ) ) {
2331 + fprintf ( stderr, "Error loading speech device at 0x%lX: status %d\n",
2332 + load_addr, i );
2333 + return -1;
2334 + }
2335 + csval = header.csval + seg_fix;
2336 + ipval = header.ipval;
2337 + if( ! dt_wait_dma( ) ) return -1;
2338 + outb_p( DMA_control, iobase+4 );
2339 + outb_p( DT_START_TASK, iobase+4 );
2340 + dma_state ^= STAT_dma_state;
2341 + if( ! dt_wait_dma( ) ) return -1;
2342 + outb_p( ipval & 0xFF, iobase+4 );
2343 + outb_p( (ipval>>8) & 0xFF, iobase+4 );
2344 + outb_p( csval & 0xFF, iobase+4 );
2345 + outb_p( (csval>>8) & 0xFF, iobase+4 );
2346 + dma_state ^= STAT_dma_state;
2347 + return 0;
2348 +}
2349 +
2350 +void release_io( void )
2351 +{
2352 + ioperm( (long)iobase, 8, 0 );
2353 + ioperm( (long)0x0080, 1, 0 );
2354 + if ( read_buff ) free( read_buff );
2355 +}
2356 +
2357 +parseparm( char *parm, char *value )
2358 +{
2359 + char *cp = parm+strlen( parm );
2360 + while ( --cp > parm ) if ( *cp > ' ' ) break;
2361 + cp[1] = '\0';
2362 + if ( !strcmp( parm, "io" ) ) {
2363 + long io = strtol( value, 0, 0 );
2364 + if ( io >= 0x100 && io <= 0x350 ) {
2365 + iobase = (u_short)io;
2366 + return;
2367 + }
2368 + fprintf( stderr, "invalid io value %s\n", value );
2369 + exit( 1 );
2370 + } else if ( !strcmp( parm,"verbose" ) ) {
2371 + verbose = atoi( value );
2372 + }
2373 +}
2374 +
2375 +do_test( void )
2376 +{
2377 + char buffer[512];
2378 + int len;
2379 + dma_state = dt_getstatus( ) & STAT_dma_state;
2380 + while ( fgets( buffer, 510, stdin ) ) {
2381 + len = strlen( buffer );
2382 + if ( len == 1 ) dt_flush( );
2383 + else {
2384 + if ( buffer[len-1] == '\n' ) buffer[len-1] = '\013';
2385 + dt_sendbuff( buffer, len );
2386 + }
2387 + }
2388 + *buffer = '\013';
2389 + dt_sendbuff( buffer, 1 );
2390 +}
2391 +
2392 +int main ( int argc, char **argv )
2393 +{
2394 + char name[80], *cp;
2395 + char *dirname = 0, *confname = "dec_pc.conf";
2396 + char *init_msg = "[:ra 360] dec pc initialized\011";
2397 + FILE *confile;
2398 + struct stat statbuf;
2399 + int maxsize = 0, status = 0;
2400 + while ( --argc > 0 ) {
2401 + argv++;
2402 + if ( !strcmp( *argv, "-v" ) ) verbose = 1;
2403 + else if ( !strcmp( *argv, "-t" ) ) intest = 1;
2404 + else dirname = *argv;
2405 + }
2406 + if ( !dirname ) dirname = "/usr/local/lib/dec_pc";
2407 + if ( chdir( dirname ) != 0 ) {
2408 + fprintf( stderr, "cannot chdir to %s\n", dirname );
2409 + exit( 1 );
2410 + }
2411 + if ( !( confile = fopen( confname, "r" ) ) ) {
2412 + fprintf( stderr, "could not open %s", confname );
2413 + exit( 1 );
2414 + }
2415 + while ( fgets( name, 80, confile ) ) {
2416 + cp = strchr( name, '\n' );
2417 + if ( cp ) *cp = '\0';
2418 + if ( ( cp = strchr( name, '=' ) ) ) {
2419 + *cp++ = '\0';
2420 + parseparm( name, cp );
2421 + continue;
2422 + }
2423 + if ( stat( name, &statbuf ) != 0 ) {
2424 + fprintf( stderr, "cannot stat %s\n", name );
2425 + exit( 1 );
2426 + }
2427 + if ( statbuf.st_size > maxsize ) maxsize = statbuf.st_size;
2428 + }
2429 + rewind( confile );
2430 + if ( ioperm( (long)0x0080, 1, 1 ) || ioperm( (long)iobase, 8, 1 ) ) {
2431 + fprintf( stderr, "could not get ioperm\n" );
2432 + exit( 1 );
2433 + }
2434 + atexit( release_io );
2435 + if ( testkernel( ) == 0 ) {
2436 + if ( intest ) do_test( );
2437 + else fprintf( stderr, "kernel already loaded\n" );
2438 + exit( 0 );
2439 + }
2440 + read_buff = malloc( maxsize );
2441 + if ( !read_buff ) {
2442 + fprintf( stderr, "cannot malloc %d bytes\n", maxsize );
2443 + exit( 1 );
2444 + }
2445 + while ( fgets( name, 80, confile ) && !status ) {
2446 + cp = strchr( name, '\n' );
2447 + if ( cp ) *cp = '\0';
2448 + if ( strchr( name, '=' ) ) continue; /* a parameter */
2449 + if ( !( cp = strchr( name, '.' ) ) ) continue;
2450 + cp++;
2451 + if ( !strcmp ( cp, "dic" ) ) {
2452 + status = loaddict ( name, "primary", PRIMARY_DIC );
2453 + } else if ( !strcmp ( cp, "dtu" ) ) {
2454 + status = loaddict ( name, "user", USER_DIC );
2455 + } else if ( !strcmp ( cp, "dta" ) ) {
2456 + status = loaddict ( name, "abbreviation file", ABBREV_DIC );
2457 + } else if ( !strcmp ( cp, "exe" ) ) {
2458 + status = loadexe ( name );
2459 + } else if ( !strcmp ( cp, "sys" ) ) {
2460 + status = loadkernel ( name );
2461 + }
2462 + }
2463 + if ( status ) fprintf( stderr, "status %d\n", status );
2464 + fclose( confile );
2465 + if ( status ) exit( status );
2466 + dt_sendbuff( init_msg, strlen( init_msg ) );
2467 + sleep( 1 );
2468 + if ( intest ) do_test( );
2469 + exit( 0 );
2470 +}
2471 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/dtload.h linux-dsd/drivers/char/speakup/dtload.h
2472 --- linux-2.6.15/drivers/char/speakup/dtload.h 1970-01-01 01:00:00.000000000 +0100
2473 +++ linux-dsd/drivers/char/speakup/dtload.h 2003-07-31 16:27:06.000000000 +0100
2474 @@ -0,0 +1,57 @@
2475 +/*
2476 + * This is the DECtalk PC firmware loader for the Linux kernel, version 1.0
2477 + *
2478 + * Original 386BSD source:
2479 + * Copyright (c) 1996 Brian Buhrow <buhrow@lothlorien.nfbcal.org>
2480 + *
2481 + * Adapted for Linux:
2482 + * Copyright (c) 1997 Nicolas Pitre <nico@cam.org>
2483 + *
2484 + * Adapted for speakup:
2485 + * Copyright (c) 2003 David Borowski <david575@golden.net>
2486 + *
2487 + * All rights reserved.
2488 + *
2489 + * This program is free software; you can redistribute it and/or modify
2490 + * it under the terms of the GNU General Public License as published by
2491 + * the Free Software Foundation; either version 2 of the License, or
2492 + * (at your option) any later version.
2493 + *
2494 + * This program is distributed in the hope that it will be useful,
2495 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2496 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2497 + * GNU General Public License for more details.
2498 + *
2499 + * You should have received a copy of the GNU General Public License
2500 + * along with this program; if not, write to the Free Software
2501 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2502 + *
2503 + */
2504 +
2505 +#define MAX_FIXUPS 512 /* maximum fixups per exe */
2506 +/*
2507 + * msdos .exe files will look like ...
2508 + */
2509 +
2510 +struct dos_exe_header {
2511 + unsigned short id; /* Linker's signature, must be 0x5a4d */
2512 + unsigned short rem; /* length of image mod 512 */
2513 + unsigned short pages; /* length of image in pages of 512 bytes */
2514 + unsigned short relen; /* number of relocation items */
2515 + unsigned short hsize; /* header size in paragraphs of 16 bytes */
2516 + unsigned short hmin; /* min # of paragraphs above prog end */
2517 + unsigned short hmax;
2518 + unsigned short ssval;
2519 + unsigned short spval; /* to be loaded in sp */
2520 + unsigned short checksum;
2521 + unsigned short ipval; /* to be loaded in ip */
2522 + unsigned short csval; /* segment offset to code */
2523 + unsigned short reloc; /* location of relocation items */
2524 + unsigned short ovrlay; /* overlay number */
2525 +};
2526 +
2527 +/* a dos relocation element looks like */
2528 +
2529 +struct dos_reloc {
2530 + short int offset, segment;
2531 +};
2532 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/dtpc_reg.h linux-dsd/drivers/char/speakup/dtpc_reg.h
2533 --- linux-2.6.15/drivers/char/speakup/dtpc_reg.h 1970-01-01 01:00:00.000000000 +0100
2534 +++ linux-dsd/drivers/char/speakup/dtpc_reg.h 2003-07-31 16:27:06.000000000 +0100
2535 @@ -0,0 +1,132 @@
2536 +/*
2537 + * This is the DECtalk PC register constants (from DEC's DOS driver)
2538 + *
2539 + * Original code:
2540 + * Copyright (c) by Digital Equipment Corp.
2541 + *
2542 + * 386BSD DECtalk PC driver:
2543 + * Copyright (c) 1996 Brian Buhrow <buhrow@lothlorien.nfbcal.org>
2544 + *
2545 + * Linux DECtalk PC driver:
2546 + * Copyright (c) 1997 Nicolas Pitre <nico@cam.org>
2547 + *
2548 + * speakup DECtalk PC driver:
2549 + * Copyright (c) 2003 David Borowski <david575@golden.net>
2550 + *
2551 + * All rights reserved.
2552 + *
2553 + * This program is free software; you can redistribute it and/or modify
2554 + * it under the terms of the GNU General Public License as published by
2555 + * the Free Software Foundation; either version 2 of the License, or
2556 + * (at your option) any later version.
2557 + *
2558 + * This program is distributed in the hope that it will be useful,
2559 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2560 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2561 + * GNU General Public License for more details.
2562 + *
2563 + * You should have received a copy of the GNU General Public License
2564 + * along with this program; if not, write to the Free Software
2565 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2566 + *
2567 + */
2568 +
2569 +/*
2570 + * port interface defs ... used by dtpc.c
2571 + */
2572 +
2573 +#define MODULE_init 0x0dec /* module in boot code */
2574 +#define MODULE_self_test 0x8800 /* module in self-test */
2575 +#define MODULE_reset 0xffff /* reinit the whole module */
2576 +
2577 +#define MODE_mask 0xf000 /* mode bits in high nibble */
2578 +#define MODE_null 0x0000
2579 +#define MODE_test 0x2000 /* in testing mode */
2580 +#define MODE_status 0x8000
2581 +#define STAT_int 0x0001 /* running in interrupt mode */
2582 +#define STAT_tr_char 0x0002 /* character data to transmit */
2583 +#define STAT_rr_char 0x0004 /* ready to receive char data */
2584 +#define STAT_cmd_ready 0x0008 /* ready to accept commands */
2585 +#define STAT_dma_ready 0x0010 /* dma command ready */
2586 +#define STAT_digitized 0x0020 /* spc in digitized mode */
2587 +#define STAT_new_index 0x0040 /* new last index ready */
2588 +#define STAT_new_status 0x0080 /* new status posted */
2589 +#define STAT_dma_state 0x0100 /* dma state toggle */
2590 +#define STAT_index_valid 0x0200 /* indexs are valid */
2591 +#define STAT_flushing 0x0400 /* flush in progress */
2592 +#define STAT_self_test 0x0800 /* module in self test */
2593 +#define MODE_ready 0xc000 /* module ready for next phase */
2594 +#define READY_boot 0x0000
2595 +#define READY_kernel 0x0001
2596 +#define MODE_error 0xf000
2597 +
2598 +#define CMD_mask 0xf000 /* mask for command nibble */
2599 +#define CMD_null 0x0000 /* post status */
2600 +#define CMD_control 0x1000 /* hard control command */
2601 +#define CTRL_mask 0x0F00 /* mask off control nibble */
2602 +#define CTRL_data 0x00FF /* madk to get data byte */
2603 +#define CTRL_null 0x0000 /* null control */
2604 +#define CTRL_vol_up 0x0100 /* increase volume */
2605 +#define CTRL_vol_down 0x0200 /* decrease volume */
2606 +#define CTRL_vol_set 0x0300 /* set volume */
2607 +#define CTRL_pause 0x0400 /* pause spc */
2608 +#define CTRL_resume 0x0500 /* resume spc clock */
2609 +#define CTRL_resume_spc 0x0001 /* resume spc soft pause */
2610 +#define CTRL_flush 0x0600 /* flush all buffers */
2611 +#define CTRL_int_enable 0x0700 /* enable status change ints */
2612 +#define CTRL_buff_free 0x0800 /* buffer remain count */
2613 +#define CTRL_buff_used 0x0900 /* buffer in use */
2614 +#define CTRL_speech 0x0a00 /* immediate speech change */
2615 +#define CTRL_SP_voice 0x0001 /* voice change */
2616 +#define CTRL_SP_rate 0x0002 /* rate change */
2617 +#define CTRL_SP_comma 0x0003 /* comma pause change */
2618 +#define CTRL_SP_period 0x0004 /* period pause change */
2619 +#define CTRL_SP_rate_delta 0x0005 /* delta rate change */
2620 +#define CTRL_SP_get_param 0x0006 /* return the desired parameter */
2621 +#define CTRL_last_index 0x0b00 /* get last index spoken */
2622 +#define CTRL_io_priority 0x0c00 /* change i/o priority */
2623 +#define CTRL_free_mem 0x0d00 /* get free paragraphs on module */
2624 +#define CTRL_get_lang 0x0e00 /* return bit mask of loaded languages */
2625 +#define CMD_test 0x2000 /* self-test request */
2626 +#define TEST_mask 0x0F00 /* isolate test field */
2627 +#define TEST_null 0x0000 /* no test requested */
2628 +#define TEST_isa_int 0x0100 /* assert isa irq */
2629 +#define TEST_echo 0x0200 /* make data in == data out */
2630 +#define TEST_seg 0x0300 /* set peek/poke segment */
2631 +#define TEST_off 0x0400 /* set peek/poke offset */
2632 +#define TEST_peek 0x0500 /* data out == *peek */
2633 +#define TEST_poke 0x0600 /* *peek == data in */
2634 +#define TEST_sub_code 0x00FF /* user defined test sub codes */
2635 +#define CMD_id 0x3000 /* return software id */
2636 +#define ID_null 0x0000 /* null id */
2637 +#define ID_kernel 0x0100 /* kernel code executing */
2638 +#define ID_boot 0x0200 /* boot code executing */
2639 +#define CMD_dma 0x4000 /* force a dma start */
2640 +#define CMD_reset 0x5000 /* reset module status */
2641 +#define CMD_sync 0x6000 /* kernel sync command */
2642 +#define CMD_char_in 0x7000 /* single character send */
2643 +#define CMD_char_out 0x8000 /* single character get */
2644 +#define CHAR_count_1 0x0100 /* one char in cmd_low */
2645 +#define CHAR_count_2 0x0200 /* the second in data_low */
2646 +#define CHAR_count_3 0x0300 /* the third in data_high */
2647 +#define CMD_spc_mode 0x9000 /* change spc mode */
2648 +#define CMD_spc_to_text 0x0100 /* set to text mode */
2649 +#define CMD_spc_to_digit 0x0200 /* set to digital mode */
2650 +#define CMD_spc_rate 0x0400 /* change spc data rate */
2651 +#define CMD_error 0xf000 /* severe error */
2652 +
2653 +enum { PRIMARY_DIC = 0, USER_DIC, COMMAND_DIC, ABBREV_DIC };
2654 +
2655 +#define DMA_single_in 0x01
2656 +#define DMA_single_out 0x02
2657 +#define DMA_buff_in 0x03
2658 +#define DMA_buff_out 0x04
2659 +#define DMA_control 0x05
2660 +#define DT_MEM_ALLOC 0x03
2661 +#define DT_SET_DIC 0x04
2662 +#define DT_START_TASK 0x05
2663 +#define DT_LOAD_MEM 0x06
2664 +#define DT_READ_MEM 0x07
2665 +#define DT_DIGITAL_IN 0x08
2666 +#define DMA_sync 0x06
2667 +#define DMA_sync_char 0x07
2668 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/genmap.c linux-dsd/drivers/char/speakup/genmap.c
2669 --- linux-2.6.15/drivers/char/speakup/genmap.c 1970-01-01 01:00:00.000000000 +0100
2670 +++ linux-dsd/drivers/char/speakup/genmap.c 2003-07-21 13:26:38.000000000 +0100
2671 @@ -0,0 +1,204 @@
2672 +#include <stdlib.h>
2673 +#include <stdio.h>
2674 +#include <libgen.h>
2675 +#include <string.h>
2676 +#include <linux/version.h>
2677 +#include <ctype.h>
2678 +
2679 +int get_define(void);
2680 +
2681 +#define MAXKEYS 512
2682 +#define MAXKEYVAL 160
2683 +#define HASHSIZE 101
2684 +#define is_shift -3
2685 +#define is_spk -2
2686 +#define is_input -1
2687 +typedef struct st_key_init t_key_init;
2688 +struct st_key_init {
2689 + char *name;
2690 + int value, shift;
2691 +};
2692 +typedef struct st_key t_key;
2693 +struct st_key {
2694 + char *name;
2695 + t_key *next;
2696 + int value, shift;
2697 +};
2698 +unsigned char key_data[MAXKEYVAL][16], *kp;
2699 +
2700 +#include "mapdata.h"
2701 +t_key key_table[MAXKEYS];
2702 +t_key *extra_keys = key_table+HASHSIZE;
2703 +char buffer[256], filename[256];
2704 +FILE *infile;
2705 +char delims[] = "\t\n ";
2706 +char *def_name, *def_val, *cp;
2707 +int map_ver = 119; /* an arbitrary number so speakup can check */
2708 +int lc, shift_table[17];
2709 +int max_states = 1, flags = 0;
2710 +/* flags reserved for later, maybe for individual console maps */
2711 +
2712 +void open_input( char *name )
2713 +{
2714 + strcpy( filename, name );
2715 + if ( ( infile = fopen( filename, "r" ) ) == 0 ) {
2716 + fprintf( stderr, "can't open %s, version %d\n", filename, LINUX_VERSION_CODE );
2717 + exit( 1 );
2718 + }
2719 + lc = 0;
2720 +}
2721 +
2722 +int
2723 +oops( char *msg, char *info )
2724 +{
2725 + if ( info == NULL ) info = " ";
2726 + fprintf( stderr, "error: file %s line %d\n", filename, lc );
2727 + fprintf( stderr, "%s %s\n", msg, info );
2728 + exit( 1 );
2729 +}
2730 +
2731 +t_key *hash_name( char *name )
2732 +{
2733 + u_char *pn = (u_char *)name;
2734 + int hash = 0;
2735 + while ( *pn ) {
2736 + hash = ( hash * 17 ) & 0xfffffff;
2737 + if ( isupper( *pn ) ) *pn = tolower( *pn );
2738 + hash += ( int )*pn;
2739 + pn++;
2740 + }
2741 + hash %= HASHSIZE;
2742 + return &key_table[hash];
2743 +}
2744 +
2745 +t_key *find_key( char *name )
2746 +{
2747 + t_key *this = hash_name( name );
2748 + while ( this ) {
2749 + if ( !strcmp( name, this->name ) ) return this;
2750 + this = this->next;
2751 + }
2752 + return this;
2753 +}
2754 +
2755 +t_key *add_key( char *name, int value, int shift )
2756 +{
2757 + t_key *this = hash_name( name );
2758 + if ( extra_keys-key_table >= MAXKEYS )
2759 + oops( "out of key table space, enlarge MAXKEYS", NULL );
2760 + if ( this->name != NULL ) {
2761 + while ( this->next ) {
2762 + if ( !strcmp( name, this->name ) )
2763 + oops( "attempt to add duplicate key", name );
2764 + this = this->next;
2765 + }
2766 + this->next = extra_keys++;
2767 + this = this->next;
2768 + }
2769 + this->name = strdup( name );
2770 + this->value = value;
2771 + this->shift = shift;
2772 + return this;
2773 +}
2774 +
2775 +int get_shift_value( int state )
2776 +{
2777 + int i;
2778 + for ( i = 0; shift_table[i] != state; i++ ) {
2779 + if ( shift_table[i] == -1 ) {
2780 + if ( i >= 16 )
2781 + oops( "too many shift states", NULL );
2782 + shift_table[i] = state;
2783 + max_states = i+1;
2784 + break;
2785 + }
2786 + }
2787 + return i;
2788 +}
2789 +
2790 +int
2791 +main( int argc, char *argv[] )
2792 +{
2793 + int value, shift_state, i, spk_val = 0, lock_val = 0;
2794 + int max_key_used = 0, num_keys_used = 0;
2795 + t_key *this;
2796 + t_key_init *p_init;
2797 +char *argpath, *argname, *argcopy;
2798 +
2799 + bzero( key_table, sizeof( key_table ) );
2800 + bzero( key_data, sizeof( key_data ) );
2801 + shift_table[0] = 0;
2802 + for ( i = 1; i <= 16; i++ ) shift_table[i] = -1;
2803 + if ( argc < 2 ) {
2804 + fputs( "usage: genmap filename\n", stderr );
2805 + exit( 1 );
2806 + }
2807 + for ( p_init = init_key_data; p_init->name[0] != '.'; p_init++ )
2808 + add_key( p_init->name, p_init->value, p_init->shift );
2809 + open_input( argv[1] );
2810 + while ( fgets( buffer, 250, infile ) ) {
2811 + lc++;
2812 + value = shift_state = 0;
2813 + cp = strtok( buffer, delims );
2814 + if ( *cp == '#' ) continue;
2815 + while ( cp ) {
2816 + if ( *cp == '=' ) break;
2817 + this = find_key( cp );
2818 + if ( this == NULL )
2819 + oops( "unknown key/modifier", cp );
2820 + if ( this->shift == is_shift ) {
2821 + if ( value )
2822 + oops( "modifiers must come first", cp );
2823 + shift_state += this->value;
2824 + } else if ( this->shift == is_input )
2825 + value = this->value;
2826 + else oops( "bad modifier or key", cp );
2827 + cp = strtok( 0, delims );
2828 + }
2829 + if ( !cp ) oops( "no = found", NULL );
2830 + cp = strtok( 0, delims );
2831 + if ( !cp ) oops( "no speakup function after =", NULL );
2832 + this = find_key( cp );
2833 + if ( this == NULL || this->shift != is_spk )
2834 + oops( "invalid speakup function", cp );
2835 + i = get_shift_value( shift_state );
2836 + if ( key_data[value][i] ) {
2837 + while ( --cp > buffer )
2838 + if ( !*cp ) *cp = ' ';
2839 + oops( "two functions on same key combination", cp );
2840 + }
2841 + key_data[value][i] = (char)this->value;
2842 + if ( value > max_key_used ) max_key_used = value;
2843 + }
2844 + fclose( infile );
2845 + this = find_key( "spk_key" );
2846 + if ( this ) spk_val = this->value;
2847 + this = find_key( "spk_lock" );
2848 + if ( this ) lock_val = this->value;
2849 + for ( lc = 1; lc <= max_key_used; lc++ ) {
2850 + kp = key_data[lc];
2851 + if ( !memcmp( key_data[0], kp, 16 ) ) continue;
2852 + num_keys_used++;
2853 + for ( i = 0; i < max_states; i++ ) {
2854 + if ( kp[i] != spk_val&& kp[i] != lock_val ) continue;
2855 + shift_state = shift_table[i];
2856 + if ( ( shift_state&16 ) ) continue;
2857 + shift_state = get_shift_value( shift_state+16 );
2858 + kp[shift_state] = kp[i];
2859 +/* fill in so we can process the key up, as spk bit will be set */
2860 + }
2861 + }
2862 + printf( "\t%d, %d, %d,\n\t", map_ver, num_keys_used, max_states );
2863 + for ( i = 0; i < max_states; i++ )
2864 + printf( "%d, ", shift_table[i] );
2865 + printf( "%d,", flags );
2866 + for ( lc = 1; lc <= max_key_used; lc++ ) {
2867 + kp = key_data[lc];
2868 + if ( !memcmp( key_data[0], kp, 16 ) ) continue;
2869 + printf( "\n\t%d,", lc );
2870 + for ( i = 0; i < max_states; i++ )
2871 + printf( " %d,", (unsigned int)kp[i] );
2872 + }
2873 + printf( "\n\t0, %d\n", map_ver );
2874 + exit( 0 );
2875 +}
2876 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/Kconfig linux-dsd/drivers/char/speakup/Kconfig
2877 --- linux-2.6.15/drivers/char/speakup/Kconfig 1970-01-01 01:00:00.000000000 +0100
2878 +++ linux-dsd/drivers/char/speakup/Kconfig 2003-12-10 15:29:56.000000000 +0000
2879 @@ -0,0 +1,210 @@
2880 +menu "Speakup console speech"
2881 +config SPEAKUP
2882 + tristate "Build speakup console speech"
2883 + ---help---
2884 +
2885 + This is the Speakup screen reader. Think of it as a
2886 + video console for blind people. If built in to the
2887 + kernel, it can speak evrything on the text console from
2888 + boot up to shutdown. For more information on Speakup,
2889 + point your browser at http://www.linux-speakup.org/.
2890 + There is also a mailing list at the above url that you
2891 + can subscribe to.
2892 +
2893 + Supported synthesizers are accent sa, accent pc, appollo
2894 + II., Auddapter, Braille 'n Speak, Dectalk external
2895 + (old), Dectalk PC (full length isa board), Dectalk
2896 + express, Doubletalk, Doubletalk LT or Litetalk,
2897 + Keynote
2898 + Gold internal PC, software synthesizers, Speakout, and transport.
2899 +
2900 + Speakup can either be built in or compiled as a module
2901 + by answering y or m. If you answer y here, then you
2902 + must answer either y or m to at least one of the
2903 + synthesizer drivers below. If you answer m here, then
2904 + the synthesizer drivers below can only be built as
2905 + modules.
2906 +
2907 + These drivers are not standalone drivers, but must be
2908 + used in conjunction with Speakup. Think of them as
2909 + video cards for blind people.
2910 +
2911 +
2912 + The Dectalk pc driver can only be built as a module, and
2913 + requires software to be pre-loaded on to the card before
2914 + the module can be loaded. See the decpc choice below
2915 + for more details.
2916 +
2917 + If you are not a blind person, or don't have access to
2918 + one of the listed synthesizers, you should say n.
2919 +
2920 +config SPEAKUP_ACNTSA
2921 + depends on SPEAKUP
2922 + tristate "Accent SA, acntsa"
2923 + ---help---
2924 +
2925 + This is the Speakup driver for the accent sa
2926 + synthesizer. You can say y to build it into the kernel,
2927 + or m to build it as a module. See the configuration
2928 + help on the Speakup choice above for more info.
2929 +
2930 +config SPEAKUP_ACNTPC
2931 + depends on SPEAKUP
2932 + tristate "Accent PC, acntpc"
2933 + ---help---
2934 +
2935 + This is the Speakup driver for the accent pc
2936 + synthesizer. You can say y to build it into the kernel,
2937 + or m to build it as a module. See the configuration
2938 + help on the Speakup choice above for more info.
2939 +
2940 +config SPEAKUP_APOLLO
2941 + depends on SPEAKUP
2942 + tristate "Apollo, apollo"
2943 + ---help---
2944 +
2945 + This is the Speakup driver for the Apollo II
2946 + synthesizer. You can say y to build it into the kernel,
2947 + or m to build it as a module. See the configuration
2948 + help on the Speakup choice above for more info.
2949 +
2950 +config SPEAKUP_AUDPTR
2951 + depends on SPEAKUP
2952 + tristate "Audapter, audptr"
2953 + ---help---
2954 +
2955 + This is the Speakup driver for the Audapter synthesizer.
2956 + You can say y to build it into the kernel, or m to
2957 + build it as a module. See the configuration help on the
2958 + Speakup choice above for more info.
2959 +
2960 +config SPEAKUP_BNS
2961 + depends on SPEAKUP
2962 + tristate "Braille 'n' Speak, bns"
2963 + ---help---
2964 +
2965 + This is the Speakup driver for the Braille 'n' Speak
2966 + synthesizer. You can say y to build it into the kernel,
2967 + or m to build it as a module. See the configuration
2968 + help on the Speakup choice above for more info.
2969 +
2970 +config SPEAKUP_DECTLK
2971 + depends on SPEAKUP
2972 + tristate "DECtalk Express, dectlk"
2973 + ---help---
2974 +
2975 + This is the Speakup driver for the DecTalk Express
2976 + synthesizer. You can say y to build it into the kernel,
2977 + or m to build it as a module. See the configuration
2978 + help on the Speakup choice above for more info.
2979 +
2980 +config SPEAKUP_DECEXT
2981 + depends on SPEAKUP
2982 + tristate "DECtalk External (old), decext"
2983 + ---help---
2984 +
2985 + This is the Speakup driver for the DecTalk External
2986 + (old) synthesizer. You can say y to build it into the
2987 + kernel, or m to build it as a module. See the
2988 + configuration help on the Speakup choice above for more
2989 + info.
2990 +
2991 +config SPEAKUP_DECPC
2992 + depends on SPEAKUP
2993 + tristate "DECtalk PC (big ISA card), decpc"
2994 + ---help---
2995 +
2996 + This is the Speakup driver for the DecTalk PC (full
2997 + length ISA) synthesizer. You can say m to build it as
2998 + a module. See the configuration help on the Speakup
2999 + choice above for more info.
3000 +
3001 + In order to use the DecTalk PC driver, you must download
3002 + the dec_pc.tgz file from linux-speakup.org. It is in
3003 + the pub/linux/goodies directory. The dec_pc.tgz file
3004 + contains the software which must be pre-loaded on to the
3005 + DecTalk PC board in order to use it with this driver.
3006 + This driver must be built as a module, and can not be
3007 + loaded until the file system is mounted and the DecTalk
3008 + PC software has been pre-loaded on to the board.
3009 +
3010 + See the README file in the dec_pc.tgz file for more
3011 + details.
3012 +
3013 +config SPEAKUP_DTLK
3014 + depends on SPEAKUP
3015 + tristate "DoubleTalk PC, dtlk"
3016 + ---help---
3017 +
3018 + This is the Speakup driver for the internal DoubleTalk
3019 + PC synthesizer. You can say y to build it into the
3020 + kernel, or m to build it as a module. See the
3021 + configuration help on the Speakup choice above for more
3022 + info.
3023 +
3024 +config SPEAKUP_KEYPC
3025 + depends on SPEAKUP
3026 + tristate "Keynote Gold PC, keypc"
3027 + ---help---
3028 +
3029 + This is the Speakup driver for the Keynote Gold
3030 + PC synthesizer. You can say y to build it into the
3031 + kernel, or m to build it as a module. See the
3032 + configuration help on the Speakup choice above for more
3033 + info.
3034 +
3035 +config SPEAKUP_LTLK
3036 + depends on SPEAKUP
3037 + tristate "DoubleTalk LT or LiteTalk, ltlk"
3038 +---help---
3039 +
3040 + This is the Speakup driver for the LiteTalk/DoubleTalk
3041 + LT synthesizer. You can say y to build it into the
3042 + kernel, or m to build it as a module. See the
3043 + configuration help on the Speakup choice above for more
3044 + info.
3045 +
3046 +config SPEAKUP_SFTSYN
3047 + depends on SPEAKUP
3048 + tristate "Software synthesizers, sftsyn"
3049 +---help---
3050 +
3051 + This is the software synthesizer device node. It will
3052 + register a device /dev/sftsyn which midware programs
3053 + and speech
3054 + daemons may open and read to provide kernel output to
3055 + software synths
3056 + such as festival, flite, tuxtalk and so forth. You
3057 + can select 'y' or
3058 + 'm' to have it built-in to the kernel or loaded as a module.
3059 +
3060 +config SPEAKUP_SPKOUT
3061 + depends on SPEAKUP
3062 + tristate "Speak Out, spkout"
3063 + ---help---
3064 +
3065 + This is the Speakup driver for the Speakout synthesizer.
3066 + You can say y to build it into the kernel, or m to
3067 + build it as a module. See the configuration help on the
3068 + Speakup choice above for more info.
3069 +
3070 +config SPEAKUP_TXPRT
3071 + depends on SPEAKUP
3072 + tristate "Transport, txprt"
3073 + ---help---
3074 +
3075 + This is the Speakup driver for the Transport
3076 + synthesizer. You can say y to build it into the kernel,
3077 + or m to build it as a module. See the configuration
3078 + help on the Speakup choice above for more info.
3079 +
3080 +if SPEAKUP != n
3081 + comment 'Enter the 3 to 6 character keyword from the list above, or none for no default synthesizer on boot up.'
3082 + depends on SPEAKUP
3083 +endif
3084 +
3085 +config SPEAKUP_DEFAULT
3086 + string "Choose Default synthesizer for Speakup"
3087 + default "none"
3088 +
3089 +endmenu
3090 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/keyinfo.h linux-dsd/drivers/char/speakup/keyinfo.h
3091 --- linux-2.6.15/drivers/char/speakup/keyinfo.h 1970-01-01 01:00:00.000000000 +0100
3092 +++ linux-dsd/drivers/char/speakup/keyinfo.h 2005-10-26 16:49:59.000000000 +0100
3093 @@ -0,0 +1,120 @@
3094 +/* spk_priv.h
3095 + review functions for the speakup screen review package.
3096 + originally written by: Kirk Reiser and Andy Berdan.
3097 +
3098 + extensively modified by David Borowski.
3099 +
3100 + Copyright (C ) 1998 Kirk Reiser.
3101 + Copyright (C ) 2003 David Borowski.
3102 +
3103 + This program is free software; you can redistribute it and/or modify
3104 + it under the terms of the GNU General Public License as published by
3105 + the Free Software Foundation; either version 2 of the License, or
3106 + (at your option ) any later version.
3107 +
3108 + This program is distributed in the hope that it will be useful,
3109 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3110 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3111 + GNU General Public License for more details.
3112 +
3113 + You should have received a copy of the GNU General Public License
3114 + along with this program; if not, write to the Free Software
3115 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3116 +*/
3117 +
3118 +enum { /* var_ids */
3119 + VERSION = 0, SYNTH, SILENT, SYNTH_DIRECT,
3120 + KEYMAP, CHARS,
3121 + PUNC_SOME, PUNC_MOST, PUNC_ALL,
3122 + DELIM, REPEATS, EXNUMBER,
3123 + DELAY, TRIGGER, JIFFY, FULL, /* all timers must be together */
3124 + BLEEP_TIME, CURSOR_TIME, BELL_POS,
3125 +SAY_CONTROL, SAY_WORD_CTL, NO_INTERRUPT, KEY_ECHO,
3126 + SPELL_DELAY, PUNC_LEVEL, READING_PUNC,
3127 + ATTRIB_BLEEP, BLEEPS,
3128 + RATE, PITCH, VOL, TONE, PUNCT, VOICE, FREQ, LANG,
3129 + CAPS_START, CAPS_STOP,
3130 + MAXVARS
3131 +};
3132 +
3133 +#define FIRST_SYNTH_VAR RATE
3134 +/* 0 is reserved for no remap */
3135 +#define SPEAKUP_GOTO 0x01
3136 +#define SPEECH_KILL 0x02
3137 +#define SPEAKUP_QUIET 0x03
3138 +#define SPEAKUP_CUT 0x04
3139 +#define SPEAKUP_PASTE 0x05
3140 +#define SAY_FIRST_CHAR 0x06
3141 +#define SAY_LAST_CHAR 0x07
3142 +#define SAY_CHAR 0x08
3143 +#define SAY_PREV_CHAR 0x09
3144 +#define SAY_NEXT_CHAR 0x0a
3145 +#define SAY_WORD 0x0b
3146 +#define SAY_PREV_WORD 0x0c
3147 +#define SAY_NEXT_WORD 0x0d
3148 +#define SAY_LINE 0x0e
3149 +#define SAY_PREV_LINE 0x0f
3150 +#define SAY_NEXT_LINE 0x10
3151 +#define TOP_EDGE 0x11
3152 +#define BOTTOM_EDGE 0x12
3153 +#define LEFT_EDGE 0x13
3154 +#define RIGHT_EDGE 0x14
3155 +#define SPELL_PHONETIC 0x15
3156 +#define SPELL_WORD 0x16
3157 +#define SAY_SCREEN 0x17
3158 +#define SAY_POSITION 0x18
3159 +#define SAY_ATTRIBUTES 0x19
3160 +#define SPEAKUP_OFF 0x1a
3161 +#define SPEAKUP_PARKED 0x1b
3162 +#define SAY_LINE_INDENT 0x1c
3163 +#define SAY_FROM_TOP 0x1d
3164 +#define SAY_TO_BOTTOM 0x1e
3165 +#define SAY_FROM_LEFT 0x1f
3166 +#define SAY_TO_RIGHT 0x20
3167 +#define SAY_CHAR_NUM 0x21
3168 +#define EDIT_SOME 0x22
3169 +#define EDIT_MOST 0x23
3170 +#define SAY_PHONETIC_CHAR 0x24
3171 +#define EDIT_DELIM 0x25
3172 +#define EDIT_REPEAT 0x26
3173 +#define EDIT_EXNUM 0x27
3174 +#define SET_WIN 0x28
3175 +#define CLEAR_WIN 0x29
3176 +#define ENABLE_WIN 0x2a
3177 +#define SAY_WIN 0x2b
3178 +#define SPK_LOCK 0x2c
3179 +#define SPEAKUP_HELP 0x2d
3180 +#define TOGGLE_CURSORING 0x2e
3181 +#define READ_ALL_DOC 0x2f
3182 +#define SPKUP_MAX_FUNC 0x30 /* one greater than the last func handler */
3183 +
3184 +#define SPK_KEY 0x80
3185 +#define FIRST_EDIT_BITS 0x22
3186 +
3187 +#define FIRST_SET_VAR SPELL_DELAY
3188 +#define VAR_START 0x40 /* increase if adding more than 0x3f functions */
3189 +
3190 +/* keys for setting variables, must be ordered same as the enum for var_ids */
3191 +/* with dec being even and inc being 1 greater */
3192 +#define SPELL_DELAY_DEC VAR_START+0
3193 +#define SPELL_DELAY_INC SPELL_DELAY_DEC+1
3194 +#define PUNC_LEVEL_DEC SPELL_DELAY_DEC+2
3195 +#define PUNC_LEVEL_INC PUNC_LEVEL_DEC+1
3196 +#define READING_PUNC_DEC PUNC_LEVEL_DEC+2
3197 +#define READING_PUNC_INC READING_PUNC_DEC+1
3198 +#define ATTRIB_BLEEP_DEC READING_PUNC_DEC+2
3199 +#define ATTRIB_BLEEP_INC ATTRIB_BLEEP_DEC+1
3200 +#define BLEEPS_DEC ATTRIB_BLEEP_DEC+2
3201 +#define BLEEPS_INC BLEEPS_DEC+1
3202 +#define RATE_DEC BLEEPS_DEC+2
3203 +#define RATE_INC RATE_DEC+1
3204 +#define PITCH_DEC RATE_DEC+2
3205 +#define PITCH_INC PITCH_DEC+1
3206 +#define VOL_DEC PITCH_DEC+2
3207 +#define VOL_INC VOL_DEC+1
3208 +#define TONE_DEC VOL_DEC+2
3209 +#define TONE_INC TONE_DEC+1
3210 +#define PUNCT_DEC TONE_DEC+2
3211 +#define PUNCT_INC PUNCT_DEC+1
3212 +#define VOICE_DEC PUNCT_DEC+2
3213 +#define VOICE_INC VOICE_DEC+1
3214 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/Makefile linux-dsd/drivers/char/speakup/Makefile
3215 --- linux-2.6.15/drivers/char/speakup/Makefile 1970-01-01 01:00:00.000000000 +0100
3216 +++ linux-dsd/drivers/char/speakup/Makefile 2004-10-21 15:39:22.000000000 +0100
3217 @@ -0,0 +1,61 @@
3218 +#
3219 +# Makefile for the speakup speech output system.
3220 +#
3221 +
3222 +V := $(shell awk '/UTS_RELEASE/ {print substr($$3,2,3)}' $(TOPDIR)/include/linux/version.h)
3223 +ifeq ($V,2.4)
3224 +# Note! Dependencies are done automagically by 'make dep', which also
3225 +# removes any old dependencies. DON'T put your own dependencies here
3226 +# unless it's something special (ie not a .c file).
3227 +#
3228 +# Note 2! The CFLAGS definitions are now inherited from the
3229 +# parent makes..
3230 +#
3231 +O_TARGET := spk.o
3232 +export-objs := speakup_drvcommon.o speakup.o
3233 +endif
3234 +obj-m = speakup_keyhelp.o
3235 +speakupmain-objs := speakup.o speakup_drvcommon.o
3236 +obj-$(CONFIG_SPEAKUP) += speakupmain.o
3237 +obj-$(CONFIG_SPEAKUP_ACNTPC) += speakup_acntpc.o
3238 +obj-$(CONFIG_SPEAKUP_ACNTSA) += speakup_acntsa.o
3239 +obj-$(CONFIG_SPEAKUP_APOLLO) += speakup_apollo.o
3240 +obj-$(CONFIG_SPEAKUP_AUDPTR) += speakup_audptr.o
3241 +obj-$(CONFIG_SPEAKUP_BNS) += speakup_bns.o
3242 +obj-$(CONFIG_SPEAKUP_DECEXT) += speakup_decext.o
3243 +obj-$(CONFIG_SPEAKUP_DECPC) += speakup_decpc.o
3244 +obj-$(CONFIG_SPEAKUP_DECTLK) += speakup_dectlk.o
3245 +obj-$(CONFIG_SPEAKUP_DTLK) += speakup_dtlk.o
3246 +obj-$(CONFIG_SPEAKUP_KEYPC) += speakup_keypc.o
3247 +obj-$(CONFIG_SPEAKUP_LTLK) += speakup_ltlk.o
3248 +obj-$(CONFIG_SPEAKUP_SFTSYN) += speakup_sftsyn.o
3249 +obj-$(CONFIG_SPEAKUP_SPKOUT) += speakup_spkout.o
3250 +obj-$(CONFIG_SPEAKUP_TXPRT) += speakup_txprt.o
3251 +
3252 +ifeq ($V,2.4)
3253 + include $(TOPDIR)/Rules.make
3254 +
3255 +speakupmap.h: speakupmap.map genmap
3256 + ./genmap speakupmap.map >$@
3257 +
3258 +genmap: genmap.c mapdata.h
3259 + cc -o genmap genmap.c
3260 +
3261 +mapdata.h: makemapdata.c keyinfo.h
3262 + cc -o makemapdata makemapdata.c
3263 + ./makemapdata >mapdata.h
3264 +
3265 +endif
3266 +speakupmain.o:speakup.o speakup_drvcommon.o
3267 + ld -r -o speakupmain.o speakup.o speakup_drvcommon.o
3268 +
3269 +$(obj)/speakupmap.h: $(src)/speakupmap.map $(src)/genmap
3270 + $(src)/genmap $(src)/speakupmap.map >$@
3271 +
3272 +$(obj)/mapdata.h: $(src)/keyinfo.h $(src)/makemapdata
3273 + $(src)/makemapdata >$@
3274 +
3275 +$(obj)/genmap: $(obj)/mapdata.h
3276 +
3277 +HOSTCFLAGS := -Iinclude -I/usr/include
3278 +hostprogs-y := makemapdata genmap
3279 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/makemapdata.c linux-dsd/drivers/char/speakup/makemapdata.c
3280 --- linux-2.6.15/drivers/char/speakup/makemapdata.c 1970-01-01 01:00:00.000000000 +0100
3281 +++ linux-dsd/drivers/char/speakup/makemapdata.c 2003-07-18 15:08:34.000000000 +0100
3282 @@ -0,0 +1,156 @@
3283 +#include <stdlib.h>
3284 +#include <stdio.h>
3285 +#include <libgen.h>
3286 +#include <string.h>
3287 +#include <linux/version.h>
3288 +#include <ctype.h>
3289 +
3290 +int get_define(void);
3291 +
3292 +#define MAXKEYS 512
3293 +#define MAXKEYVAL 160
3294 +#define HASHSIZE 101
3295 +#define is_shift -3
3296 +#define is_spk -2
3297 +#define is_input -1
3298 +typedef struct st_key t_key;
3299 +struct st_key {
3300 + char *name;
3301 + t_key *next;
3302 + int value, shift;
3303 +};
3304 +
3305 +t_key key_table[MAXKEYS];
3306 +t_key *extra_keys = key_table+HASHSIZE;
3307 +char buffer[256], filename[256];
3308 +FILE *infile;
3309 +char delims[] = "\t\n ";
3310 +char *dir_name, *def_name, *def_val, *cp;
3311 +int lc;
3312 +
3313 +void open_input( char *name )
3314 +{
3315 + sprintf( filename, "%s/%s", dir_name, name );
3316 + if ( ( infile = fopen( filename, "r" ) ) == 0 ) {
3317 + fprintf( stderr, "can't open %s\n", filename );
3318 + exit( 1 );
3319 + }
3320 + lc = 0;
3321 +}
3322 +
3323 +int
3324 +oops( char *msg, char *info )
3325 +{
3326 + if ( info == NULL ) info = " ";
3327 + fprintf( stderr, "error: file %s line %d\n", filename, lc );
3328 + fprintf( stderr, "%s %s\n", msg, info );
3329 + exit( 1 );
3330 +}
3331 +
3332 +int get_define( )
3333 +{
3334 + while ( fgets( buffer, 250, infile ) ) {
3335 + lc++;
3336 + if ( strncmp( buffer, "#define", 7 ) ) continue;
3337 + strtok( buffer, delims );
3338 + def_name = strtok( 0, delims );
3339 + def_val = strtok( 0, delims );
3340 + if ( def_val != NULL ) return 1;
3341 + }
3342 + fclose( infile );
3343 + infile = 0;
3344 + return 0;
3345 +}
3346 +
3347 +t_key *hash_name( char *name )
3348 +{
3349 + u_char *pn = (u_char *)name;
3350 + int hash = 0;
3351 + while ( *pn ) {
3352 + hash = ( hash * 17 ) & 0xfffffff;
3353 + if ( isupper( *pn ) ) *pn = tolower( *pn );
3354 + hash += ( int )*pn;
3355 + pn++;
3356 + }
3357 + hash %= HASHSIZE;
3358 + return &key_table[hash];
3359 +}
3360 +
3361 +t_key *find_key( char *name )
3362 +{
3363 + t_key *this = hash_name( name );
3364 + while ( this ) {
3365 + if ( !strcmp( name, this->name ) ) return this;
3366 + this = this->next;
3367 + }
3368 + return this;
3369 +}
3370 +
3371 +t_key *add_key( char *name, int value, int shift )
3372 +{
3373 + t_key *this = hash_name( name );
3374 + if ( extra_keys-key_table >= MAXKEYS )
3375 + oops( "out of key table space, enlarge MAXKEYS", NULL );
3376 + if ( this->name != NULL ) {
3377 + while ( this->next ) {
3378 + if ( !strcmp( name, this->name ) )
3379 + oops( "attempt to add duplicate key", name );
3380 + this = this->next;
3381 + }
3382 + this->next = extra_keys++;
3383 + this = this->next;
3384 + }
3385 + this->name = strdup( name );
3386 + this->value = value;
3387 + this->shift = shift;
3388 + return this;
3389 +}
3390 +
3391 +int
3392 +main( int argc, char *argv[] )
3393 +{
3394 + int value, i;
3395 + t_key *this;
3396 + dir_name = getenv( "TOPDIR" );
3397 + if ( !dir_name ) dir_name = "/usr/src/linux";
3398 + bzero( key_table, sizeof( key_table ) );
3399 + add_key( "shift", 1, is_shift );
3400 + add_key( "altgr", 2, is_shift );
3401 + add_key( "ctrl", 4, is_shift );
3402 + add_key( "alt", 8, is_shift );
3403 + add_key( "spk", 16, is_shift );
3404 + add_key( "double", 32, is_shift );
3405 + open_input( "include/linux/input.h" );
3406 + while ( get_define( ) ) {
3407 + if ( strncmp( def_name, "KEY_", 4 ) ) continue;
3408 + value = atoi( def_val );
3409 + if ( value > 0 && value < MAXKEYVAL )
3410 + add_key( def_name, value, is_input );
3411 + }
3412 + open_input( "drivers/char/speakup/keyinfo.h" );
3413 + while ( get_define( ) ) {
3414 + if ( strlen( def_val ) > 5 ) {
3415 + if ( !( cp = strchr( def_val, '+' ) ) ) continue;
3416 + *cp++ = '\0';
3417 + this = find_key( def_val );
3418 + if ( !this || *cp < '0' || *cp > '9' ) continue;
3419 + value = this->value+atoi( cp );
3420 + } else if ( !strncmp( def_val, "0x", 2 ) )
3421 + sscanf( def_val+2, "%x", &value );
3422 + else if ( *def_val >= '0' && *def_val <= '9' )
3423 + value = atoi( def_val );
3424 + else continue;
3425 + add_key( def_name, value, is_spk );
3426 + }
3427 + printf( "t_key_init init_key_data[] = {\n" );
3428 + for ( i = 0; i < HASHSIZE; i++ ) {
3429 + this = &key_table[i];
3430 + if ( !this->name ) continue;
3431 + do {
3432 + printf( "\t\"%s\", %d, %d,\n", this->name, this->value, this->shift );
3433 + this = this->next;
3434 + } while ( this );
3435 + }
3436 + printf( "\t\".\", 0, 0\n};\n" );
3437 + exit( 0 );
3438 +}
3439 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/mod_code.c linux-dsd/drivers/char/speakup/mod_code.c
3440 --- linux-2.6.15/drivers/char/speakup/mod_code.c 1970-01-01 01:00:00.000000000 +0100
3441 +++ linux-dsd/drivers/char/speakup/mod_code.c 2005-08-05 16:02:17.000000000 +0100
3442 @@ -0,0 +1,22 @@
3443 +/* this code is to modularize a synth specific file, included at the end */
3444 +
3445 +static void __exit mod_synth_exit( void )
3446 +{
3447 + if ( synth == &MY_SYNTH )
3448 + synth_release( );
3449 + synth_remove( &MY_SYNTH );
3450 +}
3451 +
3452 +static int __init mod_synth_init( void )
3453 +{
3454 + int status = do_synth_init( &MY_SYNTH );
3455 + if ( status != 0 ) return status;
3456 + synth_add( &MY_SYNTH );
3457 + return 0;
3458 +}
3459 +
3460 +module_init( mod_synth_init );
3461 +module_exit( mod_synth_exit );
3462 +MODULE_AUTHOR("Kirk Reiser <kirk@braille.uwo.ca>");
3463 +MODULE_DESCRIPTION("Synthesizer driver module for speakup for the synth->long_name");
3464 +MODULE_LICENSE( "GPL" );
3465 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/serialio.h linux-dsd/drivers/char/speakup/serialio.h
3466 --- linux-2.6.15/drivers/char/speakup/serialio.h 1970-01-01 01:00:00.000000000 +0100
3467 +++ linux-dsd/drivers/char/speakup/serialio.h 2003-05-05 14:56:33.000000000 +0100
3468 @@ -0,0 +1,18 @@
3469 +#ifndef SSPK_SERIAL
3470 +#define SSPK_SERIAL
3471 +
3472 +#include <linux/serial.h> /* for rs_table, serial constants &
3473 + serial_uart_config */
3474 +#include <linux/serial_reg.h> /* for more serial constants */
3475 +#include <linux/serialP.h> /* for struct serial_state */
3476 +#include <asm/serial.h>
3477 +
3478 +#define SPK_SERIAL_TIMEOUT 1000000 /* countdown values for serial timeouts */
3479 +#define SPK_XMITR_TIMEOUT 1000000 /* countdown values transmitter/dsr timeouts */
3480 +#define SPK_LO_TTY 0 /* check ttyS0 ... ttyS3 */
3481 +#define SPK_HI_TTY 3
3482 +#define NUM_DISABLE_TIMEOUTS 3 /* # of timeouts permitted before disable */
3483 +#define SPK_TIMEOUT 100 /* buffer timeout in ms */
3484 +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
3485 +
3486 +#endif
3487 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/speakup_acnt.h linux-dsd/drivers/char/speakup/speakup_acnt.h
3488 --- linux-2.6.15/drivers/char/speakup/speakup_acnt.h 1970-01-01 01:00:00.000000000 +0100
3489 +++ linux-dsd/drivers/char/speakup/speakup_acnt.h 2003-04-14 19:37:18.000000000 +0100
3490 @@ -0,0 +1,16 @@
3491 +/* speakup_acntpc.h - header file for speakups Accent-PC driver. */
3492 +
3493 +#define SYNTH_IO_EXTENT 0x02
3494 +
3495 +#define SYNTH_CLEAR 0x18 /* stops speech */
3496 +
3497 + /* Port Status Flags */
3498 +#define SYNTH_READABLE 0x01 /* mask for bit which is nonzero if a
3499 + byte can be read from the data port */
3500 +#define SYNTH_WRITABLE 0x02 /* mask for RDY bit, which when set to
3501 + 1, indicates the data port is ready
3502 + to accept a byte of data. */
3503 +#define SYNTH_QUIET 'S' /* synth is not speaking */
3504 +#define SYNTH_FULL 'F' /* synth is full. */
3505 +#define SYNTH_ALMOST_EMPTY 'M' /* synth has les than 2 seconds of text left */
3506 +#define SYNTH_SPEAKING 's' /* synth is speaking and has a fare way to go */
3507 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/speakup_acntpc.c linux-dsd/drivers/char/speakup/speakup_acntpc.c
3508 --- linux-2.6.15/drivers/char/speakup/speakup_acntpc.c 1970-01-01 01:00:00.000000000 +0100
3509 +++ linux-dsd/drivers/char/speakup/speakup_acntpc.c 2005-12-02 17:10:51.000000000 +0000
3510 @@ -0,0 +1,161 @@
3511 +/*
3512 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
3513 +* this version considerably modified by David Borowski, david575@rogers.com
3514 +
3515 + Copyright (C) 1998-99 Kirk Reiser.
3516 + Copyright (C) 2003 David Borowski.
3517 +
3518 + This program is free software; you can redistribute it and/or modify
3519 + it under the terms of the GNU General Public License as published by
3520 + the Free Software Foundation; either version 2 of the License, or
3521 + (at your option) any later version.
3522 +
3523 + This program is distributed in the hope that it will be useful,
3524 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3525 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3526 + GNU General Public License for more details.
3527 +
3528 + You should have received a copy of the GNU General Public License
3529 + along with this program; if not, write to the Free Software
3530 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3531 +
3532 + * this code is specificly written as a driver for the speakup screenreview
3533 + * package and is not a general device driver.
3534 + */
3535 +#include "spk_priv.h"
3536 +#include "speakup_acnt.h" /* local header file for Accent values */
3537 +
3538 +#define MY_SYNTH synth_acntpc
3539 +#define synth_readable( ) ( inb_p( synth_port_control ) & SYNTH_READABLE )
3540 +#define synth_writable( ) ( inb_p( synth_port_control ) & SYNTH_WRITABLE )
3541 +#define synth_full( ) ( inb_p( synth_port_tts ) == 'F' )
3542 +#define PROCSPEECH '\r'
3543 +
3544 +
3545 +static int synth_port_control;
3546 +static unsigned int synth_portlist[] =
3547 + { 0x2a8, 0 };
3548 +
3549 +static const char *synth_immediate ( const char *buf )
3550 +{
3551 + u_char ch;
3552 + while ( ( ch = *buf ) ) {
3553 + if ( ch == 0x0a ) ch = PROCSPEECH;
3554 + if ( synth_full( ) )
3555 + return buf;
3556 + while ( synth_writable( ) );
3557 + outb_p( ch, synth_port_tts );
3558 + buf++;
3559 + }
3560 + return 0;
3561 +}
3562 +
3563 +static void do_catch_up( unsigned long data )
3564 +{
3565 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
3566 + u_char ch;
3567 + synth_stop_timer( );
3568 + while ( synth_buff_out < synth_buff_in ) {
3569 + if ( synth_full( ) ) {
3570 + synth_delay( synth_full_time );
3571 + return;
3572 + }
3573 + while ( synth_writable( ) );
3574 + ch = *synth_buff_out++;
3575 + if ( ch == 0x0a ) ch = PROCSPEECH;
3576 + outb_p( ch, synth_port_tts );
3577 + if ( jiffies >= jiff_max && ch == SPACE ) {
3578 + while ( synth_writable( ) );
3579 + outb_p( PROCSPEECH, synth_port_tts );
3580 + synth_delay( synth_delay_time );
3581 + return;
3582 + }
3583 + }
3584 + while ( synth_writable( ) );
3585 + outb_p( PROCSPEECH, synth_port_tts );
3586 + synth_done( );
3587 +}
3588 +
3589 +static void synth_flush( void )
3590 +{
3591 + outb_p( SYNTH_CLEAR, synth_port_tts );
3592 +}
3593 +
3594 +static int synth_probe( void )
3595 +{
3596 + unsigned int port_val = 0;
3597 + int i = 0;
3598 + pr_info( "Probing for %s.\n", synth->long_name );
3599 + if ( synth_port_forced ) {
3600 + synth_port_tts = synth_port_forced;
3601 + pr_info( "probe forced to %x by kernel command line\n", synth_port_tts );
3602 + if ( synth_request_region( synth_port_tts-1, SYNTH_IO_EXTENT ) ) {
3603 + pr_warn( "sorry, port already reserved\n" );
3604 + return -EBUSY;
3605 + }
3606 + port_val = inw( synth_port_tts-1 );
3607 + synth_port_control = synth_port_tts-1;
3608 + } else {
3609 + for( i=0; synth_portlist[i]; i++ ) {
3610 + if ( synth_request_region( synth_portlist[i], SYNTH_IO_EXTENT ) ) {
3611 + pr_warn( "request_region: failed with 0x%x, %d\n",
3612 + synth_portlist[i], SYNTH_IO_EXTENT );
3613 + continue;
3614 + }
3615 + port_val = inw( synth_portlist[i] );
3616 + if ( ( port_val &= 0xfffc ) == 0x53fc ) { /* 'S' and out&input bits */
3617 + synth_port_control = synth_portlist[i];
3618 + synth_port_tts = synth_port_control+1;
3619 + break;
3620 + }
3621 + }
3622 + }
3623 + if ( ( port_val &= 0xfffc ) != 0x53fc ) { /* 'S' and out&input bits */
3624 + pr_info( "%s: not found\n", synth->long_name );
3625 + synth_release_region( synth_portlist[i], SYNTH_IO_EXTENT );
3626 + synth_port_control = 0;
3627 + return -ENODEV;
3628 + }
3629 + pr_info( "%s: %03x-%03x, driver version %s,\n", synth->long_name,
3630 + synth_port_control, synth_port_control+SYNTH_IO_EXTENT-1,
3631 + synth->version );
3632 + return 0;
3633 +}
3634 +
3635 +static void accent_release( void )
3636 +{
3637 + if ( synth_port_tts )
3638 + synth_release_region( synth_port_tts-1, SYNTH_IO_EXTENT );
3639 + synth_port_tts = 0;
3640 +}
3641 +
3642 +static int synth_is_alive( void )
3643 +{
3644 + synth_alive = 1;
3645 + return 1;
3646 +}
3647 +
3648 +static const char init_string[] = "\033=X \033Oi\033T2\033=M\033N1\n";
3649 +
3650 +static string_var stringvars[] = {
3651 + { CAPS_START, "\033P8" },
3652 + { CAPS_STOP, "\033P5" },
3653 + V_LAST_STRING
3654 +};
3655 +static num_var numvars[] = {
3656 + { RATE, "\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" },
3657 + { PITCH, "\033P%d", 5, 0, 9, 0, 0, 0 },
3658 + { VOL, "\033A%d", 5, 0, 9, 0, 0, 0 },
3659 + { TONE, "\033V%d", 5, 0, 9, 0, 0, 0 },
3660 + V_LAST_NUM
3661 +};
3662 +
3663 +struct spk_synth synth_acntpc = {"acntpc", "1.1", "Accent PC",
3664 + init_string, 500, 50, 50, 1000, 0, 0, SYNTH_CHECK,
3665 + stringvars, numvars, synth_probe, accent_release, synth_immediate,
3666 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL, NULL, NULL,
3667 + {NULL,0,0,0} };
3668 +
3669 +#ifdef MODULE
3670 +#include "mod_code.c"
3671 +#endif
3672 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/speakup_acntsa.c linux-dsd/drivers/char/speakup/speakup_acntsa.c
3673 --- linux-2.6.15/drivers/char/speakup/speakup_acntsa.c 1970-01-01 01:00:00.000000000 +0100
3674 +++ linux-dsd/drivers/char/speakup/speakup_acntsa.c 2005-12-02 17:10:51.000000000 +0000
3675 @@ -0,0 +1,185 @@
3676 +/*
3677 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
3678 +* this version considerably modified by David Borowski, david575@rogers.com
3679 +
3680 + Copyright (C) 1998-99 Kirk Reiser.
3681 + Copyright (C) 2003 David Borowski.
3682 +
3683 + This program is free software; you can redistribute it and/or modify
3684 + it under the terms of the GNU General Public License as published by
3685 + the Free Software Foundation; either version 2 of the License, or
3686 + (at your option) any later version.
3687 +
3688 + This program is distributed in the hope that it will be useful,
3689 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3690 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3691 + GNU General Public License for more details.
3692 +
3693 + You should have received a copy of the GNU General Public License
3694 + along with this program; if not, write to the Free Software
3695 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3696 +
3697 + * this code is specificly written as a driver for the speakup screenreview
3698 + * package and is not a general device driver.
3699 + */
3700 +#include "spk_priv.h"
3701 +#include "serialio.h"
3702 +#include "speakup_acnt.h" /* local header file for Accent values */
3703 +
3704 +#define MY_SYNTH synth_acntsa
3705 +#define synth_full( ) ( inb_p( synth_port_tts ) == 'F' )
3706 +#define PROCSPEECH '\r'
3707 +
3708 +static int timeouts = 0; /* sequential number of timeouts */
3709 +
3710 +static int
3711 +wait_for_xmitr ( void )
3712 +{
3713 + int check, tmout = SPK_XMITR_TIMEOUT;
3714 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
3715 + synth_alive = 0;
3716 + return 0;
3717 + }
3718 + do { /* holding register empty? */
3719 + check = inb_p ( synth_port_tts + UART_LSR );
3720 + if ( --tmout == 0 ) {
3721 + pr_warn ( "%s: timed out\n", synth->long_name );
3722 + timeouts++;
3723 + return 0;
3724 + }
3725 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
3726 + tmout = SPK_XMITR_TIMEOUT;
3727 + do { /* CTS */
3728 + check = inb_p ( synth_port_tts + UART_MSR );
3729 + if ( --tmout == 0 ) {
3730 + timeouts++;
3731 + return 0;
3732 + }
3733 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
3734 + timeouts = 0;
3735 + return 1;
3736 +}
3737 +
3738 +static inline int
3739 +spk_serial_out ( const char ch )
3740 +{
3741 + if ( synth_alive && wait_for_xmitr ( ) ) {
3742 + outb_p ( ch, synth_port_tts );
3743 + return 1;
3744 + }
3745 + return 0;
3746 +}
3747 +
3748 +static void
3749 +do_catch_up ( unsigned long data )
3750 +{
3751 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
3752 + u_char ch;
3753 + synth_stop_timer ( );
3754 + while ( synth_buff_out < synth_buff_in ) {
3755 + ch = *synth_buff_out;
3756 + if ( ch == 0x0a ) ch = 0x0D;
3757 + if ( !spk_serial_out ( ch ) ) {
3758 + synth_delay ( synth_full_time );
3759 + return;
3760 + }
3761 + synth_buff_out++;
3762 + if ( jiffies >= jiff_max && ch == ' ' ) {
3763 + spk_serial_out ( PROCSPEECH );
3764 + synth_delay ( synth_delay_time );
3765 + return;
3766 + }
3767 + }
3768 + spk_serial_out ( PROCSPEECH );
3769 + synth_done( );
3770 +}
3771 +
3772 +static const char *synth_immediate ( const char *buff )
3773 +{
3774 + u_char ch;
3775 + while ( ( ch = *buff ) ) {
3776 + if ( ch == 0x0a ) ch = PROCSPEECH;
3777 + if ( wait_for_xmitr( ) )
3778 + outb( ch, synth_port_tts );
3779 + else return buff;
3780 + buff++;
3781 + }
3782 + return 0;
3783 +}
3784 +
3785 +static void synth_flush ( void )
3786 +{
3787 + spk_serial_out ( SYNTH_CLEAR );
3788 +}
3789 +
3790 +static int serprobe ( int index )
3791 +{
3792 + struct serial_state *ser = spk_serial_init( index );
3793 + if ( ser == NULL ) return -1;
3794 + outb ( 0x0d, ser->port );
3795 + // mdelay ( 1 );
3796 + /* ignore any error results, if port was forced */
3797 + if ( synth_port_forced ) return 0;
3798 + /* check for accent s.a now... */
3799 + if ( !synth_immediate( "\x18" ) )
3800 + return 0;
3801 + spk_serial_release( );
3802 + timeouts = synth_alive = 0; /* not ignoring */
3803 + return -1;
3804 +}
3805 +
3806 +static int synth_probe ( void )
3807 +{
3808 + int i = 0, failed=0;
3809 + pr_info ( "Probing for %s.\n", synth->long_name );
3810 + for ( i = SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
3811 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
3812 + }
3813 + if ( failed ) {
3814 + pr_info ( "%s: not found\n", synth->long_name );
3815 + return -ENODEV;
3816 + }
3817 + pr_info ( "%s: %03x-%03x, Driver Version %s,\n", synth->long_name,
3818 + synth_port_tts, synth_port_tts + 7, synth->version );
3819 + synth_immediate( "\033=R\r" );
3820 + mdelay( 100 );
3821 + return 0;
3822 +}
3823 +
3824 +static int
3825 +synth_is_alive ( void )
3826 +{
3827 + if ( synth_alive ) return 1;
3828 + if ( !synth_alive && wait_for_xmitr ( ) > 0 ) { /* restart */
3829 + synth_alive = 1;
3830 + synth_write_string ( synth->init );
3831 + return 2;
3832 + }
3833 + pr_warn ( "%s: can't restart synth\n", synth->long_name );
3834 + return 0;
3835 +}
3836 +
3837 +static const char init_string[] = "\033T2\033=M\033Oi\033N1\n";
3838 +
3839 +static string_var stringvars[] = {
3840 + { CAPS_START, "\033P8" },
3841 + { CAPS_STOP, "\033P5" },
3842 + V_LAST_STRING
3843 +};
3844 +static num_var numvars[] = {
3845 + { RATE, "\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" },
3846 + { PITCH, "\033P%d", 5, 0, 9, 0, 0, 0 },
3847 + { VOL, "\033A%d", 9, 0, 9, 0, 0, 0 },
3848 + { TONE, "\033V%d", 5, 0, 9, 0, 0, 0 },
3849 + V_LAST_NUM
3850 +};
3851 +
3852 +struct spk_synth synth_acntsa = { "acntsa", "1.1", "Accent-SA",
3853 + init_string, 400, 5, 30, 1000, 0, 0, SYNTH_CHECK,
3854 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
3855 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL, NULL, NULL,
3856 + {NULL,0,0,0} };
3857 +
3858 +#ifdef MODULE
3859 +#include "mod_code.c"
3860 +#endif
3861 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/speakup_apollo.c linux-dsd/drivers/char/speakup/speakup_apollo.c
3862 --- linux-2.6.15/drivers/char/speakup/speakup_apollo.c 1970-01-01 01:00:00.000000000 +0100
3863 +++ linux-dsd/drivers/char/speakup/speakup_apollo.c 2005-12-02 17:10:51.000000000 +0000
3864 @@ -0,0 +1,196 @@
3865 +/*
3866 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
3867 +* this version considerably modified by David Borowski, david575@rogers.com
3868 +
3869 + Copyright (C) 1998-99 Kirk Reiser.
3870 + Copyright (C) 2003 David Borowski.
3871 +
3872 + This program is free software; you can redistribute it and/or modify
3873 + it under the terms of the GNU General Public License as published by
3874 + the Free Software Foundation; either version 2 of the License, or
3875 + (at your option) any later version.
3876 +
3877 + This program is distributed in the hope that it will be useful,
3878 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3879 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3880 + GNU General Public License for more details.
3881 +
3882 + You should have received a copy of the GNU General Public License
3883 + along with this program; if not, write to the Free Software
3884 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3885 +
3886 + * this code is specificly written as a driver for the speakup screenreview
3887 + * package and is not a general device driver.
3888 + */
3889 +#include "spk_priv.h"
3890 +#include "serialio.h"
3891 +
3892 +#define MY_SYNTH synth_apollo
3893 +#define SYNTH_CLEAR 0x18
3894 +#define PROCSPEECH '\r'
3895 +
3896 +static int timeouts = 0; /* sequential number of timeouts */
3897 +
3898 +static int wait_for_xmitr( void )
3899 +{
3900 + int check, tmout = SPK_XMITR_TIMEOUT;
3901 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
3902 + synth_alive = 0;
3903 + timeouts = 0;
3904 + return 0;
3905 + }
3906 + do {
3907 + check = inb( synth_port_tts + UART_LSR );
3908 + if ( --tmout == 0 ) {
3909 + pr_warn( "APOLLO: timed out\n" );
3910 + timeouts++;
3911 + return 0;
3912 + }
3913 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
3914 + tmout = SPK_XMITR_TIMEOUT;
3915 + do {
3916 + check = inb( synth_port_tts + UART_MSR );
3917 + if ( --tmout == 0 ) {
3918 + timeouts++;
3919 + return 0;
3920 + }
3921 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
3922 + timeouts = 0;
3923 + return 1;
3924 +}
3925 +
3926 +static inline int spk_serial_out( const char ch )
3927 +{
3928 + // int timer = 9000000;
3929 + if ( synth_alive && wait_for_xmitr( ) ) {
3930 + outb( ch, synth_port_tts );
3931 + /*while ( inb( synth_port_tts+UART_MSR ) & UART_MSR_CTS ) if ( --timer == 0 ) break;*/
3932 + /* outb( UART_MCR_DTR, synth_port_tts + UART_MCR );*/
3933 + return 1;
3934 + }
3935 + return 0;
3936 +}
3937 +
3938 +/*
3939 +static unsigned char spk_serial_in( void )
3940 +{
3941 + int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
3942 + do {
3943 + lsr = inb( synth_port_tts + UART_LSR );
3944 + if ( --tmout == 0 ) return 0xff;
3945 + } while ( !( lsr & UART_LSR_DR ) );
3946 + c = inb( synth_port_tts + UART_RX );
3947 + return ( unsigned char ) c;
3948 +}
3949 +*/
3950 +
3951 +static void do_catch_up( unsigned long data )
3952 +{
3953 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
3954 + u_char ch;
3955 +synth_stop_timer( );
3956 + while ( synth_buff_out < synth_buff_in ) {
3957 + ch = *synth_buff_out;
3958 + if ( !spk_serial_out( ch ) ) {
3959 + outb( UART_MCR_DTR, synth_port_tts + UART_MCR );
3960 + outb( UART_MCR_DTR | UART_MCR_RTS, synth_port_tts + UART_MCR );
3961 + synth_delay( synth_full_time );
3962 + return;
3963 + }
3964 + synth_buff_out++;
3965 + if ( jiffies >= jiff_max && synth_buff_out-synth_buffer > 10 ) {
3966 + spk_serial_out( PROCSPEECH );
3967 + synth_delay( synth_delay_time );
3968 + return;
3969 + }
3970 + }
3971 + spk_serial_out( PROCSPEECH );
3972 + synth_done( );
3973 +}
3974 +
3975 +static const char *synth_immediate ( const char *buf )
3976 +{
3977 + u_char ch;
3978 + while ( ( ch = *buf ) ) {
3979 + if ( ch == 0x0a ) ch = PROCSPEECH;
3980 + if ( wait_for_xmitr( ) )
3981 + outb( ch, synth_port_tts );
3982 + else return buf;
3983 + buf++;
3984 + }
3985 + return 0;
3986 +}
3987 +
3988 +static void synth_flush ( void )
3989 +{
3990 + spk_serial_out ( SYNTH_CLEAR );
3991 +}
3992 +
3993 +static int serprobe( int index )
3994 +{
3995 + struct serial_state *ser = spk_serial_init( index );
3996 + if ( ser == NULL ) return -1;
3997 + outb( 0x0d, ser->port ); /* wake it up if older BIOS */
3998 + mdelay( 1 );
3999 + synth_port_tts = ser->port;
4000 + if ( synth_port_forced ) return 0;
4001 + /* check for apollo now... */
4002 + if ( !synth_immediate( "\x18" ) ) return 0;
4003 + pr_warn( "port %x failed\n", synth_port_tts );
4004 + spk_serial_release( );
4005 + timeouts = synth_alive = synth_port_tts = 0;
4006 + return -1;
4007 +}
4008 +
4009 +static int synth_probe( void )
4010 +{
4011 +int i, failed=0;
4012 + pr_info( "Probing for %s.\n", synth->long_name );
4013 + for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
4014 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
4015 + }
4016 + if ( failed ) {
4017 + pr_info( "%s: not found\n", synth->long_name );
4018 + return -ENODEV;
4019 + }
4020 + pr_info( "%s: %03x-%03x, Driver version %s,\n", synth->long_name,
4021 + synth_port_tts, synth_port_tts + 7, synth->version );
4022 + return 0;
4023 +}
4024 +
4025 +static int synth_is_alive( void )
4026 +{
4027 + if ( synth_alive ) return 1;
4028 + if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
4029 + synth_alive = 1;
4030 + synth_write_string( synth->init );
4031 + return 2; /* reenabled */
4032 + } else pr_warn( "%s: can't restart synth\n", synth->long_name );
4033 + return 0;
4034 +}
4035 +
4036 +static const char init_string[] = "@R3@D0@K1\r";
4037 +
4038 +static string_var stringvars[] = {
4039 + { CAPS_START, "cap, " },
4040 + { CAPS_STOP, "" },
4041 + V_LAST_STRING
4042 +};
4043 +static num_var numvars[] = {
4044 + { RATE, "@W%d", 6, 1, 9, 0, 0, 0 },
4045 + { PITCH, "@F%x", 10, 0, 15, 0, 0, 0 },
4046 + { VOL, "@A%x", 10, 0, 15, 0, 0, 0 },
4047 + { VOICE, "@V%d", 1, 1, 6, 0, 0, 0 },
4048 + { LANG, "@=%d,", 1, 1, 4, 0, 0, 0 },
4049 + V_LAST_NUM
4050 +};
4051 +
4052 +struct spk_synth synth_apollo = {"apollo", "1.2", "Apollo",
4053 + init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
4054 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
4055 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL, NULL, NULL,
4056 + {NULL,0,0,0} };
4057 +
4058 +#ifdef MODULE
4059 +#include "mod_code.c"
4060 +#endif
4061 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/speakup_audptr.c linux-dsd/drivers/char/speakup/speakup_audptr.c
4062 --- linux-2.6.15/drivers/char/speakup/speakup_audptr.c 1970-01-01 01:00:00.000000000 +0100
4063 +++ linux-dsd/drivers/char/speakup/speakup_audptr.c 2005-12-02 17:10:51.000000000 +0000
4064 @@ -0,0 +1,202 @@
4065 +/*
4066 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
4067 +* this version considerably modified by David Borowski, david575@rogers.com
4068 +
4069 + Copyright (C) 1998-99 Kirk Reiser.
4070 + Copyright (C) 2003 David Borowski.
4071 +
4072 + This program is free software; you can redistribute it and/or modify
4073 + it under the terms of the GNU General Public License as published by
4074 + the Free Software Foundation; either version 2 of the License, or
4075 + (at your option) any later version.
4076 +
4077 + This program is distributed in the hope that it will be useful,
4078 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4079 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4080 + GNU General Public License for more details.
4081 +
4082 + You should have received a copy of the GNU General Public License
4083 + along with this program; if not, write to the Free Software
4084 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4085 +
4086 + * this code is specificly written as a driver for the speakup screenreview
4087 + * package and is not a general device driver.
4088 + */
4089 +#include "spk_priv.h"
4090 +#include "serialio.h"
4091 +
4092 +#define MY_SYNTH synth_audptr
4093 +#define SYNTH_CLEAR 0x18 /* flush synth buffer */
4094 +#define PROCSPEECH '\r' /* start synth processing speech char */
4095 +
4096 +static int timeouts = 0; /* sequential number of timeouts */
4097 +
4098 +static int wait_for_xmitr( void )
4099 +{
4100 + int check, tmout = SPK_XMITR_TIMEOUT;
4101 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
4102 + synth_alive = 0;
4103 + timeouts = 0;
4104 + return 0;
4105 + }
4106 + do { /* holding register empty? */
4107 + check = inb( synth_port_tts + UART_LSR );
4108 + if ( --tmout == 0 ) {
4109 + pr_warn( "%s: timed out\n", synth->long_name );
4110 + timeouts++;
4111 + return 0;
4112 + }
4113 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
4114 + tmout = SPK_XMITR_TIMEOUT;
4115 + do { /* CTS */
4116 + check = inb( synth_port_tts + UART_MSR );
4117 + if ( --tmout == 0 ) {
4118 + timeouts++;
4119 + return 0;
4120 + }
4121 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
4122 + timeouts = 0;
4123 + return 1;
4124 +}
4125 +
4126 +static inline int spk_serial_out( const char ch )
4127 +{
4128 + if ( synth_alive && wait_for_xmitr( ) ) {
4129 + outb( ch, synth_port_tts );
4130 + return 1;
4131 + }
4132 + return 0;
4133 +}
4134 +
4135 +static unsigned char spk_serial_in( void )
4136 +{
4137 + int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
4138 + do {
4139 + lsr = inb( synth_port_tts + UART_LSR );
4140 + if ( --tmout == 0 ) return 0xff;
4141 + } while ( !( lsr & UART_LSR_DR ) );
4142 + c = inb( synth_port_tts + UART_RX );
4143 + return ( unsigned char ) c;
4144 +}
4145 +
4146 +static void do_catch_up( unsigned long data )
4147 +{
4148 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
4149 + u_char ch;
4150 +synth_stop_timer( );
4151 + while ( synth_buff_out < synth_buff_in ) {
4152 + ch = *synth_buff_out;
4153 + if ( ch == 0x0a ) ch = PROCSPEECH;
4154 + if ( !spk_serial_out( ch ) ) {
4155 + synth_delay( synth_full_time );
4156 + return;
4157 + }
4158 + synth_buff_out++;
4159 + if ( jiffies >= jiff_max && ch == SPACE ) {
4160 + spk_serial_out( PROCSPEECH );
4161 + synth_delay( synth_delay_time );
4162 + return;
4163 + }
4164 + }
4165 + spk_serial_out( PROCSPEECH );
4166 + synth_done( );
4167 +}
4168 +
4169 +static const char *synth_immediate ( const char *buf )
4170 +{
4171 + u_char ch;
4172 + while ( ( ch = *buf ) ) {
4173 + if ( ch == 0x0a ) ch = PROCSPEECH;
4174 + if ( wait_for_xmitr( ) )
4175 + outb( ch, synth_port_tts );
4176 + else return buf;
4177 + buf++;
4178 + }
4179 + return 0;
4180 +}
4181 +
4182 +static void synth_flush( void )
4183 +{
4184 + while ( ( inb( synth_port_tts + UART_LSR ) & BOTH_EMPTY ) != BOTH_EMPTY );
4185 + outb( SYNTH_CLEAR, synth_port_tts );
4186 + spk_serial_out( PROCSPEECH );
4187 + }
4188 +
4189 +static char synth_id[40] = "";
4190 +
4191 +static int serprobe( int index )
4192 +{
4193 + u_char test = 0;
4194 + struct serial_state *ser = spk_serial_init( index );
4195 + if ( ser == NULL ) return -1;
4196 + /* ignore any error results, if port was forced */
4197 + if ( synth_port_forced )
4198 + return 0;
4199 + synth_immediate( "\x05[Q]" );
4200 + if ( ( synth_id[test] = spk_serial_in( ) ) == 'A' ) {
4201 + do { /* read version string from synth */
4202 + synth_id[++test] = spk_serial_in( );
4203 + } while ( synth_id[test] != '\n' && test < 32 );
4204 + synth_id[++test] = 0x00;
4205 + if ( test != 32 )
4206 + return 0;
4207 + }
4208 + spk_serial_release( );
4209 + timeouts = synth_alive = 0; /* not ignoring */
4210 + return -1;
4211 +}
4212 +
4213 +static int synth_probe( void )
4214 +{
4215 +int i=0, failed=0;
4216 + pr_info( "Probing for %s.\n", synth->long_name );
4217 + for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
4218 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
4219 + }
4220 + if ( failed ) {
4221 + pr_info( "%s: not found\n", synth->long_name );
4222 + return -ENODEV;
4223 + }
4224 + pr_info( "%s: %03x-%03x, Driver %s,\n", synth->long_name,
4225 + synth_port_tts, synth_port_tts + 7, synth->version );
4226 + if ( synth_id[0] == 'A' )
4227 + pr_info( "%s version: %s", synth->long_name, synth_id );
4228 + return 0;
4229 +}
4230 +
4231 +static int synth_is_alive( void )
4232 +{
4233 + if ( synth_alive ) return 1;
4234 + if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
4235 + synth_alive = 1;
4236 + synth_write_string( synth->init );
4237 + return 2;
4238 + }
4239 + return 0;
4240 +}
4241 +
4242 +static const char init_string[] = "\x05[D1]\x05[Ol]";
4243 +
4244 +static string_var stringvars[] = {
4245 + { CAPS_START, "\x05[f99]" },
4246 + { CAPS_STOP, "\x05[f80]" },
4247 + V_LAST_STRING
4248 +};
4249 +static num_var numvars[] = {
4250 + { RATE, "\x05[r%d]", 10, 0, 20, -100, 10, 0 },
4251 + { PITCH, "\x05[f%d]", 80, 39, 4500, 0, 0, 0 },
4252 + { VOL, "\x05[g%d]", 21, 0, 40, 0, 0, 0 },
4253 + { TONE, "\x05[s%d]", 9, 0,63, 0, 0, 0 },
4254 + { PUNCT, "\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" },
4255 + V_LAST_NUM
4256 +};
4257 +
4258 +struct spk_synth synth_audptr = {"audptr", "1.1", "Audapter",
4259 + init_string, 400, 5, 30, 5000, 0, 0, SYNTH_CHECK,
4260 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
4261 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL, NULL, NULL,
4262 + {NULL,0,0,0} };
4263 +
4264 +#ifdef MODULE
4265 +#include "mod_code.c"
4266 +#endif
4267 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/speakup_bns.c linux-dsd/drivers/char/speakup/speakup_bns.c
4268 --- linux-2.6.15/drivers/char/speakup/speakup_bns.c 1970-01-01 01:00:00.000000000 +0100
4269 +++ linux-dsd/drivers/char/speakup/speakup_bns.c 2005-12-02 17:10:51.000000000 +0000
4270 @@ -0,0 +1,175 @@
4271 +/*
4272 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
4273 +* this version considerably modified by David Borowski, david575@rogers.com
4274 +
4275 + Copyright (C) 1998-99 Kirk Reiser.
4276 + Copyright (C) 2003 David Borowski.
4277 +
4278 + This program is free software; you can redistribute it and/or modify
4279 + it under the terms of the GNU General Public License as published by
4280 + the Free Software Foundation; either version 2 of the License, or
4281 + (at your option) any later version.
4282 +
4283 + This program is distributed in the hope that it will be useful,
4284 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4285 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4286 + GNU General Public License for more details.
4287 +
4288 + You should have received a copy of the GNU General Public License
4289 + along with this program; if not, write to the Free Software
4290 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4291 +
4292 + * this code is specificly written as a driver for the speakup screenreview
4293 + * package and is not a general device driver.
4294 + */
4295 +#include "spk_priv.h"
4296 +#include "serialio.h"
4297 +
4298 +#define MY_SYNTH synth_bns
4299 +#define SYNTH_CLEAR 0x18
4300 +#define PROCSPEECH '\r'
4301 +
4302 +static int wait_for_xmitr( void )
4303 +{
4304 + static int timeouts = 0; /* sequential number of timeouts */
4305 + int check, tmout = SPK_XMITR_TIMEOUT;
4306 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
4307 + synth_alive = 0;
4308 + timeouts = 0;
4309 + return 0;
4310 + }
4311 + do {
4312 + check = inb( synth_port_tts + UART_LSR );
4313 + if ( --tmout == 0 ) {
4314 + pr_warn( "BNS: timed out\n" );
4315 + timeouts++;
4316 + return 0;
4317 + }
4318 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
4319 + tmout = SPK_XMITR_TIMEOUT;
4320 + do {
4321 + check = inb( synth_port_tts + UART_MSR );
4322 + if ( --tmout == 0 ) {
4323 + timeouts++;
4324 + return 0;
4325 + }
4326 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
4327 + timeouts = 0;
4328 + return 1;
4329 +}
4330 +
4331 +static inline int spk_serial_out( const char ch )
4332 +{
4333 + if ( synth_alive && wait_for_xmitr( ) ) {
4334 + outb( ch, synth_port_tts );
4335 + return 1;
4336 + }
4337 + return 0;
4338 +}
4339 +
4340 +static void do_catch_up( unsigned long data )
4341 +{
4342 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
4343 + u_char ch;
4344 + synth_stop_timer( );
4345 + while ( synth_buff_out < synth_buff_in ) {
4346 + ch = *synth_buff_out;
4347 + if ( ch == '\n' ) ch = PROCSPEECH;
4348 + if ( !spk_serial_out( ch ) ) {
4349 + synth_delay( synth_full_time );
4350 + return;
4351 + }
4352 + synth_buff_out++;
4353 + if ( jiffies >= jiff_max && ch == ' ' ) {
4354 + spk_serial_out( PROCSPEECH );
4355 + synth_delay( synth_delay_time );
4356 + return;
4357 + }
4358 + }
4359 + spk_serial_out( PROCSPEECH );
4360 + synth_done( );
4361 +}
4362 +
4363 +static const char *synth_immediate ( const char *buf )
4364 +{
4365 + u_char ch;
4366 + while ( ( ch = *buf ) ) {
4367 + if ( ch == 0x0a ) ch = PROCSPEECH;
4368 + if ( wait_for_xmitr( ) )
4369 + outb( ch, synth_port_tts );
4370 + else return buf;
4371 + buf++;
4372 + }
4373 + return 0;
4374 +}
4375 +
4376 +static void synth_flush ( void )
4377 +{
4378 + spk_serial_out ( SYNTH_CLEAR );
4379 +}
4380 +
4381 +static int serprobe( int index )
4382 +{
4383 + struct serial_state *ser = spk_serial_init( index );
4384 + if ( ser == NULL ) return -1;
4385 + outb( '\r', ser->port );
4386 + if ( synth_port_forced ) return 0;
4387 + /* check for bns now... */
4388 + if ( !synth_immediate( "\x18" ) ) return 0;
4389 + spk_serial_release( );
4390 + synth_alive = 0;
4391 + return -1;
4392 +}
4393 +
4394 +static int synth_probe( void )
4395 +{
4396 +int i=0, failed=0;
4397 + pr_info( "Probing for %s.\n", synth->long_name );
4398 + for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
4399 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
4400 + }
4401 + if ( failed ) {
4402 + pr_info( "%s: not found\n", synth->long_name );
4403 + return -ENODEV;
4404 + }
4405 + pr_info( "%s: %03x-%03x, Driver version %s,\n", synth->long_name,
4406 + synth_port_tts, synth_port_tts + 7, synth->version );
4407 + return 0;
4408 +}
4409 +
4410 +static int synth_is_alive( void )
4411 +{
4412 + if ( synth_alive ) return 1;
4413 + if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
4414 + synth_alive = 1;
4415 + synth_write_string( synth->init );
4416 + return 2;
4417 + }
4418 + pr_warn( "%s: can't restart synth\n", synth->long_name );
4419 + return 0;
4420 +}
4421 +
4422 +static const char init_string[] = "\x05Z\x05\x43";
4423 +
4424 +static string_var stringvars[] = {
4425 + { CAPS_START, "\x05\x31\x32P" },
4426 + { CAPS_STOP, "\x05\x38P" },
4427 + V_LAST_STRING
4428 +};
4429 +static num_var numvars[] = {
4430 + { RATE, "\x05%dE", 8, 1, 16, 0, 0, 0 },
4431 + { PITCH, "\x05%dP", 8, 0, 16, 0, 0, 0 },
4432 + { VOL, "\x05%dV", 8, 0, 16, 0, 0, 0 },
4433 + { TONE, "\x05%dT", 8, 0, 16, 0, 0, 0 },
4434 + V_LAST_NUM
4435 +};
4436 +
4437 +struct spk_synth synth_bns = {"bns", "1.1", "Braille 'N Speak",
4438 + init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
4439 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
4440 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL, NULL, NULL,
4441 + {NULL,0,0,0} };
4442 +
4443 +#ifdef MODULE
4444 +#include "mod_code.c"
4445 +#endif
4446 diff -urNpX dontdiff linux-2.6.15/drivers/char/speakup/speakup.c linux-dsd/drivers/char/speakup/speakup.c
4447 --- linux-2.6.15/drivers/char/speakup/speakup.c 1970-01-01 01:00:00.000000000 +0100
4448 +++ linux-dsd/drivers/char/speakup/speakup.c 2005-12-15 16:26:21.000000000 +0000
4449 @@ -0,0 +1,2721 @@
4450 +/* speakup.c
4451 + review functions for the speakup screen review package.
4452 + originally written by: Kirk Reiser and Andy Berdan.
4453 +
4454 + extensively modified by David Borowski.
4455 +
4456 + Copyright (C ) 1998 Kirk Reiser.
4457 + Copyright (C ) 2003 David Borowski.
4458 +
4459 + This program is free software; you can redistribute it and/or modify
4460 + it under the terms of the GNU General Public License as published by
4461 + the Free Software Foundation; either version 2 of the License, or
4462 + (at your option ) any later version.
4463 +
4464 + This program is distributed in the hope that it will be useful,
4465 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4466 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4467 + GNU General Public License for more details.
4468 +
4469 + You should have received a copy of the GNU General Public License
4470 + along with this program; if not, write to the Free Software
4471 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4472 +*/
4473 +
4474 +#define __KERNEL_SYSCALLS__
4475 +
4476 +#include <linux/kernel.h>
4477 +#include <linux/version.h>
4478 +#include <linux/vt.h>
4479 +#include <linux/tty.h>
4480 +#include <linux/mm.h> /* __get_free_page( ) and friends */
4481 +#include <linux/vt_kern.h>
4482 +#include <linux/ctype.h>
4483 +#include <linux/selection.h>
4484 +#include <asm/uaccess.h> /* copy_from|to|user( ) and others */
4485 +#include <linux/unistd.h>
4486 +
4487 +#include <linux/keyboard.h> /* for KT_SHIFT */
4488 +#include <linux/kbd_kern.h> /* for vc_kbd_* and friends */
4489 +#include <linux/vt_kern.h>
4490 +#include <linux/input.h>
4491 +#include <linux/kmod.h>
4492 +#include <linux/speakup.h>
4493 +
4494 +#include "cvsversion.h"
4495 +#include "spk_priv.h"
4496 +#include <linux/bootmem.h> /* for alloc_bootmem */
4497 +
4498 +/* speakup_*_selection */
4499 +#include <linux/module.h>
4500 +#include <linux/sched.h>
4501 +#include <linux/slab.h>
4502 +#include <linux/types.h>
4503 +#include <asm/uaccess.h>
4504 +#include <linux/consolemap.h>
4505 +
4506 +#define SPEAKUP_VERSION "Speakup v-2.00" CVSVERSION
4507 +#define MAX_DELAY ( (500 * HZ ) / 1000 )
4508 +#define KEY_MAP_VER 119
4509 +#define MINECHOCHAR SPACE
4510 +
4511 +/* these are globals from the kernel code */
4512 +extern void *kmalloc (size_t, unsigned int );
4513 +extern void kfree (const void * );
4514 +extern struct kbd_struct * kbd;
4515 +extern int fg_console;
4516 +extern short punc_masks[];
4517 +
4518 +static special_func special_handler = NULL;
4519 +special_func help_handler = NULL;
4520 +
4521 +int synth_file_inuse = 0;
4522 +short pitch_shift = 0, synth_flags = 0;
4523 +static char buf[256];
4524 +short attrib_bleep = 0, bleeps = 0, bleep_time = 1;
4525 +short no_intr = 0, spell_delay = 0;
4526 +short key_echo = 0, cursor_timeout = 120, say_word_ctl = 0;
4527 +short say_ctrl = 0, bell_pos = 0;
4528 +short punc_mask = 0, punc_level = 0, reading_punc = 0;
4529 +char str_caps_start[MAXVARLEN+1] = "\0", str_caps_stop[MAXVARLEN+1] = "\0";
4530 +bits_data punc_info[] = {
4531 + { "none", "", 0 },
4532 + { "some", "/$%&@", SOME },
4533 + { "most", "$%&#()=+*/@^<>|\\", MOST },
4534 + { "all", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", PUNC },
4535 + { "delimiters", "", B_WDLM },
4536 + { "repeats", "()", CH_RPT },
4537 + { "extended numeric", "", B_EXNUM },
4538 + { "symbols", "", B_SYM },
4539 + { 0, 0 }
4540 +};
4541 +char mark_cut_flag = 0;
4542 +u_short mark_x = 0, mark_y = 0;
4543 +char synth_name[10] = CONFIG_SPEAKUP_DEFAULT;
4544 +#define MAX_KEY 160
4545 +u_char *our_keys[MAX_KEY], *shift_table;
4546 +static u_char key_buf[600];
4547 +static u_char key_defaults[] = {
4548 +#include "speakupmap.h"
4549 +};
4550 +
4551 +// Speakup Cursor Track Variables
4552 +#define MAXCURSORTRACK 2
4553 +static int cursor_track = 1;
4554 +static int prev_cursor_track=1;
4555 +static int read_all_mode=MAXCURSORTRACK+1;
4556 +
4557 +struct tty_struct *tty;
4558 +#define key_handler k_handler
4559 +typedef void (*k_handler_fn)(struct vc_data *vc, unsigned char value,
4560 + char up_flag, struct pt_regs *regs);
4561 +#define KBD_PROTO struct vc_data *vc, u_char value, char up_flag, struct pt_regs *regs
4562 +#define KBD_ARGS vc, value, up_flag, regs
4563 +extern k_handler_fn key_handler[16];
4564 +static k_handler_fn do_shift, do_spec, do_latin, do_cursor;
4565 +EXPORT_SYMBOL( help_handler );
4566 +EXPORT_SYMBOL( special_handler );
4567 +EXPORT_SYMBOL( our_keys );
4568 +EXPORT_SYMBOL(synth_name);
4569 +
4570 +static void speakup_date (struct vc_data *vc );
4571 +static void spkup_write (const char *in_buf, int count );
4572 +int set_mask_bits( const char *input, const int which, const int how );
4573 +
4574 +char str_ctl[] = "control-";
4575 +char *colors[] = {
4576 + "black", "blue", "green", "cyan", "red", "magenta", "yellow", "white",
4577 + "grey"
4578 +};
4579 +
4580 +char *phonetic[] = {
4581 + "alpha", "beta", "charley", "delta", "echo", "fox", "gamma", "hotel",
4582 + "india", "juleiet", "keelo", "leema", "mike", "november", "oscar",
4583 + "papa",
4584 + "quebec", "romeo", "seeara", "tango", "uniform", "victer", "wiskey",
4585 + "x ray", "yankee", "zooloo"
4586 +};
4587 +
4588 +// array of 256 char pointers (one for each ASCII character description )
4589 +// initialized to default_chars and user selectable via /proc/speakup/characters
4590 +char *characters[256];
4591 +
4592 +char *default_chars[256] = {
4593 + "null", "^a", "^b", "^c", "^d", "^e", "^f", "^g",
4594 + "^h", "^i", "^j", "^k", "^l", "^m", "^n", "^o",
4595 + "^p", "^q", "^r", "^s", "^t", "^u", "^v", "^w",
4596 + "^x", "^y", "^z", NULL, NULL, NULL, NULL, NULL,
4597 + "space", "bang!", "quote", "number", "dollar", "percent", "and",
4598 + "tick",
4599 + "left paren", "right paren", "star", "plus", "comma", "dash", "dot",
4600 + "slash",
4601 + "zero", "one", "two", "three", "four", "five", "six", "seven",
4602 + "eight", "nine",
4603 + "colon", "semmy", "less", "equals", "greater", "question", "at",
4604 + "eigh", "b", "c", "d", "e", "f", "g",
4605 + "h", "i", "j", "k", "l", "m", "n", "o",
4606 + "p", "q", "r", "s", "t", "u", "v", "w", "x",
4607 + "y", "zehd", "left bracket", "backslash", "right bracket", "caret",
4608 + "line",
4609 + "accent", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4610 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4611 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4612 + NULL, NULL, NULL, "left brace", "bar", "right brace", "tihlduh",
4613 + "delta", "see cedilla", "u oomlout", "e acute", /* 128 */
4614 + "eigh circumflex", "eigh oomlout", "eigh grave", "eigh ring", /* 132 */
4615 + "see cedilla", "e circumflex", "e oomlout", "e grave", /* 136 */
4616 + "i oomlout", "i circumflex", "i grave", "eigh oomlout", /* 140 */
4617 + "eigh ring", "e acute", "eigh e dipthong", "eigh e dipthong", /* 144 */
4618 + "o circumflex", "o oomlout", "o grave", "u circumflex", /* 148 */
4619 + "u grave", "y oomlout", "o oomlout", "u oomlout", /* 152 */
4620 + "cents", "pounds", "yen", "peseta", /* 156 */
4621 + "florin", "eigh acute", "i acute", "o acute", /* 160 */
4622 + "u acute", "n tilde", "n tilde", "feminine ordinal", /* 164 */
4623 + "masculin ordinal", "inverted question", "reversed not", "not", /* 168 */
4624 + "half", "quarter", "inverted bang", "much less than", /* 172 */
4625 + "much greater than", "dark shading", "medium shading", /* 176 */
4626 + "light shading", "verticle line", "left tee", /* 179 */
4627 + "double left tee", "left double tee", "double top right", /* 182 */
4628 + "top double right", "double left double tee", /* 185 */
4629 + "double vertical line", "double top double right", /* 187 */
4630 + "double bottom double right", "double bottom right", /* 189 */
4631 + "bottom double right", "top right", "left bottom", /* 191 */
4632 + "up tee", "tee down", "tee right", "horizontal line", /* 194 */
4633 + "cross bars", "tee double right", "double tee right", /* 198 */
4634 + "double left double bottom", "double left double top", /* 201 */
4635 + "double up double tee", "double tee double down", /* 203 */
4636 + "double tee double right", "double horizontal line", /* 205 */
4637 + "double cross bars", "up double tee", "double up tee", /* 207 */
4638 + "double tee down", "tee double down", /* 210 */
4639 + "double left bottom", "left double bottom", /* 212 */
4640 + "double left top", "left double top", /* 214 */
4641 + "double vertical cross", "double horizontal cross", /* 216 */
4642 + "bottom right", "left top", "solid square", /* 218 */
4643 + "solid lower half", "solid left half", "solid right half", /* 221 */
4644 + "solid upper half", "alpha", "beta", "gamma", /* 224 */
4645 + "pie", "sigma", "sigma", "mu", /* 228 */
4646 + "tou", "phigh", "thayta", "ohmega", /* 232 */
4647 + "delta", "infinity", "phigh", "epsilaun", /* 236 */
4648 +"intersection", "identical to", "plus or minus", "equal grater than", /* 240 */
4649 + "less than equal", "upper integral", "lower integral", /* 244 */
4650 + "divided by", "almost equal", "degrees", /* 247 */
4651 + "centre dot", "bullet", "square root", /* 250 */
4652 + "power", "squared", "black square", "white space" /* 252 */
4653 +};
4654 +
4655 +u_short spk_chartab[256] = {
4656 + B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 0-7 */
4657 + B_CTL, B_CTL, A_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 8-15 */
4658 + B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /*16-23 */
4659 + B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 24-31 */
4660 +WDLM, A_PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* !"#$%&' */
4661 +PUNC, PUNC, PUNC, PUNC, A_PUNC, A_PUNC, A_PUNC, PUNC, /* ( )*+, -./ */
4662 +NUM, NUM, NUM, NUM, NUM, NUM, NUM, NUM, /* 01234567 */
4663 +NUM, NUM, A_PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* 89:;<=>? */
4664 +PUNC, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* @ABCDEFG */
4665 +A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* HIJKLMNO */
4666 +A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* PQRSTUVW */
4667 +A_CAP, A_CAP, A_CAP, PUNC, PUNC, PUNC, PUNC, PUNC, /* XYZ[\]^_ */
4668 +PUNC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* `abcdefg */
4669 +ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* hijklmno */
4670 +ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* pqrstuvw */
4671 +ALPHA, ALPHA, ALPHA, PUNC, PUNC, PUNC, PUNC, 0, /* xyz{|}~ */
4672 +B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 128-135 */
4673 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, /* 136-143 */
4674 +B_CAPSYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 144-151 */
4675 +B_SYM, B_SYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 152-159 */
4676 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, B_SYM, /* 160-167 */
4677 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 168-175 */
4678 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 176-183 */
4679 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 184-191 */
4680 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 192-199 */
4681 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 200-207 */
4682 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 208-215 */
4683 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 216-223 */
4684 +B_SYM, B_SYM, B_SYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, /* 224-231 */
4685 +B_SYM, B_CAPSYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 232-239 */
4686 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 240-247 */
4687 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM /* 248-255 */
4688 +};
4689 +
4690 +int spk_keydown = 0;
4691 +static u_char spk_lastkey = 0, spk_close_press = 0, keymap_flags = 0;
4692 +static u_char last_keycode = 0, this_speakup_key = 0;
4693 +static u_long last_spk_jiffy = 0;
4694 +
4695 +spk_t *speakup_console[MAX_NR_CONSOLES];
4696 +
4697 +int spk_setup (char *str )
4698 +{
4699 + int ints[4];
4700 + str = get_options (str, ARRAY_SIZE (ints ), ints );
4701 + if (ints[0] > 0 && ints[1] >= 0 )
4702 + synth_port_forced = ints[1];
4703 + return 1;
4704 +}
4705 +
4706 +int spk_ser_setup (char *str )
4707 +{
4708 + int lookup[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
4709 + int ints[4];
4710 + str = get_options (str, ARRAY_SIZE (ints ), ints );
4711 + if (ints[0] > 0 && ints[1] >= 0 )
4712 + synth_port_forced = lookup[ints[1]];
4713 + return 1;
4714 +}
4715 +
4716 +int spk_synth_setup (char *str )
4717 +{
4718 + size_t len = MIN (strlen (str ), 9 );
4719 + memcpy (synth_name, str, len );
4720 + synth_name[len] = '\0';
4721 + return 1;
4722 +}
4723 +
4724 +__setup ("speakup_port=", spk_setup );
4725 +__setup ("speakup_ser=", spk_ser_setup );
4726 +__setup ("speakup_synth=", spk_synth_setup );
4727 +
4728 +char *
4729 +strlwr (char *s )
4730 +{
4731 + char *p;
4732 + for (p = s; *p; p++ ) {
4733 + if (*p >= CAP_A && *p <= CAP_Z ) *p |= 32;
4734 + }
4735 + return s;
4736 +}
4737 +
4738 +static void
4739 +bleep (u_short val )
4740 +{
4741 + static short vals[] = { 350, 370, 392, 414, 440, 466, 491, 523,
4742 +554, 587, 619, 659 };
4743 + short freq;
4744 + int time = bleep_time;
4745 + freq = vals[val%12];
4746 + if (val > 11 )
4747 + freq *= (1<<(val/12 ) );
4748 + kd_mksound (freq, time );
4749 +}
4750 +
4751 +void
4752 +speakup_shut_up (struct vc_data *vc )
4753 +{
4754 + if (spk_killed ) return;
4755 + spk_shut_up |= 0x01;
4756 + spk_parked &= 0xfe;
4757 + speakup_date (vc );
4758 + if (synth == NULL ) return;
4759 + do_flush( );
4760 +}
4761 +
4762 +void
4763 +speech_kill (struct vc_data *vc )
4764 +{
4765 + char val = synth->is_alive ( );
4766 + if (val == 0 ) return;
4767 + /* re-enables synth, if disabled */
4768 + if (val == 2 || spk_killed ) { /* dead */
4769 + spk_shut_up &= ~0x40;
4770 + synth_write_msg ("Eyem a Lighve!" );
4771 + } else {
4772 + synth_write_msg ("You killed speak up!" );
4773 + spk_shut_up |= 0x40;
4774 + }
4775 +}
4776 +
4777 +static void
4778 +speakup_off (struct vc_data *vc )
4779 +{
4780 + if (spk_shut_up & 0x80 ) {
4781 + spk_shut_up &= 0x7f;
4782 + synth_write_msg ("hey. That's better!" );
4783 + } else {
4784 + spk_shut_up |= 0x80;
4785 + synth_write_msg ("You turned me off!" );
4786 + }
4787 + speakup_date (vc );
4788 +}
4789 +
4790 +static void
4791 +speakup_parked (struct vc_data *vc )
4792 +{
4793 + if (spk_parked & 0x80 ) {
4794 + spk_parked = 0;
4795 + synth_write_msg ("unparked!" );
4796 + } else {
4797 + spk_parked |= 0x80;
4798 + synth_write_msg ("parked!" );
4799 + }
4800 +}
4801 +
4802 +/* ------ cut and paste ----- */
4803 +/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */
4804 +#undef isspace
4805 +#define isspace(c) ((c) == ' ')
4806 +/* Variables for selection control. */
4807 +struct vc_data *spk_sel_cons; /* defined in selection.c must not be disallocated */
4808 +static volatile int sel_start = -1; /* cleared by clear_selection */
4809 +static int sel_end;
4810 +static int sel_buffer_lth;
4811 +static char *sel_buffer;
4812 +
4813 +static unsigned char
4814 +sel_pos(int n)
4815 +{
4816 + return inverse_translate(spk_sel_cons, screen_glyph(spk_sel_cons, n));
4817 +}
4818 +
4819 +static void
4820 +speakup_clear_selection(void)
4821 +{
4822 + sel_start = -1;
4823 +}
4824 +
4825 +/* does screen address p correspond to character at LH/RH edge of screen? */
4826 +static inline int atedge(const int p, int size_row)
4827 +{
4828 + return (!(p % size_row) || !((p + 2) % size_row));
4829 +}
4830 +
4831 +/* constrain v such that v <= u */
4832 +static inline unsigned short limit(const unsigned short v, const unsigned short u)
4833 +{
4834 + return (v > u) ? u : v;
4835 +}
4836 +
4837 +unsigned short xs, ys, xe, ye; /* our region points */
4838 +
4839 +static int
4840 +speakup_set_selection( struct tty_struct *tty)
4841 +{
4842 + int new_sel_start, new_sel_end;
4843 + char *bp, *obp;
4844 + int i, ps, pe;
4845 + struct vc_data *vc = vc_cons[fg_console].d;
4846 +
4847 + xs = limit(xs, vc->vc_cols - 1);
4848 + ys = limit(ys, vc->vc_rows - 1);
4849 + xe = limit(xe, vc->vc_cols - 1);
4850 + ye = limit(ye, vc->vc_rows - 1);
4851 + ps = ys * vc->vc_size_row + (xs << 1);
4852 + pe = ye * vc->vc_size_row + (xe << 1);
4853 +
4854 + if (ps > pe) { /* make sel_start <= sel_end */
4855 + int tmp = ps;
4856 + ps = pe;
4857 + pe = tmp;
4858 + }
4859 +
4860 + if (spk_sel_cons != vc_cons[fg_console].d) {
4861 + speakup_clear_selection();
4862 + spk_sel_cons = vc_cons[fg_console].d;
4863 + printk(KERN_WARNING "Selection: mark console not the same as cut\n");
4864 + return -EINVAL;
4865 + }
4866 +
4867 + new_sel_start = ps;
4868 + new_sel_end = pe;
4869 +
4870 + /* select to end of line if on trailing space */
4871 + if (new_sel_end > new_sel_start &&
4872 + !atedge(new_sel_end, vc->vc_size_row) &&
4873 + isspace(sel_pos(new_sel_end))) {
4874 + for (pe = new_sel_end + 2; ; pe += 2)
4875 + if (!isspace(sel_pos(pe)) ||
4876 + atedge(pe, vc->vc_size_row))
4877 + break;
4878 + if (isspace(sel_pos(pe)))
4879 + new_sel_end = pe;
4880 + }
4881 + if ((new_sel_start == sel_start)
4882 + && (new_sel_end == sel_end)) /* no action required */
4883 + return 0;
4884 +
4885 + sel_start = new_sel_start;
4886 + sel_end = new_sel_end;
4887 + /* Allocate a new buffer before freeing the old one ... */
4888 + bp = kmalloc((sel_end-sel_start)/2+1, GFP_ATOMIC);
4889 + if (!bp) {
4890 + printk(KERN_WARNING "selection: kmalloc() failed\n");
4891 + speakup_clear_selection();
4892 + return -ENOMEM;
4893 + }
4894 + if (sel_buffer)
4895 + kfree(sel_buffer);
4896 + sel_buffer = bp;
4897 +
4898 + obp = bp;
4899 + for (i = sel_start; i <= sel_end; i += 2) {
4900 + *bp = sel_pos(i);
4901 + if (!isspace(*bp++))
4902 + obp = bp;
4903 + if (! ((i + 2) % vc->vc_size_row)) {
4904 + /* strip trailing blanks from line and add newline,
4905 + unless non-space at end of line. */
4906 + if (obp != bp) {
4907 + bp = obp;
4908 + *bp++ = '\r';
4909 + }
4910 + obp = bp;
4911 + }
4912 + }
4913 + sel_buffer_lth = bp - sel_buffer;
4914 + return 0;
4915 +}
4916 +
4917 +static int
4918 +speakup_paste_selection(struct tty_struct *tty)
4919 +{
4920 + struct vc_data *vc = (struct vc_data *) tty->driver_data;
4921 + int pasted = 0, count;
4922 + DECLARE_WAITQUEUE(wait, current);
4923 + add_wait_queue(&vc->paste_wait, &wait);
4924 + while (sel_buffer && sel_buffer_lth > pasted) {
4925 + set_current_state(TASK_INTERRUPTIBLE);
4926 + if (test_bit(TTY_THROTTLED, &tty->flags)) {
4927 + schedule();
4928 + continue;
4929 + }
4930 + count = sel_buffer_lth - pasted;
4931 + count = MIN(count, tty->ldisc.receive_room(tty));
4932 + tty->ldisc.receive_buf(tty, sel_buffer + pasted, 0, count);
4933 + pasted += count;
4934 + }
4935 + remove_wait_queue(&vc->paste_wait, &wait);
4936 + current->state = TASK_RUNNING;
4937 + return 0;
4938 +}
4939 +
4940 +static void
4941 +speakup_cut (struct vc_data *vc )
4942 +{
4943 + static const char err_buf[] = "set selection failed";
4944 + int ret;
4945 +
4946 + if (!mark_cut_flag ) {
4947 + mark_cut_flag = 1;
4948 + xs = spk_x;
4949 + ys = spk_y;
4950 + spk_sel_cons = vc;
4951 + synth_write_msg ("mark" );
4952 + return;
4953 + }
4954 + xe = (u_short ) spk_x;
4955 + ye = (u_short )spk_y;
4956 + mark_cut_flag = 0;
4957 + synth_write_msg ("cut" );
4958 +
4959 + speakup_clear_selection( );
4960 + ret = speakup_set_selection ( tty );
4961 +
4962 + switch (ret ) {
4963 + case 0:
4964 + break; /* no error */
4965 + case -EFAULT :
4966 + pr_warn( "%sEFAULT\n", err_buf );
4967 + break;
4968 + case -EINVAL :
4969 + pr_warn( "%sEINVAL\n", err_buf );
4970 + break;
4971 + case -ENOMEM :
4972 + pr_warn( "%sENOMEM\n", err_buf );
4973 + break;
4974 + }
4975 +}
4976 +
4977 +static void
4978 +speakup_paste (struct vc_data *vc )
4979 +{
4980 + if (mark_cut_flag ) {
4981 + mark_cut_flag = 0;
4982 + synth_write_msg ("mark, cleared" );
4983 + } else {
4984 + synth_write_msg ("paste" );
4985 + speakup_paste_selection (tty );
4986 + }
4987 +}
4988 +
4989 +static void
4990 +say_attributes (struct vc_data *vc )
4991 +{
4992 + int fg= spk_attr&0x0f, bg = spk_attr>>4;
4993 + if (fg > 8 ) {
4994 + synth_write_string("bright " );
4995 + fg -= 8;
4996 + }
4997 + synth_write_string(colors[fg] );
4998 + if (bg > 7 ) {
4999 + synth_write_string(" on blinking " );
5000 + bg -= 8;
5001 + } else
5002 + synth_write_string(" on " );
5003 + synth_write_msg(colors[bg] );
5004 +}
5005 +
5006 +static char *blank_msg = "blank";
5007 +static char *edges[] = { "top, ", "bottom, ", "left, ", "right, ", "" };
5008 +enum { edge_top = 1, edge_bottom, edge_left, edge_right, edge_quiet };
5009 +
5010 +static void
5011 +announce_edge (struct vc_data *vc, int msg_id )
5012 +{
5013 + if (bleeps&1 )
5014 + bleep (spk_y );
5015 + if (bleeps&2 )
5016 + synth_write_msg (edges[msg_id-1] );
5017 +}
5018 +
5019 +static void
5020 +speak_char( u_char ch )
5021 +{
5022 + char *cp = characters[ ch];
5023 + synth_buffer_add( SPACE );
5024 + if (IS_CHAR(ch, B_CAP ) ) {
5025 + pitch_shift++;
5026 + synth_write_string(str_caps_start );
5027 + synth_write_string(cp );
5028 + synth_write_string(str_caps_stop );
5029 + } else {
5030 + if (*cp == '^' ) {
5031 + synth_write_string(str_ctl );
5032 + cp++;
5033 + }
5034 + synth_write_string(cp );
5035 + }
5036 + synth_buffer_add( SPACE );
5037 +}
5038 +
5039 +static void
5040 +say_char (struct vc_data *vc )
5041 +{
5042 + u_short ch;
5043 + spk_old_attr = spk_attr;
5044 + ch = scr_readw ((u_short * ) spk_pos );
5045 + spk_attr = ((ch & 0xff00 ) >> 8 );
5046 + if (spk_attr != spk_old_attr ) {
5047 + if ( attrib_bleep&1 ) bleep (spk_y );
5048 + if ( attrib_bleep&2 ) say_attributes( vc );
5049 + }
5050 + speak_char( ch&0xff );
5051 +}
5052 +
5053 +static void
5054 +say_phonetic_char (struct vc_data *vc )
5055 +{
5056 + u_short ch;
5057 + spk_old_attr = spk_attr;
5058 + ch = scr_readw ((u_short * ) spk_pos );
5059 + spk_attr = ((ch & 0xff00 ) >> 8 );
5060 + if ( IS_CHAR(ch, B_ALPHA ) ) {
5061 + ch &= 0x1f;
5062 + synth_write_msg(phonetic[--ch] );
5063 + } else {
5064 + if ( IS_CHAR(ch, B_NUM ) )
5065 + synth_write_string( "number " );
5066 + speak_char( ch );
5067 + }
5068 +}
5069 +
5070 +static void
5071 +say_prev_char (struct vc_data *vc )
5072 +{
5073 + spk_parked |= 0x01;
5074 + if (spk_x == 0 ) {
5075 + announce_edge(vc, edge_left );
5076 + return;
5077 + }
5078 + spk_x--;
5079 + spk_pos -= 2;
5080 + say_char (vc );
5081 +}
5082 +
5083 +static void
5084 +say_next_char (struct vc_data *vc )
5085 +{
5086 + spk_parked |= 0x01;
5087 + if (spk_x == vc->vc_cols - 1 ) {
5088 + announce_edge(vc, edge_right );
5089 + return;
5090 + }
5091 + spk_x++;
5092 + spk_pos += 2;
5093 + say_char (vc );
5094 +}
5095 +
5096 +/* get_word - will first check to see if the character under the
5097 + reading cursor is a space and if say_word_ctl is true it will
5098 + return the word space. If say_word_ctl is not set it will check to
5099 + see if there is a word starting on the next position to the right
5100 + and return that word if it exists. If it does not exist it will
5101 + move left to the beginning of any previous word on the line or the
5102 + beginning off the line whichever comes first.. */
5103 +
5104 +static u_long
5105 +get_word (struct vc_data *vc )
5106 +{
5107 + u_long cnt = 0, tmpx = spk_x, tmp_pos = spk_pos;
5108 + char ch;
5109 + u_short attr_ch;
5110 + spk_old_attr = spk_attr;
5111 + ch = (char ) scr_readw ((u_short * ) tmp_pos );
5112 +
5113 +/* decided to take out the sayword if on a space (mis-information */
5114 + if ( say_word_ctl && ch == SPACE ) {
5115 + *buf = '\0';
5116 + synth_write_msg( "space" );
5117 + return 0;
5118 + } else if ((tmpx < vc->vc_cols-2 )
5119 + && (ch == SPACE || IS_WDLM(ch ))
5120 + && ((char) scr_readw ((u_short * ) tmp_pos+1 ) > SPACE)) {
5121 + tmp_pos += 2;
5122 + tmpx++;
5123 + } else
5124 + while (tmpx > 0 ) {
5125 + if (((ch = (char ) scr_readw ((u_short * ) tmp_pos-1 )) == SPACE
5126 + || IS_WDLM(ch ))
5127 + && ((char) scr_readw ((u_short * ) tmp_pos ) > SPACE))
5128 + break;
5129 + tmp_pos -= 2;
5130 + tmpx--;
5131 + }
5132 + attr_ch = scr_readw ((u_short * ) tmp_pos );
5133 + spk_attr = attr_ch >> 8;
5134 + buf[cnt++] = attr_ch&0xff;
5135 + while (tmpx < vc->vc_cols-1 ) {
5136 + tmp_pos += 2;
5137 + tmpx++;
5138 + ch = (char ) scr_readw ((u_short * ) tmp_pos );
5139 + if ((ch == SPACE )
5140 + || (IS_WDLM(buf[cnt-1] ) && ( ch > SPACE )))
5141 + break;
5142 + buf[cnt++] = ch;
5143 + }
5144 + buf[cnt] = '\0';
5145 + return cnt;
5146 +}
5147 +
5148 +static void
5149 +say_word (struct vc_data *vc )
5150 +{
5151 + u_long cnt = get_word(vc );
5152 + u_short saved_punc_mask = punc_mask;
5153 + if ( cnt == 0 ) return;
5154 + punc_mask = PUNC;
5155 + buf[cnt++] = SPACE;
5156 + spkup_write (buf, cnt );
5157 + punc_mask = saved_punc_mask;
5158 +}
5159 +
5160 +static void
5161 +say_prev_word (struct vc_data *vc )
5162 +{
5163 + char ch;
5164 + u_short edge_said = 0, last_state = 0, state = 0;
5165 + spk_parked |= 0x01;
5166 + if (spk_x == 0 ) {
5167 + if ( spk_y == 0 ) {
5168 + announce_edge(vc, edge_top );
5169 + return;
5170 + }
5171 + spk_y--;
5172 + spk_x = vc->vc_cols;
5173 + edge_said = edge_quiet;
5174 + }
5175 + while ( 1 ) {
5176 + if (spk_x == 0 ) {
5177 + if (spk_y == 0 ) {
5178 + edge_said = edge_top;
5179 + break;
5180 + }
5181 + if ( edge_said != edge_quiet ) edge_said = edge_left;
5182 + if ( state > 0 ) break;
5183 + spk_y--;
5184 + spk_x = vc->vc_cols-1;
5185 + } else spk_x--;
5186 + spk_pos -= 2;
5187 + ch = (char ) scr_readw ((u_short * ) spk_pos );
5188 + if ( ch == SPACE ) state = 0;
5189 + else if (IS_WDLM(ch ) ) state = 1;
5190 + else state = 2;
5191 + if (state < last_state ) {
5192 + spk_pos += 2;
5193 + spk_x++;
5194 + break;
5195 + }
5196 + last_state = state;
5197 + }
5198 + if ( spk_x == 0 && edge_said == edge_quiet )
5199 + edge_said = edge_left;
5200 + if ( edge_said > 0 && edge_said < edge_quiet )
5201 + announce_edge( vc, edge_said );
5202 + say_word (vc );
5203 +}
5204 +
5205 +static void
5206 +say_next_word (struct vc_data *vc )
5207 +{
5208 + char ch;
5209 + u_short edge_said = 0, last_state = 2, state = 0;
5210 + spk_parked |= 0x01;
5211 + if ( spk_x == vc->vc_cols - 1 && spk_y == vc->vc_rows-1 ) {
5212 + announce_edge(vc, edge_bottom );
5213 + return;
5214 + }
5215 + while ( 1 ) {
5216 + ch = (char ) scr_readw ((u_short * ) spk_pos );
5217 + if ( ch == SPACE ) state = 0;
5218 + else if (IS_WDLM(ch ) ) state = 1;
5219 + else state = 2;
5220 + if ( state > last_state ) break;
5221 + if (spk_x >= vc->vc_cols-1 ) {
5222 + if (spk_y == vc->vc_rows-1 ) {
5223 + edge_said = edge_bottom;
5224 + break;
5225 + }
5226 + state = 0;
5227 + spk_y++;
5228 + spk_x = 0;
5229 + edge_said = edge_right;
5230 + } else spk_x++;
5231 + spk_pos += 2;
5232 + last_state = state;
5233 + }
5234 + if ( edge_said > 0 )
5235 + announce_edge( vc, edge_said );
5236 + say_word (vc );
5237 +}
5238 +
5239 +static void
5240 +spell_word (struct vc_data *vc )
5241 +{
5242 + static char *delay_str[] = { " ", ", ", ". ", ". . ", ". . . " };
5243 + char *cp = buf, *str_cap= str_caps_stop;
5244 + char *cp1, *last_cap = str_caps_stop;
5245 + u_char ch;
5246 + if ( !get_word(vc ) ) return;
5247 + while ((ch = (u_char )*cp ) ) {
5248 + if ( cp != buf )
5249 + synth_write_string (delay_str[spell_delay] );
5250 + if (IS_CHAR(ch, B_CAP ) ) {
5251 + str_cap = str_caps_start;
5252 + if ( *str_caps_stop ) pitch_shift++;
5253 + else last_cap = str_caps_stop; /* synth has no pitch */
5254 + } else str_cap = str_caps_stop;
5255 + if ( str_cap !=last_cap ) {
5256 + synth_write_string( str_cap );
5257 + last_cap = str_cap;
5258 + }
5259 + if ( this_speakup_key == SPELL_PHONETIC && ( IS_CHAR( ch, B_ALPHA ) ) ) {
5260 + ch &= 31;
5261 + cp1 = phonetic[--ch];
5262 + } else {
5263 + cp1 = characters[ch];
5264 + if (*cp1 == '^' ) {
5265 + synth_write_string(str_ctl );
5266 + cp1++;
5267 + }
5268 + }
5269 + synth_write_string(cp1 );
5270 + cp++;
5271 + }
5272 + if ( str_cap != str_caps_stop )
5273 + synth_write_string( str_caps_stop );
5274 +}
5275 +
5276 +static int
5277 +get_line (struct vc_data *vc )
5278 +{
5279 + u_long tmp = spk_pos - (spk_x * 2 );
5280 + int i = 0;
5281 + spk_old_attr = spk_attr;
5282 + spk_attr = (u_char ) (scr_readw ((u_short * ) spk_pos ) >> 8 );
5283 + for (i = 0; i < vc->vc_cols; i++ ) {
5284 + buf[i] = (u_char ) scr_readw ((u_short * ) tmp );
5285 + tmp += 2;
5286 + }
5287 + for (--i; i >= 0; i-- )
5288 + if (buf[i] != SPACE ) break;
5289 + return ++i;
5290 +}
5291 +
5292 +static void
5293 +say_line (struct vc_data *vc )
5294 +{
5295 + int i = get_line( vc );
5296 + char *cp;
5297 + char num_buf[8];
5298 + u_short saved_punc_mask = punc_mask;
5299 + if (i == 0 ) {
5300 + synth_write_msg (blank_msg );
5301 + return;
5302 + }
5303 + buf[i++] = '\n';
5304 + if ( this_speakup_key == SAY_LINE_INDENT ) {
5305 + for ( cp = buf; *cp == SPACE; cp++ );
5306 + sprintf( num_buf, "%d, ", ( cp-buf )+1 );
5307 + synth_write_string( num_buf );
5308 + }
5309 + punc_mask = punc_masks[reading_punc];
5310 + spkup_write (buf, i );
5311 + punc_mask = saved_punc_mask;
5312 +}
5313 +
5314 +static void
5315 +say_prev_line (struct vc_data *vc )
5316 +{
5317 + spk_parked |= 0x01;
5318 + if (spk_y == 0 ) {
5319 + announce_edge (vc, edge_top );
5320 + return;
5321 + }
5322 + spk_y--;
5323 + spk_pos -= vc->vc_size_row;
5324 + say_line (vc );
5325 +}
5326 +
5327 +static void
5328 +say_next_line (struct vc_data *vc )
5329 +{
5330 + spk_parked |= 0x01;
5331 + if (spk_y == vc->vc_rows - 1 ) {
5332 + announce_edge (vc, edge_bottom );
5333 + return;
5334 + }
5335 + spk_y++;
5336 + spk_pos += vc->vc_size_row;
5337 + say_line (vc );
5338 +}
5339 +
5340 +static int
5341 +say_from_to (struct vc_data *vc, u_long from, u_long to, int read_punc )
5342 +{
5343 + int i = 0;
5344 + u_short saved_punc_mask = punc_mask;
5345 + spk_old_attr = spk_attr;
5346 + spk_attr = (u_char ) (scr_readw ((u_short * ) from ) >> 8 );
5347 + while (from < to ) {
5348 + buf[i++] = (char ) scr_readw ((u_short * ) from );
5349 + from += 2;
5350 + if ( i >= vc->vc_size_row ) break;
5351 + }
5352 + for (--i; i >= 0; i-- )
5353 + if (buf[i] != SPACE ) break;
5354 + buf[++i] = SPACE;
5355 + buf[++i] = '\0';
5356 + if ( i < 1 ) return i;
5357 + if ( read_punc ) punc_mask = punc_info[reading_punc].mask;
5358 + spkup_write (buf, i );
5359 + if ( read_punc ) punc_mask = saved_punc_mask;
5360 + return i-1;
5361 +}
5362 +
5363 +static void
5364 +say_line_from_to (struct vc_data *vc, u_long from, u_long to, int read_punc )
5365 +{
5366 + u_long start = vc->vc_origin+(spk_y*vc->vc_size_row );
5367 + u_long end = start+( to * 2 );
5368 + start += from*2;
5369 + if ( say_from_to( vc, start, end, read_punc ) <= 0 )
5370 + if ( cursor_track != read_all_mode )
5371 + synth_write_msg (blank_msg );
5372 +}
5373 +
5374 +// Sentence Reading Commands
5375 +
5376 +void synth_insert_next_index( int );
5377 +
5378 +int currsentence;
5379 +int numsentences[2];
5380 +char *sentbufend[2];
5381 +char *sentmarks[2][10];
5382 +int currbuf=0;
5383 +int bn;
5384 +static char sentbuf[2][256];
5385 +
5386 +static int
5387 +say_sentence_num ( int num , int prev )
5388 +{
5389 + bn=currbuf;
5390 + currsentence=num+1;
5391 + if (prev)
5392 + {
5393 + bn--;
5394 + if (bn == -1)
5395 + bn=1;
5396 + }
5397 +
5398 + if (num>numsentences[bn])
5399 + return 0;
5400 + spkup_write (sentmarks[bn][num], sentbufend[bn]-sentmarks[bn][num]);
5401 +
5402 + return 1;
5403 +}
5404 +
5405 +static int
5406 +get_sentence_buf (struct vc_data *vc, int read_punc )
5407 +{
5408 + u_long start,end;
5409 + int i,bn;
5410 + currbuf++;
5411 + if ( currbuf == 2 )
5412 + currbuf=0;
5413 + bn=currbuf;
5414 + start = vc->vc_origin+((spk_y)*vc->vc_size_row );
5415 + end = vc->vc_origin+((spk_y)*vc->vc_size_row ) + vc->vc_cols*2;
5416 +
5417 + numsentences[bn]=0;
5418 + sentmarks[bn][0]=&sentbuf[bn][0];
5419 + i = 0;
5420 + spk_old_attr = spk_attr;
5421 + spk_attr = (u_char ) (scr_readw ((u_short * ) start ) >> 8 );
5422 +
5423 + while (start < end ) {
5424 + sentbuf[bn][i] = (char ) scr_readw ((u_short * ) start );
5425 + if (i>0)
5426 + {
5427 + if ((sentbuf[bn][i]==SPACE)&&(sentbuf[bn][i-1]=='.')&&(numsentences[bn]<9))
5428 + {
5429 + // Sentence Marker
5430 + numsentences[bn]++;
5431 + sentmarks[bn][numsentences[bn]]=&sentbuf[bn][i];
5432 + }
5433 + }
5434 + i++;
5435 + start += 2;
5436 + if ( i >= vc->vc_size_row )
5437 + break;
5438 + }
5439 +
5440 + for (--i; i >= 0; i-- )
5441 + if (sentbuf[bn][i] != SPACE )
5442 + break;
5443 +
5444 + if ( i < 1 )
5445 + return -1;
5446 +
5447 + sentbuf[bn][++i] = SPACE;
5448 + sentbuf[bn][++i] = '\0';
5449 +
5450 + sentbufend[bn]=&sentbuf[bn][i];
5451 + return numsentences[bn];
5452 +}
5453 +
5454 +//
5455 +
5456 +static void
5457 +say_screen_from_to (struct vc_data *vc, u_long from, u_long to )
5458 +{
5459 + u_long start = vc->vc_origin, end;
5460 + if ( from > 0 ) start += from * vc->vc_size_row;
5461 + if ( to > vc->vc_rows ) to = vc->vc_rows;
5462 + end = vc->vc_origin + ( to * vc->vc_size_row);
5463 + for ( from = start; from < end; from = to ) {
5464 + to = from + vc->vc_size_row;
5465 + say_from_to( vc, from, to, 1 );
5466 + }
5467 +}
5468 +
5469 +static void
5470 +say_screen (struct vc_data *vc )
5471 +{
5472 + say_screen_from_to( vc, 0, vc->vc_rows );
5473 +}
5474 +
5475 +static void
5476 +speakup_win_say (struct vc_data *vc )
5477 +{
5478 + u_long start, end, from, to;
5479 + if ( win_start < 2 ) {
5480 + synth_write_msg( "no window" );
5481 + return;
5482 + }
5483 + start = vc->vc_origin + ( win_top * vc->vc_size_row );
5484 + end = vc->vc_origin + ( win_bottom * vc->vc_size_row );
5485 + while ( start <= end ) {
5486 + from = start + ( win_left * 2 );
5487 + to = start + ( win_right * 2 );
5488 + say_from_to( vc, from, to, 1 );
5489 + start += vc->vc_size_row;
5490 + }
5491 +}
5492 +
5493 +static void
5494 +top_edge (struct vc_data *vc )
5495 +{
5496 + spk_parked |= 0x01;
5497 + spk_pos = vc->vc_origin + 2 * spk_x;
5498 + spk_y = 0;
5499 + say_line (vc );
5500 +}
5501 +
5502 +static void
5503 +bottom_edge (struct vc_data *vc )
5504 +{
5505 + spk_parked |= 0x01;
5506 + spk_pos += (vc->vc_rows - spk_y - 1 ) * vc->vc_size_row;
5507 + spk_y = vc->vc_rows - 1;
5508 + say_line (vc );
5509 +}
5510 +
5511 +static void
5512 +left_edge (struct vc_data *vc )
5513 +{
5514 + spk_parked |= 0x01;
5515 + spk_pos -= spk_x * 2;
5516 + spk_x = 0;
5517 + say_char (vc );
5518 +}
5519 +
5520 +static void
5521 +right_edge (struct vc_data *vc )
5522 +{
5523 + spk_parked |= 0x01;
5524 + spk_pos += (vc->vc_cols - spk_x - 1 ) * 2;
5525 + spk_x = vc->vc_cols - 1;
5526 + say_char (vc );
5527 +}
5528 +
5529 +static void
5530 +say_first_char (struct vc_data *vc )
5531 +{
5532 + int i, len = get_line( vc );
5533 + u_char ch;
5534 + spk_parked |= 0x01;
5535 + if ( len == 0 ) {
5536 + synth_write_msg( blank_msg );
5537 + return;
5538 + }
5539 + for ( i = 0; i < len; i++ ) if ( buf[i] != SPACE ) break;
5540 + ch = buf[i];
5541 + spk_pos -= ( spk_x-i ) * 2;
5542 + spk_x = i;
5543 + sprintf (buf, "%d, ", ++i );
5544 + synth_write_string (buf );
5545 + speak_char( ch );
5546 +}
5547 +
5548 +static void
5549 +say_last_char (struct vc_data *vc )
5550 +{
5551 + int len = get_line( vc );
5552 + u_char ch;
5553 + spk_parked |= 0x01;
5554 + if ( len == 0 ) {
5555 + synth_write_msg( blank_msg );
5556 + return;
5557 + }
5558 + ch = buf[--len];
5559 + spk_pos -= ( spk_x-len ) * 2;
5560 + spk_x = len;
5561 + sprintf (buf, "%d, ", ++len );
5562 + synth_write_string (buf );
5563 + speak_char( ch );
5564 +}
5565 +
5566 +static void
5567 +say_position (struct vc_data *vc )
5568 +{
5569 + sprintf (buf, "line %ld, col %ld, t t y %d\n", spk_y + 1,
5570 + spk_x + 1, vc->vc_num + 1 );
5571 + synth_write_string (buf );
5572 +}
5573 +
5574 +// Added by brianb
5575 +static void
5576 +say_char_num (struct vc_data *vc )
5577 +{
5578 + u_short ch = scr_readw ((u_short * ) spk_pos );
5579 + ch &= 0x0ff;
5580 + sprintf (buf, "hex %02x, decimal %d", ch, ch );
5581 + synth_write_msg (buf );
5582 +}
5583 +
5584 +/* these are stub functions to keep keyboard.c happy. */
5585 +
5586 +static void
5587 +say_from_top (struct vc_data *vc )
5588 +{
5589 + say_screen_from_to (vc, 0, spk_y );
5590 +}
5591 +
5592 +static void
5593 +say_to_bottom (struct vc_data *vc )
5594 +{
5595 + say_screen_from_to (vc, spk_y, vc->vc_rows );
5596 +}
5597 +
5598 +static void
5599 +say_from_left (struct vc_data *vc )
5600 +{
5601 + say_line_from_to (vc, 0, spk_x, 1 );
5602 +}
5603 +
5604 +static void
5605 +say_to_right (struct vc_data *vc )
5606 +{
5607 + say_line_from_to (vc, spk_x, vc->vc_cols, 1 );
5608 +}
5609 +
5610 +/* end of stub functions. */
5611 +
5612 +static void
5613 +spkup_write (const char *in_buf, int count )
5614 +{
5615 + static int rep_count = 0;
5616 + static u_char ch = '\0', old_ch = '\0';
5617 + static u_short char_type = 0, last_type = 0;
5618 + static u_char *exn_ptr = NULL;
5619 + int in_count = count;
5620 + char rpt_buf[32];
5621 + spk_keydown = 0;
5622 + while ( count-- ) {
5623 + if ( cursor_track == read_all_mode )
5624 + {
5625 + // Insert Sentence Index
5626 + if (( in_buf == sentmarks[bn][currsentence] ) &&
5627 + ( currsentence <= numsentences[bn] ))
5628 + {
5629 + synth_insert_next_index(currsentence);
5630 + currsentence++;
5631 + }
5632 + }
5633 + ch = (u_char )*in_buf++;
5634 + char_type = spk_chartab[ch];
5635 + if (ch == old_ch && !(char_type&B_NUM ) ) {
5636 + if (++rep_count > 2 ) continue;
5637 + } else {
5638 + if ( (last_type&CH_RPT) && rep_count > 2 ) {
5639 + sprintf (rpt_buf, " times %d . ", ++rep_count );
5640 + synth_write_string (rpt_buf );
5641 + }
5642 + rep_count = 0;
5643 + }
5644 + if ( !( char_type&B_NUM ) )
5645 + exn_ptr = NULL;
5646 + if (ch == spk_lastkey ) {
5647 + rep_count = 0;
5648 + if ( key_echo == 1 && ch >= MINECHOCHAR )
5649 + speak_char( ch );
5650 + } else if ( ( char_type&B_ALPHA ) ) {
5651 + if ( (synth_flags&SF_DEC) && (last_type&PUNC) )
5652 + synth_buffer_add ( SPACE );
5653 + synth_write( &ch, 1 );
5654 + } else if ( ( char_type&B_NUM ) ) {
5655 + rep_count = 0;
5656 + if ( (last_type&B_EXNUM) && synth_buff_in == exn_ptr+1 ) {
5657 + synth_buff_in--;
5658 + synth_buffer_add( old_ch );
5659 + exn_ptr = NULL;
5660 + }
5661 + synth_write( &ch, 1 );
5662 + } else if ( (char_type&punc_mask) ) {
5663 + speak_char( ch );
5664 + char_type &= ~PUNC; /* for dec nospell processing */
5665 + } else if ( ( char_type&SYNTH_OK ) ) {
5666 +/* these are usually puncts like . and , which synth needs for expression.
5667 + * suppress multiple to get rid of long pausesand clear repeat count so if
5668 + *someone has repeats on you don't get nothing repeated count */
5669 + if ( ch != old_ch )
5670 + synth_write( &ch, 1 );
5671 + else rep_count = 0;
5672 + } else {
5673 + if ( ( char_type&B_EXNUM ) )
5674 + exn_ptr = (u_char *)synth_buff_in;
5675 +/* send space and record position, if next is num overwrite space */
5676 + if ( old_ch != ch ) synth_buffer_add ( SPACE );
5677 + else rep_count = 0;
5678 + }
5679 + old_ch = ch;
5680 + last_type = char_type;
5681 + }
5682 + spk_lastkey = 0;
5683 + if (in_count > 2 && rep_count > 2 ) {
5684 + if ( (last_type&CH_RPT) ) {
5685 + sprintf (rpt_buf, " repeated %d . ", ++rep_count );
5686 + synth_write_string (rpt_buf );
5687 + }
5688 + rep_count = 0;
5689 + }
5690 +}
5691 +
5692 +static char *ctl_key_ids[] = {
5693 + "shift", "altgr", "control", "ault", "l shift", "speakup",
5694 +"l control", "r control"
5695 +};
5696 +#define NUM_CTL_LABELS 8
5697 +
5698 +static void read_all_doc( struct vc_data *vc);
5699 +void cursor_stop_timer(void );
5700 +
5701 +static void
5702 +handle_shift( KBD_PROTO )
5703 +{
5704 + (*do_shift)( KBD_ARGS );
5705 + if ( synth == NULL || up_flag || spk_killed ) return;
5706 + if (cursor_track==read_all_mode)
5707 + {
5708 + switch (value)
5709 + {
5710 + case KVAL(K_SHIFT):
5711 + cursor_stop_timer( );
5712 + spk_shut_up &= 0xfe;
5713 + do_flush();
5714 + read_all_doc( vc );
5715 + break;
5716 + case KVAL(K_CTRL):
5717 + cursor_stop_timer( );
5718 + cursor_track=prev_cursor_track;
5719 + spk_shut_up &= 0xfe;
5720 + do_flush();
5721 + break;
5722 + }
5723 + }
5724 + else
5725 + {
5726 + spk_shut_up &= 0xfe;
5727 + do_flush();
5728 + }
5729 + //synth_write_immediate("\x19");
5730 + if ( say_ctrl && value < NUM_CTL_LABELS )
5731 + synth_write_string ( ctl_key_ids[value] );
5732 +}
5733 +
5734 +static void
5735 +handle_latin( KBD_PROTO )
5736 +{
5737 + (*do_latin)( KBD_ARGS );
5738 + if ( up_flag ) {
5739 + spk_lastkey = spk_keydown = 0;
5740 + return;
5741 + }
5742 + if ( synth == NULL || spk_killed ) return;
5743 + spk_shut_up &= 0xfe;
5744 + spk_lastkey = value;
5745 + spk_keydown++;
5746 + spk_parked &= 0xfe;
5747 + if ( key_echo == 2 && value >= MINECHOCHAR )
5748 + speak_char( value );
5749 +}
5750 +
5751 +static int
5752 +set_key_info( u_char *key_info, u_char *k_buffer )
5753 +{
5754 + int i = 0, states, key_data_len;
5755 + u_char *cp = key_info, *cp1 = k_buffer;
5756 + u_char ch, version, num_keys;
5757 + version = *cp++;
5758 + if ( version != KEY_MAP_VER ) return -1;
5759 + num_keys = *cp;
5760 + states = (int)cp[1];
5761 + key_data_len = ( states+1 ) * ( num_keys+1 );
5762 + if ( key_data_len+SHIFT_TBL_SIZE+4 >= sizeof(key_buf ) ) return -2;
5763 + memset( k_buffer, 0, SHIFT_TBL_SIZE );
5764 + memset( our_keys, 0, sizeof( our_keys ) );
5765 + shift_table = k_buffer;
5766 + our_keys[0] = shift_table;
5767 + cp1 += SHIFT_TBL_SIZE;
5768 + memcpy( cp1, cp, key_data_len+3 );
5769 +/* get num_keys, states and data*/
5770 + cp1 += 2; /* now pointing at shift states */
5771 + for ( i = 1; i <= states; i++ ) {
5772 + ch = *cp1++;
5773 + if ( ch >= SHIFT_TBL_SIZE ) return -3;
5774 + shift_table[ch] = i;
5775 + }
5776 + keymap_flags = *cp1++;
5777 + while ( ( ch = *cp1 ) ) {
5778 + if ( ch >= MAX_KEY ) return -4;
5779 + our_keys[ch] = cp1;
5780 + cp1 += states+1;
5781 + }
5782 + return 0;
5783 +}
5784 +
5785 +num_var spk_num_vars[] = { /* bell must be first to set high limit */
5786 + { BELL_POS, 0, 0, 0, 0, 0, 0, 0 },
5787 + { SPELL_DELAY, 0, 0, 0, 5, 0, 0, 0 },
5788 + { ATTRIB_BLEEP, 0, 1, 0, 3, 0, 0, 0 },
5789 + { BLEEPS, 0, 3, 0, 3, 0, 0, 0 },
5790 + { BLEEP_TIME, 0, 4, 1, 20, 0, 0, 0 },
5791 + { PUNC_LEVEL, 0, 1, 0, 4, 0, 0, 0 },
5792 + { READING_PUNC, 0, 1, 0, 4, 0, 0, 0 },
5793 + { CURSOR_TIME, 0, 120, 50, 600, 0, 0, 0 },
5794 + { SAY_CONTROL, TOGGLE_0 },
5795 + { SAY_WORD_CTL, TOGGLE_0 },
5796 + { NO_INTERRUPT, TOGGLE_0 },
5797 + { KEY_ECHO, 0, 1, 0, 2, 0, 0, 0 },
5798 + V_LAST_NUM
5799 +};
5800 +
5801 +static char *cursor_msgs[] = { "cursoring off", "cursoring on",
5802 + "highlight tracking", "read all" };
5803 +//#define MAXCURSORTRACK 2 static int cursor_track = 1;static int prev_cursor_track=cursor_track;static int read_all_mode=MAXCURSORTRACK+1;
5804 +/* increase when we add more cursor modes */
5805 +/* attribute cursor code coming soon */
5806 +
5807 +static void
5808 +toggle_cursoring( struct vc_data *vc )
5809 +{
5810 + if (cursor_track==read_all_mode)
5811 + cursor_track=prev_cursor_track;
5812 + cursor_track++;
5813 + if ( cursor_track > MAXCURSORTRACK )
5814 + cursor_track = 0;
5815 + synth_write_msg (cursor_msgs[cursor_track] );
5816 +}
5817 +
5818 +static void
5819 +reset_default_chars (void )
5820 +{
5821 + int i;
5822 + if (default_chars[(int )'a'] == NULL ) { /* lowers are null first time */
5823 + for (i = (int )'a'; default_chars[i] == NULL; i++ )
5824 + default_chars[i] = default_chars[i-32];
5825 + } else { /* free any non-default */
5826 + for (i = 0; i < 256; i++ ) {
5827 + if (characters[i] != default_chars[i] )
5828 + kfree (characters[i] );
5829 + }
5830 + }
5831 + memcpy( characters, default_chars, sizeof( default_chars ) );
5832 +}
5833 +
5834 +static void
5835 +handle_cursor( KBD_PROTO );
5836 +static void
5837 +handle_spec( KBD_PROTO );
5838 +static void
5839 +cursor_done(u_long data );
5840 +
5841 +declare_timer( cursor_timer );
5842 +
5843 +void __init speakup_open (struct vc_data *vc, spk_t *first_console )
5844 +{
5845 + int i;
5846 + num_var *n_var;
5847 +
5848 + reset_default_chars();
5849 + memset( speakup_console, 0, sizeof(speakup_console));
5850 + if ( first_console == NULL ) return;
5851 + memset( first_console, 0, spk_size);
5852 + speakup_console[vc->vc_num] = first_console;
5853 + speakup_date(vc);
5854 + pr_info ("%s: initialized\n", SPEAKUP_VERSION );
5855 + init_timer(&cursor_timer);
5856 + cursor_timer.entry.prev = NULL;
5857 + cursor_timer.function = cursor_done;
5858 + init_sleeper(synth_sleeping_list);
5859 + strlwr(synth_name);
5860 + spk_num_vars[0].high = vc->vc_cols;
5861 + for ( n_var = spk_num_vars; n_var->var_id >= 0; n_var++ )
5862 + speakup_register_var(n_var);
5863 + for (i = 1; punc_info[i].mask != 0; i++ )
5864 + set_mask_bits( 0, i, 2 );
5865 + do_latin = key_handler[KT_LATIN];
5866 + key_handler[KT_LATIN] = handle_latin;
5867 + do_spec = key_handler[KT_SPEC];
5868 + key_handler[KT_SPEC] = handle_spec;
5869 + do_cursor = key_handler[KT_CUR];
5870 + key_handler[KT_CUR] = handle_cursor;
5871 + do_shift = key_handler[KT_SHIFT];
5872 + key_handler[KT_SHIFT] = handle_shift;
5873 + set_key_info(key_defaults, key_buf);
5874 +}
5875 +
5876 +#ifdef CONFIG_PROC_FS
5877 +
5878 +// speakup /proc interface code
5879 +
5880 +/* Usage:
5881 +cat /proc/speakup/version
5882 +
5883 +cat /proc/speakup/characters > foo
5884 +less /proc/speakup/characters
5885 +vi /proc/speakup/characters
5886 +
5887 +cat foo > /proc/speakup/characters
5888 +cat > /proc/speakup/characters
5889 +echo 39 apostrophe > /proc/speakup/characters
5890 +echo 87 w > /proc/speakup/characters
5891 +echo 119 w > /proc/speakup/characters
5892 +echo defaults > /proc/speakup/characters
5893 +echo reset > /proc/speakup/characters
5894 +*/
5895 +
5896 +// keymap handlers
5897 +
5898 +static int
5899 +keys_read_proc (PROC_READ_PROTOTYPE )
5900 +{
5901 + char *cp = page;
5902 + int i, n, num_keys, nstates;
5903 + u_char *cp1 = key_buf + SHIFT_TBL_SIZE, ch;
5904 + num_keys = (int)(*cp1);
5905 + nstates = (int)cp1[1];
5906 + cp += sprintf( cp, "%d, %d, %d,\n", KEY_MAP_VER, num_keys, nstates );
5907 + cp1 += 2; /* now pointing at shift states */
5908 +/* dump num_keys+1 as first row is shift states + flags,
5909 + each subsequent row is key + states */
5910 + for ( n = 0; n <= num_keys; n++ ) {
5911 + for ( i = 0; i <= nstates; i++ ) {
5912 + ch = *cp1++;
5913 + cp += sprintf( cp, "%d,", (int)ch );
5914 + *cp++ = ( i < nstates ) ? SPACE : '\n';
5915 + }
5916 + }
5917 + cp += sprintf( cp, "0, %d\n", KEY_MAP_VER );
5918 + *start = 0;
5919 + *eof = 1;
5920 + return (int)(cp-page);
5921 +}
5922 +
5923 +static char *
5924 +s2uchar ( char *start, char *dest )
5925 +{
5926 + int val = 0;
5927 + while ( *start && *start <= SPACE ) start++;
5928 + while ( *start >= '0' && *start <= '9' ) {
5929 + val *= 10;
5930 + val += ( *start ) - '0';
5931 + start++;
5932 + }
5933 + if ( *start == ',' ) start++;
5934 + *dest = (u_char)val;
5935 + return start;
5936 +}
5937 +
5938 +static int
5939 +keys_write_proc (PROC_WRITE_PROTOTYPE )
5940 +{
5941 + int i, ret = count;
5942 + char *in_buff, *cp;
5943 + u_char *cp1;
5944 + if (count < 1 || count > 1800 )
5945 + return -EINVAL;
5946 + in_buff = ( char * ) __get_free_page ( GFP_KERNEL );
5947 + if ( !in_buff ) return -ENOMEM;
5948 + if (copy_from_user (in_buff, buffer, count ) ) {
5949 + free_page ( ( unsigned long ) in_buff );
5950 + return -EFAULT;
5951 + }
5952 + if (in_buff[count - 1] == '\n' ) count--;
5953 + in_buff[count] = '\0';
5954 + if ( count == 1 && *in_buff == 'd' ) {
5955 + free_page ( ( unsigned long ) in_buff );
5956 + set_key_info( key_defaults, key_buf );
5957 + return ret;
5958 + }
5959 + cp = in_buff;
5960 + cp1 = (u_char *)in_buff;
5961 + for ( i = 0; i < 3; i++ ) {
5962 + cp = s2uchar( cp, cp1 );
5963 + cp1++;
5964 + }
5965 + i = (int)cp1[-2]+1;
5966 + i *= (int)cp1[-1]+1;
5967 + i+= 2; /* 0 and last map ver */
5968 + if ( cp1[-3] != KEY_MAP_VER || cp1[-1] > 10 ||
5969 + i+SHIFT_TBL_SIZE+4 >= sizeof(key_buf ) ) {
5970 +pr_warn( "i %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1] );
5971 + free_page ( ( unsigned long ) in_buff );
5972 + return -EINVAL;
5973 + }
5974 + while ( --i >= 0 ) {
5975 + cp = s2uchar( cp, cp1 );
5976 + cp1++;
5977 + if ( !(*cp) ) break;
5978 + }
5979 + if ( i != 0 || cp1[-1] != KEY_MAP_VER || cp1[-2] != 0 ) {
5980 + ret = -EINVAL;
5981 +pr_warn( "end %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1] );
5982 + } else {
5983 + if ( set_key_info( in_buff, key_buf ) ) {
5984 + set_key_info( key_defaults, key_buf );
5985 + ret = -EINVAL;
5986 +pr_warn( "set key failed\n" );
5987 + }
5988 + }
5989 + free_page ( ( unsigned long ) in_buff );
5990 + return ret;
5991 +}
5992 +
5993 +// this is the handler for /proc/speakup/version
5994 +static int
5995 +version_read_proc (PROC_READ_PROTOTYPE )
5996 +{
5997 + int len = sprintf (page, "%s\n", SPEAKUP_VERSION );
5998 + if ( synth != NULL )
5999 + len += sprintf( page+len, "synth %s version %s\n",
6000 + synth->name, synth->version );
6001 + *start = 0;
6002 + *eof = 1;
6003 + return len;
6004 +}
6005 +
6006 +// this is the read handler for /proc/speakup/characters
6007 +static int
6008 +chars_read_proc (PROC_READ_PROTOTYPE )
6009 +{
6010 + int i, len = 0;
6011 + off_t begin = 0;
6012 + char *cp;
6013 + for (i = 0; i < 256; i++ ) {
6014 + cp = (characters[i] ) ? characters[i] : "NULL";
6015 + len += sprintf (page + len, "%d\t%s\n", i, cp );
6016 + if (len + begin > off + count )
6017 + break;
6018 + if (len + begin < off ) {
6019 + begin += len;
6020 + len = 0;
6021 + }
6022 + }
6023 + if (i >= 256 )
6024 + *eof = 1;
6025 + if (off >= len + begin )
6026 + return 0;
6027 + *start = page + (off - begin );
6028 + return ((count < begin + len - off ) ? count : begin + len - off );
6029 +}
6030 +
6031 +static volatile int chars_timer_active = 0; // indicates when timer is set
6032 +static declare_timer( chars_timer );
6033 +
6034 +static inline void
6035 +chars_stop_timer (void )
6036 +{
6037 + if (chars_timer_active )
6038 + stop_timer ( chars_timer );
6039 +}
6040 +
6041 +static int strings, rejects, updates;
6042 +
6043 +static void
6044 +show_char_results (u_long data )
6045 +{
6046 + int len;
6047 + char buf[80];
6048 + chars_stop_timer ( );
6049 + len = sprintf (buf, " updated %d of %d character descriptions\n",
6050 + updates, strings );
6051 + if (rejects )
6052 + sprintf (buf + (len-1), " with %d reject%s\n",
6053 + rejects, rejects > 1 ? "s" : "" );
6054 + printk( buf );
6055 +}
6056 +
6057 +/* this is the write handler for /proc/speakup/silent */
6058 +static int
6059 +silent_write_proc (PROC_WRITE_PROTOTYPE )
6060 +{
6061 + struct vc_data *vc = vc_cons[fg_console].d;
6062 + char ch = 0, shut;
6063 + if (count > 0 || count < 3 ) {
6064 + get_user (ch, buffer );
6065 + if ( ch == '\n' ) ch = '0';
6066 + }
6067 + if ( ch < '0' || ch > '7' ) {
6068 + pr_warn ( "silent value not in range (0,7)\n" );
6069 + return count;
6070 + }
6071 + if ( (ch&2) ) {
6072 + shut = 1;
6073 + do_flush( );
6074 + } else shut = 0;
6075 + if ( (ch&4) ) shut |= 0x40;
6076 + if ( (ch&1) )
6077 + spk_shut_up |= shut;
6078 + else spk_shut_up &= ~shut;
6079 + return count;
6080 +}
6081 +
6082 +// this is the write handler for /proc/speakup/characters
6083 +static int
6084 +chars_write_proc (PROC_WRITE_PROTOTYPE )
6085 +{
6086 +#define max_desc_len 72
6087 + static int cnt = 0, state = 0;
6088 + static char desc[max_desc_len + 1];
6089 + static u_long jiff_last = 0;
6090 + short i = 0, num;
6091 + int len;
6092 + char ch, *cp, *p_new;
6093 + // reset certain vars if enough time has elapsed since last called
6094 + if (jiffies - jiff_last > 10 ) {
6095 + cnt = state = strings = rejects = updates = 0;
6096 + }
6097 + jiff_last = jiffies;
6098 +get_more:
6099 + desc[cnt] = '\0';
6100 + state = 0;
6101 + for (; i < count && state < 2; i++ ) {
6102 + get_user (ch, buffer + i );
6103 + if ( ch == '\n' ) {
6104 + desc[cnt] = '\0';
6105 + state = 2;
6106 + } else if (cnt < max_desc_len )
6107 + desc[cnt++] = ch;
6108 + }
6109 + if (state < 2 ) return count;
6110 + cp = desc;
6111 + while ( *cp && *cp <= SPACE ) cp++;
6112 + if ((!cnt ) || strchr ("dDrR", *cp ) ) {
6113 + reset_default_chars ( );
6114 + pr_info( "character descriptions reset to defaults\n" );
6115 + cnt = 0;
6116 + return count;
6117 + }
6118 + cnt = 0;
6119 + if (*cp == '#' ) goto get_more;
6120 + num = -1;
6121 + cp = speakup_s2i(cp, &num );
6122 + while ( *cp && *cp <= SPACE ) cp++;
6123 + if (num < 0 || num > 255 ) { // not in range
6124 + rejects++;
6125 + strings++;
6126 + goto get_more;
6127 + }
6128 + if (num >= 27 && num <= 31 ) goto get_more;
6129 + if (!strcmp(cp, characters[num] ) ) {
6130 + strings++;
6131 + goto get_more;
6132 + }
6133 + len = strlen(cp );
6134 + if (characters[num] == default_chars[num] )
6135 + p_new = (char * ) kmalloc (sizeof (char ) * len+1, GFP_KERNEL );
6136 + else if ( strlen(characters[num] ) >= len )
6137 + p_new = characters[num];
6138 + else {
6139 + kfree(characters[num] );
6140 + characters[num] = default_chars[num];
6141 + p_new = (char * ) kmalloc (sizeof (char ) * len+1, GFP_KERNEL );
6142 + }
6143 + if (!p_new ) return -ENOMEM;
6144 + strcpy ( p_new, cp );
6145 + characters[num] = p_new;
6146 + updates++;
6147 + strings++;
6148 + if (i < count ) goto get_more;
6149 + chars_stop_timer ( );
6150 + init_timer (&chars_timer );
6151 + chars_timer.function = show_char_results;
6152 + chars_timer.expires = jiffies + 5;
6153 + start_timer (chars_timer );
6154 + chars_timer_active++;
6155 + return count;
6156 +}
6157 +
6158 +static int
6159 +bits_read_proc (PROC_READ_PROTOTYPE )
6160 +{
6161 + int i;
6162 + var_header *p_header = (var_header * )data;
6163 + proc_var *var = p_header->data;
6164 + bits_data *pb = &punc_info[var->value];
6165 + short mask = pb->mask;
6166 + char *cp = page;
6167 + *start = 0;
6168 + *eof = 1;
6169 + for ( i = 33; i < 128; i++ ) {
6170 + if ( !(spk_chartab[i]&mask ) ) continue;
6171 + *cp++ = (char )i;
6172 + }
6173 + *cp++ = '\n';
6174 + return cp-page;
6175 +}
6176 +
6177 +/* set_mask_bits sets or clears the punc/delim/repeat bits,
6178 + * if input is null uses the defaults.
6179 + * values for how: 0 clears bits of chars supplied,
6180 + * 1 clears allk, 2 sets bits for chars */
6181 +
6182 +int
6183 +set_mask_bits( const char *input, const int which, const int how )
6184 +{
6185 + u_char *cp;
6186 + short mask = punc_info[which].mask;
6187 + if ( how&1 ) {
6188 + for ( cp = (u_char * )punc_info[3].value; *cp; cp++ )
6189 + spk_chartab[*cp] &= ~mask;
6190 + }
6191 + cp = (u_char * )input;
6192 + if ( cp == 0 ) cp = punc_info[which].value;
6193 + else {
6194 + for ( ; *cp; cp++ ) {
6195 + if ( *cp < SPACE ) break;
6196 + if ( mask < PUNC ) {
6197 + if ( !(spk_chartab[*cp]&PUNC) ) break;
6198 + } else if ( (spk_chartab[*cp]&B_NUM) ) break;
6199 + }
6200 + if ( *cp ) return -EINVAL;
6201 + cp = (u_char * )input;
6202 + }
6203 + if ( how&2 ) {
6204 + for ( ; *cp; cp++ )
6205 + if ( *cp > SPACE ) spk_chartab[*cp] |= mask;
6206 + } else {
6207 + for ( ; *cp; cp++ )
6208 + if ( *cp > SPACE ) spk_chartab[*cp] &= ~mask;
6209 + }
6210 + return 0;
6211 +}
6212 +
6213 +static bits_data *pb_edit = NULL;
6214 +
6215 +static int edit_bits (struct vc_data *vc, u_char type, u_char ch, u_short key )
6216 +{
6217 + short mask = pb_edit->mask, ch_type = spk_chartab[ch];
6218 + if ( type != KT_LATIN || (ch_type&B_NUM ) || ch < SPACE ) return -1;
6219 + if ( ch == SPACE ) {
6220 + synth_write_msg( "edit done" );
6221 + special_handler = NULL;
6222 + return 1;
6223 + }
6224 + if ( mask < PUNC && !(ch_type&PUNC) ) return -1;
6225 + spk_chartab[ch] ^= mask;
6226 + speak_char( ch );
6227 + synth_write_msg( (spk_chartab[ch]&mask ) ? " on" : " off" );
6228 + return 1;
6229 +}
6230 +
6231 +static int
6232 +bits_write_proc (PROC_WRITE_PROTOTYPE )
6233 +{
6234 + var_header *p_header = (var_header * )data;
6235 + proc_var *var = p_header->data;
6236 + int ret = count;
6237 + char punc_buf[100];
6238 + if (count < 1 || count > 99 )
6239 + return -EINVAL;
6240 + if (copy_from_user (punc_buf, buffer, count ) )
6241 + return -EFAULT;
6242 + if (punc_buf[count - 1] == '\n' )
6243 + count--;
6244 + punc_buf[count] = '\0';
6245 + if ( *punc_buf == 'd' || *punc_buf == 'r' )
6246 + count = set_mask_bits( 0, var->value, 3 );
6247 + else
6248 + count = set_mask_bits( punc_buf, var->value, 3 );
6249 + if ( count < 0 ) return count;
6250 + return ret;
6251 +}
6252 +
6253 +// this is the read handler for /proc/speakup/synth
6254 +static int
6255 +synth_read_proc (PROC_READ_PROTOTYPE )
6256 +{
6257 + int len;
6258 + if ( synth == NULL ) strcpy( synth_name, "none" );
6259 + else strcpy( synth_name, synth->name );
6260 + len = sprintf (page, "%s\n", synth_name );
6261 + *start = 0;
6262 + *eof = 1;
6263 + return len;
6264 +}
6265 +
6266 +// this is the write handler for /proc/speakup/synth
6267 +static int
6268 +synth_write_proc (PROC_WRITE_PROTOTYPE )
6269 +{
6270 + int ret = count;
6271 + char new_synth_name[10];
6272 + const char *old_name = ( synth != NULL ) ? synth->name : "none";
6273 + if (count < 2 || count > 9 )
6274 + return -EINVAL;
6275 + if (copy_from_user (new_synth_name, buffer, count ) )
6276 + return -EFAULT;
6277 + if (new_synth_name[count - 1] == '\n' )
6278 + count--;
6279 + new_synth_name[count] = '\0';
6280 + strlwr (new_synth_name );
6281 + if (!strcmp (new_synth_name, old_name ) ) {
6282 + pr_warn ( "%s already in use\n", new_synth_name );
6283 + return ret;
6284 + }
6285 + if ( synth_init( new_synth_name ) == 0 ) return ret;
6286 + pr_warn( "failed to init synth %s\n", new_synth_name );
6287 + return -ENODEV;
6288 +}
6289 +
6290 +proc_var spk_proc_vars[] = {
6291 + { VERSION, version_read_proc, 0, 0 },
6292 + { SILENT, 0, silent_write_proc, 0 },
6293 + { CHARS, chars_read_proc, chars_write_proc, 0 },
6294 + { SYNTH, synth_read_proc, synth_write_proc, 0 },
6295 + { KEYMAP, keys_read_proc, keys_write_proc, 0 },
6296 + { PUNC_SOME, bits_read_proc, bits_write_proc, 1 },
6297 + { PUNC_MOST, bits_read_proc, bits_write_proc, 2 },
6298 + { PUNC_ALL, bits_read_proc, 0, 3 },
6299 + { DELIM, bits_read_proc, bits_write_proc, 4 },
6300 + { REPEATS, bits_read_proc, bits_write_proc, 5 },
6301 + { EXNUMBER, bits_read_proc, bits_write_proc, 6 },
6302 + { -1, 0, 0, 0 }
6303 +};
6304 +
6305 +#endif // CONFIG_PROC_FS
6306 +
6307 +#ifdef CONFIG_SPEAKUP
6308 +
6309 +
6310 +void __init
6311 +speakup_init (struct vc_data *vc )
6312 +{
6313 + spk_t *first_console = (spk_t *) alloc_bootmem (spk_size+1 );
6314 + speakup_open( vc, first_console );
6315 +}
6316 +
6317 +#endif
6318 +
6319 +void
6320 +speakup_allocate (struct vc_data *vc )
6321 +{
6322 + int vc_num;
6323 +
6324 + vc_num = vc->vc_num;
6325 + if ( speakup_console[vc_num] == NULL ) {
6326 + speakup_console[vc_num] = (spk_t *) kmalloc (spk_size + 1,
6327 + GFP_KERNEL );
6328 + if ( speakup_console[vc_num] == NULL ) return;
6329 + memset( speakup_console[vc_num], 0, spk_size );
6330 + speakup_date( vc);
6331 + } else if ( !spk_parked ) speakup_date( vc);
6332 +}
6333 +
6334 +static void
6335 +speakup_date (struct vc_data *vc )
6336 +{
6337 + spk_x = spk_cx = vc->vc_x;
6338 + spk_y = spk_cy = vc->vc_y;
6339 + spk_pos = spk_cp = vc->vc_pos;
6340 + spk_old_attr = spk_attr;
6341 + spk_attr = ((scr_readw ((u_short * ) spk_pos ) & 0xff00 ) >> 8 );
6342 +}
6343 +
6344 +static u_char is_cursor = 0;
6345 +static u_long old_cursor_pos, old_cursor_x, old_cursor_y;
6346 +static int cursor_con;
6347 +volatile int cursor_timer_active = 0;
6348 +
6349 +void
6350 +cursor_stop_timer(void )
6351 +{
6352 + if (!cursor_timer_active ) return;
6353 + stop_timer ( cursor_timer );
6354 + cursor_timer_active = 0;
6355 +}
6356 +
6357 +static void reset_highlight_buffers( struct vc_data * );
6358 +
6359 +//extern void kbd_fakekey(unsigned int);
6360 +extern struct input_dev *fakekeydev;
6361 +
6362 +int read_all_key;
6363 +
6364 +void reset_index_count(int);
6365 +void get_index_count(int *, int *);
6366 +//int synth_supports_indexing(void);
6367 +static void start_read_all_timer( struct vc_data *vc, int command );
6368 +
6369 +enum {RA_NOTHING,RA_NEXT_SENT,RA_PREV_LINE,RA_NEXT_LINE,RA_PREV_SENT,RA_DOWN_ARROW,RA_TIMER,RA_FIND_NEXT_SENT,RA_FIND_PREV_SENT};
6370 +
6371 +static void
6372 +kbd_fakekey2(struct vc_data *vc,int v,int command)
6373 +{
6374 + cursor_stop_timer();
6375 + (*do_cursor)( vc,v,0,fakekeydev->regs);
6376 + (*do_cursor)( vc,v,1,fakekeydev->regs);
6377 + start_read_all_timer(vc,command);
6378 +}
6379 +
6380 +static void
6381 +read_all_doc( struct vc_data *vc)
6382 +{
6383 + if (!synth_supports_indexing())
6384 + return;
6385 + if ( synth == NULL || spk_shut_up || (vc->vc_num != fg_console ) )
6386 + return;
6387 + if (cursor_track!=read_all_mode)
6388 + prev_cursor_track=cursor_track;
6389 + cursor_track=read_all_mode;
6390 + reset_index_count(0);
6391 + if (get_sentence_buf(vc,0)==-1)
6392 + {
6393 + kbd_fakekey2(vc,0,RA_DOWN_ARROW);
6394 + }
6395 + else
6396 + {
6397 + say_sentence_num(0,0);
6398 + synth_insert_next_index(0);
6399 + start_read_all_timer(vc,RA_TIMER);
6400 + }
6401 +}
6402 +
6403 +static void
6404 +stop_read_all( struct vc_data *vc)
6405 +{
6406 + cursor_stop_timer( );
6407 + cursor_track=prev_cursor_track;
6408 + spk_shut_up &= 0xfe;
6409 + do_flush();
6410 +}
6411 +
6412 +static void
6413 +start_read_all_timer( struct vc_data *vc, int command )
6414 +{
6415 + cursor_con = vc->vc_num;
6416 + cursor_timer.expires = jiffies + cursor_timeout;
6417 + read_all_key=command;
6418 + start_timer (cursor_timer );
6419 + cursor_timer_active++;
6420 +}
6421 +
6422 +static void
6423 +handle_cursor_read_all( struct vc_data *vc,int command )
6424 +{
6425 + int indcount,sentcount,rv,sn;
6426 +
6427 + switch (command)
6428 + {
6429 + case RA_NEXT_SENT:
6430 + // Get Current Sentence
6431 + get_index_count(&indcount,&sentcount);
6432 + //printk("%d %d ",indcount,sentcount);
6433 + reset_index_count(sentcount+1);
6434 + if (indcount==1)
6435 + {
6436 + if (!say_sentence_num(sentcount+1,0))
6437 + {
6438 + kbd_fakekey2(vc,0,RA_FIND_NEXT_SENT);
6439 + return;
6440 + }
6441 + synth_insert_next_index(0);
6442 + }
6443 +