/[linux-patches]/genpatches-2.6/trunk/2.6.16-pre/4900_speakup-20060103.patch
Gentoo

Contents of /genpatches-2.6/trunk/2.6.16-pre/4900_speakup-20060103.patch

Parent Directory Parent Directory | Revision Log Revision Log


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