diff -u -r --new-file linux-2.4.30.orig/Documentation/Configure.help linux-2.4.30/Documentation/Configure.help
--- linux-2.4.30.orig/Documentation/Configure.help 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.30/Documentation/Configure.help 2005-05-01 19:02:59.000000000 -0700
@@ -20061,7 +20061,141 @@
determined automatically, so you need to specify it here ONLY if
running a DEC Alpha, otherwise this setting has no effect.
-Double Talk PC internal speech card support
+Speakup console speech output for Linux
+CONFIG_SPEAKUP
+ Choosing this Option will include support for console speech output.
+
+ Speakup provides access to Linux for the visually impaired community.
+ It does this by sending console output to a number of different
+ hardware speech synthesizers. It provides access to Linux by Making
+ screen review functions available such as are used in comercial screen
+ review packages for the MSDOS and MSWINDOWS world.
+
+ The drivers supplied under this option are not standard devices in the
+ /dev/ sence of the meaning. They can be thought of as a video card
+ for the blind. They are used by speakup and only speakup.
+
+ For more information about speakup and its drivers check out
+ http://www.linux-speakup.org, or read the Documentation in
+ linux/Documentation/speakup.
+
+ The currently supported synthesizers are:
+ Accent PC internal synthesizer.
+ Accent SA external Accent synthesizer.
+ Apollo II external synthesizer.
+ Audapter external synthesizer.
+ Braille 'N Speak external synthesizer.
+ Dectalk Express and external synthesizers.
+ Dectalk PC internal synthesizer (module only)
+ DoubleTalk PC Internal synthesizer,
+ LiteTalk/DoubleTalk-LT external serial synthesizers,
+ Speakout external synthesizer,
+ Transport external synthesizer.
+
+ If you do not have one of these synths, say 'N' to this option.
+
+
+ If you wish to load speakup or any of it's synthasizers as modules
+ choose 'm' at any or all of the speakup options. The synth driver
+ can then be loaded with modprobe speakup_synthname where synthname
+ is any of the above synthasizers.
+
+Default synthesizer for Speakup
+CONFIG_SPEAKUP_DEFAULT
+ This option specifies which synthesizer Speakup should use by
+ default at boot time.
+ Valid values are: none, acntpc, acntsa, apollo, audptr, bns, decext,
+ dectlk, decpc, dtlk, ltlk, spkout, txprt
+
+ You can choose an alternatively compiled-in synthesizer at boot time
+ by using the speakup_synth kernel command line option,
+ I.E. speakup_synth=dtlk.
+
+Use Speakup keymap by default
+CONFIG_SPEAKUP_KEYMAP
+ If this option is enabled, then a modified US keymap which includes
+ Speakup's screen review commands will be used by default.
+
+DoubleTalk driver for speakup.
+CONFIG_SPEAKUP_DTLK
+ The DoubleTalk synthesizer is made by RC Systems. It is an internal
+ ISA card which uses no interrupts. Do not confuse this driver with
+ the standard DoubleTalk driver included in the kernel.
+
+ If you don't have a DoubleTalk card say 'N' here.
+
+LiteTalk/DoubleTalk-LT driver for speakup.
+CONFIG_SPEAKUP_LTLK
+ This driver is for the LiteTalk synthesizer made by MicroTalk or the
+ DoubleTalk-LT synthesizer made by RC Systems. These are serial
+ drivers for those external synths.
+
+ If you don't have a LiteTalk or DoubleTalk-LT, say 'N' here.
+
+Speakout driver for speakup.
+CONFIG_SPEAKUP_SPKOUT
+ This driver is for the Speakout external serial synthesizer made by
+ GW Micro.
+
+ If you don't have a Speakout, say 'N' here.
+
+Accent PC driver for speakup.
+CONFIG_SPEAKUP_ACNTPC
+ This driver is for the Accent PC internal synthesizer made by Aicom
+ Corp.
+
+ If you Don't have an Accent PC, say 'N' here.
+
+Accent SA driver for speakup.
+CONFIG_SPEAKUP_ACNTSA
+ This driver is for the Accent SA external synthesizer made by Aicom
+ Corp.
+
+ If you Don't have an Accent SA, say 'N' here.
+
+Apollo II driver for speakup.
+CONFIG_SPEAKUP_APOLO
+ This driver is for the Apollo II external synthesizer made
+ by Dolphin Computer Access limited.
+
+ If you Don't have an Apollo II, say 'N' here.
+
+Audapter Speech System driver for speakup.
+CONFIG_SPEAKUP_AUDPTR
+ This driver is for the Audapter external synthesizer made by
+ Personal Data System Inc.
+
+ If you Don't have an Audapter, say 'N' here.
+
+Braille 'N Speak driver for speakup.
+CONFIG_SPEAKUP_BNS
+ This driver is for the Braille 'N Speak external synthesizer made by
+ Blazie Engineering.
+
+ If you Don't have a bns, say 'N' here.
+
+Dectalk Express driver for speakup.
+CONFIG_SPEAKUP_DECTLK
+ This driver is for the Dectalk Express external synthesizer made by
+ Digital Equipment Corp.
+
+ If you Don't have a Dectalk Express, say 'N' here.
+
+Dectalk External driver for speakup.
+CONFIG_SPEAKUP_DECEXT
+ This driver is for the older Dectalk external synthesizer made by
+ Digital Equipment Corp.
+
+ If you Don't have a Dectalk external, say 'N' here.
+
+Transport driver for speakup.
+CONFIG_SPEAKUP_TXPRT
+ This driver is for the Artic Transport external synthesizer made by
+ Artic Technologies.
+
+ If you Don't have a Transport, say 'N' here.
+
+Double Talk PC internal speech card support
CONFIG_DTLK
This driver is for the DoubleTalk PC, a speech synthesizer
manufactured by RC Systems (). It is also
diff -u -r --new-file linux-2.4.30.orig/Documentation/speakup/DefaultKeyAssignments linux-2.4.30/Documentation/speakup/DefaultKeyAssignments
--- linux-2.4.30.orig/Documentation/speakup/DefaultKeyAssignments 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/Documentation/speakup/DefaultKeyAssignments 2005-05-01 19:02:59.000000000 -0700
@@ -0,0 +1,46 @@
+This file is intended to give you an overview of the default keys used
+by speakup for it's review functions. You may change them to be
+anything you want but that will take some familiarity with key
+mapping.
+
+We have remapped the insert or zero key on the keypad to act as a
+shift key. Well, actually as an altgr key. So in the following list
+InsKeyPad-period means hold down the insert key like a shift key and
+hit the keypad period.
+
+KeyPad-8 Say current Line
+InsKeyPad-8 say from top of screen to reading cursor.
+KeyPad-7 Say Previous Line (UP one line)
+KeyPad-9 Say Next Line (down one line)
+KeyPad-5 Say Current Word
+InsKeyPad-5 Spell Current Word
+KeyPad-4 Say Previous Word (left one word)
+InsKeyPad-4 say from left edge of line to reading cursor.
+KeyPad-6 Say Next Word (right one word)
+InsKeyPad-6 Say from reading cursor to right edge of line.
+KeyPad-2 Say Current Letter
+InsKeyPad-2 say current letter phonetically
+KeyPad-1 Say Previous Character (left one letter)
+KeyPad-3 Say Next Character (right one letter)
+KeyPad-plus Say Entire Screen
+InsKeyPad-plus Say from reading cursor line to bottom of screen.
+KeyPad-Minus Park reading cursor (toggle)
+InsKeyPad-minus Say character hex and decimal value.
+KeyPad-period Say Position (current line, position and console)
+InsKeyPad-period say colour attributes of current position.
+InsKeyPad-9 Move reading cursor to top of screen (insert pgup)
+InsKeyPad-3 Move reading cursor to bottom of screen (insert pgdn)
+InsKeyPad-7 Move reading cursor to left edge of screen (insert home)
+InsKeyPad-1 Move reading cursor to right edge of screen (insert end)
+ControlKeyPad-1 Move reading cursor to last character on current line.
+KeyPad-Enter Shut Up (until another key is hit) and sync reading cursor
+InsKeyPad-Enter Shut Up (until toggled back on).
+InsKeyPad-star n go to line (y) or column (x). Where 'n' is any
+ allowed value for the row or column for your current screen.
+KeyPad-/ Mark and Cut screen region.
+InsKeyPad-/ Paste screen region into any console.
+
+Hitting any key while speakup is outputting speech will quiet the
+synth until it has caught up with what is being printed on the
+console.
+
diff -u -r --new-file linux-2.4.30.orig/Documentation/speakup/INSTALLATION linux-2.4.30/Documentation/speakup/INSTALLATION
--- linux-2.4.30.orig/Documentation/speakup/INSTALLATION 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/Documentation/speakup/INSTALLATION 2005-05-01 19:02:59.000000000 -0700
@@ -0,0 +1,108 @@
+This document assumes you have had some experience with kernel
+compilation and installation. If you have not, I recommend you get
+the kernel source and read the README and various documents in the
+linux/Documentation directory. In particular the Changes file to make
+sure you have the appropriate utilities needed for installing a 2.2.xx
+or 2.4xx kernel. It isn't as difficult as you might think. The
+kernel README is intimidating the first time but once you get the
+steps down, it's really pretty easy. Getting through the "make
+config" is the tedious bit.
+
+The first thing to do is to place a copy of the tarball in the /usr/src
+directory which is the directory the linux tree is located in as well.
+Next untar speakup by typing:
+
+tar zxf speakup-1.00.tar.gz
+cd speakup-1.00
+./install
+
+Note the dot-slash before the install. This will copy the speakup
+directory to the kernel tree and apply the various patches and
+components to the appropriate kernel files. Depending on how
+experienced you are with kernel compiling and hacking will determine
+whether you should bother looking at any failed patches. If this
+happens, you should probably write to the speakup mailing list for
+help or myself.
+
+If all of the patch hunks apply successfully then just continue with
+the standard steps to compile the kernel with:
+
+make mrproper
+make config
+
+When you get to the section console speech output, answer 'y' to the
+CONFIG_SPEAKUP prompt. You will be given a submenu with the list of
+synthesizers which are currently supported. You can include as many
+synths in the kernel as you wish but remember each one takes up kernel
+space. You can only choose one of the synths as the default or none,
+so just type dtlk or whatever is the correct string for the
+synthesizer you have. You will also be asked if you wish to build-in
+a speakup key map. If you do not say 'y' to this option you will need
+to load a speakup map at boot time with whichever mechanism your
+distribution uses for loading key maps.
+
+We have placed the speakup configuration options in make config just
+after the vga console choice. For the DoubleTalk PC driver included
+by Jim Van Zandt. I recommend you say no to that option. I have not
+tried configuring them both in, but I wouldn't be at all surprised if
+it didn't work.
+
+If all goes well up to this point you can continue with the compiling
+process by doing:
+
+make dep >dep.file 2>&1 &
+make bzImage >cc.file 2>&1 &
+make modules >mod.file 2>&1 &
+
+I always redirect output to the files dep.file and cc.file so I can
+look over the compilation record to make sure there are no errors and
+warnings.
+
+Okay, you are ready to install the newly compiled kernel. Make sure
+you make an linux.old entry in your lilo.conf file so you can recover
+if it blows up. next as root run "make modules_install" to install
+whatever modules you compiled and move the bzImage from
+/usr/src/linux/arch/i386/boot to wherever your kernel lives. Also
+move the System.map from /usr/src/linux to where your System.map
+lives. On our systems we use debian so we create an vmlinuz-speakup
+and System.map-speakup in our /boot directory and set the symbolic
+links vmlinuz and System.map in the root (/) directory to point to the
+images. Now type lilo to tell lilo to build the new booter file and
+install it.
+
+As of version 0.07, the keymap for speakup is automatically built in
+at compile time. If you have other keymaps installed at boot time,
+you might want to consider removing them before you reboot the system.
+
+If everything has gone OK up until now, cross your fingers and type:
+
+shutdown -r now
+
+Your system should start talking to you as soon as it starts booting.
+It will talk and talk and ... well, you might want to hit the
+keypad-enter key to tell it to shut up. You should also read the
+DefaultKeyAssignments file to learn the various review functions
+available.
+
+As of v-0.10 the speakup configuration options are in the
+/proc/speakup subtree. The individual options should be fairly
+obvious by their names such as rate, volume, punc_level and so forth.
+You can manipulate them by cat'ing or echoing new values to them such
+as:
+
+echo 9 >/proc/speakup/rate
+
+You can see what the current values are by cat'ing those files to the console:
+
+cat /proc/speakup/rate
+
+I have probably managed to overlook a whole whack of things because
+this is the, enter version number here, draft. Don't worry we'll get
+it right eventually. If you like the package you really should get on
+the mailing list and start participating in it's development.
+
+ Kirk
+
+email: kirk@braille.uwo.ca
+phone: (519) 679-6845 (home)
+
diff -u -r --new-file linux-2.4.30.orig/Documentation/speakup/README linux-2.4.30/Documentation/speakup/README
--- linux-2.4.30.orig/Documentation/speakup/README 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/Documentation/speakup/README 2005-05-01 19:02:59.000000000 -0700
@@ -0,0 +1,98 @@
+Welcome to the speakup project for the Speakup speech package for Linux.
+
+Speakup is written by Kirk Reiser and Andy Berdan. It is licensed
+under the GPL. If you don't already know, the GPL stands for the GNU
+General Public License. Which basically states that this code is free to
+copy, modify and distribute to anyone interested in playing with it.
+The one thing you may not do is turn any part of it into proprietary
+or commercial code without the permission of the author. That's me.
+
+If you are interested in being involved with the development of speech
+output for Linux you can subscribe to the Speakup mailing list by
+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.
+
+We are at a very early stage in the development of this package.
+Hopefully changes will happen often and many. The current files in
+this directory are:
+
+DefaultKeyAssignments # speakup's default review keys
+INSTALLATION # for installing speakup from the tar ball.
+README # this file
+keymap-tutorial # a tutorial on how to layout the keyboard
+
+Read the INSTALLATION file to learn how to apply the patches and the
+default.map for the keyboard. You should also read the Changes file.
+It really has any new things I've added since last time.
+
+There is no documentation in any of these files to instruct you what
+to do if something goes wrong with the patching or compilation. If
+you would like that information you will need to subscribe to the
+mailing list and ask for help, or write me kirk@braille.uwo.ca for
+help. I suggest the mailing list because I will probably tire quickly
+of answering the same questions over and over. You could always
+decide to dig-in and take on the task, and write documentation to help
+others.
+
+There also is a speakup reflector for the Speak Freely package, which
+many of us hang out on and discuss all sorts of topics from speakup
+problems to ALSA driver installation and just about anything else
+you'd like to talk about. The reflector is at lwl.braille.uwo.ca:4074
+with it's lwl page at lwl.braille.uwo.ca/speakup.html. Come and join
+us, it's fun!
+
+Acknowledgements:
+
+I am really very new at kernel hacking and screen review package
+writing, so I have depended heavily on other folks kindness to help me
+a long. No doubt I will continue to abuse them freely and others
+before this is a really good speech solution for Linux. (Oh Well!,
+somebody's got to do it.)
+
+Theodore Ts'o. He gave me a good discussion of unicode and UTF and
+the like. He doesn't even remember writing me about it.
+
+Alan Cox. He has answered many questions about scheduling and wait
+queues and timers along with code fragments and so on. I just wish I
+understood it all totally. He has also helped immensely in moving
+this package toward inclusion in the standard kernel tree. (Maybe next
+release!)
+
+Martin Mares. He pointed me in the right direction to figuring out
+the colour attributes and other useful tidbits.
+
+Paul McDermott. He really is the catalyst for me to actually get
+this all working. Besides I like seeing him bounce around and get all
+excited every time I have something new working.
+
+John Covici, He was the first person to actually attempt writing
+another synthesizer driver for speakup. It was the Speakout driver so
+it was also the first serial driver.
+
+Brian Borowski, he was the first person to actually write a speakup
+function other than Andy and I.
+
+Jim Danley, he has more or less become my main man in helping test
+code, add new features, bounce ideas off and generally become a good
+friend.
+
+Matt Campbell, he basically rewrote the drivers to be able to include
+all synths in the kernel at the same time. The distribution
+maintainers appreciate him a lot as well.
+
+Gene Collins, he was very helpful debugging the current release prior
+to its public showing. He has also worked hard educating others on
+the list and writing the ALSA mini howto.
+
+I would also like to really thank the folks that handle the
+distribution packages. I and many other people would not find access
+to speakup nearly so convenient without their efforts. They include
+Bill Acker, Tom Moore, Matt Campbell, Joe Norton and Joshua Lambert.
+
+There are probably many more I am forgetting right now. I guess I'll
+just have to add you all later.
+
+
+Happy Hacking!
+
+ Kirk
+
diff -u -r --new-file linux-2.4.30.orig/Documentation/speakup/keymap-tutorial linux-2.4.30/Documentation/speakup/keymap-tutorial
--- linux-2.4.30.orig/Documentation/speakup/keymap-tutorial 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/Documentation/speakup/keymap-tutorial 2005-05-01 19:02:59.000000000 -0700
@@ -0,0 +1,140 @@
+ Speakup Keymap Tutorial
+
+This is meant to be a basic tutorial on how to change the Linux keymap
+file to assign speakup review functions to desired keys. It is not
+intended to be a replacement for the loadkeys(8) or keymap(5) man
+pages.
+
+The basic lay-out of the keymap file is a series of lines with the
+following fields. The keyword keycode indicates this is the start of
+a new key assignment. It is then followed by a number which
+represents the actual key on the keyboard. That number is followed by
+the equals '=' operator and finally a list of keywords representing
+key names such as keypad5. Each line can have quite a few key
+functions on it. They are interpreted by loadkeys in order and
+assigned to key shift states depending on the order they are
+encountered. So for example, the first value after the equals is the
+keys unshifted state, while the second is the keys shifted state. If
+you wish to learn the order they are interpreted in read the
+loadkeys(8) and keymap(5) man pages.
+
+You can have subsequent lines which are indented and start with
+another keyword for the various shifted states. This way you can
+assign some of the states without having to specify them all in order
+up until you get to the one you want to assign.
+
+In speakup, we have assigned the insert key on the number pad to the
+altgr keyword. This is not required; you could choose any other
+shifted state keyword. We used altgr because it typically represents
+the right hand alt key. In Linux each shift key is separate and
+independent, so the left shift and the right shift keys are not
+necessarily the same. The altgr key is not really used for anything
+important, so we steel it.
+
+Here are the default key assignments for the number eight on the
+keypad:
+
+keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+As you can see, the first line starts with keycode followed by 72
+which is the actual number assigned to the key when the keyboard port
+is read. The KP_8 after the equal sign, is the symbolic representation
+of the function called when that key is hit.
+
+The second line is the same format except it starts with the keyword
+alt which is indented. That means that the function at the end of
+that line Ascii_8 is applied to the alt-shifted eight key.
+
+Now here are the speakup assignments for that key:
+
+keycode 72 = 0x0d0a
+ altgr keycode 72 = 0x0d20
+#keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+Notice that the only thing which has changed on the first line is the
+function called when the key is struck. It is a hexadecimal number
+identifying the function called in a look up table. It is not a
+symbolic representation yet because that means we need to change the
+loadkeys program to understand our symbolic names. We will do this in
+the future but for now it is more expedient to just use the table
+indices. You will find a table at the bottom of this document
+listing the review functions and their corresponding hex lookups.
+
+The 0x0d0a in the first line above is speakup's say line function.
+The second line ends with 0x0d20 which is speakup's read from top of
+screen to reading cursor line.
+
+The third line is the original key assignment commented out with a
+number-sign '#' at the beginning. I do that so I can easily find the
+keys I want to affect by symbolic name. Otherwise I would need to
+keep a look up table for all the keycodes. I recommend you do this as
+well or you'll be very sorry at some point in the future.
+
+The forth line is just the standard key assignment for the left hand
+alt key.
+
+Now let's say we want to design a different keyboard layout. I'll use
+an example for the JAWS style keypad because I've specifically been
+asked to help with that. JAWS uses the eight on the keypad to move up
+a line or the speakup function to read previous line. JAWS also uses
+the keypad_8 key in a shifted mode to read the current line. I
+apologize if these are not quite right. It has been a long time since
+I used JAWS. So we would have the following two lines:
+
+keycode 72 = 0x0d0b
+ altgr keycode 72 = 0x0d0a
+
+The hex value 0x0d0b in the first line is speakup's SAY_PREVIOUS_LINE
+function. The 0x0d0a in the second line is the same say_line function
+as we had earlier. So when the number eight is hit on the keypad
+speakup will read the previous line and when the number eight is
+shifted with the insert key on the keypad it will read the current
+line.
+
+As you can tell, it is not really very difficult to reassign the keys
+to different review functions.
+
+Once you have carefully edited the keymap file, called default.map in
+the speakup distribution, you copy it into the /etc/kbd directory.
+Make sure you back up the original default.map from that directory
+first, if there is one. Then you run loadkeys to load the new map
+into the kernel:
+
+loadkeys /etc/kbd/default.map
+
+If you wish to build your new keyboard lay-out into the kernel, after
+testing it, copy the default.map file into the drivers/char directory,
+with the name defkeymap.map, of your Linux source tree. Then rm the
+defkeymap.c file and recompile the kernel. Because there is no
+defkeymap.c `make' will rebuild it on the next compile.
+
+Here is a list of the available speakup review functions at this point
+in time.
+
+SAY_CHAR 0x0d04 /* say this character */
+SAY_PREV_CHAR 0x0d05 /* say character left of this char */
+SAY_NEXT_CHAR 0x0d06 /* say char right of this char */
+SAY_WORD 0x0d07 /* say this word under reading cursor */
+SAY_PREV_WORD 0x0d08
+SAY_NEXT_WORD 0x0d09
+SAY_LINE 0x0d0a /* say this line */
+SAY_PREV_LINE 0x0d0b /* say line above this line */
+SAY_NEXT_LINE 0x0d0c
+TOP_EDGE 0x0d0d /* move to top edge of screen */
+BOTTOM_EDGE 0x0d0e
+LEFT_EDGE 0x0d0f
+RIGHT_EDGE 0x0d10
+SAY_PHONETIC_CHAR 0x0d11 /* say this character phonetically */
+SPELL_WORD 0x0d12 /* spell this word letter by letter */
+SAY_SCREEN 0x0d14
+SAY_POSITION 0x0d1b
+SPEECH_OFF 0x0d1c
+SAY_ATTRIBUTES 0x0d1d
+SPEAKUP_PARKED 0x0d1e
+SAY_FROM_TOP 0x0d20
+SAY_TO_BOTTOM 0x0d21
+SAY_FROM_LEFT 0x0d22
+SAY_TO_RIGHT 0x0d23
+
diff -u -r --new-file linux-2.4.30.orig/Documentation/speakup/spkguide.txt linux-2.4.30/Documentation/speakup/spkguide.txt
--- linux-2.4.30.orig/Documentation/speakup/spkguide.txt 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/Documentation/speakup/spkguide.txt 2005-05-01 19:02:59.000000000 -0700
@@ -0,0 +1,1279 @@
+
+The Speakup User's Guide
+For Speakup 2.0 and Later
+By Gene Collins
+Last modified on Tue Mar 29 10:54:19 2005
+Document version 1.0
+
+Copyright (c) 2005 Gene Collins
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled "GNU Free
+Documentation License".
+
+Preface
+
+The purpose of this document is to familiarize users with the user
+interface to Speakup, a Linux Screen Reader. If you need instructions
+for installing or obtaining Speakup, visit the web site at
+http://linux-speakup.org/. Speakup is a set of patches to the standard
+Linux kernel source tree. It can be built as a series of modules, or as
+a part of a monolithic kernel. These details are beyond the scope of
+this manual, but the user may need to be aware of the module
+capabilities, depending on how your system administrator has installed
+Speakup. If Speakup is built as a part of a monolithic kernel, and the
+user is using a hardware synthesizer, then Speakup will be able to
+provide speech access from the time the kernel is loaded, until the time
+the system is shutdown. This means that if you have obtained Linux
+installation media for a distribution which includes Speakup as a part
+of its kernel, you will be able, as a blind person, to install Linux
+with speech access unaided by a sighted person. Again, these details
+are beyond the scope of this manual, but the user should be aware of
+them. See the web site mentioned above for further details.
+
+1. Starting Speakup
+
+If your system administrator has installed Speakup to work with your
+specific synthesizer by default, then all you need to do to use Speakup
+is to boot your system, and Speakup should come up talking. This
+assumes of course that your synthesizer is a supported hardware
+synthesizer, and that it is either installed in or connected to your
+system, and is if necessary powered on.
+
+It is possible, however, that Speakup may have been compiled into the
+kernel with no default synthesizer. It is even possible that your
+kernel has been compiled with support for some of the supported
+synthesizers and not others. If you find that this is the case, and
+your synthesizer is supported but not available, complain to the person
+who compiled and installed your kernel. Or better yet, go to the web
+site, and learn how to patch Speakup into your own kernel source, and
+build and install your own kernel.
+
+If your kernel has been compiled with Speakup, and has no default
+synthesizer set, or you would like to use a different synthesizer than
+the default one, then you may issue the following command at the boot
+prompt of your boot loader.
+
+linux speakup_synth=ltlk
+
+This command would tell Speakup to look for and use a LiteTalk or
+DoubleTalk LT at boot up. You may replace the ltlk synthesizer keyword
+with the keyword for whatever synthesizer you wish to use. The
+speakup_synth parameter will accept the following keywords, provided
+that support for the related synthesizers has been built into the
+kernel.
+
+acntsa -- Accent SA
+acntpc -- Accent PC
+apolo -- Apolo
+audptr -- Audapter
+bns -- Braille 'n Speak
+dectlk -- DecTalk Express (old and new, db9 serial only)
+decext -- DecTalk (old) External
+dtlk -- DoubleTalk PC
+keypc -- Keynote Gold PC
+ltlk -- DoubleTalk LT, LiteTalk, or external Tripletalk (db9 serial only)
+spkout -- Speak Out
+txprt -- Transport
+
+Note: Speakup does * NOT * support usb connections! Speakup also does *
+NOT * support the internal Tripletalk!
+
+Speakup does support two other synthesizers, but because they work in
+conjunction with other software, they must be loaded as modules after
+their related software is loaded, and so are not available at boot up.
+These are as follows:
+
+decpc -- DecTalk PC (not available at boot up)
+sftsyn -- One of several software synthesizers (not available at boot up)
+
+See the sections on loading modules and software synthesizers later in
+this manual for further details. It should be noted here that the
+speakup_synth boot parameter will have no effect if Speakup has been
+compiled as modules. In order for Speakup modules to be loaded during
+the boot process, such action must be configured by your system
+administrator. This will mean that you will hear some, but not all, of
+the bootup messages.
+
+2. Basic operation
+
+Once you have booted the system, and if necessary, have supplied the
+proper bootup parameter for your synthesizer, Speakup will begin
+talking as soon as the kernel is loaded. In fact, it will talk a lot!
+It will speak all the boot up messages that the kernel prints on the
+screen during the boot process. This is because Speakup is not a
+separate screen reader, but is actually built into the operating
+system. Since almost all console applications must print text on the
+screen using the kernel, and must get their keyboard input through the
+kernel, they are automatically handled properly by Speakup. There are a
+few exceptions, but we'll come to those later.
+
+Note: In this guide I will refer to the numeric keypad as the keypad.
+This is done because the speakupmap.map file referred to later in this
+manual uses the term keypad instead of numeric keypad. Also I'm lazy
+and would rather only type one word. So keypad it is. Got it? Good.
+
+Most of the Speakup review keys are located on the keypad at the far
+right of the keyboard. The numlock key should be off, in order for these
+to work. If you toggle the numlock on, the keypad will produce numbers,
+which is exactly what you want for spreadsheets and such. For the
+purposes of this guide, you should have the numlock turned off, which is
+its default state at bootup.
+
+You probably won't want to listen to all the bootup messages every time
+you start your system, though it's a good idea to listen to them at
+least once, just so you'll know what kind of information is available to
+you during the boot process. You can always review these messages after
+bootup with the command:
+
+dmesg | more
+
+In order to speed the boot process, and to silence the speaking of the
+bootup messages, just press the keypad enter key. This key is located
+in the bottom right corner of the keypad. Speakup will shut up and stay
+that way, until you press another key.
+
+You can check to see if the boot process has completed by pressing the 8
+key on the keypad, which reads the current line. This also has the
+effect of starting Speakup talking again, so you can press keypad enter
+to silence it again if the boot process has not completed.
+
+When the boot process is complete, you will arrive at a "login" prompt.
+At this point, you'll need to type in your user id and password, as
+provided by your system administrator. You will hear Speakup speak the
+letters of your user id as you type it, but not the password. This is
+because the password is not displayed on the screen for security
+reasons. This has nothing to do with Speakup, it's a Linux security
+feature.
+
+Once you've logged in, you can run any Linux command or program which is
+allowed by your user id. Normal users will not be able to run programs
+which require root privileges.
+
+When you are running a program or command, Speakup will automatically
+speak new text as it arrives on the screen. You can at any time silence
+the speech with keypad enter, or use any of the Speakup review keys.
+
+Here are some basic Speakup review keys, and a short description of what
+they do.
+
+keypad 1 -- read previous character
+keypad 2 -- read current character (pressing keypad 2 twice rapidly will speak
+ the current character phonetically)
+keypad 3 -- read next character
+keypad 4 -- read previous word
+keypad 5 -- read current word (press twice rapidly to spell the current word)
+keypad 6 -- read next word
+keypad 7 -- read previous line
+keypad 8 -- read current line (press twice rapidly to hear how much the
+ text on the current line is indented)
+keypad 9 -- read next line
+keypad period -- speak current cursor position and announce current
+ virtual console
+
+It's also worth noting that the insert key on the keypad is mapped
+as the speakup key. Instead of pressing and releasing this key, as you
+do under DOS or Windows, you hold it like a shift key, and press other
+keys in combination with it. For example, repeatedly holding keypad
+insert, from now on called speakup, and keypad enter will toggle the
+speaking of new text on the screen on and off. This is not the same as
+just pressing keypad enter by itself, which just silences the speech
+until you hit another key. When you hit speakup plus keypad enter,
+Speakup will say, "You turned me off.", or "Hey, that's better." When
+Speakup is turned off, no new text on the screen will be spoken. You
+can still use the reading controls to review the screen however.
+
+3. Using the Speakup Help System
+
+Speakup has a help system, which is compiled as a module. It is loaded
+automatically whenever the Speakup help system is invoked for the first
+time, and remains loaded after that, until speakup is unloaded. Note
+that if speakup was compiled into a monolithic kernel on your system,
+you will not be able to unload Speakup from your kernel. If you try to
+use the help system, and find that it is unavailable, then your system
+administrator has not installed the Speakup help module, which is called
+speakup_help. Complain to your system administrator about this.
+
+In order to enter the Speakup help system, press and hold the speakup
+key (remember that this is the keypad insert key), and press the f1 key.
+You will hear the message:
+
+"Press space to leave help, cursor up or down to scroll, or a letter to
+go to commands in list."
+
+When you press the spacebar to leave the help system, you will hear:
+
+"Leaving help."
+
+While you are in the Speakup help system, you can scroll up or down
+through the list of available commands using the cursor keys. The list
+of commands is arranged in alphabetical order. If you wish to jump to
+commands in a specific part of the alphabet, you may press the letter of
+the alphabet you wish to jump to.
+
+You can also just explore by typing keyboard keys. Pressing keys will
+cause Speakup to speak the command associated with that key. For
+example, if you press the keypad 8 key, you will hear:
+
+"Keypad 8 is line, say current."
+
+You'll notice that some commands do not have keys assigned to them.
+This is because they are very infrequently used commands, and are also
+accessible through the proc system. We'll discuss the proc system later
+in this manual.
+
+You'll also notice that some commands have two keys assigned to them.
+This is because Speakup has a built in set of alternative key bindings
+for laptop users. The alternate speakup key is the caps lock key. You
+can press and hold the caps lock key, while pressing an alternate
+speakup command key to activate the command. On most laptops, the
+numeric keypad is defined as the keys in the j k l area of the keyboard.
+
+There is usually a function key which turns this keypad function on and
+off, and some other key which controls the numlock state. Toggling the
+keypad functionality on and off can become a royal pain. So, Speakup
+gives you a simple way to get at an alternative set of key mappings for
+your laptop. These are also available by default on desktop systems,
+because Speakup does not know whether it is running on a desktop or
+laptop. So you may choose which set of Speakup keys to use. Some
+system administrators may have chosen to compile Speakup for a desktop
+system without this set of alternate key bindings, but these details are
+beyond the scope of this manual. To use the caps lock for its normal
+purpose, hold the shift key while toggling the caps lock on and off. We
+should note here, that holding the caps lock key and pressing the z key
+will toggle the alternate j k l keypad on and off.
+
+4. Keys and Their Assigned Commands
+
+In this section, we'll go through a list of all the speakup keys and
+commands. You can also get a list of commands and assigned keys from
+the help system.
+
+The following list was taken from the speakupmap.map file. Key
+assignments are on the left of the equal sign, and the associated
+Speakup commands are on the right. The designation "spk" means to press
+and hold the speakup key, a.k.a. keypad insert, a.k.a. caps lock, while
+pressing the other specified key.
+
+spk key_f9 = punc_level_dec
+spk key_f10 = punc_level_inc
+spk key_f11 = reading_punc_dec
+spk key_f12 = reading_punc_inc
+spk key_1 = vol_dec
+spk key_2 = vol_inc
+spk key_3 = pitch_dec
+spk key_4 = pitch_inc
+spk key_5 = rate_dec
+spk key_6 = rate_inc
+key_kpasterisk = toggle_cursoring
+spk key_kpasterisk = speakup_goto
+spk key_f1 = speakup_help
+spk key_f2 = set_win
+spk key_f3 = clear_win
+spk key_f4 = enable_win
+spk key_f5 = edit_some
+spk key_f6 = edit_most
+spk key_f7 = edit_delim
+spk key_f8 = edit_repeat
+shift spk key_f9 = edit_exnum
+ key_kp7 = say_prev_line
+spk key_kp7 = left_edge
+ key_kp8 = say_line
+double key_kp8 = say_line_indent
+spk key_kp8 = say_from_top
+ key_kp9 = say_next_line
+spk key_kp9 = top_edge
+ key_kpminus = speakup_parked
+spk key_kpminus = say_char_num
+ key_kp4 = say_prev_word
+spk key_kp4 = say_from_left
+ key_kp5 = say_word
+double key_kp5 = spell_word
+spk key_kp5 = spell_phonetic
+ key_kp6 = say_next_word
+spk key_kp6 = say_to_right
+ key_kpplus = say_screen
+spk key_kpplus = say_win
+ key_kp1 = say_prev_char
+spk key_kp1 = right_edge
+ key_kp2 = say_char
+spk key_kp2 = say_to_bottom
+double key_kp2 = say_phonetic_char
+ key_kp3 = say_next_char
+spk key_kp3 = bottom_edge
+ key_kp0 = spk_key
+ key_kpdot = say_position
+spk key_kpdot = say_attributes
+key_kpenter = speakup_quiet
+spk key_kpenter = speakup_off
+key_sysrq = speech_kill
+ key_kpslash = speakup_cut
+spk key_kpslash = speakup_paste
+spk key_pageup = say_first_char
+spk key_pagedown = say_last_char
+key_capslock = spk_key
+ spk key_z = spk_lock
+key_leftmeta = spk_key
+ctrl spk key_0 = speakup_goto
+spk key_u = say_prev_line
+spk key_i = say_line
+double spk key_i = say_line_indent
+spk key_o = say_next_line
+spk key_minus = speakup_parked
+shift spk key_minus = say_char_num
+spk key_j = say_prev_word
+spk key_k = say_word
+double spk key_k = spell_word
+spk key_l = say_next_word
+spk key_m = say_prev_char
+spk key_comma = say_char
+double spk key_comma = say_phonetic_char
+spk key_dot = say_next_char
+spk key_n = say_position
+ ctrl spk key_m = left_edge
+ ctrl spk key_y = top_edge
+ ctrl spk key_dot = right_edge
+ctrl spk key_p = bottom_edge
+spk key_apostrophe = say_screen
+spk key_h = say_from_left
+spk key_y = say_from_top
+spk key_semicolon = say_to_right
+spk key_p = say_to_bottom
+spk key_slash = say_attributes
+ spk key_enter = speakup_quiet
+ ctrl spk key_enter = speakup_off
+ spk key_9 = speakup_cut
+spk key_8 = speakup_paste
+shift spk key_m = say_first_char
+ ctrl spk key_semicolon = say_last_char
+
+5. The Speakup Proc System
+
+The Speakup screen reader also creates a speakup subdirectory as a part
+of the proc system. You can see these entries by typing the command:
+
+ls -1 /proc/speakup/*
+
+If you issue the above ls command, you will get back something like
+this:
+
+/proc/speakup/attrib_bleep
+/proc/speakup/bell_pos
+/proc/speakup/bleep_time
+/proc/speakup/bleeps
+/proc/speakup/caps_start
+/proc/speakup/caps_stop
+/proc/speakup/characters
+/proc/speakup/cursor_time
+/proc/speakup/delay_time
+/proc/speakup/delimiters
+/proc/speakup/ex_num
+/proc/speakup/freq
+/proc/speakup/full_time
+/proc/speakup/jiffy_delta
+/proc/speakup/key_echo
+/proc/speakup/keymap
+/proc/speakup/no_interrupt
+/proc/speakup/pitch
+/proc/speakup/punc_all
+/proc/speakup/punc_level
+/proc/speakup/punc_most
+/proc/speakup/punc_some
+/proc/speakup/punct
+/proc/speakup/rate
+/proc/speakup/reading_punc
+/proc/speakup/repeats
+/proc/speakup/say_control
+/proc/speakup/say_word_ctl
+/proc/speakup/silent
+/proc/speakup/spell_delay
+/proc/speakup/synth_direct
+/proc/speakup/synth_name
+/proc/speakup/tone
+/proc/speakup/trigger_time
+/proc/speakup/version
+/proc/speakup/voice
+/proc/speakup/vol
+
+In addition to using the Speakup hot keys to change such things as
+volume, pitch, and rate, you can also echo values to the appropriate
+entry in the /proc/speakup directory. This is very useful, since it
+lets you control Speakup parameters from within a script. How you
+would write such scripts is somewhat beyond the scope of this manual,
+but I will include a couple of simple examples here to give you a
+general idea of what such scripts can do.
+
+Suppose for example, that you wanted to control both the punctuation
+level and the reading punctuation level at the same time. For
+simplicity, we'll call them punc0, punc1, punc2, and punc3. The scripts
+might look something like this:
+
+#!/bin/bash
+# punc0
+# set punc and reading punc levels to 0
+echo 0 >/proc/speakup/punc_level
+echo 0 >/proc/speakup/reading_punc
+echo Punctuation level set to 0.
+
+#!/bin/bash
+# punc1
+# set punc and reading punc levels to 1
+echo 1 >/proc/speakup/punc_level
+echo 1 >/proc/speakup/reading_punc
+echo Punctuation level set to 1.
+
+#!/bin/bash
+# punc2
+# set punc and reading punc levels to 2
+echo 2 >/proc/speakup/punc_level
+echo 2 >/proc/speakup/reading_punc
+echo Punctuation level set to 2.
+
+#!/bin/bash
+# punc3
+# set punc and reading punc levels to 3
+echo 3 >/proc/speakup/punc_level
+echo 3 >/proc/speakup/reading_punc
+echo Punctuation level set to 3.
+
+If you were to store these four small scripts in a directory in your
+path, perhaps /usr/local/bin, and set the permissions to 755 with the
+chmod command, then you could change the default reading punc and
+punctuation levels at the same time by issuing just one command. For
+example, if you were to execute the punc3 command at your shell prompt,
+then the reading punc and punc level would both get set to 3.
+
+I should note that the above scripts were written to work with bash, but
+regardless of which shell you use, you should be able to do something
+similar.
+
+The Speakup proc system also has another interesting use. You can echo
+Speakup parameters into the proc system in a script during system
+startup, and speakup will return to your preferred parameters every time
+the system is rebooted.
+
+Most of the Speakup proc parameters can be manipulated by a regular user
+on the system. However, there are a few parameters that are dangerous
+enough that they should only be manipulated by the root user on your
+system. There are even some parameters that are read only, and cannot
+be written to at all. For example, the version entry in the Speakup
+proc system is read only. This is because there is no reason for a user
+to tamper with the version number which is reported by Speakup. Doing
+an ls -l on /proc/speakup/version will return this:
+
+-r--r--r-- 1 root root 0 Mar 21 13:46 /proc/speakup/version
+
+As you can see, the version entry in the Speakup proc system is read
+only, is owned by root, and belongs to the root group. Doing a cat of
+/proc/speakup/version will display the Speakup version number, like
+this:
+
+cat /proc/speakup/version
+Speakup v-2.00 CVS: Thu Oct 21 10:38:21 EDT 2004
+synth dtlk version 1.1
+
+The display shows the Speakup version number, along with the version
+number of the driver for the current synthesizer.
+
+Looking at entries in the Speakup proc system can be useful in many
+ways. For example, you might wish to know what level your volume is set
+at. You could type:
+
+cat /proc/speakup/vol
+5
+
+The number five which comes back is the level at which the synthesizer
+volume is set at.
+
+All the entries in the Speakup proc system are readable, some are
+writable by root only, and some are writable by everyone. Unless you
+know what you are doing, you should probably leave the ones that are
+writable by root only alone. Most of the names are self explanatory.
+Vol for controlling volume, pitch for pitch, rate for controlling speaking
+rate, etc. If you find one you aren't sure about, you can post a query
+on the Speakup list.
+
+6. Changing Synthesizers
+
+It is possible to change to a different synthesizer while speakup is
+running. In other words, it is not necessary to reboot the system
+in order to use a different synthesizer. You can simply echo the
+synthesizer keyword to the /proc/speakup/synth_name proc entry.
+Depending on your situation, you may wish to echo none to the synth_name
+proc entry, to disable speech while one synthesizer is disconnected and
+a second one is connected in its place. Then echo the keyword for the
+new synthesizer into the synth_name proc entry in order to start speech
+with the newly connected synthesizer. See the list of synthesizer
+keywords in section 1 to find the keyword which matches your synth.
+
+7. Loading modules
+
+As mentioned earlier, Speakup can either be completely compiled into the
+kernel, with the exception of the help module, or it can be compiled as
+a series of modules. When compiled as modules, Speakup will only be
+able to speak some of the bootup messages if your system administrator
+has configured the system to load the modules at boo time. The modules
+can be loaded after the file systems have been checked and mounted, or
+from an initrd. There is a third possibility. Speakup can be compiled
+with some components built into the kernel, and others as modules. As
+we'll see in the next section, this is particularly useful when you are
+working with software synthesizers.
+
+If Speakup is completely compiled as modules, then you must use the
+modprobe command to load Speakup. You do this by loading the module for
+the synthesizer driver you wish to use. The driver modules are all
+named speakup_, where is the keyword for the
+synthesizer you want. So, in order to load the driver for the DecTalk
+Express, you would type the following command:
+
+modprobe speakup_dectlk
+
+Issuing this command would load the DecTalk Express driver and all other
+related Speakup modules necessary to get Speakup up and running.
+
+To completely unload Speakup, again presuming that it is entirely built
+as modules, you would give the command:
+
+modprobe -r speakup_dectlk
+
+The above command assumes you were running a DecTalk Express. If you
+were using a different synth, then you would substitute its keyword in
+place of dectlk.
+
+But now, suppose we have a situation where the main Speakup component
+is built into the kernel, and some or all of the drivers are built as
+modules. Since the main part of Speakup is compiled into the kernel, a
+partial Speakup proc system has been created which we can take advantage
+of by simply echoing the synthesizer keyword into the
+/proc/speakup/synth_name proc entry. This will cause the kernel to
+automatically load the appropriate driver module, and start Speakup
+talking. To switch to another synth, just echo a new keyword to the
+synth_name proc entry. For example, to load the DoubleTalk LT driver,
+you would type:
+
+echo ltlk >/proc/speakup/synth_name
+
+You can use the modprobe -r command to unload driver modules, regardless
+of whether the main part of Speakup has been built into the kernel or
+not.
+
+8. Using Software Synthesizers
+
+Using a software synthesizer requires that some other software be
+installed and running on your system. For this reason, software
+synthesizers are not available for use at bootup, or during a system
+installation process.
+
+In order to use a software synthesizer, you must have a package called
+Speech Dispatcher running on your system, and it must be configured to
+work with one of its supported software synthesizers.
+
+Two open source synthesizers you might use are Flite and Festival. You
+might also choose to purchase the Software DecTalk from Fonix Sales Inc.
+If you run a google search for Fonix, you'll find their web site.
+
+You can obtain a copy of Speech Dispatcher from free(b)soft at
+http://www.freebsoft.org/. Follow the installation instructions that
+come with Speech Dispatcher in order to install and configure Speech
+Dispatcher. You can check out the web site for your Linux distribution
+in order to get a copy of either Flite or Festival. Your Linux
+distribution may also have a precompiled Speech Dispatcher package.
+
+Once you've installed, configured, and tested Speech Dispatcher with your
+chosen software synthesizer, you still need one more piece of software
+in order to make things work. You need a package called speechd-up.
+You get it from the free(b)soft web site mentioned above. After you've
+compiled and installed speechd-up, you are almost ready to begin using
+your software synthesizer.
+
+Before you can use a software synthesizer, you must have created the
+/dev/softsynth device. If you have not already done so, issue the
+following commands as root:
+
+cd /dev
+mknod softsynth c 10 26
+
+While we are at it, we might just as well create the /dev/synth device,
+which can be used to let user space programs send information to your
+synthesizer. To create /dev/synth, change to the /dev directory, and
+issue the following command as root:
+
+mknod synth c 10 25
+
+Now you can begin using your software synthesizer. In order to do so,
+echo the sftsyn keyword to the synth_name proc entry like this:
+
+echo sftsyn >/proc/speakup/synth_name
+
+Next run the speechd_up command like this:
+
+speechd_up &
+
+Your synth should now start talking, and you should be able to adjust
+the pitch, rate, etc.
+
+In this section, we have assumed that your copy of Speakup was compiled
+with the speakup_sftsyn component either built into the kernel, or
+compiled as a module.
+
+9. Using The DecTalk PC Card
+
+The DecTalk PC card is an ISA card that is inserted into one of the ISA
+slots in your computer. It requires that the DecTalk PC software be
+installed on your computer, and that the software be loaded onto the
+Dectalk PC card before it can be used.
+
+You can get the dec_pc.tgz file from the linux-speakup.org site. The
+dec_pc.tgz file is in the ~ftp/pub/linux/speakup directory.
+
+After you have downloaded the dec_pc.tgz file, untar it in your home
+directory, and read the Readme file in the newly created dec_pc
+directory.
+
+The easiest way to get the software working is to copy the entire dec_pc
+directory into /user/local/lib. To do this, su to root in your home
+directory, and issue the command:
+
+cp dec_pc /usr/local/lib
+
+You will need to copy the dtload command from the dec_pc directory to a
+directory in your path. Either /usr/bin or /usr/local/bin is a good
+choice.
+
+You can now run the dtload command in order to load the DecTalk PC
+software onto the card. After you have done this, echo the decpc
+keyword to the synth_name entry in the proc system like this:
+
+echo decpc >/proc/speakup/synth_name
+
+Your DecTalk PC should start talking, and then you can adjust the pitch,
+rate, volume, voice, etc. The voice entry in the Speakup proc system
+will accept a number from 0 through 7 for the DecTalk PC synthesizer,
+which will give you access to some of the DecTalk voices.
+
+10. Using Cursor Tracking
+
+In Speakup version 2.0 and later, cursor tracking is turned on by
+default. This means that when you are using an editor, Speakup will
+automatically speak characters as you move left and right with the
+cursor keys, and lines as you move up and down with the cursor keys.
+
+This is extremely useful, and makes editing files a snap. But there are
+times when cursor tracking can get in your way. So Speakup provides a
+toggle to turn cursor tracking on and off. You do this with the keypad
+asterisk key. Pressing this key repeatedly will toggle the cursor
+tracking on and off, and you will hear Speakup say, "cursoring off", and
+"cursoring on".
+
+Some folks like to turn cursor tracking off while they are using the
+lynx web browser. You definitely want to turn cursor tracking off when
+you are using the alsamixer application. Otherwise, you won't be able
+to hear your mixer settings while you are using the arrow keys.
+
+11. Cut and Paste
+
+One of Speakup's more useful features is the ability to cut and paste
+text on the screen. This means that you can capture information from a
+program, and paste that captured text into a different place in the
+program, or into an entirely different program, which may even be
+running on a different console.
+
+For example, in this manual, we have made references to several web
+sites. It would be nice if you could cut and paste these urls into your
+web browser. Speakup does this quite nicely. Suppose you wanted to
+past the following url into your browser:
+
+http://linux-speakup.org/
+
+Use the speakup review keys to position the reading cursor on the first
+character of the above url. When the reading cursor is in position,
+press the keypad slash key once. Speakup will say, "mark". Next,
+position the reading cursor on the rightmost character of the above
+url. Press the keypad slash key once again to actually cut the text
+from the screen. Speakup will say, "cut". Although we call this
+cutting, Speakup does not actually delete the cut text from the screen.
+It makes a copy of the text in a special buffer for later pasting.
+
+Now that you have the url cut from the screen, you can paste it into
+your browser, or even paste the url on a command line as an argument to
+your browser.
+
+Suppose you want to start lynx and go to the Speakup site.
+
+You can switch to a different console with the alt left and right
+arrows, or you can switch to a specific console by typing alt and a
+function key. These are not Speakup commands, just standard Linux
+console capabilities.
+
+Once you've changed to an appropriate console, and are at a shell prompt,
+type the word lynx, followed by a space. Now press and hold the speakup
+key, while you type the keypad slash character. The url will be pasted
+onto the command line, just as though you had typed it in. Press the
+enter key to execute the command.
+
+The paste buffer will continue to hold the cut information, until a new
+mark and cut operation is carried out. This means you can paste the cut
+information as many times as you like before doing another cut
+operation.
+
+You are not limited to cutting and pasting only one line on the screen.
+You can also cut and paste rectangular regions of the screen. Just
+position the reading cursor at the top left corner of the text to be
+cut, mark it with the keypad slash key, then position the reading cursor
+at the bottom right corner of the region to be cut, and cut it with the
+keypad slash key.
+
+12. Changing the Pronunciation of Characters
+
+Through the /proc/speakup/chars proc entry, Speakup gives you the
+ability to change how Speakup pronounces a given character. You could,
+for example, change how some punctuation characters are spoken. You can
+even change how Speakup will pronounce certain letters.
+
+You may, for example, wish to change how Speakup pronounces the z
+character. The author of Speakup, Kirk Reiser, is Canadian, and thus
+believes that the z should be pronounced zed. If you are an American,
+you might wish to use the zee pronunciation instead of zed. You can
+change the pronunciation of both the upper and lower case z with the
+following two commands:
+
+echo 90 zee >/proc/speakup/characters
+echo 122 zee >/proc/speakup/characters
+
+Let's examine the parts of the two previous commands. They are issued
+at the shell prompt, and could be placed in a startup script.
+
+The word echo tells the shell that you want to have it display the
+string of characters that follow the word echo. If you were to just
+type:
+
+echo hello.
+
+You would get the word hello printed on your screen as soon as you
+pressed the enter key. In this case, we are echoing strings that we
+want to be redirected into the proc system.
+
+The numbers 90 and 122 in the above echo commands are the ascii numeric
+values for the upper and lower case z, the characters we wish to change.
+
+The string zee is the pronunciation that we want Speakup to use for the
+upper and lower case z.
+
+The > symbol redirects the output of the echo command to a file, just
+like in DOS, or at the Windows command prompt.
+
+And finally, /proc/speakup/chars is the file entry in the proc system
+where we want the output to be directed. Speakup looks at the numeric
+value of the character we want to change, and inserts the pronunciation
+string into an internal table.
+
+You can look at the whole table with the following command:
+
+cat /proc/speakup/chars
+
+Speakup will then print out the entire character pronunciation table. I
+won't display it here, but leave you to look at it at your convenience.
+
+13. Mapping Keys
+
+Speakup has the capability of allowing you to assign or "map" keys to
+internal Speakup commands. This section necessarily assumes you have a
+Linux kernel source tree installed, and that it has been patched and
+configured with Speakup. How you do this is beyond the scope of this
+manual. For this information, visit the Speakup web site at
+http://linux-speakup.org/. The reason you'll need the kernel source
+tree patched with Speakup is that the genmap utility you'll need for
+processing keymaps is in the
+/usr/src/linux-/drivers/char/speakup directory. The
+ in the above directory path is the version number of
+the Linux source tree you are working with.
+
+So ok, you've gone off and gotten your kernel source tree, and patched
+and configured it. Now you can start manipulating keymaps.
+
+You can either use the
+/usr/src/linux-/drivers/char/speakup/speakupmap.map file
+included with the Speakup source, or you can cut and paste the copy in
+section 4 into a separate file. If you use the one in the Speakup
+source tree, make sure you make a backup of it before you start making
+changes. You have been warned!
+
+Suppose that you want to swap the key assignments for the Speakup
+say_last_char and the Speakup say_first_char commands. The
+speakupmap.map lists the key mappings for these two commands as follows:
+
+spk key_pageup = say_first_char
+spk key_pagedown = say_last_char
+
+You can edit your copy of the speakupmap.map file and swap the command
+names on the right side of the = (equals) sign. You did make a backup,
+right? The new keymap lines would look like this:
+
+spk key_pageup = say_last_char
+spk key_pagedown = say_first_char
+
+After you edit your copy of the speakupmap.map file, save it under a new
+file name, perhaps newmap.map. Then exit your editor and return to the
+shell prompt.
+
+You are now ready to load your keymap with your swapped key assignments.
+ Assuming that you saved your new keymap as the file newmap.map, you
+would load your keymap into the proc system like this:
+
+/usr/src/linux-/drivers/char/speakup/genmap newmap.map
+>/proc/speakup/keymap
+
+Remember to substitute your kernel version number for the
+ in the above command. Also note that although the
+above command wrapped onto two lines in this document, you should type
+it all on one line.
+
+Your say first and say last characters should now be swapped. Pressing
+speakup pagedown should read you the first non-whitespace character on
+the line your reading cursor is in, and pressing speakup pageup should
+read you the last character on the line your reading cursor is in.
+
+You should note that these new mappings will only stay in effect until
+you reboot, or until you load another keymap.
+
+One final warning. If you try to load a partial map, you will quickly
+find that all the mappings you didn't include in your file got deleted
+from the working map. Be extremely careful, and always make a backup!
+You have been warned!
+
+14. Using Speakup's Windowing Capability
+
+Speakup has the capability of defining and manipulating windows on the
+screen. Speakup uses the term "Window", to mean a user defined area of
+the screen. The key strokes for defining and manipulating Speakup
+windows are as follows:
+
+speakup + f2 -- Set the bounds of the window.
+Speakup + f3 -- clear the current window definition.
+speakup + f4 -- Toggle window silence on and off.
+speakup + keypad plus -- Say the currently defined window.
+
+These capabilities are useful for tracking a certain part of the screen
+without rereading the whole screen, or for silencing a part of the
+screen that is constantly changing, such as a clock or status line.
+
+There is no way to save these window settings, and you can only have one
+window defined for each virtual console. There is also no way to have
+windows automaticly defined for specific applications.
+
+In order to define a window, use the review keys to move your reading
+cursor to the beginning of the area you want to define. Then press
+speakup + f2. Speakup will tell you that the window starts at the
+indicated row and column position. Then move the reading cursor to the
+end of the area to be defined as a window, and press speakup + f2 again.
+ If there is more than one line in the window, Speakup will tell you
+that the window ends at the indicated row and column position. If there
+is only one line in the window, then Speakup will tell you that the
+window is the specified line on the screen. If you are only defining a
+one line window, you can just press speakup + f2 twice after placing the
+reading cursor on the line you want to define as a window. It is not
+necessary to position the reading cursor at the end of the line in order
+to define the whole line as a window.
+
+ GNU Free Documentation License
+ Version 1.2, November 2002
+
+
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+0. PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document "free" in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+
+1. APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The "Document", below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as "you". You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A "Modified Version" of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (Thus, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The "Cover Texts" are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A "Transparent" copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML, PostScript or PDF designed for human modification. Examples of
+transparent image formats include PNG, XCF and JPG. Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML, PostScript or PDF produced by some word
+processors for output purposes only.
+
+The "Title Page" means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, "Title Page" means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section "Entitled XYZ" means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as "Acknowledgements",
+"Dedications", "Endorsements", or "History".) To "Preserve the Title"
+of such a section when you modify the Document means that it remains a
+section "Entitled XYZ" according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+
+2. VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+3. COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+
+4. MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+ from that of the Document, and from those of previous versions
+ (which should, if there were any, be listed in the History section
+ of the Document). You may use the same title as a previous version
+ if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the Modified
+ Version, together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has fewer than five),
+ unless they release you from this requirement.
+C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice
+ giving the public permission to use the Modified Version under the
+ terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections
+ and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section Entitled "History", Preserve its Title, and add
+ to it an item stating at least the title, year, new authors, and
+ publisher of the Modified Version as given on the Title Page. If
+ there is no section Entitled "History" in the Document, create one
+ stating the title, year, authors, and publisher of the Document as
+ given on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the "History" section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section all
+ the substance and tone of each of the contributor acknowledgements
+ and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.
+M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+N. Do not retitle any existing section to be Entitled "Endorsements"
+ or to conflict in title with any Invariant Section.
+O. Preserve any Warranty Disclaimers.
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled "Endorsements", provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+
+5. COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled "History"
+in the various original documents, forming one section Entitled
+"History"; likewise combine any sections Entitled "Acknowledgements",
+and any sections Entitled "Dedications". You must delete all sections
+Entitled "Endorsements".
+
+
+6. COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an "aggregate" if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+
+8. TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled "Acknowledgements",
+"Dedications", or "History", the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+
+9. TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+
+
+ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+ Copyright (c) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+The End.
diff -u -r --new-file linux-2.4.30.orig/arch/alpha/config.in linux-2.4.30/arch/alpha/config.in
--- linux-2.4.30.orig/arch/alpha/config.in 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.30/arch/alpha/config.in 2005-05-01 19:02:59.000000000 -0700
@@ -417,6 +417,7 @@
# fi
# fi
source drivers/video/Config.in
+ source drivers/char/speakup/Config.in
if [ "$CONFIG_FB" = "y" ]; then
define_bool CONFIG_PCI_CONSOLE y
fi
diff -u -r --new-file linux-2.4.30.orig/arch/arm/config.in linux-2.4.30/arch/arm/config.in
--- linux-2.4.30.orig/arch/arm/config.in 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.30/arch/arm/config.in 2005-05-01 19:02:59.000000000 -0700
@@ -669,6 +669,7 @@
bool 'VGA text console' CONFIG_VGA_CONSOLE
fi
source drivers/video/Config.in
+ source drivers/char/speakup/Config.in
endmenu
fi
diff -u -r --new-file linux-2.4.30.orig/arch/i386/config.in linux-2.4.30/arch/i386/config.in
--- linux-2.4.30.orig/arch/i386/config.in 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.30/arch/i386/config.in 2005-05-01 19:02:59.000000000 -0700
@@ -451,6 +451,7 @@
tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
source drivers/video/Config.in
fi
+ source drivers/char/speakup/Config.in
endmenu
fi
diff -u -r --new-file linux-2.4.30.orig/arch/m68k/config.in linux-2.4.30/arch/m68k/config.in
--- linux-2.4.30.orig/arch/m68k/config.in 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.30/arch/m68k/config.in 2005-05-01 19:02:59.000000000 -0700
@@ -538,6 +538,7 @@
mainmenu_option next_comment
comment 'Console drivers'
source drivers/video/Config.in
+ source drivers/char/speakup/Config.in
endmenu
fi
diff -u -r --new-file linux-2.4.30.orig/arch/mips/config-shared.in linux-2.4.30/arch/mips/config-shared.in
--- linux-2.4.30.orig/arch/mips/config-shared.in 2005-01-19 06:09:27.000000000 -0800
+++ linux-2.4.30/arch/mips/config-shared.in 2005-05-01 19:02:59.000000000 -0700
@@ -990,6 +990,7 @@
tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
source drivers/video/Config.in
fi
+ source drivers/char/speakup/Config.in
endmenu
fi
diff -u -r --new-file linux-2.4.30.orig/arch/ppc/config.in linux-2.4.30/arch/ppc/config.in
--- linux-2.4.30.orig/arch/ppc/config.in 2004-08-07 16:26:04.000000000 -0700
+++ linux-2.4.30/arch/ppc/config.in 2005-05-01 19:02:59.000000000 -0700
@@ -533,6 +533,7 @@
bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
fi
source drivers/video/Config.in
+ source drivers/char/speakup/Config.in
if [ "$CONFIG_FB" = "y" -a "$CONFIG_ALL_PPC" = "y" ]; then
bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
fi
diff -u -r --new-file linux-2.4.30.orig/arch/sparc/config.in linux-2.4.30/arch/sparc/config.in
--- linux-2.4.30.orig/arch/sparc/config.in 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.30/arch/sparc/config.in 2005-05-01 19:02:59.000000000 -0700
@@ -85,6 +85,7 @@
comment 'Console drivers'
bool 'PROM console' CONFIG_PROM_CONSOLE
source drivers/video/Config.in
+source drivers/char/speakup/Config.in
endmenu
source drivers/mtd/Config.in
diff -u -r --new-file linux-2.4.30.orig/arch/sparc64/config.in linux-2.4.30/arch/sparc64/config.in
--- linux-2.4.30.orig/arch/sparc64/config.in 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.30/arch/sparc64/config.in 2005-05-01 19:02:59.000000000 -0700
@@ -99,6 +99,7 @@
comment 'Console drivers'
bool 'PROM console' CONFIG_PROM_CONSOLE
source drivers/video/Config.in
+source drivers/char/speakup/Config.in
endmenu
source drivers/sbus/char/Config.in
diff -u -r --new-file linux-2.4.30.orig/drivers/char/Makefile linux-2.4.30/drivers/char/Makefile
--- linux-2.4.30.orig/drivers/char/Makefile 2004-08-07 16:26:04.000000000 -0700
+++ linux-2.4.30/drivers/char/Makefile 2005-05-01 19:02:59.000000000 -0700
@@ -22,12 +22,12 @@
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
export-objs := busmouse.o console.o keyboard.o sysrq.o \
- misc.o pty.o random.o selection.o serial.o \
+ misc.o pty.o random.o selection.o serial.o vt.o \
sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \
- scx200.o fetchop.o
+ scx200.o fetchop.o consolemap.o
-mod-subdirs := joystick ftape drm drm-4.0 pcmcia
+mod-subdirs := joystick ftape drm drm-4.0 pcmcia speakup
list-multi :=
@@ -186,6 +186,9 @@
endif
obj-$(CONFIG_HIL) += hp_keyb.o
+ifeq ($(CONFIG_SPEAKUP),y)
+obj-y += speakup/spk.o
+endif
obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
obj-$(CONFIG_ROCKETPORT) += rocket.o
@@ -275,6 +278,7 @@
obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
+subdir-$(CONFIG_SPEAKUP) += speakup
subdir-$(CONFIG_FTAPE) += ftape
subdir-$(CONFIG_DRM_OLD) += drm-4.0
subdir-$(CONFIG_DRM_NEW) += drm
diff -u -r --new-file linux-2.4.30.orig/drivers/char/console.c linux-2.4.30/drivers/char/console.c
--- linux-2.4.30.orig/drivers/char/console.c 2005-01-19 06:09:44.000000000 -0800
+++ linux-2.4.30/drivers/char/console.c 2005-05-01 19:02:59.000000000 -0700
@@ -107,8 +107,13 @@
#include
#include
+#include
+
#include "console_macros.h"
+#ifdef CONFIG_SPEAKUP_MODULE
+#include "speakup/spk_con_module.h"
+#endif
const struct consw *conswitchp;
@@ -695,6 +700,7 @@
screenbuf = (unsigned short *) q;
kmalloced = 1;
vc_init(currcons, video_num_lines, video_num_columns, 1);
+ speakup_allocate(currcons); /* speakup needs more too. */
if (!pm_con) {
pm_con = pm_register(PM_SYS_DEV,
@@ -927,6 +933,7 @@
pos += video_size_row;
}
need_wrap = 0;
+ speakup_con_write(currcons, "\n",1);
}
static void ri(int currcons)
@@ -953,8 +960,9 @@
{
if (x) {
pos -= 2;
- x--;
need_wrap = 0;
+ x--;
+ speakup_bs(currcons);
}
}
@@ -1487,6 +1495,7 @@
break;
}
pos += (x << 1);
+ speakup_con_write(currcons, " ", 1);
return;
case 10: case 11: case 12:
lf(currcons);
@@ -2000,6 +2009,7 @@
}
if (decim)
insert_char(currcons, 1);
+ speakup_con_write(currcons, (char *) &tc,1);
scr_writew(himask ?
((attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
(attr << 8) + tc,
@@ -2040,6 +2050,7 @@
up(&con_buf_sem);
}
+ speakup_con_update(currcons);
return n;
#undef FLUSH
@@ -2070,6 +2081,7 @@
/* we only changed when the console had already
been allocated - a new console is not created
in an interrupt routine */
+ speakup_allocate(want_console);
}
want_console = -1;
}
@@ -2139,6 +2151,7 @@
/* Contrived structure to try to emulate original need_wrap behaviour
* Problems caused when we have need_wrap set on '\n' character */
+ speakup_con_write(currcons, b, count);
while (count--) {
c = *b++;
if (c == 10 || c == 13 || c == 8 || need_wrap) {
@@ -2183,6 +2196,7 @@
}
}
set_cursor(currcons);
+ speakup_con_update(currcons);
if (!oops_in_progress)
poke_blanked_console();
@@ -2530,6 +2544,8 @@
master_display_fg = vc_cons[currcons].d;
set_origin(currcons);
save_screen(currcons);
+ speakup_init(currcons);
+
gotoxy(currcons,x,y);
csi_J(currcons, 0);
update_screen(fg_console);
@@ -3042,6 +3058,7 @@
EXPORT_SYMBOL(video_font_height);
EXPORT_SYMBOL(video_scan_lines);
EXPORT_SYMBOL(vc_resize);
+EXPORT_SYMBOL(vc_cons);
EXPORT_SYMBOL(fg_console);
EXPORT_SYMBOL(console_blank_hook);
#ifdef CONFIG_VT
@@ -3051,3 +3068,4 @@
EXPORT_SYMBOL(take_over_console);
EXPORT_SYMBOL(give_up_console);
#endif
+EXPORT_SYMBOL(screen_glyph);
diff -u -r --new-file linux-2.4.30.orig/drivers/char/consolemap.c linux-2.4.30/drivers/char/consolemap.c
--- linux-2.4.30.orig/drivers/char/consolemap.c 2001-02-09 11:30:22.000000000 -0800
+++ linux-2.4.30/drivers/char/consolemap.c 2005-05-01 19:02:59.000000000 -0700
@@ -22,6 +22,8 @@
#include
#include
+#include
+
static unsigned short translations[][256] = {
/* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
{
@@ -231,6 +233,7 @@
else
return p->inverse_translations[inv_translate[conp->vc_num]][glyph];
}
+EXPORT_SYMBOL(inverse_translate);
static void update_user_maps(void)
{
diff -u -r --new-file linux-2.4.30.orig/drivers/char/keyboard.c linux-2.4.30/drivers/char/keyboard.c
--- linux-2.4.30.orig/drivers/char/keyboard.c 2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.30/drivers/char/keyboard.c 2005-05-01 19:02:59.000000000 -0700
@@ -43,6 +43,8 @@
#include
#include
+#include
+
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
#ifndef KBD_DEFMODE
@@ -69,6 +71,9 @@
extern void ctrl_alt_del(void);
struct console;
+#ifdef CONFIG_SPEAKUP_MODULE
+spk_key_func addr_spk_key = NULL;
+#endif
/*
* global state includes the following, and various static variables
@@ -93,8 +98,8 @@
static char rep; /* flag telling character repeat */
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
static struct tty_struct **ttytab;
-static struct kbd_struct * kbd = kbd_table;
-static struct tty_struct * tty;
+struct kbd_struct * kbd = kbd_table;
+struct tty_struct * tty;
static unsigned char prev_scancode;
void compute_shiftstate(void);
@@ -107,15 +112,19 @@
do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
do_ignore;
-static k_hand key_handler[16] = {
+k_hand key_handler[16] = {
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
do_ignore, do_ignore
};
+EXPORT_SYMBOL(kbd);
+EXPORT_SYMBOL(tty);
+EXPORT_SYMBOL(key_handler);
+
/* Key types processed even in raw modes */
-#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT))
+#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) )
typedef void (*void_fnp)(void);
typedef void (void_fn)(void);
@@ -139,7 +148,7 @@
255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
255, NR_ASCII - 1, NR_LOCK - 1, 255,
- NR_LOCK - 1, 255
+ NR_LOCK - 1, 255, 255
};
const int NR_TYPES = SIZE(max_vals);
@@ -311,6 +320,14 @@
if (type >= 0xf0) {
type -= 0xf0;
+#ifdef CONFIG_SPEAKUP
+ if ( speakup_key(shift_final, keycode, keysym, up_flag ) )
+ goto out;
+#elif defined(CONFIG_SPEAKUP_MODULE)
+ if ( addr_spk_key && (*addr_spk_key)(shift_final,
+ keycode, keysym, up_flag ) )
+ goto out;
+#endif
if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type)))
goto out;
if (type == KT_LETTER) {
@@ -330,6 +347,14 @@
to_utf8(keysym);
}
} else {
+#ifdef CONFIG_SPEAKUP
+ if ( speakup_key(shift_final, keycode, K(KT_SHIFT,0), up_flag ) )
+ goto out;
+#elif defined(CONFIG_SPEAKUP_MODULE)
+ if ( addr_spk_key && (*addr_spk_key)(shift_final,
+ keycode, K(KT_SHIFT,0), up_flag ) )
+ goto out;
+#endif
/* maybe beep? */
/* we have at least to update shift_state */
#if 1 /* how? two almost equivalent choices follow */
@@ -536,11 +561,10 @@
compute_shiftstate();
}
+
static void do_spec(unsigned char value, char up_flag)
{
- if (up_flag)
- return;
- if (value >= SIZE(spec_fn_table))
+ if (up_flag || (value >= SIZE(spec_fn_table)))
return;
if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
!(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/BUGS linux-2.4.30/drivers/char/speakup/BUGS
--- linux-2.4.30.orig/drivers/char/speakup/BUGS 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/BUGS 2001-10-18 05:53:52.000000000 -0700
@@ -0,0 +1,10 @@
+Well, there are probably just thousands to squash, but these are the
+ones I think of as bugs.
+
+There is a problem with speakup interrogating LiteTalks with rom
+versions of at least 3.22 and earlier. (kirk)
+
+I define bugs as things which aren't working correctly although
+they've been implemented. NOT features which haven't been added yet.
+
+ Kirk
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/COPYING linux-2.4.30/drivers/char/speakup/COPYING
--- linux-2.4.30.orig/drivers/char/speakup/COPYING 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/COPYING 2000-06-01 12:38:40.000000000 -0700
@@ -0,0 +1,358 @@
+
+ NOTE! This copyright does *not* cover user programs that use kernel
+ services by normal system calls - this is merely considered normal use
+ of the kernel, and does *not* fall under the heading of "derived work".
+ Also note that the GPL below is copyrighted by the Free Software
+ Foundation, but the instance of code that it refers to (the Linux
+ kernel) is copyrighted by me and others who actually wrote it.
+
+ Linus Torvalds
+
+----------------------------------------
+
+This is included for completeness of GPL for the speakup project.
+Speakup is a screen review and speech synthesizer set of drivers and
+patches for the Linux kernel. (Kirk Reiser)
+
+------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C) 19yy
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/CVS/Entries linux-2.4.30/drivers/char/speakup/CVS/Entries
--- linux-2.4.30.orig/drivers/char/speakup/CVS/Entries 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/CVS/Entries 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1,54 @@
+/BUGS/1.8/Thu Oct 18 12:53:52 2001//
+/COPYING/1.1.1.1/Thu Jun 1 19:38:40 2000//
+/ChangeLog/1.13/Tue Apr 19 16:26:21 2005//
+/Changes/1.1.1.1/Thu Jun 1 19:38:40 2000//
+/Config.in/1.13/Wed Dec 10 15:29:56 2003//
+/Kconfig/1.10/Wed Dec 10 15:29:56 2003//
+/Makefile/1.40/Thu Oct 21 14:39:22 2004//
+/TODO/1.21/Sat Mar 6 15:55:29 2004//
+/checkclean/1.4/Sun Dec 31 18:20:36 2000//
+/checkin/1.28/Tue May 13 01:05:31 2003//
+/checkout/1.25/Tue May 13 14:35:07 2003//
+/cvsversion.h/1.344/Tue Apr 19 16:26:21 2005//
+/dtload.c/1.2/Fri Aug 8 18:15:12 2003//
+/dtload.h/1.1/Thu Jul 31 15:27:06 2003//
+/dtpc_reg.h/1.1/Thu Jul 31 15:27:06 2003//
+/genmap.c/1.14/Mon Jul 21 12:26:38 2003//
+/install/1.5/Tue Apr 19 16:26:21 2005//
+/keyinfo.h/1.5/Wed Nov 12 20:41:34 2003//
+/makemapdata.c/1.1/Fri Jul 18 14:08:34 2003//
+/mod_code.c/1.10/Mon Dec 22 21:22:11 2003//
+/patchlist-v22/1.7/Sun Oct 14 18:42:46 2001//
+/patchlist-v24/1.17/Thu Apr 7 19:57:31 2005//
+/patchlist-v25/1.8/Thu May 22 21:21:33 2003//
+/patchlist-v26/1.9/Thu Apr 7 19:57:31 2005//
+/serialio.h/1.2/Mon May 5 13:56:33 2003//
+/speakup.c/1.154/Wed Mar 2 22:40:51 2005//
+/speakup_acnt.h/1.2/Mon Apr 14 18:37:18 2003//
+/speakup_acntpc.c/1.18/Wed Oct 8 01:04:35 2003//
+/speakup_acntsa.c/1.23/Thu Nov 6 19:00:59 2003//
+/speakup_apollo.c/1.2/Sat Mar 6 15:55:29 2004//
+/speakup_audptr.c/1.24/Wed Oct 8 01:04:35 2003//
+/speakup_bns.c/1.19/Thu Nov 6 19:00:59 2003//
+/speakup_decext.c/1.22/Wed Oct 8 01:04:35 2003//
+/speakup_decpc.c/1.4/Tue Oct 28 16:15:27 2003//
+/speakup_dectlk.c/1.31/Wed Mar 30 19:02:02 2005//
+/speakup_drvcommon.c/1.50/Mon Jun 7 14:53:20 2004//
+/speakup_dtlk.c/1.17/Wed Oct 8 01:04:35 2003//
+/speakup_dtlk.h/1.3/Tue Apr 22 15:06:47 2003//
+/speakup_keyhelp.c/1.6/Wed Oct 8 15:02:11 2003//
+/speakup_keypc.c/1.5/Wed Mar 10 19:56:25 2004//
+/speakup_ltlk.c/1.29/Wed Oct 8 01:04:35 2003//
+/speakup_sftsyn.c/1.3/Mon Jun 7 14:53:20 2004//
+/speakup_spkout.c/1.21/Wed Nov 12 20:41:34 2003//
+/speakup_txprt.c/1.26/Wed Oct 8 01:04:35 2003//
+/speakupconf/1.2/Thu May 13 17:38:31 2004//
+/speakupmap.h/1.11/Thu May 13 17:38:31 2004//
+/speakupmap.map/1.27/Thu May 13 17:38:31 2004//
+/spk_con_module.h/1.1/Fri May 9 19:17:56 2003//
+/spk_priv.h/1.17/Fri Oct 10 20:08:42 2003//
+/synthlist.h/1.4/Wed Dec 10 15:29:56 2003//
+D/diff-v22////
+D/diff-v24////
+D/diff-v25////
+D/diff-v26////
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/CVS/Repository linux-2.4.30/drivers/char/speakup/CVS/Repository
--- linux-2.4.30.orig/drivers/char/speakup/CVS/Repository 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/CVS/Repository 2005-05-01 19:02:55.000000000 -0700
@@ -0,0 +1 @@
+speakup
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/CVS/Root linux-2.4.30/drivers/char/speakup/CVS/Root
--- linux-2.4.30.orig/drivers/char/speakup/CVS/Root 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/CVS/Root 2005-05-01 19:02:55.000000000 -0700
@@ -0,0 +1 @@
+:pserver:anonymous@bumpy.braille.uwo.ca:/usr/src/CVS
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/ChangeLog linux-2.4.30/drivers/char/speakup/ChangeLog
--- linux-2.4.30.orig/drivers/char/speakup/ChangeLog 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/ChangeLog 2005-04-19 09:26:21.000000000 -0700
@@ -0,0 +1,2601 @@
+2005-04-07 Thursday 15:57 gene
+
+ Added Speakup User's Guide to the Speakup tree (Gene)
+
+2005-03-30 Wednesday 14:02 gene
+
+ Changed max pitch in DecTalk Express driver from 100 to 200 (Gene)
+
+2005-03-02 Wednesday 20:23 kirk
+
+ I have been also trying to figure out why the cvs mail is not going
+ out recently so this is mostly just a test of that and updating the
+ change log. (kirk)
+
+2005-03-02 Wednesday 20:04 kirk
+
+ Well, I broke it good with the last check in and now I'm trying to fix
+ it. When I took a patch against speakup.c on checkin I forgot it
+ would check in the speakup.c as well so that won't work. Now I am
+ trying the other approach to copy a speakup.c into place on a 2.4.x
+ checkout. We'll see if it works. (kirk)
+
+2005-03-02 Wednesday 17:43 kirk
+
+ Just checking in the new speakup.c.patch diff. (kirk)
+
+2005-03-02 Wednesday 17:40 kirk
+
+ Making changes to the 2.6.11 branch of speakup. Had to change four
+ areas of vt.c and we should now have our speakup cursor updating
+ working once again. Thanks to Daniel Drake of Gentoo for supplying a
+ patch against speakup.c with all the vc_data structure and variable
+ changes. I am making a v2.6 patch against the 2.4.x speakup.c to
+ hopefully allow us to maintain both trees for a little while longer.
+ (kirk)
+
+ Also made a minor change to speakup_dectlk.c driver to accommodate
+ female voices thanks to Ken Hitt for that. (kirk)
+
+2004-12-28 Tuesday 15:11 kirk
+
+ Just checking in the latest ChangeLog. (kirk)
+
+2004-12-28 Tuesday 14:21 kirk
+
+ [no log message]
+
+2004-12-28 Tuesday 14:03 kirk
+
+ 2.6.10 changed the structure of console_callback() which did away with
+ the curcons variable for the total local context and made it local to
+ a if then clause. Also moved the function up about 40 lines in the
+ vt.c file which caused the patch to fail on checkout. (kirk)
+
+2004-10-21 Thursday 10:39 kirk
+
+ I fixed host-progs-y to hostprogs-y which may have been screwing up
+ some people when installing keymaps and the like. (kirk)
+
+2004-10-20 Wednesday 14:28 kirk
+
+ Okay, it seems that the atkbd must get registered in the serio modules
+ someplace because moving it below that in the drivers/Makefile allows
+ it to not only compile but actually boot the system as well. I also
+ fix the integer/pointer warning in line 917 of speakup.c. Now I just
+ have to get speakup to work once again. (kirk)
+
+2004-10-20 Wednesday 10:14 kirk
+
+ Checking in the first set of modifications for the 2.6.9 kernel
+ speakup tree. Modified drivers/Makefile and arch/mips/Kconfig with a
+ successful compile. I still have to run some tests to check
+ operation. (kirk)
+
+2004-08-29 Sunday 23:52 kirk
+
+ Minor fix to vt.c under 2.6.8.1 which prevented one hunk of the vt.c
+ patch from being applied.
+
+ Thanks to Garry Turkington for finding the problem with speakup not
+ compiling under the amd 64 bit processors. I hope this will take care
+ of all 64 bit architectures. Garry's solution to the problem follows.
+ (kirk)
+
+ In speakup.c you include the console_macros.h file from the drivers/char
+ directory. This is included before linux/modules.h which is fine in and
+ of itself. But in modules.h there's a
+ definition for :
+ struct attribute attr;
+
+ This is conditional, within a
+ #ifdef CONFIG_MODULES
+
+ The problem is that console_macros.h defines a macro called attr. So if
+ that definition above is hit the macro is included and everything barfs
+ horribly.
+
+ So the solution is to move the #include "../console_macros.h" in speakup.c
+ from its current position further down - I put it after the
+ #include just to be safe. Everything then compiles
+ fine and from a quick 10 minutes playing around seems to work well on my
+ Athlon64 box.
+
+ I still don't understand the conditional compilation and why this hits on
+ the x86_64 build I've been using. Note that the attr nameclash isn't
+ Speakup specific - any module including that console_macros.h file is at
+ the same risk. I need to spend a little time understanding what the
+ conditional means and what config options hit it.
+
+2004-06-07 Monday 10:53 kirk
+
+ Fixed the problem with not being able to switch between synths that
+ are built-in to the kernel. Changed the softsynth internal synth name
+ to sftsyn and applied Ammer's patch to fix the synth init string for
+ the DECTalk Express. Thanks Ameer. (kirk)
+
+2004-05-13 Thursday 16:05 yue
+
+ include #include in consolemap.c, make sure EXPORT_SYMBOL
+ is defined in this file
+
+2004-05-13 Thursday 13:38 kirk
+
+ First of all I believe I have fixed the say screen run together
+ problem but I haven't tested it myself so someone please let me know
+ if I squashed it. We were properly putting a blank space at the end
+ of the line but weren't incrementing the pointer correctly.
+
+ Next Steve Holmes submitted a new script version of speakupconf which
+ will now save speakup settings separately for different synths. Thank
+ you Steve.
+
+ And last but by no means least Ameer Armaly has submitted two patches
+ for the default speakup key map the first of which he claims makes the
+ qwerty keyboard map act more closely like the key pad keys. Secondly
+ he made some changes I requested which now place volume and pitch
+ increment and decrement on keyboard 1234 next to the rate decrement
+ and increment. We have moved the review and reading punctuation keys
+ up to speakup-f9 through speakup-f12 and move edit xnum to
+ speakup-shift-f5. Thank you very much for these changes Ameer. (kirk)
+
+2004-05-11 Tuesday 16:34 kirk
+
+ Adding the new consolemap.c patch for 2.4.x. (kirk)
+
+2004-05-11 Tuesday 16:32 kirk
+
+ Removing the selection.c patch for 2.4.x and taking the initial patch
+ for consolemap.c. (kirk)
+
+2004-05-11 Tuesday 16:29 kirk
+
+ Initial check in of the 2.4.x modifications for cut and paste. I
+ believe this is still broken so try it at your own risk. My machine
+ has major hardware problems which prevent me getting this working
+ correctly just now. I'll try again from another machine later. (kirk)
+
+2004-05-11 Tuesday 14:45 kirk
+
+ Adding the new patch file for consolemap.c which just needed to have a
+ function inverse_translate() exported. (kirk)
+
+2004-05-11 Tuesday 14:44 kirk
+
+ Checking in the first draft of my cut and paste work around for 2.6.xx
+ kernels. This will temporarily break 2.4.xx kernels until I get the
+ changes there made. We are moving to our own selection.c routines
+ which are much smaller than the set_selection in selection.c because
+ we only keep the char-by-char mode and throw away the
+ highlighting. (kirk)
+
+2004-04-14 Wednesday 16:25 kirk
+
+ Reverted the speakup Makefile change to $V that John Mylchreest
+ requested because it broke 2.4.x compiling. I need to get more
+ clarification on that because it doesn't look like it should have
+ affected his situation in anycase. (kirk)
+
+2004-04-06 Tuesday 13:26 kirk
+
+ Fixed the problem with say current word when the reading cursor was
+ past the end of characters on the line. Fixed the say window problem
+ of only reading half of the line when a say window was hit. Modified
+ the speakup Makefile by request of John Mylchreest to remove the
+ $(topdir) variable being referenced because it seems to play havock
+ with koutput which Gentoo is using to build objects outside of the
+ tree. (kirk)
+
+2004-03-11 Thursday 14:35 kirk
+
+ Checking in the new patch which is needed to make the keyboard
+ responce time changes that Gene checked in last week. I didn't
+ realize it needed a new patch so his change didn't take. (kirk)
+
+2004-03-11 Thursday 14:31 kirk
+
+ Have removed the Kconfig patches for architectures alpha and m68k in
+ kernel 2.6.4 because they are using the same Kconfig as is i386 and
+ ppc. (kirk)
+
+2004-03-10 Wednesday 14:56 kirk
+
+ This is just some clean up of the 2.6.3 kernel tree. Removed the ppc
+ architecture patch because they are now using the standard
+ drivers/Kconfig which is patched for speakup under the i386
+ architecture. Editted speakup_drvcommon.c and speakup_keypc.c to
+ clean up some warnings during compile time. (kirk)
+
+2004-03-06 Saturday 10:55 kirk
+
+ Okay a bit of administrative housekeeping and some small but useful
+ tweaks. First of all much thanks to Ameer Armaly for finding a work
+ around for 2.6.x kernels to restore keyboard responciveness during the
+ boot sequence. Thank you to a host of folks that have sent me tweaks
+ for the speakup_apolo driver which I have just gotten around to
+ installing. I cannot remember all of your names but I know Christer
+ Extrum was one contributor please let me know how you all like the new
+ changes. I have updated the Todo list after a couple of years. It was
+ surprising to find how many of the items we had actually
+ accomplished. (kirk)
+
+2004-03-06 Saturday 01:09 kirk
+
+ Okay, I have updated ChangeLog and patched drivers/char/Makefile to
+ work with 2.4.25. This is mostly a test to see if the cvs mailing
+ list is once again working or not. (kirk)
+
+2004-03-05 Friday 16:53 gene
+
+ Patched drivers/Makefile to get early keyboard response at boot. (Gene)
+
+2003-12-22 Monday 16:22 kirk
+
+ Finally got get_word() working the way I intended it to. Considerably
+ simpler code. Made a number of small modifications to various
+ drivers. We still have the kernel hang problem when trying to remove
+ modules when both speakup and the drivers are modularized. I'm not
+ sure what the hell is up with that. Sort of looks like a timing issue
+ but I can't see how or where. (kirk)
+
+2003-12-10 Wednesday 11:53 kirk
+
+ Checking in the fixes to drivers/char/Makefile for the 2.4.23 kernel.
+ Hopefully this will still allow earlier 2.4.x kernels to still patch.
+ (kirk)
+
+2003-12-10 Wednesday 10:29 kirk
+
+ Checking in the initial version of speakup_sftsyn.c a simple device
+ for software synthesizers. It will create a device /dev/softsynth
+ with major number 10 and minor 26 one higher than our /dev/synth.
+ This is a read only device and can be built as either a module or into
+ the kernel. (kirk)
+
+ Also fixed a few minor other bugs, the double 'n' on the on/off label
+ which I've fixed at least twice before. Moved the park clear up a few
+ lines in handle_cursor so that bloody reading cursor is released when
+ a cursor key is hit. Fixed the kernel oops when unloading speakup as
+ a module with modprobe on the console. (kirk)
+
+2003-11-27 Thursday 08:41 kirk
+
+ Okay, I'm checking in the probable fix for the mysterious 2.6.xx bleep
+ problem thanks to Jamie Teh. It seems that somehow two lines have
+ been being removed from keyboard.c when checking in some fix well in
+ the past. The two lines were:
+
+ if (ticks)
+ mod_timer(&kd_mksound_timer, jiffies + ticks);
+
+ Would someone running 2.6.0-test? please try this and let us know how
+ it works. (kirk)
+
+2003-11-20 Thursday 14:35 gene
+
+ Updated the config help formatting in speakup/Kconfig. (Gene)
+
+2003-11-15 Saturday 14:13 david
+
+ the synth struct was incorrectly named and it would not link
+ as a built-in
+
+2003-11-14 Friday 15:03 kirk
+
+ Fixed Config.in to indicate the three to six character string rather
+ than four to six, thanks to Mario Lang for that. Also fixed a
+ conflict in Kconfig introduced when Gene checked in his new
+ configuration help information for the 2.6.xx kernels. (kirk)
+
+2003-11-13 Thursday 16:38 gene
+
+ Wrote configuration help In Kconfig file for 2.6. (Gene)
+
+2003-11-13 Thursday 10:51 david
+
+ fixed bad timer set code also cursortrack variable for possibly more
+ types of cursoring in the future.
+
+2003-11-12 Wednesday 15:53 kirk
+
+ Made the modifications for the Apollo synth in the Configure.help for
+ the 2.4.xx kernels. (kirk)
+
+2003-11-12 Wednesday 15:41 kirk
+
+ Fixed the problem with the Speakout synth not getting detected on load
+ thanks to Steve Holmes. I over looked fixing Apolo to Apollo in
+ Config.in thanks to Bill Acker for noticing that. I still have to fix
+ it in Config.help but I'll do that shortly. Put fuzzy say_word
+ processing back in when say_word_ctl is not set thanks to John Covici
+ for that one. I also put cursor tracking on/off back in do to a cast
+ of thousands asking for it. Mostly at the instigation of Gene
+ Collins. You'll have to check to see if it actually works Gene.
+ (kirk)
+
+2003-11-11 Tuesday 09:51 david
+
+ the keynote pc driver off the machine which had the working version, oops!
+
+2003-11-06 Thursday 14:00 kirk
+
+ These are mostly maintenance fixes. I added the Keynote Gold PC
+ configuration information to Kconfig. I edited the keynote driver
+ speakup_keypc.c so it actually compiles. Someone else will have to
+ test this because I don't have a Keynote Gold PC. I removed the
+ serial_in functions which were not being used from the
+ speakup_acntsa.c and speakup_bns.c drivers. I actually finally got
+ around to fixing the Apollo driver and related other code to use
+ apollo with two 'l's like it should have been a long time ago. (kirk)
+
+2003-11-03 Monday 09:31 david
+
+ fixed a multiplier bug in common so it would do negative multipliers.
+ also added prliminary keynote pc driver.
+
+2003-11-01 Saturday 17:45 kirk
+
+ I moved the synth_alive setting to true up a number of lines. The
+ synths which depend on that variable were not receiving their
+ initialization strings because it wasn't set quite early enough. The
+ speakup_write() returns if synth_alive isn't set and so it wasn't
+ sending out the initialization strings. (kirk)
+
+ I put a ten millisecond delay back in the probing code for the
+ speakout which I removed when updating last time. It may be the
+ reason the probe is failing on the Speakouts. (kirk)
+
+2003-10-28 Tuesday 11:15 david
+
+ fixed volume command for j norton
+
+2003-10-24 Friday 14:20 david
+
+ the EXPORT-OBJ is now fixed
+
+2003-10-24 Friday 14:00 david
+
+ ok hopefully keyboard.c and char/Makefile will patch correctly
+
+2003-10-23 Thursday 10:14 david
+
+ added delay for accent-sa.
+ also fixed bug where if word ended in col-80 and next line had word in col-1
+ next-word key would skip first workd on next line.
+
+2003-10-20 Monday 09:58 kirk
+
+ Changed patch for architecture i386 from arch/i386/Kconfig to
+ drivers/Kconfig for kernels above 2.6.0-test7. I suspect this may
+ happen to many of the architecture files over time. Makes sense
+ really. (kirk)
+
+2003-10-10 Friday 16:08 kirk
+
+ I have fixed the say_next_word bug which when moving to the next line
+ misses the partial word at the beginning of line caused by a wrap
+ around on the screen. I have also created a new
+ /proc/speakup/say_word_ctl option to allow a user to set whether they
+ have the old say word behavior or returns space if between words. The
+ default is the old way although not quite because I still have to fix
+ the way it used to check words. It will eventually have more control
+ options than just 0 return word or 1 return space on space. (kirk)
+
+2003-10-08 Wednesday 13:29 kirk
+
+ Temporarily removing the MOD_INC_AND_DEC_USE_COUNT variables for now.
+ I am not sure they are particularly useful. (kirk)
+
+2003-10-08 Wednesday 11:02 kirk
+
+ Made a couple of syntax changes to speakup_key_help and
+ speakup_acntsa.c. Also modified the Dectalk PC internal
+ driver. (kirk)
+
+2003-10-07 Tuesday 21:04 kirk
+
+ Okay, I have modified all of the drivers except the Dectalk PC
+ internal. People are free to try them and let me know how they do or
+ don't work. (kirk)
+
+2003-10-07 Tuesday 16:02 kirk
+
+ This is an experimental check in of speakup which has many changes and
+ fixes and most likely broken bits, in it. It is dangerous to use this
+ currently and unless you have an Apollo, Transport or LiteTalk it just
+ plain won't work.
+
+ Now what I have done so far. Modified synth_request_region to steel
+ the tty's away from the operating system if we're being loaded as a
+ module or modules. Heavily modified the module sections of the code
+ to work properly under 2.6.x and 2.4.2? hopefully. Modified three
+ drivers so far to not pretend to be ready and available when they are
+ not. We get away with it under 2.4.x but not under 2.6.x. I don't
+ remember what else just now but a lot of changes. (kirk)
+
+ When this is all finished you will be able to load or unload with
+ either modprobe or echo whichever you prefer. It will hopefully make
+ it easier for loading modules at boot time. (kirk)
+
+2003-09-19 Friday 10:03 kirk
+
+ Just updating the ChangeLog before commensing to break things! (kirk)
+
+2003-09-19 Friday 10:01 kirk
+
+ Updating the 2.6.0 tree based on 2.6.0-test5 which modified once again
+ how the arch Kconfig's are arranged. Also including the decpc driver
+ and fixing a Kconfig bug for the Audapter under 2.6.x kernels. (kirk)
+
+2003-08-18 Monday 13:02 gene
+
+ Reverted from Jul 23 to Jul 16 LiteTalk driver because of a bad port test. (Gene)
+
+2003-08-08 Friday 14:15 david
+
+ added punc level 4 for reading of extended characters above ascii 127
+ changed the say/spell word functions so that if not on a word say space
+ instead of dragging to the nearest word, prevented me from hearing
+ collumn misallignments.
+
+2003-08-02 Saturday 20:56 david
+
+ fixed accent driver, forgot to set synth_alive (cuss cuss)
+ So it use to only talk when you pressed kill oops :-)
+
+2003-08-01 Friday 16:23 david
+
+ fixed flush and some hanging issues. Also better board detection.
+
+2003-07-31 Thursday 11:27 david
+
+ the dec_pc beta driver. You will also need dec_pc.tgz to init the
+ dec_pc board. The source for dtload is here.
+ the dec_pc.tgz contains dtload, a Readme and the dec_pc software.
+
+2003-07-30 Wednesday 14:50 david
+
+ hmmm fixed help? darn thing didn't even compile. oops!!
+
+2003-07-30 Wednesday 14:45 david
+
+ fixed help so it doesn't hang.
+ also removed the synthlist for modules. this means that new synth
+ can be loaded as modules without re-compiling speakup.
+ It now just looks for a module speakup_(name) with a valid check value
+ in the synth header.
+
+2003-07-28 Monday 18:48 david
+
+ fixed dec to be more responsive after flush.
+ instead of waiting 100ms, wiat for receive ctl-a
+ from express, signals done flush.
+
+2003-07-23 Wednesday 14:26 david
+
+ fixed bug in ltlk where if no synth kernel hung
+ waiting for input. Also made sure other
+ synths could not hang on startup.
+
+2003-07-22 Tuesday 17:17 kirk
+
+ Checking in the 2.6.x changes to Makefile to support Davids new
+ makemapdata.c and makemapdata.h files. (kirk)
+
+2003-07-22 Tuesday 15:15 kirk
+
+ Okay, I lied earlier as usual. This fix works and I know it! (kirk)
+
+2003-07-22 Tuesday 10:51 kirk
+
+ Hopefully fixed once and for all the copy and paste call to
+ set_selection() for 2.4.x and 2.6.x kernels. Had to revert to using a
+ silly #if (linux_version_code) macro for a function argument which
+ gets bumped in 2.4.x kernels but is used as is in the 2.6.x
+ tree. (kirk)
+
+2003-07-21 Monday 08:26 david
+
+ fixed keyhelp so speakup key is not announced twice as in
+ keypad 0, speakup keypad 0
+ the speakup mapping is required so speakup key is processed
+ when speakup bit is set.
+ also genmap now detects two functions mapped to same key combination.
+
+2003-07-18 Friday 10:08 david
+
+ makemapdata.c creates mapdata.h which is used to
+ build genmap
+
+2003-07-18 Friday 10:07 david
+
+ split genmap into two programs so includes do not
+ have to be available.
+ makemapdata constructs the tables which genmap uses
+ mapdata.h is compiled into genmap so it can be stand-alone
+
+2003-07-17 Thursday 16:24 david
+
+ enlarged keytable was causing misread of say attributes,
+ also version #if on inc_mod_use_count was wrong
+
+2003-07-17 Thursday 09:46 david
+
+ a script to load/save speakup configurations. run as speakupconf load/save
+ as root saves in /etc/speakup, as non-root saves in $HOME/.speakup
+
+2003-07-17 Thursday 08:09 kirk
+
+ Checked in Kconfig-shared.patch which I forgot to check in yesterday.
+ Removed arch/mips/Kconfig which has been replaced with Kconfig-shared.
+ Fixed copy-and-paste which wasn't working in the 2.5.x and 2.6.x
+ kernel branches. (kirk)
+
+2003-07-16 Wednesday 20:50 kirk
+
+ Rechecking in the 2.4.21 changes to speakup. I have also changed the
+ default punctuation delimeters to none and moved reading punc default
+ back to some. (kirk)
+
+2003-07-16 Wednesday 17:17 david
+
+ long awaited keymap proc entry. use genmap to create the map.
+ as in genmap personal.map >/proc/speakup/keymap
+ or genmap personal.map >key_save
+ then at startup cat key_save >/proc/speakup/keymap
+
+2003-07-16 Wednesday 13:51 kirk
+
+ Adding in initial support for Linux version 2.6.x. (kirk)
+
+2003-07-16 Wednesday 09:07 david
+
+ added a check value to synth structure to validate on init.
+ added synth flags for synth speciffic processing.
+ added synth speciffic code for dectalk to insert a space between
+ puncs and alphas to stop dec from spelling urls etc when punc is not
+ spoken.
+
+2003-07-15 Tuesday 16:29 david
+
+ added extended numeric processing to do $4.00 correctly.
+ no exnum chars are currently on, edit them is bound to speakup f9
+
+2003-07-11 Friday 08:43 david
+
+ added a type 2 key echo for always speaking key even if system does not
+ echo, useful for validating visa numbers etc. in forms.
+
+2003-07-08 Tuesday 08:51 david
+
+ fixed keyboard so works in raw mode and also prev hang bug fix from 2.4
+
+2003-07-08 Tuesday 08:35 david
+
+ fixed keyboard hang, caused by shift_state pointing at null map
+ and I passed KT_SPKUP instead of KT_SHIFT which caused shift_state to not be computed
+
+2003-06-26 Thursday 14:32 kirk
+
+ Modified Makefile to handle compiling of genmap and the speakupmap.h
+ dependency correctly once again in the 2.4.x tree. Also updated
+ ChangeLog because it hasn't been done for a while. (kirk)
+
+2003-06-26 Thursday 13:43 kirk
+
+ These are mostly changes to try to get the modularization working with
+ the 2.5.x kernel tree. They may have had an unstablizing affect on
+ the 2.4.x tree so beware.
+
+ Changes include modifying genmap.c to hopefully work in both the 2.4.x
+ and 2.5.x trees. This has not yet been tested on the 2.4.x tree
+ although it will be soon. The reason for it's changes are because the
+ 2.4.x kernels 'cd' into each directory and then run Makefile. In the
+ 2.5.x kernels all compiling is run from the tree root.
+
+ Modified Makefile to also use the 2.5.x Makefile changes and reordered
+ the synth lines alphabetically.
+
+ Modified a couple of drivers and the module include files to
+ incorporate Tom Stivers module licensing strings which will hopefully
+ stop the tainted kernel messages on module loading.
+
+ Partially incorporated the modularization code into keyboard.c, vt.c
+ and I'm not sure what other patches. This is not complete. Speakup
+ works if built-in but I am getting all sorts of kernel oopses when
+ loading modules. There's something I don't have quite right just
+ yet. (kirk)
+
+2003-06-19 Thursday 09:41 kirk
+
+ qUpdated files for 2.4.21 which will require using it. Files changed are arch/mips/config-share.in, drivers/char/Makefile, drivers/char/keyboard.c and removed the miscdevices.h patch which doesn't appear to be necessary any longer. (kirk)
+
+2003-06-18 Wednesday 16:29 david
+
+ added module include
+
+2003-06-17 Tuesday 16:37 david
+
+ fixes to makefiles in speakup and char so it actually builds :-)
+
+2003-06-16 Monday 16:55 david
+
+ added hopefully all the exported symbols for
+ modular speakup
+
+2003-06-16 Monday 16:40 david
+
+ added the patch for vt.c to export kd_mksound for spk module
+
+2003-06-16 Monday 16:38 david
+
+ modularized speakup now works on 2.4.
+ loading any synth with modprobe should load spk.o and start talking
+
+2003-06-13 Friday 12:43 david
+
+ added key exploring to help so they ident when pressed.
+ also took off the unsigned from the int currcons as
+ fg_console is an int so the called funcs ought to take an int
+
+2003-06-13 Friday 08:39 kirk
+
+ A couple of small fixes I keep making and forgetting to check in. Fixed
+ CONFIG_SPEAKUP_APOLO in the Kconfig file. Placed a space after cap in
+ the caps_start string for the apolo. I can't remember what else
+ off-hand. (kirk)
+
+2003-06-12 Thursday 15:48 kirk
+
+ A simple typo fix in ld_help although I like having hell in the middle
+ of help. (kirk)
+
+2003-06-12 Thursday 14:39 david
+
+ keyinfo.h is #defines and enum formerly in include/linux/speakup.h
+ these are not kernel specific and might as well be here!
+
+2003-06-12 Thursday 14:37 david
+
+ moved defines to keyinfo.h and 2.5 task scheduling stuff
+
+2003-06-12 Thursday 14:30 david
+
+ moved defines for keys to keyinfo.h in speakup directory.
+ version 2.5 scheduling also
+
+2003-06-12 Thursday 12:07 david
+
+ added speakup_keyhelp.c
+ key help module
+
+2003-06-12 Thursday 12:05 david
+
+ added a rather nifty key help module currently speakup-f1
+ must do make modules and make modules_install to install it.
+
+2003-05-30 Friday 13:18 david
+
+ changed special handlers to return int so -1 is error, 0 let system
+ do key, 1 we used the key.
+ also changed read_punc default to 3.
+ also goto can end with another goto press or enter,
+ I prefer enter to do the goto.
+
+2003-05-30 Friday 09:52 david
+
+ moved the re-enable synth to speech_kill as this is the total speech off
+ also fixed a bug where if speakup_off it was reading when cursor keys pressed
+
+2003-05-27 Tuesday 21:19 david
+
+ forgot to add speech_kill to speakupmap.map
+
+2003-05-27 Tuesday 11:20 kirk
+
+ I believe I've fixed the 2.5.x speech output going away. It was
+ is_cursor never getting set back to zero because of an inverted test
+ in cursor_stop_timer(). Took one hell of a lot of work to hunt it
+ down though. I also fixed another bug which was passing a u_char in a
+ function header when the calling argument was actually an int, talk
+ about interesting results. (kirk)
+
+2003-05-23 Friday 11:04 david
+
+ fixed a couple of missing parens in speakup.h and took out double setting
+ of $V in Makefile. It stays set from first test.
+
+2003-05-22 Thursday 19:35 kirk
+
+ Okay, doesn't it figure that I couldn't get it right the first time
+ anytime. Moved the #if linux_version_code test block for the
+ #includes down to get around the voodoo compiler errors. Also had to
+ remove a line I missed having in a version check #ifdef in
+ speakup_drvcommon.c. (kirk)
+
+2003-05-22 Thursday 17:21 kirk
+
+ This is the first preliminary check in of the new #if revisions for
+ the 2.4.x and 2.5.x kernels. The files affected are Makefile,
+ speakup.c, speakup_drvcommon.c and spk_priv.h. I have also removed
+ the speakupmap section of Kconfig and the char/Makefile related to the
+ speakupmap code. Hopefully this won't break anything but world peace
+ is probably just around the corner as well. (kirk)
+
+2003-05-21 Wednesday 16:40 david
+
+ fixed keyboard.h and speakup.h for b2.5 kernels
+
+2003-05-21 Wednesday 16:21 david
+
+ #ifdef versioned Kirk's changed for 2.5
+ added a version of Terry Cudney's keymap so laptop users will be happy
+ allowed multiple defs of the speakup key currently
+ caps_lock, left_meta and numpad_insert
+
+2003-05-16 Friday 18:20 kirk
+
+ Okay, I've figured out what's wrong now I have to figure out how to
+ fix it. Here is a temporary fix though I think. I'm placing the
+ original 2.4.20 spk_priv.h back in place. (kirk)
+
+2003-05-16 Friday 18:07 kirk
+
+ To weird, this is 2.4.x being fixed yet again. (kirk)
+
+2003-05-16 Friday 18:04 kirk
+
+ Okay, trying this once again. this is the 2.5.x tree. (kirk)
+
+2003-05-16 Friday 17:44 kirk
+
+ This is just getting to weird. This is another check in of Makefile,
+ speakup.c and speakup_drvcommon.c for the 2.4.20 tree. These seem to
+ keep getting overwritten when I checkin the 2.5.x tree. (kirk)
+
+2003-05-16 Friday 16:53 kirk
+
+ cvs add'ing the new spk_priv.h file for 2.5.x. (kirk)
+
+2003-05-16 Friday 16:51 kirk
+
+ Forgot to checkin a slightly modified spk_priv.h earlier. It seems
+ the timer_list structure has changed somewhat in 2.5.x kernels. The
+ member structure list has changed names to entry. (kirk)
+
+2003-05-16 Friday 15:40 kirk
+
+ Okay, checking the proper 2.4.x Makefile, speakup.c and
+ speakup_drvcommon.c files hopefully. (kirk)
+
+2003-05-16 Friday 14:57 yue
+
+ Still trying to clean up all of my screw-ups from the original checkin
+ of the 2.5.x material. (kirk)
+
+2003-05-16 Friday 14:04 yue
+
+ Forgot to add the new patch files in diff-v25. Time to take a break I
+ think. (kirk)
+
+2003-05-16 Friday 13:20 yue
+
+ Just removing the config.help which isn't needed under v2.5.x any
+ longer. (kirk)
+
+2003-05-16 Friday 12:43 yue
+
+ This is the first checkin of the new 2.5.x speakup code. We have
+ created patches against the 2.4.x versions of speakup Makefile,
+ speakup.c speakup_drvcommon.c, as well as adding Kconfig which is the
+ new 2.5.x configuration system. (kirk really Yue)
+
+2003-05-13 Tuesday 13:05 david
+
+ took out the console announce, added stuff for the soon coming help handler
+ add speakup.o to the objects that export symbols in Makefile
+
+2003-05-13 Tuesday 10:35 david
+
+ moved the shift check in speakup_key so the spk key can be one
+ of the shift/ctrl/alts if someone wants that.
+ added announcement when switching consoles.
+ added flag to stop multiple misc_register from being done,
+ crashed kernel if called more than once.
+
+2003-05-13 Tuesday 09:51 kirk
+
+ Okay, I fucked things up big time when I cleaned up the Makefile last
+ night. I kinda cleaned up to much. I think it's all better
+ now. (kirk)
+
+2003-05-12 Monday 21:48 kirk
+
+ Fixed a couple of typos in checkout. BTW, everyone needs a new
+ checkout script. (kirk)
+
+2003-05-12 Monday 21:35 kirk
+
+ Turning on the --silent flag in patch. (kirk)
+
+2003-05-12 Monday 21:28 kirk
+
+ Adding in the new patch files in diff-v24. (kirk)
+
+2003-05-12 Monday 21:05 kirk
+
+ Cleaning up the speakup Makefile and about to destroy checkin and
+ checkout. Hopefully not for long. I, if successful, am modifying the
+ files in diff-vxx to be relative to the root dir which is the top
+ directory of the kernel tree. Checkout will first look for a command
+ line argument pointing to the kernel tree. If none is given it will
+ check for the existence of a kernel and Documentation directory in the
+ current directory and if found will determine that it is in the root
+ directory and set ROOTDIR accordingly. if not we will fall back to
+ assuming the tree is in /usr/src/linux. (kirk)
+
+2003-05-12 Monday 19:36 david
+
+ fixed edit punc/delim/repeats to allow shift.
+ Also allow alpha in delim/repeats
+
+2003-05-12 Monday 17:20 david
+
+ added the shift states to thespeakup internam key_buf
+ required for help, coming soon.
+ also extened key_max to 128 so windows keys could be used.
+
+2003-05-12 Monday 11:38 david
+
+ added more info to the keymap, also finished spk key now defineable.
+ added it to map as KEY_KP0. genmap just puts out numbers to speakupmap.h now.
+ working towards /proc/speakup/keymap loading.
+ using genmap to generate the proc stuff as well as the built-in map.
+ added error checking to set_key_info as well as pass in the buffer so we could
+ have console speciffic keymaps if we want too at a later time.
+
+2003-05-10 Saturday 18:36 david
+
+ in the second call to speakup_key keysym was uninitialized and could have
+ inadvertantly called one of the handlers with bad data.
+
+2003-05-10 Saturday 14:45 david
+
+ I put the fix in for keyboard.c so if no map speakup_key will
+ still be called. also the = in genmap.c
+
+2003-05-10 Saturday 13:33 kirk
+
+ Okay, added an equal sign to the output loop condition in genmap.c
+ which was causing the speakupmap.h to be cut-off one entry to soon.
+ Removed a 'l' from the word coll in say_position() which was causing
+ some synths the Audapter in particular to mispronounce it. Removed
+ symbols.h because it appears we do not need it any longer. (kirk)
+
+2003-05-10 Saturday 00:00 david
+
+ fixed a tolower bug in genmap.c as you can't downshift a quoted string.
+ also some module unloading code in speakup.c to restore the key_handlers.
+ Still more module stuff to be done.
+
+2003-05-09 Friday 15:17 david
+
+ spk_con_module.h is include by ../console.c when speakup
+ is configured as a module.
+
+2003-05-09 Friday 15:16 david
+
+ the new mappings generated from speakupmap.map
+
+2003-05-09 Friday 15:15 david
+
+ now speakupmap.h is included in speakup to provide mappings
+
+2003-05-09 Friday 15:13 david
+
+ changed genmap and speakupmap.map to be the new style of keymaps
+ key names are now from include/linux/input.h
+ no special default keymap anymore, speakup mappings are done in speakup itself.
+ many changes in speakup.c also for local keymapping and more moving towards being able to be a
+ module. the speakup key numpad 0 is currently hardcoded but may change soon.
+ the modifiers currently supported are shift, ctrl, alt, altgr, spk and double
+ the double press keys can now be anything which has a single press map.
+ Warning: this is relatively untested code and may not be extremely stable
+ although it has not crashed for me.
+
+2003-05-07 Wednesday 13:14 david
+
+ more moving to a module version. fixed init so is module callable by moving
+ the code into speakup_open accept the initial alloc then module can alloc first console
+ and call open. Also changed KT_SPKUP to 14 so if null synth they will
+ be ignored.
+
+2003-05-05 Monday 09:56 kirk
+
+ Starting the trashing of 2.2.x kernel support. We are moving toward
+ 2.4.x and 2.5.x. (kirk)
+
+2003-05-05 Monday 09:46 david
+
+ start of modularizing speakup.
+ also fixed char/Makefile so in no speakup default keymap the kernel still
+ compiles. changed parms to speakup_key for mapping of speakup keys in speakup
+ itself to support 2.5 kernels.
+
+2003-05-03 Saturday 19:29 kirk
+
+ Fixed bug in say_next_word which caused skipping over the entire next
+ word if you were on the space just before the word. (kirk)
+
+2003-05-02 Friday 20:10 kirk
+
+ Moved spk_register_dev() into proc_init() and removed the main.c patch
+ to do the registration. That should fix the devfs hang problem. Also
+ took the \r out of the synth_interrogate() function in
+ speakup_ltlk.c. (kirk)
+
+2003-05-02 Friday 18:43 kirk
+
+ Fixed the problem with writing back to a string file in /proc/speakup
+ by surrounding the string in quotes and prepending a \x before
+ unprintable characters. I think it's a bit of a kludge so if anyone
+ sees a more elligant solution to the problem please invoke
+ same. (kirk)
+
+2003-05-02 Friday 12:01 kirk
+
+ Now that I've added the ChangeLog, maybe just maybe I should make sure
+ it's up to date. (kirk)
+
+2003-05-02 Friday 11:56 kirk
+
+ Adding the correct tome offset from Steve Homes for the Speak Out
+ driver. Also adding the ChangeLog which I thought was already part of
+ it. Go figure. (kirk)
+
+2003-05-01 Thursday 10:52 david
+
+ fixed a bug in phonetic char and also have it prefix digits with number.
+
+2003-04-30 Wednesday 22:33 david
+
+ try to get the cvs to eat my tab mod in console.c so tabbed
+ columns read properly
+
+2003-04-30 Wednesday 22:27 david
+
+ fixed a bug where punctuation allowed to synth when punct is off said
+ nothing but could announce repeats.
+ also suppress multiples so repeats don't give long pauses.
+ added a write of a space in the console for a tab so tabbed columns
+ read properly not run together.
+
+2003-04-30 Wednesday 19:14 kirk
+
+ I've put a test in synth_interrogate() to break from the rom version
+ loop if i gets larger than 48. I'm trying to find out what could
+ cause some ltlks to hang the system. (kirk)
+
+2003-04-30 Wednesday 17:02 kirk
+
+ Just checking in the latest cvs logs. We have been remiss in keeping
+ on top of it.. (kirk)
+
+2003-04-30 Wednesday 14:29 david
+
+ forgot to append a space in speak_char, kind of sounds funny!
+
+2003-04-30 Wednesday 14:21 david
+
+ fixed one line windows, forgot to set bottom.
+ also some optimization in synth_start and spkup_write.
+ took the ex_num handling for now as it was buggy
+
+2003-04-30 Wednesday 12:35 kirk
+
+ Changed speakup_ltlk.c to support the newer chip set needing a \r the
+ interrogate command. This now works with the TrippleTalk serial ports
+ on the usb synths as well. (Kirk)
+
+2003-04-29 Tuesday 08:43 kirk
+
+ Fix synth detection string in speakup_audptr.c from "0x05[q" to
+ "\x05[q". (kirk)
+
+2003-04-28 Monday 12:24 david
+
+ fixed chars_write_proc a rather silly bug, well two of them,
+ a bad optimization, and cnt was not zero when going back to get_more
+
+2003-04-25 Friday 15:35 david
+
+ fixed get_word so if on a space before a word, advances one char.
+ Also an odd bug insay_word where multiple words of one char the same would get counted
+ as repeats, append a space to the word to stop this behaviour.
+
+2003-04-24 Thursday 15:32 david
+
+ speakup.h in include/linux needs updating
+
+2003-04-24 Thursday 13:40 david
+
+ fixed the rate and voice keys in the map I got caught by cut and paste
+
+2003-04-24 Thursday 13:28 kirk
+
+ Fixed lock_status[] array to remove the second 'n' in on. Rewrote the
+ probe routine for the Transport driver to get a more reliable probing
+ on module loads. (kirk)
+
+2003-04-24 Thursday 12:09 david
+
+ added reading level punctuation on speakup 3-4 top row numbers, moved rate to speakup 5-6
+ and voice change on speakup 7-8 top row numbers
+ also took out the __init declarations on places that may be called
+ more than once such as synth init/probe code
+
+2003-04-23 Wednesday 21:03 kirk
+
+ A small modification to the top_edge() function to try to correct the
+ move to top of screen problem. (kirk)
+
+2003-04-23 Wednesday 20:14 david
+
+ fixed a bug where numlock also made cursor keys numeric
+ was passing scancode to speakup_key not the translated keycode.
+ also makes numeric + and / work too!
+
+2003-04-23 Wednesday 13:53 david
+
+ fix to mod_code that should fix the null pointer problem
+ If a module was installed wile another synth was active the wrong pointer
+ was updated
+
+2003-04-22 Tuesday 22:13 david
+
+ fixed prev and next word so they stop on lines containing only delimiters
+ hopefully right this time.
+
+2003-04-22 Tuesday 11:16 david
+
+ turn off temp park on type KT_SPEC keys such as enter, locks etc.
+
+2003-04-22 Tuesday 11:06 david
+
+ added window which can be set, cleared, silenced or read,
+ currently bound to speakup with f1-f4 respectively
+ added keyboard editing of punc/delimiter/repeat chars.
+ currently mapped as follows:
+ speakup f5, edit some. speakup f6, edit most.
+ speakup f7, edit delimiters. speakup f8, edit repeats.
+ also touched initial rates in dectlk, decext, dtlk and ltlk synth files.
+
+2003-04-21 Monday 14:03 kirk
+
+ I've fixed a character misplacement in speakup_decext.c in serprobe().
+ I hope this fixes Genes problem. (kirk)
+
+2003-04-21 Monday 12:35 kirk
+
+ Just changing grave to accent again in the characters array. This is
+ really a test to see how cvs logging to a mailing list works. (kirk)
+
+2003-04-21 Monday 12:28 kirk
+
+ Just changing grave to accent again in the characters array. This is
+ really a test to see how cvs logging to a mailing list works. (kirk)
+
+2003-04-18 Friday 15:44 david
+
+ fixed open brace function begins, added numlock on gives numbers, fixed bugs in next/prev word
+ bleeps for attrib and bleep now do: 0 nothing, 1 beep, 2 announce, 3 both
+ changed speakup_reset to speakup_key, better name.
+ changed temperary park so it goes on only you move the review cursor.
+ i.e. prev/next char, word, line, edges, first/last char.
+
+2003-04-16 Wednesday 14:04 kirk
+
+ I've changed speakupmap.map keycode 14 back to Delete from Backspace.
+ Thank you David for finding that. I've also changed the grave accent
+ key back to accent from grave which I'm afraid blends into strings to
+ well. (kirk)
+
+2003-04-14 Monday 16:32 kirk
+
+ I forgot to #include "cvsversion.h" in the last check in. This also
+ has David's new speakup_reset() function. I haven't tested it
+ yet. (kirk)
+
+2003-04-14 Monday 14:37 kirk
+
+ Okay, this is the first check in of Dave Borowski's major revisions to
+ speakup. It includes automagic cursor tracking, synth driver
+ modularization a whole bunch of rewritten code and a whack of new bugs
+ as well. This is very unstable currently, use at your own
+ risk. (kirk)
+
+2003-03-18 Tuesday 16:11 kirk
+
+ Put a key definition into speakupmap.map for ShiftR keycode 55 which I
+ forgot to include when I was modifying how the map worked. This
+ restores the speakup go to column and row with the insert cursoring
+ mode. (kirk)
+
+2002-12-13 Friday 20:15 kirk
+
+ Okay, to fix the problem when there is no speakup map loaded and
+ numlock is turned on, I've renamed all altgr modifiers to Shiftr which
+ is not used. I also changed the key check in speakup_control to the
+ shiftr code. As far as I can tell this fixes the problem. I had to
+ define the keymaps = line to include the 32 weight for the shiftr
+ key. (kirk)
+
+2002-08-15 Thursday 20:00 gene
+
+ Fix multiple quick_quiet definition for 2.2.x (Gene)
+
+2002-08-07 Wednesday 14:10 kirk
+
+ Stupid me forgot to remove a plus sign. Sorry about that folks. (kirk)
+
+2002-08-07 Wednesday 12:27 kirk
+
+ Just fixing the miscdev.h /dev/synth entry which was rejected because a new line added to the file. (kirk)
+
+2002-07-05 Friday 21:52 gene
+
+ fixed 2.2.x numlock 0 bug (Gene)
+
+2002-07-05 Friday 14:01 kirk
+
+ Checking numlock keyboard enter '0' fix for 2.4.18 in keyboard.c
+ (kirk)
+
+2002-07-05 Friday 13:51 kirk
+
+ Added in David Borowski's patches with takes speakupmap.map with text
+ strings representing the functions and converts them to their hex
+ string values usable by loadkeys. This patch affects Makefile in
+ speakup, speakupmap.map and a new file genmap.c. (kirk)
+
+ Fixed the bug which placed a '0' on the command line when hitting
+ 'enter' with numlock mode on. Speakup_control() was being called from
+ do_spec() with a bad value. (kirk)
+
+2002-06-14 Friday 15:55 gene
+
+ Edited drivers/char/Makefile to elimate multiple keymap definition problem (Gene)
+
+2002-06-13 Thursday 17:43 kirk
+
+ Removed the speakup/Makefile patch I added last week because I found a
+ cleaner way to handle the make build variable changes. (kirk)
+
+2002-06-13 Thursday 10:21 jim
+
+ /usr/src/linux/drivers/char/Makefile:
+ truncated line to read:
+ KEYMAP =
+ (jim)
+
+2002-06-11 Tuesday 14:24 kirk
+
+ Once again fixing changes to drivers/char/Makefile and speakup/Makefile. I think this will work better and more cleanly now. (kirk)
+
+2002-06-10 Monday 13:58 kirk
+
+ Trying to fix speakup/Makefile so it is the original once again. (kirk)
+
+2002-06-04 Tuesday 15:00 kirk
+
+ Adding the new speakup/Makefile.patch to the cvs repository. (kirk)
+
+2002-06-04 Tuesday 14:57 kirk
+
+ Modified drivers/charMakefile to fix rejected speakup patch. I also
+ had to modify speakup/Makefile to use export-objs instead of O_OBJECTS
+ which was causing multiple symbol definitions from
+ speakupmap.o. (kirk)
+
+2002-04-30 Tuesday 13:25 kirk
+
+ Updating speakup to 2.5.11 and fixing ppc architecture patch. Also
+ included the move to end of line function from 2.4.x and 2.2.x trees.
+ (kirk)
+
+2002-04-11 Thursday 09:31 gene
+
+ Checked in nr_speakup changes for 2.2.x to fix load keys problem (Gene)
+
+2002-04-10 Wednesday 14:30 kirk
+
+ Changed NR_SPKUP to 0x2a in keyboard.h which was causing an unable to
+ bind error when leading speakupmap.map with loadkeys in 2.4.x
+ kernels with the new control-kp1 key. (kirk)
+ ----------------------------------------------------------------------
+ speakupmap.map CVS:
+ diff-v24/^usr^src^linux^Documentation^Configure.help.patch CVS:
+ diff-v24/^usr^src^linux^Documentation^speakup^DefaultKeyAssignments.copy
+ diff-v24/^usr^src^linux^Documentation^speakup^keymap-tutorial.copy
+ diff-v24/^usr^src^linux^arch^alpha^config.in.patch CVS:
+ diff-v24/^usr^src^linux^arch^arm^config.in.patch CVS:
+ diff-v24/^usr^src^linux^arch^i386^config.in.patch CVS:
+ diff-v24/^usr^src^linux^arch^m68k^config.in.patch CVS:
+ diff-v24/^usr^src^linux^arch^mips^config.in.patch CVS:
+ diff-v24/^usr^src^linux^arch^ppc^config.in.patch CVS:
+ diff-v24/^usr^src^linux^arch^sparc64^config.in.patch CVS:
+ diff-v24/^usr^src^linux^arch^sparc^config.in.patch CVS:
+ diff-v24/^usr^src^linux^drivers^char^Makefile.patch CVS:
+ diff-v24/^usr^src^linux^drivers^char^console.c.patch CVS:
+ diff-v24/^usr^src^linux^drivers^char^keyboard.c.patch CVS:
+ diff-v24/^usr^src^linux^drivers^char^selection.c.patch CVS:
+ diff-v24/^usr^src^linux^fs^proc^root.c.patch CVS:
+ diff-v24/^usr^src^linux^include^linux^keyboard.h.patch CVS:
+ diff-v24/^usr^src^linux^include^linux^miscdevice.h.patch CVS:
+ diff-v24/^usr^src^linux^include^linux^proc_fs.h.patch CVS:
+ diff-v24/^usr^src^linux^include^linux^speakup.h.copy CVS:
+ diff-v24/^usr^src^linux^init^main.c.patch CVS:
+ ----------------------------------------------------------------------
+
+2002-04-04 Thursday 11:33 gene
+
+ Updated DefaultKeyAssignments for 2.2.x kernels - Gene Collins
+
+2002-04-02 Tuesday 12:27 kirk
+
+ Editted defaultKeyAssignments to reflect the new key combination
+ control keypad 1 for move to last character on line. (kirk)
+
+2002-04-02 Tuesday 10:45 kirk
+
+ Added new function end_of_line() to move the reading cursor to the
+ last character on the current line. (kirk)
+
+2002-03-27 Wednesday 10:44 kirk
+
+ Have modified speakup_shut_off() or whatever it's called to not sync
+ the reading cursor to the actual cursor when temporarily shutting off
+ speakup. It was a request from Geoff Shang and others. (kirk)
+
+ I cleaned up the Todo file to remove recent changes in features.
+ (kirk)
+
+2002-03-03 Sunday 22:32 kirk
+
+ Checking in changes for 2.4.18 which stop the two patch hunks from
+ failing on keyboard.c. As far as I can tell they are format changes
+ which don't have anything to do with speakup directly. (kirk)
+
+2002-02-19 Tuesday 11:12 kirk
+
+ Checking in modifications to linux/init/main.c for 2.5.5pre1. I still
+ need to find a better place for that patch; it is very out of place
+ there now. (kirk)
+
+2002-02-05 Tuesday 22:31 gene
+
+
+ Updated 2.2 tree with the new numlock handling code. (Gene)
+
+2002-02-05 Tuesday 20:22 kirk
+
+ Removed some duplicate #include lines in speakup.c (kirk)
+
+2002-02-05 Tuesday 11:15 kirk
+
+ Made the changes to move numlock checking code out of keyboard.c into
+ speakup_control() in the 2.4.x tree. (kirk)
+
+2002-02-05 Tuesday 11:01 kirk
+
+ Moved the numlock checking code into speakup_control() where it
+ belongs and out of keyboard.c in the 2.5.x tree. (kirk)
+
+2002-02-04 Monday 15:18 kirk
+
+ Just adding the new Config.help copy file into cvs. (kirk)
+
+2002-02-04 Monday 15:16 kirk
+
+ Modified speakup to work with linux 2.5.3 which intailed changing the
+ patch for linux/init/main.c and creating Config.help for the speakup
+ directory instead of the linuxDocumentation/Configure.help. The help
+ for each subdirectory is now maintained within that directory.
+
+ Also hand patched keyboard.c to be compatible with the numlock changes
+ to the 2.4.x tree. Just dropped speakup.h from that distribution in
+ place it hasn't changed much yet. (Kirk)
+
+2002-01-25 Friday 10:48 gene
+
+
+ Updated 2.2 tree to work with new keypad numlock layout (Gene)
+
+2002-01-20 Sunday 17:46 kirk
+
+ I've changed the #define's for TOP_EDGE, LEFT_EDGE and RIGHT_EDGE from
+ 0x4[def] which are out of range for nr speakup keys to values in
+ range. I hope this fixes the problem without breaking something
+ else. (kirk)
+
+2002-01-20 Sunday 16:13 kirk
+
+ Removed a few double tab chars before altgr keycodes 71 and 73.
+ Hopefully this will correct the key binding problem when loading
+ speakupmap.map with loadkeys. (kirk)
+
+2002-01-11 Friday 14:43 gene
+
+
+ Checked in numlock feature for the 2.2 tree. (Gene)
+
+2002-01-11 Friday 11:11 kirk
+
+ Modified the Apollo driver to allow chars above 0x80 through as an
+ experiment to see if foreign languages using those upper characters
+ will work correctly. (kirk)
+
+2002-01-10 Thursday 16:37 kirk
+
+ Woops! Some how we lost cut and paste in our upgrades to numlock
+ control. Wouldn't that just make everyone happy! (kirk)
+
+2002-01-10 Thursday 15:41 kirk
+
+ Checking in speakup.h again for the 2.4.x tree, it didn't take. (Kirk)
+
+2002-01-09 Wednesday 17:54 kirk
+
+ For some reason speakup.h didn't get updated this morning. Should be
+ okay now. (kirk)
+
+2002-01-09 Wednesday 09:58 kirk
+
+ Woops, the correct keyboard.c didn't get checked in. (kirk)
+
+2002-01-09 Wednesday 08:16 kirk
+
+ Added numlock feature to allow the keypad to act as a normal number
+ pad when the numlock is on. (Yue)
+
+2001-12-21 Friday 10:49 kirk
+
+ Just checking in for kernel 2.5.1 to stay sync'd with the code. (kirk)
+
+2001-12-07 Friday 11:55 kirk
+
+ Updating speakup for kernel 2.5.1pre6. Seems to be something weird
+ going on. I think I'll have to edit some of the patches by
+ hand. (kirk)
+
+2001-12-05 Wednesday 14:33 kirk
+
+ Cleaned up speakup.h and speakup.c which were giving warnings during
+ compile and moved stuff around to compile with 2.5.1pre5. (kirk)
+
+2001-11-23 Friday 14:44 kirk
+
+ Hmmm, something went wrong with the first attempt at adding the
+ diff-v25 directory tree, so we're trying again. (kirk)
+
+2001-11-23 Friday 09:45 kirk
+
+ Checking in changes to speakup.c to have the system bleep when a shift key is hit while the caps lock is on. (Yue)
+
+2001-11-23 Friday 09:41 kirk
+
+ Opening a new branch of speakup for the new version 2.5.0 of
+ linux. (Kirk)
+
+2001-11-13 Tuesday 13:36 jim
+
+ speakup.c:
+ Fixed the mixed case pitching bug.
+ The speech rates for upper and lower case chars when spelling a word
+ should now be the same.
+ (Jim Danley)
+
+2001-10-26 Friday 21:38 jim
+
+ Fixed /usr/src/linux/drivers/char/Makefile patch to work with kernels
+ 2.4.12 and 2.4.13
+ (Jim)
+
+2001-10-18 Thursday 08:53 jim
+
+ Removed the cut and paste bug description from the BUGS file. (Jim)
+
+2001-10-14 Sunday 15:28 jim
+
+ Part two of the selection.c patch for 2.2. This process sure was fun! (Jim)
+
+2001-10-14 Sunday 15:21 jim
+
+ Just adding the new patch file for selection.c in the diff-v22 patch
+ directory. (Jim)
+
+2001-10-14 Sunday 14:45 kirk
+
+ Just adding the new patch file for selection.c in the diff-v24 patch
+ directory. (kirk)
+
+2001-10-14 Sunday 14:42 kirk
+
+ Changed selection.c to test if call is coming from userspace or kernel
+ space and using GFP_ATOMIC if it is being called from kernel-space.
+ This works around kmalloc not returning and hanging the system in
+ set_selection for the block and paste function of speakup. (Jim)
+
+2001-10-12 Friday 12:10 jim
+
+ speakup.c:
+ Removed statements which were appending 0x00 to buffers to be spoken
+ from functions say_curr_line and say_line_from_to.
+
+ Inspected and modified all spkup_write() calls to be consistent,
+ that is, end in \n and count is correct.
+ (Jim Danley)
+
+2001-10-09 Tuesday 08:34 kirk
+
+ Updated the BUGS and Todo list to reflect current speakup
+ states. (kirk)
+
+2001-10-07 Sunday 21:19 jim
+
+ speakup.c:
+ Moved following variable declarations to top of function speakup_cut().
+ int ret;
+ unsigned char args[6*sizeof(short)];
+ unsigned short *arg;
+ static char *buf = "speakup_cut: set_selection failed: ";
+ (Jim Danley)
+
+2001-10-07 Sunday 17:11 jim
+
+ Put speakup_dectlk.c back to its original state. Sorry about that!
+
+ Also added a clear_selection() call to speakup.c when hitting the "mark"
+ key to remove (if any) hi-lighting of a previous mark/cut from the screen.
+ (Jim Danley)
+
+2001-10-05 Friday 09:14 kirk
+
+ Checking in a slight change to speakupmap.map to uncomment alt-keypad
+ five to allow ascii five for extended character sets. (kirk)
+
+2001-10-02 Tuesday 12:34 kirk
+
+ Modified installation and readme files for the version 1.0 release in
+ linux/Documentation/speakup. (kirk)
+
+2001-10-02 Tuesday 11:00 kirk
+
+ Start of the check-ins for the official speakup v-1.00 release.
+ Modified checkin to change cvsversion format. Modified install to
+ remove reference to touching speakupmap.map. Modified speakup.c to
+ reflect version now moved to v-1.00. (kirk)
+
+2001-10-02 Tuesday 01:18 jim
+
+ Modified the way that cut/paste variables are stored. No longer in spk_t
+ structure but stand-alone (one per speakup rather than one per console).
+
+ speakup.c:
+ eliminated unsigned short mode = 0; /* char-by-char selection */
+ by assigning it directly.
+
+ Added globals
+ char mark_cut_flag;
+ unsigned short mark_x, mark_y;
+
+ /usr/include/linux/include/linux/speakup.h:
+ removed mark_x and mark_y from the spk_t structure and the associated
+ defines.
+ (Jim Danley)
+
+2001-09-17 Monday 19:58 jim
+
+ speakup.c:
+ Added:
+ #define Mark_Cut_Bit 0x04
+ #define Mark_Cut_Bit_Mask 0xFB
+
+ Changed from using bit 2 of spk_shut_up to bit 2 of spk_sound to
+ indicate mark/cut state.
+
+ Removed statement that was assigning 2 to second byte of first short
+ in args array.
+ (Jim Danley)
+
+2001-09-14 Friday 15:43 kirk
+
+ Removed the blank line at the bottom of drivers/char/Makefile which I
+ must have dreamed I removed in the last log. (kirk)
+
+2001-09-14 Friday 15:28 kirk
+
+ Added a couple of missing key definitions in DefaultKeyAssignments.
+ Removed the blank line at the bottom of drivers/char/Makefile.
+ Rewrote spell_word() to use say_curr_char() and super stream line
+ it. (kirk)
+
+2001-09-14 Friday 14:11 jim
+
+ speakup_dectlk.c:
+ Changed the valid pitch range from 0-99 to 50-350.
+ (Jim Danley)
+
+2001-09-14 Friday 01:28 jim
+
+ Made similar changes to add cut and paste feature to 2.2 kernels. (Jim Danley
+
+2001-09-13 Thursday 23:13 jim
+
+ diff-v2[24]/^usr^src^linux^Documentation^speakup^DefaultKeyAssignments.copy:
+ Added:
+ KeyPad-/ Mark and Cut screen region.
+ InsKeyPad-/ Paste screen region into any console.
+ (Jim Danley)
+
+2001-09-13 Thursday 21:41 jim
+
+ Wrote mark/cut/paste feature.
+
+ Usage:
+ 1. Move reading cursor to one end of the block of text you wish to cut
+ 2. Press the mark/cut key. You should hear "mark".
+ 3. Move reading cursor to other end of block of text to be cut.
+ 4. Press the mark/cut key. You should hear "cut".
+ 5. The cut buffer is now saved.
+ 6. Move to a program in any console where you wish to copy the cut buffer.
+ 7. Press the paste key. You should hear "paste" and text from
+ the cut buffer will be output just as if you had entered it
+ at the keyboard.
+
+ Note: Trailing whitespace is stripped and newlines added where appropriate.
+
+ speakup.c:
+ Added two new functions; speakup_cut() and speakup_paste()
+
+ speakupmap.map:
+ Modified default keymap so that keypad divide toggles mark/cut and
+ insert-keypad divide is paste.
+
+ /usr/src/linux/include/linux/speakup.h:
+ Added two new variables to the spk_t structure; unsigned long mark_x, mark_y
+ to store the coordinates of the beginning of the mark area to be cut.
+ Added:
+ #define spk_mx speakup_console[currcons]->mark_x
+ #define spk_my speakup_console[currcons]->mark_y
+ #define SPEAKUP_CUT 0x27
+ #define SPEAKUP_PASTE 0x28
+ Added two new prototypes:
+ extern void speakup_cut(unsigned int, struct tty_struct *);
+ extern void speakup_paste(struct tty_struct *);
+
+ /usr/src/linux/drivers/char/keyboard.c:
+ In function do_spkup():
+ Added case blocks for SPEAKUP_CUT and SPEAKUP_PASTE.
+
+ /usr/src/linux/include/linux/keyboard.h:
+ Added:
+ #define K_SPEAKUP_CUT K(KT_SPKUP,SPEAKUP_CUT)
+ #define K_SPEAKUP_PASTE K(KT_SPKUP,SPEAKUP_PASTE)
+ and modified: (was 27)
+ #define NR_SPKUP 0x29
+
+ Also modified patch/copy files below in both diff-v22 and diff-v24 directories.
+ ^usr^src^linux^include^linux^keyboard.h.patch
+ ^usr^src^linux^drivers^char^keyboard.c.patch
+ ^usr^src^linux^include^linux^speakup.h.copy
+
+2001-09-08 Saturday 22:22 kirk
+
+ Re-implementing the alpha patch for kernels 2.4.x which somehow keeps
+ getting lost. I also removed the bottom three lines of the checkout
+ script which are not needed anymore because we include a
+ speakupmap.c. (Kirk)
+
+2001-08-30 Thursday 17:25 kirk
+
+ Modified drivers/char/Makefile to work with the new speakupmap.c
+ changes to 2.4.x. These changes include a portion of Shane's patch as
+ well as other rewrites by me. (kirk)
+
+2001-08-30 Thursday 16:17 kirk
+
+ Modified drivers/char/Makefile and speakup/Makefile to accomodate the
+ new 2.4.9ac3 Makefile changes. This will also include a new
+ speakupmap.c moving towards Shane's Makefile patches for the 2.2.x
+ kernels, not included yet. (kirk)
+
+2001-08-29 Wednesday 21:26 kirk
+
+ Just adding new patch against linux/init/main.c to cvs. (kirk)
+
+2001-08-29 Wednesday 21:23 kirk
+
+ Rewrote speakup_init() to call a function speakup_register_devsynth()
+ which gets called from do_basic_setup in init/main.c. We need to do
+ this so that miscdevice will get called after the mm has been set up.
+ This should allow devfs to work with speakup. (kirk)
+
+2001-08-26 Sunday 13:54 kirk
+
+ Removed an old comment line from console.c which prevent clean
+ patching against 2.4.8ac11. (kirk)
+
+2001-08-25 Saturday 18:46 kirk
+
+ Modified keyboard.c, keyboard.h, speakup.c and speakup.h to conform with the standard kernel source tree under 2.4.x kernels. (Kirk)
+
+2001-08-25 Saturday 18:30 kirk
+
+ Removing lxdialog patch files and removing their entries from
+ patchlist-22. These are now part of the standard 2.2.19+ kernel
+ tree. (Kirk)
+ ----------------------------------------------------------------------
+ patchlist-v22 speakupmap.map symbols.h CVS:
+ diff-v22/^usr^src^linux^Documentation^speakup^DefaultKeyAssignments.copy
+ diff-v22/^usr^src^linux^Documentation^speakup^keymap-tutorial.copy
+ Removed Files: CVS:
+ diff-v22/^usr^src^linux^scripts^lxdialog^menubox.c.patch CVS:
+ ----------------------------------------------------------------------
+
+2001-08-25 Saturday 18:15 kirk
+
+ Changed keyboard.c, keyboard.h, speakup.c and speakup.h to conform to
+ the standard linux kernel tree code style for the 2.2.x
+ kernels. (Kirk)
+
+2001-08-18 Saturday 03:31 jim
+
+ diff-v22/^usr^src^linux^drivers^char^keyboard.c.patch: Modified patch
+ to allow raw keyboard for version 2.2 kernels. (Jim Danley)
+
+2001-08-02 Thursday 13:47 kirk
+
+ Adding \x20 to the flush string for the Audapter synths. (Kirk)
+
+2001-07-31 Tuesday 19:07 jim
+
+ speakup_ltlk.c: appended \x20 to flush string of \x18 for litetalk driver.
+ This seems to fix the bug that was causing first chars to be dropped by
+ the double lt and litetalk synths for some users. (Jim Danley)
+
+2001-07-26 Thursday 20:12 kirk
+
+ A few small clean ups trying to get 2.4.7 to work. (Kirk)
+
+2001-07-16 Monday 11:30 kirk
+
+ Added KT_SPKUP to allowed_in_raw_mode macro so speakup's review
+ functions are available in raw mode for v-2.4.x kernels. (Kirk)
+
+2001-03-17 Saturday 15:40 jim
+
+ speakup.c:
+ Added silent feature.
+ The print screen key kills and revives speakup. Sending specific values to
+ /proc/speakup/silent now allows the same control without having to press a key.
+ Valid settings are 0 through 3.
+ 0 and 2 turn on speakup if not already alive.
+ 1 and 3 turn off speakup if not already killed.
+ 0 and 1 announce the changes as the print screen key does,
+ 2 and 3 act silently.
+ (Jim Danley)
+
+2001-03-17 Saturday 08:45 jim
+
+ speakup.c and symbols.h:
+ Added bell position feature.
+ When a letter is typed in column bell_pos, console beeps.
+ Valid settings are 0 through video_num_columns. Zero disables.
+ Get/set via /proc/speakup/bell_pos.
+ (Brian Borowski)
+
+2001-03-13 Tuesday 14:50 jim
+
+ speakup.c:
+ Added code in say_screen() to insert a space at the end of full lines.
+ (Gene Collins)
+
+2001-03-13 Tuesday 14:40 jim
+
+ speakup.c:
+ Found and fixed a couple of places where synth_write() was writing len of
+ string plus 1 which caused a NULL to be sent to the synth which causes
+ problems for the Doubletalk LT.
+
+ speakup.c and keyboard.c for 2.2 and 2.4
+ Corrected the length parameter on several spkup_write() statements which
+ were also sending unnecessary NULLs.
+
+ Corrected spelling of /proc/speakup/transport directory. (Jim Danley)
+
+2001-02-28 Wednesday 10:55 kirk
+
+ Removing the make menuconfig patches for checklist.c and menubox.c
+ because they have been included in linux 2.4.2. (Kirk)
+
+2001-02-11 Sunday 14:05 kirk
+
+ Checking support for alpha support in 2.4.x kernels. (Kirk)
+
+2001-01-30 Tuesday 20:55 kirk
+
+ Fixed arch/ppc/config.in to source drivers/char/Config.in which had
+ gotten broken in the post 2.4.0 ac patches. (Kirk)
+
+2001-01-28 Sunday 23:53 jim
+
+ Reduced duplicate code in proc_speakup_synth_init() by creating two arrays
+ of strings, read_only[] and root_writable[] and using these arrays in
+ for loops.
+ Bumped version numbers on remaining serial synth drivers. (Jim Danley)
+
+2001-01-28 Sunday 20:26 kirk
+
+ Made modifications to speakup.h for v2.2 and the remainder of the
+ serial synth drivers to use the initialize_uart() function in
+ speakup_drvcommon.c. (Kirk)
+
+2001-01-28 Sunday 19:15 kirk
+
+ Made changes to 2.4.0 to move uart initialization code into
+ speakup_drvcommon.c and modified speakup_dectlk.c to use that
+ change. (Kirk)
+
+2001-01-28 Sunday 00:26 jim
+
+ Modified the serprobe() function in the Accent SA driver.
+ This should allow the Accent SA to start talking from a cold boot with
+ no help from the lilo serial= or speakup_ser= options.
+ Ran speakup_acntsa.c through Lindent.
+ Bumped speakup_acntsa.c version number. (Jim Danley)
+
+2001-01-27 Saturday 23:26 jim
+
+ Modified the serprobe() function in the Dectalk Express driver.
+ My Dectalk Express now starts talking just fine from a cold boot with
+ no help from the lilo serial= or speakup_ser= options.
+ Ran speakup_dectlk.c through Lindent and cleaned up some comments.
+ Bumped Dectalk Express driver version number. (Jim Danley)
+
+2001-01-25 Thursday 17:58 jim
+
+ Worked on the write handler for /proc/speakup/synth.
+ It error-checks new_synth_name, prints out msg if synth selected is
+ already in use, looks for new_synth_name in list of synths compiled into
+ kernel, and prepares to switch to new synth.
+ Ran speakup.c through Lindent and cleaned up some comments. (Jim Danley)
+
+2001-01-24 Wednesday 22:59 jim
+
+
+ Modified speakup_drvcommon.c so that those synth-specific /proc file
+ entries which are writable will now accept "" to trigger resetting of
+ the default value.
+ Ran speakup_drvcommon.c through Lindent and cleaned up some comments.
+ (Jim Danley)
+
+2001-01-24 Wednesday 12:33 kirk
+
+ Made changes for Maintaners to v-24. (Kirk)
+
+2001-01-24 Wednesday 12:31 kirk
+
+ Another typo fix in Configure.help and an update to the URL in Maintaners. (Kirk)
+
+2001-01-24 Wednesday 11:57 kirk
+
+ Fixed clarification in Configure.help in v-24. (Kirk)
+
+2001-01-24 Wednesday 11:56 kirk
+
+ Fixed spelling error in Config.in and modified Configure.help yet again. (Kirk)
+
+2001-01-24 Wednesday 11:47 kirk
+
+ Fixed formatting in v-24 configure.help. (Kirk)
+
+2001-01-24 Wednesday 11:46 kirk
+
+ Fixed indentation and spelling errors in configure.help. (Kirk)
+
+2001-01-24 Wednesday 10:49 kirk
+
+ Fixing the v-2.4 version of the Configure.help file. (Kirk)
+
+2001-01-24 Wednesday 10:47 kirk
+
+ Updated the Configure.help documentation and re-arranged the speakup
+ Config.in file. (Kirk)
+
+2001-01-23 Tuesday 15:45 jim
+
+
+ Modified speakup.c to handle input in either upper or lower case written
+ to the /proc file entries for those settings that accept a range of
+ values that includes alpha chars.
+ The value is forced to lower case before any comparisons.
+ Modified the synth driver range parameters to accept only lower case as follows:
+ rate in both speakup_acntpc.c and speakup_acntsa.c,
+ pitch and volume in speakup_apolo.c,
+ tone in speakup_txprt.c.
+ Bumped synth driver version numbers.
+ (Jim Danley)
+
+2001-01-23 Tuesday 11:58 jim
+
+
+ Fixed typo in speakup_dectlk.c.
+ (Jim Danley)
+
+2001-01-23 Tuesday 11:39 jim
+
+
+ Moved full_time into the spk_synth structure for all synths and created
+ /proc/speakup/synth-specific/full_time entry.
+ Modified /usr/include/linux/speakup.h and associated files in diff-v22 and diff-v24.
+ (Jim Danley)
+
+2001-01-23 Tuesday 01:14 jim
+
+
+ Added to the TODO list.
+ (Jim Danley)
+
+2001-01-23 Tuesday 00:42 jim
+
+
+ Moved delay_time, trigger_time, and jiffy_delta into the spk_synth
+ structure for all synths.
+ Modified /usr/include/linux/speakup.h and associated files in diff-v22 and diff-v24.
+ Assigned following default values for Accent SA and Audapter drivers:
+ delay_time = 400, trigger_time = 5, jiffy_delta = 3.
+ Bumped synth driver version numbers.
+ (Jim Danley)
+
+2001-01-22 Monday 21:32 jim
+
+
+ Moved INIT_STRING and REINIT_STRING into the spk_synth structure for all synths.
+ Modified /usr/include/linux/speakup.h and associated files in diff-v22 and diff-v24.
+ Commented out some unused driver code that caused compile warnings.
+ (Jim Danley)
+
+2001-01-22 Monday 17:44 jim
+
+
+ Test number 2.
+ (Jim Danley)
+
+2001-01-22 Monday 16:28 kirk
+
+
+ Testing my new CVS login.
+ (Jim Danley)
+
+2001-01-21 Sunday 19:48 kirk
+
+ Wrote char *strlwr(char *) and now use it to be certain that the
+ synth_name (provided by the user in config or at boot time) is forced
+ to lower case.
+ (Jim Danley)
+
+2001-01-21 Sunday 13:53 kirk
+
+ Added /proc/speakup/synth entry -- read-only so far.
+ Removed old ioctl functions from speakup.c
+ Wrote xlate function to translate escape chars in user provided strings.
+ Added synth_name to "unknown synthesizer" message at boot up.
+ Check for length of synth_name.
+ Made certain that synth_name is NULL terminated.
+ (Jim Danley)
+
+2001-01-21 Sunday 09:03 kirk
+
+ Changed synth_write("\n", 2);
+ to synth_write("\n", 1);
+ when sending user provided synth settings via /proc to the synth.
+ This *might* fix the problem reported by litetalk users.
+ Cleaned up some comments and indenting.
+ (Jim Danley)
+
+2001-01-14 Sunday 21:05 matt
+
+ Checking in 2.2.x patches for the last modification. (Matt)
+
+2001-01-14 Sunday 20:49 kirk
+
+ Checking in Matt Campbells driver rewrite to include all the synths in
+ the kernel at the same time. (Kirk)
+
+2001-01-10 Wednesday 12:16 kirk
+
+ Fixed bug when writing to /proc/speakup files caps_start, caps_stop,
+ punc_some, and punc_most.
+ Defined PUNC_CHARS and PUNC_CHARS_SIZE in symbols.h.
+ Added MULTI_CHAR to list of possible spk_variable.flags, necessary to
+ define a list of chars that must belong to another list of chars --
+ used for punc_some and punc_most.
+ Set arbitrary limit of 33 chars on caps_*.
+ Set PUNC_CHARS_SIZE char limit on user supplied value to punc_some and punc_most.
+ Fixed erroneous error strings.
+ #define'd error conditions to make code more clear.
+ Added STRING_TOO_LONG and CHAR_NOT_ONE_OF.
+ Added missing volume setting to DEFAULT_STATIC for Dectalk Express.
+ (Jim Danley)
+
+2001-01-08 Monday 19:08 kirk
+
+ Made more changes to the cursoring. I got backspace working in and
+ out of cursoring. (Kirk)
+
+2001-01-08 Monday 16:25 kirk
+
+ I have rewritten the cursoring routine speakup_check() to hopefully
+ improve it. We are not there yet! (Kirk)
+
+2001-01-07 Sunday 16:05 kirk
+
+ Just fixing some indentation settings. (Kirk)
+
+2001-01-07 Sunday 13:37 kirk
+
+ added a single line to the top of speakup.c for testing.
+ (Jim Danley)
+
+2001-01-07 Sunday 12:58 kirk
+
+ Fixed char/Makefile to build depends which it wasn't doing for some
+ reason under 2.2.18. (Kirk)
+
+2001-01-07 Sunday 12:16 kirk
+
+ Fixed char/Makefile to create the speakup/.depend correctly. I don't
+ know why it wasn't working before. Everything else did. (Kirk)
+
+2001-01-07 Sunday 12:05 kirk
+
+ modified range checking code in speakup.c to handle negative numbers in
+ user provided parameter to /proc/speakup/* and also in spk_variable.valid.
+ (Jim Danley)
+
+2001-01-07 Sunday 09:02 kirk
+
+ cleaned up and commented symbols.h.
+ re-wrote some of the range logic in symbols.h and speakup.c.
+ changed char valid[33] to char *valid in spk_variable struct.
+ dropped 0xff as char string terminator for spk_variable.valid member.
+ removed NUMERIC from rate flags for accents.
+ made /proc/speakup/tone read-only for dectalk express.
+ (Jim Danley)
+
+2001-01-06 Saturday 15:52 kirk
+
+ Reorganized the Todo list and placed bugs in the bugs file. (Kirk)
+
+2001-01-05 Friday 21:19 kirk
+
+ Made modifications to fix the make menuconfig bug in 2.4.0. (Kirk)
+
+2001-01-05 Friday 20:42 kirk
+
+ Modified menubox.c in lxdialog to fix bug with initial menus not being
+ shown completely. (Kirk)
+
+2001-01-05 Friday 15:54 kirk
+
+ merged symbols_*.h into symbols.h and removed symbols_*.h from CVS.
+ cleaned up the format a bit along the way.
+ (Jim Danley)
+
+2001-01-04 Thursday 18:33 kirk
+
+ Modified the console.c, speakup.h and speakup.c for the 2.4.0 kernels.
+ I have also removed vt.c in preparation for just using the
+ /proc/speakup configuration system. (Kirk)
+
+2001-01-04 Thursday 12:11 kirk
+
+ Starting major changes for merging into the kernel source tree. Files
+ updated are console.c speakup.c speakup.h and vt.c. I have built a
+ new set of functions to interact with the kernel which will be speakup
+ functions if speakup is configured in and null stubs if speakup is not
+ configured in. So far they include: speakup_allocate(), speakup_bs(),
+ speakup_con_update(), speakup_con_write() and speakup_init(). These
+ changes only affect the 2.2.18 tree currently. (Kirk)
+
+2001-01-03 Wednesday 10:04 kirk
+
+ Fixed transport driver by giving the uart time to settle before
+ testing for the port. (Kirk)
+
+2001-01-02 Tuesday 20:18 kirk
+
+ First attempt to change checkout to work with an installed tarball and
+ update it to cvs. (Kirk)
+
+2001-01-02 Tuesday 14:09 kirk
+
+ Made tchanges to make v24 compatible with 2.4.0-prerelease. (Kirk)
+
+2001-01-02 Tuesday 09:50 kirk
+
+ Added code to correctly parse range string for /proc file speech
+ parameters which use a range of chars.
+ Added a priority of KERN_ALERT to printk statements that need to be
+ displayed on user's console regardless.
+ Enhanced warning output if user attempts to assign a value out of range
+ to a /proc variable.
+ (Jim Danley)
+
+2000-12-31 Sunday 13:20 kirk
+
+ Rewrote checkclean and changed semee to semi in the character
+ array. (Kirk)
+
+2000-12-31 Sunday 12:12 kirk
+
+ Fixed syntax errors in speakup_txprt.c and modified the install
+ script. (Kirk)
+
+2000-12-31 Sunday 11:43 kirk
+
+ Fixing typo's in the documentation files. (Kirk)
+
+2000-12-30 Saturday 23:33 kirk
+
+ Rewrote install and INSTALLATION for a different installing
+ design. (Kirk)
+
+2000-12-30 Saturday 17:03 kirk
+
+ We are officially version v-0.10. (Kirk)
+
+2000-12-30 Saturday 16:58 kirk
+
+ Modified the installation file and created an install script. (Kirk)
+
+2000-12-30 Saturday 15:13 kirk
+
+ Fixed a syntax problem with speakup_audptr.c. (Kirk)
+
+2000-12-30 Saturday 14:58 kirk
+
+ Placed a length limit on reading of version number in
+ speakup_audptr.c. (Kirk)
+
+2000-12-30 Saturday 13:12 kirk
+
+ Adding file changes for v22. (Kirk)
+
+2000-12-30 Saturday 13:10 kirk
+
+ Removing files related to version changes. (Kirk)
+
+2000-12-30 Saturday 13:00 kirk
+
+ Changed structure of Documentation/speakup and related files to remove
+ references to speakup version for ease in updating documentation.
+ (Kirk)
+
+2000-12-29 Friday 14:00 kirk
+
+ echo "" > /proc/speakup/characters now resets to defaults for consistency.
+ wrote script to reset all speakup defaults
+ added key_echo toggle to speakup vars controllable by user
+ via /proc/speakup/key_echo
+ key_echo is not 100% -- keypad slash talks even if key_echo == 0
+ (Jim Danley)
+
+2000-12-24 Sunday 16:46 kirk
+
+ finished ability to write to /proc files, changed some default char descs, added "direct" to /proc
+
+2000-12-22 Friday 15:04 kirk
+
+ These are the cursoring fixes for the 2.4.0-testxx kernels. They also
+ include the requested changes I was experimenting with by Alan Cox in
+ preparation for kernel source tree inclusion. (Kirk)
+
+2000-12-22 Friday 13:54 kirk
+
+ Fixed up some of the cursoring issues and have started making the
+ changes requested by Alan Cox in preparation for kernel source tree
+ inclusion. (Kirk)
+
+2000-12-21 Thursday 08:56 kirk
+
+ rewrite of speakup_characters_write_proc() to handle fragmented buffers when called by dd, cp, or cat in kernel 2.4 (Jim Danley)
+
+2000-12-20 Wednesday 12:17 kirk
+
+ Cleaned up some warnings. (Kirk)
+
+2000-12-20 Wednesday 11:32 kirk
+
+ Fixed toggle for synth timeout to set it off when waking up the
+ synth. (Kirk)
+
+2000-12-19 Tuesday 19:31 kirk
+
+ This is atest fix to see if I have helped eliminate the synth bleed
+ through problem with all of the synths. (Kirk)
+
+2000-12-19 Tuesday 16:29 kirk
+
+ quick change to speakup_audptr.c to fix synth_ver typo for kernel 2.2.18 (Jim Danley)
+
+2000-12-19 Tuesday 15:35 kirk
+
+ Checking in the 2.2.18 fixes for the synth hanging problems. (Kirk)
+
+2000-12-19 Tuesday 15:10 kirk
+
+ Finally fixed the synth hanging problem on synth turn off. (Kirk)
+
+2000-12-18 Monday 14:44 kirk
+
+ Just updating BUGS to put the backspace problem to bed. (Kirk)
+
+2000-12-18 Monday 14:40 kirk
+
+ Checking in the backspace fix for 2.4.0-test11. Yeah! Finally
+ fixed. (Kirk)
+
+2000-12-18 Monday 14:14 kirk
+
+ Fixed the backspace bug at last! In 2.2.18 so far. (Kirk)
+
+2000-12-18 Monday 10:03 kirk
+
+ Checking in Jim Danleys changes again. When will I learn to checkout
+ before checking in?? (Kirk)
+
+2000-12-15 Friday 13:50 kirk
+
+ Checking first draft of menubox.c and checklist.c for
+ v-2.4.0-testxx. (Kirk)
+
+2000-12-15 Friday 13:48 kirk
+
+ Taking first diff of menubox.c and checklist.c for v2.4.0-test11 for
+ make menuconfig cursoring. (Kirk)
+
+2000-12-15 Friday 13:17 kirk
+
+ Checking in the new diffs of menubox.c and checklist.c for the first
+ time. (Kirk)
+
+2000-12-15 Friday 13:14 kirk
+
+ Taking first diff of the make menuconfig patches from checklist.c and
+ menubox.c. (Kirk)
+
+2000-12-12 Tuesday 18:56 kirk
+
+ Fixed a spelling error added to Todo list and fix speakup.c to not
+ need the is_alive() function. (Kirk)
+
+2000-12-12 Tuesday 15:21 kirk
+
+ Fixed speakup to patch correctly with 2.2.18. Unfortunately it won't
+ work with kernels less than 2.2.18 anymore. It was totally agreed
+ upon by the folks on the reflector. It's not my fault mom! (Kirk)
+
+2000-12-12 Tuesday 10:41 kirk
+
+ Fix a problem with a conflict in cvsversion.h. (Kirk)
+
+2000-12-11 Monday 20:40 kirk
+
+ Attempt to fix the Audapter driver by limiting how long it can stay in
+ kernel space. (Kirk)
+
+2000-12-11 Monday 17:37 kirk
+
+ Made a slight fix to spk_reset() and moved it's call up a bit in
+ handle_scancodes(); (Kirk)
+
+2000-12-11 Monday 16:28 kirk
+
+ Just checking in the cvs adds for the new diff-v24 patch files. (Kirk)
+
+2000-12-11 Monday 16:25 kirk
+
+ Checking in the 2.4.0 kernel patches for Jim Danley's /proc file
+ system additions. (Kirk)
+
+2000-12-11 Monday 14:34 kirk
+
+ Checking in added proc files. (Kirk)
+
+2000-12-11 Monday 14:31 kirk
+
+ Added two new files to v22 kernel for /proc file system,
+ linux/include/linux/proc_fs.h and linux/fs/proc/root.c. (Kirk)
+
+2000-12-11 Monday 12:59 kirk
+
+ Checking in Jim Danleys /proc file system additions to speakup. (Kirk)
+
+2000-12-09 Saturday 19:14 kirk
+
+ Changed spk_control to test for zero specifically on say_control. (Kirk)
+
+2000-12-09 Saturday 18:29 kirk
+
+ Changed spk_control to say capslock scroll_lock and num_lock even when
+ say_control isn't on. (Kirk)
+
+2000-12-08 Friday 16:21 kirk
+
+ Removing the linux version 2.3.xx stuff again. (Kirk)
+
+2000-12-08 Friday 15:40 kirk
+
+ patched Configure.help by hand from v2.4 and committing. (Kirk)
+
+2000-12-08 Friday 14:47 kirk
+
+ Checked in diff-v22/^usr^src^linux^Documentation^Configure.help.patch
+ which seems to have been missed as well as the init/main.c stuff.
+ This is really weird (Kirk)
+
+2000-12-08 Friday 14:40 kirk
+
+ Added the -d flag to updat in checkout to see if we get cleanup
+ improvement. (Kirk)
+
+2000-12-08 Friday 13:13 kirk
+
+ Removing patchlist and the linux 2.3.xx support. (Kirk)
+
+2000-12-08 Friday 13:07 kirk
+
+ Edited check.orig and fix.orig to use the new patchlist filename
+ convention. (Kirk)
+
+2000-12-07 Thursday 22:17 kirk
+
+ Just checking in the new files, three to be exact. (kirk)
+
+2000-12-07 Thursday 22:14 kirk
+
+ rewrote checkin, checkout and moved patchlist to patchlist-v22 and
+ patchlist-v24 because we were missing the linux/init/main.c patches
+ and we didn't have a way to handle different files for different
+ versions. (kirk)
+
+2000-12-06 Wednesday 19:06 kirk
+
+ Added support for the codepage 437 extended character set. (Jim and Kirk)
+
+2000-11-29 Wednesday 11:30 kirk
+
+ Fixed the 2.2.xx kernels to have the almost correct backspace code.
+ Also move the new character output in do_con_write() to lf(). I've
+ experimentally put a 'space' in to see if that helps the wrapping
+ during console output. (Kirk)
+
+2000-11-27 Monday 15:38 kirk
+
+ Fix or partial to the backspace problem at least on 2.4.0-test11. I
+ probably broke cursoring.
+
+2000-11-22 Wednesday 20:12 kirk
+
+ Fixed a stupid unused variable by deleting it.
+ Fixed speakup_file_write to send raw user data to the synth. (Thanx Matt)
+
+2000-11-21 Tuesday 15:10 kirk
+
+ Adjusted console.c patch for test11 of 2.4.0.
+
+2000-11-16 Thursday 11:42 kirk
+
+ Modified all drivers to test for no port when clearing the holding
+ register.
+
+2000-11-16 Thursday 07:56 kirk
+
+ Fixed console.c patch to compensate for the line movement. in Test10.
+
+2000-10-24 Tuesday 11:10 kirk
+
+ Fix to the LiteTalk driver to get around the hanging when the synth isn't
+ on.
+
+2000-10-23 Monday 12:15 kirk
+
+ Fixed dtlk driver so non-valid ports are released correctly in
+ dev_probe. Also added externs for synth_request_region and
+ release. (Kirk)
+
+2000-08-28 Monday 13:29 kirk
+
+ Fixed Makefile for 2.4.0-test7 in drivers/char.
+
+2000-08-17 Thursday 16:21 kirk
+
+ Birth of cursoring for version 2.4.xx kernels.
+
+2000-08-17 Thursday 12:06 kirk
+
+ Okay, I proclaim the birth of cursoring, at least in the 2.2.x kernels. Next we'll try the 2.3/4.x kernels.
+
+2000-08-17 Thursday 11:01 kirk
+
+ Fixed CFLAGS to EXTRA_CFLAGS in Makefile to get speakup to compile
+ again. The break took place between 2.4.0-test4 and test5.
+
+2000-07-20 Thursday 10:43 kirk
+
+ Changed krealloc to just use kfree instead of kfree_s. Kirk
+
+2000-07-03 Monday 14:19 kirk
+
+ Fixed one line in keyboard.c and changes to cvs
+
+2000-06-29 Thursday 16:32 andy
+
+ Fixed checkin / cvsversion.h
+
+2000-06-29 Thursday 16:26 andy
+
+ v2.2.x keyboard.c + speakup_kill() fix
+
+2000-06-29 Thursday 16:00 andy
+
+ v2.2 addition of speakup_kill() function (bound to sysreq key)
+
+2000-06-29 Thursday 15:56 andy
+
+ v2.4 addition of speakup_kill() function (bound to sysrq key)
+
+2000-06-26 Monday 16:19 andy
+
+ Added (very minimal) read() and ioctl() functions for /dev/synth.
+
+2000-06-23 Friday 11:16 andy
+
+ Fixed miscdevice.h bad patch
+
+2000-06-22 Thursday 15:47 andy
+
+ Fixed defkeymap.c not being built properly.
+
+2000-06-22 Thursday 15:17 andy
+
+ Fixed v2.2.x zero-byte patch bug
+
+2000-06-22 Thursday 14:48 andy
+
+ Checkout prunes now.
+
+2000-06-22 Thursday 12:48 andy
+
+ Forgot to kill the old patch files... cleaning up.
+
+2000-06-22 Thursday 12:45 andy
+
+ Changed checkin/checkout philosophy...
+ v2.2.x, v2.3.x, v2.4.x trees are all in this release
+
+2000-06-21 Wednesday 16:27 andy
+
+ More checkin/checkout fixes.
+
+2000-06-21 Wednesday 16:19 andy
+
+ Changed checkin/checkout philosophy, so 0-byte files aren't such a headache
+
+2000-06-21 Wednesday 14:13 andy
+
+ New checkout script, fixing non-updating of previously patched files.
+
+2000-06-20 Tuesday 15:14 andy
+
+ /dev/synth (MAJOR 10, MINOR 25) fix for v2.2.x tree
+
+2000-06-19 Monday 16:02 andy
+
+ checkin script that fixes busted/nonexstant .orig files
+
+2000-06-19 Monday 13:08 andy
+
+ cvsversion.h fix
+ speakup_decext.c fix for v2.2.x (no such member 'list' problem)
+
+2000-06-14 Wednesday 16:00 andy
+
+ TODO update
+
+2000-06-14 Wednesday 15:25 andy
+
+ Fixed:
+ checkin 'older than' bug
+ disabled -lock speech when spk_shut_up is set
+
+2000-06-14 Wednesday 13:15 andy
+
+ Added a cvsversion.h and cvs date tracking into speakup.
+
+2000-06-14 Wednesday 12:44 andy
+
+ Oops. Forgot these.
+
+2000-06-14 Wednesday 08:06 kirk
+
+ Put SYNTH_MINOR #ifdefs in miscdevices.h for v2.2.x kernels.
+ Updated Todo file and temporarily incremented version number of speakup. (Kirk)
+
+2000-06-13 Tuesday 16:30 andy
+
+ v2.4.x spanky checkin
+
+2000-06-13 Tuesday 15:36 andy
+
+ v2.4.x checkin for /dev/synth stuff.
+
+2000-06-13 Tuesday 15:28 andy
+
+ typo fix.
+
+2000-06-13 Tuesday 15:23 andy
+
+ v2.2.x checkin for the new /dev/synth stuff.
+
+2000-06-13 Tuesday 15:17 andy
+
+ Added a /dev/synth fops to speakup (MAJOR 10, MINOR 25), so that users can
+ use the synth without speakup (but why?). :)
+
+ Also fixed a couple of issues with the check* scripts, and added a -p option
+ to checkin to just create patches.
+
+2000-06-12 Monday 14:36 andy
+
+ Had a 0-byte defkeymap.c file...
+
+2000-06-12 Monday 14:26 andy
+
+ Fixed the screwed up v2.2.x patch files, and added a fixorig script which
+ copies .orig files from /usr/src/linux.orig as stated in the
+ patchlist file
+
+2000-06-09 Friday 16:03 andy
+
+ TODO change
+
+2000-06-09 Friday 14:21 andy
+
+ added checkclean script
+
+2000-06-09 Friday 12:46 andy
+
+ updates to the v2.2.x tree.
+
+2000-06-08 Thursday 14:59 andy
+
+ Fixed v2.2.x diffs, and made a few changes to checkin/checkout/checkorig..
+
+ Namely,
+ checkin:
+ fixed bailout on CVSROOT set
+ diffs only for new or files that have changed since last patch
+ cvs adds directories properly
+ checks exit values of cvs commands
+ checkout/checkorig:
+ zeroes out .orig files that should exist and should be zeroed
+ patchlist:
+ now specifies patchfiles in the form:
+ <0|1>,
+ where the first number is a flag to copy the file to create
+ a .orig, or create a zero-byte file (0) for .orig
+
+2000-06-07 Wednesday 15:52 kirk
+
+ [no log message]
+
+2000-06-07 Wednesday 14:15 andy
+
+ checkin mod
+
+2000-06-07 Wednesday 14:14 andy
+
+ date test added to ./checkin
+
+2000-06-07 Wednesday 14:11 andy
+
+ test
+
+2000-06-07 Wednesday 14:09 andy
+
+ test patch
+
+2000-06-07 Wednesday 13:02 kirk
+
+ test of checkin on spanky
+
+2000-06-07 Wednesday 12:32 andy
+
+ more checkin/checkout updates
+
+2000-06-07 Wednesday 12:19 andy
+
+ quick print fix for checkin script
+
+2000-06-07 Wednesday 12:17 andy
+
+ Fixed new tree commit/checkout/update bugs with checkin and checkout
+
+2000-06-07 Wednesday 12:10 kirk
+
+ v24 tree added to cvs
+
+2000-06-07 Wednesday 11:30 andy
+
+ logic error in ./checkin
+
+ New diff-vXX directories are added now... just cp -a diff-vYY div-vXX, and
+ kill the CVS/ dir.
+
+2000-06-05 Monday 15:54 andy
+
+ Fixed ./checkin to 'cvs add' created patch directories.
+
+2000-06-05 Monday 15:39 andy
+
+ Added synth_release_region, and seperated out a speakup_drvcommon.c file,
+ which contains common driver stuff -- current just synth_release_region(),
+ and synth_request_region().
+
+2000-06-02 Friday 15:32 andy
+
+ Final test??
+
+2000-06-02 Friday 14:11 andy
+
+ bleah
+
+2000-06-02 Friday 13:58 andy
+
+ another test.. *sigh*
+
+2000-06-02 Friday 13:57 andy
+
+ foo
+
+2000-06-02 Friday 13:49 andy
+
+ test 342.7
+
+2000-06-02 Friday 12:56 andy
+
+ wrong checkout script.
+
+2000-06-02 Friday 12:51 andy
+
+ Yet another test.
+
+2000-06-01 Thursday 15:45 andy
+
+ test #2
+
+2000-06-01 Thursday 15:40 andy
+
+ ./checkin script test
+
+2000-06-01 Thursday 15:38 andy
+
+ Initial version of speakup in CVS.
+
+2000-06-01 Thursday 15:38 andy
+
+ Initial revision
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/Changes linux-2.4.30/drivers/char/speakup/Changes
--- linux-2.4.30.orig/drivers/char/speakup/Changes 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/Changes 2000-06-01 12:38:40.000000000 -0700
@@ -0,0 +1,221 @@
+version 0.09
+
+May.24.2000, fixed piles o' bugs, and patched speakup forward to kernel
+2.3.99-pre8 (at least). (Andy)
+
+sometime before May 24th, 2000, wrote several new drivers. (Kirk)
+
+version 0.08
+
+18/11/1999, Finally nailed down and fixed a bug with the serial
+drivers filling their buffer and causing the kernel to hang. Of
+course, once again I've totally rewritten the serial drivers. (Kirk)
+
+10/11/1999, Fixed the end of buffer water mark so the kernel wouldn't
+over run the buffer when a process was put to sleep but there was
+already enough chars in the loop to over write end of buffer and trash
+the system. (Kirk)
+
+29/10/1999, Added code to the drivers to test the kernel version, so
+we could include the proper wait_queue tags for 2.2.x vs 2.3.x. (Kirk)
+
+27/10/1999, fix small bug which made the reading cursor not get stored
+when switching between allocated consoles. (Kirk)
+
+08/10/1999, Totally rewrote all drivers to follow fixed format. No
+more will we have drivers which don't look anything like the other
+drivers. (Kirk)
+
+15/09/1999, Rewrote synth drivers and kernel to support command line
+loading of synth ports at boot time. (Andy)
+
+14/09/1999, Rewrote portions of the speakup_ltlk.c driver to fix a
+problem with the DoubleTalk LT losing the first character sent to it
+after a null character. Seems to be a problem only with the LT, not
+being able to deal with characters immediately following NULLs.
+(Kirk)
+
+10/08/1999, Completed writing absolute go to function for speakup
+reading cursor. (Andy)
+
+04/08/1999, Completed routines for speaking punctuation and
+non-character assigned keys, such as shift/control/alt. (Andy)
+
+02/08/1999, Added routines to kernel.c and speakup to allow capturing
+of keystrokes when they're hit. This allows us to speakup characters
+which are typed for cursor control detection and pronouncing chars
+which are not in the allowable punctuation set. (Andy)
+
+23/07/1999, Added routine speakup_check() to help track cursor
+movement for cursor position pronunciation. It isn't working yet.
+(Kirk)
+
+16/07/1999, Rewrote serial probe in ltlk driver to deal with autobaud
+versions of the LiteTalk and DoubleTalk LT. (Andy)
+
+05/07/1999, Fixed a problem with characters like tick and dash which
+don't get passed through to the synth even though they don't get
+spoken. They are needed to get the synth to handle some words
+correctly. (Kirk)
+
+25/06/1999, Fixed a bug I missed which caused speakup to not read the
+last character on a line with say_curr_line(). (Kirk)
+
+25/06/1999, Fixed a bug which caused speakup to miss the end of
+wrapped around words to the next line. (Kirk)
+
+
+version 0.07
+
+18/06/1999, Rewrote the Speakout driver to make it more inline with
+the current driver design. This driver hasn't been tested yet. An
+exercise for John. (Andy)
+
+17/06/1999, Finished rewriting and testing the new version of load_spk
+utilities to handle multiple synths. This intailed redesigning the
+entire way synth control protocals are stored and passed back and
+forth between configuration files and the ioctl() handler. (Andy)
+
+31/05/1999, Finished writing the driver for the Accent SA and
+Transport external synthesizers. (Kirk)
+
+20/05/1999, Rewrote portions of the DTLK and LTLK drivers to fix slow
+responce and choppiness of the output with say_curr_line and
+say_screen. (Kirk)
+
+18/05/1999, Finished the make config changes to make it easier to
+include various synths before compiling the kernel. This included a
+lot of changes to make files and config.in files as well as the
+config.hlp and maintainers documents. We have moved speakup to its
+own subdirectory under linux/drivers/char and will place all future
+files in there. (Kirk)
+
+17/05/1999, Placed newline characters at the end of all strings in
+speakup.c to facilitate proper output with the Speakout driver. (Kirk)
+
+13/05/1999, Finished writing and testing the ACNTPC driver for the
+Accent PC synthesizer. (Kirk)
+
+11/05/1999, Finished writing and testing the LTLK driver for the
+LightTalk synthesizer. (Andy)
+
+version 0.06
+
+07/04/1999, Hunted down and squashed a bug which caused the system to
+lock up when X11 allocated another console. Now, you want to talk
+about weird bugs? (Kirk and Andy)
+
+05/04/1999, Fixed a small bug where the reading cursor structure was
+floating when switching from console to console. (Kirk)
+
+05/03/1999, Finally got repeat function to work correctly. It didn't
+want to give the proper repeat value on say_word and say_line. (Kirk)
+
+4/27/1999, Changed the two shut up functions to sync the reading
+cursor with the console cursor. (Kirk)
+
+4/25/1999, Added a say hex and ASCII value function. (Brian)
+
+4/22/1999, Added our own punctuation handling. This will give us
+consistancy across various synthesizers. It also allows us custom
+punctuation sets. We have four levels currently, NONE, SOME, MOST,
+ALL. The some and most can be user defined, this will eventually
+become a configuration option with loadspk. (Kirk)
+
+4/19/1999, Added a repeat count function so that speakup doesn't read
+all of a repeating sequence of characters like dashes or equal signs.
+(Kirk)
+
+4/15/1999, Rewrote the synth driver to be smaller and utilize
+buffering all the time. This entailed a total rewrite of the driver.
+It works much better than the older style driver. We won't try to be
+compatible with external drivers anymore. That caused us much grief!
+(Kirk)
+
+Version 0.05
+
+03/01/1999, Modified the kernel code and wrote a number of functions
+for loading and dumping speakups configuration settings. The two
+client programs are loadspk and dumpspk, see the accompanying README
+and INSTALLATION files for details. (Andy)
+
+Version 0.04
+
+12/23/1998, Added park reading cursor function. It toggles on and off
+like the speakup off function. (Kirk)
+
+12/10/1998, added code to announce cursor function calls. This is to
+help me try and figure out how and what to say when. (Kirk)
+
+12/08/1998, Added a check in say character to beep when the colour
+attribute changes. (Kirk)
+
+12/08/1998, rewrote say previous and next word to wrap around at the
+end of lines and beep when going from line to line. (Kirk)
+
+12/07/1998, Fixed a little bug which read the bottom half of a
+character which was higher than 0x7f. It makes make menuconfig work a lot
+nicer. (Kirk)
+
+12/07/1998, Added some new functions to read from reading cursor to
+bottom of screen, read from top of screen, read from left edge of
+screen to reading cursor and read from reading cursor to right edge of
+screen. These are basically stub functions which call two general
+purpose functions say_screen_from_to() and say_line_from_to(). (Kirk)
+
+version 0.03
+
+11/19/1998, Added say phonetic character function. I have temporarily
+bound it to InsKeyPad-2. (Kirk)
+
+11/19/1998, Added pronunciation of caps, num and scroll lock on and
+off in keyboard.c. (Andy)
+
+11/18/1998, Fixed the bug which made speakup say the entire current
+word even if it wrapped over the end of line. I also made
+say_curr_word read the word to the right if you have your reading
+cursor on the space just to the left of the word. Makes it a little
+nicer for reading links in lynx. (Kirk)
+
+version 0.02
+
+11/11/1998, fixed a little problem with the attr byte not being
+correct when speakup_update() was called. (Kirk)
+
+11/11/1998, fixed consoles which are not the foreground console
+speaking while they're updating their screens. (Kirk)
+
+11/11/1998, put in the GPL stuff and revised the documentation. (Kirk)
+
+11/10/1998, Rewrote the say_screen function to be super faster than it
+was. (Kirk)
+
+11/10/1998, started to scratch in the soft parked system for reviewing
+around the screen. This is mostly to prevent the reading cursor from
+moving whenever the screen clock or something gets updated. (Kirk)
+
+11/09/1998, rewrote sections of dtlk.c to do away with writing out
+inside cli()/sti() statements. Now we time out after 4 usec and
+assume we missed the bit drop on the rdy bit because of an interrupt.
+Seems to work pretty well except the damn thing reads garbage until
+the bogomips line. Sure is more responsive normally though. (Kirk)
+
+11/05/1998, got the total shut_up routine to work correctly. In
+vc_allocate() we were allocating a new structure every time it was
+called. It was supposed to be everytime a new console was
+successfully allocated. (Kirk)
+
+11/04/1998, Wrote colour attribute routine say_attrib(). I have
+temporarily assigned it to the keypad-period. (Kirk)
+
+11/02/1998, vmalloc() didn't work, to early in the boot process. So
+took our 8192 byte buffer directly by using kmem_start. (Kirk)
+
+10/29/1998, Increased dtlk buffer to 8192 bytes by moving to vmalloc()
+and vfree() instead of get_free_page()/free_page(). We have moved
+from one PAGE_SIZE to two. (kirk)
+
+10/29/1998, changed spk_shut_up to use bit 8 for total shut up instead
+of a seperate variable. Works independantly for each console
+now. (kirk)
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/Config.in linux-2.4.30/drivers/char/speakup/Config.in
--- linux-2.4.30.orig/drivers/char/speakup/Config.in 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/Config.in 2003-12-10 07:29:56.000000000 -0800
@@ -0,0 +1,26 @@
+tristate 'Speakup console speech' CONFIG_SPEAKUP
+if [ "$CONFIG_SPEAKUP" != "n" ]; then
+ comment 'Type "y" for each synthesizer you want built into the kernel.'
+ dep_tristate "Accent SA, acntsa" CONFIG_SPEAKUP_ACNTSA $CONFIG_SPEAKUP
+ dep_tristate "Accent PC, acntpc" CONFIG_SPEAKUP_ACNTPC $CONFIG_SPEAKUP
+ dep_tristate "Apollo, apollo" CONFIG_SPEAKUP_APOLLO $CONFIG_SPEAKUP
+ dep_tristate "Audapter, audptr" CONFIG_SPEAKUP_AUDPTR $CONFIG_SPEAKUP
+ dep_tristate "Braille 'n' Speak, bns" CONFIG_SPEAKUP_BNS $CONFIG_SPEAKUP
+ dep_tristate "DECtalk Express, dectlk" CONFIG_SPEAKUP_DECTLK $CONFIG_SPEAKUP
+ dep_tristate "DECtalk External (old), decext" CONFIG_SPEAKUP_DECEXT $CONFIG_SPEAKUP
+ dep_tristate "DECtalk PC (big ISA card), decpc" CONFIG_SPEAKUP_DECPC $CONFIG_SPEAKUP
+ if [ "$CONFIG_SPEAKUP_DECPC" = "y" ] ;then
+ comment 'warning: decpc can only be built as a module'
+ fi
+ comment 'In order to use this you will need'
+ comment 'the dtload program and DECPC software files '
+ comment 'Read the accompanying DECPC documentation for more details'
+ dep_tristate "DoubleTalk PC, dtlk" CONFIG_SPEAKUP_DTLK $CONFIG_SPEAKUP
+ dep_tristate "Keynote Gold PC, keypc" CONFIG_SPEAKUP_KEYPC $CONFIG_SPEAKUP
+ dep_tristate "DoubleTalk LT or LiteTalk, ltlk" CONFIG_SPEAKUP_LTLK $CONFIG_SPEAKUP
+ dep_tristate "Software synthesizers /dev/sftsyn, sftsyn" CONFIG_SPEAKUP_SFTSYN $CONFIG_SPEAKUP
+ dep_tristate "Speak Out, spkout" CONFIG_SPEAKUP_SPKOUT $CONFIG_SPEAKUP
+ dep_tristate "Transport, txprt" CONFIG_SPEAKUP_TXPRT $CONFIG_SPEAKUP
+ comment 'Enter the three to six character synth string from above or none.'
+ string "Default synthesizer for Speakup" CONFIG_SPEAKUP_DEFAULT "none"
+fi
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/Kconfig linux-2.4.30/drivers/char/speakup/Kconfig
--- linux-2.4.30.orig/drivers/char/speakup/Kconfig 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/Kconfig 2003-12-10 07:29:56.000000000 -0800
@@ -0,0 +1,210 @@
+menu "Speakup console speech"
+config SPEAKUP
+ tristate "Build speakup console speech"
+ ---help---
+
+ This is the Speakup screen reader. Think of it as a
+ video console for blind people. If built in to the
+ kernel, it can speak evrything on the text console from
+ boot up to shutdown. For more information on Speakup,
+ point your browser at http://www.linux-speakup.org/.
+ There is also a mailing list at the above url that you
+ can subscribe to.
+
+ Supported synthesizers are accent sa, accent pc, appollo
+ II., Auddapter, Braille 'n Speak, Dectalk external
+ (old), Dectalk PC (full length isa board), Dectalk
+ express, Doubletalk, Doubletalk LT or Litetalk,
+ Keynote
+ Gold internal PC, software synthesizers, Speakout, and transport.
+
+ Speakup can either be built in or compiled as a module
+ by answering y or m. If you answer y here, then you
+ must answer either y or m to at least one of the
+ synthesizer drivers below. If you answer m here, then
+ the synthesizer drivers below can only be built as
+ modules.
+
+ These drivers are not standalone drivers, but must be
+ used in conjunction with Speakup. Think of them as
+ video cards for blind people.
+
+
+ The Dectalk pc driver can only be built as a module, and
+ requires software to be pre-loaded on to the card before
+ the module can be loaded. See the decpc choice below
+ for more details.
+
+ If you are not a blind person, or don't have access to
+ one of the listed synthesizers, you should say n.
+
+config SPEAKUP_ACNTSA
+ depends on SPEAKUP
+ tristate "Accent SA, acntsa"
+ ---help---
+
+ This is the Speakup driver for the accent sa
+ synthesizer. You can say y to build it into the kernel,
+ or m to build it as a module. See the configuration
+ help on the Speakup choice above for more info.
+
+config SPEAKUP_ACNTPC
+ depends on SPEAKUP
+ tristate "Accent PC, acntpc"
+ ---help---
+
+ This is the Speakup driver for the accent pc
+ synthesizer. You can say y to build it into the kernel,
+ or m to build it as a module. See the configuration
+ help on the Speakup choice above for more info.
+
+config SPEAKUP_APOLLO
+ depends on SPEAKUP
+ tristate "Apollo, apollo"
+ ---help---
+
+ This is the Speakup driver for the Apollo II
+ synthesizer. You can say y to build it into the kernel,
+ or m to build it as a module. See the configuration
+ help on the Speakup choice above for more info.
+
+config SPEAKUP_AUDPTR
+ depends on SPEAKUP
+ tristate "Audapter, audptr"
+ ---help---
+
+ This is the Speakup driver for the Audapter synthesizer.
+ You can say y to build it into the kernel, or m to
+ build it as a module. See the configuration help on the
+ Speakup choice above for more info.
+
+config SPEAKUP_BNS
+ depends on SPEAKUP
+ tristate "Braille 'n' Speak, bns"
+ ---help---
+
+ This is the Speakup driver for the Braille 'n' Speak
+ synthesizer. You can say y to build it into the kernel,
+ or m to build it as a module. See the configuration
+ help on the Speakup choice above for more info.
+
+config SPEAKUP_DECTLK
+ depends on SPEAKUP
+ tristate "DECtalk Express, dectlk"
+ ---help---
+
+ This is the Speakup driver for the DecTalk Express
+ synthesizer. You can say y to build it into the kernel,
+ or m to build it as a module. See the configuration
+ help on the Speakup choice above for more info.
+
+config SPEAKUP_DECEXT
+ depends on SPEAKUP
+ tristate "DECtalk External (old), decext"
+ ---help---
+
+ This is the Speakup driver for the DecTalk External
+ (old) synthesizer. You can say y to build it into the
+ kernel, or m to build it as a module. See the
+ configuration help on the Speakup choice above for more
+ info.
+
+config SPEAKUP_DECPC
+ depends on SPEAKUP
+ tristate "DECtalk PC (big ISA card), decpc"
+ ---help---
+
+ This is the Speakup driver for the DecTalk PC (full
+ length ISA) synthesizer. You can say m to build it as
+ a module. See the configuration help on the Speakup
+ choice above for more info.
+
+ In order to use the DecTalk PC driver, you must download
+ the dec_pc.tgz file from linux-speakup.org. It is in
+ the pub/linux/goodies directory. The dec_pc.tgz file
+ contains the software which must be pre-loaded on to the
+ DecTalk PC board in order to use it with this driver.
+ This driver must be built as a module, and can not be
+ loaded until the file system is mounted and the DecTalk
+ PC software has been pre-loaded on to the board.
+
+ See the README file in the dec_pc.tgz file for more
+ details.
+
+config SPEAKUP_DTLK
+ depends on SPEAKUP
+ tristate "DoubleTalk PC, dtlk"
+ ---help---
+
+ This is the Speakup driver for the internal DoubleTalk
+ PC synthesizer. You can say y to build it into the
+ kernel, or m to build it as a module. See the
+ configuration help on the Speakup choice above for more
+ info.
+
+config SPEAKUP_KEYPC
+ depends on SPEAKUP
+ tristate "Keynote Gold PC, keypc"
+ ---help---
+
+ This is the Speakup driver for the Keynote Gold
+ PC synthesizer. You can say y to build it into the
+ kernel, or m to build it as a module. See the
+ configuration help on the Speakup choice above for more
+ info.
+
+config SPEAKUP_LTLK
+ depends on SPEAKUP
+ tristate "DoubleTalk LT or LiteTalk, ltlk"
+---help---
+
+ This is the Speakup driver for the LiteTalk/DoubleTalk
+ LT synthesizer. You can say y to build it into the
+ kernel, or m to build it as a module. See the
+ configuration help on the Speakup choice above for more
+ info.
+
+config SPEAKUP_SFTSYN
+ depends on SPEAKUP
+ tristate "Software synthesizers, sftsyn"
+---help---
+
+ This is the software synthesizer device node. It will
+ register a device /dev/sftsyn which midware programs
+ and speech
+ daemons may open and read to provide kernel output to
+ software synths
+ such as festival, flite, tuxtalk and so forth. You
+ can select 'y' or
+ 'm' to have it built-in to the kernel or loaded as a module.
+
+config SPEAKUP_SPKOUT
+ depends on SPEAKUP
+ tristate "Speak Out, spkout"
+ ---help---
+
+ This is the Speakup driver for the Speakout synthesizer.
+ You can say y to build it into the kernel, or m to
+ build it as a module. See the configuration help on the
+ Speakup choice above for more info.
+
+config SPEAKUP_TXPRT
+ depends on SPEAKUP
+ tristate "Transport, txprt"
+ ---help---
+
+ This is the Speakup driver for the Transport
+ synthesizer. You can say y to build it into the kernel,
+ or m to build it as a module. See the configuration
+ help on the Speakup choice above for more info.
+
+if SPEAKUP != n
+ comment 'Enter the 3 to 6 character keyword from the list above, or none for no default synthesizer on boot up.'
+ depends on SPEAKUP
+endif
+
+config SPEAKUP_DEFAULT
+ string "Choose Default synthesizer for Speakup"
+ default "none"
+
+endmenu
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/Makefile linux-2.4.30/drivers/char/speakup/Makefile
--- linux-2.4.30.orig/drivers/char/speakup/Makefile 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/Makefile 2004-10-21 07:39:22.000000000 -0700
@@ -0,0 +1,61 @@
+#
+# Makefile for the speakup speech output system.
+#
+
+V := $(shell awk '/UTS_RELEASE/ {print substr($$3,2,3)}' $(TOPDIR)/include/linux/version.h)
+ifeq ($V,2.4)
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now inherited from the
+# parent makes..
+#
+O_TARGET := spk.o
+export-objs := speakup_drvcommon.o speakup.o
+endif
+obj-m = speakup_keyhelp.o
+speakupmain-objs := speakup.o speakup_drvcommon.o
+obj-$(CONFIG_SPEAKUP) += speakupmain.o
+obj-$(CONFIG_SPEAKUP_ACNTPC) += speakup_acntpc.o
+obj-$(CONFIG_SPEAKUP_ACNTSA) += speakup_acntsa.o
+obj-$(CONFIG_SPEAKUP_APOLLO) += speakup_apollo.o
+obj-$(CONFIG_SPEAKUP_AUDPTR) += speakup_audptr.o
+obj-$(CONFIG_SPEAKUP_BNS) += speakup_bns.o
+obj-$(CONFIG_SPEAKUP_DECEXT) += speakup_decext.o
+obj-$(CONFIG_SPEAKUP_DECPC) += speakup_decpc.o
+obj-$(CONFIG_SPEAKUP_DECTLK) += speakup_dectlk.o
+obj-$(CONFIG_SPEAKUP_DTLK) += speakup_dtlk.o
+obj-$(CONFIG_SPEAKUP_KEYPC) += speakup_keypc.o
+obj-$(CONFIG_SPEAKUP_LTLK) += speakup_ltlk.o
+obj-$(CONFIG_SPEAKUP_SFTSYN) += speakup_sftsyn.o
+obj-$(CONFIG_SPEAKUP_SPKOUT) += speakup_spkout.o
+obj-$(CONFIG_SPEAKUP_TXPRT) += speakup_txprt.o
+
+ifeq ($V,2.4)
+ include $(TOPDIR)/Rules.make
+
+speakupmap.h: speakupmap.map genmap
+ ./genmap speakupmap.map >$@
+
+genmap: genmap.c mapdata.h
+ cc -o genmap genmap.c
+
+mapdata.h: makemapdata.c keyinfo.h
+ cc -o makemapdata makemapdata.c
+ ./makemapdata >mapdata.h
+
+endif
+speakupmain.o:speakup.o speakup_drvcommon.o
+ ld -r -o speakupmain.o speakup.o speakup_drvcommon.o
+
+$(obj)/speakupmap.h: $(src)/speakupmap.map $(src)/genmap
+ $(src)/genmap $(src)/speakupmap.map >$@
+
+$(obj)/mapdata.h: $(src)/keyinfo.h $(src)/makemapdata
+ $(src)/makemapdata >$@
+
+$(obj)/genmap: $(obj)/mapdata.h
+
+HOSTCFLAGS := -Iinclude -I/usr/include
+hostprogs-y := makemapdata genmap
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/TODO linux-2.4.30/drivers/char/speakup/TODO
--- linux-2.4.30.orig/drivers/char/speakup/TODO 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/TODO 2004-03-06 07:55:29.000000000 -0800
@@ -0,0 +1,50 @@
+The format of this file is getting organized to help me keep track of
+where we are going. I am organizing it into three sections.
+Immediate things which need to be done I.E. code re-organization. New
+features we are currently working on or at least in the near future.
+Long term features which will move to the new features list as the new
+features list empties.
+
+Immediate:
+
+Check and test all linux supported architectures to make sure speakup
+works with them.
+
+New-Features:
+
+A screen memory find function to place the reading cursor.
+
+synth_file fops need to be filled in and expanded such as some type of
+ioctl function and a real synth_file_read() function.
+
+
+Long-Term-Features:
+
+keyboard macros (ala ASAP/qedit)
+
+finding calling process, so per-program configurations can be loaded
+
+Check park status and store it before doing a console switch. (non-trivial)
+
+user defined scroll-back ala shift-pgup.
+
+insert as 'capslock-style'/'next-style' key -- have internalized speakup
+ variable, which tracks state of the insert key; each speakup bare-key
+ function checks the variable, and possibly calls the alternate
+ function and returns
+
+Chuck wants a bleep if the shift key is hit and the capslock is on.
+Here is his suggested test sequence:
+1. check if the caps lock is set; if it is,
+2. check if the char is alphabetic; if it is,
+3. check if the shift key is pressed; if it is,
+4. send a bell char to the console.
+
+Frank would like a fast way to go to the end of the word in addition
+to moving to the beginning.
+
+Gene thinks we should have a /proc function to store and show the rom
+version of any synth currently operating.
+
+The items in each list have no connection with the order of
+implementation. I just jotted them down as I thought of them.
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/checkclean linux-2.4.30/drivers/char/speakup/checkclean
--- linux-2.4.30.orig/drivers/char/speakup/checkclean 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/checkclean 2000-12-31 10:20:36.000000000 -0800
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+if [ "$1" == "" ]; then
+ echo "You forgot to include a path"
+ exit
+fi
+
+cp -R /usr/src/linux/drivers/char/speakup $1/speakup
+cd $1/speakup
+
+rm -rf checkin checkorig checkclean *.o *~ \
+ CVS diff-v22/CVS diff-v24/CVS cvsversion.h
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/checkin linux-2.4.30/drivers/char/speakup/checkin
--- linux-2.4.30.orig/drivers/char/speakup/checkin 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/checkin 2003-05-12 18:05:31.000000000 -0700
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+cd ../../..
+ROOTDIR=`pwd`
+VERSION=v`head -2 $ROOTDIR/Makefile | \
+ awk '{ printf "%s",$3 }'`
+
+DIR=$ROOTDIR/drivers/char/speakup
+
+echo "Checking in $VERSION"
+
+# check for CVSROOT stuff
+if [ ! -d ${DIR}/CVS ] && [ "$CVSROOT" == "" ]; then
+ echo 'CVSROOT not set. Enter it below.'
+ read -p 'CVSROOT> ' CVSROOT
+ [ "$CVSROOT" == "" ] && exit
+ export CVSROOT
+ cvs login || exit
+fi
+
+# do I have a new version to deal with?
+CVS_ADD=n
+if [ ! -d ${DIR}/diff-${VERSION}/CVS ]; then
+ CVS_ADD=y
+fi
+
+# make patch files
+echo -n 'Creating CVS files ['
+for i in `cat ${DIR}/patchlist-${VERSION}`; do
+ patch=`echo $i | cut -f 1 -d ,`
+ filebase=`echo $i | cut -f 2 -d ,`
+
+ mkdir -p ${DIR}/diff-${VERSION}
+ fname="${DIR}/diff-${VERSION}/${filebase//\//^}"
+
+ if [ "$patch" == "0" ]; then
+ # Just copy it
+ if [ $fname.copy -ot $filebase ] || [ ! -e $fname.copy ]; then
+ echo -n c
+ cp $ROOTDIR/$filebase $fname.copy
+ else
+ echo -n .
+ fi
+ else
+ # Make a patch
+ if [ -e $ROOTDIR/$filebase.orig ]; then
+ if [ $fname.patch -ot $filebase ] || [ ! -e $fname.patch ] ; then
+ echo -n p
+ diff -urN $ROOTDIR/$filebase.orig $filebase > $fname.patch
+ else
+ echo -n .
+ fi
+ else
+ # can't patch w/o .orig
+ echo !
+ echo Error: $ROOTDIR/$filebase.orig doesn\'t exist!
+ exit
+ fi
+ fi
+done
+echo '] done.'
+
+[ "$1" == "-p" ] && exit
+
+cd ${DIR}
+
+echo 'Creating cvsversion.h'
+echo '#define CVSVERSION " CVS:' `date` '"' > cvsversion.h
+
+echo 'Sending to CVS...'
+if [ "$CVS_ADD" == "y" ]; then
+ cvs add diff-${VERSION} || exit
+ cvs add diff-${VERSION}/* || exit
+fi
+cvs -Q ci || exit
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/checkout linux-2.4.30/drivers/char/speakup/checkout
--- linux-2.4.30.orig/drivers/char/speakup/checkout 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/checkout 2003-05-13 07:35:07.000000000 -0700
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+ROOTDIR=/usr/src/linux
+if [ "$1" != "" ]; then
+ ROOTDIR="$1"
+else
+ if [ -d kernel -a -d Documentation ]; then
+ ROOTDIR=`pwd`
+ fi
+fi
+
+VERSION=v`head -2 $ROOTDIR/Makefile | \
+ awk '{ printf "%s",$3 }'`
+
+DIR=$ROOTDIR/drivers/char/speakup
+
+echo "Patching version $VERSION"
+
+if [ ! -d ${DIR}/CVS ] && [ "$CVSROOT" == "" ]; then
+ echo 'CVSROOT not set. Enter it below. Hit enter for anonymous.'
+ read -p 'CVSROOT> ' CVSROOT
+ [ "$CVSROOT" == "" ] &&
+ CVSROOT=':pserver:anonymous@bumpy.braille.uwo.ca:/usr/src/CVS'
+ export CVSROOT
+ cvs login || exit
+fi
+
+if [ "$1" != "-p" ]; then
+ # get new version
+ mkdir -p ${DIR%/speakup}
+ cd ${DIR%/speakup}
+ if [ -d speakup ] && [ -d ${DIR}/CVS ]; then
+ cd speakup
+ cvs update -d -P || exit
+ else
+ rm -fr ${DIR}
+ cvs co -P speakup || exit
+ cd speakup
+ fi
+fi
+
+# make .orig files
+echo -n 'Creating .orig files ['
+for i in `cat ${DIR}/patchlist-${VERSION}`; do
+ patch=`echo $i | cut -f 1 -d ,`
+ filebase=`echo $i | cut -f 2 -d ,`
+
+ mkdir -p `dirname $ROOTDIR/$filebase`
+ if [ "$patch" == "1" ]; then
+ if [ ! -e $ROOTDIR/$filebase.orig ]; then
+ echo -n .
+ cp $ROOTDIR/$filebase $ROOTDIR/$filebase.orig
+ fi
+ fi
+done
+echo '] done.'
+
+# apply patches
+echo -n 'Patching files ['
+for i in ${DIR}/diff-${VERSION}/*.patch; do
+ # skip dirs
+ [ -d $i ] && continue
+ echo -n p
+ writeloc=${i##$DIR\/diff-${VERSION}\/}
+ writeloc=${writeloc%.patch}
+ writeloc=${writeloc//^/\/}
+ patch --silent -f -p0 -o $ROOTDIR/$writeloc $ROOTDIR/$writeloc.orig $i
+done
+echo '] done.'
+
+# copy files
+echo -n 'Copying files ['
+for i in ${DIR}/diff-${VERSION}/*.copy; do
+ # skip dirs
+ [ -d $i ] && continue
+ echo -n c
+ writeloc=${i##$DIR\/diff-${VERSION}\/}
+ writeloc=${writeloc%.copy}
+ writeloc=${writeloc//^/\/}
+ cp $i $ROOTDIR/$writeloc
+done
+echo '] done.'
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/cvsversion.h linux-2.4.30/drivers/char/speakup/cvsversion.h
--- linux-2.4.30.orig/drivers/char/speakup/cvsversion.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/cvsversion.h 2005-04-19 09:26:21.000000000 -0700
@@ -0,0 +1 @@
+#define CVSVERSION " CVS: Tue Apr 19 12:22:52 EDT 2005 "
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/CVS/Entries linux-2.4.30/drivers/char/speakup/diff-v22/CVS/Entries
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/CVS/Entries 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/CVS/Entries 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1,24 @@
+/^usr^src^linux^Documentation^Configure.help.patch/1.66/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^Documentation^speakup^DefaultKeyAssignments.copy/1.2/Fri Sep 14 03:13:23 2001//
+/^usr^src^linux^Documentation^speakup^INSTALLATION.copy/1.5/Tue Oct 2 16:34:59 2001//
+/^usr^src^linux^Documentation^speakup^README.copy/1.2/Tue Oct 2 16:34:59 2001//
+/^usr^src^linux^Documentation^speakup^keymap-tutorial.copy/1.1/Thu Jun 22 16:45:07 2000//
+/^usr^src^linux^MAINTAINERS.patch/1.68/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^arch^arm^config.in.patch/1.69/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^arch^i386^config.in.patch/1.67/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^arch^m68k^config.in.patch/1.69/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^arch^mips^config.in.patch/1.69/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^arch^ppc^config.in.patch/1.69/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^arch^sparc64^config.in.patch/1.69/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^arch^sparc^config.in.patch/1.69/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^drivers^char^Makefile.patch/1.68/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^drivers^char^console.c.patch/1.68/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^drivers^char^keyboard.c.patch/1.74/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^drivers^char^selection.c.patch/1.9/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^fs^proc^root.c.patch/1.54/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^include^linux^keyboard.h.patch/1.74/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^include^linux^miscdevice.h.patch/1.66/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^include^linux^proc_fs.h.patch/1.54/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^include^linux^speakup.h.copy/1.19/Fri Aug 16 00:00:30 2002//
+/^usr^src^linux^init^main.c.patch/1.57/Fri Aug 16 00:00:30 2002//
+D
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/CVS/Repository linux-2.4.30/drivers/char/speakup/diff-v22/CVS/Repository
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/CVS/Repository 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/CVS/Repository 2005-05-01 19:02:57.000000000 -0700
@@ -0,0 +1 @@
+speakup/diff-v22
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/CVS/Root linux-2.4.30/drivers/char/speakup/diff-v22/CVS/Root
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/CVS/Root 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/CVS/Root 2005-05-01 19:02:57.000000000 -0700
@@ -0,0 +1 @@
+:pserver:anonymous@bumpy.braille.uwo.ca:/usr/src/CVS
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^Configure.help.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^Configure.help.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^Configure.help.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^Configure.help.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,138 @@
+--- /usr/src/linux/Documentation/Configure.help.orig Thu Aug 15 15:04:43 2002
++++ /usr/src/linux/Documentation/Configure.help Thu Aug 15 15:04:46 2002
+@@ -11118,7 +11118,134 @@
+ If you are asked this question, something is wrong with config scripts.
+ Zilog serial driver is always enabled in sparc architecture.
+
+-Double Talk PC internal speech card support
++Speakup console speech output for Linux
++CONFIG_SPEAKUP
++ Choosing this Option will include support for console speech output.
++
++ Speakup provides access to Linux for the visually impaired community.
++ It does this by sending console output to a number of different
++ hardware speech synthesizers. It provides access to Linux by Making
++ screen review functions available such as are used in comercial screen
++ review packages for the MSDOS and MSWINDOWS world.
++
++ The drivers supplied under this option are not standard devices in the
++ /dev/ sence of the meaning. They can be thought of as a video card
++ for the blind. They are used by speakup and only speakup.
++
++ For more information about speakup and its drivers check out
++ http://www.linux-speakup.org, or read the Documentation in
++ linux/Documentation/speakup.
++
++ The currently supported synthesizers are:
++ Accent PC internal synthesizer.
++ Accent SA external Accent synthesizer.
++ Apollo II external synthesizer.
++ Audapter external synthesizer.
++ Braille 'N Speak external synthesizer.
++ Dectalk Express and external synthesizers.
++ DoubleTalk PC Internal synthesizer,
++ LiteTalk/DoubleTalk-LT external serial synthesizers,
++ Speakout external synthesizer,
++ Transport external synthesizer.
++
++ If you do not have one of these synths, say 'N' to this option.
++
++Default synthesizer for Speakup
++CONFIG_SPEAKUP_DEFAULT
++ This option specifies which synthesizer Speakup should use by
++ default at boot time.
++ Valid values are: none, acntpc, acntsa, apolo, audptr, bns, decext,
++ dectlk dtlk, ltlk, spkout, txprt
++
++ You can choose an alternatively compiled-in synthesizer at boot time
++ by using the speakup_synth kernel command line option,
++ I.E. speakup_synth=dtlk.
++
++Use Speakup keymap by default
++CONFIG_SPEAKUP_KEYMAP
++ If this option is enabled, then a modified US keymap which includes
++ Speakup's screen review commands will be used by default.
++
++DoubleTalk driver for speakup.
++CONFIG_SPEAKUP_DTLK
++ The DoubleTalk synthesizer is made by RC Systems. It is an internal
++ ISA card which uses no interrupts. Do not confuse this driver with
++ the standard DoubleTalk driver included in the kernel.
++
++ If you don't have a DoubleTalk card say 'N' here.
++
++LiteTalk/DoubleTalk-LT driver for speakup.
++CONFIG_SPEAKUP_LTLK
++ This driver is for the LiteTalk synthesizer made by MicroTalk or the
++ DoubleTalk-LT synthesizer made by RC Systems. These are serial
++ drivers for those external synths.
++
++ If you don't have a LiteTalk or DoubleTalk-LT, say 'N' here.
++
++Speakout driver for speakup.
++CONFIG_SPEAKUP_SPKOUT
++ This driver is for the Speakout external serial synthesizer made by
++ GW Micro.
++
++ If you don't have a Speakout, say 'N' here.
++
++Accent PC driver for speakup.
++CONFIG_SPEAKUP_ACNTPC
++ This driver is for the Accent PC internal synthesizer made by Aicom
++ Corp.
++
++ If you Don't have an Accent PC, say 'N' here.
++
++Accent SA driver for speakup.
++CONFIG_SPEAKUP_ACNTSA
++ This driver is for the Accent SA external synthesizer made by Aicom
++ Corp.
++
++ If you Don't have an Accent SA, say 'N' here.
++
++Apollo II driver for speakup.
++CONFIG_SPEAKUP_APOLO
++ This driver is for the Apollo II external synthesizer made
++ by Dolphin Computer Access limited.
++
++ If you Don't have an Apollo II, say 'N' here.
++
++Audapter Speech System driver for speakup.
++CONFIG_SPEAKUP_AUDPTR
++ This driver is for the Audapter external synthesizer made by
++ Personal Data System Inc.
++
++ If you Don't have an Audapter, say 'N' here.
++
++Braille 'N Speak driver for speakup.
++CONFIG_SPEAKUP_BNS
++ This driver is for the Braille 'N Speak external synthesizer made by
++ Blazie Engineering.
++
++ If you Don't have a bns, say 'N' here.
++
++Dectalk Express driver for speakup.
++CONFIG_SPEAKUP_DECTLK
++ This driver is for the Dectalk Express external synthesizer made by
++ Digital Equipment Corp.
++
++ If you Don't have a Dectalk Express, say 'N' here.
++
++Dectalk External driver for speakup.
++CONFIG_SPEAKUP_DECEXT
++ This driver is for the older Dectalk external synthesizer made by
++ Digital Equipment Corp.
++
++ If you Don't have a Dectalk external, say 'N' here.
++
++Transport driver for speakup.
++CONFIG_SPEAKUP_TXPRT
++ This driver is for the Artic Transport external synthesizer made by
++ Artic Technologies.
++
++ If you Don't have a Transport, say 'N' here.
++
++Double Talk PC internal speech card support
+ CONFIG_DTLK
+ This driver is for the DoubleTalk PC, a speech synthesizer
+ manufactured by RC Systems (http://www.rcsys.com/). It is also
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^DefaultKeyAssignments.copy linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^DefaultKeyAssignments.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^DefaultKeyAssignments.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^DefaultKeyAssignments.copy 2001-09-13 20:13:23.000000000 -0700
@@ -0,0 +1,45 @@
+This file is intended to give you an overview of the default keys used
+by speakup for it's review functions. You may change them to be
+anything you want but that will take some familiarity with key
+mapping.
+
+We have remapped the insert or zero key on the keypad to act as a
+shift key. Well, actually as an altgr key. So in the following list
+InsKeyPad-period means hold down the insert key like a shift key and
+hit the keypad period.
+
+KeyPad-8 Say current Line
+InsKeyPad-8 say from top of screen to reading cursor.
+KeyPad-7 Say Previous Line (UP one line)
+KeyPad-9 Say Next Line (down one line)
+KeyPad-5 Say Current Word
+InsKeyPad-5 Spell Current Word
+KeyPad-4 Say Previous Word (left one word)
+InsKeyPad-4 say from left edge of line to reading cursor.
+KeyPad-6 Say Next Word (right one word)
+InsKeyPad-6 Say from reading cursor to right edge of line.
+KeyPad-2 Say Current Letter
+InsKeyPad-2 say current letter phonetically
+KeyPad-1 Say Previous Character (left one letter)
+KeyPad-3 Say Next Character (right one letter)
+KeyPad-plus Say Entire Screen
+InsKeyPad-plus Say from reading cursor line to bottom of screen.
+KeyPad-Minus Park reading cursor (toggle)
+InsKeyPad-minus Say character hex and decimal value.
+KeyPad-period Say Position (current line, position and console)
+InsKeyPad-period say colour attributes of current position.
+InsKeyPad-9 Move reading cursor to top of screen (insert pgup)
+InsKeyPad-3 Move reading cursor to bottom of screen (insert pgdn)
+InsKeyPad-7 Move reading cursor to left edge of screen (insert home)
+InsKeyPad-1 Move reading cursor to right edge of screen (insert end)
+KeyPad-Enter Shut Up (until another key is hit) and sync reading cursor
+InsKeyPad-Enter Shut Up (until toggled back on) and sync cursors
+InsKeyPad-star n go to line (y) or column (x). Where 'n' is any
+ allowed value for the row or column for your current screen.
+KeyPad-/ Mark and Cut screen region.
+InsKeyPad-/ Paste screen region into any console.
+
+Hitting any key while speakup is outputting speech will quiet the
+synth until it has caught up with what is being printed on the
+console.
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^INSTALLATION.copy linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^INSTALLATION.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^INSTALLATION.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^INSTALLATION.copy 2001-10-02 09:34:59.000000000 -0700
@@ -0,0 +1,108 @@
+This document assumes you have had some experience with kernel
+compilation and installation. If you have not, I recommend you get
+the kernel source and read the README and various documents in the
+linux/Documentation directory. In particular the Changes file to make
+sure you have the appropriate utilities needed for installing a 2.2.xx
+or 2.4xx kernel. It isn't as difficult as you might think. The
+kernel README is intimidating the first time but once you get the
+steps down, it's really pretty easy. Getting through the "make
+config" is the tedious bit.
+
+The first thing to do is to place a copy of the tarball in the /usr/src
+directory which is the directory the linux tree is located in as well.
+Next untar speakup by typing:
+
+tar zxf speakup-1.00.tar.gz
+cd speakup-1.00
+./install
+
+Note the dot-slash before the install. This will copy the speakup
+directory to the kernel tree and apply the various patches and
+components to the appropriate kernel files. Depending on how
+experienced you are with kernel compiling and hacking will determine
+whether you should bother looking at any failed patches. If this
+happens, you should probably write to the speakup mailing list for
+help or myself.
+
+If all of the patch hunks apply successfully then just continue with
+the standard steps to compile the kernel with:
+
+make mrproper
+make config
+
+When you get to the section console speech output, answer 'y' to the
+CONFIG_SPEAKUP prompt. You will be given a submenu with the list of
+synthesizers which are currently supported. You can include as many
+synths in the kernel as you wish but remember each one takes up kernel
+space. You can only choose one of the synths as the default or none,
+so just type dtlk or whatever is the correct string for the
+synthesizer you have. You will also be asked if you wish to build-in
+a speakup key map. If you do not say 'y' to this option you will need
+to load a speakup map at boot time with whichever mechanism your
+distribution uses for loading key maps.
+
+We have placed the speakup configuration options in make config just
+after the vga console choice. For the DoubleTalk PC driver included
+by Jim Van Zandt. I recommend you say no to that option. I have not
+tried configuring them both in, but I wouldn't be at all surprised if
+it didn't work.
+
+If all goes well up to this point you can continue with the compiling
+process by doing:
+
+make dep >dep.file 2>&1 &
+make bzImage >cc.file 2>&1 &
+make modules >mod.file 2>&1 &
+
+I always redirect output to the files dep.file and cc.file so I can
+look over the compilation record to make sure there are no errors and
+warnings.
+
+Okay, you are ready to install the newly compiled kernel. Make sure
+you make an linux.old entry in your lilo.conf file so you can recover
+if it blows up. next as root run "make modules_install" to install
+whatever modules you compiled and move the bzImage from
+/usr/src/linux/arch/i386/boot to wherever your kernel lives. Also
+move the System.map from /usr/src/linux to where your System.map
+lives. On our systems we use debian so we create an vmlinuz-speakup
+and System.map-speakup in our /boot directory and set the symbolic
+links vmlinuz and System.map in the root (/) directory to point to the
+images. Now type lilo to tell lilo to build the new booter file and
+install it.
+
+As of version 0.07, the keymap for speakup is automatically built in
+at compile time. If you have other keymaps installed at boot time,
+you might want to consider removing them before you reboot the system.
+
+If everything has gone OK up until now, cross your fingers and type:
+
+shutdown -r now
+
+Your system should start talking to you as soon as it starts booting.
+It will talk and talk and ... well, you might want to hit the
+keypad-enter key to tell it to shut up. You should also read the
+DefaultKeyAssignments file to learn the various review functions
+available.
+
+As of v-0.10 the speakup configuration options are in the
+/proc/speakup subtree. The individual options should be fairly
+obvious by their names such as rate, volume, punc_level and so forth.
+You can manipulate them by cat'ing or echoing new values to them such
+as:
+
+echo 9 >/proc/speakup/rate
+
+You can see what the current values are by cat'ing those files to the console:
+
+cat /proc/speakup/rate
+
+I have probably managed to overlook a whole whack of things because
+this is the, enter version number here, draft. Don't worry we'll get
+it right eventually. If you like the package you really should get on
+the mailing list and start participating in it's development.
+
+ Kirk
+
+email: kirk@braille.uwo.ca
+phone: (519) 679-6845 (home)
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^README.copy linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^README.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^README.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^README.copy 2001-10-02 09:34:59.000000000 -0700
@@ -0,0 +1,98 @@
+Welcome to the speakup project for the Speakup speech package for Linux.
+
+Speakup is written by Kirk Reiser and Andy Berdan. It is licensed
+under the GPL. If you don't already know, the GPL stands for the GNU
+General Public License. Which basically states that this code is free to
+copy, modify and distribute to anyone interested in playing with it.
+The one thing you may not do is turn any part of it into proprietary
+or commercial code without the permission of the author. That's me.
+
+If you are interested in being involved with the development of speech
+output for Linux you can subscribe to the Speakup mailing list by
+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.
+
+We are at a very early stage in the development of this package.
+Hopefully changes will happen often and many. The current files in
+this directory are:
+
+DefaultKeyAssignments # speakup's default review keys
+INSTALLATION # for installing speakup from the tar ball.
+README # this file
+keymap-tutorial # a tutorial on how to layout the keyboard
+
+Read the INSTALLATION file to learn how to apply the patches and the
+default.map for the keyboard. You should also read the Changes file.
+It really has any new things I've added since last time.
+
+There is no documentation in any of these files to instruct you what
+to do if something goes wrong with the patching or compilation. If
+you would like that information you will need to subscribe to the
+mailing list and ask for help, or write me kirk@braille.uwo.ca for
+help. I suggest the mailing list because I will probably tire quickly
+of answering the same questions over and over. You could always
+decide to dig-in and take on the task, and write documentation to help
+others.
+
+There also is a speakup reflector for the Speak Freely package, which
+many of us hang out on and discuss all sorts of topics from speakup
+problems to ALSA driver installation and just about anything else
+you'd like to talk about. The reflector is at lwl.braille.uwo.ca:4074
+with it's lwl page at lwl.braille.uwo.ca/speakup.html. Come and join
+us, it's fun!
+
+Acknowledgements:
+
+I am really very new at kernel hacking and screen review package
+writing, so I have depended heavily on other folks kindness to help me
+a long. No doubt I will continue to abuse them freely and others
+before this is a really good speech solution for Linux. (Oh Well!,
+somebody's got to do it.)
+
+Theodore Ts'o. He gave me a good discussion of unicode and UTF and
+the like. He doesn't even remember writing me about it.
+
+Alan Cox. He has answered many questions about scheduling and wait
+queues and timers along with code fragments and so on. I just wish I
+understood it all totally. He has also helped immensely in moving
+this package toward inclusion in the standard kernel tree. (Maybe next
+release!)
+
+Martin Mares. He pointed me in the right direction to figuring out
+the colour attributes and other useful tidbits.
+
+Paul McDermott. He really is the catalyst for me to actually get
+this all working. Besides I like seeing him bounce around and get all
+excited every time I have something new working.
+
+John Covici, He was the first person to actually attempt writing
+another synthesizer driver for speakup. It was the Speakout driver so
+it was also the first serial driver.
+
+Brian Borowski, he was the first person to actually write a speakup
+function other than Andy and I.
+
+Jim Danley, he has more or less become my main man in helping test
+code, add new features, bounce ideas off and generally become a good
+friend.
+
+Matt Campbell, he basically rewrote the drivers to be able to include
+all synths in the kernel at the same time. The distribution
+maintainers appreciate him a lot as well.
+
+Gene Collins, he was very helpful debugging the current release prior
+to its public showing. He has also worked hard educating others on
+the list and writing the ALSA mini howto.
+
+I would also like to really thank the folks that handle the
+distribution packages. I and many other people would not find access
+to speakup nearly so convenient without their efforts. They include
+Bill Acker, Tom Moore, Matt Campbell, Joe Norton and Joshua Lambert.
+
+There are probably many more I am forgetting right now. I guess I'll
+just have to add you all later.
+
+
+Happy Hacking!
+
+ Kirk
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^keymap-tutorial.copy linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^keymap-tutorial.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^keymap-tutorial.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^Documentation^speakup^keymap-tutorial.copy 2000-06-22 09:45:07.000000000 -0700
@@ -0,0 +1,140 @@
+ Speakup Keymap Tutorial
+
+This is meant to be a basic tutorial on how to change the Linux keymap
+file to assign speakup review functions to desired keys. It is not
+intended to be a replacement for the loadkeys(8) or keymap(5) man
+pages.
+
+The basic lay-out of the keymap file is a series of lines with the
+following fields. The keyword keycode indicates this is the start of
+a new key assignment. It is then followed by a number which
+represents the actual key on the keyboard. That number is followed by
+the equals '=' operator and finally a list of keywords representing
+key names such as keypad5. Each line can have quite a few key
+functions on it. They are interpreted by loadkeys in order and
+assigned to key shift states depending on the order they are
+encountered. So for example, the first value after the equals is the
+keys unshifted state, while the second is the keys shifted state. If
+you wish to learn the order they are interpreted in read the
+loadkeys(8) and keymap(5) man pages.
+
+You can have subsequent lines which are indented and start with
+another keyword for the various shifted states. This way you can
+assign some of the states without having to specify them all in order
+up until you get to the one you want to assign.
+
+In speakup, we have assigned the insert key on the number pad to the
+altgr keyword. This is not required; you could choose any other
+shifted state keyword. We used altgr because it typically represents
+the right hand alt key. In Linux each shift key is separate and
+independent, so the left shift and the right shift keys are not
+necessarily the same. The altgr key is not really used for anything
+important, so we steel it.
+
+Here are the default key assignments for the number eight on the
+keypad:
+
+keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+As you can see, the first line starts with keycode followed by 72
+which is the actual number assigned to the key when the keyboard port
+is read. The KP_8 after the equal sign, is the symbolic representation
+of the function called when that key is hit.
+
+The second line is the same format except it starts with the keyword
+alt which is indented. That means that the function at the end of
+that line Ascii_8 is applied to the alt-shifted eight key.
+
+Now here are the speakup assignments for that key:
+
+keycode 72 = 0x0d0a
+ altgr keycode 72 = 0x0d20
+#keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+Notice that the only thing which has changed on the first line is the
+function called when the key is struck. It is a hexadecimal number
+identifying the function called in a look up table. It is not a
+symbolic representation yet because that means we need to change the
+loadkeys program to understand our symbolic names. We will do this in
+the future but for now it is more expedient to just use the table
+indices. You will find a table at the bottom of this document
+listing the review functions and their corresponding hex lookups.
+
+The 0x0d0a in the first line above is speakup's say line function.
+The second line ends with 0x0d20 which is speakup's read from top of
+screen to reading cursor line.
+
+The third line is the original key assignment commented out with a
+number-sign '#' at the beginning. I do that so I can easily find the
+keys I want to affect by symbolic name. Otherwise I would need to
+keep a look up table for all the keycodes. I recommend you do this as
+well or you'll be very sorry at some point in the future.
+
+The forth line is just the standard key assignment for the left hand
+alt key.
+
+Now let's say we want to design a different keyboard layout. I'll use
+an example for the JAWS style keypad because I've specifically been
+asked to help with that. JAWS uses the eight on the keypad to move up
+a line or the speakup function to read previous line. JAWS also uses
+the keypad_8 key in a shifted mode to read the current line. I
+apologize if these are not quite right. It has been a long time since
+I used JAWS. So we would have the following two lines:
+
+keycode 72 = 0x0d0b
+ altgr keycode 72 = 0x0d0a
+
+The hex value 0x0d0b in the first line is speakup's SAY_PREVIOUS_LINE
+function. The 0x0d0a in the second line is the same say_line function
+as we had earlier. So when the number eight is hit on the keypad
+speakup will read the previous line and when the number eight is
+shifted with the insert key on the keypad it will read the current
+line.
+
+As you can tell, it is not really very difficult to reassign the keys
+to different review functions.
+
+Once you have carefully edited the keymap file, called default.map in
+the speakup distribution, you copy it into the /etc/kbd directory.
+Make sure you back up the original default.map from that directory
+first, if there is one. Then you run loadkeys to load the new map
+into the kernel:
+
+loadkeys /etc/kbd/default.map
+
+If you wish to build your new keyboard lay-out into the kernel, after
+testing it, copy the default.map file into the drivers/char directory,
+with the name defkeymap.map, of your Linux source tree. Then rm the
+defkeymap.c file and recompile the kernel. Because there is no
+defkeymap.c `make' will rebuild it on the next compile.
+
+Here is a list of the available speakup review functions at this point
+in time.
+
+SAY_CHAR 0x0d04 /* say this character */
+SAY_PREV_CHAR 0x0d05 /* say character left of this char */
+SAY_NEXT_CHAR 0x0d06 /* say char right of this char */
+SAY_WORD 0x0d07 /* say this word under reading cursor */
+SAY_PREV_WORD 0x0d08
+SAY_NEXT_WORD 0x0d09
+SAY_LINE 0x0d0a /* say this line */
+SAY_PREV_LINE 0x0d0b /* say line above this line */
+SAY_NEXT_LINE 0x0d0c
+TOP_EDGE 0x0d0d /* move to top edge of screen */
+BOTTOM_EDGE 0x0d0e
+LEFT_EDGE 0x0d0f
+RIGHT_EDGE 0x0d10
+SAY_PHONETIC_CHAR 0x0d11 /* say this character phonetically */
+SPELL_WORD 0x0d12 /* spell this word letter by letter */
+SAY_SCREEN 0x0d14
+SAY_POSITION 0x0d1b
+SPEECH_OFF 0x0d1c
+SAY_ATTRIBUTES 0x0d1d
+SPEAKUP_PARKED 0x0d1e
+SAY_FROM_TOP 0x0d20
+SAY_TO_BOTTOM 0x0d21
+SAY_FROM_LEFT 0x0d22
+SAY_TO_RIGHT 0x0d23
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^MAINTAINERS.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^MAINTAINERS.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^MAINTAINERS.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^MAINTAINERS.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,16 @@
+--- /usr/src/linux/MAINTAINERS.orig Thu Aug 15 15:04:43 2002
++++ /usr/src/linux/MAINTAINERS Thu Aug 15 15:04:46 2002
+@@ -922,6 +922,13 @@
+ W: http://www.geog.ubc.ca/s_linux.html
+ S: Maintained
+
++SPEAKUP Console speech output
++P: Kirk Reiser
++M: kirk@braille.uwo.ca
++L: speakup@braille.uwo.ca
++W: http://www.linux-speakup.org
++S: Maintained
++
+ SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
+ P: Roger Wolff
+ M: R.E.Wolff@BitWizard.nl
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^arm^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^arm^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^arm^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^arm^config.in.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/arm/config.in.orig Thu Aug 15 15:04:43 2002
++++ /usr/src/linux/arch/arm/config.in Thu Aug 15 15:04:46 2002
+@@ -203,6 +203,7 @@
+ fi
+ bool 'Support Frame buffer devices' CONFIG_FB
+ source drivers/video/Config.in
++ source drivers/char/speakup/Config.in
+ endmenu
+ fi
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^i386^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^i386^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^i386^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^i386^config.in.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/i386/config.in.orig Thu Aug 15 15:04:43 2002
++++ /usr/src/linux/arch/i386/config.in Thu Aug 15 15:04:46 2002
+@@ -195,6 +195,7 @@
+ bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB
+ fi
+ source drivers/video/Config.in
++ source drivers/char/speakup/Config.in
+ endmenu
+ fi
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^m68k^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^m68k^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^m68k^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^m68k^config.in.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/m68k/config.in.orig Thu Aug 15 15:04:44 2002
++++ /usr/src/linux/arch/m68k/config.in Thu Aug 15 15:04:46 2002
+@@ -459,6 +459,7 @@
+ define_bool CONFIG_FB y
+ fi
+ source drivers/video/Config.in
++ source drivers/char/speakup/Config.in
+ endmenu
+ fi
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^mips^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^mips^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^mips^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^mips^config.in.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/mips/config.in.orig Thu Aug 15 15:04:44 2002
++++ /usr/src/linux/arch/mips/config.in Thu Aug 15 15:04:47 2002
+@@ -276,6 +276,7 @@
+ bool 'Support for frame buffer devices' CONFIG_FB
+ source drivers/video/Config.in
+ fi
++ source drivers/char/speakup/Config.in
+ endmenu
+ fi
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^ppc^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^ppc^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^ppc^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^ppc^config.in.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/ppc/config.in.orig Thu Aug 15 15:04:44 2002
++++ /usr/src/linux/arch/ppc/config.in Thu Aug 15 15:04:47 2002
+@@ -171,6 +171,7 @@
+ mainmenu_option next_comment
+ comment 'Console drivers'
+ source drivers/video/Config.in
++source drivers/char/speakup/Config.in
+ endmenu
+
+ source drivers/char/Config.in
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^sparc64^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^sparc64^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^sparc64^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^sparc64^config.in.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/sparc64/config.in.orig Thu Aug 15 15:04:44 2002
++++ /usr/src/linux/arch/sparc64/config.in Thu Aug 15 15:04:47 2002
+@@ -47,6 +47,7 @@
+ bool 'PROM console' CONFIG_PROM_CONSOLE
+ bool 'Support Frame buffer devices' CONFIG_FB
+ source drivers/video/Config.in
++source drivers/char/speakup/Config.in
+ endmenu
+
+ source drivers/sbus/char/Config.in
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^sparc^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^sparc^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^arch^sparc^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^arch^sparc^config.in.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/sparc/config.in.orig Thu Aug 15 15:04:44 2002
++++ /usr/src/linux/arch/sparc/config.in Thu Aug 15 15:04:47 2002
+@@ -48,6 +48,7 @@
+ bool 'PROM console' CONFIG_PROM_CONSOLE
+ bool 'Support Frame buffer devices' CONFIG_FB
+ source drivers/video/Config.in
++ source drivers/char/speakup/Config.in
+ endmenu
+
+ # Global things across all Sun machines.
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^Makefile.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^Makefile.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^Makefile.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^Makefile.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,44 @@
+--- /usr/src/linux/drivers/char/Makefile.orig Thu Aug 15 15:04:44 2002
++++ /usr/src/linux/drivers/char/Makefile Thu Aug 15 15:04:47 2002
+@@ -61,13 +61,21 @@
+ OX_OBJS += keyboard.o
+ ifneq ($(ARCH),m68k)
+ ifneq ($(ARCH),s390)
++ ifeq ($(CONFIG_SPEAKUP_KEYMAP),y)
++ O_OBJS += pc_keyb.o
++ else
+ O_OBJS += pc_keyb.o defkeymap.o
+ endif
+ endif
++ endif
+ endif
+ else
+ ifdef CONFIG_PCI
++ ifeq ($(CONFIG_SPEAKUP_KEYMAP),y)
++O_OBJS +=
++else
+ O_OBJS += defkeymap.o
++endif
+ OX_OBJS += keyboard.o
+ endif
+ endif
+@@ -719,6 +727,12 @@
+ endif
+ endif
+
++ifeq ($(CONFIG_SPEAKUP),y)
++ SUB_DIRS += speakup
++ O_OBJS += speakup/spk.o
++ ALL_SUB_DIRS += speakup
++endif
++
+ # remove objects from modular that are also built in
+ obj-m := $(filter-out $(obj-y), $(obj-m))
+
+@@ -742,5 +756,5 @@
+ consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h
+
+ defkeymap.c: defkeymap.map
+- loadkeys --mktable defkeymap.map > defkeymap.c
++ loadkeys --mktable $(KEYMAPFILE) > defkeymap.c
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^console.c.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^console.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^console.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^console.c.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,122 @@
+--- /usr/src/linux/drivers/char/console.c.orig Thu Aug 15 15:04:44 2002
++++ /usr/src/linux/drivers/char/console.c Thu Aug 15 15:04:47 2002
+@@ -101,6 +101,7 @@
+
+ #include "console_macros.h"
+
++#include
+
+ struct consw *conswitchp = NULL;
+
+@@ -143,6 +144,7 @@
+ static void set_cursor(int currcons);
+ static void hide_cursor(int currcons);
+
++
+ static int printable = 0; /* Is console ready for printing? */
+
+ int do_poke_blanked_console = 0;
+@@ -658,6 +660,7 @@
+ screenbuf = (unsigned short *) q;
+ kmalloced = 1;
+ vc_init(currcons, video_num_lines, video_num_columns, 1);
++ speakup_allocate(currcons); /* speakup needs more too. */
+ }
+ return 0;
+ }
+@@ -876,6 +879,7 @@
+ pos += video_size_row;
+ }
+ need_wrap = 0;
++ speakup_con_write(currcons, " \n", 2);
+ }
+
+ static void ri(int currcons)
+@@ -904,6 +908,7 @@
+ pos -= 2;
+ x--;
+ need_wrap = 0;
++ speakup_bs(currcons);
+ }
+ }
+
+@@ -1644,7 +1649,12 @@
+ if (par[0]) par[0]--;
+ gotoxay(currcons,x,par[0]);
+ return;
+- case 'H': case 'f':
++ case 'f':
++ if (par[0]) par[0]--;
++ if (par[1]) par[1]--;
++ gotoxay(currcons,par[1],par[0]);
++ return;
++ case 'H':
+ if (par[0]) par[0]--;
+ if (par[1]) par[1]--;
+ gotoxay(currcons,par[1],par[0]);
+@@ -1885,6 +1895,7 @@
+ if (vc_state == ESnormal && ok) {
+ /* Now try to find out how to display it */
+ tc = conv_uni_to_pc(vc_cons[currcons].d, tc);
++
+ if ( tc == -4 ) {
+ /* If we got -4 (not found) then see if we have
+ defined a replacement character (U+FFFD) */
+@@ -1910,6 +1921,7 @@
+ }
+ if (decim)
+ insert_char(currcons, 1);
++ speakup_con_write(currcons, (char *) &tc,1);
+ scr_writew(himask ?
+ ((attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+ (attr << 8) + tc,
+@@ -1931,6 +1943,7 @@
+ do_con_trol(tty, currcons, c);
+ }
+ FLUSH
++ speakup_con_update(currcons);
+ enable_bh(CONSOLE_BH);
+ return n;
+ #undef FLUSH
+@@ -1955,6 +1968,7 @@
+ /* we only changed when the console had already
+ been allocated - a new console is not created
+ in an interrupt routine */
++ speakup_con_update(want_console);
+ }
+ want_console = -1;
+ }
+@@ -2019,6 +2033,7 @@
+
+ /* Contrived structure to try to emulate original need_wrap behaviour
+ * Problems caused when we have need_wrap set on '\n' character */
++ speakup_con_write(currcons, b, count);
+ while (count--) {
+ c = *b++;
+ if (c == 10 || c == 13 || c == 8 || need_wrap) {
+@@ -2064,7 +2079,7 @@
+ }
+ set_cursor(currcons);
+ poke_blanked_console();
+-
++ speakup_con_update(currcons);
+ quit:
+ clear_bit(0, &printing);
+ }
+@@ -2224,6 +2239,7 @@
+ static void con_flush_chars(struct tty_struct *tty)
+ {
+ struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
++ /*char stc[2]; kirk*/
+
+ set_cursor(vt->vc_num);
+ }
+@@ -2367,6 +2383,8 @@
+ master_display_fg = vc_cons[currcons].d;
+ set_origin(currcons);
+ save_screen(currcons);
++ kmem_start = speakup_init(kmem_start, currcons);
++
+ gotoxy(currcons,x,y);
+ csi_J(currcons, 0);
+ update_screen(fg_console);
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^keyboard.c.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^keyboard.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^keyboard.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^keyboard.c.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,321 @@
+--- /usr/src/linux/drivers/char/keyboard.c.orig Thu Aug 15 15:04:45 2002
++++ /usr/src/linux/drivers/char/keyboard.c Thu Aug 15 15:04:47 2002
+@@ -1,3 +1,4 @@
++
+ /*
+ * linux/drivers/char/keyboard.c
+ *
+@@ -42,6 +43,9 @@
+ #include
+ #include
+ #include
++#include /* for mdelay() */
++
++#include
+
+ #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
+
+@@ -107,20 +111,21 @@
+ typedef void (*k_hand)(unsigned char value, char up_flag);
+ typedef void (k_handfn)(unsigned char value, char up_flag);
+
++
+ static k_handfn
+ do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
+- do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
+- do_ignore;
++ do_meta, do_ascii, do_lock, do_lowercase, do_slock,
++ do_spkup, do_dead2, do_ignore;
+
+-static k_hand key_handler[16] = {
++static k_hand key_handler[17] = {
+ do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
+- do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
+- do_ignore, do_ignore
++ do_meta, do_ascii, do_lock, do_lowercase, do_slock,
++ do_spkup, do_dead2, do_ignore, do_ignore
+ };
+
+ /* Key types processed even in raw modes */
+
+-#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT))
++#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) | (1 << KT_SPKUP))
+
+ typedef void (*void_fnp)(void);
+ typedef void (void_fn)(void);
+@@ -144,7 +149,7 @@
+ 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
+ NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
+ 255, NR_ASCII - 1, NR_LOCK - 1, 255,
+- NR_LOCK - 1, 255
++ NR_LOCK - 1, NR_SPKUP - 1, 255, 255
+ };
+
+ const int NR_TYPES = SIZE(max_vals);
+@@ -262,6 +267,7 @@
+ raw_mode = 1; /* Most key classes will be ignored */
+ }
+
++
+ /*
+ * Small change in philosophy: earlier we defined repetition by
+ * rep = keycode == prev_keycode;
+@@ -301,6 +307,9 @@
+ keysym = key_map[keycode];
+ }
+ }
++ if (!up_flag)
++ speakup_reset(fg_console, type);
++
+ (*key_handler[type])(keysym & 0xff, up_flag);
+ if (type != KT_SLOCK)
+ kbd->slockstate = 0;
+@@ -531,6 +540,153 @@
+ compute_shiftstate();
+ }
+
++#ifdef CONFIG_SPEAKUP /* console speech for linux */
++static void do_spkup(unsigned char value, char up_flag)
++{
++ /* some data for pad_num */
++static const char *pad_chars = "0123456789+-*/.\015";
++
++ speakup_savekey(0); /* clear! brzzzot */
++ if (up_flag)
++ return; /* do nothing on key release */
++
++ /* check numlock is on or not, if not normal reviewkey, if yes */
++ if (spkup_num_lock_on) {
++ if (value>16)
++ return;
++ put_queue(pad_chars[value]);
++ if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd,VC_CRLF))
++ put_queue(10);
++ return;
++ }
++
++ if (value == SPEECH_KILL) {
++ speakup_kill(fg_console); return;
++ }
++
++ if (speakup_console[fg_console]->shut_up & 0x40) return;
++
++ switch(value) {
++ case (QUICK_QUIET):
++ /* -x- */
++ spkup_write("\x18",1);
++ return;
++ case (LINE_QUIET):
++ return;
++ case (FULL_QUIET):
++ spkup_write("\x18",1);
++ speakup_shut_up(fg_console);
++ return;
++ case (SAY_CHAR):
++ say_curr_char(fg_console);
++ return;
++ case (SAY_PREV_CHAR):
++ say_prev_char(fg_console);
++ return;
++ case (SAY_NEXT_CHAR):
++ say_next_char(fg_console);
++ return;
++ case (SAY_WORD):
++ say_curr_word(fg_console);
++ return;
++ case (SAY_PREV_WORD):
++ say_prev_word(fg_console);
++ return;
++ case (SAY_NEXT_WORD):
++ say_next_word(fg_console);
++ return;
++ case (SAY_LINE):
++ say_curr_line(fg_console);
++ return;
++ case (SAY_PREV_LINE):
++ say_prev_line(fg_console);
++ return;
++ case (SAY_NEXT_LINE):
++ say_next_line(fg_console);
++ return;
++ case (TOP_EDGE):
++ top_edge(fg_console);
++ return;
++ case (BOTTOM_EDGE):
++ bottom_edge(fg_console);
++ return;
++ case (LEFT_EDGE):
++ left_edge(fg_console);
++ return;
++ case (RIGHT_EDGE):
++ right_edge(fg_console);
++ return;
++ case (SAY_PHONETIC_CHAR):
++ say_phonetic_char(fg_console);
++ return;
++ case (SPELL_WORD):
++ spell_word(fg_console);
++ return;
++ case (SPELL_PHONETIC_WORD):
++ return;
++ case (SAY_SCREEN):
++ say_screen(fg_console);
++ return;
++ case (SAY_WINDOW):
++ return;
++ case (SET_SPEED):
++ return;
++ case (SET_PITCH):
++ return;
++ case (SET_PUNCTUATION):
++ return;
++ case (SET_VOICE):
++ return;
++ case (SET_TONE):
++ return;
++ case (SAY_POSITION):
++ say_position(fg_console);
++ return;
++ case (SAY_CHAR_NUM):
++ say_char_num(fg_console);
++ return;
++ case (SPEECH_OFF):
++ speakup_off(fg_console);
++ return;
++ case (SPEAKUP_CURSORING):
++ speakup_cursoring(fg_console);
++ return;
++ case (SPEAKUP_CUT):
++ speakup_cut(fg_console, tty);
++ return;
++ case (SPEAKUP_PASTE):
++ speakup_paste(tty);
++ return;
++ case (SAY_ATTRIBUTES):
++ say_attributes(fg_console);
++ return;
++ case (SPEAKUP_PARKED):
++ speakup_parked(fg_console);
++ return;
++ case (SAY_FROM_TOP):
++ say_from_top(fg_console);
++ return;
++ case (SAY_TO_BOTTOM):
++ say_to_bottom(fg_console);
++ return;
++ case (SAY_FROM_LEFT):
++ say_from_left(fg_console);
++ return;
++ case (SAY_TO_RIGHT):
++ say_to_right(fg_console);
++ return;
++ case (END_OF_LINE): /* Move to end of line. */
++ end_of_line(fg_console);
++ return;
++ default:
++ spkup_write("SpeakUp: Invalid command",25);
++ return;
++ }
++}
++#else
++static void do_spkup(unsigned char value, char up_flag) {};
++#endif /* console speech for linux */
++
+ static void do_spec(unsigned char value, char up_flag)
+ {
+ if (up_flag)
+@@ -541,6 +697,7 @@
+ !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
+ return;
+ spec_fn_table[value]();
++ if (value > 1) speakup_control(fg_console, kbd, value);
+ }
+
+ static void do_lowercase(unsigned char value, char up_flag)
+@@ -554,7 +711,7 @@
+ return; /* no action, if this is a key release */
+
+ if (diacr)
+- value = handle_diacr(value);
++ if ((value = handle_diacr(value)) == 0xff) return;
+
+ if (dead_key_next) {
+ dead_key_next = 0;
+@@ -562,6 +719,7 @@
+ return;
+ }
+
++ speakup_savekey(value);
+ put_queue(value);
+ }
+
+@@ -571,8 +729,10 @@
+ #define A_TILDE '~'
+ #define A_DIAER '"'
+ #define A_CEDIL ','
++#define SPEAKUP_DIACR '$'
++
+ static unsigned char ret_diacr[NR_DEAD] =
+- {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };
++ {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL, SPEAKUP_DIACR};
+
+ /* Obsolete - for backwards compatibility only */
+ static void do_dead(unsigned char value, char up_flag)
+@@ -591,6 +751,11 @@
+ if (up_flag)
+ return;
+
++ if (value == SPEAKUP_DIACR) { /*beep to alert that speakup's waiting */
++ kd_mksound(1250,10);
++ mdelay(100);
++ kd_mksound(1500,15);
++ }
+ diacr = (diacr ? handle_diacr(value) : value);
+ }
+
+@@ -607,6 +772,12 @@
+ int d = diacr;
+ int i;
+
++ if (d == '$') {
++ if (speakup_diacr(ch,fg_console))
++ diacr = 0;
++ return 0xff;
++ }
++
+ diacr = 0;
+
+ for (i = 0; i < accent_table_size; i++) {
+@@ -660,7 +831,7 @@
+ do_fn(KVAL(K_REMOVE), 0);
+ return;
+ case KVAL(K_P0):
+- do_fn(KVAL(K_INSERT), 0);
++ do_fn(KVAL(K_INSERT), 0);
+ return;
+ case KVAL(K_P1):
+ do_fn(KVAL(K_SELECT), 0);
+@@ -720,6 +891,10 @@
+ clr_vc_kbd_led(kbd, VC_CAPSLOCK);
+ }
+
++ /* shift = 0, altgr = 1, ctrl=2, alt=3 */
++ if (!up_flag)
++ speakup_control(fg_console, kbd, value);
++
+ if (up_flag) {
+ /* handle the case that two shift or control
+ keys are depressed simultaneously */
+@@ -808,6 +983,7 @@
+ if (up_flag || rep)
+ return;
+ chg_vc_kbd_lock(kbd, value);
++
+ }
+
+ static void do_slock(unsigned char value, char up_flag)
+@@ -934,3 +1110,4 @@
+ mark_bh(KEYBOARD_BH);
+ return 0;
+ }
++
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^selection.c.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^selection.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^selection.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^drivers^char^selection.c.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,14 @@
+--- /usr/src/linux/drivers/char/selection.c.orig Thu Aug 15 15:04:45 2002
++++ /usr/src/linux/drivers/char/selection.c Thu Aug 15 15:04:47 2002
+@@ -259,7 +259,10 @@
+ sel_end = new_sel_end;
+
+ /* Allocate a new buffer before freeing the old one ... */
+- bp = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL);
++ if (user)
++ bp = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL);
++ else
++ bp = kmalloc((sel_end-sel_start)/2+1, GFP_ATOMIC);
+ if (!bp) {
+ printk(KERN_WARNING "selection: kmalloc() failed\n");
+ clear_selection();
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^fs^proc^root.c.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^fs^proc^root.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^fs^proc^root.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^fs^proc^root.c.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,12 @@
+--- /usr/src/linux/fs/proc/root.c.orig Thu Aug 15 15:04:45 2002
++++ /usr/src/linux/fs/proc/root.c Thu Aug 15 15:04:47 2002
+@@ -744,6 +744,9 @@
+ }
+
+ proc_tty_init();
++#ifdef CONFIG_SPEAKUP /* console speech output */
++ proc_speakup_init();
++#endif /* speakup */
+ #ifdef __powerpc__
+ proc_register(&proc_root, &proc_root_ppc_htab);
+ #endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^keyboard.h.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^keyboard.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^keyboard.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^keyboard.h.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,83 @@
+--- /usr/src/linux/include/linux/keyboard.h.orig Thu Aug 15 15:04:45 2002
++++ /usr/src/linux/include/linux/keyboard.h Thu Aug 15 18:47:04 2002
+@@ -43,6 +43,9 @@
+ #define KT_ASCII 9
+ #define KT_LOCK 10
+ #define KT_SLOCK 12
++#ifdef CONFIG_SPEAKUP /* console speech output */
++#define KT_SPKUP 13
++#endif /* speakup */
+
+ #define K(t,v) (((t)<<8)|(v))
+ #define KTYP(x) ((x) >> 8)
+@@ -360,8 +363,16 @@
+ #define K_DDIERE K(KT_DEAD,4)
+ #define K_DCEDIL K(KT_DEAD,5)
+
++#ifdef CONFIG_SPEAKUP
++/* adjust diacriticals for goto keyboard function */
++#define K_DSPKUP K(KT_DEAD,6)
++#define NR_DEAD 7
++
++#else
+ #define NR_DEAD 6
+
++#endif /* config_speakup */
++
+ #define K_DOWN K(KT_CUR,0)
+ #define K_LEFT K(KT_CUR,1)
+ #define K_RIGHT K(KT_CUR,2)
+@@ -425,6 +436,53 @@
+ #define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR)
+
+ #define NR_LOCK 8
++
++#ifdef CONFIG_SPEAKUP /* console speech output */
++#include
++
++#define K_QUICK_QUIET K(KT_SPKUP,QUICK_QUIET)
++#define K_LINE_QUIET K(KT_SPKUP,LINE_QUIET)
++#define K_FULL_QUIET K(KT_SPKUP,FULL_QUIET)
++#define K_SAY_CHAR K(KT_SPKUP,SAY_CHAR)
++#define K_SAY_PREV_CHAR K(KT_SPKUP,SAY_PREV_CHAR)
++#define K_SAY_NEXT_CHAR K(KT_SPKUP,SAY_NEXT_CHAR)
++#define K_SAY_WORD K(KT_SPKUP,SAY_WORD)
++#define K_SAY_PREV_WORD K(KT_SPKUP,SAY_PREV_WORD)
++#define K_SAY_NEXT_WORD K(KT_SPKUP,SAY_NEXT_WORD)
++#define K_SAY_LINE K(KT_SPKUP,SAY_LINE)
++#define K_SAY_PREV_LINE K(KT_SPKUP,SAY_PREV_LINE)
++#define K_SAY_NEXT_LINE K(KT_SPKUP,SAY_NEXT_LINE)
++#define K_TOP_EDGE K(KT_SPKUP,TOP_EDGE)
++#define K_BOTTOM_EDGE K(KT_SPKUP,BOTTOM_EDGE)
++#define K_LEFT_EDGE K(KT_SPKUP,LEFT_EDGE)
++#define K_RIGHT_EDGE K(KT_SPKUP,RIGHT_EDGE )
++#define K_SAY_PHONETIC_CHAR K(KT_SPKUP,SAY_PHONETIC_CHAR)
++#define K_SPELL_WORD K(KT_SPKUP,SPELL_WORD)
++#define K_SPELL_PHONETIC_WORD K(KT_SPKUP,SPELL_PHONETIC_WORD)
++#define K_SAY_SCREEN K(KT_SPKUP,SAY_SCREEN)
++#define K_SAY_WINDOW K(KT_SPKUP,SAY_WINDOW)
++#define K_SET_SPEED K(KT_SPKUP,SET_SPEED)
++#define K_SET_PITCH K(KT_SPKUP,SET_PITCH)
++#define K_SET_PUNCTUATION K(KT_SPKUP,SET_PUNCTUATION)
++#define K_SET_VOICE K(KT_SPKUP,SET_VOICE)
++#define K_SET_TONE K(KT_SPKUP,SET_TONE)
++#define K_SAY_POSITION K(KT_SPKUP,SAY_POSITION)
++#define K_SPEECH_OFF K(KT_SPKUP,SPEECH_OFF)
++#define K_SAY_ATTRIBUTES K(KT_SPKUP,SAY_ATTRIBUTES)
++#define K_SPEAKUP_PARKED K(KT_SPKUP,SPEAKUP_PARKED)
++#define K_INS_TOGGLE K(KT_SPKUP,INS_TOGGLE)
++#define K_SAY_FROM_TOP K(KT_SPKUP,SAY_FROM_TOP)
++#define K_SAY_TO_BOTTOM K(KT_SPKUP,SAY_TO_BOTTOM)
++#define K_SAY_FROM_LEFT K(KT_SPKUP,SAY_FROM_LEFT)
++#define K_SAY_TO_RIGHT K(KT_SPKUP,SAY_TO_RIGHT)
++#define K_SAY_CHAR_NUM K(KT_SPKUP,SAY_CHAR_NUM)
++#define K_SPEECH_KILL K(KT_SPKUP,SPEECH_KILL)
++#define K_SPEAKUP_CURSORING K(KT_SPKUP,SPEAKUP_CURSORING)
++#define K_SPEAKUP_CUT K(KT_SPKUP,SPEAKUP_CUT)
++#define K_SPEAKUP_PASTE K(KT_SPKUP,SPEAKUP_PASTE)
++
++#define NR_SPKUP 0x2a
++#endif /* speakup */
+
+ #define MAX_DIACR 256
+ #endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^miscdevice.h.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^miscdevice.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^miscdevice.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^miscdevice.h.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,14 @@
+--- /usr/src/linux/include/linux/miscdevice.h.orig Thu Aug 15 15:04:45 2002
++++ /usr/src/linux/include/linux/miscdevice.h Thu Aug 15 17:58:13 2002
+@@ -11,6 +11,11 @@
+ #define APOLLO_MOUSE_MINOR 7
+ #define PC110PAD_MINOR 9
+ #define MAC_MOUSE_MINOR 10
++
++#ifdef CONFIG_SPEAKUP
++#define SYNTH_MINOR 25
++#endif
++
+ #define WATCHDOG_MINOR 130 /* Watchdog timer */
+ #define TEMP_MINOR 131 /* Temperature Sensor */
+ #define RTC_MINOR 135
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^proc_fs.h.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^proc_fs.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^proc_fs.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^proc_fs.h.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,13 @@
+--- /usr/src/linux/include/linux/proc_fs.h.orig Thu Aug 15 15:04:45 2002
++++ /usr/src/linux/include/linux/proc_fs.h Thu Aug 15 17:57:33 2002
+@@ -450,6 +450,10 @@
+ extern void proc_tty_register_driver(struct tty_driver *driver);
+ extern void proc_tty_unregister_driver(struct tty_driver *driver);
+
++#ifdef CONFIG_SPEAKUP /* console speech output */
++extern void proc_speakup_init(void);
++#endif /* speakup */
++
+ /*
+ * proc_devtree.c
+ */
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^speakup.h.copy linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^speakup.h.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^speakup.h.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^include^linux^speakup.h.copy 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,229 @@
+#ifndef __SPEAKUP_H
+#define __SPEAKUP_H
+
+#include
+struct serial_state;
+struct kbd_struct;
+#define QUICK_QUIET 0x40 /* flush buffer and shut up immediately! */
+#define LINE_QUIET 0x41 /* flush buffer up to next NULL/cr and continue */
+
+/* start f key pad keys */
+#define SAY_NOTHING 0x00 /* this is a dummy command for speakup */
+#define SAY_PREV_CHAR 0x01 /* say character left of this char, LINE_QUIET 0x01 */
+#define SAY_CHAR 0x02 /* say this character */
+#define SAY_NEXT_CHAR 0x03 /* say char right of this char */
+#define SAY_PREV_WORD 0x04
+#define SAY_WORD 0x05 /* say this word under reading cursor */
+#define SAY_NEXT_WORD 0x06
+#define SAY_PREV_LINE 0x07 /* say line above this line */
+#define SAY_LINE 0x08 /* say this line */
+#define SAY_NEXT_LINE 0x09
+#define SAY_SCREEN 0x0a /* + */
+#define SPEAKUP_PARKED 0x0b /* - */
+#define SPEAKUP_CURSORING 0x0c /* * */
+#define SPEAKUP_CUT 0x0d /* / */
+#define SAY_POSITION 0x0e /* dot */
+#define FULL_QUIET 0x0f /* enter */
+/* end of key pad keys */
+
+#define RIGHT_EDGE 0x10
+
+#define SAY_PHONETIC_CHAR 0x11 /* say this character phonetically */
+#define SPELL_WORD 0x12 /* spell this word letter by letter */
+#define SPELL_PHONETIC_WORD 0x13
+#define TOP_EDGE 0x14 /* move to top edge of screen */
+#define SAY_WINDOW 0x15
+#define SET_SPEED 0x16
+#define SET_PITCH 0x17
+#define SET_PUNCTUATION 0x18
+#define SET_VOICE 0x19
+#define SET_TONE 0x1a
+#define BOTTOM_EDGE 0x1b
+#define SPEECH_OFF 0x1c
+#define SAY_ATTRIBUTES 0x1d
+#define LEFT_EDGE 0x1e
+#define INS_TOGGLE 0x1f
+#define SAY_FROM_TOP 0x20
+#define SAY_TO_BOTTOM 0x21
+#define SAY_FROM_LEFT 0x22
+#define SAY_TO_RIGHT 0x23
+#define SAY_CHAR_NUM 0x24
+#define SPEECH_KILL 0x25
+#define SPEAKUP_PASTE 0x28
+#define END_OF_LINE 0x29 // mv to last char on line.
+
+/* our basic punctuation levels as array indecies */
+#define NONE 0x30 /* no punctuation spoken */
+#define SOME 0x31 /* some punctuation spoken */
+#define MOST 0x32 /* most punctuation spoken */
+#define ALL 0x33 /* you guessed it. */
+
+/* let's develop a structure for keeping our goodies in. */
+struct spk_t {
+ unsigned char reading_attr;
+ unsigned char old_attr;
+ char parked;
+ char shut_up;
+ char sound;
+ unsigned long reading_x, cursor_x, old_cursor_x, mark_x;
+ unsigned long reading_y, cursor_y, old_cursor_y, mark_y;
+ unsigned long reading_pos, cursor_pos, old_cursor_pos;
+};
+
+/* now some defines to make these easier to use. */
+#define spk_shut_up speakup_console[currcons]->shut_up
+#define spk_killed (speakup_console[currcons]->shut_up & 0x40)
+#define spk_x speakup_console[currcons]->reading_x
+#define spk_cx speakup_console[currcons]->cursor_x
+#define spk_o_cx speakup_console[currcons]->old_cursor_x
+#define spk_mx speakup_console[currcons]->mark_x
+#define spk_y speakup_console[currcons]->reading_y
+#define spk_cy speakup_console[currcons]->cursor_y
+#define spk_o_cy speakup_console[currcons]->old_cursor_y
+#define spk_my speakup_console[currcons]->mark_y
+#define spk_pos (speakup_console[currcons]->reading_pos)
+#define spk_cp speakup_console[currcons]->cursor_pos
+#define spk_o_cp speakup_console[currcons]->old_cursor_pos
+#define spk_attr speakup_console[currcons]->reading_attr
+#define spk_old_attr speakup_console[currcons]->old_attr
+#define spk_parked speakup_console[currcons]->parked
+#define spk_sound speakup_console[currcons]->sound
+
+/* how about some prototypes! */
+extern void speakup_shut_up(unsigned int);
+extern void say_attributes(int);
+extern void say_curr_char(unsigned int);
+extern void say_phonetic_char(unsigned int);
+extern void say_prev_char(unsigned int);
+extern void say_next_char(unsigned int);
+extern void say_curr_word(unsigned int);
+extern void say_prev_word(unsigned int);
+extern void say_next_word(unsigned int);
+extern void spell_word(unsigned int);
+extern void say_curr_line(unsigned int);
+extern void say_prev_line(unsigned int);
+extern void say_next_line(unsigned int);
+extern void say_screen(unsigned int);
+extern void top_edge(unsigned int);
+extern void bottom_edge(unsigned int);
+extern void left_edge(unsigned int);
+extern void right_edge(unsigned int);
+extern void say_position(unsigned int);
+extern void say_char_num(unsigned int);
+extern void speakup_off(unsigned int);
+extern void speakup_kill(unsigned int);
+extern void say_from_top(unsigned int);
+extern void say_to_bottom(unsigned int);
+extern void say_from_left(unsigned int);
+extern void say_to_right(unsigned int);
+extern void speakup_status(unsigned int);
+extern void function_announce(unsigned int);
+extern void speakup_open(unsigned int);
+extern void speakup_date(unsigned int);
+extern void speakup_check(unsigned int);
+extern int spkup_write(const char *, int);
+extern void speakup_parked(unsigned int);
+extern void speakup_cursoring(unsigned int);
+extern void speakup_cut(unsigned int, struct tty_struct *);
+extern void speakup_paste(struct tty_struct *);
+extern void spk_skip(unsigned short);
+
+/* Speakup variable structure and definitions */
+#define HARD_DIRECT 0x01 /* a variable that is immediately sent to the
+ hardware synth */
+#define SOFT_DIRECT 0x02 // as above, but sent to speakup
+#define NUMERIC 0x04 /* ASCII-represented numerical value
+ currently requires USE_RANGE to be set */
+#define USE_RANGE 0x08 // all values in ASCII range from valid are accepted
+#define BUILDER 0x10 // variable must be built into the reset string
+#define NO_USER 0x20 // variable is not allowed to be set by the user
+#define ALLOW_BLANK 0x40 // alias-only flag to allow a blank parameter
+#define MULTI_SET 0x80 // ASCII string of chars, each must be one of the valid set
+#define END_VARS { NULL, NULL, NULL, 0, NULL }
+#define TOGGLE "0,1"
+
+struct spk_variable {
+ char *id; // command name
+ char *param; // value of the parameter to the command
+ char *build; /* a string, describing how to construct the
+ string sent to the synth, with the character '_' to be filled in with
+ the parameter. eg. "\x01_P" will convert to "\x01+30P", if param is
+ "+30" */
+ int flags; // see #defines below
+ char *valid; /* If the flag USE_RANGE is given, valid is a range
+ described by "lowval,highval". For example, "0,20" is the range 0-20.
+ If USE_RANGE is not given, valid is a NULL terminated set of valid
+ values for param. eg. "aeiou". Wildcard "*" matches anything. */
+};
+
+/* speakup_drvcommon.c */
+struct spk_synth {
+ const char *name;
+ const char *version;
+ const char *proc_name;
+ const char *init;
+ const char *reinit;
+ unsigned short delay_time;
+ unsigned short trigger_time;
+ unsigned char jiffy_delta;
+ unsigned short full_time;
+ struct spk_variable *vars;
+ char **config;
+ long config_map;
+ int (*probe)(void);
+ void (*catch_up)(unsigned long data);
+ void (*write)(char c);
+ int (*is_alive)(void);
+};
+
+extern struct spk_synth *synth;
+extern int synth_request_region(unsigned long, unsigned long);
+extern int synth_release_region(unsigned long, unsigned long);
+extern unsigned char synth_jiffy_delta;
+extern int synth_port_tts;
+extern volatile int synth_timer_active;
+#if (LINUX_VERSION_CODE < 0x20300) /* is it a 2.2.x kernel? */
+extern struct wait_queue *synth_sleeping_list;
+#else /* nope it's 2.3.x */
+extern DECLARE_WAIT_QUEUE_HEAD (synth_sleeping_list);
+#endif
+extern struct timer_list synth_timer;
+extern unsigned short synth_delay_time; /* time to schedule handler */
+extern unsigned short synth_trigger_time;
+extern unsigned short synth_full_time;
+extern char synth_buffering; /* flag to indicate we're buffering */
+extern unsigned char synth_buffer[]; /* guess what this is for! */
+extern unsigned short synth_end_of_buffer;
+extern volatile unsigned short synth_queued_bytes, synth_sent_bytes;
+extern unsigned short spkup_num_lock_on; /* a variable used by keyboard.c */
+
+extern void initialize_uart(struct serial_state *);
+extern void synth_delay(int ms);
+extern void synth_stop_timer(void);
+extern void synth_buffer_add(char ch);
+extern void synth_write(const char *buf, size_t count);
+
+#ifdef CONFIG_SPEAKUP
+extern struct spk_t *speakup_console[];
+extern void speakup_allocate(int);
+extern void speakup_bs(int);
+extern void speakup_con_write(int, const char *, int);
+extern void speakup_con_update(int);
+extern unsigned long speakup_init(unsigned long, unsigned int);
+extern void speakup_reset(int, unsigned char);
+extern void speakup_control(int, struct kbd_struct *, int);
+extern int speakup_diacr(unsigned char,unsigned int);
+extern void speakup_savekey(unsigned char);
+#else
+static inline void speakup_allocate(int currcons) {};
+static inline void speakup_bs(int currcons) {};
+static inline void speakup_con_write(int currcons, const char *str, int len) {};
+static inline void speakup_con_update(int currcons) {};
+static inline unsigned long speakup_init(unsigned long mem, unsigned int currcons) {return mem;};
+static inline void speakup_reset(int fg_console, unsigned char type) {};
+static inline void speakup_control(int fg_console, struct kbd_struct * kbd, int value) {};
+static inline int speakup_diacr(unsigned char ch, unsigned int fg_console) {return 0;};
+static inline void speakup_savekey(unsigned char ch) {};
+#endif
+#endif
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^init^main.c.patch linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^init^main.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v22/^usr^src^linux^init^main.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v22/^usr^src^linux^init^main.c.patch 2002-08-15 17:00:30.000000000 -0700
@@ -0,0 +1,46 @@
+--- /usr/src/linux/init/main.c.orig Thu Aug 15 15:04:46 2002
++++ /usr/src/linux/init/main.c Thu Aug 15 15:04:47 2002
+@@ -401,6 +401,12 @@
+ extern void dquot_init_hash(void);
+ #endif
+
++#ifdef CONFIG_SPEAKUP
++extern void spk_setup(char *str, int *ints);
++extern void spk_ser_setup(char *str, int *ints);
++extern void spk_synth_setup(char *str, int *ints);
++#endif
++
+ #ifdef CONFIG_MD_BOOT
+ extern void md_setup(char *str,int *ints) __init;
+ #endif
+@@ -432,6 +438,10 @@
+ #endif
+ #endif
+
++#ifdef CONFIG_SPEAKUP
++extern int synth_port_tts; /* forced address of text-to-speech port */
++#endif
++
+ int root_mountflags = MS_RDONLY;
+ char *execute_command = NULL;
+
+@@ -1024,6 +1034,11 @@
+ #ifdef CONFIG_BLK_CPQ_DA
+ { "smart2=", cpqarray_setup },
+ #endif
++#ifdef CONFIG_SPEAKUP
++ { "speakup_port=", spk_setup },
++ { "speakup_ser=", spk_ser_setup },
++ { "speakup_synth=", spk_synth_setup },
++#endif
+ { 0, 0 }
+ };
+
+@@ -1075,7 +1090,6 @@
+ #endif
+ { 0, 0 }
+ };
+-
+
+ #ifdef CONFIG_BLK_DEV_RAM
+ static void __init ramdisk_start_setup(char *str, int *ints)
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/CVS/Entries linux-2.4.30/drivers/char/speakup/diff-v24/CVS/Entries
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/CVS/Entries 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/CVS/Entries 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1,25 @@
+/Documentation^Configure.help.patch/1.38/Tue Apr 19 16:26:22 2005//
+/Documentation^speakup^DefaultKeyAssignments.copy/1.1/Tue May 13 01:28:14 2003//
+/Documentation^speakup^INSTALLATION.copy/1.1/Tue May 13 01:28:14 2003//
+/Documentation^speakup^README.copy/1.1/Tue May 13 01:28:14 2003//
+/Documentation^speakup^keymap-tutorial.copy/1.1/Tue May 13 01:28:14 2003//
+/Documentation^speakup^spkguide.txt.copy/1.1/Thu Apr 7 19:57:32 2005//
+/arch^alpha^config.in.patch/1.38/Tue Apr 19 16:26:22 2005//
+/arch^arm^config.in.patch/1.38/Tue Apr 19 16:26:22 2005//
+/arch^i386^config.in.patch/1.38/Tue Apr 19 16:26:22 2005//
+/arch^m68k^config.in.patch/1.38/Tue Apr 19 16:26:22 2005//
+/arch^mips^config-shared.in.patch/1.38/Tue Apr 19 16:26:22 2005//
+/arch^ppc^config.in.patch/1.38/Tue Apr 19 16:26:22 2005//
+/arch^sparc64^config.in.patch/1.38/Tue Apr 19 16:26:22 2005//
+/arch^sparc^config.in.patch/1.38/Tue Apr 19 16:26:22 2005//
+/drivers^char^Makefile.patch/1.39/Tue Apr 19 16:26:22 2005//
+/drivers^char^console.c.patch/1.39/Tue Apr 19 16:26:22 2005//
+/drivers^char^consolemap.c.patch/1.5/Tue Apr 19 16:26:22 2005//
+/drivers^char^keyboard.c.patch/1.39/Tue Apr 19 16:26:22 2005//
+/drivers^char^speakup^speakup.c.copy/1.2/Tue Apr 19 18:37:27 2005//
+/drivers^char^vt.c.patch/1.27/Tue Apr 19 16:26:22 2005//
+/fs^proc^root.c.patch/1.38/Tue Apr 19 16:26:22 2005//
+/include^linux^keyboard.h.patch/1.38/Tue Apr 19 16:26:22 2005//
+/include^linux^proc_fs.h.patch/1.39/Tue Apr 19 16:26:22 2005//
+/include^linux^speakup.h.copy/1.5/Thu Jun 12 18:30:01 2003//
+D
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/CVS/Repository linux-2.4.30/drivers/char/speakup/diff-v24/CVS/Repository
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/CVS/Repository 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/CVS/Repository 2005-05-01 19:02:57.000000000 -0700
@@ -0,0 +1 @@
+speakup/diff-v24
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/CVS/Root linux-2.4.30/drivers/char/speakup/diff-v24/CVS/Root
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/CVS/Root 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/CVS/Root 2005-05-01 19:02:57.000000000 -0700
@@ -0,0 +1 @@
+:pserver:anonymous@bumpy.braille.uwo.ca:/usr/src/CVS
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^Configure.help.patch linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^Configure.help.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^Configure.help.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^Configure.help.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,145 @@
+--- /usr/src/linux-2.4.30/Documentation/Configure.help.orig 2005-04-19 09:48:50.000000000 -0400
++++ Documentation/Configure.help 2005-04-19 09:48:51.000000000 -0400
+@@ -20061,7 +20061,141 @@
+ determined automatically, so you need to specify it here ONLY if
+ running a DEC Alpha, otherwise this setting has no effect.
+
+-Double Talk PC internal speech card support
++Speakup console speech output for Linux
++CONFIG_SPEAKUP
++ Choosing this Option will include support for console speech output.
++
++ Speakup provides access to Linux for the visually impaired community.
++ It does this by sending console output to a number of different
++ hardware speech synthesizers. It provides access to Linux by Making
++ screen review functions available such as are used in comercial screen
++ review packages for the MSDOS and MSWINDOWS world.
++
++ The drivers supplied under this option are not standard devices in the
++ /dev/ sence of the meaning. They can be thought of as a video card
++ for the blind. They are used by speakup and only speakup.
++
++ For more information about speakup and its drivers check out
++ http://www.linux-speakup.org, or read the Documentation in
++ linux/Documentation/speakup.
++
++ The currently supported synthesizers are:
++ Accent PC internal synthesizer.
++ Accent SA external Accent synthesizer.
++ Apollo II external synthesizer.
++ Audapter external synthesizer.
++ Braille 'N Speak external synthesizer.
++ Dectalk Express and external synthesizers.
++ Dectalk PC internal synthesizer (module only)
++ DoubleTalk PC Internal synthesizer,
++ LiteTalk/DoubleTalk-LT external serial synthesizers,
++ Speakout external synthesizer,
++ Transport external synthesizer.
++
++ If you do not have one of these synths, say 'N' to this option.
++
++
++ If you wish to load speakup or any of it's synthasizers as modules
++ choose 'm' at any or all of the speakup options. The synth driver
++ can then be loaded with modprobe speakup_synthname where synthname
++ is any of the above synthasizers.
++
++Default synthesizer for Speakup
++CONFIG_SPEAKUP_DEFAULT
++ This option specifies which synthesizer Speakup should use by
++ default at boot time.
++ Valid values are: none, acntpc, acntsa, apollo, audptr, bns, decext,
++ dectlk, decpc, dtlk, ltlk, spkout, txprt
++
++ You can choose an alternatively compiled-in synthesizer at boot time
++ by using the speakup_synth kernel command line option,
++ I.E. speakup_synth=dtlk.
++
++Use Speakup keymap by default
++CONFIG_SPEAKUP_KEYMAP
++ If this option is enabled, then a modified US keymap which includes
++ Speakup's screen review commands will be used by default.
++
++DoubleTalk driver for speakup.
++CONFIG_SPEAKUP_DTLK
++ The DoubleTalk synthesizer is made by RC Systems. It is an internal
++ ISA card which uses no interrupts. Do not confuse this driver with
++ the standard DoubleTalk driver included in the kernel.
++
++ If you don't have a DoubleTalk card say 'N' here.
++
++LiteTalk/DoubleTalk-LT driver for speakup.
++CONFIG_SPEAKUP_LTLK
++ This driver is for the LiteTalk synthesizer made by MicroTalk or the
++ DoubleTalk-LT synthesizer made by RC Systems. These are serial
++ drivers for those external synths.
++
++ If you don't have a LiteTalk or DoubleTalk-LT, say 'N' here.
++
++Speakout driver for speakup.
++CONFIG_SPEAKUP_SPKOUT
++ This driver is for the Speakout external serial synthesizer made by
++ GW Micro.
++
++ If you don't have a Speakout, say 'N' here.
++
++Accent PC driver for speakup.
++CONFIG_SPEAKUP_ACNTPC
++ This driver is for the Accent PC internal synthesizer made by Aicom
++ Corp.
++
++ If you Don't have an Accent PC, say 'N' here.
++
++Accent SA driver for speakup.
++CONFIG_SPEAKUP_ACNTSA
++ This driver is for the Accent SA external synthesizer made by Aicom
++ Corp.
++
++ If you Don't have an Accent SA, say 'N' here.
++
++Apollo II driver for speakup.
++CONFIG_SPEAKUP_APOLO
++ This driver is for the Apollo II external synthesizer made
++ by Dolphin Computer Access limited.
++
++ If you Don't have an Apollo II, say 'N' here.
++
++Audapter Speech System driver for speakup.
++CONFIG_SPEAKUP_AUDPTR
++ This driver is for the Audapter external synthesizer made by
++ Personal Data System Inc.
++
++ If you Don't have an Audapter, say 'N' here.
++
++Braille 'N Speak driver for speakup.
++CONFIG_SPEAKUP_BNS
++ This driver is for the Braille 'N Speak external synthesizer made by
++ Blazie Engineering.
++
++ If you Don't have a bns, say 'N' here.
++
++Dectalk Express driver for speakup.
++CONFIG_SPEAKUP_DECTLK
++ This driver is for the Dectalk Express external synthesizer made by
++ Digital Equipment Corp.
++
++ If you Don't have a Dectalk Express, say 'N' here.
++
++Dectalk External driver for speakup.
++CONFIG_SPEAKUP_DECEXT
++ This driver is for the older Dectalk external synthesizer made by
++ Digital Equipment Corp.
++
++ If you Don't have a Dectalk external, say 'N' here.
++
++Transport driver for speakup.
++CONFIG_SPEAKUP_TXPRT
++ This driver is for the Artic Transport external synthesizer made by
++ Artic Technologies.
++
++ If you Don't have a Transport, say 'N' here.
++
++Double Talk PC internal speech card support
+ CONFIG_DTLK
+ This driver is for the DoubleTalk PC, a speech synthesizer
+ manufactured by RC Systems (). It is also
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^DefaultKeyAssignments.copy linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^DefaultKeyAssignments.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^DefaultKeyAssignments.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^DefaultKeyAssignments.copy 2003-05-12 18:28:14.000000000 -0700
@@ -0,0 +1,46 @@
+This file is intended to give you an overview of the default keys used
+by speakup for it's review functions. You may change them to be
+anything you want but that will take some familiarity with key
+mapping.
+
+We have remapped the insert or zero key on the keypad to act as a
+shift key. Well, actually as an altgr key. So in the following list
+InsKeyPad-period means hold down the insert key like a shift key and
+hit the keypad period.
+
+KeyPad-8 Say current Line
+InsKeyPad-8 say from top of screen to reading cursor.
+KeyPad-7 Say Previous Line (UP one line)
+KeyPad-9 Say Next Line (down one line)
+KeyPad-5 Say Current Word
+InsKeyPad-5 Spell Current Word
+KeyPad-4 Say Previous Word (left one word)
+InsKeyPad-4 say from left edge of line to reading cursor.
+KeyPad-6 Say Next Word (right one word)
+InsKeyPad-6 Say from reading cursor to right edge of line.
+KeyPad-2 Say Current Letter
+InsKeyPad-2 say current letter phonetically
+KeyPad-1 Say Previous Character (left one letter)
+KeyPad-3 Say Next Character (right one letter)
+KeyPad-plus Say Entire Screen
+InsKeyPad-plus Say from reading cursor line to bottom of screen.
+KeyPad-Minus Park reading cursor (toggle)
+InsKeyPad-minus Say character hex and decimal value.
+KeyPad-period Say Position (current line, position and console)
+InsKeyPad-period say colour attributes of current position.
+InsKeyPad-9 Move reading cursor to top of screen (insert pgup)
+InsKeyPad-3 Move reading cursor to bottom of screen (insert pgdn)
+InsKeyPad-7 Move reading cursor to left edge of screen (insert home)
+InsKeyPad-1 Move reading cursor to right edge of screen (insert end)
+ControlKeyPad-1 Move reading cursor to last character on current line.
+KeyPad-Enter Shut Up (until another key is hit) and sync reading cursor
+InsKeyPad-Enter Shut Up (until toggled back on).
+InsKeyPad-star n go to line (y) or column (x). Where 'n' is any
+ allowed value for the row or column for your current screen.
+KeyPad-/ Mark and Cut screen region.
+InsKeyPad-/ Paste screen region into any console.
+
+Hitting any key while speakup is outputting speech will quiet the
+synth until it has caught up with what is being printed on the
+console.
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^INSTALLATION.copy linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^INSTALLATION.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^INSTALLATION.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^INSTALLATION.copy 2003-05-12 18:28:14.000000000 -0700
@@ -0,0 +1,108 @@
+This document assumes you have had some experience with kernel
+compilation and installation. If you have not, I recommend you get
+the kernel source and read the README and various documents in the
+linux/Documentation directory. In particular the Changes file to make
+sure you have the appropriate utilities needed for installing a 2.2.xx
+or 2.4xx kernel. It isn't as difficult as you might think. The
+kernel README is intimidating the first time but once you get the
+steps down, it's really pretty easy. Getting through the "make
+config" is the tedious bit.
+
+The first thing to do is to place a copy of the tarball in the /usr/src
+directory which is the directory the linux tree is located in as well.
+Next untar speakup by typing:
+
+tar zxf speakup-1.00.tar.gz
+cd speakup-1.00
+./install
+
+Note the dot-slash before the install. This will copy the speakup
+directory to the kernel tree and apply the various patches and
+components to the appropriate kernel files. Depending on how
+experienced you are with kernel compiling and hacking will determine
+whether you should bother looking at any failed patches. If this
+happens, you should probably write to the speakup mailing list for
+help or myself.
+
+If all of the patch hunks apply successfully then just continue with
+the standard steps to compile the kernel with:
+
+make mrproper
+make config
+
+When you get to the section console speech output, answer 'y' to the
+CONFIG_SPEAKUP prompt. You will be given a submenu with the list of
+synthesizers which are currently supported. You can include as many
+synths in the kernel as you wish but remember each one takes up kernel
+space. You can only choose one of the synths as the default or none,
+so just type dtlk or whatever is the correct string for the
+synthesizer you have. You will also be asked if you wish to build-in
+a speakup key map. If you do not say 'y' to this option you will need
+to load a speakup map at boot time with whichever mechanism your
+distribution uses for loading key maps.
+
+We have placed the speakup configuration options in make config just
+after the vga console choice. For the DoubleTalk PC driver included
+by Jim Van Zandt. I recommend you say no to that option. I have not
+tried configuring them both in, but I wouldn't be at all surprised if
+it didn't work.
+
+If all goes well up to this point you can continue with the compiling
+process by doing:
+
+make dep >dep.file 2>&1 &
+make bzImage >cc.file 2>&1 &
+make modules >mod.file 2>&1 &
+
+I always redirect output to the files dep.file and cc.file so I can
+look over the compilation record to make sure there are no errors and
+warnings.
+
+Okay, you are ready to install the newly compiled kernel. Make sure
+you make an linux.old entry in your lilo.conf file so you can recover
+if it blows up. next as root run "make modules_install" to install
+whatever modules you compiled and move the bzImage from
+/usr/src/linux/arch/i386/boot to wherever your kernel lives. Also
+move the System.map from /usr/src/linux to where your System.map
+lives. On our systems we use debian so we create an vmlinuz-speakup
+and System.map-speakup in our /boot directory and set the symbolic
+links vmlinuz and System.map in the root (/) directory to point to the
+images. Now type lilo to tell lilo to build the new booter file and
+install it.
+
+As of version 0.07, the keymap for speakup is automatically built in
+at compile time. If you have other keymaps installed at boot time,
+you might want to consider removing them before you reboot the system.
+
+If everything has gone OK up until now, cross your fingers and type:
+
+shutdown -r now
+
+Your system should start talking to you as soon as it starts booting.
+It will talk and talk and ... well, you might want to hit the
+keypad-enter key to tell it to shut up. You should also read the
+DefaultKeyAssignments file to learn the various review functions
+available.
+
+As of v-0.10 the speakup configuration options are in the
+/proc/speakup subtree. The individual options should be fairly
+obvious by their names such as rate, volume, punc_level and so forth.
+You can manipulate them by cat'ing or echoing new values to them such
+as:
+
+echo 9 >/proc/speakup/rate
+
+You can see what the current values are by cat'ing those files to the console:
+
+cat /proc/speakup/rate
+
+I have probably managed to overlook a whole whack of things because
+this is the, enter version number here, draft. Don't worry we'll get
+it right eventually. If you like the package you really should get on
+the mailing list and start participating in it's development.
+
+ Kirk
+
+email: kirk@braille.uwo.ca
+phone: (519) 679-6845 (home)
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^README.copy linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^README.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^README.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^README.copy 2003-05-12 18:28:14.000000000 -0700
@@ -0,0 +1,98 @@
+Welcome to the speakup project for the Speakup speech package for Linux.
+
+Speakup is written by Kirk Reiser and Andy Berdan. It is licensed
+under the GPL. If you don't already know, the GPL stands for the GNU
+General Public License. Which basically states that this code is free to
+copy, modify and distribute to anyone interested in playing with it.
+The one thing you may not do is turn any part of it into proprietary
+or commercial code without the permission of the author. That's me.
+
+If you are interested in being involved with the development of speech
+output for Linux you can subscribe to the Speakup mailing list by
+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.
+
+We are at a very early stage in the development of this package.
+Hopefully changes will happen often and many. The current files in
+this directory are:
+
+DefaultKeyAssignments # speakup's default review keys
+INSTALLATION # for installing speakup from the tar ball.
+README # this file
+keymap-tutorial # a tutorial on how to layout the keyboard
+
+Read the INSTALLATION file to learn how to apply the patches and the
+default.map for the keyboard. You should also read the Changes file.
+It really has any new things I've added since last time.
+
+There is no documentation in any of these files to instruct you what
+to do if something goes wrong with the patching or compilation. If
+you would like that information you will need to subscribe to the
+mailing list and ask for help, or write me kirk@braille.uwo.ca for
+help. I suggest the mailing list because I will probably tire quickly
+of answering the same questions over and over. You could always
+decide to dig-in and take on the task, and write documentation to help
+others.
+
+There also is a speakup reflector for the Speak Freely package, which
+many of us hang out on and discuss all sorts of topics from speakup
+problems to ALSA driver installation and just about anything else
+you'd like to talk about. The reflector is at lwl.braille.uwo.ca:4074
+with it's lwl page at lwl.braille.uwo.ca/speakup.html. Come and join
+us, it's fun!
+
+Acknowledgements:
+
+I am really very new at kernel hacking and screen review package
+writing, so I have depended heavily on other folks kindness to help me
+a long. No doubt I will continue to abuse them freely and others
+before this is a really good speech solution for Linux. (Oh Well!,
+somebody's got to do it.)
+
+Theodore Ts'o. He gave me a good discussion of unicode and UTF and
+the like. He doesn't even remember writing me about it.
+
+Alan Cox. He has answered many questions about scheduling and wait
+queues and timers along with code fragments and so on. I just wish I
+understood it all totally. He has also helped immensely in moving
+this package toward inclusion in the standard kernel tree. (Maybe next
+release!)
+
+Martin Mares. He pointed me in the right direction to figuring out
+the colour attributes and other useful tidbits.
+
+Paul McDermott. He really is the catalyst for me to actually get
+this all working. Besides I like seeing him bounce around and get all
+excited every time I have something new working.
+
+John Covici, He was the first person to actually attempt writing
+another synthesizer driver for speakup. It was the Speakout driver so
+it was also the first serial driver.
+
+Brian Borowski, he was the first person to actually write a speakup
+function other than Andy and I.
+
+Jim Danley, he has more or less become my main man in helping test
+code, add new features, bounce ideas off and generally become a good
+friend.
+
+Matt Campbell, he basically rewrote the drivers to be able to include
+all synths in the kernel at the same time. The distribution
+maintainers appreciate him a lot as well.
+
+Gene Collins, he was very helpful debugging the current release prior
+to its public showing. He has also worked hard educating others on
+the list and writing the ALSA mini howto.
+
+I would also like to really thank the folks that handle the
+distribution packages. I and many other people would not find access
+to speakup nearly so convenient without their efforts. They include
+Bill Acker, Tom Moore, Matt Campbell, Joe Norton and Joshua Lambert.
+
+There are probably many more I am forgetting right now. I guess I'll
+just have to add you all later.
+
+
+Happy Hacking!
+
+ Kirk
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^keymap-tutorial.copy linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^keymap-tutorial.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^keymap-tutorial.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^keymap-tutorial.copy 2003-05-12 18:28:14.000000000 -0700
@@ -0,0 +1,140 @@
+ Speakup Keymap Tutorial
+
+This is meant to be a basic tutorial on how to change the Linux keymap
+file to assign speakup review functions to desired keys. It is not
+intended to be a replacement for the loadkeys(8) or keymap(5) man
+pages.
+
+The basic lay-out of the keymap file is a series of lines with the
+following fields. The keyword keycode indicates this is the start of
+a new key assignment. It is then followed by a number which
+represents the actual key on the keyboard. That number is followed by
+the equals '=' operator and finally a list of keywords representing
+key names such as keypad5. Each line can have quite a few key
+functions on it. They are interpreted by loadkeys in order and
+assigned to key shift states depending on the order they are
+encountered. So for example, the first value after the equals is the
+keys unshifted state, while the second is the keys shifted state. If
+you wish to learn the order they are interpreted in read the
+loadkeys(8) and keymap(5) man pages.
+
+You can have subsequent lines which are indented and start with
+another keyword for the various shifted states. This way you can
+assign some of the states without having to specify them all in order
+up until you get to the one you want to assign.
+
+In speakup, we have assigned the insert key on the number pad to the
+altgr keyword. This is not required; you could choose any other
+shifted state keyword. We used altgr because it typically represents
+the right hand alt key. In Linux each shift key is separate and
+independent, so the left shift and the right shift keys are not
+necessarily the same. The altgr key is not really used for anything
+important, so we steel it.
+
+Here are the default key assignments for the number eight on the
+keypad:
+
+keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+As you can see, the first line starts with keycode followed by 72
+which is the actual number assigned to the key when the keyboard port
+is read. The KP_8 after the equal sign, is the symbolic representation
+of the function called when that key is hit.
+
+The second line is the same format except it starts with the keyword
+alt which is indented. That means that the function at the end of
+that line Ascii_8 is applied to the alt-shifted eight key.
+
+Now here are the speakup assignments for that key:
+
+keycode 72 = 0x0d0a
+ altgr keycode 72 = 0x0d20
+#keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+Notice that the only thing which has changed on the first line is the
+function called when the key is struck. It is a hexadecimal number
+identifying the function called in a look up table. It is not a
+symbolic representation yet because that means we need to change the
+loadkeys program to understand our symbolic names. We will do this in
+the future but for now it is more expedient to just use the table
+indices. You will find a table at the bottom of this document
+listing the review functions and their corresponding hex lookups.
+
+The 0x0d0a in the first line above is speakup's say line function.
+The second line ends with 0x0d20 which is speakup's read from top of
+screen to reading cursor line.
+
+The third line is the original key assignment commented out with a
+number-sign '#' at the beginning. I do that so I can easily find the
+keys I want to affect by symbolic name. Otherwise I would need to
+keep a look up table for all the keycodes. I recommend you do this as
+well or you'll be very sorry at some point in the future.
+
+The forth line is just the standard key assignment for the left hand
+alt key.
+
+Now let's say we want to design a different keyboard layout. I'll use
+an example for the JAWS style keypad because I've specifically been
+asked to help with that. JAWS uses the eight on the keypad to move up
+a line or the speakup function to read previous line. JAWS also uses
+the keypad_8 key in a shifted mode to read the current line. I
+apologize if these are not quite right. It has been a long time since
+I used JAWS. So we would have the following two lines:
+
+keycode 72 = 0x0d0b
+ altgr keycode 72 = 0x0d0a
+
+The hex value 0x0d0b in the first line is speakup's SAY_PREVIOUS_LINE
+function. The 0x0d0a in the second line is the same say_line function
+as we had earlier. So when the number eight is hit on the keypad
+speakup will read the previous line and when the number eight is
+shifted with the insert key on the keypad it will read the current
+line.
+
+As you can tell, it is not really very difficult to reassign the keys
+to different review functions.
+
+Once you have carefully edited the keymap file, called default.map in
+the speakup distribution, you copy it into the /etc/kbd directory.
+Make sure you back up the original default.map from that directory
+first, if there is one. Then you run loadkeys to load the new map
+into the kernel:
+
+loadkeys /etc/kbd/default.map
+
+If you wish to build your new keyboard lay-out into the kernel, after
+testing it, copy the default.map file into the drivers/char directory,
+with the name defkeymap.map, of your Linux source tree. Then rm the
+defkeymap.c file and recompile the kernel. Because there is no
+defkeymap.c `make' will rebuild it on the next compile.
+
+Here is a list of the available speakup review functions at this point
+in time.
+
+SAY_CHAR 0x0d04 /* say this character */
+SAY_PREV_CHAR 0x0d05 /* say character left of this char */
+SAY_NEXT_CHAR 0x0d06 /* say char right of this char */
+SAY_WORD 0x0d07 /* say this word under reading cursor */
+SAY_PREV_WORD 0x0d08
+SAY_NEXT_WORD 0x0d09
+SAY_LINE 0x0d0a /* say this line */
+SAY_PREV_LINE 0x0d0b /* say line above this line */
+SAY_NEXT_LINE 0x0d0c
+TOP_EDGE 0x0d0d /* move to top edge of screen */
+BOTTOM_EDGE 0x0d0e
+LEFT_EDGE 0x0d0f
+RIGHT_EDGE 0x0d10
+SAY_PHONETIC_CHAR 0x0d11 /* say this character phonetically */
+SPELL_WORD 0x0d12 /* spell this word letter by letter */
+SAY_SCREEN 0x0d14
+SAY_POSITION 0x0d1b
+SPEECH_OFF 0x0d1c
+SAY_ATTRIBUTES 0x0d1d
+SPEAKUP_PARKED 0x0d1e
+SAY_FROM_TOP 0x0d20
+SAY_TO_BOTTOM 0x0d21
+SAY_FROM_LEFT 0x0d22
+SAY_TO_RIGHT 0x0d23
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^spkguide.txt.copy linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^spkguide.txt.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/Documentation^speakup^spkguide.txt.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/Documentation^speakup^spkguide.txt.copy 2005-04-07 12:57:32.000000000 -0700
@@ -0,0 +1,1279 @@
+
+The Speakup User's Guide
+For Speakup 2.0 and Later
+By Gene Collins
+Last modified on Tue Mar 29 10:54:19 2005
+Document version 1.0
+
+Copyright (c) 2005 Gene Collins
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled "GNU Free
+Documentation License".
+
+Preface
+
+The purpose of this document is to familiarize users with the user
+interface to Speakup, a Linux Screen Reader. If you need instructions
+for installing or obtaining Speakup, visit the web site at
+http://linux-speakup.org/. Speakup is a set of patches to the standard
+Linux kernel source tree. It can be built as a series of modules, or as
+a part of a monolithic kernel. These details are beyond the scope of
+this manual, but the user may need to be aware of the module
+capabilities, depending on how your system administrator has installed
+Speakup. If Speakup is built as a part of a monolithic kernel, and the
+user is using a hardware synthesizer, then Speakup will be able to
+provide speech access from the time the kernel is loaded, until the time
+the system is shutdown. This means that if you have obtained Linux
+installation media for a distribution which includes Speakup as a part
+of its kernel, you will be able, as a blind person, to install Linux
+with speech access unaided by a sighted person. Again, these details
+are beyond the scope of this manual, but the user should be aware of
+them. See the web site mentioned above for further details.
+
+1. Starting Speakup
+
+If your system administrator has installed Speakup to work with your
+specific synthesizer by default, then all you need to do to use Speakup
+is to boot your system, and Speakup should come up talking. This
+assumes of course that your synthesizer is a supported hardware
+synthesizer, and that it is either installed in or connected to your
+system, and is if necessary powered on.
+
+It is possible, however, that Speakup may have been compiled into the
+kernel with no default synthesizer. It is even possible that your
+kernel has been compiled with support for some of the supported
+synthesizers and not others. If you find that this is the case, and
+your synthesizer is supported but not available, complain to the person
+who compiled and installed your kernel. Or better yet, go to the web
+site, and learn how to patch Speakup into your own kernel source, and
+build and install your own kernel.
+
+If your kernel has been compiled with Speakup, and has no default
+synthesizer set, or you would like to use a different synthesizer than
+the default one, then you may issue the following command at the boot
+prompt of your boot loader.
+
+linux speakup_synth=ltlk
+
+This command would tell Speakup to look for and use a LiteTalk or
+DoubleTalk LT at boot up. You may replace the ltlk synthesizer keyword
+with the keyword for whatever synthesizer you wish to use. The
+speakup_synth parameter will accept the following keywords, provided
+that support for the related synthesizers has been built into the
+kernel.
+
+acntsa -- Accent SA
+acntpc -- Accent PC
+apolo -- Apolo
+audptr -- Audapter
+bns -- Braille 'n Speak
+dectlk -- DecTalk Express (old and new, db9 serial only)
+decext -- DecTalk (old) External
+dtlk -- DoubleTalk PC
+keypc -- Keynote Gold PC
+ltlk -- DoubleTalk LT, LiteTalk, or external Tripletalk (db9 serial only)
+spkout -- Speak Out
+txprt -- Transport
+
+Note: Speakup does * NOT * support usb connections! Speakup also does *
+NOT * support the internal Tripletalk!
+
+Speakup does support two other synthesizers, but because they work in
+conjunction with other software, they must be loaded as modules after
+their related software is loaded, and so are not available at boot up.
+These are as follows:
+
+decpc -- DecTalk PC (not available at boot up)
+sftsyn -- One of several software synthesizers (not available at boot up)
+
+See the sections on loading modules and software synthesizers later in
+this manual for further details. It should be noted here that the
+speakup_synth boot parameter will have no effect if Speakup has been
+compiled as modules. In order for Speakup modules to be loaded during
+the boot process, such action must be configured by your system
+administrator. This will mean that you will hear some, but not all, of
+the bootup messages.
+
+2. Basic operation
+
+Once you have booted the system, and if necessary, have supplied the
+proper bootup parameter for your synthesizer, Speakup will begin
+talking as soon as the kernel is loaded. In fact, it will talk a lot!
+It will speak all the boot up messages that the kernel prints on the
+screen during the boot process. This is because Speakup is not a
+separate screen reader, but is actually built into the operating
+system. Since almost all console applications must print text on the
+screen using the kernel, and must get their keyboard input through the
+kernel, they are automatically handled properly by Speakup. There are a
+few exceptions, but we'll come to those later.
+
+Note: In this guide I will refer to the numeric keypad as the keypad.
+This is done because the speakupmap.map file referred to later in this
+manual uses the term keypad instead of numeric keypad. Also I'm lazy
+and would rather only type one word. So keypad it is. Got it? Good.
+
+Most of the Speakup review keys are located on the keypad at the far
+right of the keyboard. The numlock key should be off, in order for these
+to work. If you toggle the numlock on, the keypad will produce numbers,
+which is exactly what you want for spreadsheets and such. For the
+purposes of this guide, you should have the numlock turned off, which is
+its default state at bootup.
+
+You probably won't want to listen to all the bootup messages every time
+you start your system, though it's a good idea to listen to them at
+least once, just so you'll know what kind of information is available to
+you during the boot process. You can always review these messages after
+bootup with the command:
+
+dmesg | more
+
+In order to speed the boot process, and to silence the speaking of the
+bootup messages, just press the keypad enter key. This key is located
+in the bottom right corner of the keypad. Speakup will shut up and stay
+that way, until you press another key.
+
+You can check to see if the boot process has completed by pressing the 8
+key on the keypad, which reads the current line. This also has the
+effect of starting Speakup talking again, so you can press keypad enter
+to silence it again if the boot process has not completed.
+
+When the boot process is complete, you will arrive at a "login" prompt.
+At this point, you'll need to type in your user id and password, as
+provided by your system administrator. You will hear Speakup speak the
+letters of your user id as you type it, but not the password. This is
+because the password is not displayed on the screen for security
+reasons. This has nothing to do with Speakup, it's a Linux security
+feature.
+
+Once you've logged in, you can run any Linux command or program which is
+allowed by your user id. Normal users will not be able to run programs
+which require root privileges.
+
+When you are running a program or command, Speakup will automatically
+speak new text as it arrives on the screen. You can at any time silence
+the speech with keypad enter, or use any of the Speakup review keys.
+
+Here are some basic Speakup review keys, and a short description of what
+they do.
+
+keypad 1 -- read previous character
+keypad 2 -- read current character (pressing keypad 2 twice rapidly will speak
+ the current character phonetically)
+keypad 3 -- read next character
+keypad 4 -- read previous word
+keypad 5 -- read current word (press twice rapidly to spell the current word)
+keypad 6 -- read next word
+keypad 7 -- read previous line
+keypad 8 -- read current line (press twice rapidly to hear how much the
+ text on the current line is indented)
+keypad 9 -- read next line
+keypad period -- speak current cursor position and announce current
+ virtual console
+
+It's also worth noting that the insert key on the keypad is mapped
+as the speakup key. Instead of pressing and releasing this key, as you
+do under DOS or Windows, you hold it like a shift key, and press other
+keys in combination with it. For example, repeatedly holding keypad
+insert, from now on called speakup, and keypad enter will toggle the
+speaking of new text on the screen on and off. This is not the same as
+just pressing keypad enter by itself, which just silences the speech
+until you hit another key. When you hit speakup plus keypad enter,
+Speakup will say, "You turned me off.", or "Hey, that's better." When
+Speakup is turned off, no new text on the screen will be spoken. You
+can still use the reading controls to review the screen however.
+
+3. Using the Speakup Help System
+
+Speakup has a help system, which is compiled as a module. It is loaded
+automatically whenever the Speakup help system is invoked for the first
+time, and remains loaded after that, until speakup is unloaded. Note
+that if speakup was compiled into a monolithic kernel on your system,
+you will not be able to unload Speakup from your kernel. If you try to
+use the help system, and find that it is unavailable, then your system
+administrator has not installed the Speakup help module, which is called
+speakup_help. Complain to your system administrator about this.
+
+In order to enter the Speakup help system, press and hold the speakup
+key (remember that this is the keypad insert key), and press the f1 key.
+You will hear the message:
+
+"Press space to leave help, cursor up or down to scroll, or a letter to
+go to commands in list."
+
+When you press the spacebar to leave the help system, you will hear:
+
+"Leaving help."
+
+While you are in the Speakup help system, you can scroll up or down
+through the list of available commands using the cursor keys. The list
+of commands is arranged in alphabetical order. If you wish to jump to
+commands in a specific part of the alphabet, you may press the letter of
+the alphabet you wish to jump to.
+
+You can also just explore by typing keyboard keys. Pressing keys will
+cause Speakup to speak the command associated with that key. For
+example, if you press the keypad 8 key, you will hear:
+
+"Keypad 8 is line, say current."
+
+You'll notice that some commands do not have keys assigned to them.
+This is because they are very infrequently used commands, and are also
+accessible through the proc system. We'll discuss the proc system later
+in this manual.
+
+You'll also notice that some commands have two keys assigned to them.
+This is because Speakup has a built in set of alternative key bindings
+for laptop users. The alternate speakup key is the caps lock key. You
+can press and hold the caps lock key, while pressing an alternate
+speakup command key to activate the command. On most laptops, the
+numeric keypad is defined as the keys in the j k l area of the keyboard.
+
+There is usually a function key which turns this keypad function on and
+off, and some other key which controls the numlock state. Toggling the
+keypad functionality on and off can become a royal pain. So, Speakup
+gives you a simple way to get at an alternative set of key mappings for
+your laptop. These are also available by default on desktop systems,
+because Speakup does not know whether it is running on a desktop or
+laptop. So you may choose which set of Speakup keys to use. Some
+system administrators may have chosen to compile Speakup for a desktop
+system without this set of alternate key bindings, but these details are
+beyond the scope of this manual. To use the caps lock for its normal
+purpose, hold the shift key while toggling the caps lock on and off. We
+should note here, that holding the caps lock key and pressing the z key
+will toggle the alternate j k l keypad on and off.
+
+4. Keys and Their Assigned Commands
+
+In this section, we'll go through a list of all the speakup keys and
+commands. You can also get a list of commands and assigned keys from
+the help system.
+
+The following list was taken from the speakupmap.map file. Key
+assignments are on the left of the equal sign, and the associated
+Speakup commands are on the right. The designation "spk" means to press
+and hold the speakup key, a.k.a. keypad insert, a.k.a. caps lock, while
+pressing the other specified key.
+
+spk key_f9 = punc_level_dec
+spk key_f10 = punc_level_inc
+spk key_f11 = reading_punc_dec
+spk key_f12 = reading_punc_inc
+spk key_1 = vol_dec
+spk key_2 = vol_inc
+spk key_3 = pitch_dec
+spk key_4 = pitch_inc
+spk key_5 = rate_dec
+spk key_6 = rate_inc
+key_kpasterisk = toggle_cursoring
+spk key_kpasterisk = speakup_goto
+spk key_f1 = speakup_help
+spk key_f2 = set_win
+spk key_f3 = clear_win
+spk key_f4 = enable_win
+spk key_f5 = edit_some
+spk key_f6 = edit_most
+spk key_f7 = edit_delim
+spk key_f8 = edit_repeat
+shift spk key_f9 = edit_exnum
+ key_kp7 = say_prev_line
+spk key_kp7 = left_edge
+ key_kp8 = say_line
+double key_kp8 = say_line_indent
+spk key_kp8 = say_from_top
+ key_kp9 = say_next_line
+spk key_kp9 = top_edge
+ key_kpminus = speakup_parked
+spk key_kpminus = say_char_num
+ key_kp4 = say_prev_word
+spk key_kp4 = say_from_left
+ key_kp5 = say_word
+double key_kp5 = spell_word
+spk key_kp5 = spell_phonetic
+ key_kp6 = say_next_word
+spk key_kp6 = say_to_right
+ key_kpplus = say_screen
+spk key_kpplus = say_win
+ key_kp1 = say_prev_char
+spk key_kp1 = right_edge
+ key_kp2 = say_char
+spk key_kp2 = say_to_bottom
+double key_kp2 = say_phonetic_char
+ key_kp3 = say_next_char
+spk key_kp3 = bottom_edge
+ key_kp0 = spk_key
+ key_kpdot = say_position
+spk key_kpdot = say_attributes
+key_kpenter = speakup_quiet
+spk key_kpenter = speakup_off
+key_sysrq = speech_kill
+ key_kpslash = speakup_cut
+spk key_kpslash = speakup_paste
+spk key_pageup = say_first_char
+spk key_pagedown = say_last_char
+key_capslock = spk_key
+ spk key_z = spk_lock
+key_leftmeta = spk_key
+ctrl spk key_0 = speakup_goto
+spk key_u = say_prev_line
+spk key_i = say_line
+double spk key_i = say_line_indent
+spk key_o = say_next_line
+spk key_minus = speakup_parked
+shift spk key_minus = say_char_num
+spk key_j = say_prev_word
+spk key_k = say_word
+double spk key_k = spell_word
+spk key_l = say_next_word
+spk key_m = say_prev_char
+spk key_comma = say_char
+double spk key_comma = say_phonetic_char
+spk key_dot = say_next_char
+spk key_n = say_position
+ ctrl spk key_m = left_edge
+ ctrl spk key_y = top_edge
+ ctrl spk key_dot = right_edge
+ctrl spk key_p = bottom_edge
+spk key_apostrophe = say_screen
+spk key_h = say_from_left
+spk key_y = say_from_top
+spk key_semicolon = say_to_right
+spk key_p = say_to_bottom
+spk key_slash = say_attributes
+ spk key_enter = speakup_quiet
+ ctrl spk key_enter = speakup_off
+ spk key_9 = speakup_cut
+spk key_8 = speakup_paste
+shift spk key_m = say_first_char
+ ctrl spk key_semicolon = say_last_char
+
+5. The Speakup Proc System
+
+The Speakup screen reader also creates a speakup subdirectory as a part
+of the proc system. You can see these entries by typing the command:
+
+ls -1 /proc/speakup/*
+
+If you issue the above ls command, you will get back something like
+this:
+
+/proc/speakup/attrib_bleep
+/proc/speakup/bell_pos
+/proc/speakup/bleep_time
+/proc/speakup/bleeps
+/proc/speakup/caps_start
+/proc/speakup/caps_stop
+/proc/speakup/characters
+/proc/speakup/cursor_time
+/proc/speakup/delay_time
+/proc/speakup/delimiters
+/proc/speakup/ex_num
+/proc/speakup/freq
+/proc/speakup/full_time
+/proc/speakup/jiffy_delta
+/proc/speakup/key_echo
+/proc/speakup/keymap
+/proc/speakup/no_interrupt
+/proc/speakup/pitch
+/proc/speakup/punc_all
+/proc/speakup/punc_level
+/proc/speakup/punc_most
+/proc/speakup/punc_some
+/proc/speakup/punct
+/proc/speakup/rate
+/proc/speakup/reading_punc
+/proc/speakup/repeats
+/proc/speakup/say_control
+/proc/speakup/say_word_ctl
+/proc/speakup/silent
+/proc/speakup/spell_delay
+/proc/speakup/synth_direct
+/proc/speakup/synth_name
+/proc/speakup/tone
+/proc/speakup/trigger_time
+/proc/speakup/version
+/proc/speakup/voice
+/proc/speakup/vol
+
+In addition to using the Speakup hot keys to change such things as
+volume, pitch, and rate, you can also echo values to the appropriate
+entry in the /proc/speakup directory. This is very useful, since it
+lets you control Speakup parameters from within a script. How you
+would write such scripts is somewhat beyond the scope of this manual,
+but I will include a couple of simple examples here to give you a
+general idea of what such scripts can do.
+
+Suppose for example, that you wanted to control both the punctuation
+level and the reading punctuation level at the same time. For
+simplicity, we'll call them punc0, punc1, punc2, and punc3. The scripts
+might look something like this:
+
+#!/bin/bash
+# punc0
+# set punc and reading punc levels to 0
+echo 0 >/proc/speakup/punc_level
+echo 0 >/proc/speakup/reading_punc
+echo Punctuation level set to 0.
+
+#!/bin/bash
+# punc1
+# set punc and reading punc levels to 1
+echo 1 >/proc/speakup/punc_level
+echo 1 >/proc/speakup/reading_punc
+echo Punctuation level set to 1.
+
+#!/bin/bash
+# punc2
+# set punc and reading punc levels to 2
+echo 2 >/proc/speakup/punc_level
+echo 2 >/proc/speakup/reading_punc
+echo Punctuation level set to 2.
+
+#!/bin/bash
+# punc3
+# set punc and reading punc levels to 3
+echo 3 >/proc/speakup/punc_level
+echo 3 >/proc/speakup/reading_punc
+echo Punctuation level set to 3.
+
+If you were to store these four small scripts in a directory in your
+path, perhaps /usr/local/bin, and set the permissions to 755 with the
+chmod command, then you could change the default reading punc and
+punctuation levels at the same time by issuing just one command. For
+example, if you were to execute the punc3 command at your shell prompt,
+then the reading punc and punc level would both get set to 3.
+
+I should note that the above scripts were written to work with bash, but
+regardless of which shell you use, you should be able to do something
+similar.
+
+The Speakup proc system also has another interesting use. You can echo
+Speakup parameters into the proc system in a script during system
+startup, and speakup will return to your preferred parameters every time
+the system is rebooted.
+
+Most of the Speakup proc parameters can be manipulated by a regular user
+on the system. However, there are a few parameters that are dangerous
+enough that they should only be manipulated by the root user on your
+system. There are even some parameters that are read only, and cannot
+be written to at all. For example, the version entry in the Speakup
+proc system is read only. This is because there is no reason for a user
+to tamper with the version number which is reported by Speakup. Doing
+an ls -l on /proc/speakup/version will return this:
+
+-r--r--r-- 1 root root 0 Mar 21 13:46 /proc/speakup/version
+
+As you can see, the version entry in the Speakup proc system is read
+only, is owned by root, and belongs to the root group. Doing a cat of
+/proc/speakup/version will display the Speakup version number, like
+this:
+
+cat /proc/speakup/version
+Speakup v-2.00 CVS: Thu Oct 21 10:38:21 EDT 2004
+synth dtlk version 1.1
+
+The display shows the Speakup version number, along with the version
+number of the driver for the current synthesizer.
+
+Looking at entries in the Speakup proc system can be useful in many
+ways. For example, you might wish to know what level your volume is set
+at. You could type:
+
+cat /proc/speakup/vol
+5
+
+The number five which comes back is the level at which the synthesizer
+volume is set at.
+
+All the entries in the Speakup proc system are readable, some are
+writable by root only, and some are writable by everyone. Unless you
+know what you are doing, you should probably leave the ones that are
+writable by root only alone. Most of the names are self explanatory.
+Vol for controlling volume, pitch for pitch, rate for controlling speaking
+rate, etc. If you find one you aren't sure about, you can post a query
+on the Speakup list.
+
+6. Changing Synthesizers
+
+It is possible to change to a different synthesizer while speakup is
+running. In other words, it is not necessary to reboot the system
+in order to use a different synthesizer. You can simply echo the
+synthesizer keyword to the /proc/speakup/synth_name proc entry.
+Depending on your situation, you may wish to echo none to the synth_name
+proc entry, to disable speech while one synthesizer is disconnected and
+a second one is connected in its place. Then echo the keyword for the
+new synthesizer into the synth_name proc entry in order to start speech
+with the newly connected synthesizer. See the list of synthesizer
+keywords in section 1 to find the keyword which matches your synth.
+
+7. Loading modules
+
+As mentioned earlier, Speakup can either be completely compiled into the
+kernel, with the exception of the help module, or it can be compiled as
+a series of modules. When compiled as modules, Speakup will only be
+able to speak some of the bootup messages if your system administrator
+has configured the system to load the modules at boo time. The modules
+can be loaded after the file systems have been checked and mounted, or
+from an initrd. There is a third possibility. Speakup can be compiled
+with some components built into the kernel, and others as modules. As
+we'll see in the next section, this is particularly useful when you are
+working with software synthesizers.
+
+If Speakup is completely compiled as modules, then you must use the
+modprobe command to load Speakup. You do this by loading the module for
+the synthesizer driver you wish to use. The driver modules are all
+named speakup_, where is the keyword for the
+synthesizer you want. So, in order to load the driver for the DecTalk
+Express, you would type the following command:
+
+modprobe speakup_dectlk
+
+Issuing this command would load the DecTalk Express driver and all other
+related Speakup modules necessary to get Speakup up and running.
+
+To completely unload Speakup, again presuming that it is entirely built
+as modules, you would give the command:
+
+modprobe -r speakup_dectlk
+
+The above command assumes you were running a DecTalk Express. If you
+were using a different synth, then you would substitute its keyword in
+place of dectlk.
+
+But now, suppose we have a situation where the main Speakup component
+is built into the kernel, and some or all of the drivers are built as
+modules. Since the main part of Speakup is compiled into the kernel, a
+partial Speakup proc system has been created which we can take advantage
+of by simply echoing the synthesizer keyword into the
+/proc/speakup/synth_name proc entry. This will cause the kernel to
+automatically load the appropriate driver module, and start Speakup
+talking. To switch to another synth, just echo a new keyword to the
+synth_name proc entry. For example, to load the DoubleTalk LT driver,
+you would type:
+
+echo ltlk >/proc/speakup/synth_name
+
+You can use the modprobe -r command to unload driver modules, regardless
+of whether the main part of Speakup has been built into the kernel or
+not.
+
+8. Using Software Synthesizers
+
+Using a software synthesizer requires that some other software be
+installed and running on your system. For this reason, software
+synthesizers are not available for use at bootup, or during a system
+installation process.
+
+In order to use a software synthesizer, you must have a package called
+Speech Dispatcher running on your system, and it must be configured to
+work with one of its supported software synthesizers.
+
+Two open source synthesizers you might use are Flite and Festival. You
+might also choose to purchase the Software DecTalk from Fonix Sales Inc.
+If you run a google search for Fonix, you'll find their web site.
+
+You can obtain a copy of Speech Dispatcher from free(b)soft at
+http://www.freebsoft.org/. Follow the installation instructions that
+come with Speech Dispatcher in order to install and configure Speech
+Dispatcher. You can check out the web site for your Linux distribution
+in order to get a copy of either Flite or Festival. Your Linux
+distribution may also have a precompiled Speech Dispatcher package.
+
+Once you've installed, configured, and tested Speech Dispatcher with your
+chosen software synthesizer, you still need one more piece of software
+in order to make things work. You need a package called speechd-up.
+You get it from the free(b)soft web site mentioned above. After you've
+compiled and installed speechd-up, you are almost ready to begin using
+your software synthesizer.
+
+Before you can use a software synthesizer, you must have created the
+/dev/softsynth device. If you have not already done so, issue the
+following commands as root:
+
+cd /dev
+mknod softsynth c 10 26
+
+While we are at it, we might just as well create the /dev/synth device,
+which can be used to let user space programs send information to your
+synthesizer. To create /dev/synth, change to the /dev directory, and
+issue the following command as root:
+
+mknod synth c 10 25
+
+Now you can begin using your software synthesizer. In order to do so,
+echo the sftsyn keyword to the synth_name proc entry like this:
+
+echo sftsyn >/proc/speakup/synth_name
+
+Next run the speechd_up command like this:
+
+speechd_up &
+
+Your synth should now start talking, and you should be able to adjust
+the pitch, rate, etc.
+
+In this section, we have assumed that your copy of Speakup was compiled
+with the speakup_sftsyn component either built into the kernel, or
+compiled as a module.
+
+9. Using The DecTalk PC Card
+
+The DecTalk PC card is an ISA card that is inserted into one of the ISA
+slots in your computer. It requires that the DecTalk PC software be
+installed on your computer, and that the software be loaded onto the
+Dectalk PC card before it can be used.
+
+You can get the dec_pc.tgz file from the linux-speakup.org site. The
+dec_pc.tgz file is in the ~ftp/pub/linux/speakup directory.
+
+After you have downloaded the dec_pc.tgz file, untar it in your home
+directory, and read the Readme file in the newly created dec_pc
+directory.
+
+The easiest way to get the software working is to copy the entire dec_pc
+directory into /user/local/lib. To do this, su to root in your home
+directory, and issue the command:
+
+cp dec_pc /usr/local/lib
+
+You will need to copy the dtload command from the dec_pc directory to a
+directory in your path. Either /usr/bin or /usr/local/bin is a good
+choice.
+
+You can now run the dtload command in order to load the DecTalk PC
+software onto the card. After you have done this, echo the decpc
+keyword to the synth_name entry in the proc system like this:
+
+echo decpc >/proc/speakup/synth_name
+
+Your DecTalk PC should start talking, and then you can adjust the pitch,
+rate, volume, voice, etc. The voice entry in the Speakup proc system
+will accept a number from 0 through 7 for the DecTalk PC synthesizer,
+which will give you access to some of the DecTalk voices.
+
+10. Using Cursor Tracking
+
+In Speakup version 2.0 and later, cursor tracking is turned on by
+default. This means that when you are using an editor, Speakup will
+automatically speak characters as you move left and right with the
+cursor keys, and lines as you move up and down with the cursor keys.
+
+This is extremely useful, and makes editing files a snap. But there are
+times when cursor tracking can get in your way. So Speakup provides a
+toggle to turn cursor tracking on and off. You do this with the keypad
+asterisk key. Pressing this key repeatedly will toggle the cursor
+tracking on and off, and you will hear Speakup say, "cursoring off", and
+"cursoring on".
+
+Some folks like to turn cursor tracking off while they are using the
+lynx web browser. You definitely want to turn cursor tracking off when
+you are using the alsamixer application. Otherwise, you won't be able
+to hear your mixer settings while you are using the arrow keys.
+
+11. Cut and Paste
+
+One of Speakup's more useful features is the ability to cut and paste
+text on the screen. This means that you can capture information from a
+program, and paste that captured text into a different place in the
+program, or into an entirely different program, which may even be
+running on a different console.
+
+For example, in this manual, we have made references to several web
+sites. It would be nice if you could cut and paste these urls into your
+web browser. Speakup does this quite nicely. Suppose you wanted to
+past the following url into your browser:
+
+http://linux-speakup.org/
+
+Use the speakup review keys to position the reading cursor on the first
+character of the above url. When the reading cursor is in position,
+press the keypad slash key once. Speakup will say, "mark". Next,
+position the reading cursor on the rightmost character of the above
+url. Press the keypad slash key once again to actually cut the text
+from the screen. Speakup will say, "cut". Although we call this
+cutting, Speakup does not actually delete the cut text from the screen.
+It makes a copy of the text in a special buffer for later pasting.
+
+Now that you have the url cut from the screen, you can paste it into
+your browser, or even paste the url on a command line as an argument to
+your browser.
+
+Suppose you want to start lynx and go to the Speakup site.
+
+You can switch to a different console with the alt left and right
+arrows, or you can switch to a specific console by typing alt and a
+function key. These are not Speakup commands, just standard Linux
+console capabilities.
+
+Once you've changed to an appropriate console, and are at a shell prompt,
+type the word lynx, followed by a space. Now press and hold the speakup
+key, while you type the keypad slash character. The url will be pasted
+onto the command line, just as though you had typed it in. Press the
+enter key to execute the command.
+
+The paste buffer will continue to hold the cut information, until a new
+mark and cut operation is carried out. This means you can paste the cut
+information as many times as you like before doing another cut
+operation.
+
+You are not limited to cutting and pasting only one line on the screen.
+You can also cut and paste rectangular regions of the screen. Just
+position the reading cursor at the top left corner of the text to be
+cut, mark it with the keypad slash key, then position the reading cursor
+at the bottom right corner of the region to be cut, and cut it with the
+keypad slash key.
+
+12. Changing the Pronunciation of Characters
+
+Through the /proc/speakup/chars proc entry, Speakup gives you the
+ability to change how Speakup pronounces a given character. You could,
+for example, change how some punctuation characters are spoken. You can
+even change how Speakup will pronounce certain letters.
+
+You may, for example, wish to change how Speakup pronounces the z
+character. The author of Speakup, Kirk Reiser, is Canadian, and thus
+believes that the z should be pronounced zed. If you are an American,
+you might wish to use the zee pronunciation instead of zed. You can
+change the pronunciation of both the upper and lower case z with the
+following two commands:
+
+echo 90 zee >/proc/speakup/characters
+echo 122 zee >/proc/speakup/characters
+
+Let's examine the parts of the two previous commands. They are issued
+at the shell prompt, and could be placed in a startup script.
+
+The word echo tells the shell that you want to have it display the
+string of characters that follow the word echo. If you were to just
+type:
+
+echo hello.
+
+You would get the word hello printed on your screen as soon as you
+pressed the enter key. In this case, we are echoing strings that we
+want to be redirected into the proc system.
+
+The numbers 90 and 122 in the above echo commands are the ascii numeric
+values for the upper and lower case z, the characters we wish to change.
+
+The string zee is the pronunciation that we want Speakup to use for the
+upper and lower case z.
+
+The > symbol redirects the output of the echo command to a file, just
+like in DOS, or at the Windows command prompt.
+
+And finally, /proc/speakup/chars is the file entry in the proc system
+where we want the output to be directed. Speakup looks at the numeric
+value of the character we want to change, and inserts the pronunciation
+string into an internal table.
+
+You can look at the whole table with the following command:
+
+cat /proc/speakup/chars
+
+Speakup will then print out the entire character pronunciation table. I
+won't display it here, but leave you to look at it at your convenience.
+
+13. Mapping Keys
+
+Speakup has the capability of allowing you to assign or "map" keys to
+internal Speakup commands. This section necessarily assumes you have a
+Linux kernel source tree installed, and that it has been patched and
+configured with Speakup. How you do this is beyond the scope of this
+manual. For this information, visit the Speakup web site at
+http://linux-speakup.org/. The reason you'll need the kernel source
+tree patched with Speakup is that the genmap utility you'll need for
+processing keymaps is in the
+/usr/src/linux-/drivers/char/speakup directory. The
+ in the above directory path is the version number of
+the Linux source tree you are working with.
+
+So ok, you've gone off and gotten your kernel source tree, and patched
+and configured it. Now you can start manipulating keymaps.
+
+You can either use the
+/usr/src/linux-/drivers/char/speakup/speakupmap.map file
+included with the Speakup source, or you can cut and paste the copy in
+section 4 into a separate file. If you use the one in the Speakup
+source tree, make sure you make a backup of it before you start making
+changes. You have been warned!
+
+Suppose that you want to swap the key assignments for the Speakup
+say_last_char and the Speakup say_first_char commands. The
+speakupmap.map lists the key mappings for these two commands as follows:
+
+spk key_pageup = say_first_char
+spk key_pagedown = say_last_char
+
+You can edit your copy of the speakupmap.map file and swap the command
+names on the right side of the = (equals) sign. You did make a backup,
+right? The new keymap lines would look like this:
+
+spk key_pageup = say_last_char
+spk key_pagedown = say_first_char
+
+After you edit your copy of the speakupmap.map file, save it under a new
+file name, perhaps newmap.map. Then exit your editor and return to the
+shell prompt.
+
+You are now ready to load your keymap with your swapped key assignments.
+ Assuming that you saved your new keymap as the file newmap.map, you
+would load your keymap into the proc system like this:
+
+/usr/src/linux-/drivers/char/speakup/genmap newmap.map
+>/proc/speakup/keymap
+
+Remember to substitute your kernel version number for the
+ in the above command. Also note that although the
+above command wrapped onto two lines in this document, you should type
+it all on one line.
+
+Your say first and say last characters should now be swapped. Pressing
+speakup pagedown should read you the first non-whitespace character on
+the line your reading cursor is in, and pressing speakup pageup should
+read you the last character on the line your reading cursor is in.
+
+You should note that these new mappings will only stay in effect until
+you reboot, or until you load another keymap.
+
+One final warning. If you try to load a partial map, you will quickly
+find that all the mappings you didn't include in your file got deleted
+from the working map. Be extremely careful, and always make a backup!
+You have been warned!
+
+14. Using Speakup's Windowing Capability
+
+Speakup has the capability of defining and manipulating windows on the
+screen. Speakup uses the term "Window", to mean a user defined area of
+the screen. The key strokes for defining and manipulating Speakup
+windows are as follows:
+
+speakup + f2 -- Set the bounds of the window.
+Speakup + f3 -- clear the current window definition.
+speakup + f4 -- Toggle window silence on and off.
+speakup + keypad plus -- Say the currently defined window.
+
+These capabilities are useful for tracking a certain part of the screen
+without rereading the whole screen, or for silencing a part of the
+screen that is constantly changing, such as a clock or status line.
+
+There is no way to save these window settings, and you can only have one
+window defined for each virtual console. There is also no way to have
+windows automaticly defined for specific applications.
+
+In order to define a window, use the review keys to move your reading
+cursor to the beginning of the area you want to define. Then press
+speakup + f2. Speakup will tell you that the window starts at the
+indicated row and column position. Then move the reading cursor to the
+end of the area to be defined as a window, and press speakup + f2 again.
+ If there is more than one line in the window, Speakup will tell you
+that the window ends at the indicated row and column position. If there
+is only one line in the window, then Speakup will tell you that the
+window is the specified line on the screen. If you are only defining a
+one line window, you can just press speakup + f2 twice after placing the
+reading cursor on the line you want to define as a window. It is not
+necessary to position the reading cursor at the end of the line in order
+to define the whole line as a window.
+
+ GNU Free Documentation License
+ Version 1.2, November 2002
+
+
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+0. PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document "free" in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+
+1. APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The "Document", below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as "you". You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A "Modified Version" of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (Thus, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The "Cover Texts" are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A "Transparent" copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML, PostScript or PDF designed for human modification. Examples of
+transparent image formats include PNG, XCF and JPG. Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML, PostScript or PDF produced by some word
+processors for output purposes only.
+
+The "Title Page" means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, "Title Page" means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section "Entitled XYZ" means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as "Acknowledgements",
+"Dedications", "Endorsements", or "History".) To "Preserve the Title"
+of such a section when you modify the Document means that it remains a
+section "Entitled XYZ" according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+
+2. VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+3. COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+
+4. MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+ from that of the Document, and from those of previous versions
+ (which should, if there were any, be listed in the History section
+ of the Document). You may use the same title as a previous version
+ if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the Modified
+ Version, together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has fewer than five),
+ unless they release you from this requirement.
+C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice
+ giving the public permission to use the Modified Version under the
+ terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections
+ and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section Entitled "History", Preserve its Title, and add
+ to it an item stating at least the title, year, new authors, and
+ publisher of the Modified Version as given on the Title Page. If
+ there is no section Entitled "History" in the Document, create one
+ stating the title, year, authors, and publisher of the Document as
+ given on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the "History" section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section all
+ the substance and tone of each of the contributor acknowledgements
+ and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.
+M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+N. Do not retitle any existing section to be Entitled "Endorsements"
+ or to conflict in title with any Invariant Section.
+O. Preserve any Warranty Disclaimers.
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled "Endorsements", provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+
+5. COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled "History"
+in the various original documents, forming one section Entitled
+"History"; likewise combine any sections Entitled "Acknowledgements",
+and any sections Entitled "Dedications". You must delete all sections
+Entitled "Endorsements".
+
+
+6. COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an "aggregate" if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+
+8. TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled "Acknowledgements",
+"Dedications", or "History", the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+
+9. TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+
+
+ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+ Copyright (c) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+The End.
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^alpha^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v24/arch^alpha^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^alpha^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/arch^alpha^config.in.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/arch/alpha/config.in.orig 2005-04-19 09:48:50.000000000 -0400
++++ arch/alpha/config.in 2005-04-19 09:48:51.000000000 -0400
+@@ -417,6 +417,7 @@
+ # fi
+ # fi
+ source drivers/video/Config.in
++ source drivers/char/speakup/Config.in
+ if [ "$CONFIG_FB" = "y" ]; then
+ define_bool CONFIG_PCI_CONSOLE y
+ fi
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^arm^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v24/arch^arm^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^arm^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/arch^arm^config.in.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/arch/arm/config.in.orig 2005-04-19 09:48:50.000000000 -0400
++++ arch/arm/config.in 2005-04-19 09:48:51.000000000 -0400
+@@ -669,6 +669,7 @@
+ bool 'VGA text console' CONFIG_VGA_CONSOLE
+ fi
+ source drivers/video/Config.in
++ source drivers/char/speakup/Config.in
+ endmenu
+ fi
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^i386^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v24/arch^i386^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^i386^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/arch^i386^config.in.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/arch/i386/config.in.orig 2005-04-19 09:48:50.000000000 -0400
++++ arch/i386/config.in 2005-04-19 09:48:51.000000000 -0400
+@@ -451,6 +451,7 @@
+ tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+ source drivers/video/Config.in
+ fi
++ source drivers/char/speakup/Config.in
+ endmenu
+ fi
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^m68k^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v24/arch^m68k^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^m68k^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/arch^m68k^config.in.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/arch/m68k/config.in.orig 2005-04-19 09:48:50.000000000 -0400
++++ arch/m68k/config.in 2005-04-19 09:48:51.000000000 -0400
+@@ -538,6 +538,7 @@
+ mainmenu_option next_comment
+ comment 'Console drivers'
+ source drivers/video/Config.in
++ source drivers/char/speakup/Config.in
+ endmenu
+ fi
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^mips^config-shared.in.patch linux-2.4.30/drivers/char/speakup/diff-v24/arch^mips^config-shared.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^mips^config-shared.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/arch^mips^config-shared.in.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/arch/mips/config-shared.in.orig 2005-04-19 09:48:50.000000000 -0400
++++ arch/mips/config-shared.in 2005-04-19 09:48:51.000000000 -0400
+@@ -990,6 +990,7 @@
+ tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+ source drivers/video/Config.in
+ fi
++ source drivers/char/speakup/Config.in
+ endmenu
+ fi
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^ppc^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v24/arch^ppc^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^ppc^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/arch^ppc^config.in.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/arch/ppc/config.in.orig 2005-04-19 09:48:50.000000000 -0400
++++ arch/ppc/config.in 2005-04-19 09:48:51.000000000 -0400
+@@ -533,6 +533,7 @@
+ bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
+ fi
+ source drivers/video/Config.in
++ source drivers/char/speakup/Config.in
+ if [ "$CONFIG_FB" = "y" -a "$CONFIG_ALL_PPC" = "y" ]; then
+ bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
+ fi
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^sparc64^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v24/arch^sparc64^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^sparc64^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/arch^sparc64^config.in.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/arch/sparc64/config.in.orig 2005-04-19 09:48:50.000000000 -0400
++++ arch/sparc64/config.in 2005-04-19 09:48:51.000000000 -0400
+@@ -99,6 +99,7 @@
+ comment 'Console drivers'
+ bool 'PROM console' CONFIG_PROM_CONSOLE
+ source drivers/video/Config.in
++source drivers/char/speakup/Config.in
+ endmenu
+
+ source drivers/sbus/char/Config.in
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^sparc^config.in.patch linux-2.4.30/drivers/char/speakup/diff-v24/arch^sparc^config.in.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/arch^sparc^config.in.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/arch^sparc^config.in.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/arch/sparc/config.in.orig 2005-04-19 09:48:50.000000000 -0400
++++ arch/sparc/config.in 2005-04-19 09:48:51.000000000 -0400
+@@ -85,6 +85,7 @@
+ comment 'Console drivers'
+ bool 'PROM console' CONFIG_PROM_CONSOLE
+ source drivers/video/Config.in
++source drivers/char/speakup/Config.in
+ endmenu
+
+ source drivers/mtd/Config.in
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^Makefile.patch linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^Makefile.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^Makefile.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^Makefile.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,36 @@
+--- /usr/src/linux-2.4.30/drivers/char/Makefile.orig 2005-04-19 09:48:50.000000000 -0400
++++ drivers/char/Makefile 2005-04-19 09:48:51.000000000 -0400
+@@ -22,12 +22,12 @@
+ # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
+
+ export-objs := busmouse.o console.o keyboard.o sysrq.o \
+- misc.o pty.o random.o selection.o serial.o \
++ misc.o pty.o random.o selection.o serial.o vt.o \
+ sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
+ au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \
+- scx200.o fetchop.o
++ scx200.o fetchop.o consolemap.o
+
+-mod-subdirs := joystick ftape drm drm-4.0 pcmcia
++mod-subdirs := joystick ftape drm drm-4.0 pcmcia speakup
+
+ list-multi :=
+
+@@ -186,6 +186,9 @@
+ endif
+
+ obj-$(CONFIG_HIL) += hp_keyb.o
++ifeq ($(CONFIG_SPEAKUP),y)
++obj-y += speakup/spk.o
++endif
+ obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
+ obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
+ obj-$(CONFIG_ROCKETPORT) += rocket.o
+@@ -275,6 +278,7 @@
+
+ obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
+
++subdir-$(CONFIG_SPEAKUP) += speakup
+ subdir-$(CONFIG_FTAPE) += ftape
+ subdir-$(CONFIG_DRM_OLD) += drm-4.0
+ subdir-$(CONFIG_DRM_NEW) += drm
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^console.c.patch linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^console.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^console.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^console.c.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,113 @@
+--- /usr/src/linux-2.4.30/drivers/char/console.c.orig 2005-04-19 09:48:50.000000000 -0400
++++ drivers/char/console.c 2005-04-19 09:48:51.000000000 -0400
+@@ -107,8 +107,13 @@
+ #include
+ #include
+
++#include
++
+ #include "console_macros.h"
+
++#ifdef CONFIG_SPEAKUP_MODULE
++#include "speakup/spk_con_module.h"
++#endif
+
+ const struct consw *conswitchp;
+
+@@ -695,6 +700,7 @@
+ screenbuf = (unsigned short *) q;
+ kmalloced = 1;
+ vc_init(currcons, video_num_lines, video_num_columns, 1);
++ speakup_allocate(currcons); /* speakup needs more too. */
+
+ if (!pm_con) {
+ pm_con = pm_register(PM_SYS_DEV,
+@@ -927,6 +933,7 @@
+ pos += video_size_row;
+ }
+ need_wrap = 0;
++ speakup_con_write(currcons, "\n",1);
+ }
+
+ static void ri(int currcons)
+@@ -953,8 +960,9 @@
+ {
+ if (x) {
+ pos -= 2;
+- x--;
+ need_wrap = 0;
++ x--;
++ speakup_bs(currcons);
+ }
+ }
+
+@@ -1487,6 +1495,7 @@
+ break;
+ }
+ pos += (x << 1);
++ speakup_con_write(currcons, " ", 1);
+ return;
+ case 10: case 11: case 12:
+ lf(currcons);
+@@ -2000,6 +2009,7 @@
+ }
+ if (decim)
+ insert_char(currcons, 1);
++ speakup_con_write(currcons, (char *) &tc,1);
+ scr_writew(himask ?
+ ((attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+ (attr << 8) + tc,
+@@ -2040,6 +2050,7 @@
+
+ up(&con_buf_sem);
+ }
++ speakup_con_update(currcons);
+
+ return n;
+ #undef FLUSH
+@@ -2070,6 +2081,7 @@
+ /* we only changed when the console had already
+ been allocated - a new console is not created
+ in an interrupt routine */
++ speakup_allocate(want_console);
+ }
+ want_console = -1;
+ }
+@@ -2139,6 +2151,7 @@
+
+ /* Contrived structure to try to emulate original need_wrap behaviour
+ * Problems caused when we have need_wrap set on '\n' character */
++ speakup_con_write(currcons, b, count);
+ while (count--) {
+ c = *b++;
+ if (c == 10 || c == 13 || c == 8 || need_wrap) {
+@@ -2183,6 +2196,7 @@
+ }
+ }
+ set_cursor(currcons);
++ speakup_con_update(currcons);
+
+ if (!oops_in_progress)
+ poke_blanked_console();
+@@ -2530,6 +2544,8 @@
+ master_display_fg = vc_cons[currcons].d;
+ set_origin(currcons);
+ save_screen(currcons);
++ speakup_init(currcons);
++
+ gotoxy(currcons,x,y);
+ csi_J(currcons, 0);
+ update_screen(fg_console);
+@@ -3042,6 +3058,7 @@
+ EXPORT_SYMBOL(video_font_height);
+ EXPORT_SYMBOL(video_scan_lines);
+ EXPORT_SYMBOL(vc_resize);
++EXPORT_SYMBOL(vc_cons);
+ EXPORT_SYMBOL(fg_console);
+ EXPORT_SYMBOL(console_blank_hook);
+ #ifdef CONFIG_VT
+@@ -3051,3 +3068,4 @@
+ EXPORT_SYMBOL(take_over_console);
+ EXPORT_SYMBOL(give_up_console);
+ #endif
++EXPORT_SYMBOL(screen_glyph);
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^consolemap.c.patch linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^consolemap.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^consolemap.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^consolemap.c.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,19 @@
+--- /usr/src/linux-2.4.30/drivers/char/consolemap.c.orig 2005-04-19 09:48:50.000000000 -0400
++++ drivers/char/consolemap.c 2005-04-19 09:48:51.000000000 -0400
+@@ -22,6 +22,8 @@
+ #include
+ #include
+
++#include
++
+ static unsigned short translations[][256] = {
+ /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
+ {
+@@ -231,6 +233,7 @@
+ else
+ return p->inverse_translations[inv_translate[conp->vc_num]][glyph];
+ }
++EXPORT_SYMBOL(inverse_translate);
+
+ static void update_user_maps(void)
+ {
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^keyboard.c.patch linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^keyboard.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^keyboard.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^keyboard.c.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,107 @@
+--- /usr/src/linux-2.4.30/drivers/char/keyboard.c.orig 2005-04-19 09:48:50.000000000 -0400
++++ drivers/char/keyboard.c 2005-04-19 09:48:51.000000000 -0400
+@@ -43,6 +43,8 @@
+ #include
+ #include
+
++#include
++
+ #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
+
+ #ifndef KBD_DEFMODE
+@@ -69,6 +71,9 @@
+ extern void ctrl_alt_del(void);
+
+ struct console;
++#ifdef CONFIG_SPEAKUP_MODULE
++spk_key_func addr_spk_key = NULL;
++#endif
+
+ /*
+ * global state includes the following, and various static variables
+@@ -93,8 +98,8 @@
+ static char rep; /* flag telling character repeat */
+ struct kbd_struct kbd_table[MAX_NR_CONSOLES];
+ static struct tty_struct **ttytab;
+-static struct kbd_struct * kbd = kbd_table;
+-static struct tty_struct * tty;
++struct kbd_struct * kbd = kbd_table;
++struct tty_struct * tty;
+ static unsigned char prev_scancode;
+
+ void compute_shiftstate(void);
+@@ -107,15 +112,19 @@
+ do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
+ do_ignore;
+
+-static k_hand key_handler[16] = {
++k_hand key_handler[16] = {
+ do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
+ do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
+ do_ignore, do_ignore
+ };
+
++EXPORT_SYMBOL(kbd);
++EXPORT_SYMBOL(tty);
++EXPORT_SYMBOL(key_handler);
++
+ /* Key types processed even in raw modes */
+
+-#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT))
++#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) )
+
+ typedef void (*void_fnp)(void);
+ typedef void (void_fn)(void);
+@@ -139,7 +148,7 @@
+ 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
+ NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
+ 255, NR_ASCII - 1, NR_LOCK - 1, 255,
+- NR_LOCK - 1, 255
++ NR_LOCK - 1, 255, 255
+ };
+
+ const int NR_TYPES = SIZE(max_vals);
+@@ -311,6 +320,14 @@
+
+ if (type >= 0xf0) {
+ type -= 0xf0;
++#ifdef CONFIG_SPEAKUP
++ if ( speakup_key(shift_final, keycode, keysym, up_flag ) )
++ goto out;
++#elif defined(CONFIG_SPEAKUP_MODULE)
++ if ( addr_spk_key && (*addr_spk_key)(shift_final,
++ keycode, keysym, up_flag ) )
++ goto out;
++#endif
+ if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type)))
+ goto out;
+ if (type == KT_LETTER) {
+@@ -330,6 +347,14 @@
+ to_utf8(keysym);
+ }
+ } else {
++#ifdef CONFIG_SPEAKUP
++ if ( speakup_key(shift_final, keycode, K(KT_SHIFT,0), up_flag ) )
++ goto out;
++#elif defined(CONFIG_SPEAKUP_MODULE)
++ if ( addr_spk_key && (*addr_spk_key)(shift_final,
++ keycode, K(KT_SHIFT,0), up_flag ) )
++ goto out;
++#endif
+ /* maybe beep? */
+ /* we have at least to update shift_state */
+ #if 1 /* how? two almost equivalent choices follow */
+@@ -536,11 +561,10 @@
+ compute_shiftstate();
+ }
+
++
+ static void do_spec(unsigned char value, char up_flag)
+ {
+- if (up_flag)
+- return;
+- if (value >= SIZE(spec_fn_table))
++ if (up_flag || (value >= SIZE(spec_fn_table)))
+ return;
+ if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
+ !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^speakup^speakup.c.copy linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^speakup^speakup.c.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^speakup^speakup.c.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^speakup^speakup.c.copy 2005-04-19 11:37:27.000000000 -0700
@@ -0,0 +1,2285 @@
+/* speakup.c
+ review functions for the speakup screen review package.
+ originally written by: Kirk Reiser and Andy Berdan.
+
+ extensively modified by David Borowski.
+
+ Copyright (C ) 1998 Kirk Reiser.
+ Copyright (C ) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define __KERNEL_SYSCALLS__
+
+#include
+#include
+#include
+#include
+#include /* __get_free_page( ) and friends */
+#include
+#if (LINUX_VERSION_CODE < 132419)
+#include
+#include
+#include
+#endif
+#include
+#include
+#include /* copy_from|to|user( ) and others */
+#include
+
+#include /* for KT_SHIFT */
+#include /* for vc_kbd_* and friends */
+#include
+#include
+#include
+#include
+
+#include "cvsversion.h"
+#include "spk_priv.h"
+#include /* for alloc_bootmem */
+
+/* speakup_*_selection */
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../console_macros.h" /* for x, y, attr and pos macros */
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define SPEAKUP_VERSION "Speakup v-2.00" CVSVERSION
+#define MAX_DELAY ( (500 * HZ ) / 1000 )
+#define KEY_MAP_VER 119
+#define MINECHOCHAR SPACE
+
+/* these are globals from the kernel code */
+extern void *kmalloc (size_t, int );
+extern void kfree (const void * );
+extern struct kbd_struct * kbd;
+extern int fg_console;
+extern short punc_masks[];
+
+static special_func special_handler = NULL;
+special_func help_handler = NULL;
+
+static int errno;
+int synth_file_inuse = 0;
+short pitch_shift = 0, synth_flags = 0;
+static char buf[256];
+short attrib_bleep = 0, bleeps = 0, bleep_time = 1;
+short no_intr = 0, spell_delay = 0;
+short key_echo = 0, cursor_timeout = 120, say_word_ctl = 0;
+short say_ctrl = 0, bell_pos = 0;
+short punc_mask = 0, punc_level = 0, reading_punc = 0;
+char str_caps_start[MAXVARLEN+1] = "\0", str_caps_stop[MAXVARLEN+1] = "\0";
+bits_data punc_info[] = {
+ { "none", "", 0 },
+ { "some", "/$%&@", SOME },
+ { "most", "$%()=+*/@^<>|\\", MOST },
+ { "all", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", PUNC },
+ { "delimiters", "", B_WDLM },
+ { "repeats", "()", CH_RPT },
+ { "extended numeric", "", B_EXNUM },
+ { "symbols", "", B_SYM },
+ { 0, 0 }
+};
+char mark_cut_flag = 0;
+u_short mark_x = 0, mark_y = 0;
+static char synth_name[10] = CONFIG_SPEAKUP_DEFAULT;
+#define MAX_KEY 160
+u_char *our_keys[MAX_KEY], *shift_table;
+static u_char key_buf[600];
+static u_char key_defaults[] = {
+#include "speakupmap.h"
+};
+
+#if (LINUX_VERSION_CODE < 132419)
+extern struct tty_struct *tty;
+typedef void (*k_handler_fn)(unsigned char value, char up_flag);
+#define KBD_PROTO u_char value, char up_flag
+#define KBD_ARGS value, up_flag
+#else
+struct tty_struct *tty;
+#define key_handler k_handler
+typedef void (*k_handler_fn)(struct vc_data *vc, unsigned char value,
+ char up_flag, struct pt_regs *regs);
+#define KBD_PROTO struct vc_data *vc, u_char value, char up_flag, struct pt_regs *regs
+#define KBD_ARGS vc, value, up_flag, regs
+#endif
+extern k_handler_fn key_handler[16];
+static k_handler_fn do_shift, do_spec, do_latin, do_cursor;
+EXPORT_SYMBOL( help_handler );
+EXPORT_SYMBOL( special_handler );
+EXPORT_SYMBOL( our_keys );
+
+static void speakup_date (int currcons );
+static void spkup_write (const char *in_buf, int count );
+int set_mask_bits( const char *input, const int which, const int how );
+
+char str_ctl[] = "control-";
+char *colors[] = {
+ "black", "blue", "green", "cyan", "red", "magenta", "yellow", "white",
+ "grey"
+};
+
+char *phonetic[] = {
+ "alpha", "beta", "charley", "delta", "echo", "fox", "gamma", "hotel",
+ "india", "juleiet", "keelo", "leema", "mike", "november", "oscar",
+ "papa",
+ "quebec", "romeo", "seeara", "tango", "uniform", "victer", "wiskey",
+ "x ray", "yankee", "zooloo"
+};
+
+// array of 256 char pointers (one for each ASCII character description )
+// initialized to default_chars and user selectable via /proc/speakup/characters
+char *characters[256];
+
+char *default_chars[256] = {
+ "null", "^a", "^b", "^c", "^d", "^e", "^f", "^g",
+ "^h", "^i", "^j", "^k", "^l", "^m", "^n", "^o",
+ "^p", "^q", "^r", "^s", "^t", "^u", "^v", "^w",
+ "^x", "^y", "^z", NULL, NULL, NULL, NULL, NULL,
+ "space", "bang!", "quote", "number", "dollar", "percent", "and",
+ "tick",
+ "left paren", "right paren", "star", "plus", "comma", "dash", "dot",
+ "slash",
+ "zero", "one", "two", "three", "four", "five", "six", "seven",
+ "eight", "nine",
+ "colon", "semmy", "less", "equals", "greater", "question", "at",
+ "eigh", "b", "c", "d", "e", "f", "g",
+ "h", "i", "j", "k", "l", "m", "n", "o",
+ "p", "q", "r", "s", "t", "u", "v", "w", "x",
+ "y", "zehd", "left bracket", "backslash", "right bracket", "caret",
+ "line",
+ "accent", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "left brace", "bar", "right brace", "tihlduh",
+ "delta", "see cedilla", "u oomlout", "e acute", /* 128 */
+ "eigh circumflex", "eigh oomlout", "eigh grave", "eigh ring", /* 132 */
+ "see cedilla", "e circumflex", "e oomlout", "e grave", /* 136 */
+ "i oomlout", "i circumflex", "i grave", "eigh oomlout", /* 140 */
+ "eigh ring", "e acute", "eigh e dipthong", "eigh e dipthong", /* 144 */
+ "o circumflex", "o oomlout", "o grave", "u circumflex", /* 148 */
+ "u grave", "y oomlout", "o oomlout", "u oomlout", /* 152 */
+ "cents", "pounds", "yen", "peseta", /* 156 */
+ "florin", "eigh acute", "i acute", "o acute", /* 160 */
+ "u acute", "n tilde", "n tilde", "feminine ordinal", /* 164 */
+ "masculin ordinal", "inverted question", "reversed not", "not", /* 168 */
+ "half", "quarter", "inverted bang", "much less than", /* 172 */
+ "much greater than", "dark shading", "medium shading", /* 176 */
+ "light shading", "verticle line", "left tee", /* 179 */
+ "double left tee", "left double tee", "double top right", /* 182 */
+ "top double right", "double left double tee", /* 185 */
+ "double vertical line", "double top double right", /* 187 */
+ "double bottom double right", "double bottom right", /* 189 */
+ "bottom double right", "top right", "left bottom", /* 191 */
+ "up tee", "tee down", "tee right", "horizontal line", /* 194 */
+ "cross bars", "tee double right", "double tee right", /* 198 */
+ "double left double bottom", "double left double top", /* 201 */
+ "double up double tee", "double tee double down", /* 203 */
+ "double tee double right", "double horizontal line", /* 205 */
+ "double cross bars", "up double tee", "double up tee", /* 207 */
+ "double tee down", "tee double down", /* 210 */
+ "double left bottom", "left double bottom", /* 212 */
+ "double left top", "left double top", /* 214 */
+ "double vertical cross", "double horizontal cross", /* 216 */
+ "bottom right", "left top", "solid square", /* 218 */
+ "solid lower half", "solid left half", "solid right half", /* 221 */
+ "solid upper half", "alpha", "beta", "gamma", /* 224 */
+ "pie", "sigma", "sigma", "mu", /* 228 */
+ "tou", "phigh", "thayta", "ohmega", /* 232 */
+ "delta", "infinity", "phigh", "epsilaun", /* 236 */
+"intersection", "identical to", "plus or minus", "equal grater than", /* 240 */
+ "less than equal", "upper integral", "lower integral", /* 244 */
+ "divided by", "almost equal", "degrees", /* 247 */
+ "centre dot", "bullet", "square root", /* 250 */
+ "power", "squared", "black square", "white space" /* 252 */
+};
+
+u_short spk_chartab[256] = {
+ B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 0-7 */
+ B_CTL, B_CTL, A_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 8-15 */
+ B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /*16-23 */
+ B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 24-31 */
+WDLM, A_PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* !"#$%&' */
+PUNC, PUNC, PUNC, PUNC, A_PUNC, A_PUNC, A_PUNC, PUNC, /* ( )*+, -./ */
+NUM, NUM, NUM, NUM, NUM, NUM, NUM, NUM, /* 01234567 */
+NUM, NUM, A_PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* 89:;<=>? */
+PUNC, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* @ABCDEFG */
+A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* HIJKLMNO */
+A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* PQRSTUVW */
+A_CAP, A_CAP, A_CAP, PUNC, PUNC, PUNC, PUNC, PUNC, /* XYZ[\]^_ */
+PUNC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* `abcdefg */
+ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* hijklmno */
+ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* pqrstuvw */
+ALPHA, ALPHA, ALPHA, PUNC, PUNC, PUNC, PUNC, 0, /* xyz{|}~ */
+B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 128-135 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, /* 136-143 */
+B_CAPSYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 144-151 */
+B_SYM, B_SYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 152-159 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, B_SYM, /* 160-167 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 168-175 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 176-183 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 184-191 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 192-199 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 200-207 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 208-215 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 216-223 */
+B_SYM, B_SYM, B_SYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, /* 224-231 */
+B_SYM, B_CAPSYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 232-239 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 240-247 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM /* 248-255 */
+};
+
+int spk_keydown = 0;
+static u_char spk_lastkey = 0, spk_close_press = 0, keymap_flags = 0;
+static u_char last_keycode = 0, this_speakup_key = 0;
+static u_long last_spk_jiffy = 0;
+
+spk_t *speakup_console[MAX_NR_CONSOLES];
+
+int spk_setup (char *str )
+{
+ int ints[4];
+ str = get_options (str, ARRAY_SIZE (ints ), ints );
+ if (ints[0] > 0 && ints[1] >= 0 )
+ synth_port_forced = ints[1];
+ return 1;
+}
+
+int spk_ser_setup (char *str )
+{
+ int lookup[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+ int ints[4];
+ str = get_options (str, ARRAY_SIZE (ints ), ints );
+ if (ints[0] > 0 && ints[1] >= 0 )
+ synth_port_forced = lookup[ints[1]];
+ return 1;
+}
+
+int spk_synth_setup (char *str )
+{
+ size_t len = MIN (strlen (str ), 9 );
+ memcpy (synth_name, str, len );
+ synth_name[len] = '\0';
+ return 1;
+}
+
+__setup ("speakup_port=", spk_setup );
+__setup ("speakup_ser=", spk_ser_setup );
+__setup ("speakup_synth=", spk_synth_setup );
+
+char *
+strlwr (char *s )
+{
+ char *p;
+ for (p = s; *p; p++ ) {
+ if (*p >= CAP_A && *p <= CAP_Z ) *p |= 32;
+ }
+ return s;
+}
+
+static void
+bleep (u_short val )
+{
+ static short vals[] = { 350, 370, 392, 414, 440, 466, 491, 523,
+554, 587, 619, 659 };
+ short freq;
+ int time = bleep_time;
+ freq = vals[val%12];
+ if (val > 11 )
+ freq *= (1<<(val/12 ) );
+ kd_mksound (freq, time );
+}
+
+void
+speakup_shut_up (int currcons )
+{
+ if (spk_killed ) return;
+ spk_shut_up |= 0x01;
+ spk_parked &= 0xfe;
+ speakup_date (currcons );
+ if (synth == NULL ) return;
+ do_flush( );
+}
+
+void
+speech_kill (int currcons )
+{
+ char val = synth->is_alive ( );
+ if (val == 0 ) return;
+ /* re-enables synth, if disabled */
+ if (val == 2 || spk_killed ) { /* dead */
+ spk_shut_up &= ~0x40;
+ synth_write_msg ("Eyem a Lighve!" );
+ } else {
+ synth_write_msg ("You killed speak up!" );
+ spk_shut_up |= 0x40;
+ }
+}
+
+static void
+speakup_off (int currcons )
+{
+ if (spk_shut_up & 0x80 ) {
+ spk_shut_up &= 0x7f;
+ synth_write_msg ("hey. That's better!" );
+ } else {
+ spk_shut_up |= 0x80;
+ synth_write_msg ("You turned me off!" );
+ }
+ speakup_date (currcons );
+}
+
+static void
+speakup_parked (int currcons )
+{
+ if (spk_parked & 0x80 ) {
+ spk_parked = 0;
+ synth_write_msg ("unparked!" );
+ } else {
+ spk_parked |= 0x80;
+ synth_write_msg ("parked!" );
+ }
+}
+
+/* ------ cut and paste ----- */
+/* Don't take this from : 011-015 on the screen aren't spaces */
+#undef isspace
+#define isspace(c) ((c) == ' ')
+/* Variables for selection control. */
+int spk_sel_cons; /* defined in selection.c must not be disallocated */
+static volatile int sel_start = -1; /* cleared by clear_selection */
+static int sel_end;
+static int sel_buffer_lth;
+static char *sel_buffer;
+
+static unsigned char
+sel_pos(int n)
+{
+ return inverse_translate(vc_cons[spk_sel_cons].d, screen_glyph(spk_sel_cons, n));
+}
+
+static void
+speakup_clear_selection(void)
+{
+ sel_start = -1;
+}
+
+/* does screen address p correspond to character at LH/RH edge of screen? */
+static inline int atedge(const int p, int size_row)
+{
+ return (!(p % size_row) || !((p + 2) % size_row));
+}
+
+/* constrain v such that v <= u */
+static inline unsigned short limit(const unsigned short v, const unsigned short u)
+{
+ return (v > u) ? u : v;
+}
+
+unsigned short xs, ys, xe, ye; /* our region points */
+
+static int
+speakup_set_selection( struct tty_struct *tty)
+{
+ int new_sel_start, new_sel_end;
+ char *bp, *obp;
+ int i, ps, pe;
+ unsigned int currcons = fg_console;
+
+ xs = limit(xs, video_num_columns - 1);
+ ys = limit(ys, video_num_lines - 1);
+ xe = limit(xe, video_num_columns - 1);
+ ye = limit(ye, video_num_lines - 1);
+ ps = ys * video_size_row + (xs << 1);
+ pe = ye * video_size_row + (xe << 1);
+
+ if (ps > pe) { /* make sel_start <= sel_end */
+ int tmp = ps;
+ ps = pe;
+ pe = tmp;
+ }
+
+ if (spk_sel_cons != fg_console) {
+ speakup_clear_selection();
+ spk_sel_cons = fg_console;
+ printk(KERN_WARNING "Selection: mark console not the same as cut\n");
+ return -EINVAL;
+ }
+
+ new_sel_start = ps;
+ new_sel_end = pe;
+
+ /* select to end of line if on trailing space */
+ if (new_sel_end > new_sel_start &&
+ !atedge(new_sel_end, video_size_row) &&
+ isspace(sel_pos(new_sel_end))) {
+ for (pe = new_sel_end + 2; ; pe += 2)
+ if (!isspace(sel_pos(pe)) ||
+ atedge(pe, video_size_row))
+ break;
+ if (isspace(sel_pos(pe)))
+ new_sel_end = pe;
+ }
+ if ((new_sel_start == sel_start)
+ && (new_sel_end == sel_end)) /* no action required */
+ return 0;
+
+ sel_start = new_sel_start;
+ sel_end = new_sel_end;
+ /* Allocate a new buffer before freeing the old one ... */
+ bp = kmalloc((sel_end-sel_start)/2+1, GFP_ATOMIC);
+ if (!bp) {
+ printk(KERN_WARNING "selection: kmalloc() failed\n");
+ speakup_clear_selection();
+ return -ENOMEM;
+ }
+ if (sel_buffer)
+ kfree(sel_buffer);
+ sel_buffer = bp;
+
+ obp = bp;
+ for (i = sel_start; i <= sel_end; i += 2) {
+ *bp = sel_pos(i);
+ if (!isspace(*bp++))
+ obp = bp;
+ if (! ((i + 2) % video_size_row)) {
+ /* strip trailing blanks from line and add newline,
+ unless non-space at end of line. */
+ if (obp != bp) {
+ bp = obp;
+ *bp++ = '\r';
+ }
+ obp = bp;
+ }
+ }
+ sel_buffer_lth = bp - sel_buffer;
+ return 0;
+}
+
+static int
+speakup_paste_selection(struct tty_struct *tty)
+{
+ struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
+ int pasted = 0, count;
+ DECLARE_WAITQUEUE(wait, current);
+ add_wait_queue(&vt->paste_wait, &wait);
+ while (sel_buffer && sel_buffer_lth > pasted) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (test_bit(TTY_THROTTLED, &tty->flags)) {
+ schedule();
+ continue;
+ }
+ count = sel_buffer_lth - pasted;
+ count = MIN(count, tty->ldisc.receive_room(tty));
+ tty->ldisc.receive_buf(tty, sel_buffer + pasted, 0, count);
+ pasted += count;
+ }
+ remove_wait_queue(&vt->paste_wait, &wait);
+ current->state = TASK_RUNNING;
+ return 0;
+}
+
+static void
+speakup_cut (int currcons )
+{
+ static const char err_buf[] = "set selection failed";
+ int ret;
+
+ if (!mark_cut_flag ) {
+ mark_cut_flag = 1;
+ xs = spk_x;
+ ys = spk_y;
+ spk_sel_cons = currcons;
+ synth_write_msg ("mark" );
+ return;
+ }
+ xe = (u_short ) spk_x;
+ ye = (u_short )spk_y;
+ mark_cut_flag = 0;
+ synth_write_msg ("cut" );
+
+ speakup_clear_selection( );
+ ret = speakup_set_selection ( tty );
+
+ switch (ret ) {
+ case 0:
+ break; /* no error */
+ case -EFAULT :
+ pr_warn( "%sEFAULT\n", err_buf );
+ break;
+ case -EINVAL :
+ pr_warn( "%sEINVAL\n", err_buf );
+ break;
+ case -ENOMEM :
+ pr_warn( "%sENOMEM\n", err_buf );
+ break;
+ }
+}
+
+static void
+speakup_paste (int currcons )
+{
+ if (mark_cut_flag ) {
+ mark_cut_flag = 0;
+ synth_write_msg ("mark, cleared" );
+ } else {
+ synth_write_msg ("paste" );
+ speakup_paste_selection (tty );
+ }
+}
+
+static void
+say_attributes (int currcons )
+{
+ int fg= spk_attr&0x0f, bg = spk_attr>>4;
+ if (fg > 8 ) {
+ synth_write_string("bright " );
+ fg -= 8;
+ }
+ synth_write_string(colors[fg] );
+ if (bg > 7 ) {
+ synth_write_string(" on blinking " );
+ bg -= 8;
+ } else
+ synth_write_string(" on " );
+ synth_write_msg(colors[bg] );
+}
+
+static char *blank_msg = "blank";
+static char *edges[] = { "top, ", "bottom, ", "left, ", "right, ", "" };
+enum { edge_top = 1, edge_bottom, edge_left, edge_right, edge_quiet };
+
+static void
+announce_edge (int currcons, int msg_id )
+{
+ if (bleeps&1 )
+ bleep (spk_y );
+ if (bleeps&2 )
+ synth_write_msg (edges[msg_id-1] );
+}
+
+static void
+speak_char( u_char ch )
+{
+ char *cp = characters[ ch];
+ synth_buffer_add( SPACE );
+ if (IS_CHAR(ch, B_CAP ) ) {
+ pitch_shift++;
+ synth_write_string(str_caps_start );
+ synth_write_string(cp );
+ synth_write_string(str_caps_stop );
+ } else {
+ if (*cp == '^' ) {
+ synth_write_string(str_ctl );
+ cp++;
+ }
+ synth_write_string(cp );
+ }
+ synth_buffer_add( SPACE );
+}
+
+static void
+say_char (int currcons )
+{
+ u_short ch;
+ spk_old_attr = spk_attr;
+ ch = scr_readw ((u_short * ) spk_pos );
+ spk_attr = ((ch & 0xff00 ) >> 8 );
+ if (spk_attr != spk_old_attr ) {
+ if ( attrib_bleep&1 ) bleep (spk_y );
+ if ( attrib_bleep&2 ) say_attributes( currcons );
+ }
+ speak_char( ch&0xff );
+}
+
+static void
+say_phonetic_char (int currcons )
+{
+ u_short ch;
+ spk_old_attr = spk_attr;
+ ch = scr_readw ((u_short * ) spk_pos );
+ spk_attr = ((ch & 0xff00 ) >> 8 );
+ if ( IS_CHAR(ch, B_ALPHA ) ) {
+ ch &= 0x1f;
+ synth_write_msg(phonetic[--ch] );
+ } else {
+ if ( IS_CHAR(ch, B_NUM ) )
+ synth_write_string( "number " );
+ speak_char( ch );
+ }
+}
+
+static void
+say_prev_char (int currcons )
+{
+ spk_parked |= 0x01;
+ if (spk_x == 0 ) {
+ announce_edge(currcons, edge_left );
+ return;
+ }
+ spk_x--;
+ spk_pos -= 2;
+ say_char (currcons );
+}
+
+static void
+say_next_char (int currcons )
+{
+ spk_parked |= 0x01;
+ if (spk_x == video_num_columns - 1 ) {
+ announce_edge(currcons, edge_right );
+ return;
+ }
+ spk_x++;
+ spk_pos += 2;
+ say_char (currcons );
+}
+
+/* get_word - will first check to see if the character under the
+ reading cursor is a space and if say_word_ctl is true it will
+ return the word space. If say_word_ctl is not set it will check to
+ see if there is a word starting on the next position to the right
+ and return that word if it exists. If it does not exist it will
+ move left to the beginning of any previous word on the line or the
+ beginning off the line whichever comes first.. */
+
+static u_long
+get_word (int currcons )
+{
+ u_long cnt = 0, tmpx = spk_x, tmp_pos = spk_pos;
+ char ch;
+ u_short attr_ch;
+ spk_old_attr = spk_attr;
+ ch = (char ) scr_readw ((u_short * ) tmp_pos );
+
+/* decided to take out the sayword if on a space (mis-information */
+ if ( say_word_ctl && ch == SPACE ) {
+ *buf = '\0';
+ synth_write_msg( "space" );
+ return 0;
+ } else if ((tmpx < video_num_columns-2 )
+ && (ch == SPACE || IS_WDLM(ch ))
+ && ((char) scr_readw ((u_short * ) tmp_pos+1 ) > SPACE)) {
+ tmp_pos += 2;
+ tmpx++;
+ } else
+ while (tmpx > 0 ) {
+ if (((ch = (char ) scr_readw ((u_short * ) tmp_pos-1 )) == SPACE
+ || IS_WDLM(ch ))
+ && ((char) scr_readw ((u_short * ) tmp_pos ) > SPACE))
+ break;
+ tmp_pos -= 2;
+ tmpx--;
+ }
+ attr_ch = scr_readw ((u_short * ) tmp_pos );
+ spk_attr = attr_ch >> 8;
+ buf[cnt++] = attr_ch&0xff;
+ while (tmpx < video_num_columns-1 ) {
+ tmp_pos += 2;
+ tmpx++;
+ ch = (char ) scr_readw ((u_short * ) tmp_pos );
+ if ((ch == SPACE )
+ || (IS_WDLM(buf[cnt-1] ) && ( ch > SPACE )))
+ break;
+ buf[cnt++] = ch;
+ }
+ buf[cnt] = '\0';
+ return cnt;
+}
+
+static void
+say_word (int currcons )
+{
+ u_long cnt = get_word(currcons );
+ u_short saved_punc_mask = punc_mask;
+ if ( cnt == 0 ) return;
+ punc_mask = PUNC;
+ buf[cnt++] = SPACE;
+ spkup_write (buf, cnt );
+ punc_mask = saved_punc_mask;
+}
+
+static void
+say_prev_word (int currcons )
+{
+ char ch;
+ u_short edge_said = 0, last_state = 0, state = 0;
+ spk_parked |= 0x01;
+ if (spk_x == 0 ) {
+ if ( spk_y == 0 ) {
+ announce_edge(currcons, edge_top );
+ return;
+ }
+ spk_y--;
+ spk_x = video_num_columns;
+ edge_said = edge_quiet;
+ }
+ while ( 1 ) {
+ if (spk_x == 0 ) {
+ if (spk_y == 0 ) {
+ edge_said = edge_top;
+ break;
+ }
+ if ( edge_said != edge_quiet ) edge_said = edge_left;
+ if ( state > 0 ) break;
+ spk_y--;
+ spk_x = video_num_columns-1;
+ } else spk_x--;
+ spk_pos -= 2;
+ ch = (char ) scr_readw ((u_short * ) spk_pos );
+ if ( ch == SPACE ) state = 0;
+ else if (IS_WDLM(ch ) ) state = 1;
+ else state = 2;
+ if (state < last_state ) {
+ spk_pos += 2;
+ spk_x++;
+ break;
+ }
+ last_state = state;
+ }
+ if ( spk_x == 0 && edge_said == edge_quiet )
+ edge_said = edge_left;
+ if ( edge_said > 0 && edge_said < edge_quiet )
+ announce_edge( currcons, edge_said );
+ say_word (currcons );
+}
+
+static void
+say_next_word (int currcons )
+{
+ char ch;
+ u_short edge_said = 0, last_state = 2, state = 0;
+ spk_parked |= 0x01;
+ if ( spk_x == video_num_columns - 1 && spk_y == video_num_lines-1 ) {
+ announce_edge(currcons, edge_bottom );
+ return;
+ }
+ while ( 1 ) {
+ ch = (char ) scr_readw ((u_short * ) spk_pos );
+ if ( ch == SPACE ) state = 0;
+ else if (IS_WDLM(ch ) ) state = 1;
+ else state = 2;
+ if ( state > last_state ) break;
+ if (spk_x >= video_num_columns-1 ) {
+ if (spk_y == video_num_lines-1 ) {
+ edge_said = edge_bottom;
+ break;
+ }
+ state = 0;
+ spk_y++;
+ spk_x = 0;
+ edge_said = edge_right;
+ } else spk_x++;
+ spk_pos += 2;
+ last_state = state;
+ }
+ if ( edge_said > 0 )
+ announce_edge( currcons, edge_said );
+ say_word (currcons );
+}
+
+static void
+spell_word (int currcons )
+{
+ static char *delay_str[] = { " ", ", ", ". ", ". . ", ". . . " };
+ char *cp = buf, *str_cap= str_caps_stop;
+ char *cp1, *last_cap = str_caps_stop;
+ u_char ch;
+ if ( !get_word(currcons ) ) return;
+ while ((ch = (u_char )*cp ) ) {
+ if ( cp != buf )
+ synth_write_string (delay_str[spell_delay] );
+ if (IS_CHAR(ch, B_CAP ) ) {
+ str_cap = str_caps_start;
+ if ( *str_caps_stop ) pitch_shift++;
+ else last_cap = str_caps_stop; /* synth has no pitch */
+ } else str_cap = str_caps_stop;
+ if ( str_cap !=last_cap ) {
+ synth_write_string( str_cap );
+ last_cap = str_cap;
+ }
+ if ( this_speakup_key == SPELL_PHONETIC && ( IS_CHAR( ch, B_ALPHA ) ) ) {
+ ch &= 31;
+ cp1 = phonetic[--ch];
+ } else {
+ cp1 = characters[ch];
+ if (*cp1 == '^' ) {
+ synth_write_string(str_ctl );
+ cp1++;
+ }
+ }
+ synth_write_string(cp1 );
+ cp++;
+ }
+ if ( str_cap != str_caps_stop )
+ synth_write_string( str_caps_stop );
+}
+
+static int
+get_line (int currcons )
+{
+ u_long tmp = spk_pos - (spk_x * 2 );
+ int i = 0;
+ spk_old_attr = spk_attr;
+ spk_attr = (u_char ) (scr_readw ((u_short * ) spk_pos ) >> 8 );
+ for (i = 0; i < video_num_columns; i++ ) {
+ buf[i] = (u_char ) scr_readw ((u_short * ) tmp );
+ tmp += 2;
+ }
+ for (--i; i >= 0; i-- )
+ if (buf[i] != SPACE ) break;
+ return ++i;
+}
+
+static void
+say_line (int currcons )
+{
+ int i = get_line( currcons );
+ char *cp;
+ char num_buf[8];
+ u_short saved_punc_mask = punc_mask;
+ if (i == 0 ) {
+ synth_write_msg (blank_msg );
+ return;
+ }
+ buf[i++] = '\n';
+ if ( this_speakup_key == SAY_LINE_INDENT ) {
+ for ( cp = buf; *cp == SPACE; cp++ );
+ sprintf( num_buf, "%d, ", ( cp-buf )+1 );
+ synth_write_string( num_buf );
+ }
+ punc_mask = punc_masks[reading_punc];
+ spkup_write (buf, i );
+ punc_mask = saved_punc_mask;
+}
+
+static void
+say_prev_line (int currcons )
+{
+ spk_parked |= 0x01;
+ if (spk_y == 0 ) {
+ announce_edge (currcons, edge_top );
+ return;
+ }
+ spk_y--;
+ spk_pos -= video_size_row;
+ say_line (currcons );
+}
+
+static void
+say_next_line (int currcons )
+{
+ spk_parked |= 0x01;
+ if (spk_y == video_num_lines - 1 ) {
+ announce_edge (currcons, edge_bottom );
+ return;
+ }
+ spk_y++;
+ spk_pos += video_size_row;
+ say_line (currcons );
+}
+
+static int
+say_from_to (int currcons, u_long from, u_long to, int read_punc )
+{
+ int i = 0;
+ u_short saved_punc_mask = punc_mask;
+ spk_old_attr = spk_attr;
+ spk_attr = (u_char ) (scr_readw ((u_short * ) from ) >> 8 );
+ while (from < to ) {
+ buf[i++] = (char ) scr_readw ((u_short * ) from );
+ from += 2;
+ if ( i >= video_size_row ) break;
+ }
+ for (--i; i >= 0; i-- )
+ if (buf[i] != SPACE ) break;
+ buf[++i] = SPACE;
+ buf[++i] = NULL;
+ if ( i < 1 ) return i;
+ if ( read_punc ) punc_mask = punc_info[reading_punc].mask;
+ spkup_write (buf, i );
+ if ( read_punc ) punc_mask = saved_punc_mask;
+ return i-1;
+}
+
+static void
+say_line_from_to (int currcons, u_long from, u_long to, int read_punc )
+{
+ u_long start = origin+(spk_y*video_size_row );
+ u_long end = start+( to * 2 );
+ start += from*2;
+ if ( say_from_to( currcons, start, end, read_punc ) <= 0 )
+ synth_write_msg (blank_msg );
+}
+
+static void
+say_screen_from_to (int currcons, u_long from, u_long to )
+{
+ u_long start = origin, end;
+ if ( from > 0 ) start += from * video_size_row;
+ if ( to > video_num_lines ) to = video_num_lines;
+ end = origin + ( to * video_size_row);
+ for ( from = start; from < end; from = to ) {
+ to = from + video_size_row;
+ say_from_to( currcons, from, to, 1 );
+ }
+}
+
+static void
+say_screen (int currcons )
+{
+ say_screen_from_to( currcons, 0, video_num_lines );
+}
+
+static void
+speakup_win_say (int currcons )
+{
+ u_long start, end, from, to;
+ if ( win_start < 2 ) {
+ synth_write_msg( "no window" );
+ return;
+ }
+ start = origin + ( win_top * video_size_row );
+ end = origin + ( win_bottom * video_size_row );
+ while ( start <= end ) {
+ from = start + ( win_left * 2 );
+ to = start + ( win_right * 2 );
+ say_from_to( currcons, from, to, 1 );
+ start += video_size_row;
+ }
+}
+
+static void
+top_edge (int currcons )
+{
+ spk_parked |= 0x01;
+ spk_pos = origin + 2 * spk_x;
+ spk_y = 0;
+ say_line (currcons );
+}
+
+static void
+bottom_edge (int currcons )
+{
+ spk_parked |= 0x01;
+ spk_pos += (video_num_lines - spk_y - 1 ) * video_size_row;
+ spk_y = video_num_lines - 1;
+ say_line (currcons );
+}
+
+static void
+left_edge (int currcons )
+{
+ spk_parked |= 0x01;
+ spk_pos -= spk_x * 2;
+ spk_x = 0;
+ say_char (currcons );
+}
+
+static void
+right_edge (int currcons )
+{
+ spk_parked |= 0x01;
+ spk_pos += (video_num_columns - spk_x - 1 ) * 2;
+ spk_x = video_num_columns - 1;
+ say_char (currcons );
+}
+
+static void
+say_first_char (int currcons )
+{
+ int i, len = get_line( currcons );
+ u_char ch;
+ spk_parked |= 0x01;
+ if ( len == 0 ) {
+ synth_write_msg( blank_msg );
+ return;
+ }
+ for ( i = 0; i < len; i++ ) if ( buf[i] != SPACE ) break;
+ ch = buf[i];
+ spk_pos -= ( spk_x-i ) * 2;
+ spk_x = i;
+ sprintf (buf, "%d, ", ++i );
+ synth_write_string (buf );
+ speak_char( ch );
+}
+
+static void
+say_last_char (int currcons )
+{
+ int len = get_line( currcons );
+ u_char ch;
+ spk_parked |= 0x01;
+ if ( len == 0 ) {
+ synth_write_msg( blank_msg );
+ return;
+ }
+ ch = buf[--len];
+ spk_pos -= ( spk_x-len ) * 2;
+ spk_x = len;
+ sprintf (buf, "%d, ", ++len );
+ synth_write_string (buf );
+ speak_char( ch );
+}
+
+static void
+say_position (int currcons )
+{
+ sprintf (buf, "line %ld, col %ld, t t y %d\n", spk_y + 1,
+ spk_x + 1, currcons + 1 );
+ synth_write_string (buf );
+}
+
+// Added by brianb
+static void
+say_char_num (int currcons )
+{
+ u_short ch = scr_readw ((u_short * ) spk_pos );
+ ch &= 0x0ff;
+ sprintf (buf, "hex %02x, decimal %d", ch, ch );
+ synth_write_msg (buf );
+}
+
+/* these are stub functions to keep keyboard.c happy. */
+
+static void
+say_from_top (int currcons )
+{
+ say_screen_from_to (currcons, 0, spk_y );
+}
+
+static void
+say_to_bottom (int currcons )
+{
+ say_screen_from_to (currcons, spk_y, video_num_lines );
+}
+
+static void
+say_from_left (int currcons )
+{
+ say_line_from_to (currcons, 0, spk_x, 1 );
+}
+
+static void
+say_to_right (int currcons )
+{
+ say_line_from_to (currcons, spk_x, video_num_columns, 1 );
+}
+
+/* end of stub functions. */
+
+static void
+spkup_write (const char *in_buf, int count )
+{
+ static int rep_count = 0;
+ static u_char ch = '\0', old_ch = '\0';
+ static u_short char_type = 0, last_type = 0;
+ static u_char *exn_ptr = NULL;
+ int in_count = count;
+ char rpt_buf[32];
+ spk_keydown = 0;
+ while ( count-- ) {
+ ch = (u_char )*in_buf++;
+ char_type = spk_chartab[ch];
+ if (ch == old_ch && !(char_type&B_NUM ) ) {
+ if (++rep_count > 2 ) continue;
+ } else {
+ if ( (last_type&CH_RPT) && rep_count > 2 ) {
+ sprintf (rpt_buf, " times %d . ", ++rep_count );
+ synth_write_string (rpt_buf );
+ }
+ rep_count = 0;
+ }
+ if ( !( char_type&B_NUM ) )
+ exn_ptr = NULL;
+ if (ch == spk_lastkey ) {
+ rep_count = 0;
+ if ( key_echo == 1 && ch >= MINECHOCHAR )
+ speak_char( ch );
+ } else if ( ( char_type&B_ALPHA ) ) {
+ if ( (synth_flags&SF_DEC) && (last_type&PUNC) )
+ synth_buffer_add ( SPACE );
+ synth_write( &ch, 1 );
+ } else if ( ( char_type&B_NUM ) ) {
+ rep_count = 0;
+ if ( (last_type&B_EXNUM) && synth_buff_in == exn_ptr+1 ) {
+ synth_buff_in--;
+ synth_buffer_add( old_ch );
+ exn_ptr = NULL;
+ }
+ synth_write( &ch, 1 );
+ } else if ( (char_type&punc_mask) ) {
+ speak_char( ch );
+ char_type &= ~PUNC; /* for dec nospell processing */
+ } else if ( ( char_type&SYNTH_OK ) ) {
+/* these are usually puncts like . and , which synth needs for expression.
+ * suppress multiple to get rid of long pausesand clear repeat count so if
+ *someone has repeats on you don't get nothing repeated count */
+ if ( ch != old_ch )
+ synth_write( &ch, 1 );
+ else rep_count = 0;
+ } else {
+ if ( ( char_type&B_EXNUM ) )
+ exn_ptr = (u_char *)synth_buff_in;
+/* send space and record position, if next is num overwrite space */
+ if ( old_ch != ch ) synth_buffer_add ( SPACE );
+ else rep_count = 0;
+ }
+ old_ch = ch;
+ last_type = char_type;
+ }
+ spk_lastkey = 0;
+ if (in_count > 2 && rep_count > 2 ) {
+ if ( (last_type&CH_RPT) ) {
+ sprintf (rpt_buf, " repeated %d . ", ++rep_count );
+ synth_write_string (rpt_buf );
+ }
+ rep_count = 0;
+ }
+}
+
+static char *ctl_key_ids[] = {
+ "shift", "altgr", "control", "ault", "l shift", "speakup",
+"l control", "r control"
+};
+#define NUM_CTL_LABELS 8
+
+static void
+handle_shift( KBD_PROTO )
+{
+ int currcons = fg_console;
+ (*do_shift)( KBD_ARGS );
+ if ( synth == NULL || up_flag || spk_killed ) return;
+ spk_shut_up &= 0xfe;
+ do_flush( );
+ if ( say_ctrl && value < NUM_CTL_LABELS )
+ synth_write_string ( ctl_key_ids[value] );
+}
+
+static void
+handle_latin( KBD_PROTO )
+{
+ int currcons = fg_console;
+ (*do_latin)( KBD_ARGS );
+ if ( up_flag ) {
+ spk_lastkey = spk_keydown = 0;
+ return;
+ }
+ if ( synth == NULL || spk_killed ) return;
+ spk_shut_up &= 0xfe;
+ spk_lastkey = value;
+ spk_keydown++;
+ spk_parked &= 0xfe;
+ if ( key_echo == 2 && value >= MINECHOCHAR )
+ speak_char( value );
+}
+
+static int
+set_key_info( u_char *key_info, u_char *k_buffer )
+{
+ int i = 0, states, key_data_len;
+ u_char *cp = key_info, *cp1 = k_buffer;
+ u_char ch, version, num_keys;
+ version = *cp++;
+ if ( version != KEY_MAP_VER ) return -1;
+ num_keys = *cp;
+ states = (int)cp[1];
+ key_data_len = ( states+1 ) * ( num_keys+1 );
+ if ( key_data_len+SHIFT_TBL_SIZE+4 >= sizeof(key_buf ) ) return -2;
+ memset( k_buffer, 0, SHIFT_TBL_SIZE );
+ memset( our_keys, 0, sizeof( our_keys ) );
+ shift_table = k_buffer;
+ our_keys[0] = shift_table;
+ cp1 += SHIFT_TBL_SIZE;
+ memcpy( cp1, cp, key_data_len+3 );
+/* get num_keys, states and data*/
+ cp1 += 2; /* now pointing at shift states */
+ for ( i = 1; i <= states; i++ ) {
+ ch = *cp1++;
+ if ( ch >= SHIFT_TBL_SIZE ) return -3;
+ shift_table[ch] = i;
+ }
+ keymap_flags = *cp1++;
+ while ( ( ch = *cp1 ) ) {
+ if ( ch >= MAX_KEY ) return -4;
+ our_keys[ch] = cp1;
+ cp1 += states+1;
+ }
+ return 0;
+}
+
+num_var spk_num_vars[] = { /* bell must be first to set high limit */
+ { BELL_POS, 0, 0, 0, 0, 0, 0, 0 },
+ { SPELL_DELAY, 0, 0, 0, 5, 0, 0, 0 },
+ { ATTRIB_BLEEP, 0, 1, 0, 3, 0, 0, 0 },
+ { BLEEPS, 0, 3, 0, 3, 0, 0, 0 },
+ { BLEEP_TIME, 0, 4, 1, 20, 0, 0, 0 },
+ { PUNC_LEVEL, 0, 1, 0, 4, 0, 0, 0 },
+ { READING_PUNC, 0, 1, 0, 4, 0, 0, 0 },
+ { CURSOR_TIME, 0, 120, 50, 600, 0, 0, 0 },
+ { SAY_CONTROL, TOGGLE_0 },
+ { SAY_WORD_CTL, TOGGLE_0 },
+ { NO_INTERRUPT, TOGGLE_0 },
+ { KEY_ECHO, 0, 1, 0, 2, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+static int cursor_track = 1;
+static char *cursor_msgs[] = { "cursoring off", "cursoring on",
+ "attribute cursor" };
+#define MAXCURSORTRACK 1
+/* increase when we add more cursor modes */
+/* attribute cursor code coming soon */
+
+static void
+toggle_cursoring( int currcons )
+{
+ cursor_track++;
+ if ( cursor_track > MAXCURSORTRACK )
+ cursor_track = 0;
+ synth_write_msg (cursor_msgs[cursor_track] );
+}
+
+static void
+reset_default_chars (void )
+{
+ int i;
+ if (default_chars[(int )'a'] == NULL ) { /* lowers are null first time */
+ for (i = (int )'a'; default_chars[i] == NULL; i++ )
+ default_chars[i] = default_chars[i-32];
+ } else { /* free any non-default */
+ for (i = 0; i < 256; i++ ) {
+ if (characters[i] != default_chars[i] )
+ kfree (characters[i] );
+ }
+ }
+ memcpy( characters, default_chars, sizeof( default_chars ) );
+}
+
+static void
+handle_cursor( KBD_PROTO );
+static void
+handle_spec( KBD_PROTO );
+static void
+cursor_done(u_long data );
+declare_timer( cursor_timer );
+
+void __init speakup_open (int currcons, spk_t *first_console )
+{
+ int i;
+ num_var *n_var;
+ reset_default_chars ( );
+ memset( speakup_console, 0, sizeof( speakup_console ) );
+ if ( first_console == NULL ) return;
+ memset( first_console, 0, spk_size );
+ speakup_console[currcons] = first_console;
+ speakup_date( currcons);
+ pr_info ("%s: initialized\n", SPEAKUP_VERSION );
+ init_timer (&cursor_timer );
+#if (LINUX_VERSION_CODE >= 132419)
+ cursor_timer.entry.prev=NULL;
+#endif
+ cursor_timer.function = cursor_done;
+ init_sleeper ( synth_sleeping_list );
+ strlwr (synth_name );
+ synth_init ( synth_name );
+ spk_num_vars[0].high = video_num_columns;
+ for ( n_var = spk_num_vars; n_var->var_id >= 0; n_var++ )
+ speakup_register_var( n_var );
+ for (i = 1; punc_info[i].mask != 0; i++ )
+ set_mask_bits( 0, i, 2 );
+ do_latin = key_handler[KT_LATIN];
+ key_handler[KT_LATIN] = handle_latin;
+ do_spec = key_handler[KT_SPEC];
+ key_handler[KT_SPEC] = handle_spec;
+ do_cursor = key_handler[KT_CUR];
+ key_handler[KT_CUR] = handle_cursor;
+ do_shift = key_handler[KT_SHIFT];
+ key_handler[KT_SHIFT] = handle_shift;
+ set_key_info( key_defaults, key_buf );
+}
+
+#ifdef CONFIG_PROC_FS
+
+// speakup /proc interface code
+
+/* Usage:
+cat /proc/speakup/version
+
+cat /proc/speakup/characters > foo
+less /proc/speakup/characters
+vi /proc/speakup/characters
+
+cat foo > /proc/speakup/characters
+cat > /proc/speakup/characters
+echo 39 apostrophe > /proc/speakup/characters
+echo 87 w > /proc/speakup/characters
+echo 119 w > /proc/speakup/characters
+echo defaults > /proc/speakup/characters
+echo reset > /proc/speakup/characters
+*/
+
+// keymap handlers
+
+static int
+keys_read_proc (PROC_READ_PROTOTYPE )
+{
+ char *cp = page;
+ int i, n, num_keys, nstates;
+ u_char *cp1 = key_buf + SHIFT_TBL_SIZE, ch;
+ num_keys = (int)(*cp1);
+ nstates = (int)cp1[1];
+ cp += sprintf( cp, "%d, %d, %d,\n", KEY_MAP_VER, num_keys, nstates );
+ cp1 += 2; /* now pointing at shift states */
+/* dump num_keys+1 as first row is shift states + flags,
+ each subsequent row is key + states */
+ for ( n = 0; n <= num_keys; n++ ) {
+ for ( i = 0; i <= nstates; i++ ) {
+ ch = *cp1++;
+ cp += sprintf( cp, "%d,", (int)ch );
+ *cp++ = ( i < nstates ) ? SPACE : '\n';
+ }
+ }
+ cp += sprintf( cp, "0, %d\n", KEY_MAP_VER );
+ *start = 0;
+ *eof = 1;
+ return (int)(cp-page);
+}
+
+static char *
+s2uchar ( char *start, char *dest )
+{
+ int val = 0;
+ while ( *start && *start <= SPACE ) start++;
+ while ( *start >= '0' && *start <= '9' ) {
+ val *= 10;
+ val += ( *start ) - '0';
+ start++;
+ }
+ if ( *start == ',' ) start++;
+ *dest = (u_char)val;
+ return start;
+}
+
+static int
+keys_write_proc (PROC_WRITE_PROTOTYPE )
+{
+ int i, ret = count;
+ char *in_buff, *cp;
+ u_char *cp1;
+ if (count < 1 || count > 1800 )
+ return -EINVAL;
+ in_buff = ( char * ) __get_free_page ( GFP_KERNEL );
+ if ( !in_buff ) return -ENOMEM;
+ if (copy_from_user (in_buff, buffer, count ) ) {
+ free_page ( ( unsigned long ) in_buff );
+ return -EFAULT;
+ }
+ if (in_buff[count - 1] == '\n' ) count--;
+ in_buff[count] = '\0';
+ if ( count == 1 && *in_buff == 'd' ) {
+ free_page ( ( unsigned long ) in_buff );
+ set_key_info( key_defaults, key_buf );
+ return ret;
+ }
+ cp = in_buff;
+ cp1 = (u_char *)in_buff;
+ for ( i = 0; i < 3; i++ ) {
+ cp = s2uchar( cp, cp1 );
+ cp1++;
+ }
+ i = (int)cp1[-2]+1;
+ i *= (int)cp1[-1]+1;
+ i+= 2; /* 0 and last map ver */
+ if ( cp1[-3] != KEY_MAP_VER || cp1[-1] > 10 ||
+ i+SHIFT_TBL_SIZE+4 >= sizeof(key_buf ) ) {
+pr_warn( "i %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1] );
+ free_page ( ( unsigned long ) in_buff );
+ return -EINVAL;
+ }
+ while ( --i >= 0 ) {
+ cp = s2uchar( cp, cp1 );
+ cp1++;
+ if ( !(*cp) ) break;
+ }
+ if ( i != 0 || cp1[-1] != KEY_MAP_VER || cp1[-2] != 0 ) {
+ ret = -EINVAL;
+pr_warn( "end %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1] );
+ } else {
+ if ( set_key_info( in_buff, key_buf ) ) {
+ set_key_info( key_defaults, key_buf );
+ ret = -EINVAL;
+pr_warn( "set key failed\n" );
+ }
+ }
+ free_page ( ( unsigned long ) in_buff );
+ return ret;
+}
+
+// this is the handler for /proc/speakup/version
+static int
+version_read_proc (PROC_READ_PROTOTYPE )
+{
+ int len = sprintf (page, "%s\n", SPEAKUP_VERSION );
+ if ( synth != NULL )
+ len += sprintf( page+len, "synth %s version %s\n",
+ synth->name, synth->version );
+ *start = 0;
+ *eof = 1;
+ return len;
+}
+
+// this is the read handler for /proc/speakup/characters
+static int
+chars_read_proc (PROC_READ_PROTOTYPE )
+{
+ int i, len = 0;
+ off_t begin = 0;
+ char *cp;
+ for (i = 0; i < 256; i++ ) {
+ cp = (characters[i] ) ? characters[i] : "NULL";
+ len += sprintf (page + len, "%d\t%s\n", i, cp );
+ if (len + begin > off + count )
+ break;
+ if (len + begin < off ) {
+ begin += len;
+ len = 0;
+ }
+ }
+ if (i >= 256 )
+ *eof = 1;
+ if (off >= len + begin )
+ return 0;
+ *start = page + (off - begin );
+ return ((count < begin + len - off ) ? count : begin + len - off );
+}
+
+static volatile int chars_timer_active = 0; // indicates when timer is set
+static declare_timer( chars_timer );
+
+static inline void
+chars_stop_timer (void )
+{
+ if (chars_timer_active )
+ stop_timer ( chars_timer );
+}
+
+static int strings, rejects, updates;
+
+static void
+show_char_results (u_long data )
+{
+ int len;
+ char buf[80];
+ chars_stop_timer ( );
+ len = sprintf (buf, " updated %d of %d character descriptions\n",
+ updates, strings );
+ if (rejects )
+ sprintf (buf + (len-1), " with %d reject%s\n",
+ rejects, rejects > 1 ? "s" : "" );
+ printk( buf );
+}
+
+/* this is the write handler for /proc/speakup/silent */
+static int
+silent_write_proc (PROC_WRITE_PROTOTYPE )
+{
+ int currcons = fg_console;
+ char ch = 0, shut;
+ if (count > 0 || count < 3 ) {
+ get_user (ch, buffer );
+ if ( ch == '\n' ) ch = '0';
+ }
+ if ( ch < '0' || ch > '7' ) {
+ pr_warn ( "silent value not in range (0,7)\n" );
+ return count;
+ }
+ if ( (ch&2) ) {
+ shut = 1;
+ do_flush( );
+ } else shut = 0;
+ if ( (ch&4) ) shut |= 0x40;
+ if ( (ch&1) )
+ spk_shut_up |= shut;
+ else spk_shut_up &= ~shut;
+ return count;
+}
+
+// this is the write handler for /proc/speakup/characters
+static int
+chars_write_proc (PROC_WRITE_PROTOTYPE )
+{
+#define max_desc_len 72
+ static int cnt = 0, state = 0;
+ static char desc[max_desc_len + 1];
+ static u_long jiff_last = 0;
+ short i = 0, num;
+ int len;
+ char ch, *cp, *p_new;
+ // reset certain vars if enough time has elapsed since last called
+ if (jiffies - jiff_last > 10 ) {
+ cnt = state = strings = rejects = updates = 0;
+ }
+ jiff_last = jiffies;
+get_more:
+ desc[cnt] = '\0';
+ state = 0;
+ for (; i < count && state < 2; i++ ) {
+ get_user (ch, buffer + i );
+ if ( ch == '\n' ) {
+ desc[cnt] = '\0';
+ state = 2;
+ } else if (cnt < max_desc_len )
+ desc[cnt++] = ch;
+ }
+ if (state < 2 ) return count;
+ cp = desc;
+ while ( *cp && *cp <= SPACE ) cp++;
+ if ((!cnt ) || strchr ("dDrR", *cp ) ) {
+ reset_default_chars ( );
+ pr_info( "character descriptions reset to defaults\n" );
+ cnt = 0;
+ return count;
+ }
+ cnt = 0;
+ if (*cp == '#' ) goto get_more;
+ num = -1;
+ cp = speakup_s2i(cp, &num );
+ while ( *cp && *cp <= SPACE ) cp++;
+ if (num < 0 || num > 255 ) { // not in range
+ rejects++;
+ strings++;
+ goto get_more;
+ }
+ if (num >= 27 && num <= 31 ) goto get_more;
+ if (!strcmp(cp, characters[num] ) ) {
+ strings++;
+ goto get_more;
+ }
+ len = strlen(cp );
+ if (characters[num] == default_chars[num] )
+ p_new = (char * ) kmalloc (sizeof (char ) * len+1, GFP_KERNEL );
+ else if ( strlen(characters[num] ) >= len )
+ p_new = characters[num];
+ else {
+ kfree(characters[num] );
+ characters[num] = default_chars[num];
+ p_new = (char * ) kmalloc (sizeof (char ) * len+1, GFP_KERNEL );
+ }
+ if (!p_new ) return -ENOMEM;
+ strcpy ( p_new, cp );
+ characters[num] = p_new;
+ updates++;
+ strings++;
+ if (i < count ) goto get_more;
+ chars_stop_timer ( );
+ init_timer (&chars_timer );
+ chars_timer.function = show_char_results;
+ chars_timer.expires = jiffies + 5;
+ start_timer (chars_timer );
+ chars_timer_active++;
+ return count;
+}
+
+static int
+bits_read_proc (PROC_READ_PROTOTYPE )
+{
+ int i;
+ var_header *p_header = (var_header * )data;
+ proc_var *var = p_header->data;
+ bits_data *pb = &punc_info[var->value];
+ short mask = pb->mask;
+ char *cp = page;
+ *start = 0;
+ *eof = 1;
+ for ( i = 33; i < 128; i++ ) {
+ if ( !(spk_chartab[i]&mask ) ) continue;
+ *cp++ = (char )i;
+ }
+ *cp++ = '\n';
+ return cp-page;
+}
+
+/* set_mask_bits sets or clears the punc/delim/repeat bits,
+ * if input is null uses the defaults.
+ * values for how: 0 clears bits of chars supplied,
+ * 1 clears allk, 2 sets bits for chars */
+
+int
+set_mask_bits( const char *input, const int which, const int how )
+{
+ u_char *cp;
+ short mask = punc_info[which].mask;
+ if ( how&1 ) {
+ for ( cp = (u_char * )punc_info[3].value; *cp; cp++ )
+ spk_chartab[*cp] &= ~mask;
+ }
+ cp = (u_char * )input;
+ if ( cp == 0 ) cp = punc_info[which].value;
+ else {
+ for ( ; *cp; cp++ ) {
+ if ( *cp < SPACE ) break;
+ if ( mask < PUNC ) {
+ if ( !(spk_chartab[*cp]&PUNC) ) break;
+ } else if ( (spk_chartab[*cp]&B_NUM) ) break;
+ }
+ if ( *cp ) return -EINVAL;
+ cp = (u_char * )input;
+ }
+ if ( how&2 ) {
+ for ( ; *cp; cp++ )
+ if ( *cp > SPACE ) spk_chartab[*cp] |= mask;
+ } else {
+ for ( ; *cp; cp++ )
+ if ( *cp > SPACE ) spk_chartab[*cp] &= ~mask;
+ }
+ return 0;
+}
+
+static bits_data *pb_edit = NULL;
+
+static int edit_bits (int currcons, u_char type, u_char ch, u_short key )
+{
+ short mask = pb_edit->mask, ch_type = spk_chartab[ch];
+ if ( type != KT_LATIN || (ch_type&B_NUM ) || ch < SPACE ) return -1;
+ if ( ch == SPACE ) {
+ synth_write_msg( "edit done" );
+ special_handler = NULL;
+ return 1;
+ }
+ if ( mask < PUNC && !(ch_type&PUNC) ) return -1;
+ spk_chartab[ch] ^= mask;
+ speak_char( ch );
+ synth_write_msg( (spk_chartab[ch]&mask ) ? " on" : " off" );
+ return 1;
+}
+
+static int
+bits_write_proc (PROC_WRITE_PROTOTYPE )
+{
+ var_header *p_header = (var_header * )data;
+ proc_var *var = p_header->data;
+ int ret = count;
+ char punc_buf[100];
+ if (count < 1 || count > 99 )
+ return -EINVAL;
+ if (copy_from_user (punc_buf, buffer, count ) )
+ return -EFAULT;
+ if (punc_buf[count - 1] == '\n' )
+ count--;
+ punc_buf[count] = '\0';
+ if ( *punc_buf == 'd' || *punc_buf == 'r' )
+ count = set_mask_bits( 0, var->value, 3 );
+ else
+ count = set_mask_bits( punc_buf, var->value, 3 );
+ if ( count < 0 ) return count;
+ return ret;
+}
+
+// this is the read handler for /proc/speakup/synth
+static int
+synth_read_proc (PROC_READ_PROTOTYPE )
+{
+ int len;
+ if ( synth == NULL ) strcpy( synth_name, "none" );
+ else strcpy( synth_name, synth->name );
+ len = sprintf (page, "%s\n", synth_name );
+ *start = 0;
+ *eof = 1;
+ return len;
+}
+
+// this is the write handler for /proc/speakup/synth
+static int
+synth_write_proc (PROC_WRITE_PROTOTYPE )
+{
+ int ret = count;
+ char new_synth_name[10];
+ const char *old_name = ( synth != NULL ) ? synth->name : "none";
+ if (count < 2 || count > 9 )
+ return -EINVAL;
+ if (copy_from_user (new_synth_name, buffer, count ) )
+ return -EFAULT;
+ if (new_synth_name[count - 1] == '\n' )
+ count--;
+ new_synth_name[count] = '\0';
+ strlwr (new_synth_name );
+ if (!strcmp (new_synth_name, old_name ) ) {
+ pr_warn ( "%s already in use\n", new_synth_name );
+ return ret;
+ }
+ if ( synth_init( new_synth_name ) == 0 ) return ret;
+ pr_warn( "failed to init synth %s\n", new_synth_name );
+ return -ENODEV;
+}
+
+proc_var spk_proc_vars[] = {
+ { VERSION, version_read_proc, 0, 0 },
+ { SILENT, 0, silent_write_proc, 0 },
+ { CHARS, chars_read_proc, chars_write_proc, 0 },
+ { SYNTH, synth_read_proc, synth_write_proc, 0 },
+ { KEYMAP, keys_read_proc, keys_write_proc, 0 },
+ { PUNC_SOME, bits_read_proc, bits_write_proc, 1 },
+ { PUNC_MOST, bits_read_proc, bits_write_proc, 2 },
+ { PUNC_ALL, bits_read_proc, 0, 3 },
+ { DELIM, bits_read_proc, bits_write_proc, 4 },
+ { REPEATS, bits_read_proc, bits_write_proc, 5 },
+ { EXNUMBER, bits_read_proc, bits_write_proc, 6 },
+ { -1, 0, 0, 0 }
+};
+
+#endif // CONFIG_PROC_FS
+
+#ifdef CONFIG_SPEAKUP
+
+void __init
+speakup_init (int currcons )
+{
+ spk_t *first_console = (spk_t *) alloc_bootmem (spk_size+1 );
+ speakup_open( currcons, first_console );
+}
+
+#endif
+
+void
+speakup_allocate (int currcons )
+{
+ if ( speakup_console[currcons] == NULL ) {
+ speakup_console[currcons] = (spk_t *) kmalloc (spk_size + 1,
+ GFP_KERNEL );
+ if ( speakup_console[currcons] == NULL ) return;
+ memset( speakup_console[currcons], 0, spk_size );
+ speakup_date( currcons);
+ } else if ( !spk_parked ) speakup_date( currcons);
+}
+
+static void
+speakup_date (int currcons )
+{
+ spk_x = spk_cx = x;
+ spk_y = spk_cy = y;
+ spk_pos = spk_cp = pos;
+ spk_old_attr = spk_attr;
+ spk_attr = ((scr_readw ((u_short * ) spk_pos ) & 0xff00 ) >> 8 );
+}
+
+static u_char is_cursor = 0;
+static u_long old_cursor_pos, old_cursor_x, old_cursor_y;
+static int cursor_con;
+volatile int cursor_timer_active = 0;
+
+void
+cursor_stop_timer(void )
+{
+ if (!cursor_timer_active ) return;
+ stop_timer ( cursor_timer );
+ cursor_timer_active = 0;
+}
+
+static void
+handle_cursor( KBD_PROTO )
+{
+ int currcons = fg_console;
+ (*do_cursor)( KBD_ARGS );
+ spk_parked &= 0xfe;
+ if ( synth == NULL || up_flag || spk_shut_up || cursor_track == 0 )
+ return;
+ spk_shut_up &= 0xfe;
+ if ( no_intr ) do_flush( );
+/* the key press flushes if !no_inter but we want to flush on cursor
+ * moves regardless of no_inter state */
+ is_cursor = value+1;
+ old_cursor_pos = pos;
+ old_cursor_x = x;
+ old_cursor_y = y;
+ cursor_con = currcons;
+ cursor_stop_timer( );
+ cursor_timer.expires = jiffies + cursor_timeout;
+ start_timer (cursor_timer );
+ cursor_timer_active++;
+}
+
+static void
+cursor_done (u_long data )
+{
+ int currcons = cursor_con;
+ cursor_stop_timer( );
+ if (cursor_con != fg_console ) {
+ is_cursor = 0;
+ return;
+ }
+ speakup_date (currcons );
+ if ( win_enabled ) {
+ if ( x >= win_left && x <= win_right &&
+ y >= win_top && y <= win_bottom ) {
+ spk_keydown = is_cursor = 0;
+ return;
+ }
+ }
+ if ( is_cursor == 1 || is_cursor == 4 )
+ say_line_from_to (currcons, 0, video_num_columns, 0 );
+ else say_char ( currcons );
+ spk_keydown = is_cursor = 0;
+}
+
+/* These functions are the interface to speakup from the actual kernel code. */
+
+void
+speakup_bs (int currcons )
+{
+ if (!spk_parked )
+ speakup_date (currcons );
+ if ( spk_shut_up || synth == NULL ) return;
+ if ( currcons == fg_console && spk_keydown ) {
+ spk_keydown = 0;
+ if (!is_cursor ) say_char (currcons );
+ }
+}
+
+void
+speakup_con_write (int currcons, const char *str, int len )
+{
+ if (spk_shut_up || (currcons != fg_console ) )
+ return;
+ if (bell_pos && spk_keydown && (x == bell_pos - 1 ) )
+ bleep(3 );
+ if (synth == NULL || is_cursor ) return;
+ if ( win_enabled ) {
+ if ( x >= win_left && x <= win_right &&
+ y >= win_top && y <= win_bottom ) return;
+ }
+ spkup_write (str, len );
+}
+
+void
+speakup_con_update (int currcons )
+{
+ if ( speakup_console[currcons] == NULL || spk_parked )
+ return;
+ speakup_date (currcons );
+}
+
+static void
+handle_spec( KBD_PROTO )
+{
+ int currcons = fg_console, on_off = 2;
+ char *label;
+static const char *lock_status[] = { " off", " on", "" };
+ (*do_spec)( KBD_ARGS );
+ if ( synth == NULL || up_flag || spk_killed ) return;
+ spk_shut_up &= 0xfe;
+ if ( no_intr ) do_flush( );
+ switch (value ) {
+ case KVAL( K_CAPS ):
+ label = "caps lock";
+ on_off = (vc_kbd_led(kbd , VC_CAPSLOCK ) );
+ break;
+ case KVAL( K_NUM ):
+ label = "num lock";
+ on_off = (vc_kbd_led(kbd , VC_NUMLOCK ) );
+ break;
+ case KVAL( K_HOLD ):
+ label = "scroll lock";
+ on_off = (vc_kbd_led(kbd , VC_SCROLLOCK ) );
+ break;
+ default:
+ spk_parked &= 0xfe;
+ return;
+ }
+ synth_write_string ( label );
+ synth_write_msg ( lock_status[on_off] );
+}
+
+static int
+inc_dec_var( u_char value )
+{
+ var_header *p_header;
+ num_var *var_data;
+ char num_buf[32];
+ char *cp = num_buf, *pn;
+ int var_id = (int)value - VAR_START;
+ int how = (var_id&1) ? E_INC : E_DEC;
+ var_id = var_id/2+FIRST_SET_VAR;
+ p_header = get_var_header( var_id );
+ if ( p_header == NULL ) return -1;
+ if ( p_header->var_type != VAR_NUM ) return -1;
+ var_data = p_header->data;
+ if ( set_num_var( 1, p_header, how ) != 0 )
+ return -1;
+ if ( !spk_close_press ) {
+ for ( pn = p_header->name; *pn; pn++ ) {
+ if ( *pn == '_' ) *cp = SPACE;
+ else *cp++ = *pn;
+ }
+ }
+ sprintf( cp, " %d ", (int)var_data->value );
+ synth_write_string( num_buf );
+ return 0;
+}
+
+static void
+speakup_win_set (int currcons )
+{
+ char info[40];
+ if ( win_start > 1 ) {
+ synth_write_msg( "window already set, clear then reset" );
+ return;
+ }
+ if ( spk_x < win_left || spk_y < win_top ) {
+ synth_write_msg( "error end before start" );
+ return;
+ }
+ if ( win_start && spk_x == win_left && spk_y == win_top ) {
+ win_left = 0;
+ win_right = video_num_columns-1;
+ win_bottom = spk_y;
+ sprintf( info, "window is line %d", (int)win_top+1 );
+ } else {
+ if ( !win_start ) {
+ win_top = spk_y;
+ win_left = spk_x;
+ } else {
+ win_bottom = spk_y;
+ win_right = spk_x;
+ }
+ sprintf( info, "%s at line %d, column %d",
+ (win_start) ? "end" : "start",
+ (int)spk_y+1, (int)spk_x+1 );
+ }
+ synth_write_msg( info );
+ win_start++;
+}
+
+static void
+speakup_win_clear (int currcons )
+{
+ win_top = win_bottom = 0;
+ win_left = win_right = 0;
+ win_start = 0;
+ synth_write_msg( "window cleared" );
+}
+
+static void
+speakup_win_enable (int currcons )
+{
+ if ( win_start < 2 ) {
+ synth_write_msg( "no window" );
+ return;
+ }
+ win_enabled ^= 1;
+ if ( win_enabled ) synth_write_msg( "window silenced" );
+ else synth_write_msg( "window silence disabled" );
+}
+
+static void
+speakup_bits (int currcons )
+{
+ int val = this_speakup_key - ( FIRST_EDIT_BITS - 1 );
+ if ( special_handler != NULL || val < 1 || val > 6 ) {
+ synth_write_msg( "error" );
+ return;
+ }
+ pb_edit = &punc_info[val];
+ sprintf( buf, "edit %s, press space when done", pb_edit->name );
+ synth_write_msg( buf );
+ special_handler = edit_bits;
+}
+
+static int handle_goto (int currcons, u_char type, u_char ch, u_short key )
+{
+ static u_char *goto_buf = "\0\0\0\0\0\0";
+ static int num = 0;
+ short maxlen, go_pos;
+ char *cp;
+ if ( type == KT_SPKUP && ch == SPEAKUP_GOTO ) goto do_goto;
+ if ( type == KT_LATIN && ch == '\n' ) goto do_goto;
+ if ( type != 0 ) goto oops;
+ if (ch == 8 ) {
+ if ( num == 0 ) return -1;
+ ch = goto_buf[--num];
+ goto_buf[num] = '\0';
+ spkup_write( &ch, 1 );
+ return 1;
+}
+ if ( ch < '+' || ch > 'y' ) goto oops;
+ goto_buf[num++] = ch;
+ goto_buf[num] = '\0';
+ spkup_write( &ch, 1 );
+ maxlen = ( *goto_buf >= '0' ) ? 3 : 4;
+ if ((ch == '+' || ch == '-' ) && num == 1 ) return 1;
+ if (ch >= '0' && ch <= '9' && num < maxlen ) return 1;
+ if ( num < maxlen-1 || num > maxlen ) goto oops;
+ if ( ch < 'x' || ch > 'y' ) {
+oops:
+ if (!spk_killed )
+ synth_write_msg (" goto canceled" );
+ goto_buf[num = 0] = '\0';
+ special_handler = NULL;
+ return 1;
+ }
+ cp = speakup_s2i (goto_buf, &go_pos );
+ goto_pos = (u_long)go_pos;
+ if (*cp == 'x' ) {
+ if (*goto_buf < '0' ) goto_pos += spk_x;
+ else goto_pos--;
+ if (goto_pos < 0 ) goto_pos = 0;
+ if (goto_pos >= video_num_columns )
+ goto_pos = video_num_columns-1;
+ goto_x = 1;
+ } else {
+ if (*goto_buf < '0' ) goto_pos += spk_y;
+ else goto_pos--;
+ if (goto_pos < 0 ) goto_pos = 0;
+ if (goto_pos >= video_num_lines ) goto_pos = video_num_lines-1;
+ goto_x = 0;
+ }
+ goto_buf[num = 0] = '\0';
+do_goto:
+ special_handler = NULL;
+ spk_parked |= 0x01;
+ if ( goto_x ) {
+ spk_pos -= spk_x * 2;
+ spk_x = goto_pos;
+ spk_pos += goto_pos * 2;
+ say_word( currcons );
+ } else {
+ spk_y = goto_pos;
+ spk_pos = origin + ( goto_pos * video_size_row );
+ say_line( currcons );
+ }
+ return 1;
+}
+
+static void
+speakup_goto (int currcons )
+{
+ if ( special_handler != NULL ) {
+ synth_write_msg( "error" );
+ return;
+ }
+ synth_write_msg( "go to?" );
+ special_handler = handle_goto;
+ return;
+}
+
+static void
+load_help ( void *dummy )
+{
+ request_module( "speakup_keyhelp" );
+ if ( help_handler ) {
+ (*help_handler)(0, KT_SPKUP, SPEAKUP_HELP, 0 );
+ } else synth_write_string( "help module not found" );
+}
+
+#if (LINUX_VERSION_CODE >= 132419)
+static DECLARE_WORK(ld_help, load_help, NULL);
+#define schedule_help schedule_work
+#else
+static struct tq_struct ld_help = { routine: load_help, };
+#define schedule_help schedule_task
+#endif
+
+static void
+speakup_help (int currcons )
+{
+ if ( help_handler == NULL ) {
+/* we can't call request_module from this context so schedule it*/
+/* **** note kernel hangs and my wrath will be on you */
+ schedule_help (&ld_help);
+ return;
+ }
+ (*help_handler)(currcons, KT_SPKUP, SPEAKUP_HELP, 0 );
+}
+
+static void
+do_nothing (int currcons )
+{
+ return; /* flush done in do_spkup */
+}
+static u_char key_speakup = 0, spk_key_locked = 0;
+
+static void
+speakup_lock (int currcons )
+{
+ if ( !spk_key_locked )
+ spk_key_locked = key_speakup = 16;
+ else spk_key_locked = key_speakup = 0;
+}
+
+typedef void (*spkup_hand )(int );
+spkup_hand spkup_handler[] = { /* must be ordered same as defines in speakup.h */
+ do_nothing, speakup_goto, speech_kill, speakup_shut_up,
+ speakup_cut, speakup_paste, say_first_char, say_last_char,
+ say_char, say_prev_char, say_next_char,
+ say_word, say_prev_word, say_next_word,
+ say_line, say_prev_line, say_next_line,
+ top_edge, bottom_edge, left_edge, right_edge,
+ spell_word, spell_word, say_screen,
+ say_position, say_attributes,
+ speakup_off, speakup_parked, say_line, // this is for indent
+ say_from_top, say_to_bottom,
+ say_from_left, say_to_right,
+ say_char_num, speakup_bits, speakup_bits, say_phonetic_char,
+ speakup_bits, speakup_bits, speakup_bits,
+ speakup_win_set, speakup_win_clear, speakup_win_enable, speakup_win_say,
+ speakup_lock, speakup_help, toggle_cursoring, NULL
+};
+
+void do_spkup( int currcons,u_char value )
+{
+ if (spk_killed && value != SPEECH_KILL ) return;
+ spk_keydown = 0;
+ spk_lastkey = 0;
+ spk_shut_up &= 0xfe;
+ this_speakup_key = value;
+ if (value < SPKUP_MAX_FUNC && spkup_handler[value] ) {
+ do_flush( );
+ (*spkup_handler[value] )(currcons );
+ } else {
+ if ( inc_dec_var( value ) < 0 )
+ bleep( 9 );
+ }
+}
+
+ static const char *pad_chars = "0123456789+-*/\015,.?()";
+
+int
+#if (LINUX_VERSION_CODE < 132419)
+speakup_key ( int shift_state, u_char keycode, u_short keysym, u_char up_flag )
+#else
+speakup_key (struct vc_data *vc, int shift_state, int keycode, u_short keysym, int up_flag, struct pt_regs *regs )
+#endif
+{
+ int currcons = fg_console;
+ u_char *key_info;
+ u_char type = KTYP( keysym ), value = KVAL( keysym ), new_key = 0;
+ u_char shift_info, offset;
+#if (LINUX_VERSION_CODE >= 132419)
+ tty = vc_cons[currcons].d->vc_tty;
+#endif
+ if ( synth == NULL ) return 0;
+ if ( type >= 0xf0 ) type -= 0xf0;
+ if ( type == KT_PAD && (vc_kbd_led(kbd , VC_NUMLOCK ) ) ) {
+ if ( up_flag ) {
+ spk_keydown = 0;
+ return 0;
+ }
+ value = spk_lastkey = pad_chars[value];
+ spk_keydown++;
+ spk_parked &= 0xfe;
+ goto no_map;
+ }
+ if ( keycode >= MAX_KEY ) goto no_map;
+ if ( ( key_info = our_keys[keycode] ) == 0 ) goto no_map;
+ shift_info = ( shift_state&0x0f ) + key_speakup;
+ offset = shift_table[shift_info];
+ if ( offset && ( new_key = key_info[offset] ) ) {
+ if ( new_key == SPK_KEY ) {
+ if ( !spk_key_locked )
+ key_speakup = ( up_flag ) ? 0 : 16;
+ if ( up_flag || spk_killed ) return 1;
+ spk_shut_up &= 0xfe;
+ do_flush( );
+ return 1;
+ }
+ if ( up_flag ) return 1;
+ if ( last_keycode == keycode && last_spk_jiffy+MAX_DELAY > jiffies ) {
+ spk_close_press = 1;
+ offset = shift_table[shift_info+32];
+/* double press? */
+ if ( offset && key_info[offset] )
+ new_key = key_info[offset];
+ }
+ last_keycode = keycode;
+ last_spk_jiffy = jiffies;
+ type = KT_SPKUP;
+ value = new_key;
+ }
+no_map:
+ if ( type == KT_SPKUP && special_handler == NULL ) {
+ do_spkup( currcons, new_key );
+ spk_close_press = 0;
+ return 1;
+ }
+ if ( up_flag || spk_killed || type == KT_SHIFT ) return 0;
+ spk_shut_up &= 0xfe;
+ if (!no_intr ) do_flush( );
+ if ( special_handler ) {
+ int status;
+ if ( type == KT_SPEC && value == 1 ) {
+ value = '\n';
+ type = KT_LATIN;
+ } else if ( type == KT_LETTER ) type = KT_LATIN;
+ else if ( value == 0x7f ) value = 8; /* make del = backspace */
+ status = (*special_handler)(currcons, type, value, keycode );
+ spk_close_press = 0;
+ if ( status < 0 ) bleep( 9 );
+ return status;
+ }
+ last_keycode = 0;
+ return 0;
+}
+
+#ifdef MODULE
+
+extern void proc_speakup_init( void );
+extern void proc_speakup_remove( void );
+extern void speakup_set_addresses ( spk_con_func, spk_con_func, spk_write_func, spk_con_func, spk_key_func);
+
+static void __exit mod_speakup_exit( void )
+{
+ int i;
+ key_handler[KT_LATIN] = do_latin;
+ key_handler[KT_SPEC] = do_spec;
+ key_handler[KT_CUR] = do_cursor;
+ key_handler[KT_SHIFT] = do_shift;
+ speakup_set_addresses( NULL, NULL, NULL, NULL, NULL );
+ synth_release( );
+ proc_speakup_remove( );
+ for (i = 0; i < 256; i++ ) {
+ if (characters[i] != default_chars[i] )
+ kfree (characters[i] );
+ }
+ for ( i = 0; speakup_console[i]; i++) {
+ kfree( speakup_console[i] );
+ speakup_console[i] = NULL;
+ }
+}
+
+static int __init mod_speakup_init( void )
+{
+int i;
+ spk_t *first_console = (spk_t *) kmalloc (spk_size + 1, GFP_KERNEL );
+ speakup_open( fg_console, first_console );
+for ( i = 0; vc_cons[i].d; i++)
+ speakup_allocate(i);
+ speakup_set_addresses( speakup_allocate, speakup_bs,
+ speakup_con_write, speakup_con_update, speakup_key );
+ proc_speakup_init( );
+ return 0;
+}
+
+module_init( mod_speakup_init );
+module_exit( mod_speakup_exit );
+
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^vt.c.patch linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^vt.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/drivers^char^vt.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/drivers^char^vt.c.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,18 @@
+--- /usr/src/linux-2.4.30/drivers/char/vt.c.orig 2005-04-19 09:48:50.000000000 -0400
++++ drivers/char/vt.c 2005-04-19 09:48:51.000000000 -0400
+@@ -13,6 +13,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+ #include
+ #include
+@@ -150,6 +151,7 @@
+ }
+
+ void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
++EXPORT_SYMBOL(kd_mksound);
+ int (*kbd_rate)(struct kbd_repeat *rep) = _kbd_rate;
+
+ #define i (tmp.kb_index)
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/fs^proc^root.c.patch linux-2.4.30/drivers/char/speakup/diff-v24/fs^proc^root.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/fs^proc^root.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/fs^proc^root.c.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,12 @@
+--- /usr/src/linux-2.4.30/fs/proc/root.c.orig 2005-04-19 09:48:50.000000000 -0400
++++ fs/proc/root.c 2005-04-19 09:48:51.000000000 -0400
+@@ -57,6 +57,9 @@
+ proc_mkdir("openprom", 0);
+ #endif
+ proc_tty_init();
++#ifdef CONFIG_SPEAKUP /* console speech output */
++ proc_speakup_init();
++#endif /* speakup */
+ #ifdef CONFIG_PROC_DEVICETREE
+ proc_device_tree_init();
+ #endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/include^linux^keyboard.h.patch linux-2.4.30/drivers/char/speakup/diff-v24/include^linux^keyboard.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/include^linux^keyboard.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/include^linux^keyboard.h.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.4.30/include/linux/keyboard.h.orig 2005-04-19 09:48:50.000000000 -0400
++++ include/linux/keyboard.h 2005-04-19 10:11:19.000000000 -0400
+@@ -44,6 +44,7 @@
+ #define KT_ASCII 9
+ #define KT_LOCK 10
+ #define KT_SLOCK 12
++#define KT_SPKUP 14 // is ignore if synth null
+
+ #define K(t,v) (((t)<<8)|(v))
+ #define KTYP(x) ((x) >> 8)
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/include^linux^proc_fs.h.patch linux-2.4.30/drivers/char/speakup/diff-v24/include^linux^proc_fs.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/include^linux^proc_fs.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/include^linux^proc_fs.h.patch 2005-04-19 09:26:22.000000000 -0700
@@ -0,0 +1,13 @@
+--- /usr/src/linux-2.4.30/include/linux/proc_fs.h.orig 2005-04-19 09:48:51.000000000 -0400
++++ include/linux/proc_fs.h 2005-04-19 10:10:27.000000000 -0400
+@@ -123,6 +123,10 @@
+ extern void proc_tty_register_driver(struct tty_driver *driver);
+ extern void proc_tty_unregister_driver(struct tty_driver *driver);
+
++#ifdef CONFIG_SPEAKUP /* console speech output */
++extern void proc_speakup_init(void);
++#endif /* speakup */
++
+ /*
+ * proc_devtree.c
+ */
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v24/include^linux^speakup.h.copy linux-2.4.30/drivers/char/speakup/diff-v24/include^linux^speakup.h.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v24/include^linux^speakup.h.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v24/include^linux^speakup.h.copy 2003-06-12 11:30:01.000000000 -0700
@@ -0,0 +1,31 @@
+#ifndef __SPEAKUP_H
+#define __SPEAKUP_H
+
+#include
+struct kbd_struct;
+
+/* how about some prototypes! */
+extern int do_spk_ioctl(int,unsigned char *data,int,void *);
+
+#if defined(CONFIG_SPEAKUP)
+extern void speakup_init(int);
+extern void speakup_allocate(int);
+extern void speakup_bs(int);
+extern void speakup_con_write(int, const char *, int);
+extern void speakup_con_update(int);
+extern int speakup_key(int, u_char, u_short, u_char );
+#elif defined(CONFIG_SPEAKUP_MODULE)
+typedef void (*spk_con_func)(int );
+typedef void (*spk_write_func)(int, const char *, int);
+typedef int (*spk_key_func)(int, u_char, u_short, u_char );
+extern void speakup_set_addresses( spk_con_func allocate, spk_con_func bs,
+ spk_write_func con_write, spk_con_func con_update, spk_key_func key );
+#define speakup_init(currcons)
+#else
+#define speakup_allocate(currcons)
+#define speakup_bs(currcons)
+#define speakup_con_write(currcons, str, len)
+#define speakup_con_update(currcons)
+#define speakup_init(currcons)
+#endif
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/CVS/Entries linux-2.4.30/drivers/char/speakup/diff-v25/CVS/Entries
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/CVS/Entries 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/CVS/Entries 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1,23 @@
+/Documentation^speakup^DefaultKeyAssignments.copy/1.1/Fri May 16 18:04:19 2003//
+/Documentation^speakup^INSTALLATION.copy/1.1/Fri May 16 18:04:19 2003//
+/Documentation^speakup^README.copy/1.1/Fri May 16 18:04:19 2003//
+/Documentation^speakup^keymap-tutorial.copy/1.1/Fri May 16 18:04:19 2003//
+/MAINTAINERS.patch/1.10/Tue Jul 8 12:51:40 2003//
+/arch^alpha^Kconfig.patch/1.10/Tue Jul 8 12:51:40 2003//
+/arch^arm^Kconfig.patch/1.10/Tue Jul 8 12:51:40 2003//
+/arch^i386^Kconfig.patch/1.10/Tue Jul 8 12:51:40 2003//
+/arch^m68k^Kconfig.patch/1.10/Tue Jul 8 12:51:40 2003//
+/arch^mips^Kconfig.patch/1.10/Tue Jul 8 12:51:40 2003//
+/arch^ppc^Kconfig.patch/1.10/Tue Jul 8 12:51:40 2003//
+/arch^sparc64^Kconfig.patch/1.10/Tue Jul 8 12:51:40 2003//
+/arch^sparc^Kconfig.patch/1.10/Tue Jul 8 12:51:40 2003//
+/drivers^char^Makefile.patch/1.10/Tue Jul 8 12:51:40 2003//
+/drivers^char^keyboard.c.patch/1.10/Tue Jul 8 12:51:40 2003//
+/drivers^char^selection.c.patch/1.10/Tue Jul 8 12:51:40 2003//
+/drivers^char^vt.c.patch/1.10/Tue Jul 8 12:51:40 2003//
+/fs^proc^root.c.patch/1.10/Tue Jul 8 12:51:40 2003//
+/include^linux^keyboard.h.patch/1.11/Tue Jul 8 12:51:40 2003//
+/include^linux^miscdevice.h.patch/1.10/Tue Jul 8 12:51:40 2003//
+/include^linux^proc_fs.h.patch/1.10/Tue Jul 8 12:51:40 2003//
+/include^linux^speakup.h.copy/1.7/Tue Jul 8 12:51:40 2003//
+D
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/CVS/Repository linux-2.4.30/drivers/char/speakup/diff-v25/CVS/Repository
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/CVS/Repository 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/CVS/Repository 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1 @@
+speakup/diff-v25
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/CVS/Root linux-2.4.30/drivers/char/speakup/diff-v25/CVS/Root
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/CVS/Root 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/CVS/Root 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1 @@
+:pserver:anonymous@bumpy.braille.uwo.ca:/usr/src/CVS
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/Documentation^speakup^DefaultKeyAssignments.copy linux-2.4.30/drivers/char/speakup/diff-v25/Documentation^speakup^DefaultKeyAssignments.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/Documentation^speakup^DefaultKeyAssignments.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/Documentation^speakup^DefaultKeyAssignments.copy 2003-05-16 11:04:19.000000000 -0700
@@ -0,0 +1,46 @@
+This file is intended to give you an overview of the default keys used
+by speakup for it's review functions. You may change them to be
+anything you want but that will take some familiarity with key
+mapping.
+
+We have remapped the insert or zero key on the keypad to act as a
+shift key. Well, actually as an altgr key. So in the following list
+InsKeyPad-period means hold down the insert key like a shift key and
+hit the keypad period.
+
+KeyPad-8 Say current Line
+InsKeyPad-8 say from top of screen to reading cursor.
+KeyPad-7 Say Previous Line (UP one line)
+KeyPad-9 Say Next Line (down one line)
+KeyPad-5 Say Current Word
+InsKeyPad-5 Spell Current Word
+KeyPad-4 Say Previous Word (left one word)
+InsKeyPad-4 say from left edge of line to reading cursor.
+KeyPad-6 Say Next Word (right one word)
+InsKeyPad-6 Say from reading cursor to right edge of line.
+KeyPad-2 Say Current Letter
+InsKeyPad-2 say current letter phonetically
+KeyPad-1 Say Previous Character (left one letter)
+KeyPad-3 Say Next Character (right one letter)
+KeyPad-plus Say Entire Screen
+InsKeyPad-plus Say from reading cursor line to bottom of screen.
+KeyPad-Minus Park reading cursor (toggle)
+InsKeyPad-minus Say character hex and decimal value.
+KeyPad-period Say Position (current line, position and console)
+InsKeyPad-period say colour attributes of current position.
+InsKeyPad-9 Move reading cursor to top of screen (insert pgup)
+InsKeyPad-3 Move reading cursor to bottom of screen (insert pgdn)
+InsKeyPad-7 Move reading cursor to left edge of screen (insert home)
+InsKeyPad-1 Move reading cursor to right edge of screen (insert end)
+ControlKeyPad-1 Move reading cursor to last character on current line.
+KeyPad-Enter Shut Up (until another key is hit) and sync reading cursor
+InsKeyPad-Enter Shut Up (until toggled back on).
+InsKeyPad-star n go to line (y) or column (x). Where 'n' is any
+ allowed value for the row or column for your current screen.
+KeyPad-/ Mark and Cut screen region.
+InsKeyPad-/ Paste screen region into any console.
+
+Hitting any key while speakup is outputting speech will quiet the
+synth until it has caught up with what is being printed on the
+console.
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/Documentation^speakup^INSTALLATION.copy linux-2.4.30/drivers/char/speakup/diff-v25/Documentation^speakup^INSTALLATION.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/Documentation^speakup^INSTALLATION.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/Documentation^speakup^INSTALLATION.copy 2003-05-16 11:04:19.000000000 -0700
@@ -0,0 +1,108 @@
+This document assumes you have had some experience with kernel
+compilation and installation. If you have not, I recommend you get
+the kernel source and read the README and various documents in the
+linux/Documentation directory. In particular the Changes file to make
+sure you have the appropriate utilities needed for installing a 2.2.xx
+or 2.4xx kernel. It isn't as difficult as you might think. The
+kernel README is intimidating the first time but once you get the
+steps down, it's really pretty easy. Getting through the "make
+config" is the tedious bit.
+
+The first thing to do is to place a copy of the tarball in the /usr/src
+directory which is the directory the linux tree is located in as well.
+Next untar speakup by typing:
+
+tar zxf speakup-1.00.tar.gz
+cd speakup-1.00
+./install
+
+Note the dot-slash before the install. This will copy the speakup
+directory to the kernel tree and apply the various patches and
+components to the appropriate kernel files. Depending on how
+experienced you are with kernel compiling and hacking will determine
+whether you should bother looking at any failed patches. If this
+happens, you should probably write to the speakup mailing list for
+help or myself.
+
+If all of the patch hunks apply successfully then just continue with
+the standard steps to compile the kernel with:
+
+make mrproper
+make config
+
+When you get to the section console speech output, answer 'y' to the
+CONFIG_SPEAKUP prompt. You will be given a submenu with the list of
+synthesizers which are currently supported. You can include as many
+synths in the kernel as you wish but remember each one takes up kernel
+space. You can only choose one of the synths as the default or none,
+so just type dtlk or whatever is the correct string for the
+synthesizer you have. You will also be asked if you wish to build-in
+a speakup key map. If you do not say 'y' to this option you will need
+to load a speakup map at boot time with whichever mechanism your
+distribution uses for loading key maps.
+
+We have placed the speakup configuration options in make config just
+after the vga console choice. For the DoubleTalk PC driver included
+by Jim Van Zandt. I recommend you say no to that option. I have not
+tried configuring them both in, but I wouldn't be at all surprised if
+it didn't work.
+
+If all goes well up to this point you can continue with the compiling
+process by doing:
+
+make dep >dep.file 2>&1 &
+make bzImage >cc.file 2>&1 &
+make modules >mod.file 2>&1 &
+
+I always redirect output to the files dep.file and cc.file so I can
+look over the compilation record to make sure there are no errors and
+warnings.
+
+Okay, you are ready to install the newly compiled kernel. Make sure
+you make an linux.old entry in your lilo.conf file so you can recover
+if it blows up. next as root run "make modules_install" to install
+whatever modules you compiled and move the bzImage from
+/usr/src/linux/arch/i386/boot to wherever your kernel lives. Also
+move the System.map from /usr/src/linux to where your System.map
+lives. On our systems we use debian so we create an vmlinuz-speakup
+and System.map-speakup in our /boot directory and set the symbolic
+links vmlinuz and System.map in the root (/) directory to point to the
+images. Now type lilo to tell lilo to build the new booter file and
+install it.
+
+As of version 0.07, the keymap for speakup is automatically built in
+at compile time. If you have other keymaps installed at boot time,
+you might want to consider removing them before you reboot the system.
+
+If everything has gone OK up until now, cross your fingers and type:
+
+shutdown -r now
+
+Your system should start talking to you as soon as it starts booting.
+It will talk and talk and ... well, you might want to hit the
+keypad-enter key to tell it to shut up. You should also read the
+DefaultKeyAssignments file to learn the various review functions
+available.
+
+As of v-0.10 the speakup configuration options are in the
+/proc/speakup subtree. The individual options should be fairly
+obvious by their names such as rate, volume, punc_level and so forth.
+You can manipulate them by cat'ing or echoing new values to them such
+as:
+
+echo 9 >/proc/speakup/rate
+
+You can see what the current values are by cat'ing those files to the console:
+
+cat /proc/speakup/rate
+
+I have probably managed to overlook a whole whack of things because
+this is the, enter version number here, draft. Don't worry we'll get
+it right eventually. If you like the package you really should get on
+the mailing list and start participating in it's development.
+
+ Kirk
+
+email: kirk@braille.uwo.ca
+phone: (519) 679-6845 (home)
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/Documentation^speakup^README.copy linux-2.4.30/drivers/char/speakup/diff-v25/Documentation^speakup^README.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/Documentation^speakup^README.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/Documentation^speakup^README.copy 2003-05-16 11:04:19.000000000 -0700
@@ -0,0 +1,98 @@
+Welcome to the speakup project for the Speakup speech package for Linux.
+
+Speakup is written by Kirk Reiser and Andy Berdan. It is licensed
+under the GPL. If you don't already know, the GPL stands for the GNU
+General Public License. Which basically states that this code is free to
+copy, modify and distribute to anyone interested in playing with it.
+The one thing you may not do is turn any part of it into proprietary
+or commercial code without the permission of the author. That's me.
+
+If you are interested in being involved with the development of speech
+output for Linux you can subscribe to the Speakup mailing list by
+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.
+
+We are at a very early stage in the development of this package.
+Hopefully changes will happen often and many. The current files in
+this directory are:
+
+DefaultKeyAssignments # speakup's default review keys
+INSTALLATION # for installing speakup from the tar ball.
+README # this file
+keymap-tutorial # a tutorial on how to layout the keyboard
+
+Read the INSTALLATION file to learn how to apply the patches and the
+default.map for the keyboard. You should also read the Changes file.
+It really has any new things I've added since last time.
+
+There is no documentation in any of these files to instruct you what
+to do if something goes wrong with the patching or compilation. If
+you would like that information you will need to subscribe to the
+mailing list and ask for help, or write me kirk@braille.uwo.ca for
+help. I suggest the mailing list because I will probably tire quickly
+of answering the same questions over and over. You could always
+decide to dig-in and take on the task, and write documentation to help
+others.
+
+There also is a speakup reflector for the Speak Freely package, which
+many of us hang out on and discuss all sorts of topics from speakup
+problems to ALSA driver installation and just about anything else
+you'd like to talk about. The reflector is at lwl.braille.uwo.ca:4074
+with it's lwl page at lwl.braille.uwo.ca/speakup.html. Come and join
+us, it's fun!
+
+Acknowledgements:
+
+I am really very new at kernel hacking and screen review package
+writing, so I have depended heavily on other folks kindness to help me
+a long. No doubt I will continue to abuse them freely and others
+before this is a really good speech solution for Linux. (Oh Well!,
+somebody's got to do it.)
+
+Theodore Ts'o. He gave me a good discussion of unicode and UTF and
+the like. He doesn't even remember writing me about it.
+
+Alan Cox. He has answered many questions about scheduling and wait
+queues and timers along with code fragments and so on. I just wish I
+understood it all totally. He has also helped immensely in moving
+this package toward inclusion in the standard kernel tree. (Maybe next
+release!)
+
+Martin Mares. He pointed me in the right direction to figuring out
+the colour attributes and other useful tidbits.
+
+Paul McDermott. He really is the catalyst for me to actually get
+this all working. Besides I like seeing him bounce around and get all
+excited every time I have something new working.
+
+John Covici, He was the first person to actually attempt writing
+another synthesizer driver for speakup. It was the Speakout driver so
+it was also the first serial driver.
+
+Brian Borowski, he was the first person to actually write a speakup
+function other than Andy and I.
+
+Jim Danley, he has more or less become my main man in helping test
+code, add new features, bounce ideas off and generally become a good
+friend.
+
+Matt Campbell, he basically rewrote the drivers to be able to include
+all synths in the kernel at the same time. The distribution
+maintainers appreciate him a lot as well.
+
+Gene Collins, he was very helpful debugging the current release prior
+to its public showing. He has also worked hard educating others on
+the list and writing the ALSA mini howto.
+
+I would also like to really thank the folks that handle the
+distribution packages. I and many other people would not find access
+to speakup nearly so convenient without their efforts. They include
+Bill Acker, Tom Moore, Matt Campbell, Joe Norton and Joshua Lambert.
+
+There are probably many more I am forgetting right now. I guess I'll
+just have to add you all later.
+
+
+Happy Hacking!
+
+ Kirk
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/Documentation^speakup^keymap-tutorial.copy linux-2.4.30/drivers/char/speakup/diff-v25/Documentation^speakup^keymap-tutorial.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/Documentation^speakup^keymap-tutorial.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/Documentation^speakup^keymap-tutorial.copy 2003-05-16 11:04:19.000000000 -0700
@@ -0,0 +1,140 @@
+ Speakup Keymap Tutorial
+
+This is meant to be a basic tutorial on how to change the Linux keymap
+file to assign speakup review functions to desired keys. It is not
+intended to be a replacement for the loadkeys(8) or keymap(5) man
+pages.
+
+The basic lay-out of the keymap file is a series of lines with the
+following fields. The keyword keycode indicates this is the start of
+a new key assignment. It is then followed by a number which
+represents the actual key on the keyboard. That number is followed by
+the equals '=' operator and finally a list of keywords representing
+key names such as keypad5. Each line can have quite a few key
+functions on it. They are interpreted by loadkeys in order and
+assigned to key shift states depending on the order they are
+encountered. So for example, the first value after the equals is the
+keys unshifted state, while the second is the keys shifted state. If
+you wish to learn the order they are interpreted in read the
+loadkeys(8) and keymap(5) man pages.
+
+You can have subsequent lines which are indented and start with
+another keyword for the various shifted states. This way you can
+assign some of the states without having to specify them all in order
+up until you get to the one you want to assign.
+
+In speakup, we have assigned the insert key on the number pad to the
+altgr keyword. This is not required; you could choose any other
+shifted state keyword. We used altgr because it typically represents
+the right hand alt key. In Linux each shift key is separate and
+independent, so the left shift and the right shift keys are not
+necessarily the same. The altgr key is not really used for anything
+important, so we steel it.
+
+Here are the default key assignments for the number eight on the
+keypad:
+
+keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+As you can see, the first line starts with keycode followed by 72
+which is the actual number assigned to the key when the keyboard port
+is read. The KP_8 after the equal sign, is the symbolic representation
+of the function called when that key is hit.
+
+The second line is the same format except it starts with the keyword
+alt which is indented. That means that the function at the end of
+that line Ascii_8 is applied to the alt-shifted eight key.
+
+Now here are the speakup assignments for that key:
+
+keycode 72 = 0x0d0a
+ altgr keycode 72 = 0x0d20
+#keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+Notice that the only thing which has changed on the first line is the
+function called when the key is struck. It is a hexadecimal number
+identifying the function called in a look up table. It is not a
+symbolic representation yet because that means we need to change the
+loadkeys program to understand our symbolic names. We will do this in
+the future but for now it is more expedient to just use the table
+indices. You will find a table at the bottom of this document
+listing the review functions and their corresponding hex lookups.
+
+The 0x0d0a in the first line above is speakup's say line function.
+The second line ends with 0x0d20 which is speakup's read from top of
+screen to reading cursor line.
+
+The third line is the original key assignment commented out with a
+number-sign '#' at the beginning. I do that so I can easily find the
+keys I want to affect by symbolic name. Otherwise I would need to
+keep a look up table for all the keycodes. I recommend you do this as
+well or you'll be very sorry at some point in the future.
+
+The forth line is just the standard key assignment for the left hand
+alt key.
+
+Now let's say we want to design a different keyboard layout. I'll use
+an example for the JAWS style keypad because I've specifically been
+asked to help with that. JAWS uses the eight on the keypad to move up
+a line or the speakup function to read previous line. JAWS also uses
+the keypad_8 key in a shifted mode to read the current line. I
+apologize if these are not quite right. It has been a long time since
+I used JAWS. So we would have the following two lines:
+
+keycode 72 = 0x0d0b
+ altgr keycode 72 = 0x0d0a
+
+The hex value 0x0d0b in the first line is speakup's SAY_PREVIOUS_LINE
+function. The 0x0d0a in the second line is the same say_line function
+as we had earlier. So when the number eight is hit on the keypad
+speakup will read the previous line and when the number eight is
+shifted with the insert key on the keypad it will read the current
+line.
+
+As you can tell, it is not really very difficult to reassign the keys
+to different review functions.
+
+Once you have carefully edited the keymap file, called default.map in
+the speakup distribution, you copy it into the /etc/kbd directory.
+Make sure you back up the original default.map from that directory
+first, if there is one. Then you run loadkeys to load the new map
+into the kernel:
+
+loadkeys /etc/kbd/default.map
+
+If you wish to build your new keyboard lay-out into the kernel, after
+testing it, copy the default.map file into the drivers/char directory,
+with the name defkeymap.map, of your Linux source tree. Then rm the
+defkeymap.c file and recompile the kernel. Because there is no
+defkeymap.c `make' will rebuild it on the next compile.
+
+Here is a list of the available speakup review functions at this point
+in time.
+
+SAY_CHAR 0x0d04 /* say this character */
+SAY_PREV_CHAR 0x0d05 /* say character left of this char */
+SAY_NEXT_CHAR 0x0d06 /* say char right of this char */
+SAY_WORD 0x0d07 /* say this word under reading cursor */
+SAY_PREV_WORD 0x0d08
+SAY_NEXT_WORD 0x0d09
+SAY_LINE 0x0d0a /* say this line */
+SAY_PREV_LINE 0x0d0b /* say line above this line */
+SAY_NEXT_LINE 0x0d0c
+TOP_EDGE 0x0d0d /* move to top edge of screen */
+BOTTOM_EDGE 0x0d0e
+LEFT_EDGE 0x0d0f
+RIGHT_EDGE 0x0d10
+SAY_PHONETIC_CHAR 0x0d11 /* say this character phonetically */
+SPELL_WORD 0x0d12 /* spell this word letter by letter */
+SAY_SCREEN 0x0d14
+SAY_POSITION 0x0d1b
+SPEECH_OFF 0x0d1c
+SAY_ATTRIBUTES 0x0d1d
+SPEAKUP_PARKED 0x0d1e
+SAY_FROM_TOP 0x0d20
+SAY_TO_BOTTOM 0x0d21
+SAY_FROM_LEFT 0x0d22
+SAY_TO_RIGHT 0x0d23
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/MAINTAINERS.patch linux-2.4.30/drivers/char/speakup/diff-v25/MAINTAINERS.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/MAINTAINERS.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/MAINTAINERS.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,16 @@
+--- /usr/src/linux/MAINTAINERS.orig Wed May 21 09:48:21 2003
++++ MAINTAINERS Tue Jul 8 08:36:26 2003
+@@ -1702,6 +1702,13 @@
+ L: sparclinux@vger.kernel.org
+ S: Unmaintained - please send patches to mailing list
+
++SPEAKUP Console speech output
++P: Kirk Reiser
++M: kirk@braille.uwo.ca
++L: speakup@braille.uwo.ca
++W: http://www.linux-speakup.org
++S: Maintained
++
+ SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
+ P: Roger Wolff
+ M: R.E.Wolff@BitWizard.nl
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^alpha^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v25/arch^alpha^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^alpha^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/arch^alpha^Kconfig.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,12 @@
+--- /usr/src/linux/arch/alpha/Kconfig.orig Wed May 21 09:48:21 2003
++++ arch/alpha/Kconfig Tue Jul 8 08:36:26 2003
+@@ -900,7 +900,8 @@
+ source "fs/Kconfig"
+
+ source "drivers/video/Kconfig"
+-
++source "drivers/char/speakup/Kconfig"
++
+ menu "Sound"
+
+ config SOUND
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^arm^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v25/arch^arm^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^arm^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/arch^arm^Kconfig.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/arm/Kconfig.orig Wed May 21 09:48:21 2003
++++ arch/arm/Kconfig Tue Jul 8 08:36:26 2003
+@@ -1052,6 +1052,7 @@
+ source "fs/Kconfig"
+
+ source "drivers/video/Kconfig"
++source "drivers/char/speakup/Kconfig"
+
+ menu "Sound"
+ depends on ARCH_ACORN || ARCH_CLPS7500 || ARCH_TBOX || ARCH_SHARK || ARCH_SA1100 || PCI
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^i386^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v25/arch^i386^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^i386^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/arch^i386^Kconfig.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/i386/Kconfig.orig Wed May 21 09:48:21 2003
++++ arch/i386/Kconfig Tue Jul 8 08:36:26 2003
+@@ -1397,6 +1397,7 @@
+ source "fs/Kconfig"
+
+ source "drivers/video/Kconfig"
++source "drivers/char/speakup/Kconfig"
+
+ menu "Sound"
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^m68k^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v25/arch^m68k^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^m68k^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/arch^m68k^Kconfig.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/m68k/Kconfig.orig Wed May 21 09:48:21 2003
++++ arch/m68k/Kconfig Tue Jul 8 08:36:26 2003
+@@ -1799,6 +1799,7 @@
+ source "fs/Kconfig"
+
+ source "drivers/video/Kconfig"
++source "drivers/char/speakup/Kconfig"
+
+ menu "Kernel hacking"
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^mips^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v25/arch^mips^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^mips^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/arch^mips^Kconfig.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/arch/mips/Kconfig.orig Wed May 21 09:48:21 2003
++++ arch/mips/Kconfig Tue Jul 8 08:36:26 2003
+@@ -1161,6 +1161,7 @@
+ package, available at .
+
+ source "sound/Kconfig"
++source "drivers/char/speakup/Kconfig"
+
+ endmenu
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^ppc^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v25/arch^ppc^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^ppc^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/arch^ppc^Kconfig.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,11 @@
+--- /usr/src/linux/arch/ppc/Kconfig.orig Wed May 21 09:48:21 2003
++++ arch/ppc/Kconfig Tue Jul 8 08:36:26 2003
+@@ -1275,6 +1275,8 @@
+
+ source "drivers/video/Kconfig"
+
++source "drivers/char/speakup/Kconfig"
++
+ menu "Old CD-ROM drivers (not SCSI, not IDE)"
+
+ config CD_NO_IDESCSI
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^sparc64^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v25/arch^sparc64^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^sparc64^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/arch^sparc64^Kconfig.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,11 @@
+--- /usr/src/linux/arch/sparc64/Kconfig.orig Wed May 21 09:48:21 2003
++++ arch/sparc64/Kconfig Tue Jul 8 08:36:26 2003
+@@ -571,6 +571,8 @@
+
+ source "drivers/video/Kconfig"
+
++source "drivers/char/speakup/Kconfig"
++
+ source "drivers/serial/Kconfig"
+
+ source "drivers/sbus/char/Kconfig"
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^sparc^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v25/arch^sparc^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/arch^sparc^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/arch^sparc^Kconfig.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,11 @@
+--- /usr/src/linux/arch/sparc/Kconfig.orig Wed May 21 09:48:21 2003
++++ arch/sparc/Kconfig Tue Jul 8 08:36:26 2003
+@@ -395,6 +395,8 @@
+
+ source "drivers/video/Kconfig"
+
++source "drivers/char/speakup/Kconfig"
++
+ source "drivers/mtd/Kconfig"
+
+ source "drivers/serial/Kconfig"
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/drivers^char^Makefile.patch linux-2.4.30/drivers/char/speakup/diff-v25/drivers^char^Makefile.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/drivers^char^Makefile.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/drivers^char^Makefile.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,10 @@
+--- /usr/src/linux/drivers/char/Makefile.orig Wed May 21 09:48:21 2003
++++ drivers/char/Makefile Tue Jul 8 08:36:26 2003
+@@ -70,6 +70,7 @@
+ obj-$(CONFIG_NWFLASH) += nwflash.o
+ obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
+
++obj-$(CONFIG_SPEAKUP) += speakup/
+ obj-$(CONFIG_WATCHDOG) += watchdog/
+ obj-$(CONFIG_MWAVE) += mwave/
+ obj-$(CONFIG_AGP) += agp/
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/drivers^char^keyboard.c.patch linux-2.4.30/drivers/char/speakup/diff-v25/drivers^char^keyboard.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/drivers^char^keyboard.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/drivers^char^keyboard.c.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,122 @@
+--- /usr/src/linux/drivers/char/keyboard.c.orig Wed May 21 09:48:21 2003
++++ drivers/char/keyboard.c Tue Jul 8 08:50:52 2003
+@@ -41,6 +41,13 @@
+ #include
+ #include
+
++
++#include
++
++#ifdef CONFIG_SPEAKUP_MODULE
++spk_key_func addr_spk_key = NULL;
++#endif
++
+ static void kbd_disconnect(struct input_handle *handle);
+ extern void ctrl_alt_del(void);
+
+@@ -64,6 +71,10 @@
+
+ #define KBD_DEFLOCK 0
+
++/* Key types processed even in raw modes */
++
++#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) | (1 << KT_SPKUP))
++
+ void compute_shiftstate(void);
+
+ /*
+@@ -79,7 +90,7 @@
+ typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
+ char up_flag, struct pt_regs *regs);
+ static k_handler_fn K_HANDLERS;
+-static k_handler_fn *k_handler[16] = { K_HANDLERS };
++k_handler_fn *k_handler[16] = { K_HANDLERS };
+
+ #define FN_HANDLERS\
+ fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
+@@ -100,15 +111,18 @@
+ const int max_vals[] = {
+ 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
+ NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
+- 255, NR_LOCK - 1, 255
++ 255, NR_LOCK - 1, 255, 255
+ };
+
+ const int NR_TYPES = ARRAY_SIZE(max_vals);
+
+ struct kbd_struct kbd_table[MAX_NR_CONSOLES];
+-static struct kbd_struct *kbd = kbd_table;
++struct kbd_struct *kbd = kbd_table;
+ static struct kbd_struct kbd0;
+
++EXPORT_SYMBOL(kbd);
++EXPORT_SYMBOL(k_handler);
++
+ int spawnpid, spawnsig;
+
+ /*
+@@ -253,12 +267,12 @@
+ }
+ }
+ }
+- if (ticks)
+- mod_timer(&kd_mksound_timer, jiffies + ticks);
+ } else
+ kd_nosound(0);
+ }
+
++EXPORT_SYMBOL(kd_mksound);
++
+ /*
+ * Setting the keyboard rate.
+ */
+@@ -598,6 +612,7 @@
+ if (up_flag)
+ return;
+ if (value >= ARRAY_SIZE(fn_handler))
++ if (up_flag || (value >= ARRAY_SIZE(fn_handler)))
+ return;
+ if ((kbd->kbdmode == VC_RAW ||
+ kbd->kbdmode == VC_MEDIUMRAW) &&
+@@ -1102,6 +1117,13 @@
+ key_map = key_maps[shift_final];
+
+ if (!key_map) {
++#ifdef CONFIG_SPEAKUP
++ if (speakup_key(vc, shift_final, keycode, K(KT_SHIFT,0), !down, regs ))
++ return;
++#elif defined(CONFIG_SPEAKUP_MODULE)
++ if ( addr_spk_key && (*addr_spk_key)(vc, shift_final,
++ keycode, K(KT_SHIFT,0), !down, regs) ) return;
++#endif
+ compute_shiftstate();
+ kbd->slockstate = 0;
+ return;
+@@ -1116,10 +1138,17 @@
+ }
+
+ type -= 0xf0;
+-
+- if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
++#ifdef CONFIG_SPEAKUP
++ if (speakup_key(vc, shift_final, keycode, keysym, !down, regs ))
+ return;
++#elif defined(CONFIG_SPEAKUP_MODULE)
++ if ( addr_spk_key && (*addr_spk_key)(vc, shift_final,
++ keycode, keysym, !down, regs) ) return;
++#endif
+
++ if (raw_mode && type != KT_SPEC && type != KT_SHIFT )
++ return;
++
+ if (type == KT_LETTER) {
+ type = KT_LATIN;
+ if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
+@@ -1128,7 +1157,6 @@
+ keysym = key_map[keycode];
+ }
+ }
+-
+ (*k_handler[type])(vc, keysym & 0xff, !down, regs);
+
+ if (type != KT_SLOCK)
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/drivers^char^selection.c.patch linux-2.4.30/drivers/char/speakup/diff-v25/drivers^char^selection.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/drivers^char^selection.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/drivers^char^selection.c.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,17 @@
+--- /usr/src/linux/drivers/char/selection.c.orig Wed May 21 09:48:21 2003
++++ drivers/char/selection.c Tue Jul 8 08:36:26 2003
+@@ -252,7 +252,8 @@
+ sel_end = new_sel_end;
+
+ /* Allocate a new buffer before freeing the old one ... */
+- bp = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL);
++ bp = kmalloc((sel_end-sel_start)/2+1, (user) ?
++ GFP_KERNEL: GFP_ATOMIC);
+ if (!bp) {
+ printk(KERN_WARNING "selection: kmalloc() failed\n");
+ clear_selection();
+@@ -311,3 +312,4 @@
+
+ EXPORT_SYMBOL(set_selection);
+ EXPORT_SYMBOL(paste_selection);
++EXPORT_SYMBOL(clear_selection);
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/drivers^char^vt.c.patch linux-2.4.30/drivers/char/speakup/diff-v25/drivers^char^vt.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/drivers^char^vt.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/drivers^char^vt.c.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,108 @@
+--- /usr/src/linux/drivers/char/vt.c.orig Wed May 21 09:48:21 2003
++++ drivers/char/vt.c Tue Jul 8 08:36:26 2003
+@@ -99,7 +99,11 @@
+ #include
+ #include
+ #include
+-
++#include
++#ifdef CONFIG_SPEAKUP_MODULE
++#include "speakup/spk_con_module.h"
++#endif
++
+ #include
+ #include
+ #include
+@@ -689,6 +693,7 @@
+ screenbuf = (unsigned short *) q;
+ kmalloced = 1;
+ vc_init(currcons, video_num_lines, video_num_columns, 1);
++ speakup_allocate(currcons); /* speakup needs more too. */
+
+ if (!pm_con) {
+ pm_con = pm_register(PM_SYS_DEV,
+@@ -918,6 +923,7 @@
+ pos += video_size_row;
+ }
+ need_wrap = 0;
++ speakup_con_write(currcons, "\n",1);
+ }
+
+ static void ri(int currcons)
+@@ -946,6 +952,7 @@
+ pos -= 2;
+ x--;
+ need_wrap = 0;
++ speakup_bs(currcons);
+ }
+ }
+
+@@ -1479,6 +1486,7 @@
+ break;
+ }
+ pos += (x << 1);
++ speakup_con_write(currcons, " ", 1);
+ return;
+ case 10: case 11: case 12:
+ lf(currcons);
+@@ -1992,6 +2000,7 @@
+ }
+ if (decim)
+ insert_char(currcons, 1);
++ speakup_con_write(currcons, (char *) &tc,1);
+ scr_writew(himask ?
+ ((attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+ (attr << 8) + tc,
+@@ -2032,6 +2041,7 @@
+
+ up(&con_buf_sem);
+ }
++ speakup_con_update(currcons);
+
+ return n;
+ #undef FLUSH
+@@ -2057,6 +2067,7 @@
+ /* we only changed when the console had already
+ been allocated - a new console is not created
+ in an interrupt routine */
++ speakup_con_update(want_console);
+ }
+ want_console = -1;
+ }
+@@ -2128,6 +2139,7 @@
+
+ /* Contrived structure to try to emulate original need_wrap behaviour
+ * Problems caused when we have need_wrap set on '\n' character */
++ speakup_con_write(currcons, b, count);
+ while (count--) {
+ c = *b++;
+ if (c == 10 || c == 13 || c == 8 || need_wrap) {
+@@ -2172,6 +2184,7 @@
+ }
+ }
+ set_cursor(currcons);
++ speakup_con_update(currcons);
+
+ if (!oops_in_progress)
+ poke_blanked_console();
+@@ -2496,6 +2509,7 @@
+ master_display_fg = vc_cons[currcons].d;
+ set_origin(currcons);
+ save_screen(currcons);
++ speakup_init(currcons);
+ gotoxy(currcons,x,y);
+ csi_J(currcons, 0);
+ update_screen(fg_console);
+@@ -3059,11 +3073,11 @@
+ EXPORT_SYMBOL(update_region);
+ EXPORT_SYMBOL(redraw_screen);
+ EXPORT_SYMBOL(vc_resize);
++EXPORT_SYMBOL(vc_cons);
+ EXPORT_SYMBOL(fg_console);
+ EXPORT_SYMBOL(console_blank_hook);
+ EXPORT_SYMBOL(console_blanked);
+ EXPORT_SYMBOL(vt_cons);
+-EXPORT_SYMBOL(vc_cons);
+ #ifndef VT_SINGLE_DRIVER
+ EXPORT_SYMBOL(take_over_console);
+ EXPORT_SYMBOL(give_up_console);
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/fs^proc^root.c.patch linux-2.4.30/drivers/char/speakup/diff-v25/fs^proc^root.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/fs^proc^root.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/fs^proc^root.c.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,13 @@
+--- /usr/src/linux/fs/proc/root.c.orig Wed May 21 09:48:21 2003
++++ fs/proc/root.c Tue Jul 8 08:36:26 2003
+@@ -70,6 +70,10 @@
+ proc_mkdir("openprom", 0);
+ #endif
+ proc_tty_init();
++#ifdef CONFIG_SPEAKUP /* console speech output */
++ proc_speakup_init();
++#endif /* speakup */
++
+ #ifdef CONFIG_PROC_DEVICETREE
+ proc_device_tree_init();
+ #endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/include^linux^keyboard.h.patch linux-2.4.30/drivers/char/speakup/diff-v25/include^linux^keyboard.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/include^linux^keyboard.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/include^linux^keyboard.h.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,18 @@
+--- /usr/src/linux/include/linux/keyboard.h.orig Wed May 21 09:48:21 2003
++++ include/linux/keyboard.h Tue Jul 8 08:36:26 2003
+@@ -46,6 +46,7 @@
+ #define KT_ASCII 9
+ #define KT_LOCK 10
+ #define KT_SLOCK 12
++#define KT_SPKUP 14
+
+ #define K(t,v) (((t)<<8)|(v))
+ #define KTYP(x) ((x) >> 8)
+@@ -428,6 +429,7 @@
+ #define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR)
+
+ #define NR_LOCK 8
++#define NR_SPKUP 0x45
+
+ #define MAX_DIACR 256
+ #endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/include^linux^miscdevice.h.patch linux-2.4.30/drivers/char/speakup/diff-v25/include^linux^miscdevice.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/include^linux^miscdevice.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/include^linux^miscdevice.h.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,18 @@
+--- /usr/src/linux/include/linux/miscdevice.h.orig Wed May 21 09:48:21 2003
++++ include/linux/miscdevice.h Tue Jul 8 08:36:26 2003
+@@ -11,6 +11,7 @@
+ #define APOLLO_MOUSE_MINOR 7
+ #define PC110PAD_MINOR 9
+ /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
++#define SYNTH_MINOR 25
+ #define WATCHDOG_MINOR 130 /* Watchdog timer */
+ #define TEMP_MINOR 131 /* Temperature Sensor */
+ #define RTC_MINOR 135
+@@ -33,6 +34,7 @@
+ #define SGI_USEMACLONE 151
+
+ #define TUN_MINOR 200
++
+
+ extern int misc_init(void);
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/include^linux^proc_fs.h.patch linux-2.4.30/drivers/char/speakup/diff-v25/include^linux^proc_fs.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/include^linux^proc_fs.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/include^linux^proc_fs.h.patch 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,13 @@
+--- /usr/src/linux/include/linux/proc_fs.h.orig Wed May 21 09:48:21 2003
++++ include/linux/proc_fs.h Tue Jul 8 08:36:26 2003
+@@ -121,6 +121,10 @@
+ extern void proc_tty_register_driver(struct tty_driver *driver);
+ extern void proc_tty_unregister_driver(struct tty_driver *driver);
+
++#ifdef CONFIG_SPEAKUP /* console speech output */
++extern void proc_speakup_init(void);
++#endif /* speakup */
++
+ /*
+ * proc_devtree.c
+ */
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v25/include^linux^speakup.h.copy linux-2.4.30/drivers/char/speakup/diff-v25/include^linux^speakup.h.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v25/include^linux^speakup.h.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v25/include^linux^speakup.h.copy 2003-07-08 05:51:40.000000000 -0700
@@ -0,0 +1,41 @@
+#ifndef __SPEAKUP_H
+#define __SPEAKUP_H
+
+#include
+
+struct kbd_struct;
+struct vc_data;
+
+/* how about some prototypes! */
+extern int do_spk_ioctl(int,unsigned char *data,int,void *);
+
+#if defined(CONFIG_SPEAKUP)
+extern void speakup_init(int);
+extern void speakup_allocate(int);
+extern void speakup_bs(int);
+extern void speakup_con_write(int, const char *, int);
+extern void speakup_con_update(int);
+#if (LINUX_VERSION_CODE < 132419)
+extern int speakup_key ( int, u_char, u_short, u_char );
+#else
+extern int speakup_key(struct vc_data*, int, int, u_short, int, struct pt_regs *);
+#endif
+#elif defined(CONFIG_SPEAKUP_MODULE)
+typedef void (*spk_con_func)(int );
+typedef void (*spk_write_func)(int, const char *, int);
+#if (LINUX_VERSION_CODE < 132419)
+typedef int (*spk_key_func)(int, u_char, u_short, u_char );
+#else
+typedef int (*spk_key_func)(struct vc_data*, int, int, u_short, int, struct pt_regs *);
+#endif
+extern void spk_set_addresses( spk_con_func allocate, spk_con_func bs,
+ spk_write_func con_write, spk_con_func con_update, spk_key_func key );
+#define speakup_init(currcons)
+#else
+#define speakup_allocate(currcons)
+#define speakup_bs(currcons)
+#define speakup_con_write(currcons, str, len)
+#define speakup_con_update(currcons)
+#define speakup_init(currcons)
+#endif
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/CVS/Entries linux-2.4.30/drivers/char/speakup/diff-v26/CVS/Entries
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/CVS/Entries 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/CVS/Entries 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1,22 @@
+/Documentation^speakup^DefaultKeyAssignments.copy/1.1/Wed Jul 16 17:51:21 2003//
+/Documentation^speakup^INSTALLATION.copy/1.1/Wed Jul 16 17:51:21 2003//
+/Documentation^speakup^README.copy/1.1/Wed Jul 16 17:51:21 2003//
+/Documentation^speakup^keymap-tutorial.copy/1.1/Wed Jul 16 17:51:21 2003//
+/Documentation^speakup^spkguide.txt.copy/1.1/Thu Apr 7 19:57:32 2005//
+/MAINTAINERS.patch/1.27/Thu Mar 3 01:23:56 2005//
+/arch^arm^Kconfig.patch/1.27/Thu Mar 3 01:23:56 2005//
+/arch^mips^Kconfig.patch/1.26/Thu Mar 3 01:23:56 2005//
+/arch^sparc64^Kconfig.patch/1.27/Thu Mar 3 01:23:56 2005//
+/arch^sparc^Kconfig.patch/1.27/Thu Mar 3 01:23:56 2005//
+/drivers^Kconfig.patch/1.22/Thu Mar 3 01:23:56 2005//
+/drivers^Makefile.patch/1.13/Thu Mar 3 01:23:56 2005//
+/drivers^char^Makefile.patch/1.27/Thu Mar 3 01:23:56 2005//
+/drivers^char^consolemap.c.patch/1.10/Thu Mar 3 01:23:56 2005//
+/drivers^char^keyboard.c.patch/1.27/Thu Mar 3 01:23:56 2005//
+/drivers^char^vt.c.patch/1.27/Thu Mar 3 01:23:56 2005//
+/fs^proc^root.c.patch/1.27/Thu Mar 3 01:23:56 2005//
+/include^linux^keyboard.h.patch/1.27/Thu Mar 3 01:23:56 2005//
+/include^linux^miscdevice.h.patch/1.27/Thu Mar 3 01:23:56 2005//
+/include^linux^proc_fs.h.patch/1.27/Thu Mar 3 01:23:56 2005//
+/include^linux^speakup.h.copy/1.1/Wed Jul 16 17:51:21 2003//
+D
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/CVS/Repository linux-2.4.30/drivers/char/speakup/diff-v26/CVS/Repository
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/CVS/Repository 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/CVS/Repository 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1 @@
+speakup/diff-v26
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/CVS/Root linux-2.4.30/drivers/char/speakup/diff-v26/CVS/Root
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/CVS/Root 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/CVS/Root 2005-05-01 19:02:58.000000000 -0700
@@ -0,0 +1 @@
+:pserver:anonymous@bumpy.braille.uwo.ca:/usr/src/CVS
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^DefaultKeyAssignments.copy linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^DefaultKeyAssignments.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^DefaultKeyAssignments.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^DefaultKeyAssignments.copy 2003-07-16 10:51:21.000000000 -0700
@@ -0,0 +1,46 @@
+This file is intended to give you an overview of the default keys used
+by speakup for it's review functions. You may change them to be
+anything you want but that will take some familiarity with key
+mapping.
+
+We have remapped the insert or zero key on the keypad to act as a
+shift key. Well, actually as an altgr key. So in the following list
+InsKeyPad-period means hold down the insert key like a shift key and
+hit the keypad period.
+
+KeyPad-8 Say current Line
+InsKeyPad-8 say from top of screen to reading cursor.
+KeyPad-7 Say Previous Line (UP one line)
+KeyPad-9 Say Next Line (down one line)
+KeyPad-5 Say Current Word
+InsKeyPad-5 Spell Current Word
+KeyPad-4 Say Previous Word (left one word)
+InsKeyPad-4 say from left edge of line to reading cursor.
+KeyPad-6 Say Next Word (right one word)
+InsKeyPad-6 Say from reading cursor to right edge of line.
+KeyPad-2 Say Current Letter
+InsKeyPad-2 say current letter phonetically
+KeyPad-1 Say Previous Character (left one letter)
+KeyPad-3 Say Next Character (right one letter)
+KeyPad-plus Say Entire Screen
+InsKeyPad-plus Say from reading cursor line to bottom of screen.
+KeyPad-Minus Park reading cursor (toggle)
+InsKeyPad-minus Say character hex and decimal value.
+KeyPad-period Say Position (current line, position and console)
+InsKeyPad-period say colour attributes of current position.
+InsKeyPad-9 Move reading cursor to top of screen (insert pgup)
+InsKeyPad-3 Move reading cursor to bottom of screen (insert pgdn)
+InsKeyPad-7 Move reading cursor to left edge of screen (insert home)
+InsKeyPad-1 Move reading cursor to right edge of screen (insert end)
+ControlKeyPad-1 Move reading cursor to last character on current line.
+KeyPad-Enter Shut Up (until another key is hit) and sync reading cursor
+InsKeyPad-Enter Shut Up (until toggled back on).
+InsKeyPad-star n go to line (y) or column (x). Where 'n' is any
+ allowed value for the row or column for your current screen.
+KeyPad-/ Mark and Cut screen region.
+InsKeyPad-/ Paste screen region into any console.
+
+Hitting any key while speakup is outputting speech will quiet the
+synth until it has caught up with what is being printed on the
+console.
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^INSTALLATION.copy linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^INSTALLATION.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^INSTALLATION.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^INSTALLATION.copy 2003-07-16 10:51:21.000000000 -0700
@@ -0,0 +1,108 @@
+This document assumes you have had some experience with kernel
+compilation and installation. If you have not, I recommend you get
+the kernel source and read the README and various documents in the
+linux/Documentation directory. In particular the Changes file to make
+sure you have the appropriate utilities needed for installing a 2.2.xx
+or 2.4xx kernel. It isn't as difficult as you might think. The
+kernel README is intimidating the first time but once you get the
+steps down, it's really pretty easy. Getting through the "make
+config" is the tedious bit.
+
+The first thing to do is to place a copy of the tarball in the /usr/src
+directory which is the directory the linux tree is located in as well.
+Next untar speakup by typing:
+
+tar zxf speakup-1.00.tar.gz
+cd speakup-1.00
+./install
+
+Note the dot-slash before the install. This will copy the speakup
+directory to the kernel tree and apply the various patches and
+components to the appropriate kernel files. Depending on how
+experienced you are with kernel compiling and hacking will determine
+whether you should bother looking at any failed patches. If this
+happens, you should probably write to the speakup mailing list for
+help or myself.
+
+If all of the patch hunks apply successfully then just continue with
+the standard steps to compile the kernel with:
+
+make mrproper
+make config
+
+When you get to the section console speech output, answer 'y' to the
+CONFIG_SPEAKUP prompt. You will be given a submenu with the list of
+synthesizers which are currently supported. You can include as many
+synths in the kernel as you wish but remember each one takes up kernel
+space. You can only choose one of the synths as the default or none,
+so just type dtlk or whatever is the correct string for the
+synthesizer you have. You will also be asked if you wish to build-in
+a speakup key map. If you do not say 'y' to this option you will need
+to load a speakup map at boot time with whichever mechanism your
+distribution uses for loading key maps.
+
+We have placed the speakup configuration options in make config just
+after the vga console choice. For the DoubleTalk PC driver included
+by Jim Van Zandt. I recommend you say no to that option. I have not
+tried configuring them both in, but I wouldn't be at all surprised if
+it didn't work.
+
+If all goes well up to this point you can continue with the compiling
+process by doing:
+
+make dep >dep.file 2>&1 &
+make bzImage >cc.file 2>&1 &
+make modules >mod.file 2>&1 &
+
+I always redirect output to the files dep.file and cc.file so I can
+look over the compilation record to make sure there are no errors and
+warnings.
+
+Okay, you are ready to install the newly compiled kernel. Make sure
+you make an linux.old entry in your lilo.conf file so you can recover
+if it blows up. next as root run "make modules_install" to install
+whatever modules you compiled and move the bzImage from
+/usr/src/linux/arch/i386/boot to wherever your kernel lives. Also
+move the System.map from /usr/src/linux to where your System.map
+lives. On our systems we use debian so we create an vmlinuz-speakup
+and System.map-speakup in our /boot directory and set the symbolic
+links vmlinuz and System.map in the root (/) directory to point to the
+images. Now type lilo to tell lilo to build the new booter file and
+install it.
+
+As of version 0.07, the keymap for speakup is automatically built in
+at compile time. If you have other keymaps installed at boot time,
+you might want to consider removing them before you reboot the system.
+
+If everything has gone OK up until now, cross your fingers and type:
+
+shutdown -r now
+
+Your system should start talking to you as soon as it starts booting.
+It will talk and talk and ... well, you might want to hit the
+keypad-enter key to tell it to shut up. You should also read the
+DefaultKeyAssignments file to learn the various review functions
+available.
+
+As of v-0.10 the speakup configuration options are in the
+/proc/speakup subtree. The individual options should be fairly
+obvious by their names such as rate, volume, punc_level and so forth.
+You can manipulate them by cat'ing or echoing new values to them such
+as:
+
+echo 9 >/proc/speakup/rate
+
+You can see what the current values are by cat'ing those files to the console:
+
+cat /proc/speakup/rate
+
+I have probably managed to overlook a whole whack of things because
+this is the, enter version number here, draft. Don't worry we'll get
+it right eventually. If you like the package you really should get on
+the mailing list and start participating in it's development.
+
+ Kirk
+
+email: kirk@braille.uwo.ca
+phone: (519) 679-6845 (home)
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^README.copy linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^README.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^README.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^README.copy 2003-07-16 10:51:21.000000000 -0700
@@ -0,0 +1,98 @@
+Welcome to the speakup project for the Speakup speech package for Linux.
+
+Speakup is written by Kirk Reiser and Andy Berdan. It is licensed
+under the GPL. If you don't already know, the GPL stands for the GNU
+General Public License. Which basically states that this code is free to
+copy, modify and distribute to anyone interested in playing with it.
+The one thing you may not do is turn any part of it into proprietary
+or commercial code without the permission of the author. That's me.
+
+If you are interested in being involved with the development of speech
+output for Linux you can subscribe to the Speakup mailing list by
+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.
+
+We are at a very early stage in the development of this package.
+Hopefully changes will happen often and many. The current files in
+this directory are:
+
+DefaultKeyAssignments # speakup's default review keys
+INSTALLATION # for installing speakup from the tar ball.
+README # this file
+keymap-tutorial # a tutorial on how to layout the keyboard
+
+Read the INSTALLATION file to learn how to apply the patches and the
+default.map for the keyboard. You should also read the Changes file.
+It really has any new things I've added since last time.
+
+There is no documentation in any of these files to instruct you what
+to do if something goes wrong with the patching or compilation. If
+you would like that information you will need to subscribe to the
+mailing list and ask for help, or write me kirk@braille.uwo.ca for
+help. I suggest the mailing list because I will probably tire quickly
+of answering the same questions over and over. You could always
+decide to dig-in and take on the task, and write documentation to help
+others.
+
+There also is a speakup reflector for the Speak Freely package, which
+many of us hang out on and discuss all sorts of topics from speakup
+problems to ALSA driver installation and just about anything else
+you'd like to talk about. The reflector is at lwl.braille.uwo.ca:4074
+with it's lwl page at lwl.braille.uwo.ca/speakup.html. Come and join
+us, it's fun!
+
+Acknowledgements:
+
+I am really very new at kernel hacking and screen review package
+writing, so I have depended heavily on other folks kindness to help me
+a long. No doubt I will continue to abuse them freely and others
+before this is a really good speech solution for Linux. (Oh Well!,
+somebody's got to do it.)
+
+Theodore Ts'o. He gave me a good discussion of unicode and UTF and
+the like. He doesn't even remember writing me about it.
+
+Alan Cox. He has answered many questions about scheduling and wait
+queues and timers along with code fragments and so on. I just wish I
+understood it all totally. He has also helped immensely in moving
+this package toward inclusion in the standard kernel tree. (Maybe next
+release!)
+
+Martin Mares. He pointed me in the right direction to figuring out
+the colour attributes and other useful tidbits.
+
+Paul McDermott. He really is the catalyst for me to actually get
+this all working. Besides I like seeing him bounce around and get all
+excited every time I have something new working.
+
+John Covici, He was the first person to actually attempt writing
+another synthesizer driver for speakup. It was the Speakout driver so
+it was also the first serial driver.
+
+Brian Borowski, he was the first person to actually write a speakup
+function other than Andy and I.
+
+Jim Danley, he has more or less become my main man in helping test
+code, add new features, bounce ideas off and generally become a good
+friend.
+
+Matt Campbell, he basically rewrote the drivers to be able to include
+all synths in the kernel at the same time. The distribution
+maintainers appreciate him a lot as well.
+
+Gene Collins, he was very helpful debugging the current release prior
+to its public showing. He has also worked hard educating others on
+the list and writing the ALSA mini howto.
+
+I would also like to really thank the folks that handle the
+distribution packages. I and many other people would not find access
+to speakup nearly so convenient without their efforts. They include
+Bill Acker, Tom Moore, Matt Campbell, Joe Norton and Joshua Lambert.
+
+There are probably many more I am forgetting right now. I guess I'll
+just have to add you all later.
+
+
+Happy Hacking!
+
+ Kirk
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^keymap-tutorial.copy linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^keymap-tutorial.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^keymap-tutorial.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^keymap-tutorial.copy 2003-07-16 10:51:21.000000000 -0700
@@ -0,0 +1,140 @@
+ Speakup Keymap Tutorial
+
+This is meant to be a basic tutorial on how to change the Linux keymap
+file to assign speakup review functions to desired keys. It is not
+intended to be a replacement for the loadkeys(8) or keymap(5) man
+pages.
+
+The basic lay-out of the keymap file is a series of lines with the
+following fields. The keyword keycode indicates this is the start of
+a new key assignment. It is then followed by a number which
+represents the actual key on the keyboard. That number is followed by
+the equals '=' operator and finally a list of keywords representing
+key names such as keypad5. Each line can have quite a few key
+functions on it. They are interpreted by loadkeys in order and
+assigned to key shift states depending on the order they are
+encountered. So for example, the first value after the equals is the
+keys unshifted state, while the second is the keys shifted state. If
+you wish to learn the order they are interpreted in read the
+loadkeys(8) and keymap(5) man pages.
+
+You can have subsequent lines which are indented and start with
+another keyword for the various shifted states. This way you can
+assign some of the states without having to specify them all in order
+up until you get to the one you want to assign.
+
+In speakup, we have assigned the insert key on the number pad to the
+altgr keyword. This is not required; you could choose any other
+shifted state keyword. We used altgr because it typically represents
+the right hand alt key. In Linux each shift key is separate and
+independent, so the left shift and the right shift keys are not
+necessarily the same. The altgr key is not really used for anything
+important, so we steel it.
+
+Here are the default key assignments for the number eight on the
+keypad:
+
+keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+As you can see, the first line starts with keycode followed by 72
+which is the actual number assigned to the key when the keyboard port
+is read. The KP_8 after the equal sign, is the symbolic representation
+of the function called when that key is hit.
+
+The second line is the same format except it starts with the keyword
+alt which is indented. That means that the function at the end of
+that line Ascii_8 is applied to the alt-shifted eight key.
+
+Now here are the speakup assignments for that key:
+
+keycode 72 = 0x0d0a
+ altgr keycode 72 = 0x0d20
+#keycode 72 = KP_8
+ alt keycode 72 = Ascii_8
+
+Notice that the only thing which has changed on the first line is the
+function called when the key is struck. It is a hexadecimal number
+identifying the function called in a look up table. It is not a
+symbolic representation yet because that means we need to change the
+loadkeys program to understand our symbolic names. We will do this in
+the future but for now it is more expedient to just use the table
+indices. You will find a table at the bottom of this document
+listing the review functions and their corresponding hex lookups.
+
+The 0x0d0a in the first line above is speakup's say line function.
+The second line ends with 0x0d20 which is speakup's read from top of
+screen to reading cursor line.
+
+The third line is the original key assignment commented out with a
+number-sign '#' at the beginning. I do that so I can easily find the
+keys I want to affect by symbolic name. Otherwise I would need to
+keep a look up table for all the keycodes. I recommend you do this as
+well or you'll be very sorry at some point in the future.
+
+The forth line is just the standard key assignment for the left hand
+alt key.
+
+Now let's say we want to design a different keyboard layout. I'll use
+an example for the JAWS style keypad because I've specifically been
+asked to help with that. JAWS uses the eight on the keypad to move up
+a line or the speakup function to read previous line. JAWS also uses
+the keypad_8 key in a shifted mode to read the current line. I
+apologize if these are not quite right. It has been a long time since
+I used JAWS. So we would have the following two lines:
+
+keycode 72 = 0x0d0b
+ altgr keycode 72 = 0x0d0a
+
+The hex value 0x0d0b in the first line is speakup's SAY_PREVIOUS_LINE
+function. The 0x0d0a in the second line is the same say_line function
+as we had earlier. So when the number eight is hit on the keypad
+speakup will read the previous line and when the number eight is
+shifted with the insert key on the keypad it will read the current
+line.
+
+As you can tell, it is not really very difficult to reassign the keys
+to different review functions.
+
+Once you have carefully edited the keymap file, called default.map in
+the speakup distribution, you copy it into the /etc/kbd directory.
+Make sure you back up the original default.map from that directory
+first, if there is one. Then you run loadkeys to load the new map
+into the kernel:
+
+loadkeys /etc/kbd/default.map
+
+If you wish to build your new keyboard lay-out into the kernel, after
+testing it, copy the default.map file into the drivers/char directory,
+with the name defkeymap.map, of your Linux source tree. Then rm the
+defkeymap.c file and recompile the kernel. Because there is no
+defkeymap.c `make' will rebuild it on the next compile.
+
+Here is a list of the available speakup review functions at this point
+in time.
+
+SAY_CHAR 0x0d04 /* say this character */
+SAY_PREV_CHAR 0x0d05 /* say character left of this char */
+SAY_NEXT_CHAR 0x0d06 /* say char right of this char */
+SAY_WORD 0x0d07 /* say this word under reading cursor */
+SAY_PREV_WORD 0x0d08
+SAY_NEXT_WORD 0x0d09
+SAY_LINE 0x0d0a /* say this line */
+SAY_PREV_LINE 0x0d0b /* say line above this line */
+SAY_NEXT_LINE 0x0d0c
+TOP_EDGE 0x0d0d /* move to top edge of screen */
+BOTTOM_EDGE 0x0d0e
+LEFT_EDGE 0x0d0f
+RIGHT_EDGE 0x0d10
+SAY_PHONETIC_CHAR 0x0d11 /* say this character phonetically */
+SPELL_WORD 0x0d12 /* spell this word letter by letter */
+SAY_SCREEN 0x0d14
+SAY_POSITION 0x0d1b
+SPEECH_OFF 0x0d1c
+SAY_ATTRIBUTES 0x0d1d
+SPEAKUP_PARKED 0x0d1e
+SAY_FROM_TOP 0x0d20
+SAY_TO_BOTTOM 0x0d21
+SAY_FROM_LEFT 0x0d22
+SAY_TO_RIGHT 0x0d23
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^spkguide.txt.copy linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^spkguide.txt.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/Documentation^speakup^spkguide.txt.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/Documentation^speakup^spkguide.txt.copy 2005-04-07 12:57:32.000000000 -0700
@@ -0,0 +1,1279 @@
+
+The Speakup User's Guide
+For Speakup 2.0 and Later
+By Gene Collins
+Last modified on Tue Mar 29 10:54:19 2005
+Document version 1.0
+
+Copyright (c) 2005 Gene Collins
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled "GNU Free
+Documentation License".
+
+Preface
+
+The purpose of this document is to familiarize users with the user
+interface to Speakup, a Linux Screen Reader. If you need instructions
+for installing or obtaining Speakup, visit the web site at
+http://linux-speakup.org/. Speakup is a set of patches to the standard
+Linux kernel source tree. It can be built as a series of modules, or as
+a part of a monolithic kernel. These details are beyond the scope of
+this manual, but the user may need to be aware of the module
+capabilities, depending on how your system administrator has installed
+Speakup. If Speakup is built as a part of a monolithic kernel, and the
+user is using a hardware synthesizer, then Speakup will be able to
+provide speech access from the time the kernel is loaded, until the time
+the system is shutdown. This means that if you have obtained Linux
+installation media for a distribution which includes Speakup as a part
+of its kernel, you will be able, as a blind person, to install Linux
+with speech access unaided by a sighted person. Again, these details
+are beyond the scope of this manual, but the user should be aware of
+them. See the web site mentioned above for further details.
+
+1. Starting Speakup
+
+If your system administrator has installed Speakup to work with your
+specific synthesizer by default, then all you need to do to use Speakup
+is to boot your system, and Speakup should come up talking. This
+assumes of course that your synthesizer is a supported hardware
+synthesizer, and that it is either installed in or connected to your
+system, and is if necessary powered on.
+
+It is possible, however, that Speakup may have been compiled into the
+kernel with no default synthesizer. It is even possible that your
+kernel has been compiled with support for some of the supported
+synthesizers and not others. If you find that this is the case, and
+your synthesizer is supported but not available, complain to the person
+who compiled and installed your kernel. Or better yet, go to the web
+site, and learn how to patch Speakup into your own kernel source, and
+build and install your own kernel.
+
+If your kernel has been compiled with Speakup, and has no default
+synthesizer set, or you would like to use a different synthesizer than
+the default one, then you may issue the following command at the boot
+prompt of your boot loader.
+
+linux speakup_synth=ltlk
+
+This command would tell Speakup to look for and use a LiteTalk or
+DoubleTalk LT at boot up. You may replace the ltlk synthesizer keyword
+with the keyword for whatever synthesizer you wish to use. The
+speakup_synth parameter will accept the following keywords, provided
+that support for the related synthesizers has been built into the
+kernel.
+
+acntsa -- Accent SA
+acntpc -- Accent PC
+apolo -- Apolo
+audptr -- Audapter
+bns -- Braille 'n Speak
+dectlk -- DecTalk Express (old and new, db9 serial only)
+decext -- DecTalk (old) External
+dtlk -- DoubleTalk PC
+keypc -- Keynote Gold PC
+ltlk -- DoubleTalk LT, LiteTalk, or external Tripletalk (db9 serial only)
+spkout -- Speak Out
+txprt -- Transport
+
+Note: Speakup does * NOT * support usb connections! Speakup also does *
+NOT * support the internal Tripletalk!
+
+Speakup does support two other synthesizers, but because they work in
+conjunction with other software, they must be loaded as modules after
+their related software is loaded, and so are not available at boot up.
+These are as follows:
+
+decpc -- DecTalk PC (not available at boot up)
+sftsyn -- One of several software synthesizers (not available at boot up)
+
+See the sections on loading modules and software synthesizers later in
+this manual for further details. It should be noted here that the
+speakup_synth boot parameter will have no effect if Speakup has been
+compiled as modules. In order for Speakup modules to be loaded during
+the boot process, such action must be configured by your system
+administrator. This will mean that you will hear some, but not all, of
+the bootup messages.
+
+2. Basic operation
+
+Once you have booted the system, and if necessary, have supplied the
+proper bootup parameter for your synthesizer, Speakup will begin
+talking as soon as the kernel is loaded. In fact, it will talk a lot!
+It will speak all the boot up messages that the kernel prints on the
+screen during the boot process. This is because Speakup is not a
+separate screen reader, but is actually built into the operating
+system. Since almost all console applications must print text on the
+screen using the kernel, and must get their keyboard input through the
+kernel, they are automatically handled properly by Speakup. There are a
+few exceptions, but we'll come to those later.
+
+Note: In this guide I will refer to the numeric keypad as the keypad.
+This is done because the speakupmap.map file referred to later in this
+manual uses the term keypad instead of numeric keypad. Also I'm lazy
+and would rather only type one word. So keypad it is. Got it? Good.
+
+Most of the Speakup review keys are located on the keypad at the far
+right of the keyboard. The numlock key should be off, in order for these
+to work. If you toggle the numlock on, the keypad will produce numbers,
+which is exactly what you want for spreadsheets and such. For the
+purposes of this guide, you should have the numlock turned off, which is
+its default state at bootup.
+
+You probably won't want to listen to all the bootup messages every time
+you start your system, though it's a good idea to listen to them at
+least once, just so you'll know what kind of information is available to
+you during the boot process. You can always review these messages after
+bootup with the command:
+
+dmesg | more
+
+In order to speed the boot process, and to silence the speaking of the
+bootup messages, just press the keypad enter key. This key is located
+in the bottom right corner of the keypad. Speakup will shut up and stay
+that way, until you press another key.
+
+You can check to see if the boot process has completed by pressing the 8
+key on the keypad, which reads the current line. This also has the
+effect of starting Speakup talking again, so you can press keypad enter
+to silence it again if the boot process has not completed.
+
+When the boot process is complete, you will arrive at a "login" prompt.
+At this point, you'll need to type in your user id and password, as
+provided by your system administrator. You will hear Speakup speak the
+letters of your user id as you type it, but not the password. This is
+because the password is not displayed on the screen for security
+reasons. This has nothing to do with Speakup, it's a Linux security
+feature.
+
+Once you've logged in, you can run any Linux command or program which is
+allowed by your user id. Normal users will not be able to run programs
+which require root privileges.
+
+When you are running a program or command, Speakup will automatically
+speak new text as it arrives on the screen. You can at any time silence
+the speech with keypad enter, or use any of the Speakup review keys.
+
+Here are some basic Speakup review keys, and a short description of what
+they do.
+
+keypad 1 -- read previous character
+keypad 2 -- read current character (pressing keypad 2 twice rapidly will speak
+ the current character phonetically)
+keypad 3 -- read next character
+keypad 4 -- read previous word
+keypad 5 -- read current word (press twice rapidly to spell the current word)
+keypad 6 -- read next word
+keypad 7 -- read previous line
+keypad 8 -- read current line (press twice rapidly to hear how much the
+ text on the current line is indented)
+keypad 9 -- read next line
+keypad period -- speak current cursor position and announce current
+ virtual console
+
+It's also worth noting that the insert key on the keypad is mapped
+as the speakup key. Instead of pressing and releasing this key, as you
+do under DOS or Windows, you hold it like a shift key, and press other
+keys in combination with it. For example, repeatedly holding keypad
+insert, from now on called speakup, and keypad enter will toggle the
+speaking of new text on the screen on and off. This is not the same as
+just pressing keypad enter by itself, which just silences the speech
+until you hit another key. When you hit speakup plus keypad enter,
+Speakup will say, "You turned me off.", or "Hey, that's better." When
+Speakup is turned off, no new text on the screen will be spoken. You
+can still use the reading controls to review the screen however.
+
+3. Using the Speakup Help System
+
+Speakup has a help system, which is compiled as a module. It is loaded
+automatically whenever the Speakup help system is invoked for the first
+time, and remains loaded after that, until speakup is unloaded. Note
+that if speakup was compiled into a monolithic kernel on your system,
+you will not be able to unload Speakup from your kernel. If you try to
+use the help system, and find that it is unavailable, then your system
+administrator has not installed the Speakup help module, which is called
+speakup_help. Complain to your system administrator about this.
+
+In order to enter the Speakup help system, press and hold the speakup
+key (remember that this is the keypad insert key), and press the f1 key.
+You will hear the message:
+
+"Press space to leave help, cursor up or down to scroll, or a letter to
+go to commands in list."
+
+When you press the spacebar to leave the help system, you will hear:
+
+"Leaving help."
+
+While you are in the Speakup help system, you can scroll up or down
+through the list of available commands using the cursor keys. The list
+of commands is arranged in alphabetical order. If you wish to jump to
+commands in a specific part of the alphabet, you may press the letter of
+the alphabet you wish to jump to.
+
+You can also just explore by typing keyboard keys. Pressing keys will
+cause Speakup to speak the command associated with that key. For
+example, if you press the keypad 8 key, you will hear:
+
+"Keypad 8 is line, say current."
+
+You'll notice that some commands do not have keys assigned to them.
+This is because they are very infrequently used commands, and are also
+accessible through the proc system. We'll discuss the proc system later
+in this manual.
+
+You'll also notice that some commands have two keys assigned to them.
+This is because Speakup has a built in set of alternative key bindings
+for laptop users. The alternate speakup key is the caps lock key. You
+can press and hold the caps lock key, while pressing an alternate
+speakup command key to activate the command. On most laptops, the
+numeric keypad is defined as the keys in the j k l area of the keyboard.
+
+There is usually a function key which turns this keypad function on and
+off, and some other key which controls the numlock state. Toggling the
+keypad functionality on and off can become a royal pain. So, Speakup
+gives you a simple way to get at an alternative set of key mappings for
+your laptop. These are also available by default on desktop systems,
+because Speakup does not know whether it is running on a desktop or
+laptop. So you may choose which set of Speakup keys to use. Some
+system administrators may have chosen to compile Speakup for a desktop
+system without this set of alternate key bindings, but these details are
+beyond the scope of this manual. To use the caps lock for its normal
+purpose, hold the shift key while toggling the caps lock on and off. We
+should note here, that holding the caps lock key and pressing the z key
+will toggle the alternate j k l keypad on and off.
+
+4. Keys and Their Assigned Commands
+
+In this section, we'll go through a list of all the speakup keys and
+commands. You can also get a list of commands and assigned keys from
+the help system.
+
+The following list was taken from the speakupmap.map file. Key
+assignments are on the left of the equal sign, and the associated
+Speakup commands are on the right. The designation "spk" means to press
+and hold the speakup key, a.k.a. keypad insert, a.k.a. caps lock, while
+pressing the other specified key.
+
+spk key_f9 = punc_level_dec
+spk key_f10 = punc_level_inc
+spk key_f11 = reading_punc_dec
+spk key_f12 = reading_punc_inc
+spk key_1 = vol_dec
+spk key_2 = vol_inc
+spk key_3 = pitch_dec
+spk key_4 = pitch_inc
+spk key_5 = rate_dec
+spk key_6 = rate_inc
+key_kpasterisk = toggle_cursoring
+spk key_kpasterisk = speakup_goto
+spk key_f1 = speakup_help
+spk key_f2 = set_win
+spk key_f3 = clear_win
+spk key_f4 = enable_win
+spk key_f5 = edit_some
+spk key_f6 = edit_most
+spk key_f7 = edit_delim
+spk key_f8 = edit_repeat
+shift spk key_f9 = edit_exnum
+ key_kp7 = say_prev_line
+spk key_kp7 = left_edge
+ key_kp8 = say_line
+double key_kp8 = say_line_indent
+spk key_kp8 = say_from_top
+ key_kp9 = say_next_line
+spk key_kp9 = top_edge
+ key_kpminus = speakup_parked
+spk key_kpminus = say_char_num
+ key_kp4 = say_prev_word
+spk key_kp4 = say_from_left
+ key_kp5 = say_word
+double key_kp5 = spell_word
+spk key_kp5 = spell_phonetic
+ key_kp6 = say_next_word
+spk key_kp6 = say_to_right
+ key_kpplus = say_screen
+spk key_kpplus = say_win
+ key_kp1 = say_prev_char
+spk key_kp1 = right_edge
+ key_kp2 = say_char
+spk key_kp2 = say_to_bottom
+double key_kp2 = say_phonetic_char
+ key_kp3 = say_next_char
+spk key_kp3 = bottom_edge
+ key_kp0 = spk_key
+ key_kpdot = say_position
+spk key_kpdot = say_attributes
+key_kpenter = speakup_quiet
+spk key_kpenter = speakup_off
+key_sysrq = speech_kill
+ key_kpslash = speakup_cut
+spk key_kpslash = speakup_paste
+spk key_pageup = say_first_char
+spk key_pagedown = say_last_char
+key_capslock = spk_key
+ spk key_z = spk_lock
+key_leftmeta = spk_key
+ctrl spk key_0 = speakup_goto
+spk key_u = say_prev_line
+spk key_i = say_line
+double spk key_i = say_line_indent
+spk key_o = say_next_line
+spk key_minus = speakup_parked
+shift spk key_minus = say_char_num
+spk key_j = say_prev_word
+spk key_k = say_word
+double spk key_k = spell_word
+spk key_l = say_next_word
+spk key_m = say_prev_char
+spk key_comma = say_char
+double spk key_comma = say_phonetic_char
+spk key_dot = say_next_char
+spk key_n = say_position
+ ctrl spk key_m = left_edge
+ ctrl spk key_y = top_edge
+ ctrl spk key_dot = right_edge
+ctrl spk key_p = bottom_edge
+spk key_apostrophe = say_screen
+spk key_h = say_from_left
+spk key_y = say_from_top
+spk key_semicolon = say_to_right
+spk key_p = say_to_bottom
+spk key_slash = say_attributes
+ spk key_enter = speakup_quiet
+ ctrl spk key_enter = speakup_off
+ spk key_9 = speakup_cut
+spk key_8 = speakup_paste
+shift spk key_m = say_first_char
+ ctrl spk key_semicolon = say_last_char
+
+5. The Speakup Proc System
+
+The Speakup screen reader also creates a speakup subdirectory as a part
+of the proc system. You can see these entries by typing the command:
+
+ls -1 /proc/speakup/*
+
+If you issue the above ls command, you will get back something like
+this:
+
+/proc/speakup/attrib_bleep
+/proc/speakup/bell_pos
+/proc/speakup/bleep_time
+/proc/speakup/bleeps
+/proc/speakup/caps_start
+/proc/speakup/caps_stop
+/proc/speakup/characters
+/proc/speakup/cursor_time
+/proc/speakup/delay_time
+/proc/speakup/delimiters
+/proc/speakup/ex_num
+/proc/speakup/freq
+/proc/speakup/full_time
+/proc/speakup/jiffy_delta
+/proc/speakup/key_echo
+/proc/speakup/keymap
+/proc/speakup/no_interrupt
+/proc/speakup/pitch
+/proc/speakup/punc_all
+/proc/speakup/punc_level
+/proc/speakup/punc_most
+/proc/speakup/punc_some
+/proc/speakup/punct
+/proc/speakup/rate
+/proc/speakup/reading_punc
+/proc/speakup/repeats
+/proc/speakup/say_control
+/proc/speakup/say_word_ctl
+/proc/speakup/silent
+/proc/speakup/spell_delay
+/proc/speakup/synth_direct
+/proc/speakup/synth_name
+/proc/speakup/tone
+/proc/speakup/trigger_time
+/proc/speakup/version
+/proc/speakup/voice
+/proc/speakup/vol
+
+In addition to using the Speakup hot keys to change such things as
+volume, pitch, and rate, you can also echo values to the appropriate
+entry in the /proc/speakup directory. This is very useful, since it
+lets you control Speakup parameters from within a script. How you
+would write such scripts is somewhat beyond the scope of this manual,
+but I will include a couple of simple examples here to give you a
+general idea of what such scripts can do.
+
+Suppose for example, that you wanted to control both the punctuation
+level and the reading punctuation level at the same time. For
+simplicity, we'll call them punc0, punc1, punc2, and punc3. The scripts
+might look something like this:
+
+#!/bin/bash
+# punc0
+# set punc and reading punc levels to 0
+echo 0 >/proc/speakup/punc_level
+echo 0 >/proc/speakup/reading_punc
+echo Punctuation level set to 0.
+
+#!/bin/bash
+# punc1
+# set punc and reading punc levels to 1
+echo 1 >/proc/speakup/punc_level
+echo 1 >/proc/speakup/reading_punc
+echo Punctuation level set to 1.
+
+#!/bin/bash
+# punc2
+# set punc and reading punc levels to 2
+echo 2 >/proc/speakup/punc_level
+echo 2 >/proc/speakup/reading_punc
+echo Punctuation level set to 2.
+
+#!/bin/bash
+# punc3
+# set punc and reading punc levels to 3
+echo 3 >/proc/speakup/punc_level
+echo 3 >/proc/speakup/reading_punc
+echo Punctuation level set to 3.
+
+If you were to store these four small scripts in a directory in your
+path, perhaps /usr/local/bin, and set the permissions to 755 with the
+chmod command, then you could change the default reading punc and
+punctuation levels at the same time by issuing just one command. For
+example, if you were to execute the punc3 command at your shell prompt,
+then the reading punc and punc level would both get set to 3.
+
+I should note that the above scripts were written to work with bash, but
+regardless of which shell you use, you should be able to do something
+similar.
+
+The Speakup proc system also has another interesting use. You can echo
+Speakup parameters into the proc system in a script during system
+startup, and speakup will return to your preferred parameters every time
+the system is rebooted.
+
+Most of the Speakup proc parameters can be manipulated by a regular user
+on the system. However, there are a few parameters that are dangerous
+enough that they should only be manipulated by the root user on your
+system. There are even some parameters that are read only, and cannot
+be written to at all. For example, the version entry in the Speakup
+proc system is read only. This is because there is no reason for a user
+to tamper with the version number which is reported by Speakup. Doing
+an ls -l on /proc/speakup/version will return this:
+
+-r--r--r-- 1 root root 0 Mar 21 13:46 /proc/speakup/version
+
+As you can see, the version entry in the Speakup proc system is read
+only, is owned by root, and belongs to the root group. Doing a cat of
+/proc/speakup/version will display the Speakup version number, like
+this:
+
+cat /proc/speakup/version
+Speakup v-2.00 CVS: Thu Oct 21 10:38:21 EDT 2004
+synth dtlk version 1.1
+
+The display shows the Speakup version number, along with the version
+number of the driver for the current synthesizer.
+
+Looking at entries in the Speakup proc system can be useful in many
+ways. For example, you might wish to know what level your volume is set
+at. You could type:
+
+cat /proc/speakup/vol
+5
+
+The number five which comes back is the level at which the synthesizer
+volume is set at.
+
+All the entries in the Speakup proc system are readable, some are
+writable by root only, and some are writable by everyone. Unless you
+know what you are doing, you should probably leave the ones that are
+writable by root only alone. Most of the names are self explanatory.
+Vol for controlling volume, pitch for pitch, rate for controlling speaking
+rate, etc. If you find one you aren't sure about, you can post a query
+on the Speakup list.
+
+6. Changing Synthesizers
+
+It is possible to change to a different synthesizer while speakup is
+running. In other words, it is not necessary to reboot the system
+in order to use a different synthesizer. You can simply echo the
+synthesizer keyword to the /proc/speakup/synth_name proc entry.
+Depending on your situation, you may wish to echo none to the synth_name
+proc entry, to disable speech while one synthesizer is disconnected and
+a second one is connected in its place. Then echo the keyword for the
+new synthesizer into the synth_name proc entry in order to start speech
+with the newly connected synthesizer. See the list of synthesizer
+keywords in section 1 to find the keyword which matches your synth.
+
+7. Loading modules
+
+As mentioned earlier, Speakup can either be completely compiled into the
+kernel, with the exception of the help module, or it can be compiled as
+a series of modules. When compiled as modules, Speakup will only be
+able to speak some of the bootup messages if your system administrator
+has configured the system to load the modules at boo time. The modules
+can be loaded after the file systems have been checked and mounted, or
+from an initrd. There is a third possibility. Speakup can be compiled
+with some components built into the kernel, and others as modules. As
+we'll see in the next section, this is particularly useful when you are
+working with software synthesizers.
+
+If Speakup is completely compiled as modules, then you must use the
+modprobe command to load Speakup. You do this by loading the module for
+the synthesizer driver you wish to use. The driver modules are all
+named speakup_, where is the keyword for the
+synthesizer you want. So, in order to load the driver for the DecTalk
+Express, you would type the following command:
+
+modprobe speakup_dectlk
+
+Issuing this command would load the DecTalk Express driver and all other
+related Speakup modules necessary to get Speakup up and running.
+
+To completely unload Speakup, again presuming that it is entirely built
+as modules, you would give the command:
+
+modprobe -r speakup_dectlk
+
+The above command assumes you were running a DecTalk Express. If you
+were using a different synth, then you would substitute its keyword in
+place of dectlk.
+
+But now, suppose we have a situation where the main Speakup component
+is built into the kernel, and some or all of the drivers are built as
+modules. Since the main part of Speakup is compiled into the kernel, a
+partial Speakup proc system has been created which we can take advantage
+of by simply echoing the synthesizer keyword into the
+/proc/speakup/synth_name proc entry. This will cause the kernel to
+automatically load the appropriate driver module, and start Speakup
+talking. To switch to another synth, just echo a new keyword to the
+synth_name proc entry. For example, to load the DoubleTalk LT driver,
+you would type:
+
+echo ltlk >/proc/speakup/synth_name
+
+You can use the modprobe -r command to unload driver modules, regardless
+of whether the main part of Speakup has been built into the kernel or
+not.
+
+8. Using Software Synthesizers
+
+Using a software synthesizer requires that some other software be
+installed and running on your system. For this reason, software
+synthesizers are not available for use at bootup, or during a system
+installation process.
+
+In order to use a software synthesizer, you must have a package called
+Speech Dispatcher running on your system, and it must be configured to
+work with one of its supported software synthesizers.
+
+Two open source synthesizers you might use are Flite and Festival. You
+might also choose to purchase the Software DecTalk from Fonix Sales Inc.
+If you run a google search for Fonix, you'll find their web site.
+
+You can obtain a copy of Speech Dispatcher from free(b)soft at
+http://www.freebsoft.org/. Follow the installation instructions that
+come with Speech Dispatcher in order to install and configure Speech
+Dispatcher. You can check out the web site for your Linux distribution
+in order to get a copy of either Flite or Festival. Your Linux
+distribution may also have a precompiled Speech Dispatcher package.
+
+Once you've installed, configured, and tested Speech Dispatcher with your
+chosen software synthesizer, you still need one more piece of software
+in order to make things work. You need a package called speechd-up.
+You get it from the free(b)soft web site mentioned above. After you've
+compiled and installed speechd-up, you are almost ready to begin using
+your software synthesizer.
+
+Before you can use a software synthesizer, you must have created the
+/dev/softsynth device. If you have not already done so, issue the
+following commands as root:
+
+cd /dev
+mknod softsynth c 10 26
+
+While we are at it, we might just as well create the /dev/synth device,
+which can be used to let user space programs send information to your
+synthesizer. To create /dev/synth, change to the /dev directory, and
+issue the following command as root:
+
+mknod synth c 10 25
+
+Now you can begin using your software synthesizer. In order to do so,
+echo the sftsyn keyword to the synth_name proc entry like this:
+
+echo sftsyn >/proc/speakup/synth_name
+
+Next run the speechd_up command like this:
+
+speechd_up &
+
+Your synth should now start talking, and you should be able to adjust
+the pitch, rate, etc.
+
+In this section, we have assumed that your copy of Speakup was compiled
+with the speakup_sftsyn component either built into the kernel, or
+compiled as a module.
+
+9. Using The DecTalk PC Card
+
+The DecTalk PC card is an ISA card that is inserted into one of the ISA
+slots in your computer. It requires that the DecTalk PC software be
+installed on your computer, and that the software be loaded onto the
+Dectalk PC card before it can be used.
+
+You can get the dec_pc.tgz file from the linux-speakup.org site. The
+dec_pc.tgz file is in the ~ftp/pub/linux/speakup directory.
+
+After you have downloaded the dec_pc.tgz file, untar it in your home
+directory, and read the Readme file in the newly created dec_pc
+directory.
+
+The easiest way to get the software working is to copy the entire dec_pc
+directory into /user/local/lib. To do this, su to root in your home
+directory, and issue the command:
+
+cp dec_pc /usr/local/lib
+
+You will need to copy the dtload command from the dec_pc directory to a
+directory in your path. Either /usr/bin or /usr/local/bin is a good
+choice.
+
+You can now run the dtload command in order to load the DecTalk PC
+software onto the card. After you have done this, echo the decpc
+keyword to the synth_name entry in the proc system like this:
+
+echo decpc >/proc/speakup/synth_name
+
+Your DecTalk PC should start talking, and then you can adjust the pitch,
+rate, volume, voice, etc. The voice entry in the Speakup proc system
+will accept a number from 0 through 7 for the DecTalk PC synthesizer,
+which will give you access to some of the DecTalk voices.
+
+10. Using Cursor Tracking
+
+In Speakup version 2.0 and later, cursor tracking is turned on by
+default. This means that when you are using an editor, Speakup will
+automatically speak characters as you move left and right with the
+cursor keys, and lines as you move up and down with the cursor keys.
+
+This is extremely useful, and makes editing files a snap. But there are
+times when cursor tracking can get in your way. So Speakup provides a
+toggle to turn cursor tracking on and off. You do this with the keypad
+asterisk key. Pressing this key repeatedly will toggle the cursor
+tracking on and off, and you will hear Speakup say, "cursoring off", and
+"cursoring on".
+
+Some folks like to turn cursor tracking off while they are using the
+lynx web browser. You definitely want to turn cursor tracking off when
+you are using the alsamixer application. Otherwise, you won't be able
+to hear your mixer settings while you are using the arrow keys.
+
+11. Cut and Paste
+
+One of Speakup's more useful features is the ability to cut and paste
+text on the screen. This means that you can capture information from a
+program, and paste that captured text into a different place in the
+program, or into an entirely different program, which may even be
+running on a different console.
+
+For example, in this manual, we have made references to several web
+sites. It would be nice if you could cut and paste these urls into your
+web browser. Speakup does this quite nicely. Suppose you wanted to
+past the following url into your browser:
+
+http://linux-speakup.org/
+
+Use the speakup review keys to position the reading cursor on the first
+character of the above url. When the reading cursor is in position,
+press the keypad slash key once. Speakup will say, "mark". Next,
+position the reading cursor on the rightmost character of the above
+url. Press the keypad slash key once again to actually cut the text
+from the screen. Speakup will say, "cut". Although we call this
+cutting, Speakup does not actually delete the cut text from the screen.
+It makes a copy of the text in a special buffer for later pasting.
+
+Now that you have the url cut from the screen, you can paste it into
+your browser, or even paste the url on a command line as an argument to
+your browser.
+
+Suppose you want to start lynx and go to the Speakup site.
+
+You can switch to a different console with the alt left and right
+arrows, or you can switch to a specific console by typing alt and a
+function key. These are not Speakup commands, just standard Linux
+console capabilities.
+
+Once you've changed to an appropriate console, and are at a shell prompt,
+type the word lynx, followed by a space. Now press and hold the speakup
+key, while you type the keypad slash character. The url will be pasted
+onto the command line, just as though you had typed it in. Press the
+enter key to execute the command.
+
+The paste buffer will continue to hold the cut information, until a new
+mark and cut operation is carried out. This means you can paste the cut
+information as many times as you like before doing another cut
+operation.
+
+You are not limited to cutting and pasting only one line on the screen.
+You can also cut and paste rectangular regions of the screen. Just
+position the reading cursor at the top left corner of the text to be
+cut, mark it with the keypad slash key, then position the reading cursor
+at the bottom right corner of the region to be cut, and cut it with the
+keypad slash key.
+
+12. Changing the Pronunciation of Characters
+
+Through the /proc/speakup/chars proc entry, Speakup gives you the
+ability to change how Speakup pronounces a given character. You could,
+for example, change how some punctuation characters are spoken. You can
+even change how Speakup will pronounce certain letters.
+
+You may, for example, wish to change how Speakup pronounces the z
+character. The author of Speakup, Kirk Reiser, is Canadian, and thus
+believes that the z should be pronounced zed. If you are an American,
+you might wish to use the zee pronunciation instead of zed. You can
+change the pronunciation of both the upper and lower case z with the
+following two commands:
+
+echo 90 zee >/proc/speakup/characters
+echo 122 zee >/proc/speakup/characters
+
+Let's examine the parts of the two previous commands. They are issued
+at the shell prompt, and could be placed in a startup script.
+
+The word echo tells the shell that you want to have it display the
+string of characters that follow the word echo. If you were to just
+type:
+
+echo hello.
+
+You would get the word hello printed on your screen as soon as you
+pressed the enter key. In this case, we are echoing strings that we
+want to be redirected into the proc system.
+
+The numbers 90 and 122 in the above echo commands are the ascii numeric
+values for the upper and lower case z, the characters we wish to change.
+
+The string zee is the pronunciation that we want Speakup to use for the
+upper and lower case z.
+
+The > symbol redirects the output of the echo command to a file, just
+like in DOS, or at the Windows command prompt.
+
+And finally, /proc/speakup/chars is the file entry in the proc system
+where we want the output to be directed. Speakup looks at the numeric
+value of the character we want to change, and inserts the pronunciation
+string into an internal table.
+
+You can look at the whole table with the following command:
+
+cat /proc/speakup/chars
+
+Speakup will then print out the entire character pronunciation table. I
+won't display it here, but leave you to look at it at your convenience.
+
+13. Mapping Keys
+
+Speakup has the capability of allowing you to assign or "map" keys to
+internal Speakup commands. This section necessarily assumes you have a
+Linux kernel source tree installed, and that it has been patched and
+configured with Speakup. How you do this is beyond the scope of this
+manual. For this information, visit the Speakup web site at
+http://linux-speakup.org/. The reason you'll need the kernel source
+tree patched with Speakup is that the genmap utility you'll need for
+processing keymaps is in the
+/usr/src/linux-/drivers/char/speakup directory. The
+ in the above directory path is the version number of
+the Linux source tree you are working with.
+
+So ok, you've gone off and gotten your kernel source tree, and patched
+and configured it. Now you can start manipulating keymaps.
+
+You can either use the
+/usr/src/linux-/drivers/char/speakup/speakupmap.map file
+included with the Speakup source, or you can cut and paste the copy in
+section 4 into a separate file. If you use the one in the Speakup
+source tree, make sure you make a backup of it before you start making
+changes. You have been warned!
+
+Suppose that you want to swap the key assignments for the Speakup
+say_last_char and the Speakup say_first_char commands. The
+speakupmap.map lists the key mappings for these two commands as follows:
+
+spk key_pageup = say_first_char
+spk key_pagedown = say_last_char
+
+You can edit your copy of the speakupmap.map file and swap the command
+names on the right side of the = (equals) sign. You did make a backup,
+right? The new keymap lines would look like this:
+
+spk key_pageup = say_last_char
+spk key_pagedown = say_first_char
+
+After you edit your copy of the speakupmap.map file, save it under a new
+file name, perhaps newmap.map. Then exit your editor and return to the
+shell prompt.
+
+You are now ready to load your keymap with your swapped key assignments.
+ Assuming that you saved your new keymap as the file newmap.map, you
+would load your keymap into the proc system like this:
+
+/usr/src/linux-/drivers/char/speakup/genmap newmap.map
+>/proc/speakup/keymap
+
+Remember to substitute your kernel version number for the
+ in the above command. Also note that although the
+above command wrapped onto two lines in this document, you should type
+it all on one line.
+
+Your say first and say last characters should now be swapped. Pressing
+speakup pagedown should read you the first non-whitespace character on
+the line your reading cursor is in, and pressing speakup pageup should
+read you the last character on the line your reading cursor is in.
+
+You should note that these new mappings will only stay in effect until
+you reboot, or until you load another keymap.
+
+One final warning. If you try to load a partial map, you will quickly
+find that all the mappings you didn't include in your file got deleted
+from the working map. Be extremely careful, and always make a backup!
+You have been warned!
+
+14. Using Speakup's Windowing Capability
+
+Speakup has the capability of defining and manipulating windows on the
+screen. Speakup uses the term "Window", to mean a user defined area of
+the screen. The key strokes for defining and manipulating Speakup
+windows are as follows:
+
+speakup + f2 -- Set the bounds of the window.
+Speakup + f3 -- clear the current window definition.
+speakup + f4 -- Toggle window silence on and off.
+speakup + keypad plus -- Say the currently defined window.
+
+These capabilities are useful for tracking a certain part of the screen
+without rereading the whole screen, or for silencing a part of the
+screen that is constantly changing, such as a clock or status line.
+
+There is no way to save these window settings, and you can only have one
+window defined for each virtual console. There is also no way to have
+windows automaticly defined for specific applications.
+
+In order to define a window, use the review keys to move your reading
+cursor to the beginning of the area you want to define. Then press
+speakup + f2. Speakup will tell you that the window starts at the
+indicated row and column position. Then move the reading cursor to the
+end of the area to be defined as a window, and press speakup + f2 again.
+ If there is more than one line in the window, Speakup will tell you
+that the window ends at the indicated row and column position. If there
+is only one line in the window, then Speakup will tell you that the
+window is the specified line on the screen. If you are only defining a
+one line window, you can just press speakup + f2 twice after placing the
+reading cursor on the line you want to define as a window. It is not
+necessary to position the reading cursor at the end of the line in order
+to define the whole line as a window.
+
+ GNU Free Documentation License
+ Version 1.2, November 2002
+
+
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+0. PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document "free" in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+
+1. APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The "Document", below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as "you". You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A "Modified Version" of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (Thus, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The "Cover Texts" are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A "Transparent" copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML, PostScript or PDF designed for human modification. Examples of
+transparent image formats include PNG, XCF and JPG. Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML, PostScript or PDF produced by some word
+processors for output purposes only.
+
+The "Title Page" means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, "Title Page" means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section "Entitled XYZ" means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as "Acknowledgements",
+"Dedications", "Endorsements", or "History".) To "Preserve the Title"
+of such a section when you modify the Document means that it remains a
+section "Entitled XYZ" according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+
+2. VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+3. COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+
+4. MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+ from that of the Document, and from those of previous versions
+ (which should, if there were any, be listed in the History section
+ of the Document). You may use the same title as a previous version
+ if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the Modified
+ Version, together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has fewer than five),
+ unless they release you from this requirement.
+C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice
+ giving the public permission to use the Modified Version under the
+ terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections
+ and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section Entitled "History", Preserve its Title, and add
+ to it an item stating at least the title, year, new authors, and
+ publisher of the Modified Version as given on the Title Page. If
+ there is no section Entitled "History" in the Document, create one
+ stating the title, year, authors, and publisher of the Document as
+ given on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the "History" section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section all
+ the substance and tone of each of the contributor acknowledgements
+ and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.
+M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+N. Do not retitle any existing section to be Entitled "Endorsements"
+ or to conflict in title with any Invariant Section.
+O. Preserve any Warranty Disclaimers.
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled "Endorsements", provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+
+5. COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled "History"
+in the various original documents, forming one section Entitled
+"History"; likewise combine any sections Entitled "Acknowledgements",
+and any sections Entitled "Dedications". You must delete all sections
+Entitled "Endorsements".
+
+
+6. COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an "aggregate" if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+
+8. TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled "Acknowledgements",
+"Dedications", or "History", the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+
+9. TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+
+
+ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+ Copyright (c) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+The End.
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/MAINTAINERS.patch linux-2.4.30/drivers/char/speakup/diff-v26/MAINTAINERS.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/MAINTAINERS.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/MAINTAINERS.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,16 @@
+--- /usr/src/linux-2.6.11/MAINTAINERS.orig 2005-03-02 20:16:01.241297800 -0500
++++ MAINTAINERS 2005-03-02 20:16:01.776225072 -0500
+@@ -2113,6 +2113,13 @@
+ L: sparclinux@vger.kernel.org
+ S: Maintained
+
++SPEAKUP Console speech output
++P: Kirk Reiser
++M: kirk@braille.uwo.ca
++L: speakup@braille.uwo.ca
++W: http://www.linux-speakup.org
++S: Maintained
++
+ SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
+ P: Roger Wolff
+ M: R.E.Wolff@BitWizard.nl
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/arch^arm^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v26/arch^arm^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/arch^arm^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/arch^arm^Kconfig.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.6.11/arch/arm/Kconfig.orig 2005-03-02 20:16:01.260295217 -0500
++++ arch/arm/Kconfig 2005-03-02 20:16:01.784223984 -0500
+@@ -720,6 +720,7 @@
+ source "arch/arm/oprofile/Kconfig"
+
+ source "drivers/video/Kconfig"
++source "drivers/char/speakup/Kconfig"
+
+ source "sound/Kconfig"
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/arch^mips^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v26/arch^mips^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/arch^mips^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/arch^mips^Kconfig.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,11 @@
+--- /usr/src/linux-2.6.11/arch/mips/Kconfig.orig 2005-03-02 20:16:01.300289780 -0500
++++ arch/mips/Kconfig 2005-03-02 20:16:01.790223169 -0500
+@@ -843,6 +843,8 @@
+ depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
+ default y
+
++source "drivers/char/speakup/Kconfig"
++
+ config SIBYTE_STANDALONE_RAM_SIZE
+ int "Memory size (in megabytes)"
+ depends on SIBYTE_STANDALONE
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/arch^sparc64^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v26/arch^sparc64^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/arch^sparc64^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/arch^sparc64^Kconfig.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,11 @@
+--- /usr/src/linux-2.6.11/arch/sparc64/Kconfig.orig 2005-03-02 20:16:01.336284886 -0500
++++ arch/sparc64/Kconfig 2005-03-02 20:16:01.795222489 -0500
+@@ -468,6 +468,8 @@
+
+ source "drivers/video/Kconfig"
+
++source "drivers/char/speakup/Kconfig"
++
+ source "drivers/serial/Kconfig"
+
+ source "drivers/sbus/char/Kconfig"
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/arch^sparc^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v26/arch^sparc^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/arch^sparc^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/arch^sparc^Kconfig.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,11 @@
+--- /usr/src/linux-2.6.11/arch/sparc/Kconfig.orig 2005-03-02 20:16:01.318287333 -0500
++++ arch/sparc/Kconfig 2005-03-02 20:16:01.800221809 -0500
+@@ -297,6 +297,8 @@
+
+ source "drivers/video/Kconfig"
+
++source "drivers/char/speakup/Kconfig"
++
+ source "drivers/mtd/Kconfig"
+
+ source "drivers/serial/Kconfig"
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^Kconfig.patch linux-2.4.30/drivers/char/speakup/diff-v26/drivers^Kconfig.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^Kconfig.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/drivers^Kconfig.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,11 @@
+--- /usr/src/linux-2.6.11/drivers/Kconfig.orig 2005-03-02 20:16:01.368280536 -0500
++++ drivers/Kconfig 2005-03-02 20:16:01.804221266 -0500
+@@ -50,6 +50,8 @@
+
+ source "drivers/video/Kconfig"
+
++source "drivers/char/speakup/Kconfig"
++
+ source "sound/Kconfig"
+
+ source "drivers/usb/Kconfig"
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^Makefile.patch linux-2.4.30/drivers/char/speakup/diff-v26/drivers^Makefile.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^Makefile.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/drivers^Makefile.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,24 @@
+--- /usr/src/linux-2.6.11/drivers/Makefile.orig 2005-03-02 20:16:01.391277409 -0500
++++ drivers/Makefile 2005-03-02 20:16:01.808220722 -0500
+@@ -1,4 +1,3 @@
+-#
+ # Makefile for the Linux kernel device drivers.
+ #
+ # 15 Sep 2000, Christoph Hellwig
+@@ -25,6 +24,8 @@
+ # serial drivers start registering their serio ports
+ obj-$(CONFIG_SERIO) += input/serio/
+ obj-y += serial/
++# load keyboard early so speakup can be quieted
++obj-$(CONFIG_INPUT) += input/
+ obj-$(CONFIG_PARPORT) += parport/
+ obj-y += base/ block/ misc/ net/ media/
+ obj-$(CONFIG_NUBUS) += nubus/
+@@ -47,7 +48,6 @@
+ obj-$(CONFIG_TC) += tc/
+ obj-$(CONFIG_USB) += usb/
+ obj-$(CONFIG_USB_GADGET) += usb/gadget/
+-obj-$(CONFIG_INPUT) += input/
+ obj-$(CONFIG_GAMEPORT) += input/gameport/
+ obj-$(CONFIG_I2O) += message/
+ obj-$(CONFIG_I2C) += i2c/
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^char^Makefile.patch linux-2.4.30/drivers/char/speakup/diff-v26/drivers^char^Makefile.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^char^Makefile.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/drivers^char^Makefile.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.6.11/drivers/char/Makefile.orig 2005-03-02 20:16:01.409274962 -0500
++++ drivers/char/Makefile 2005-03-02 20:16:01.813220042 -0500
+@@ -81,6 +81,7 @@
+ obj-$(CONFIG_NWFLASH) += nwflash.o
+ obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
+
++obj-$(CONFIG_SPEAKUP) += speakup/
+ obj-$(CONFIG_WATCHDOG) += watchdog/
+ obj-$(CONFIG_MWAVE) += mwave/
+ obj-$(CONFIG_AGP) += agp/
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^char^consolemap.c.patch linux-2.4.30/drivers/char/speakup/diff-v26/drivers^char^consolemap.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^char^consolemap.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/drivers^char^consolemap.c.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,7 @@
+--- /usr/src/linux-2.6.11/drivers/char/consolemap.c.orig 2005-03-02 20:16:01.451269253 -0500
++++ drivers/char/consolemap.c 2005-03-02 20:16:01.818219362 -0500
+@@ -683,3 +683,4 @@
+ }
+
+ EXPORT_SYMBOL(con_copy_unimap);
++EXPORT_SYMBOL(inverse_translate);
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^char^keyboard.c.patch linux-2.4.30/drivers/char/speakup/diff-v26/drivers^char^keyboard.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^char^keyboard.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/drivers^char^keyboard.c.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,124 @@
+--- /usr/src/linux-2.6.11/drivers/char/keyboard.c.orig 2005-03-02 20:16:01.491263815 -0500
++++ drivers/char/keyboard.c 2005-03-02 20:16:01.824218547 -0500
+@@ -40,6 +40,13 @@
+ #include
+ #include
+
++
++#include
++
++#ifdef CONFIG_SPEAKUP_MODULE
++spk_key_func addr_spk_key = NULL;
++#endif
++
+ static void kbd_disconnect(struct input_handle *handle);
+ extern void ctrl_alt_del(void);
+
+@@ -64,6 +71,10 @@
+
+ #define KBD_DEFLOCK 0
+
++/* Key types processed even in raw modes */
++
++#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) | (1 << KT_SPKUP))
++
+ void compute_shiftstate(void);
+
+ /*
+@@ -79,7 +90,7 @@
+ typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
+ char up_flag, struct pt_regs *regs);
+ static k_handler_fn K_HANDLERS;
+-static k_handler_fn *k_handler[16] = { K_HANDLERS };
++k_handler_fn *k_handler[16] = { K_HANDLERS };
+
+ #define FN_HANDLERS\
+ fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
+@@ -100,15 +111,18 @@
+ const int max_vals[] = {
+ 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
+ NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
+- 255, NR_LOCK - 1, 255
++ 255, NR_LOCK - 1, 255, 255
+ };
+
+ const int NR_TYPES = ARRAY_SIZE(max_vals);
+
+ struct kbd_struct kbd_table[MAX_NR_CONSOLES];
+-static struct kbd_struct *kbd = kbd_table;
++struct kbd_struct *kbd = kbd_table;
+ static struct kbd_struct kbd0;
+
++EXPORT_SYMBOL(kbd);
++EXPORT_SYMBOL(k_handler);
++
+ int spawnpid, spawnsig;
+
+ /*
+@@ -254,12 +268,14 @@
+ }
+ }
+ }
+- if (ticks)
+- mod_timer(&kd_mksound_timer, jiffies + ticks);
++ if (ticks)
++ mod_timer(&kd_mksound_timer, jiffies + ticks);
+ } else
+ kd_nosound(0);
+ }
+
++EXPORT_SYMBOL(kd_mksound);
++
+ /*
+ * Setting the keyboard rate.
+ */
+@@ -601,6 +617,7 @@
+ if (up_flag)
+ return;
+ if (value >= ARRAY_SIZE(fn_handler))
++ if (up_flag || (value >= ARRAY_SIZE(fn_handler)))
+ return;
+ if ((kbd->kbdmode == VC_RAW ||
+ kbd->kbdmode == VC_MEDIUMRAW) &&
+@@ -1116,6 +1133,13 @@
+ key_map = key_maps[shift_final];
+
+ if (!key_map) {
++#ifdef CONFIG_SPEAKUP
++ if (speakup_key(vc, shift_final, keycode, K(KT_SHIFT,0), !down, regs ))
++ return;
++#elif defined(CONFIG_SPEAKUP_MODULE)
++ if ( addr_spk_key && (*addr_spk_key)(vc, shift_final,
++ keycode, K(KT_SHIFT,0), !down, regs) ) return;
++#endif
+ compute_shiftstate();
+ kbd->slockstate = 0;
+ return;
+@@ -1133,10 +1157,17 @@
+ }
+
+ type -= 0xf0;
+-
+- if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
++#ifdef CONFIG_SPEAKUP
++ if (speakup_key(vc, shift_final, keycode, keysym, !down, regs ))
+ return;
++#elif defined(CONFIG_SPEAKUP_MODULE)
++ if ( addr_spk_key && (*addr_spk_key)(vc, shift_final,
++ keycode, keysym, !down, regs) ) return;
++#endif
+
++ if (raw_mode && type != KT_SPEC && type != KT_SHIFT )
++ return;
++
+ if (type == KT_LETTER) {
+ type = KT_LATIN;
+ if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
+@@ -1145,7 +1176,6 @@
+ keysym = key_map[keycode];
+ }
+ }
+-
+ (*k_handler[type])(vc, keysym & 0xff, !down, regs);
+
+ if (type != KT_SLOCK)
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^char^vt.c.patch linux-2.4.30/drivers/char/speakup/diff-v26/drivers^char^vt.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/drivers^char^vt.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/drivers^char^vt.c.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,118 @@
+--- /usr/src/linux-2.6.11/drivers/char/vt.c.orig 2005-03-02 20:16:01.537257562 -0500
++++ drivers/char/vt.c 2005-03-02 20:16:01.833217323 -0500
+@@ -98,6 +98,10 @@
+ #include
+ #include
+
++#include
++#ifdef CONFIG_SPEAKUP_MODULE
++#include "speakup/spk_con_module.h"
++#endif
+ #include "console_macros.h"
+
+
+@@ -742,6 +746,7 @@
+ screenbuf = (unsigned short *) q;
+ kmalloced = 1;
+ vc_init(currcons, vc_cons[currcons].d->vc_rows, vc_cons[currcons].d->vc_cols, 1);
++ speakup_allocate(currcons); /* speakup needs more too. */
+
+ if (!pm_con) {
+ pm_con = pm_register(PM_SYS_DEV,
+@@ -978,6 +983,7 @@
+ pos += vc_cons[currcons].d->vc_size_row;
+ }
+ need_wrap = 0;
++ speakup_con_write(currcons, "\n",1);
+ }
+
+ static void ri(int currcons)
+@@ -1006,6 +1012,7 @@
+ pos -= 2;
+ x--;
+ need_wrap = 0;
++ speakup_bs(currcons);
+ }
+ }
+
+@@ -1541,6 +1548,7 @@
+ break;
+ }
+ pos += (x << 1);
++ speakup_con_write(currcons, " ", 1);
+ return;
+ case 10: case 11: case 12:
+ lf(currcons);
+@@ -2060,6 +2068,7 @@
+ }
+ if (decim)
+ insert_char(currcons, 1);
++ speakup_con_write(currcons, (char *) &tc,1);
+ scr_writew(himask ?
+ ((attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+ (attr << 8) + tc,
+@@ -2085,6 +2094,7 @@
+ release_console_sem();
+
+ out:
++ speakup_con_update(currcons);
+ return n;
+ #undef FLUSH
+ }
+@@ -2110,6 +2120,7 @@
+ /* we only changed when the console had already
+ been allocated - a new console is not created
+ in an interrupt routine */
++ speakup_con_update(want_console);
+ }
+ want_console = -1;
+ }
+@@ -2128,6 +2139,7 @@
+ do_blank_screen(0);
+ blank_timer_expired = 0;
+ }
++ speakup_con_update(fg_console);
+
+ release_console_sem();
+ }
+@@ -2185,6 +2197,7 @@
+
+ /* Contrived structure to try to emulate original need_wrap behaviour
+ * Problems caused when we have need_wrap set on '\n' character */
++ speakup_con_write(currcons, b, count);
+ while (count--) {
+ c = *b++;
+ if (c == 10 || c == 13 || c == 8 || need_wrap) {
+@@ -2229,7 +2242,8 @@
+ }
+ }
+ set_cursor(vc_cons[currcons].d);
+-
++ speakup_con_update(currcons);
++
+ if (!oops_in_progress)
+ poke_blanked_console();
+
+@@ -2577,6 +2591,7 @@
+ master_display_fg = vc_cons[currcons].d;
+ set_origin(currcons);
+ save_screen(currcons);
++ speakup_init(currcons);
+ gotoxy(vc_cons[currcons].d, x, y);
+ csi_J(currcons, 0);
+ update_screen(fg_console);
+@@ -3262,12 +3277,13 @@
+ EXPORT_SYMBOL(update_region);
+ EXPORT_SYMBOL(redraw_screen);
+ EXPORT_SYMBOL(vc_resize);
++EXPORT_SYMBOL(vc_cons);
+ EXPORT_SYMBOL(fg_console);
+ EXPORT_SYMBOL(console_blank_hook);
+ EXPORT_SYMBOL(console_blanked);
+ EXPORT_SYMBOL(vt_cons);
+-EXPORT_SYMBOL(vc_cons);
+ #ifndef VT_SINGLE_DRIVER
+ EXPORT_SYMBOL(take_over_console);
+ EXPORT_SYMBOL(give_up_console);
+ #endif
++EXPORT_SYMBOL(screen_glyph);
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/fs^proc^root.c.patch linux-2.4.30/drivers/char/speakup/diff-v26/fs^proc^root.c.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/fs^proc^root.c.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/fs^proc^root.c.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,13 @@
+--- /usr/src/linux-2.6.11/fs/proc/root.c.orig 2005-03-02 20:16:01.571252940 -0500
++++ fs/proc/root.c 2005-03-02 20:16:01.837216780 -0500
+@@ -73,6 +73,10 @@
+ proc_mkdir("openprom", NULL);
+ #endif
+ proc_tty_init();
++#ifdef CONFIG_SPEAKUP /* console speech output */
++ proc_speakup_init();
++#endif /* speakup */
++
+ #ifdef CONFIG_PROC_DEVICETREE
+ proc_device_tree_init();
+ #endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/include^linux^keyboard.h.patch linux-2.4.30/drivers/char/speakup/diff-v26/include^linux^keyboard.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/include^linux^keyboard.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/include^linux^keyboard.h.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,18 @@
+--- /usr/src/linux-2.6.11/include/linux/keyboard.h.orig 2005-03-02 20:16:01.593249949 -0500
++++ include/linux/keyboard.h 2005-03-02 20:16:01.842216100 -0500
+@@ -45,6 +45,7 @@
+ #define KT_ASCII 9
+ #define KT_LOCK 10
+ #define KT_SLOCK 12
++#define KT_SPKUP 14
+
+ #define K(t,v) (((t)<<8)|(v))
+ #define KTYP(x) ((x) >> 8)
+@@ -427,6 +428,7 @@
+ #define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR)
+
+ #define NR_LOCK 8
++#define NR_SPKUP 0x45
+
+ #define MAX_DIACR 256
+ #endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/include^linux^miscdevice.h.patch linux-2.4.30/drivers/char/speakup/diff-v26/include^linux^miscdevice.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/include^linux^miscdevice.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/include^linux^miscdevice.h.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,10 @@
+--- /usr/src/linux-2.6.11/include/linux/miscdevice.h.orig 2005-03-02 20:16:01.610247638 -0500
++++ include/linux/miscdevice.h 2005-03-02 20:16:01.847215420 -0500
+@@ -12,6 +12,7 @@
+ #define APOLLO_MOUSE_MINOR 7
+ #define PC110PAD_MINOR 9
+ /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
++#define SYNTH_MINOR 25
+ #define WATCHDOG_MINOR 130 /* Watchdog timer */
+ #define TEMP_MINOR 131 /* Temperature Sensor */
+ #define RTC_MINOR 135
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/include^linux^proc_fs.h.patch linux-2.4.30/drivers/char/speakup/diff-v26/include^linux^proc_fs.h.patch
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/include^linux^proc_fs.h.patch 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/include^linux^proc_fs.h.patch 2005-03-02 17:23:56.000000000 -0800
@@ -0,0 +1,13 @@
+--- /usr/src/linux-2.6.11/include/linux/proc_fs.h.orig 2005-03-02 20:16:01.641243424 -0500
++++ include/linux/proc_fs.h 2005-03-02 20:16:01.851214876 -0500
+@@ -129,6 +129,10 @@
+ extern void proc_tty_register_driver(struct tty_driver *driver);
+ extern void proc_tty_unregister_driver(struct tty_driver *driver);
+
++#ifdef CONFIG_SPEAKUP /* console speech output */
++extern void proc_speakup_init(void);
++#endif /* speakup */
++
+ /*
+ * proc_devtree.c
+ */
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/diff-v26/include^linux^speakup.h.copy linux-2.4.30/drivers/char/speakup/diff-v26/include^linux^speakup.h.copy
--- linux-2.4.30.orig/drivers/char/speakup/diff-v26/include^linux^speakup.h.copy 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/diff-v26/include^linux^speakup.h.copy 2003-07-16 10:51:21.000000000 -0700
@@ -0,0 +1,41 @@
+#ifndef __SPEAKUP_H
+#define __SPEAKUP_H
+
+#include
+
+struct kbd_struct;
+struct vc_data;
+
+/* how about some prototypes! */
+extern int do_spk_ioctl(int,unsigned char *data,int,void *);
+
+#if defined(CONFIG_SPEAKUP)
+extern void speakup_init(int);
+extern void speakup_allocate(int);
+extern void speakup_bs(int);
+extern void speakup_con_write(int, const char *, int);
+extern void speakup_con_update(int);
+#if (LINUX_VERSION_CODE < 132419)
+extern int speakup_key ( int, u_char, u_short, u_char );
+#else
+extern int speakup_key(struct vc_data*, int, int, u_short, int, struct pt_regs *);
+#endif
+#elif defined(CONFIG_SPEAKUP_MODULE)
+typedef void (*spk_con_func)(int );
+typedef void (*spk_write_func)(int, const char *, int);
+#if (LINUX_VERSION_CODE < 132419)
+typedef int (*spk_key_func)(int, u_char, u_short, u_char );
+#else
+typedef int (*spk_key_func)(struct vc_data*, int, int, u_short, int, struct pt_regs *);
+#endif
+extern void spk_set_addresses( spk_con_func allocate, spk_con_func bs,
+ spk_write_func con_write, spk_con_func con_update, spk_key_func key );
+#define speakup_init(currcons)
+#else
+#define speakup_allocate(currcons)
+#define speakup_bs(currcons)
+#define speakup_con_write(currcons, str, len)
+#define speakup_con_update(currcons)
+#define speakup_init(currcons)
+#endif
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/dtload.c linux-2.4.30/drivers/char/speakup/dtload.c
--- linux-2.4.30.orig/drivers/char/speakup/dtload.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/dtload.c 2003-08-08 11:15:12.000000000 -0700
@@ -0,0 +1,554 @@
+/*
+ * This is the DECtalk PC firmware loader for the Linux kernel, version 1.0
+ *
+ * Original 386BSD source:
+ * Copyright ( c ) 1996 Brian Buhrow
+ *
+ * Adapted for Linux:
+ * Copyright ( c ) 1997 Nicolas Pitre
+ *
+ * Adapted for speakup:
+ * Copyright ( c ) 2003 David Borowski
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "dtload.h"
+#include "dtpc_reg.h"
+
+#define dt_delay(x) usleep(x)
+int verbose = 0, intest = 0,infd = -1;
+int image_len, total_paras;
+int dt_stat, dma_state = 0, has_kernel = 0;
+struct dos_reloc fixups[512];
+char *read_buff = NULL;
+struct dos_exe_header header;
+u_short iobase = 0x350;
+
+static inline int dt_getstatus( )
+{
+ dt_stat = inb_p( iobase )|(inb_p( iobase+1 )<<8);
+ return dt_stat;
+}
+
+static void dt_sendcmd( u_int cmd )
+{
+ outb_p( cmd & 0xFF, iobase );
+ outb_p( (cmd>>8) & 0xFF, iobase+1 );
+}
+
+static int dt_waitbit( int bit )
+{
+ int timeout = 100;
+ while ( --timeout > 0 ) {
+ if( (dt_getstatus( ) & bit ) == bit ) return 1;
+ usleep( 1000 );
+ }
+ return 0;
+}
+
+static int dt_sendcmd_wait( u_int cmd, int bit )
+{
+ int timeout = 1000;
+ outb_p( cmd & 0xFF, iobase );
+ outb_p( (cmd>>8) & 0xFF, iobase+1 );
+ while ( --timeout > 0 ) {
+ if( (dt_getstatus( ) & bit ) == bit ) return 1;
+ usleep( 1000 );
+ }
+ return 0;
+}
+
+static int dt_waitmode( int pattern )
+{
+ int timeout = 1000;
+ while ( --timeout > 0 ) {
+ if( dt_getstatus( ) == pattern ) return 1;
+ usleep( 1000 );
+ }
+ fprintf( stderr, "waitmode p=%x s = %x\n", pattern, dt_stat );
+ return 0;
+}
+
+static int dt_wait_dma( )
+{
+ int timeout = 1000, state = dma_state;
+ if( !has_kernel ){
+ dt_delay( 500 );
+ return( dt_waitbit( STAT_dma_ready ) );
+ }
+ if( ! dt_waitbit( STAT_dma_ready ) ) return 0;
+ while ( --timeout > 0 ) {
+ if( (dt_getstatus()&STAT_dma_state) == state ) return 1;
+ usleep( 1000 );
+ }
+ dma_state = dt_getstatus( ) & STAT_dma_state;
+ return 1;
+}
+
+dt_ctrl( u_int cmd )
+{
+ while ( ! dt_waitbit( STAT_cmd_ready ) ) dt_delay( 100 );
+ outb_p( 0, iobase+2 );
+ outb_p( 0, iobase+3 );
+ dt_getstatus( );
+ dt_sendcmd( CMD_control|cmd );
+ outb_p( 0, iobase+6 );
+ dt_delay( 100 );
+ dt_sendcmd( CMD_null );
+ while ( ! dt_waitbit( STAT_cmd_ready ) ) dt_delay( 100 );
+}
+
+int dt_flush( void )
+{
+ dt_ctrl( CTRL_flush );
+ dt_waitbit( STAT_dma_ready );
+ outb_p( DMA_sync, iobase+4 );
+ outb_p( 0, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ while( dt_getstatus( ) & STAT_flushing ) dt_delay( 100 );
+ return 0;
+}
+
+static int dt_sendbuff( char *src, int len )
+{
+ while( len-- ){
+ if( ! dt_wait_dma( ) ) return -1;
+ if( ! (dt_getstatus( ) & STAT_rr_char) ) break;
+ outb_p( DMA_single_in, iobase+4 );
+ outb_p( *src++, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ }
+ return 0;
+}
+
+unsigned long dt_allocmem( unsigned long paras )
+{
+ unsigned long addr;
+ if( ! dt_wait_dma( ) ) return 0;
+ outb_p( DMA_control, iobase+4 );
+ outb_p( DT_MEM_ALLOC, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ if( ! dt_wait_dma( ) ) return 0;
+ outb_p( paras & 0xFF, iobase+4 );
+ outb_p( (paras>>8) & 0xFF, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ if( ! dt_wait_dma( ) ) return 0;
+ addr = inb_p( iobase+4 );
+ addr |= (inb_p( iobase+4 )<<8);
+ addr += (inb_p( iobase+4 )<<4);
+ addr += (inb_p( iobase+4 )<<12);
+ dma_state ^= STAT_dma_state;
+ return addr;
+}
+
+static int testkernel( void )
+{
+ dt_sendcmd( CMD_sync );
+ if( ! dt_waitbit( STAT_cmd_ready ) ) return -10;
+ has_kernel = ( dt_stat&0x8000 ) ? 1 : 0;
+ if ( verbose ) printf( "testkernel got %x\n", dt_stat );
+ if ( has_kernel ) return 0;
+ dt_delay( 100 );
+ return 1;
+}
+
+static int dt_loadmem( int addr, int len, char *src )
+{
+ char c;
+ int l;
+ if ( verbose ) printf( "dt_loadmem: addr = %08X size = %d\n", addr, len );
+ do {
+ l = len;
+ if ( l >= 0xc000 ) l = 0xc000;
+ len -= l;
+ if( ! dt_wait_dma( ) ) return -1;
+ outb_p( DMA_control, iobase+4 );
+ outb_p( DT_LOAD_MEM, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ if( ! dt_wait_dma( ) ) return -2;
+ outb_p( addr & 0xFF, iobase+4 );
+ outb_p( (addr>>8) & 0xFF, iobase+4 );
+ outb_p( (addr>>16) & 0xFF, iobase+4 );
+ outb_p( (addr>>24) & 0xFF, iobase+4 );
+ outb_p( l & 0xFF, iobase+4 );
+ outb_p( (l>>8) & 0xFF, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ if( ! dt_wait_dma( ) ) return -3;
+ addr += l;
+ while( l-- ){
+ c = *src++;
+ outb_p( c, iobase+4 );
+ }
+ dma_state ^= STAT_dma_state;
+ } while ( len > 0 );
+ return 0;
+}
+
+unsigned int loadfile ( char *filename )
+{
+ int i, header_size;
+ unsigned int total_paras;
+ long fix;
+ infd = open ( filename, O_RDONLY );
+ if ( infd == -1 ) {
+ perror ( "Opening file: " );
+ return 0;
+ }
+ read ( infd, &header, sizeof ( struct dos_exe_header ) );
+ if ( header.id != 0x5a4d ) {
+ fprintf ( stderr, "Invalid header file format\n" );
+ fprintf ( stderr, "Want 0x5a4d, got 0x%x\n", header.id );
+ return 0;
+ }
+ if ( header.relen > MAX_FIXUPS ) {
+ fprintf ( stderr, "Too many fixups\n" );
+ return 0;
+ }
+ lseek ( infd, ( long ) header.reloc, SEEK_SET );
+ read ( infd, fixups, sizeof ( struct dos_reloc ) * header.relen );
+ header_size = header.hsize * 16;
+ lseek ( infd, ( long )header_size, SEEK_SET );
+ image_len = ( ( header.pages-1 )*512 ) + ( header.rem- header_size );
+ total_paras = ( image_len >> 4 ) + header.hmin + 16;
+ read ( infd, read_buff, image_len );
+ close( infd );
+ return total_paras;
+}
+
+static int loadkernel( char *filename )
+{
+ int segfix = 0x40, fix, i;
+ int ipval, csval;
+ if ( has_kernel ) return 0;
+ if ( !loadfile( filename ) ) return -1;
+ header.csval += segfix;
+ header.ssval += segfix;
+ if ( verbose ) {
+ printf ( "Loading kernel of %ld bytes ( %d relocs )\n",
+ image_len, header.relen );
+ printf ( " cs:ip == %04x:%04x ss:sp == %04x:%04x\n",
+ header.csval, header.ipval, header.ssval, header.spval );
+ }
+ for ( i = 0; i < header.relen; i++ ) {
+ fix = ( fixups[i].segment << 4 ) + fixups[i].offset;
+ ( *( unsigned int * ) &read_buff[fix] ) += segfix;
+ }
+ csval = header.csval;
+ ipval = header.ipval;
+ dt_sendcmd_wait( MODULE_reset, MODULE_init );
+ dt_sendcmd( CMD_reset );
+ if( dt_getstatus( ) == MODULE_self_test ){
+ if( ! dt_waitmode( MODULE_init ) ) return -1;
+ }
+ if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -2;
+ if ( !dt_sendcmd_wait( CMD_sync, MODE_error ) ) return -3;
+ if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -4;
+ if ( verbose ) printf( "card is ready\n" );
+ dt_sendcmd( CMD_dma );
+ if( ! dt_waitbit( STAT_dma_ready ) ) return -5;
+ if( ( i = dt_loadmem( 0x00000400, image_len, read_buff ) ) ) {
+ fprintf( stderr, "kernel load failed, status %d\n", i );
+ return -6;
+ }
+ dt_delay( 100 );
+ /* the kernel is loaded, start it */
+ if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -7;
+ dt_sendcmd( CMD_dma+1 ); /**xxx**/
+ dt_delay( 100 );
+ if( ! dt_waitbit( STAT_dma_ready ) ) return-8;
+ outb_p( DMA_control, iobase+4 );
+ outb_p( DT_START_TASK, iobase+4 );
+ dt_delay( 100 );
+ outb_p( ipval & 0xFF, iobase+4 );
+ outb_p( (ipval>>8) & 0xFF, iobase+4 );
+ outb_p( csval & 0xFF, iobase+4 );
+ outb_p( (csval>>8) & 0xFF, iobase+4 );
+ if( ! dt_waitmode( 0xc001 ) ) return -9;
+ if ( verbose ) {
+ printf( "done loading kernel\n" );
+ }
+ return testkernel( );
+}
+
+int loaddict ( char *filename, char *name, int type )
+{
+ int i, read_index, read_size, act_size;
+ unsigned short *index_fix, seg_fix;
+ unsigned long entries, index, dic_bytes, dic_addr;
+ unsigned int total_paras;
+ unsigned long param, l;
+ infd = open ( filename, O_RDONLY );
+ if ( infd == -1 ) {
+ perror ( filename );
+ return -1;
+ }
+/* read in the entry count and the actual entry size excluding the
+ * index table ( which is entries * 4 ) ... */
+ read ( infd, &entries, 4 );
+ read ( infd, &dic_bytes, 4 );
+ if ( verbose )
+ printf ( "Loading %s dictionary of %lu entries, %lu bytes.\n",
+ name, entries, dic_bytes );
+ total_paras = ( ( ( entries * 4 ) + dic_bytes ) >> 4 ) + 2;
+ if ( verbose )
+ printf ( "Allocating %d paragraphs of free ram ...\n", total_paras );
+ l = dt_allocmem( total_paras );
+ if ( l == 0 ) {
+ perror ( "Error requesting memory from speech device" );
+ return -1;
+ }
+ seg_fix = ( l >> 4 ) & 0xffff;
+ dic_addr = l;
+ index = entries;
+ index_fix = ( unsigned short * ) &read_buff[0];
+ if ( verbose )
+ printf ( "Index table starts at %lx\n", l );
+ read_index = index*4;
+ act_size = read ( infd, read_buff, read_index );
+ if ( act_size != read_index ) {
+ fprintf ( stderr, "\nError reading indexes\n" );
+ fprintf ( stderr, " exp : %d act : %d\n", read_index * 4, act_size );
+ return -1;
+ }
+ for ( i = 1; i < index * 2; i += 2 )
+ index_fix[i] += seg_fix;
+ if( ( i = dt_loadmem( l, read_index, read_buff ) ) ) {
+ fprintf ( stderr, "\nError loading indexes at 0x%lX: i %d\n",
+ l, i );
+ return -1;
+ }
+ l += read_index;
+/* now, load up the dictionary bytes ... */
+ if ( verbose )
+ printf ( "Dictionary text starts at %lx\n", l );
+ read_size = dic_bytes;
+ if ( ( act_size = read ( infd, read_buff, read_size ) ) != read_size ) {
+ fprintf ( stderr, "\nError reading dictionary text!\n" );
+ fprintf ( stderr, "asked : %d actual : %d\n", act_size, read_size );
+ return -1;
+ }
+ if( ( i = dt_loadmem( l, read_size, read_buff ) ) ) {
+ fprintf ( stderr, "\nError loading dictionary at 0x%lX: status %d\n",
+ l, i );
+ return -1;
+ }
+ if( ! dt_wait_dma( ) ) return -1;
+ outb_p( DMA_control, iobase+4 );
+ outb_p( DT_SET_DIC, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ if( ! dt_wait_dma( ) ) return -1;
+ l = dic_addr;
+ l = ((l << 12) & 0xFFFF0000) + (l & 0x0000000F);
+ outb_p( l & 0xFF, iobase+4 );
+ outb_p( (l>>8) & 0xFF, iobase+4 );
+ outb_p( (l>>16) & 0xFF, iobase+4 );
+ outb_p( (l>>24) & 0xFF, iobase+4 );
+ l = entries;
+ outb_p( l & 0xFF, iobase+4 );
+ outb_p( (l>>8) & 0xFF, iobase+4 );
+ outb_p( (l>>16) & 0xFF, iobase+4 );
+ outb_p( (l>>24) & 0xFF, iobase+4 );
+ l = type;
+ outb_p( l & 0xFF, iobase+4 );
+ outb_p( (l>>8) & 0xFF, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ close ( infd );
+ if ( verbose ) printf( "dictionary load complete\n" );
+ return 0;
+}
+
+int loadexe ( char *filename )
+{
+ unsigned int load_addr = 0, seg_fix;
+ int i, read_size;
+ int ipval, csval;
+ long fix;
+ unsigned long total_paras;
+ total_paras = loadfile ( filename );
+ if ( total_paras == 0 ) return -1;
+ load_addr = dt_allocmem( total_paras );
+ if ( load_addr == 0 ) {
+ fprintf ( stderr, "Error allocating memory on card: " );
+ return -1;
+ }
+ seg_fix = ( load_addr >> 4 ) & 0xffff;
+ if ( verbose ) {
+ printf ( "Loading %s %ld bytes ( %d relocs )\n",
+ filename, image_len, header.relen );
+ printf ( "Allocating %ld bytes of free ram at %05x\n",
+ ( long ) header.hmin * 16, load_addr );
+ printf ( "Total memory taken is %ld bytes\n", ( long ) total_paras * 16 );
+ printf ( " cs:ip == %04x:%04x ss:sp == %04x:%04x\n",
+ header.csval + seg_fix, header.ipval, header.ssval + seg_fix, header.spval );
+ }
+ for ( i = 0; i < header.relen; i++ ) {
+ fix = ( ( long ) fixups[i].segment << 4 ) + ( long ) fixups[i].offset;
+ ( *( unsigned int * ) &read_buff[fix] ) += seg_fix;
+ }
+ if( ( i = dt_loadmem( load_addr, image_len, read_buff ) ) ) {
+ fprintf ( stderr, "Error loading speech device at 0x%lX: status %d\n",
+ load_addr, i );
+ return -1;
+ }
+ csval = header.csval + seg_fix;
+ ipval = header.ipval;
+ if( ! dt_wait_dma( ) ) return -1;
+ outb_p( DMA_control, iobase+4 );
+ outb_p( DT_START_TASK, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ if( ! dt_wait_dma( ) ) return -1;
+ outb_p( ipval & 0xFF, iobase+4 );
+ outb_p( (ipval>>8) & 0xFF, iobase+4 );
+ outb_p( csval & 0xFF, iobase+4 );
+ outb_p( (csval>>8) & 0xFF, iobase+4 );
+ dma_state ^= STAT_dma_state;
+ return 0;
+}
+
+void release_io( void )
+{
+ ioperm( (long)iobase, 8, 0 );
+ ioperm( (long)0x0080, 1, 0 );
+ if ( read_buff ) free( read_buff );
+}
+
+parseparm( char *parm, char *value )
+{
+ char *cp = parm+strlen( parm );
+ while ( --cp > parm ) if ( *cp > ' ' ) break;
+ cp[1] = '\0';
+ if ( !strcmp( parm, "io" ) ) {
+ long io = strtol( value, 0, 0 );
+ if ( io >= 0x100 && io <= 0x350 ) {
+ iobase = (u_short)io;
+ return;
+ }
+ fprintf( stderr, "invalid io value %s\n", value );
+ exit( 1 );
+ } else if ( !strcmp( parm,"verbose" ) ) {
+ verbose = atoi( value );
+ }
+}
+
+do_test( void )
+{
+ char buffer[512];
+ int len;
+ dma_state = dt_getstatus( ) & STAT_dma_state;
+ while ( fgets( buffer, 510, stdin ) ) {
+ len = strlen( buffer );
+ if ( len == 1 ) dt_flush( );
+ else {
+ if ( buffer[len-1] == '\n' ) buffer[len-1] = '\013';
+ dt_sendbuff( buffer, len );
+ }
+ }
+ *buffer = '\013';
+ dt_sendbuff( buffer, 1 );
+}
+
+int main ( int argc, char **argv )
+{
+ char name[80], *cp;
+ char *dirname = 0, *confname = "dec_pc.conf";
+ char *init_msg = "[:ra 360] dec pc initialized\011";
+ FILE *confile;
+ struct stat statbuf;
+ int maxsize = 0, status = 0;
+ while ( --argc > 0 ) {
+ argv++;
+ if ( !strcmp( *argv, "-v" ) ) verbose = 1;
+ else if ( !strcmp( *argv, "-t" ) ) intest = 1;
+ else dirname = *argv;
+ }
+ if ( !dirname ) dirname = "/usr/local/lib/dec_pc";
+ if ( chdir( dirname ) != 0 ) {
+ fprintf( stderr, "cannot chdir to %s\n", dirname );
+ exit( 1 );
+ }
+ if ( !( confile = fopen( confname, "r" ) ) ) {
+ fprintf( stderr, "could not open %s", confname );
+ exit( 1 );
+ }
+ while ( fgets( name, 80, confile ) ) {
+ cp = strchr( name, '\n' );
+ if ( cp ) *cp = '\0';
+ if ( ( cp = strchr( name, '=' ) ) ) {
+ *cp++ = '\0';
+ parseparm( name, cp );
+ continue;
+ }
+ if ( stat( name, &statbuf ) != 0 ) {
+ fprintf( stderr, "cannot stat %s\n", name );
+ exit( 1 );
+ }
+ if ( statbuf.st_size > maxsize ) maxsize = statbuf.st_size;
+ }
+ rewind( confile );
+ if ( ioperm( (long)0x0080, 1, 1 ) || ioperm( (long)iobase, 8, 1 ) ) {
+ fprintf( stderr, "could not get ioperm\n" );
+ exit( 1 );
+ }
+ atexit( release_io );
+ if ( testkernel( ) == 0 ) {
+ if ( intest ) do_test( );
+ else fprintf( stderr, "kernel already loaded\n" );
+ exit( 0 );
+ }
+ read_buff = malloc( maxsize );
+ if ( !read_buff ) {
+ fprintf( stderr, "cannot malloc %d bytes\n", maxsize );
+ exit( 1 );
+ }
+ while ( fgets( name, 80, confile ) && !status ) {
+ cp = strchr( name, '\n' );
+ if ( cp ) *cp = '\0';
+ if ( strchr( name, '=' ) ) continue; /* a parameter */
+ if ( !( cp = strchr( name, '.' ) ) ) continue;
+ cp++;
+ if ( !strcmp ( cp, "dic" ) ) {
+ status = loaddict ( name, "primary", PRIMARY_DIC );
+ } else if ( !strcmp ( cp, "dtu" ) ) {
+ status = loaddict ( name, "user", USER_DIC );
+ } else if ( !strcmp ( cp, "dta" ) ) {
+ status = loaddict ( name, "abbreviation file", ABBREV_DIC );
+ } else if ( !strcmp ( cp, "exe" ) ) {
+ status = loadexe ( name );
+ } else if ( !strcmp ( cp, "sys" ) ) {
+ status = loadkernel ( name );
+ }
+ }
+ if ( status ) fprintf( stderr, "status %d\n", status );
+ fclose( confile );
+ if ( status ) exit( status );
+ dt_sendbuff( init_msg, strlen( init_msg ) );
+ sleep( 1 );
+ if ( intest ) do_test( );
+ exit( 0 );
+}
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/dtload.h linux-2.4.30/drivers/char/speakup/dtload.h
--- linux-2.4.30.orig/drivers/char/speakup/dtload.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/dtload.h 2003-07-31 08:27:06.000000000 -0700
@@ -0,0 +1,57 @@
+/*
+ * This is the DECtalk PC firmware loader for the Linux kernel, version 1.0
+ *
+ * Original 386BSD source:
+ * Copyright (c) 1996 Brian Buhrow
+ *
+ * Adapted for Linux:
+ * Copyright (c) 1997 Nicolas Pitre
+ *
+ * Adapted for speakup:
+ * Copyright (c) 2003 David Borowski
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define MAX_FIXUPS 512 /* maximum fixups per exe */
+/*
+ * msdos .exe files will look like ...
+ */
+
+struct dos_exe_header {
+ unsigned short id; /* Linker's signature, must be 0x5a4d */
+ unsigned short rem; /* length of image mod 512 */
+ unsigned short pages; /* length of image in pages of 512 bytes */
+ unsigned short relen; /* number of relocation items */
+ unsigned short hsize; /* header size in paragraphs of 16 bytes */
+ unsigned short hmin; /* min # of paragraphs above prog end */
+ unsigned short hmax;
+ unsigned short ssval;
+ unsigned short spval; /* to be loaded in sp */
+ unsigned short checksum;
+ unsigned short ipval; /* to be loaded in ip */
+ unsigned short csval; /* segment offset to code */
+ unsigned short reloc; /* location of relocation items */
+ unsigned short ovrlay; /* overlay number */
+};
+
+/* a dos relocation element looks like */
+
+struct dos_reloc {
+ short int offset, segment;
+};
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/dtpc_reg.h linux-2.4.30/drivers/char/speakup/dtpc_reg.h
--- linux-2.4.30.orig/drivers/char/speakup/dtpc_reg.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/dtpc_reg.h 2003-07-31 08:27:06.000000000 -0700
@@ -0,0 +1,132 @@
+/*
+ * This is the DECtalk PC register constants (from DEC's DOS driver)
+ *
+ * Original code:
+ * Copyright (c) by Digital Equipment Corp.
+ *
+ * 386BSD DECtalk PC driver:
+ * Copyright (c) 1996 Brian Buhrow
+ *
+ * Linux DECtalk PC driver:
+ * Copyright (c) 1997 Nicolas Pitre
+ *
+ * speakup DECtalk PC driver:
+ * Copyright (c) 2003 David Borowski
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * port interface defs ... used by dtpc.c
+ */
+
+#define MODULE_init 0x0dec /* module in boot code */
+#define MODULE_self_test 0x8800 /* module in self-test */
+#define MODULE_reset 0xffff /* reinit the whole module */
+
+#define MODE_mask 0xf000 /* mode bits in high nibble */
+#define MODE_null 0x0000
+#define MODE_test 0x2000 /* in testing mode */
+#define MODE_status 0x8000
+#define STAT_int 0x0001 /* running in interrupt mode */
+#define STAT_tr_char 0x0002 /* character data to transmit */
+#define STAT_rr_char 0x0004 /* ready to receive char data */
+#define STAT_cmd_ready 0x0008 /* ready to accept commands */
+#define STAT_dma_ready 0x0010 /* dma command ready */
+#define STAT_digitized 0x0020 /* spc in digitized mode */
+#define STAT_new_index 0x0040 /* new last index ready */
+#define STAT_new_status 0x0080 /* new status posted */
+#define STAT_dma_state 0x0100 /* dma state toggle */
+#define STAT_index_valid 0x0200 /* indexs are valid */
+#define STAT_flushing 0x0400 /* flush in progress */
+#define STAT_self_test 0x0800 /* module in self test */
+#define MODE_ready 0xc000 /* module ready for next phase */
+#define READY_boot 0x0000
+#define READY_kernel 0x0001
+#define MODE_error 0xf000
+
+#define CMD_mask 0xf000 /* mask for command nibble */
+#define CMD_null 0x0000 /* post status */
+#define CMD_control 0x1000 /* hard control command */
+#define CTRL_mask 0x0F00 /* mask off control nibble */
+#define CTRL_data 0x00FF /* madk to get data byte */
+#define CTRL_null 0x0000 /* null control */
+#define CTRL_vol_up 0x0100 /* increase volume */
+#define CTRL_vol_down 0x0200 /* decrease volume */
+#define CTRL_vol_set 0x0300 /* set volume */
+#define CTRL_pause 0x0400 /* pause spc */
+#define CTRL_resume 0x0500 /* resume spc clock */
+#define CTRL_resume_spc 0x0001 /* resume spc soft pause */
+#define CTRL_flush 0x0600 /* flush all buffers */
+#define CTRL_int_enable 0x0700 /* enable status change ints */
+#define CTRL_buff_free 0x0800 /* buffer remain count */
+#define CTRL_buff_used 0x0900 /* buffer in use */
+#define CTRL_speech 0x0a00 /* immediate speech change */
+#define CTRL_SP_voice 0x0001 /* voice change */
+#define CTRL_SP_rate 0x0002 /* rate change */
+#define CTRL_SP_comma 0x0003 /* comma pause change */
+#define CTRL_SP_period 0x0004 /* period pause change */
+#define CTRL_SP_rate_delta 0x0005 /* delta rate change */
+#define CTRL_SP_get_param 0x0006 /* return the desired parameter */
+#define CTRL_last_index 0x0b00 /* get last index spoken */
+#define CTRL_io_priority 0x0c00 /* change i/o priority */
+#define CTRL_free_mem 0x0d00 /* get free paragraphs on module */
+#define CTRL_get_lang 0x0e00 /* return bit mask of loaded languages */
+#define CMD_test 0x2000 /* self-test request */
+#define TEST_mask 0x0F00 /* isolate test field */
+#define TEST_null 0x0000 /* no test requested */
+#define TEST_isa_int 0x0100 /* assert isa irq */
+#define TEST_echo 0x0200 /* make data in == data out */
+#define TEST_seg 0x0300 /* set peek/poke segment */
+#define TEST_off 0x0400 /* set peek/poke offset */
+#define TEST_peek 0x0500 /* data out == *peek */
+#define TEST_poke 0x0600 /* *peek == data in */
+#define TEST_sub_code 0x00FF /* user defined test sub codes */
+#define CMD_id 0x3000 /* return software id */
+#define ID_null 0x0000 /* null id */
+#define ID_kernel 0x0100 /* kernel code executing */
+#define ID_boot 0x0200 /* boot code executing */
+#define CMD_dma 0x4000 /* force a dma start */
+#define CMD_reset 0x5000 /* reset module status */
+#define CMD_sync 0x6000 /* kernel sync command */
+#define CMD_char_in 0x7000 /* single character send */
+#define CMD_char_out 0x8000 /* single character get */
+#define CHAR_count_1 0x0100 /* one char in cmd_low */
+#define CHAR_count_2 0x0200 /* the second in data_low */
+#define CHAR_count_3 0x0300 /* the third in data_high */
+#define CMD_spc_mode 0x9000 /* change spc mode */
+#define CMD_spc_to_text 0x0100 /* set to text mode */
+#define CMD_spc_to_digit 0x0200 /* set to digital mode */
+#define CMD_spc_rate 0x0400 /* change spc data rate */
+#define CMD_error 0xf000 /* severe error */
+
+enum { PRIMARY_DIC = 0, USER_DIC, COMMAND_DIC, ABBREV_DIC };
+
+#define DMA_single_in 0x01
+#define DMA_single_out 0x02
+#define DMA_buff_in 0x03
+#define DMA_buff_out 0x04
+#define DMA_control 0x05
+#define DT_MEM_ALLOC 0x03
+#define DT_SET_DIC 0x04
+#define DT_START_TASK 0x05
+#define DT_LOAD_MEM 0x06
+#define DT_READ_MEM 0x07
+#define DT_DIGITAL_IN 0x08
+#define DMA_sync 0x06
+#define DMA_sync_char 0x07
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/genmap.c linux-2.4.30/drivers/char/speakup/genmap.c
--- linux-2.4.30.orig/drivers/char/speakup/genmap.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/genmap.c 2003-07-21 05:26:38.000000000 -0700
@@ -0,0 +1,204 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+int get_define(void);
+
+#define MAXKEYS 512
+#define MAXKEYVAL 160
+#define HASHSIZE 101
+#define is_shift -3
+#define is_spk -2
+#define is_input -1
+typedef struct st_key_init t_key_init;
+struct st_key_init {
+ char *name;
+ int value, shift;
+};
+typedef struct st_key t_key;
+struct st_key {
+ char *name;
+ t_key *next;
+ int value, shift;
+};
+unsigned char key_data[MAXKEYVAL][16], *kp;
+
+#include "mapdata.h"
+t_key key_table[MAXKEYS];
+t_key *extra_keys = key_table+HASHSIZE;
+char buffer[256], filename[256];
+FILE *infile;
+char delims[] = "\t\n ";
+char *def_name, *def_val, *cp;
+int map_ver = 119; /* an arbitrary number so speakup can check */
+int lc, shift_table[17];
+int max_states = 1, flags = 0;
+/* flags reserved for later, maybe for individual console maps */
+
+void open_input( char *name )
+{
+ strcpy( filename, name );
+ if ( ( infile = fopen( filename, "r" ) ) == 0 ) {
+ fprintf( stderr, "can't open %s, version %d\n", filename, LINUX_VERSION_CODE );
+ exit( 1 );
+ }
+ lc = 0;
+}
+
+int
+oops( char *msg, char *info )
+{
+ if ( info == NULL ) info = " ";
+ fprintf( stderr, "error: file %s line %d\n", filename, lc );
+ fprintf( stderr, "%s %s\n", msg, info );
+ exit( 1 );
+}
+
+t_key *hash_name( char *name )
+{
+ u_char *pn = (u_char *)name;
+ int hash = 0;
+ while ( *pn ) {
+ hash = ( hash * 17 ) & 0xfffffff;
+ if ( isupper( *pn ) ) *pn = tolower( *pn );
+ hash += ( int )*pn;
+ pn++;
+ }
+ hash %= HASHSIZE;
+ return &key_table[hash];
+}
+
+t_key *find_key( char *name )
+{
+ t_key *this = hash_name( name );
+ while ( this ) {
+ if ( !strcmp( name, this->name ) ) return this;
+ this = this->next;
+ }
+ return this;
+}
+
+t_key *add_key( char *name, int value, int shift )
+{
+ t_key *this = hash_name( name );
+ if ( extra_keys-key_table >= MAXKEYS )
+ oops( "out of key table space, enlarge MAXKEYS", NULL );
+ if ( this->name != NULL ) {
+ while ( this->next ) {
+ if ( !strcmp( name, this->name ) )
+ oops( "attempt to add duplicate key", name );
+ this = this->next;
+ }
+ this->next = extra_keys++;
+ this = this->next;
+ }
+ this->name = strdup( name );
+ this->value = value;
+ this->shift = shift;
+ return this;
+}
+
+int get_shift_value( int state )
+{
+ int i;
+ for ( i = 0; shift_table[i] != state; i++ ) {
+ if ( shift_table[i] == -1 ) {
+ if ( i >= 16 )
+ oops( "too many shift states", NULL );
+ shift_table[i] = state;
+ max_states = i+1;
+ break;
+ }
+ }
+ return i;
+}
+
+int
+main( int argc, char *argv[] )
+{
+ int value, shift_state, i, spk_val = 0, lock_val = 0;
+ int max_key_used = 0, num_keys_used = 0;
+ t_key *this;
+ t_key_init *p_init;
+char *argpath, *argname, *argcopy;
+
+ bzero( key_table, sizeof( key_table ) );
+ bzero( key_data, sizeof( key_data ) );
+ shift_table[0] = 0;
+ for ( i = 1; i <= 16; i++ ) shift_table[i] = -1;
+ if ( argc < 2 ) {
+ fputs( "usage: genmap filename\n", stderr );
+ exit( 1 );
+ }
+ for ( p_init = init_key_data; p_init->name[0] != '.'; p_init++ )
+ add_key( p_init->name, p_init->value, p_init->shift );
+ open_input( argv[1] );
+ while ( fgets( buffer, 250, infile ) ) {
+ lc++;
+ value = shift_state = 0;
+ cp = strtok( buffer, delims );
+ if ( *cp == '#' ) continue;
+ while ( cp ) {
+ if ( *cp == '=' ) break;
+ this = find_key( cp );
+ if ( this == NULL )
+ oops( "unknown key/modifier", cp );
+ if ( this->shift == is_shift ) {
+ if ( value )
+ oops( "modifiers must come first", cp );
+ shift_state += this->value;
+ } else if ( this->shift == is_input )
+ value = this->value;
+ else oops( "bad modifier or key", cp );
+ cp = strtok( 0, delims );
+ }
+ if ( !cp ) oops( "no = found", NULL );
+ cp = strtok( 0, delims );
+ if ( !cp ) oops( "no speakup function after =", NULL );
+ this = find_key( cp );
+ if ( this == NULL || this->shift != is_spk )
+ oops( "invalid speakup function", cp );
+ i = get_shift_value( shift_state );
+ if ( key_data[value][i] ) {
+ while ( --cp > buffer )
+ if ( !*cp ) *cp = ' ';
+ oops( "two functions on same key combination", cp );
+ }
+ key_data[value][i] = (char)this->value;
+ if ( value > max_key_used ) max_key_used = value;
+ }
+ fclose( infile );
+ this = find_key( "spk_key" );
+ if ( this ) spk_val = this->value;
+ this = find_key( "spk_lock" );
+ if ( this ) lock_val = this->value;
+ for ( lc = 1; lc <= max_key_used; lc++ ) {
+ kp = key_data[lc];
+ if ( !memcmp( key_data[0], kp, 16 ) ) continue;
+ num_keys_used++;
+ for ( i = 0; i < max_states; i++ ) {
+ if ( kp[i] != spk_val&& kp[i] != lock_val ) continue;
+ shift_state = shift_table[i];
+ if ( ( shift_state&16 ) ) continue;
+ shift_state = get_shift_value( shift_state+16 );
+ kp[shift_state] = kp[i];
+/* fill in so we can process the key up, as spk bit will be set */
+ }
+ }
+ printf( "\t%d, %d, %d,\n\t", map_ver, num_keys_used, max_states );
+ for ( i = 0; i < max_states; i++ )
+ printf( "%d, ", shift_table[i] );
+ printf( "%d,", flags );
+ for ( lc = 1; lc <= max_key_used; lc++ ) {
+ kp = key_data[lc];
+ if ( !memcmp( key_data[0], kp, 16 ) ) continue;
+ printf( "\n\t%d,", lc );
+ for ( i = 0; i < max_states; i++ )
+ printf( " %d,", (unsigned int)kp[i] );
+ }
+ printf( "\n\t0, %d\n", map_ver );
+ exit( 0 );
+}
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/install linux-2.4.30/drivers/char/speakup/install
--- linux-2.4.30.orig/drivers/char/speakup/install 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/install 2005-04-19 09:26:21.000000000 -0700
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+VERSION=v`head -2 /usr/src/linux/Makefile | \
+ awk '{ printf "%s",$3 }'`
+
+DIR=/usr/src/linux/drivers/char/speakup
+
+echo "Patching version $VERSION"
+
+if [ "$1" != "--debug" ]; then
+ SILENT=--silent
+fi
+
+cp -R speakup /usr/src/linux/drivers/char/
+cd /usr/src/linux
+
+# make .orig files
+echo -n 'Creating .orig files ['
+for i in `cat ${DIR}/patchlist-${VERSION}`; do
+ patch=`echo $i | cut -f 1 -d ,`
+ filebase=`echo $i | cut -f 2 -d ,`
+
+ mkdir -p `dirname $filebase`
+ if [ "$patch" == "1" ]; then
+ if [ ! -e $filebase.orig ]; then
+ echo -n .
+ cp $filebase $filebase.orig
+ fi
+ fi
+done
+echo '] done.'
+
+# apply patches
+echo -n 'Patching files ['
+for i in ${DIR}/diff-${VERSION}/*.patch; do
+ # skip dirs
+ [ -d $i ] && continue
+ echo -n p
+ writeloc=${i##$DIR\/diff-${VERSION}\/}
+ writeloc=${writeloc%.patch}
+ writeloc=${writeloc//^/\/}
+ patch $SILENT -f -p0 -o $writeloc $writeloc.orig $i
+done
+echo '] done.'
+
+# copy files
+echo -n 'Copying files ['
+for i in ${DIR}/diff-${VERSION}/*.copy; do
+ # skip dirs
+ [ -d $i ] && continue
+ echo -n c
+ writeloc=${i##$DIR\/diff-${VERSION}\/}
+ writeloc=${writeloc%.copy}
+ writeloc=${writeloc//^/\/}
+ cp $i $writeloc
+done
+echo '] done.'
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/keyinfo.h linux-2.4.30/drivers/char/speakup/keyinfo.h
--- linux-2.4.30.orig/drivers/char/speakup/keyinfo.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/keyinfo.h 2003-11-12 12:41:34.000000000 -0800
@@ -0,0 +1,119 @@
+/* spk_priv.h
+ review functions for the speakup screen review package.
+ originally written by: Kirk Reiser and Andy Berdan.
+
+ extensively modified by David Borowski.
+
+ Copyright (C ) 1998 Kirk Reiser.
+ Copyright (C ) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+enum { /* var_ids */
+ VERSION = 0, SYNTH, SILENT, SYNTH_DIRECT,
+ KEYMAP, CHARS,
+ PUNC_SOME, PUNC_MOST, PUNC_ALL,
+ DELIM, REPEATS, EXNUMBER,
+ DELAY, TRIGGER, JIFFY, FULL, /* all timers must be together */
+ BLEEP_TIME, CURSOR_TIME, BELL_POS,
+SAY_CONTROL, SAY_WORD_CTL, NO_INTERRUPT, KEY_ECHO,
+ SPELL_DELAY, PUNC_LEVEL, READING_PUNC,
+ ATTRIB_BLEEP, BLEEPS,
+ RATE, PITCH, VOL, TONE, PUNCT, VOICE, FREQ, LANG,
+ CAPS_START, CAPS_STOP,
+ MAXVARS
+};
+
+#define FIRST_SYNTH_VAR RATE
+/* 0 is reserved for no remap */
+#define SPEAKUP_GOTO 0x01
+#define SPEECH_KILL 0x02
+#define SPEAKUP_QUIET 0x03
+#define SPEAKUP_CUT 0x04
+#define SPEAKUP_PASTE 0x05
+#define SAY_FIRST_CHAR 0x06
+#define SAY_LAST_CHAR 0x07
+#define SAY_CHAR 0x08
+#define SAY_PREV_CHAR 0x09
+#define SAY_NEXT_CHAR 0x0a
+#define SAY_WORD 0x0b
+#define SAY_PREV_WORD 0x0c
+#define SAY_NEXT_WORD 0x0d
+#define SAY_LINE 0x0e
+#define SAY_PREV_LINE 0x0f
+#define SAY_NEXT_LINE 0x10
+#define TOP_EDGE 0x11
+#define BOTTOM_EDGE 0x12
+#define LEFT_EDGE 0x13
+#define RIGHT_EDGE 0x14
+#define SPELL_PHONETIC 0x15
+#define SPELL_WORD 0x16
+#define SAY_SCREEN 0x17
+#define SAY_POSITION 0x18
+#define SAY_ATTRIBUTES 0x19
+#define SPEAKUP_OFF 0x1a
+#define SPEAKUP_PARKED 0x1b
+#define SAY_LINE_INDENT 0x1c
+#define SAY_FROM_TOP 0x1d
+#define SAY_TO_BOTTOM 0x1e
+#define SAY_FROM_LEFT 0x1f
+#define SAY_TO_RIGHT 0x20
+#define SAY_CHAR_NUM 0x21
+#define EDIT_SOME 0x22
+#define EDIT_MOST 0x23
+#define SAY_PHONETIC_CHAR 0x24
+#define EDIT_DELIM 0x25
+#define EDIT_REPEAT 0x26
+#define EDIT_EXNUM 0x27
+#define SET_WIN 0x28
+#define CLEAR_WIN 0x29
+#define ENABLE_WIN 0x2a
+#define SAY_WIN 0x2b
+#define SPK_LOCK 0x2c
+#define SPEAKUP_HELP 0x2d
+#define TOGGLE_CURSORING 0x2e
+#define SPKUP_MAX_FUNC 0x2f /* one greater than the last func handler */
+
+#define SPK_KEY 0x80
+#define FIRST_EDIT_BITS 0x22
+
+#define FIRST_SET_VAR SPELL_DELAY
+#define VAR_START 0x40 /* increase if adding more than 0x3f functions */
+
+/* keys for setting variables, must be ordered same as the enum for var_ids */
+/* with dec being even and inc being 1 greater */
+#define SPELL_DELAY_DEC VAR_START+0
+#define SPELL_DELAY_INC SPELL_DELAY_DEC+1
+#define PUNC_LEVEL_DEC SPELL_DELAY_DEC+2
+#define PUNC_LEVEL_INC PUNC_LEVEL_DEC+1
+#define READING_PUNC_DEC PUNC_LEVEL_DEC+2
+#define READING_PUNC_INC READING_PUNC_DEC+1
+#define ATTRIB_BLEEP_DEC READING_PUNC_DEC+2
+#define ATTRIB_BLEEP_INC ATTRIB_BLEEP_DEC+1
+#define BLEEPS_DEC ATTRIB_BLEEP_DEC+2
+#define BLEEPS_INC BLEEPS_DEC+1
+#define RATE_DEC BLEEPS_DEC+2
+#define RATE_INC RATE_DEC+1
+#define PITCH_DEC RATE_DEC+2
+#define PITCH_INC PITCH_DEC+1
+#define VOL_DEC PITCH_DEC+2
+#define VOL_INC VOL_DEC+1
+#define TONE_DEC VOL_DEC+2
+#define TONE_INC TONE_DEC+1
+#define PUNCT_DEC TONE_DEC+2
+#define PUNCT_INC PUNCT_DEC+1
+#define VOICE_DEC PUNCT_DEC+2
+#define VOICE_INC VOICE_DEC+1
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/makemapdata.c linux-2.4.30/drivers/char/speakup/makemapdata.c
--- linux-2.4.30.orig/drivers/char/speakup/makemapdata.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/makemapdata.c 2003-07-18 07:08:34.000000000 -0700
@@ -0,0 +1,156 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+int get_define(void);
+
+#define MAXKEYS 512
+#define MAXKEYVAL 160
+#define HASHSIZE 101
+#define is_shift -3
+#define is_spk -2
+#define is_input -1
+typedef struct st_key t_key;
+struct st_key {
+ char *name;
+ t_key *next;
+ int value, shift;
+};
+
+t_key key_table[MAXKEYS];
+t_key *extra_keys = key_table+HASHSIZE;
+char buffer[256], filename[256];
+FILE *infile;
+char delims[] = "\t\n ";
+char *dir_name, *def_name, *def_val, *cp;
+int lc;
+
+void open_input( char *name )
+{
+ sprintf( filename, "%s/%s", dir_name, name );
+ if ( ( infile = fopen( filename, "r" ) ) == 0 ) {
+ fprintf( stderr, "can't open %s\n", filename );
+ exit( 1 );
+ }
+ lc = 0;
+}
+
+int
+oops( char *msg, char *info )
+{
+ if ( info == NULL ) info = " ";
+ fprintf( stderr, "error: file %s line %d\n", filename, lc );
+ fprintf( stderr, "%s %s\n", msg, info );
+ exit( 1 );
+}
+
+int get_define( )
+{
+ while ( fgets( buffer, 250, infile ) ) {
+ lc++;
+ if ( strncmp( buffer, "#define", 7 ) ) continue;
+ strtok( buffer, delims );
+ def_name = strtok( 0, delims );
+ def_val = strtok( 0, delims );
+ if ( def_val != NULL ) return 1;
+ }
+ fclose( infile );
+ infile = 0;
+ return 0;
+}
+
+t_key *hash_name( char *name )
+{
+ u_char *pn = (u_char *)name;
+ int hash = 0;
+ while ( *pn ) {
+ hash = ( hash * 17 ) & 0xfffffff;
+ if ( isupper( *pn ) ) *pn = tolower( *pn );
+ hash += ( int )*pn;
+ pn++;
+ }
+ hash %= HASHSIZE;
+ return &key_table[hash];
+}
+
+t_key *find_key( char *name )
+{
+ t_key *this = hash_name( name );
+ while ( this ) {
+ if ( !strcmp( name, this->name ) ) return this;
+ this = this->next;
+ }
+ return this;
+}
+
+t_key *add_key( char *name, int value, int shift )
+{
+ t_key *this = hash_name( name );
+ if ( extra_keys-key_table >= MAXKEYS )
+ oops( "out of key table space, enlarge MAXKEYS", NULL );
+ if ( this->name != NULL ) {
+ while ( this->next ) {
+ if ( !strcmp( name, this->name ) )
+ oops( "attempt to add duplicate key", name );
+ this = this->next;
+ }
+ this->next = extra_keys++;
+ this = this->next;
+ }
+ this->name = strdup( name );
+ this->value = value;
+ this->shift = shift;
+ return this;
+}
+
+int
+main( int argc, char *argv[] )
+{
+ int value, i;
+ t_key *this;
+ dir_name = getenv( "TOPDIR" );
+ if ( !dir_name ) dir_name = "/usr/src/linux";
+ bzero( key_table, sizeof( key_table ) );
+ add_key( "shift", 1, is_shift );
+ add_key( "altgr", 2, is_shift );
+ add_key( "ctrl", 4, is_shift );
+ add_key( "alt", 8, is_shift );
+ add_key( "spk", 16, is_shift );
+ add_key( "double", 32, is_shift );
+ open_input( "include/linux/input.h" );
+ while ( get_define( ) ) {
+ if ( strncmp( def_name, "KEY_", 4 ) ) continue;
+ value = atoi( def_val );
+ if ( value > 0 && value < MAXKEYVAL )
+ add_key( def_name, value, is_input );
+ }
+ open_input( "drivers/char/speakup/keyinfo.h" );
+ while ( get_define( ) ) {
+ if ( strlen( def_val ) > 5 ) {
+ if ( !( cp = strchr( def_val, '+' ) ) ) continue;
+ *cp++ = '\0';
+ this = find_key( def_val );
+ if ( !this || *cp < '0' || *cp > '9' ) continue;
+ value = this->value+atoi( cp );
+ } else if ( !strncmp( def_val, "0x", 2 ) )
+ sscanf( def_val+2, "%x", &value );
+ else if ( *def_val >= '0' && *def_val <= '9' )
+ value = atoi( def_val );
+ else continue;
+ add_key( def_name, value, is_spk );
+ }
+ printf( "t_key_init init_key_data[] = {\n" );
+ for ( i = 0; i < HASHSIZE; i++ ) {
+ this = &key_table[i];
+ if ( !this->name ) continue;
+ do {
+ printf( "\t\"%s\", %d, %d,\n", this->name, this->value, this->shift );
+ this = this->next;
+ } while ( this );
+ }
+ printf( "\t\".\", 0, 0\n};\n" );
+ exit( 0 );
+}
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/mod_code.c linux-2.4.30/drivers/char/speakup/mod_code.c
--- linux-2.4.30.orig/drivers/char/speakup/mod_code.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/mod_code.c 2003-12-22 13:22:11.000000000 -0800
@@ -0,0 +1,25 @@
+/* this code is to modularize a synth specific file, included at the end */
+
+static void __exit mod_synth_exit( void )
+{
+ if ( synth == &MY_SYNTH )
+ synth_release( );
+ synth_remove( &MY_SYNTH );
+}
+
+static int __init mod_synth_init( void )
+{
+ int status = do_synth_init( &MY_SYNTH );
+ if ( status != 0 ) return status;
+ synth_add( &MY_SYNTH );
+#if (LINUX_VERSION_CODE < 132419)
+// MOD_INC_USE_COUNT;
+#endif
+ return 0;
+}
+
+module_init( mod_synth_init );
+module_exit( mod_synth_exit );
+MODULE_AUTHOR("Kirk Reiser ");
+MODULE_DESCRIPTION("Synthesizer driver module for speakup for the synth->long_name");
+MODULE_LICENSE( "GPL" );
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/patchlist-v22 linux-2.4.30/drivers/char/speakup/patchlist-v22
--- linux-2.4.30.orig/drivers/char/speakup/patchlist-v22 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/patchlist-v22 2001-10-14 11:42:46.000000000 -0700
@@ -0,0 +1,24 @@
+1,/usr/src/linux/Documentation/Configure.help
+1,/usr/src/linux/MAINTAINERS
+1,/usr/src/linux/arch/arm/config.in
+1,/usr/src/linux/arch/i386/config.in
+1,/usr/src/linux/arch/m68k/config.in
+1,/usr/src/linux/arch/mips/config.in
+1,/usr/src/linux/arch/ppc/config.in
+1,/usr/src/linux/arch/sparc/config.in
+1,/usr/src/linux/arch/sparc64/config.in
+1,/usr/src/linux/drivers/char/Makefile
+1,/usr/src/linux/drivers/char/console.c
+1,/usr/src/linux/drivers/char/keyboard.c
+1,/usr/src/linux/drivers/char/selection.c
+1,/usr/src/linux/fs/proc/root.c
+1,/usr/src/linux/include/linux/keyboard.h
+1,/usr/src/linux/include/linux/miscdevice.h
+1,/usr/src/linux/include/linux/proc_fs.h
+1,/usr/src/linux/init/main.c
+1,/usr/src/linux/scripts/lxdialog/checklist.c
+0,/usr/src/linux/Documentation/speakup/INSTALLATION
+0,/usr/src/linux/Documentation/speakup/README
+0,/usr/src/linux/Documentation/speakup/keymap-tutorial
+0,/usr/src/linux/include/linux/speakup.h
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/patchlist-v24 linux-2.4.30/drivers/char/speakup/patchlist-v24
--- linux-2.4.30.orig/drivers/char/speakup/patchlist-v24 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/patchlist-v24 2005-04-07 12:57:31.000000000 -0700
@@ -0,0 +1,26 @@
+1,Documentation/Configure.help
+1,MAINTAINERS
+1,arch/alpha/config.in
+1,arch/arm/config.in
+1,arch/i386/config.in
+1,arch/m68k/config.in
+1,arch/mips/config-shared.in
+1,arch/ppc/config.in
+1,arch/sparc/config.in
+1,arch/sparc64/config.in
+1,drivers/char/Makefile
+1,drivers/char/console.c
+1,drivers/char/consolemap.c
+1,drivers/char/keyboard.c
+1,drivers/char/vt.c
+1,fs/proc/root.c
+1,include/linux/keyboard.h
+1,include/linux/proc_fs.h
+0,Documentation/speakup/DefaultKeyAssignments
+0,Documentation/speakup/INSTALLATION
+0,Documentation/speakup/README
+0,Documentation/speakup/keymap-tutorial
+0,Documentation/speakup/spkguide.txt
+0,drivers/char/speakup/speakup.c
+0,include/linux/speakup.h
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/patchlist-v25 linux-2.4.30/drivers/char/speakup/patchlist-v25
--- linux-2.4.30.orig/drivers/char/speakup/patchlist-v25 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/patchlist-v25 2003-05-22 14:21:33.000000000 -0700
@@ -0,0 +1,23 @@
+1,MAINTAINERS
+1,arch/alpha/Kconfig
+1,arch/arm/Kconfig
+1,arch/i386/Kconfig
+1,arch/m68k/Kconfig
+1,arch/mips/Kconfig
+1,arch/ppc/Kconfig
+1,arch/sparc/Kconfig
+1,arch/sparc64/Kconfig
+1,drivers/char/Makefile
+1,drivers/char/keyboard.c
+1,drivers/char/selection.c
+1,drivers/char/vt.c
+1,fs/proc/root.c
+1,include/linux/keyboard.h
+1,include/linux/miscdevice.h
+1,include/linux/proc_fs.h
+0,Documentation/speakup/DefaultKeyAssignments
+0,Documentation/speakup/INSTALLATION
+0,Documentation/speakup/README
+0,Documentation/speakup/keymap-tutorial
+0,include/linux/speakup.h
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/patchlist-v26 linux-2.4.30/drivers/char/speakup/patchlist-v26
--- linux-2.4.30.orig/drivers/char/speakup/patchlist-v26 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/patchlist-v26 2005-04-07 12:57:31.000000000 -0700
@@ -0,0 +1,22 @@
+1,MAINTAINERS
+1,arch/arm/Kconfig
+1,arch/mips/Kconfig
+1,arch/sparc/Kconfig
+1,arch/sparc64/Kconfig
+1,drivers/Kconfig
+1,drivers/Makefile
+1,drivers/char/Makefile
+1,drivers/char/consolemap.c
+1,drivers/char/keyboard.c
+1,drivers/char/vt.c
+1,fs/proc/root.c
+1,include/linux/keyboard.h
+1,include/linux/miscdevice.h
+1,include/linux/proc_fs.h
+0,Documentation/speakup/DefaultKeyAssignments
+0,Documentation/speakup/INSTALLATION
+0,Documentation/speakup/README
+0,Documentation/speakup/keymap-tutorial
+0,Documentation/speakup/spkguide.txt
+0,include/linux/speakup.h
+
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/serialio.h linux-2.4.30/drivers/char/speakup/serialio.h
--- linux-2.4.30.orig/drivers/char/speakup/serialio.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/serialio.h 2003-05-05 06:56:33.000000000 -0700
@@ -0,0 +1,18 @@
+#ifndef SSPK_SERIAL
+#define SSPK_SERIAL
+
+#include /* for rs_table, serial constants &
+ serial_uart_config */
+#include /* for more serial constants */
+#include /* for struct serial_state */
+#include
+
+#define SPK_SERIAL_TIMEOUT 1000000 /* countdown values for serial timeouts */
+#define SPK_XMITR_TIMEOUT 1000000 /* countdown values transmitter/dsr timeouts */
+#define SPK_LO_TTY 0 /* check ttyS0 ... ttyS3 */
+#define SPK_HI_TTY 3
+#define NUM_DISABLE_TIMEOUTS 3 /* # of timeouts permitted before disable */
+#define SPK_TIMEOUT 100 /* buffer timeout in ms */
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup.c linux-2.4.30/drivers/char/speakup/speakup.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup.c 2005-05-01 19:02:59.000000000 -0700
@@ -0,0 +1,2285 @@
+/* speakup.c
+ review functions for the speakup screen review package.
+ originally written by: Kirk Reiser and Andy Berdan.
+
+ extensively modified by David Borowski.
+
+ Copyright (C ) 1998 Kirk Reiser.
+ Copyright (C ) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define __KERNEL_SYSCALLS__
+
+#include
+#include
+#include
+#include
+#include /* __get_free_page( ) and friends */
+#include
+#if (LINUX_VERSION_CODE < 132419)
+#include
+#include
+#include
+#endif
+#include
+#include
+#include /* copy_from|to|user( ) and others */
+#include
+
+#include /* for KT_SHIFT */
+#include /* for vc_kbd_* and friends */
+#include
+#include
+#include
+#include
+
+#include "cvsversion.h"
+#include "spk_priv.h"
+#include /* for alloc_bootmem */
+
+/* speakup_*_selection */
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../console_macros.h" /* for x, y, attr and pos macros */
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define SPEAKUP_VERSION "Speakup v-2.00" CVSVERSION
+#define MAX_DELAY ( (500 * HZ ) / 1000 )
+#define KEY_MAP_VER 119
+#define MINECHOCHAR SPACE
+
+/* these are globals from the kernel code */
+extern void *kmalloc (size_t, int );
+extern void kfree (const void * );
+extern struct kbd_struct * kbd;
+extern int fg_console;
+extern short punc_masks[];
+
+static special_func special_handler = NULL;
+special_func help_handler = NULL;
+
+static int errno;
+int synth_file_inuse = 0;
+short pitch_shift = 0, synth_flags = 0;
+static char buf[256];
+short attrib_bleep = 0, bleeps = 0, bleep_time = 1;
+short no_intr = 0, spell_delay = 0;
+short key_echo = 0, cursor_timeout = 120, say_word_ctl = 0;
+short say_ctrl = 0, bell_pos = 0;
+short punc_mask = 0, punc_level = 0, reading_punc = 0;
+char str_caps_start[MAXVARLEN+1] = "\0", str_caps_stop[MAXVARLEN+1] = "\0";
+bits_data punc_info[] = {
+ { "none", "", 0 },
+ { "some", "/$%&@", SOME },
+ { "most", "$%()=+*/@^<>|\\", MOST },
+ { "all", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", PUNC },
+ { "delimiters", "", B_WDLM },
+ { "repeats", "()", CH_RPT },
+ { "extended numeric", "", B_EXNUM },
+ { "symbols", "", B_SYM },
+ { 0, 0 }
+};
+char mark_cut_flag = 0;
+u_short mark_x = 0, mark_y = 0;
+static char synth_name[10] = CONFIG_SPEAKUP_DEFAULT;
+#define MAX_KEY 160
+u_char *our_keys[MAX_KEY], *shift_table;
+static u_char key_buf[600];
+static u_char key_defaults[] = {
+#include "speakupmap.h"
+};
+
+#if (LINUX_VERSION_CODE < 132419)
+extern struct tty_struct *tty;
+typedef void (*k_handler_fn)(unsigned char value, char up_flag);
+#define KBD_PROTO u_char value, char up_flag
+#define KBD_ARGS value, up_flag
+#else
+struct tty_struct *tty;
+#define key_handler k_handler
+typedef void (*k_handler_fn)(struct vc_data *vc, unsigned char value,
+ char up_flag, struct pt_regs *regs);
+#define KBD_PROTO struct vc_data *vc, u_char value, char up_flag, struct pt_regs *regs
+#define KBD_ARGS vc, value, up_flag, regs
+#endif
+extern k_handler_fn key_handler[16];
+static k_handler_fn do_shift, do_spec, do_latin, do_cursor;
+EXPORT_SYMBOL( help_handler );
+EXPORT_SYMBOL( special_handler );
+EXPORT_SYMBOL( our_keys );
+
+static void speakup_date (int currcons );
+static void spkup_write (const char *in_buf, int count );
+int set_mask_bits( const char *input, const int which, const int how );
+
+char str_ctl[] = "control-";
+char *colors[] = {
+ "black", "blue", "green", "cyan", "red", "magenta", "yellow", "white",
+ "grey"
+};
+
+char *phonetic[] = {
+ "alpha", "beta", "charley", "delta", "echo", "fox", "gamma", "hotel",
+ "india", "juleiet", "keelo", "leema", "mike", "november", "oscar",
+ "papa",
+ "quebec", "romeo", "seeara", "tango", "uniform", "victer", "wiskey",
+ "x ray", "yankee", "zooloo"
+};
+
+// array of 256 char pointers (one for each ASCII character description )
+// initialized to default_chars and user selectable via /proc/speakup/characters
+char *characters[256];
+
+char *default_chars[256] = {
+ "null", "^a", "^b", "^c", "^d", "^e", "^f", "^g",
+ "^h", "^i", "^j", "^k", "^l", "^m", "^n", "^o",
+ "^p", "^q", "^r", "^s", "^t", "^u", "^v", "^w",
+ "^x", "^y", "^z", NULL, NULL, NULL, NULL, NULL,
+ "space", "bang!", "quote", "number", "dollar", "percent", "and",
+ "tick",
+ "left paren", "right paren", "star", "plus", "comma", "dash", "dot",
+ "slash",
+ "zero", "one", "two", "three", "four", "five", "six", "seven",
+ "eight", "nine",
+ "colon", "semmy", "less", "equals", "greater", "question", "at",
+ "eigh", "b", "c", "d", "e", "f", "g",
+ "h", "i", "j", "k", "l", "m", "n", "o",
+ "p", "q", "r", "s", "t", "u", "v", "w", "x",
+ "y", "zehd", "left bracket", "backslash", "right bracket", "caret",
+ "line",
+ "accent", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "left brace", "bar", "right brace", "tihlduh",
+ "delta", "see cedilla", "u oomlout", "e acute", /* 128 */
+ "eigh circumflex", "eigh oomlout", "eigh grave", "eigh ring", /* 132 */
+ "see cedilla", "e circumflex", "e oomlout", "e grave", /* 136 */
+ "i oomlout", "i circumflex", "i grave", "eigh oomlout", /* 140 */
+ "eigh ring", "e acute", "eigh e dipthong", "eigh e dipthong", /* 144 */
+ "o circumflex", "o oomlout", "o grave", "u circumflex", /* 148 */
+ "u grave", "y oomlout", "o oomlout", "u oomlout", /* 152 */
+ "cents", "pounds", "yen", "peseta", /* 156 */
+ "florin", "eigh acute", "i acute", "o acute", /* 160 */
+ "u acute", "n tilde", "n tilde", "feminine ordinal", /* 164 */
+ "masculin ordinal", "inverted question", "reversed not", "not", /* 168 */
+ "half", "quarter", "inverted bang", "much less than", /* 172 */
+ "much greater than", "dark shading", "medium shading", /* 176 */
+ "light shading", "verticle line", "left tee", /* 179 */
+ "double left tee", "left double tee", "double top right", /* 182 */
+ "top double right", "double left double tee", /* 185 */
+ "double vertical line", "double top double right", /* 187 */
+ "double bottom double right", "double bottom right", /* 189 */
+ "bottom double right", "top right", "left bottom", /* 191 */
+ "up tee", "tee down", "tee right", "horizontal line", /* 194 */
+ "cross bars", "tee double right", "double tee right", /* 198 */
+ "double left double bottom", "double left double top", /* 201 */
+ "double up double tee", "double tee double down", /* 203 */
+ "double tee double right", "double horizontal line", /* 205 */
+ "double cross bars", "up double tee", "double up tee", /* 207 */
+ "double tee down", "tee double down", /* 210 */
+ "double left bottom", "left double bottom", /* 212 */
+ "double left top", "left double top", /* 214 */
+ "double vertical cross", "double horizontal cross", /* 216 */
+ "bottom right", "left top", "solid square", /* 218 */
+ "solid lower half", "solid left half", "solid right half", /* 221 */
+ "solid upper half", "alpha", "beta", "gamma", /* 224 */
+ "pie", "sigma", "sigma", "mu", /* 228 */
+ "tou", "phigh", "thayta", "ohmega", /* 232 */
+ "delta", "infinity", "phigh", "epsilaun", /* 236 */
+"intersection", "identical to", "plus or minus", "equal grater than", /* 240 */
+ "less than equal", "upper integral", "lower integral", /* 244 */
+ "divided by", "almost equal", "degrees", /* 247 */
+ "centre dot", "bullet", "square root", /* 250 */
+ "power", "squared", "black square", "white space" /* 252 */
+};
+
+u_short spk_chartab[256] = {
+ B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 0-7 */
+ B_CTL, B_CTL, A_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 8-15 */
+ B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /*16-23 */
+ B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 24-31 */
+WDLM, A_PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* !"#$%&' */
+PUNC, PUNC, PUNC, PUNC, A_PUNC, A_PUNC, A_PUNC, PUNC, /* ( )*+, -./ */
+NUM, NUM, NUM, NUM, NUM, NUM, NUM, NUM, /* 01234567 */
+NUM, NUM, A_PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* 89:;<=>? */
+PUNC, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* @ABCDEFG */
+A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* HIJKLMNO */
+A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* PQRSTUVW */
+A_CAP, A_CAP, A_CAP, PUNC, PUNC, PUNC, PUNC, PUNC, /* XYZ[\]^_ */
+PUNC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* `abcdefg */
+ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* hijklmno */
+ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* pqrstuvw */
+ALPHA, ALPHA, ALPHA, PUNC, PUNC, PUNC, PUNC, 0, /* xyz{|}~ */
+B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 128-135 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, /* 136-143 */
+B_CAPSYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 144-151 */
+B_SYM, B_SYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 152-159 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, B_SYM, /* 160-167 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 168-175 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 176-183 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 184-191 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 192-199 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 200-207 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 208-215 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 216-223 */
+B_SYM, B_SYM, B_SYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, /* 224-231 */
+B_SYM, B_CAPSYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 232-239 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 240-247 */
+B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM /* 248-255 */
+};
+
+int spk_keydown = 0;
+static u_char spk_lastkey = 0, spk_close_press = 0, keymap_flags = 0;
+static u_char last_keycode = 0, this_speakup_key = 0;
+static u_long last_spk_jiffy = 0;
+
+spk_t *speakup_console[MAX_NR_CONSOLES];
+
+int spk_setup (char *str )
+{
+ int ints[4];
+ str = get_options (str, ARRAY_SIZE (ints ), ints );
+ if (ints[0] > 0 && ints[1] >= 0 )
+ synth_port_forced = ints[1];
+ return 1;
+}
+
+int spk_ser_setup (char *str )
+{
+ int lookup[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+ int ints[4];
+ str = get_options (str, ARRAY_SIZE (ints ), ints );
+ if (ints[0] > 0 && ints[1] >= 0 )
+ synth_port_forced = lookup[ints[1]];
+ return 1;
+}
+
+int spk_synth_setup (char *str )
+{
+ size_t len = MIN (strlen (str ), 9 );
+ memcpy (synth_name, str, len );
+ synth_name[len] = '\0';
+ return 1;
+}
+
+__setup ("speakup_port=", spk_setup );
+__setup ("speakup_ser=", spk_ser_setup );
+__setup ("speakup_synth=", spk_synth_setup );
+
+char *
+strlwr (char *s )
+{
+ char *p;
+ for (p = s; *p; p++ ) {
+ if (*p >= CAP_A && *p <= CAP_Z ) *p |= 32;
+ }
+ return s;
+}
+
+static void
+bleep (u_short val )
+{
+ static short vals[] = { 350, 370, 392, 414, 440, 466, 491, 523,
+554, 587, 619, 659 };
+ short freq;
+ int time = bleep_time;
+ freq = vals[val%12];
+ if (val > 11 )
+ freq *= (1<<(val/12 ) );
+ kd_mksound (freq, time );
+}
+
+void
+speakup_shut_up (int currcons )
+{
+ if (spk_killed ) return;
+ spk_shut_up |= 0x01;
+ spk_parked &= 0xfe;
+ speakup_date (currcons );
+ if (synth == NULL ) return;
+ do_flush( );
+}
+
+void
+speech_kill (int currcons )
+{
+ char val = synth->is_alive ( );
+ if (val == 0 ) return;
+ /* re-enables synth, if disabled */
+ if (val == 2 || spk_killed ) { /* dead */
+ spk_shut_up &= ~0x40;
+ synth_write_msg ("Eyem a Lighve!" );
+ } else {
+ synth_write_msg ("You killed speak up!" );
+ spk_shut_up |= 0x40;
+ }
+}
+
+static void
+speakup_off (int currcons )
+{
+ if (spk_shut_up & 0x80 ) {
+ spk_shut_up &= 0x7f;
+ synth_write_msg ("hey. That's better!" );
+ } else {
+ spk_shut_up |= 0x80;
+ synth_write_msg ("You turned me off!" );
+ }
+ speakup_date (currcons );
+}
+
+static void
+speakup_parked (int currcons )
+{
+ if (spk_parked & 0x80 ) {
+ spk_parked = 0;
+ synth_write_msg ("unparked!" );
+ } else {
+ spk_parked |= 0x80;
+ synth_write_msg ("parked!" );
+ }
+}
+
+/* ------ cut and paste ----- */
+/* Don't take this from : 011-015 on the screen aren't spaces */
+#undef isspace
+#define isspace(c) ((c) == ' ')
+/* Variables for selection control. */
+int spk_sel_cons; /* defined in selection.c must not be disallocated */
+static volatile int sel_start = -1; /* cleared by clear_selection */
+static int sel_end;
+static int sel_buffer_lth;
+static char *sel_buffer;
+
+static unsigned char
+sel_pos(int n)
+{
+ return inverse_translate(vc_cons[spk_sel_cons].d, screen_glyph(spk_sel_cons, n));
+}
+
+static void
+speakup_clear_selection(void)
+{
+ sel_start = -1;
+}
+
+/* does screen address p correspond to character at LH/RH edge of screen? */
+static inline int atedge(const int p, int size_row)
+{
+ return (!(p % size_row) || !((p + 2) % size_row));
+}
+
+/* constrain v such that v <= u */
+static inline unsigned short limit(const unsigned short v, const unsigned short u)
+{
+ return (v > u) ? u : v;
+}
+
+unsigned short xs, ys, xe, ye; /* our region points */
+
+static int
+speakup_set_selection( struct tty_struct *tty)
+{
+ int new_sel_start, new_sel_end;
+ char *bp, *obp;
+ int i, ps, pe;
+ unsigned int currcons = fg_console;
+
+ xs = limit(xs, video_num_columns - 1);
+ ys = limit(ys, video_num_lines - 1);
+ xe = limit(xe, video_num_columns - 1);
+ ye = limit(ye, video_num_lines - 1);
+ ps = ys * video_size_row + (xs << 1);
+ pe = ye * video_size_row + (xe << 1);
+
+ if (ps > pe) { /* make sel_start <= sel_end */
+ int tmp = ps;
+ ps = pe;
+ pe = tmp;
+ }
+
+ if (spk_sel_cons != fg_console) {
+ speakup_clear_selection();
+ spk_sel_cons = fg_console;
+ printk(KERN_WARNING "Selection: mark console not the same as cut\n");
+ return -EINVAL;
+ }
+
+ new_sel_start = ps;
+ new_sel_end = pe;
+
+ /* select to end of line if on trailing space */
+ if (new_sel_end > new_sel_start &&
+ !atedge(new_sel_end, video_size_row) &&
+ isspace(sel_pos(new_sel_end))) {
+ for (pe = new_sel_end + 2; ; pe += 2)
+ if (!isspace(sel_pos(pe)) ||
+ atedge(pe, video_size_row))
+ break;
+ if (isspace(sel_pos(pe)))
+ new_sel_end = pe;
+ }
+ if ((new_sel_start == sel_start)
+ && (new_sel_end == sel_end)) /* no action required */
+ return 0;
+
+ sel_start = new_sel_start;
+ sel_end = new_sel_end;
+ /* Allocate a new buffer before freeing the old one ... */
+ bp = kmalloc((sel_end-sel_start)/2+1, GFP_ATOMIC);
+ if (!bp) {
+ printk(KERN_WARNING "selection: kmalloc() failed\n");
+ speakup_clear_selection();
+ return -ENOMEM;
+ }
+ if (sel_buffer)
+ kfree(sel_buffer);
+ sel_buffer = bp;
+
+ obp = bp;
+ for (i = sel_start; i <= sel_end; i += 2) {
+ *bp = sel_pos(i);
+ if (!isspace(*bp++))
+ obp = bp;
+ if (! ((i + 2) % video_size_row)) {
+ /* strip trailing blanks from line and add newline,
+ unless non-space at end of line. */
+ if (obp != bp) {
+ bp = obp;
+ *bp++ = '\r';
+ }
+ obp = bp;
+ }
+ }
+ sel_buffer_lth = bp - sel_buffer;
+ return 0;
+}
+
+static int
+speakup_paste_selection(struct tty_struct *tty)
+{
+ struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
+ int pasted = 0, count;
+ DECLARE_WAITQUEUE(wait, current);
+ add_wait_queue(&vt->paste_wait, &wait);
+ while (sel_buffer && sel_buffer_lth > pasted) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (test_bit(TTY_THROTTLED, &tty->flags)) {
+ schedule();
+ continue;
+ }
+ count = sel_buffer_lth - pasted;
+ count = MIN(count, tty->ldisc.receive_room(tty));
+ tty->ldisc.receive_buf(tty, sel_buffer + pasted, 0, count);
+ pasted += count;
+ }
+ remove_wait_queue(&vt->paste_wait, &wait);
+ current->state = TASK_RUNNING;
+ return 0;
+}
+
+static void
+speakup_cut (int currcons )
+{
+ static const char err_buf[] = "set selection failed";
+ int ret;
+
+ if (!mark_cut_flag ) {
+ mark_cut_flag = 1;
+ xs = spk_x;
+ ys = spk_y;
+ spk_sel_cons = currcons;
+ synth_write_msg ("mark" );
+ return;
+ }
+ xe = (u_short ) spk_x;
+ ye = (u_short )spk_y;
+ mark_cut_flag = 0;
+ synth_write_msg ("cut" );
+
+ speakup_clear_selection( );
+ ret = speakup_set_selection ( tty );
+
+ switch (ret ) {
+ case 0:
+ break; /* no error */
+ case -EFAULT :
+ pr_warn( "%sEFAULT\n", err_buf );
+ break;
+ case -EINVAL :
+ pr_warn( "%sEINVAL\n", err_buf );
+ break;
+ case -ENOMEM :
+ pr_warn( "%sENOMEM\n", err_buf );
+ break;
+ }
+}
+
+static void
+speakup_paste (int currcons )
+{
+ if (mark_cut_flag ) {
+ mark_cut_flag = 0;
+ synth_write_msg ("mark, cleared" );
+ } else {
+ synth_write_msg ("paste" );
+ speakup_paste_selection (tty );
+ }
+}
+
+static void
+say_attributes (int currcons )
+{
+ int fg= spk_attr&0x0f, bg = spk_attr>>4;
+ if (fg > 8 ) {
+ synth_write_string("bright " );
+ fg -= 8;
+ }
+ synth_write_string(colors[fg] );
+ if (bg > 7 ) {
+ synth_write_string(" on blinking " );
+ bg -= 8;
+ } else
+ synth_write_string(" on " );
+ synth_write_msg(colors[bg] );
+}
+
+static char *blank_msg = "blank";
+static char *edges[] = { "top, ", "bottom, ", "left, ", "right, ", "" };
+enum { edge_top = 1, edge_bottom, edge_left, edge_right, edge_quiet };
+
+static void
+announce_edge (int currcons, int msg_id )
+{
+ if (bleeps&1 )
+ bleep (spk_y );
+ if (bleeps&2 )
+ synth_write_msg (edges[msg_id-1] );
+}
+
+static void
+speak_char( u_char ch )
+{
+ char *cp = characters[ ch];
+ synth_buffer_add( SPACE );
+ if (IS_CHAR(ch, B_CAP ) ) {
+ pitch_shift++;
+ synth_write_string(str_caps_start );
+ synth_write_string(cp );
+ synth_write_string(str_caps_stop );
+ } else {
+ if (*cp == '^' ) {
+ synth_write_string(str_ctl );
+ cp++;
+ }
+ synth_write_string(cp );
+ }
+ synth_buffer_add( SPACE );
+}
+
+static void
+say_char (int currcons )
+{
+ u_short ch;
+ spk_old_attr = spk_attr;
+ ch = scr_readw ((u_short * ) spk_pos );
+ spk_attr = ((ch & 0xff00 ) >> 8 );
+ if (spk_attr != spk_old_attr ) {
+ if ( attrib_bleep&1 ) bleep (spk_y );
+ if ( attrib_bleep&2 ) say_attributes( currcons );
+ }
+ speak_char( ch&0xff );
+}
+
+static void
+say_phonetic_char (int currcons )
+{
+ u_short ch;
+ spk_old_attr = spk_attr;
+ ch = scr_readw ((u_short * ) spk_pos );
+ spk_attr = ((ch & 0xff00 ) >> 8 );
+ if ( IS_CHAR(ch, B_ALPHA ) ) {
+ ch &= 0x1f;
+ synth_write_msg(phonetic[--ch] );
+ } else {
+ if ( IS_CHAR(ch, B_NUM ) )
+ synth_write_string( "number " );
+ speak_char( ch );
+ }
+}
+
+static void
+say_prev_char (int currcons )
+{
+ spk_parked |= 0x01;
+ if (spk_x == 0 ) {
+ announce_edge(currcons, edge_left );
+ return;
+ }
+ spk_x--;
+ spk_pos -= 2;
+ say_char (currcons );
+}
+
+static void
+say_next_char (int currcons )
+{
+ spk_parked |= 0x01;
+ if (spk_x == video_num_columns - 1 ) {
+ announce_edge(currcons, edge_right );
+ return;
+ }
+ spk_x++;
+ spk_pos += 2;
+ say_char (currcons );
+}
+
+/* get_word - will first check to see if the character under the
+ reading cursor is a space and if say_word_ctl is true it will
+ return the word space. If say_word_ctl is not set it will check to
+ see if there is a word starting on the next position to the right
+ and return that word if it exists. If it does not exist it will
+ move left to the beginning of any previous word on the line or the
+ beginning off the line whichever comes first.. */
+
+static u_long
+get_word (int currcons )
+{
+ u_long cnt = 0, tmpx = spk_x, tmp_pos = spk_pos;
+ char ch;
+ u_short attr_ch;
+ spk_old_attr = spk_attr;
+ ch = (char ) scr_readw ((u_short * ) tmp_pos );
+
+/* decided to take out the sayword if on a space (mis-information */
+ if ( say_word_ctl && ch == SPACE ) {
+ *buf = '\0';
+ synth_write_msg( "space" );
+ return 0;
+ } else if ((tmpx < video_num_columns-2 )
+ && (ch == SPACE || IS_WDLM(ch ))
+ && ((char) scr_readw ((u_short * ) tmp_pos+1 ) > SPACE)) {
+ tmp_pos += 2;
+ tmpx++;
+ } else
+ while (tmpx > 0 ) {
+ if (((ch = (char ) scr_readw ((u_short * ) tmp_pos-1 )) == SPACE
+ || IS_WDLM(ch ))
+ && ((char) scr_readw ((u_short * ) tmp_pos ) > SPACE))
+ break;
+ tmp_pos -= 2;
+ tmpx--;
+ }
+ attr_ch = scr_readw ((u_short * ) tmp_pos );
+ spk_attr = attr_ch >> 8;
+ buf[cnt++] = attr_ch&0xff;
+ while (tmpx < video_num_columns-1 ) {
+ tmp_pos += 2;
+ tmpx++;
+ ch = (char ) scr_readw ((u_short * ) tmp_pos );
+ if ((ch == SPACE )
+ || (IS_WDLM(buf[cnt-1] ) && ( ch > SPACE )))
+ break;
+ buf[cnt++] = ch;
+ }
+ buf[cnt] = '\0';
+ return cnt;
+}
+
+static void
+say_word (int currcons )
+{
+ u_long cnt = get_word(currcons );
+ u_short saved_punc_mask = punc_mask;
+ if ( cnt == 0 ) return;
+ punc_mask = PUNC;
+ buf[cnt++] = SPACE;
+ spkup_write (buf, cnt );
+ punc_mask = saved_punc_mask;
+}
+
+static void
+say_prev_word (int currcons )
+{
+ char ch;
+ u_short edge_said = 0, last_state = 0, state = 0;
+ spk_parked |= 0x01;
+ if (spk_x == 0 ) {
+ if ( spk_y == 0 ) {
+ announce_edge(currcons, edge_top );
+ return;
+ }
+ spk_y--;
+ spk_x = video_num_columns;
+ edge_said = edge_quiet;
+ }
+ while ( 1 ) {
+ if (spk_x == 0 ) {
+ if (spk_y == 0 ) {
+ edge_said = edge_top;
+ break;
+ }
+ if ( edge_said != edge_quiet ) edge_said = edge_left;
+ if ( state > 0 ) break;
+ spk_y--;
+ spk_x = video_num_columns-1;
+ } else spk_x--;
+ spk_pos -= 2;
+ ch = (char ) scr_readw ((u_short * ) spk_pos );
+ if ( ch == SPACE ) state = 0;
+ else if (IS_WDLM(ch ) ) state = 1;
+ else state = 2;
+ if (state < last_state ) {
+ spk_pos += 2;
+ spk_x++;
+ break;
+ }
+ last_state = state;
+ }
+ if ( spk_x == 0 && edge_said == edge_quiet )
+ edge_said = edge_left;
+ if ( edge_said > 0 && edge_said < edge_quiet )
+ announce_edge( currcons, edge_said );
+ say_word (currcons );
+}
+
+static void
+say_next_word (int currcons )
+{
+ char ch;
+ u_short edge_said = 0, last_state = 2, state = 0;
+ spk_parked |= 0x01;
+ if ( spk_x == video_num_columns - 1 && spk_y == video_num_lines-1 ) {
+ announce_edge(currcons, edge_bottom );
+ return;
+ }
+ while ( 1 ) {
+ ch = (char ) scr_readw ((u_short * ) spk_pos );
+ if ( ch == SPACE ) state = 0;
+ else if (IS_WDLM(ch ) ) state = 1;
+ else state = 2;
+ if ( state > last_state ) break;
+ if (spk_x >= video_num_columns-1 ) {
+ if (spk_y == video_num_lines-1 ) {
+ edge_said = edge_bottom;
+ break;
+ }
+ state = 0;
+ spk_y++;
+ spk_x = 0;
+ edge_said = edge_right;
+ } else spk_x++;
+ spk_pos += 2;
+ last_state = state;
+ }
+ if ( edge_said > 0 )
+ announce_edge( currcons, edge_said );
+ say_word (currcons );
+}
+
+static void
+spell_word (int currcons )
+{
+ static char *delay_str[] = { " ", ", ", ". ", ". . ", ". . . " };
+ char *cp = buf, *str_cap= str_caps_stop;
+ char *cp1, *last_cap = str_caps_stop;
+ u_char ch;
+ if ( !get_word(currcons ) ) return;
+ while ((ch = (u_char )*cp ) ) {
+ if ( cp != buf )
+ synth_write_string (delay_str[spell_delay] );
+ if (IS_CHAR(ch, B_CAP ) ) {
+ str_cap = str_caps_start;
+ if ( *str_caps_stop ) pitch_shift++;
+ else last_cap = str_caps_stop; /* synth has no pitch */
+ } else str_cap = str_caps_stop;
+ if ( str_cap !=last_cap ) {
+ synth_write_string( str_cap );
+ last_cap = str_cap;
+ }
+ if ( this_speakup_key == SPELL_PHONETIC && ( IS_CHAR( ch, B_ALPHA ) ) ) {
+ ch &= 31;
+ cp1 = phonetic[--ch];
+ } else {
+ cp1 = characters[ch];
+ if (*cp1 == '^' ) {
+ synth_write_string(str_ctl );
+ cp1++;
+ }
+ }
+ synth_write_string(cp1 );
+ cp++;
+ }
+ if ( str_cap != str_caps_stop )
+ synth_write_string( str_caps_stop );
+}
+
+static int
+get_line (int currcons )
+{
+ u_long tmp = spk_pos - (spk_x * 2 );
+ int i = 0;
+ spk_old_attr = spk_attr;
+ spk_attr = (u_char ) (scr_readw ((u_short * ) spk_pos ) >> 8 );
+ for (i = 0; i < video_num_columns; i++ ) {
+ buf[i] = (u_char ) scr_readw ((u_short * ) tmp );
+ tmp += 2;
+ }
+ for (--i; i >= 0; i-- )
+ if (buf[i] != SPACE ) break;
+ return ++i;
+}
+
+static void
+say_line (int currcons )
+{
+ int i = get_line( currcons );
+ char *cp;
+ char num_buf[8];
+ u_short saved_punc_mask = punc_mask;
+ if (i == 0 ) {
+ synth_write_msg (blank_msg );
+ return;
+ }
+ buf[i++] = '\n';
+ if ( this_speakup_key == SAY_LINE_INDENT ) {
+ for ( cp = buf; *cp == SPACE; cp++ );
+ sprintf( num_buf, "%d, ", ( cp-buf )+1 );
+ synth_write_string( num_buf );
+ }
+ punc_mask = punc_masks[reading_punc];
+ spkup_write (buf, i );
+ punc_mask = saved_punc_mask;
+}
+
+static void
+say_prev_line (int currcons )
+{
+ spk_parked |= 0x01;
+ if (spk_y == 0 ) {
+ announce_edge (currcons, edge_top );
+ return;
+ }
+ spk_y--;
+ spk_pos -= video_size_row;
+ say_line (currcons );
+}
+
+static void
+say_next_line (int currcons )
+{
+ spk_parked |= 0x01;
+ if (spk_y == video_num_lines - 1 ) {
+ announce_edge (currcons, edge_bottom );
+ return;
+ }
+ spk_y++;
+ spk_pos += video_size_row;
+ say_line (currcons );
+}
+
+static int
+say_from_to (int currcons, u_long from, u_long to, int read_punc )
+{
+ int i = 0;
+ u_short saved_punc_mask = punc_mask;
+ spk_old_attr = spk_attr;
+ spk_attr = (u_char ) (scr_readw ((u_short * ) from ) >> 8 );
+ while (from < to ) {
+ buf[i++] = (char ) scr_readw ((u_short * ) from );
+ from += 2;
+ if ( i >= video_size_row ) break;
+ }
+ for (--i; i >= 0; i-- )
+ if (buf[i] != SPACE ) break;
+ buf[++i] = SPACE;
+ buf[++i] = NULL;
+ if ( i < 1 ) return i;
+ if ( read_punc ) punc_mask = punc_info[reading_punc].mask;
+ spkup_write (buf, i );
+ if ( read_punc ) punc_mask = saved_punc_mask;
+ return i-1;
+}
+
+static void
+say_line_from_to (int currcons, u_long from, u_long to, int read_punc )
+{
+ u_long start = origin+(spk_y*video_size_row );
+ u_long end = start+( to * 2 );
+ start += from*2;
+ if ( say_from_to( currcons, start, end, read_punc ) <= 0 )
+ synth_write_msg (blank_msg );
+}
+
+static void
+say_screen_from_to (int currcons, u_long from, u_long to )
+{
+ u_long start = origin, end;
+ if ( from > 0 ) start += from * video_size_row;
+ if ( to > video_num_lines ) to = video_num_lines;
+ end = origin + ( to * video_size_row);
+ for ( from = start; from < end; from = to ) {
+ to = from + video_size_row;
+ say_from_to( currcons, from, to, 1 );
+ }
+}
+
+static void
+say_screen (int currcons )
+{
+ say_screen_from_to( currcons, 0, video_num_lines );
+}
+
+static void
+speakup_win_say (int currcons )
+{
+ u_long start, end, from, to;
+ if ( win_start < 2 ) {
+ synth_write_msg( "no window" );
+ return;
+ }
+ start = origin + ( win_top * video_size_row );
+ end = origin + ( win_bottom * video_size_row );
+ while ( start <= end ) {
+ from = start + ( win_left * 2 );
+ to = start + ( win_right * 2 );
+ say_from_to( currcons, from, to, 1 );
+ start += video_size_row;
+ }
+}
+
+static void
+top_edge (int currcons )
+{
+ spk_parked |= 0x01;
+ spk_pos = origin + 2 * spk_x;
+ spk_y = 0;
+ say_line (currcons );
+}
+
+static void
+bottom_edge (int currcons )
+{
+ spk_parked |= 0x01;
+ spk_pos += (video_num_lines - spk_y - 1 ) * video_size_row;
+ spk_y = video_num_lines - 1;
+ say_line (currcons );
+}
+
+static void
+left_edge (int currcons )
+{
+ spk_parked |= 0x01;
+ spk_pos -= spk_x * 2;
+ spk_x = 0;
+ say_char (currcons );
+}
+
+static void
+right_edge (int currcons )
+{
+ spk_parked |= 0x01;
+ spk_pos += (video_num_columns - spk_x - 1 ) * 2;
+ spk_x = video_num_columns - 1;
+ say_char (currcons );
+}
+
+static void
+say_first_char (int currcons )
+{
+ int i, len = get_line( currcons );
+ u_char ch;
+ spk_parked |= 0x01;
+ if ( len == 0 ) {
+ synth_write_msg( blank_msg );
+ return;
+ }
+ for ( i = 0; i < len; i++ ) if ( buf[i] != SPACE ) break;
+ ch = buf[i];
+ spk_pos -= ( spk_x-i ) * 2;
+ spk_x = i;
+ sprintf (buf, "%d, ", ++i );
+ synth_write_string (buf );
+ speak_char( ch );
+}
+
+static void
+say_last_char (int currcons )
+{
+ int len = get_line( currcons );
+ u_char ch;
+ spk_parked |= 0x01;
+ if ( len == 0 ) {
+ synth_write_msg( blank_msg );
+ return;
+ }
+ ch = buf[--len];
+ spk_pos -= ( spk_x-len ) * 2;
+ spk_x = len;
+ sprintf (buf, "%d, ", ++len );
+ synth_write_string (buf );
+ speak_char( ch );
+}
+
+static void
+say_position (int currcons )
+{
+ sprintf (buf, "line %ld, col %ld, t t y %d\n", spk_y + 1,
+ spk_x + 1, currcons + 1 );
+ synth_write_string (buf );
+}
+
+// Added by brianb
+static void
+say_char_num (int currcons )
+{
+ u_short ch = scr_readw ((u_short * ) spk_pos );
+ ch &= 0x0ff;
+ sprintf (buf, "hex %02x, decimal %d", ch, ch );
+ synth_write_msg (buf );
+}
+
+/* these are stub functions to keep keyboard.c happy. */
+
+static void
+say_from_top (int currcons )
+{
+ say_screen_from_to (currcons, 0, spk_y );
+}
+
+static void
+say_to_bottom (int currcons )
+{
+ say_screen_from_to (currcons, spk_y, video_num_lines );
+}
+
+static void
+say_from_left (int currcons )
+{
+ say_line_from_to (currcons, 0, spk_x, 1 );
+}
+
+static void
+say_to_right (int currcons )
+{
+ say_line_from_to (currcons, spk_x, video_num_columns, 1 );
+}
+
+/* end of stub functions. */
+
+static void
+spkup_write (const char *in_buf, int count )
+{
+ static int rep_count = 0;
+ static u_char ch = '\0', old_ch = '\0';
+ static u_short char_type = 0, last_type = 0;
+ static u_char *exn_ptr = NULL;
+ int in_count = count;
+ char rpt_buf[32];
+ spk_keydown = 0;
+ while ( count-- ) {
+ ch = (u_char )*in_buf++;
+ char_type = spk_chartab[ch];
+ if (ch == old_ch && !(char_type&B_NUM ) ) {
+ if (++rep_count > 2 ) continue;
+ } else {
+ if ( (last_type&CH_RPT) && rep_count > 2 ) {
+ sprintf (rpt_buf, " times %d . ", ++rep_count );
+ synth_write_string (rpt_buf );
+ }
+ rep_count = 0;
+ }
+ if ( !( char_type&B_NUM ) )
+ exn_ptr = NULL;
+ if (ch == spk_lastkey ) {
+ rep_count = 0;
+ if ( key_echo == 1 && ch >= MINECHOCHAR )
+ speak_char( ch );
+ } else if ( ( char_type&B_ALPHA ) ) {
+ if ( (synth_flags&SF_DEC) && (last_type&PUNC) )
+ synth_buffer_add ( SPACE );
+ synth_write( &ch, 1 );
+ } else if ( ( char_type&B_NUM ) ) {
+ rep_count = 0;
+ if ( (last_type&B_EXNUM) && synth_buff_in == exn_ptr+1 ) {
+ synth_buff_in--;
+ synth_buffer_add( old_ch );
+ exn_ptr = NULL;
+ }
+ synth_write( &ch, 1 );
+ } else if ( (char_type&punc_mask) ) {
+ speak_char( ch );
+ char_type &= ~PUNC; /* for dec nospell processing */
+ } else if ( ( char_type&SYNTH_OK ) ) {
+/* these are usually puncts like . and , which synth needs for expression.
+ * suppress multiple to get rid of long pausesand clear repeat count so if
+ *someone has repeats on you don't get nothing repeated count */
+ if ( ch != old_ch )
+ synth_write( &ch, 1 );
+ else rep_count = 0;
+ } else {
+ if ( ( char_type&B_EXNUM ) )
+ exn_ptr = (u_char *)synth_buff_in;
+/* send space and record position, if next is num overwrite space */
+ if ( old_ch != ch ) synth_buffer_add ( SPACE );
+ else rep_count = 0;
+ }
+ old_ch = ch;
+ last_type = char_type;
+ }
+ spk_lastkey = 0;
+ if (in_count > 2 && rep_count > 2 ) {
+ if ( (last_type&CH_RPT) ) {
+ sprintf (rpt_buf, " repeated %d . ", ++rep_count );
+ synth_write_string (rpt_buf );
+ }
+ rep_count = 0;
+ }
+}
+
+static char *ctl_key_ids[] = {
+ "shift", "altgr", "control", "ault", "l shift", "speakup",
+"l control", "r control"
+};
+#define NUM_CTL_LABELS 8
+
+static void
+handle_shift( KBD_PROTO )
+{
+ int currcons = fg_console;
+ (*do_shift)( KBD_ARGS );
+ if ( synth == NULL || up_flag || spk_killed ) return;
+ spk_shut_up &= 0xfe;
+ do_flush( );
+ if ( say_ctrl && value < NUM_CTL_LABELS )
+ synth_write_string ( ctl_key_ids[value] );
+}
+
+static void
+handle_latin( KBD_PROTO )
+{
+ int currcons = fg_console;
+ (*do_latin)( KBD_ARGS );
+ if ( up_flag ) {
+ spk_lastkey = spk_keydown = 0;
+ return;
+ }
+ if ( synth == NULL || spk_killed ) return;
+ spk_shut_up &= 0xfe;
+ spk_lastkey = value;
+ spk_keydown++;
+ spk_parked &= 0xfe;
+ if ( key_echo == 2 && value >= MINECHOCHAR )
+ speak_char( value );
+}
+
+static int
+set_key_info( u_char *key_info, u_char *k_buffer )
+{
+ int i = 0, states, key_data_len;
+ u_char *cp = key_info, *cp1 = k_buffer;
+ u_char ch, version, num_keys;
+ version = *cp++;
+ if ( version != KEY_MAP_VER ) return -1;
+ num_keys = *cp;
+ states = (int)cp[1];
+ key_data_len = ( states+1 ) * ( num_keys+1 );
+ if ( key_data_len+SHIFT_TBL_SIZE+4 >= sizeof(key_buf ) ) return -2;
+ memset( k_buffer, 0, SHIFT_TBL_SIZE );
+ memset( our_keys, 0, sizeof( our_keys ) );
+ shift_table = k_buffer;
+ our_keys[0] = shift_table;
+ cp1 += SHIFT_TBL_SIZE;
+ memcpy( cp1, cp, key_data_len+3 );
+/* get num_keys, states and data*/
+ cp1 += 2; /* now pointing at shift states */
+ for ( i = 1; i <= states; i++ ) {
+ ch = *cp1++;
+ if ( ch >= SHIFT_TBL_SIZE ) return -3;
+ shift_table[ch] = i;
+ }
+ keymap_flags = *cp1++;
+ while ( ( ch = *cp1 ) ) {
+ if ( ch >= MAX_KEY ) return -4;
+ our_keys[ch] = cp1;
+ cp1 += states+1;
+ }
+ return 0;
+}
+
+num_var spk_num_vars[] = { /* bell must be first to set high limit */
+ { BELL_POS, 0, 0, 0, 0, 0, 0, 0 },
+ { SPELL_DELAY, 0, 0, 0, 5, 0, 0, 0 },
+ { ATTRIB_BLEEP, 0, 1, 0, 3, 0, 0, 0 },
+ { BLEEPS, 0, 3, 0, 3, 0, 0, 0 },
+ { BLEEP_TIME, 0, 4, 1, 20, 0, 0, 0 },
+ { PUNC_LEVEL, 0, 1, 0, 4, 0, 0, 0 },
+ { READING_PUNC, 0, 1, 0, 4, 0, 0, 0 },
+ { CURSOR_TIME, 0, 120, 50, 600, 0, 0, 0 },
+ { SAY_CONTROL, TOGGLE_0 },
+ { SAY_WORD_CTL, TOGGLE_0 },
+ { NO_INTERRUPT, TOGGLE_0 },
+ { KEY_ECHO, 0, 1, 0, 2, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+static int cursor_track = 1;
+static char *cursor_msgs[] = { "cursoring off", "cursoring on",
+ "attribute cursor" };
+#define MAXCURSORTRACK 1
+/* increase when we add more cursor modes */
+/* attribute cursor code coming soon */
+
+static void
+toggle_cursoring( int currcons )
+{
+ cursor_track++;
+ if ( cursor_track > MAXCURSORTRACK )
+ cursor_track = 0;
+ synth_write_msg (cursor_msgs[cursor_track] );
+}
+
+static void
+reset_default_chars (void )
+{
+ int i;
+ if (default_chars[(int )'a'] == NULL ) { /* lowers are null first time */
+ for (i = (int )'a'; default_chars[i] == NULL; i++ )
+ default_chars[i] = default_chars[i-32];
+ } else { /* free any non-default */
+ for (i = 0; i < 256; i++ ) {
+ if (characters[i] != default_chars[i] )
+ kfree (characters[i] );
+ }
+ }
+ memcpy( characters, default_chars, sizeof( default_chars ) );
+}
+
+static void
+handle_cursor( KBD_PROTO );
+static void
+handle_spec( KBD_PROTO );
+static void
+cursor_done(u_long data );
+declare_timer( cursor_timer );
+
+void __init speakup_open (int currcons, spk_t *first_console )
+{
+ int i;
+ num_var *n_var;
+ reset_default_chars ( );
+ memset( speakup_console, 0, sizeof( speakup_console ) );
+ if ( first_console == NULL ) return;
+ memset( first_console, 0, spk_size );
+ speakup_console[currcons] = first_console;
+ speakup_date( currcons);
+ pr_info ("%s: initialized\n", SPEAKUP_VERSION );
+ init_timer (&cursor_timer );
+#if (LINUX_VERSION_CODE >= 132419)
+ cursor_timer.entry.prev=NULL;
+#endif
+ cursor_timer.function = cursor_done;
+ init_sleeper ( synth_sleeping_list );
+ strlwr (synth_name );
+ synth_init ( synth_name );
+ spk_num_vars[0].high = video_num_columns;
+ for ( n_var = spk_num_vars; n_var->var_id >= 0; n_var++ )
+ speakup_register_var( n_var );
+ for (i = 1; punc_info[i].mask != 0; i++ )
+ set_mask_bits( 0, i, 2 );
+ do_latin = key_handler[KT_LATIN];
+ key_handler[KT_LATIN] = handle_latin;
+ do_spec = key_handler[KT_SPEC];
+ key_handler[KT_SPEC] = handle_spec;
+ do_cursor = key_handler[KT_CUR];
+ key_handler[KT_CUR] = handle_cursor;
+ do_shift = key_handler[KT_SHIFT];
+ key_handler[KT_SHIFT] = handle_shift;
+ set_key_info( key_defaults, key_buf );
+}
+
+#ifdef CONFIG_PROC_FS
+
+// speakup /proc interface code
+
+/* Usage:
+cat /proc/speakup/version
+
+cat /proc/speakup/characters > foo
+less /proc/speakup/characters
+vi /proc/speakup/characters
+
+cat foo > /proc/speakup/characters
+cat > /proc/speakup/characters
+echo 39 apostrophe > /proc/speakup/characters
+echo 87 w > /proc/speakup/characters
+echo 119 w > /proc/speakup/characters
+echo defaults > /proc/speakup/characters
+echo reset > /proc/speakup/characters
+*/
+
+// keymap handlers
+
+static int
+keys_read_proc (PROC_READ_PROTOTYPE )
+{
+ char *cp = page;
+ int i, n, num_keys, nstates;
+ u_char *cp1 = key_buf + SHIFT_TBL_SIZE, ch;
+ num_keys = (int)(*cp1);
+ nstates = (int)cp1[1];
+ cp += sprintf( cp, "%d, %d, %d,\n", KEY_MAP_VER, num_keys, nstates );
+ cp1 += 2; /* now pointing at shift states */
+/* dump num_keys+1 as first row is shift states + flags,
+ each subsequent row is key + states */
+ for ( n = 0; n <= num_keys; n++ ) {
+ for ( i = 0; i <= nstates; i++ ) {
+ ch = *cp1++;
+ cp += sprintf( cp, "%d,", (int)ch );
+ *cp++ = ( i < nstates ) ? SPACE : '\n';
+ }
+ }
+ cp += sprintf( cp, "0, %d\n", KEY_MAP_VER );
+ *start = 0;
+ *eof = 1;
+ return (int)(cp-page);
+}
+
+static char *
+s2uchar ( char *start, char *dest )
+{
+ int val = 0;
+ while ( *start && *start <= SPACE ) start++;
+ while ( *start >= '0' && *start <= '9' ) {
+ val *= 10;
+ val += ( *start ) - '0';
+ start++;
+ }
+ if ( *start == ',' ) start++;
+ *dest = (u_char)val;
+ return start;
+}
+
+static int
+keys_write_proc (PROC_WRITE_PROTOTYPE )
+{
+ int i, ret = count;
+ char *in_buff, *cp;
+ u_char *cp1;
+ if (count < 1 || count > 1800 )
+ return -EINVAL;
+ in_buff = ( char * ) __get_free_page ( GFP_KERNEL );
+ if ( !in_buff ) return -ENOMEM;
+ if (copy_from_user (in_buff, buffer, count ) ) {
+ free_page ( ( unsigned long ) in_buff );
+ return -EFAULT;
+ }
+ if (in_buff[count - 1] == '\n' ) count--;
+ in_buff[count] = '\0';
+ if ( count == 1 && *in_buff == 'd' ) {
+ free_page ( ( unsigned long ) in_buff );
+ set_key_info( key_defaults, key_buf );
+ return ret;
+ }
+ cp = in_buff;
+ cp1 = (u_char *)in_buff;
+ for ( i = 0; i < 3; i++ ) {
+ cp = s2uchar( cp, cp1 );
+ cp1++;
+ }
+ i = (int)cp1[-2]+1;
+ i *= (int)cp1[-1]+1;
+ i+= 2; /* 0 and last map ver */
+ if ( cp1[-3] != KEY_MAP_VER || cp1[-1] > 10 ||
+ i+SHIFT_TBL_SIZE+4 >= sizeof(key_buf ) ) {
+pr_warn( "i %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1] );
+ free_page ( ( unsigned long ) in_buff );
+ return -EINVAL;
+ }
+ while ( --i >= 0 ) {
+ cp = s2uchar( cp, cp1 );
+ cp1++;
+ if ( !(*cp) ) break;
+ }
+ if ( i != 0 || cp1[-1] != KEY_MAP_VER || cp1[-2] != 0 ) {
+ ret = -EINVAL;
+pr_warn( "end %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1] );
+ } else {
+ if ( set_key_info( in_buff, key_buf ) ) {
+ set_key_info( key_defaults, key_buf );
+ ret = -EINVAL;
+pr_warn( "set key failed\n" );
+ }
+ }
+ free_page ( ( unsigned long ) in_buff );
+ return ret;
+}
+
+// this is the handler for /proc/speakup/version
+static int
+version_read_proc (PROC_READ_PROTOTYPE )
+{
+ int len = sprintf (page, "%s\n", SPEAKUP_VERSION );
+ if ( synth != NULL )
+ len += sprintf( page+len, "synth %s version %s\n",
+ synth->name, synth->version );
+ *start = 0;
+ *eof = 1;
+ return len;
+}
+
+// this is the read handler for /proc/speakup/characters
+static int
+chars_read_proc (PROC_READ_PROTOTYPE )
+{
+ int i, len = 0;
+ off_t begin = 0;
+ char *cp;
+ for (i = 0; i < 256; i++ ) {
+ cp = (characters[i] ) ? characters[i] : "NULL";
+ len += sprintf (page + len, "%d\t%s\n", i, cp );
+ if (len + begin > off + count )
+ break;
+ if (len + begin < off ) {
+ begin += len;
+ len = 0;
+ }
+ }
+ if (i >= 256 )
+ *eof = 1;
+ if (off >= len + begin )
+ return 0;
+ *start = page + (off - begin );
+ return ((count < begin + len - off ) ? count : begin + len - off );
+}
+
+static volatile int chars_timer_active = 0; // indicates when timer is set
+static declare_timer( chars_timer );
+
+static inline void
+chars_stop_timer (void )
+{
+ if (chars_timer_active )
+ stop_timer ( chars_timer );
+}
+
+static int strings, rejects, updates;
+
+static void
+show_char_results (u_long data )
+{
+ int len;
+ char buf[80];
+ chars_stop_timer ( );
+ len = sprintf (buf, " updated %d of %d character descriptions\n",
+ updates, strings );
+ if (rejects )
+ sprintf (buf + (len-1), " with %d reject%s\n",
+ rejects, rejects > 1 ? "s" : "" );
+ printk( buf );
+}
+
+/* this is the write handler for /proc/speakup/silent */
+static int
+silent_write_proc (PROC_WRITE_PROTOTYPE )
+{
+ int currcons = fg_console;
+ char ch = 0, shut;
+ if (count > 0 || count < 3 ) {
+ get_user (ch, buffer );
+ if ( ch == '\n' ) ch = '0';
+ }
+ if ( ch < '0' || ch > '7' ) {
+ pr_warn ( "silent value not in range (0,7)\n" );
+ return count;
+ }
+ if ( (ch&2) ) {
+ shut = 1;
+ do_flush( );
+ } else shut = 0;
+ if ( (ch&4) ) shut |= 0x40;
+ if ( (ch&1) )
+ spk_shut_up |= shut;
+ else spk_shut_up &= ~shut;
+ return count;
+}
+
+// this is the write handler for /proc/speakup/characters
+static int
+chars_write_proc (PROC_WRITE_PROTOTYPE )
+{
+#define max_desc_len 72
+ static int cnt = 0, state = 0;
+ static char desc[max_desc_len + 1];
+ static u_long jiff_last = 0;
+ short i = 0, num;
+ int len;
+ char ch, *cp, *p_new;
+ // reset certain vars if enough time has elapsed since last called
+ if (jiffies - jiff_last > 10 ) {
+ cnt = state = strings = rejects = updates = 0;
+ }
+ jiff_last = jiffies;
+get_more:
+ desc[cnt] = '\0';
+ state = 0;
+ for (; i < count && state < 2; i++ ) {
+ get_user (ch, buffer + i );
+ if ( ch == '\n' ) {
+ desc[cnt] = '\0';
+ state = 2;
+ } else if (cnt < max_desc_len )
+ desc[cnt++] = ch;
+ }
+ if (state < 2 ) return count;
+ cp = desc;
+ while ( *cp && *cp <= SPACE ) cp++;
+ if ((!cnt ) || strchr ("dDrR", *cp ) ) {
+ reset_default_chars ( );
+ pr_info( "character descriptions reset to defaults\n" );
+ cnt = 0;
+ return count;
+ }
+ cnt = 0;
+ if (*cp == '#' ) goto get_more;
+ num = -1;
+ cp = speakup_s2i(cp, &num );
+ while ( *cp && *cp <= SPACE ) cp++;
+ if (num < 0 || num > 255 ) { // not in range
+ rejects++;
+ strings++;
+ goto get_more;
+ }
+ if (num >= 27 && num <= 31 ) goto get_more;
+ if (!strcmp(cp, characters[num] ) ) {
+ strings++;
+ goto get_more;
+ }
+ len = strlen(cp );
+ if (characters[num] == default_chars[num] )
+ p_new = (char * ) kmalloc (sizeof (char ) * len+1, GFP_KERNEL );
+ else if ( strlen(characters[num] ) >= len )
+ p_new = characters[num];
+ else {
+ kfree(characters[num] );
+ characters[num] = default_chars[num];
+ p_new = (char * ) kmalloc (sizeof (char ) * len+1, GFP_KERNEL );
+ }
+ if (!p_new ) return -ENOMEM;
+ strcpy ( p_new, cp );
+ characters[num] = p_new;
+ updates++;
+ strings++;
+ if (i < count ) goto get_more;
+ chars_stop_timer ( );
+ init_timer (&chars_timer );
+ chars_timer.function = show_char_results;
+ chars_timer.expires = jiffies + 5;
+ start_timer (chars_timer );
+ chars_timer_active++;
+ return count;
+}
+
+static int
+bits_read_proc (PROC_READ_PROTOTYPE )
+{
+ int i;
+ var_header *p_header = (var_header * )data;
+ proc_var *var = p_header->data;
+ bits_data *pb = &punc_info[var->value];
+ short mask = pb->mask;
+ char *cp = page;
+ *start = 0;
+ *eof = 1;
+ for ( i = 33; i < 128; i++ ) {
+ if ( !(spk_chartab[i]&mask ) ) continue;
+ *cp++ = (char )i;
+ }
+ *cp++ = '\n';
+ return cp-page;
+}
+
+/* set_mask_bits sets or clears the punc/delim/repeat bits,
+ * if input is null uses the defaults.
+ * values for how: 0 clears bits of chars supplied,
+ * 1 clears allk, 2 sets bits for chars */
+
+int
+set_mask_bits( const char *input, const int which, const int how )
+{
+ u_char *cp;
+ short mask = punc_info[which].mask;
+ if ( how&1 ) {
+ for ( cp = (u_char * )punc_info[3].value; *cp; cp++ )
+ spk_chartab[*cp] &= ~mask;
+ }
+ cp = (u_char * )input;
+ if ( cp == 0 ) cp = punc_info[which].value;
+ else {
+ for ( ; *cp; cp++ ) {
+ if ( *cp < SPACE ) break;
+ if ( mask < PUNC ) {
+ if ( !(spk_chartab[*cp]&PUNC) ) break;
+ } else if ( (spk_chartab[*cp]&B_NUM) ) break;
+ }
+ if ( *cp ) return -EINVAL;
+ cp = (u_char * )input;
+ }
+ if ( how&2 ) {
+ for ( ; *cp; cp++ )
+ if ( *cp > SPACE ) spk_chartab[*cp] |= mask;
+ } else {
+ for ( ; *cp; cp++ )
+ if ( *cp > SPACE ) spk_chartab[*cp] &= ~mask;
+ }
+ return 0;
+}
+
+static bits_data *pb_edit = NULL;
+
+static int edit_bits (int currcons, u_char type, u_char ch, u_short key )
+{
+ short mask = pb_edit->mask, ch_type = spk_chartab[ch];
+ if ( type != KT_LATIN || (ch_type&B_NUM ) || ch < SPACE ) return -1;
+ if ( ch == SPACE ) {
+ synth_write_msg( "edit done" );
+ special_handler = NULL;
+ return 1;
+ }
+ if ( mask < PUNC && !(ch_type&PUNC) ) return -1;
+ spk_chartab[ch] ^= mask;
+ speak_char( ch );
+ synth_write_msg( (spk_chartab[ch]&mask ) ? " on" : " off" );
+ return 1;
+}
+
+static int
+bits_write_proc (PROC_WRITE_PROTOTYPE )
+{
+ var_header *p_header = (var_header * )data;
+ proc_var *var = p_header->data;
+ int ret = count;
+ char punc_buf[100];
+ if (count < 1 || count > 99 )
+ return -EINVAL;
+ if (copy_from_user (punc_buf, buffer, count ) )
+ return -EFAULT;
+ if (punc_buf[count - 1] == '\n' )
+ count--;
+ punc_buf[count] = '\0';
+ if ( *punc_buf == 'd' || *punc_buf == 'r' )
+ count = set_mask_bits( 0, var->value, 3 );
+ else
+ count = set_mask_bits( punc_buf, var->value, 3 );
+ if ( count < 0 ) return count;
+ return ret;
+}
+
+// this is the read handler for /proc/speakup/synth
+static int
+synth_read_proc (PROC_READ_PROTOTYPE )
+{
+ int len;
+ if ( synth == NULL ) strcpy( synth_name, "none" );
+ else strcpy( synth_name, synth->name );
+ len = sprintf (page, "%s\n", synth_name );
+ *start = 0;
+ *eof = 1;
+ return len;
+}
+
+// this is the write handler for /proc/speakup/synth
+static int
+synth_write_proc (PROC_WRITE_PROTOTYPE )
+{
+ int ret = count;
+ char new_synth_name[10];
+ const char *old_name = ( synth != NULL ) ? synth->name : "none";
+ if (count < 2 || count > 9 )
+ return -EINVAL;
+ if (copy_from_user (new_synth_name, buffer, count ) )
+ return -EFAULT;
+ if (new_synth_name[count - 1] == '\n' )
+ count--;
+ new_synth_name[count] = '\0';
+ strlwr (new_synth_name );
+ if (!strcmp (new_synth_name, old_name ) ) {
+ pr_warn ( "%s already in use\n", new_synth_name );
+ return ret;
+ }
+ if ( synth_init( new_synth_name ) == 0 ) return ret;
+ pr_warn( "failed to init synth %s\n", new_synth_name );
+ return -ENODEV;
+}
+
+proc_var spk_proc_vars[] = {
+ { VERSION, version_read_proc, 0, 0 },
+ { SILENT, 0, silent_write_proc, 0 },
+ { CHARS, chars_read_proc, chars_write_proc, 0 },
+ { SYNTH, synth_read_proc, synth_write_proc, 0 },
+ { KEYMAP, keys_read_proc, keys_write_proc, 0 },
+ { PUNC_SOME, bits_read_proc, bits_write_proc, 1 },
+ { PUNC_MOST, bits_read_proc, bits_write_proc, 2 },
+ { PUNC_ALL, bits_read_proc, 0, 3 },
+ { DELIM, bits_read_proc, bits_write_proc, 4 },
+ { REPEATS, bits_read_proc, bits_write_proc, 5 },
+ { EXNUMBER, bits_read_proc, bits_write_proc, 6 },
+ { -1, 0, 0, 0 }
+};
+
+#endif // CONFIG_PROC_FS
+
+#ifdef CONFIG_SPEAKUP
+
+void __init
+speakup_init (int currcons )
+{
+ spk_t *first_console = (spk_t *) alloc_bootmem (spk_size+1 );
+ speakup_open( currcons, first_console );
+}
+
+#endif
+
+void
+speakup_allocate (int currcons )
+{
+ if ( speakup_console[currcons] == NULL ) {
+ speakup_console[currcons] = (spk_t *) kmalloc (spk_size + 1,
+ GFP_KERNEL );
+ if ( speakup_console[currcons] == NULL ) return;
+ memset( speakup_console[currcons], 0, spk_size );
+ speakup_date( currcons);
+ } else if ( !spk_parked ) speakup_date( currcons);
+}
+
+static void
+speakup_date (int currcons )
+{
+ spk_x = spk_cx = x;
+ spk_y = spk_cy = y;
+ spk_pos = spk_cp = pos;
+ spk_old_attr = spk_attr;
+ spk_attr = ((scr_readw ((u_short * ) spk_pos ) & 0xff00 ) >> 8 );
+}
+
+static u_char is_cursor = 0;
+static u_long old_cursor_pos, old_cursor_x, old_cursor_y;
+static int cursor_con;
+volatile int cursor_timer_active = 0;
+
+void
+cursor_stop_timer(void )
+{
+ if (!cursor_timer_active ) return;
+ stop_timer ( cursor_timer );
+ cursor_timer_active = 0;
+}
+
+static void
+handle_cursor( KBD_PROTO )
+{
+ int currcons = fg_console;
+ (*do_cursor)( KBD_ARGS );
+ spk_parked &= 0xfe;
+ if ( synth == NULL || up_flag || spk_shut_up || cursor_track == 0 )
+ return;
+ spk_shut_up &= 0xfe;
+ if ( no_intr ) do_flush( );
+/* the key press flushes if !no_inter but we want to flush on cursor
+ * moves regardless of no_inter state */
+ is_cursor = value+1;
+ old_cursor_pos = pos;
+ old_cursor_x = x;
+ old_cursor_y = y;
+ cursor_con = currcons;
+ cursor_stop_timer( );
+ cursor_timer.expires = jiffies + cursor_timeout;
+ start_timer (cursor_timer );
+ cursor_timer_active++;
+}
+
+static void
+cursor_done (u_long data )
+{
+ int currcons = cursor_con;
+ cursor_stop_timer( );
+ if (cursor_con != fg_console ) {
+ is_cursor = 0;
+ return;
+ }
+ speakup_date (currcons );
+ if ( win_enabled ) {
+ if ( x >= win_left && x <= win_right &&
+ y >= win_top && y <= win_bottom ) {
+ spk_keydown = is_cursor = 0;
+ return;
+ }
+ }
+ if ( is_cursor == 1 || is_cursor == 4 )
+ say_line_from_to (currcons, 0, video_num_columns, 0 );
+ else say_char ( currcons );
+ spk_keydown = is_cursor = 0;
+}
+
+/* These functions are the interface to speakup from the actual kernel code. */
+
+void
+speakup_bs (int currcons )
+{
+ if (!spk_parked )
+ speakup_date (currcons );
+ if ( spk_shut_up || synth == NULL ) return;
+ if ( currcons == fg_console && spk_keydown ) {
+ spk_keydown = 0;
+ if (!is_cursor ) say_char (currcons );
+ }
+}
+
+void
+speakup_con_write (int currcons, const char *str, int len )
+{
+ if (spk_shut_up || (currcons != fg_console ) )
+ return;
+ if (bell_pos && spk_keydown && (x == bell_pos - 1 ) )
+ bleep(3 );
+ if (synth == NULL || is_cursor ) return;
+ if ( win_enabled ) {
+ if ( x >= win_left && x <= win_right &&
+ y >= win_top && y <= win_bottom ) return;
+ }
+ spkup_write (str, len );
+}
+
+void
+speakup_con_update (int currcons )
+{
+ if ( speakup_console[currcons] == NULL || spk_parked )
+ return;
+ speakup_date (currcons );
+}
+
+static void
+handle_spec( KBD_PROTO )
+{
+ int currcons = fg_console, on_off = 2;
+ char *label;
+static const char *lock_status[] = { " off", " on", "" };
+ (*do_spec)( KBD_ARGS );
+ if ( synth == NULL || up_flag || spk_killed ) return;
+ spk_shut_up &= 0xfe;
+ if ( no_intr ) do_flush( );
+ switch (value ) {
+ case KVAL( K_CAPS ):
+ label = "caps lock";
+ on_off = (vc_kbd_led(kbd , VC_CAPSLOCK ) );
+ break;
+ case KVAL( K_NUM ):
+ label = "num lock";
+ on_off = (vc_kbd_led(kbd , VC_NUMLOCK ) );
+ break;
+ case KVAL( K_HOLD ):
+ label = "scroll lock";
+ on_off = (vc_kbd_led(kbd , VC_SCROLLOCK ) );
+ break;
+ default:
+ spk_parked &= 0xfe;
+ return;
+ }
+ synth_write_string ( label );
+ synth_write_msg ( lock_status[on_off] );
+}
+
+static int
+inc_dec_var( u_char value )
+{
+ var_header *p_header;
+ num_var *var_data;
+ char num_buf[32];
+ char *cp = num_buf, *pn;
+ int var_id = (int)value - VAR_START;
+ int how = (var_id&1) ? E_INC : E_DEC;
+ var_id = var_id/2+FIRST_SET_VAR;
+ p_header = get_var_header( var_id );
+ if ( p_header == NULL ) return -1;
+ if ( p_header->var_type != VAR_NUM ) return -1;
+ var_data = p_header->data;
+ if ( set_num_var( 1, p_header, how ) != 0 )
+ return -1;
+ if ( !spk_close_press ) {
+ for ( pn = p_header->name; *pn; pn++ ) {
+ if ( *pn == '_' ) *cp = SPACE;
+ else *cp++ = *pn;
+ }
+ }
+ sprintf( cp, " %d ", (int)var_data->value );
+ synth_write_string( num_buf );
+ return 0;
+}
+
+static void
+speakup_win_set (int currcons )
+{
+ char info[40];
+ if ( win_start > 1 ) {
+ synth_write_msg( "window already set, clear then reset" );
+ return;
+ }
+ if ( spk_x < win_left || spk_y < win_top ) {
+ synth_write_msg( "error end before start" );
+ return;
+ }
+ if ( win_start && spk_x == win_left && spk_y == win_top ) {
+ win_left = 0;
+ win_right = video_num_columns-1;
+ win_bottom = spk_y;
+ sprintf( info, "window is line %d", (int)win_top+1 );
+ } else {
+ if ( !win_start ) {
+ win_top = spk_y;
+ win_left = spk_x;
+ } else {
+ win_bottom = spk_y;
+ win_right = spk_x;
+ }
+ sprintf( info, "%s at line %d, column %d",
+ (win_start) ? "end" : "start",
+ (int)spk_y+1, (int)spk_x+1 );
+ }
+ synth_write_msg( info );
+ win_start++;
+}
+
+static void
+speakup_win_clear (int currcons )
+{
+ win_top = win_bottom = 0;
+ win_left = win_right = 0;
+ win_start = 0;
+ synth_write_msg( "window cleared" );
+}
+
+static void
+speakup_win_enable (int currcons )
+{
+ if ( win_start < 2 ) {
+ synth_write_msg( "no window" );
+ return;
+ }
+ win_enabled ^= 1;
+ if ( win_enabled ) synth_write_msg( "window silenced" );
+ else synth_write_msg( "window silence disabled" );
+}
+
+static void
+speakup_bits (int currcons )
+{
+ int val = this_speakup_key - ( FIRST_EDIT_BITS - 1 );
+ if ( special_handler != NULL || val < 1 || val > 6 ) {
+ synth_write_msg( "error" );
+ return;
+ }
+ pb_edit = &punc_info[val];
+ sprintf( buf, "edit %s, press space when done", pb_edit->name );
+ synth_write_msg( buf );
+ special_handler = edit_bits;
+}
+
+static int handle_goto (int currcons, u_char type, u_char ch, u_short key )
+{
+ static u_char *goto_buf = "\0\0\0\0\0\0";
+ static int num = 0;
+ short maxlen, go_pos;
+ char *cp;
+ if ( type == KT_SPKUP && ch == SPEAKUP_GOTO ) goto do_goto;
+ if ( type == KT_LATIN && ch == '\n' ) goto do_goto;
+ if ( type != 0 ) goto oops;
+ if (ch == 8 ) {
+ if ( num == 0 ) return -1;
+ ch = goto_buf[--num];
+ goto_buf[num] = '\0';
+ spkup_write( &ch, 1 );
+ return 1;
+}
+ if ( ch < '+' || ch > 'y' ) goto oops;
+ goto_buf[num++] = ch;
+ goto_buf[num] = '\0';
+ spkup_write( &ch, 1 );
+ maxlen = ( *goto_buf >= '0' ) ? 3 : 4;
+ if ((ch == '+' || ch == '-' ) && num == 1 ) return 1;
+ if (ch >= '0' && ch <= '9' && num < maxlen ) return 1;
+ if ( num < maxlen-1 || num > maxlen ) goto oops;
+ if ( ch < 'x' || ch > 'y' ) {
+oops:
+ if (!spk_killed )
+ synth_write_msg (" goto canceled" );
+ goto_buf[num = 0] = '\0';
+ special_handler = NULL;
+ return 1;
+ }
+ cp = speakup_s2i (goto_buf, &go_pos );
+ goto_pos = (u_long)go_pos;
+ if (*cp == 'x' ) {
+ if (*goto_buf < '0' ) goto_pos += spk_x;
+ else goto_pos--;
+ if (goto_pos < 0 ) goto_pos = 0;
+ if (goto_pos >= video_num_columns )
+ goto_pos = video_num_columns-1;
+ goto_x = 1;
+ } else {
+ if (*goto_buf < '0' ) goto_pos += spk_y;
+ else goto_pos--;
+ if (goto_pos < 0 ) goto_pos = 0;
+ if (goto_pos >= video_num_lines ) goto_pos = video_num_lines-1;
+ goto_x = 0;
+ }
+ goto_buf[num = 0] = '\0';
+do_goto:
+ special_handler = NULL;
+ spk_parked |= 0x01;
+ if ( goto_x ) {
+ spk_pos -= spk_x * 2;
+ spk_x = goto_pos;
+ spk_pos += goto_pos * 2;
+ say_word( currcons );
+ } else {
+ spk_y = goto_pos;
+ spk_pos = origin + ( goto_pos * video_size_row );
+ say_line( currcons );
+ }
+ return 1;
+}
+
+static void
+speakup_goto (int currcons )
+{
+ if ( special_handler != NULL ) {
+ synth_write_msg( "error" );
+ return;
+ }
+ synth_write_msg( "go to?" );
+ special_handler = handle_goto;
+ return;
+}
+
+static void
+load_help ( void *dummy )
+{
+ request_module( "speakup_keyhelp" );
+ if ( help_handler ) {
+ (*help_handler)(0, KT_SPKUP, SPEAKUP_HELP, 0 );
+ } else synth_write_string( "help module not found" );
+}
+
+#if (LINUX_VERSION_CODE >= 132419)
+static DECLARE_WORK(ld_help, load_help, NULL);
+#define schedule_help schedule_work
+#else
+static struct tq_struct ld_help = { routine: load_help, };
+#define schedule_help schedule_task
+#endif
+
+static void
+speakup_help (int currcons )
+{
+ if ( help_handler == NULL ) {
+/* we can't call request_module from this context so schedule it*/
+/* **** note kernel hangs and my wrath will be on you */
+ schedule_help (&ld_help);
+ return;
+ }
+ (*help_handler)(currcons, KT_SPKUP, SPEAKUP_HELP, 0 );
+}
+
+static void
+do_nothing (int currcons )
+{
+ return; /* flush done in do_spkup */
+}
+static u_char key_speakup = 0, spk_key_locked = 0;
+
+static void
+speakup_lock (int currcons )
+{
+ if ( !spk_key_locked )
+ spk_key_locked = key_speakup = 16;
+ else spk_key_locked = key_speakup = 0;
+}
+
+typedef void (*spkup_hand )(int );
+spkup_hand spkup_handler[] = { /* must be ordered same as defines in speakup.h */
+ do_nothing, speakup_goto, speech_kill, speakup_shut_up,
+ speakup_cut, speakup_paste, say_first_char, say_last_char,
+ say_char, say_prev_char, say_next_char,
+ say_word, say_prev_word, say_next_word,
+ say_line, say_prev_line, say_next_line,
+ top_edge, bottom_edge, left_edge, right_edge,
+ spell_word, spell_word, say_screen,
+ say_position, say_attributes,
+ speakup_off, speakup_parked, say_line, // this is for indent
+ say_from_top, say_to_bottom,
+ say_from_left, say_to_right,
+ say_char_num, speakup_bits, speakup_bits, say_phonetic_char,
+ speakup_bits, speakup_bits, speakup_bits,
+ speakup_win_set, speakup_win_clear, speakup_win_enable, speakup_win_say,
+ speakup_lock, speakup_help, toggle_cursoring, NULL
+};
+
+void do_spkup( int currcons,u_char value )
+{
+ if (spk_killed && value != SPEECH_KILL ) return;
+ spk_keydown = 0;
+ spk_lastkey = 0;
+ spk_shut_up &= 0xfe;
+ this_speakup_key = value;
+ if (value < SPKUP_MAX_FUNC && spkup_handler[value] ) {
+ do_flush( );
+ (*spkup_handler[value] )(currcons );
+ } else {
+ if ( inc_dec_var( value ) < 0 )
+ bleep( 9 );
+ }
+}
+
+ static const char *pad_chars = "0123456789+-*/\015,.?()";
+
+int
+#if (LINUX_VERSION_CODE < 132419)
+speakup_key ( int shift_state, u_char keycode, u_short keysym, u_char up_flag )
+#else
+speakup_key (struct vc_data *vc, int shift_state, int keycode, u_short keysym, int up_flag, struct pt_regs *regs )
+#endif
+{
+ int currcons = fg_console;
+ u_char *key_info;
+ u_char type = KTYP( keysym ), value = KVAL( keysym ), new_key = 0;
+ u_char shift_info, offset;
+#if (LINUX_VERSION_CODE >= 132419)
+ tty = vc_cons[currcons].d->vc_tty;
+#endif
+ if ( synth == NULL ) return 0;
+ if ( type >= 0xf0 ) type -= 0xf0;
+ if ( type == KT_PAD && (vc_kbd_led(kbd , VC_NUMLOCK ) ) ) {
+ if ( up_flag ) {
+ spk_keydown = 0;
+ return 0;
+ }
+ value = spk_lastkey = pad_chars[value];
+ spk_keydown++;
+ spk_parked &= 0xfe;
+ goto no_map;
+ }
+ if ( keycode >= MAX_KEY ) goto no_map;
+ if ( ( key_info = our_keys[keycode] ) == 0 ) goto no_map;
+ shift_info = ( shift_state&0x0f ) + key_speakup;
+ offset = shift_table[shift_info];
+ if ( offset && ( new_key = key_info[offset] ) ) {
+ if ( new_key == SPK_KEY ) {
+ if ( !spk_key_locked )
+ key_speakup = ( up_flag ) ? 0 : 16;
+ if ( up_flag || spk_killed ) return 1;
+ spk_shut_up &= 0xfe;
+ do_flush( );
+ return 1;
+ }
+ if ( up_flag ) return 1;
+ if ( last_keycode == keycode && last_spk_jiffy+MAX_DELAY > jiffies ) {
+ spk_close_press = 1;
+ offset = shift_table[shift_info+32];
+/* double press? */
+ if ( offset && key_info[offset] )
+ new_key = key_info[offset];
+ }
+ last_keycode = keycode;
+ last_spk_jiffy = jiffies;
+ type = KT_SPKUP;
+ value = new_key;
+ }
+no_map:
+ if ( type == KT_SPKUP && special_handler == NULL ) {
+ do_spkup( currcons, new_key );
+ spk_close_press = 0;
+ return 1;
+ }
+ if ( up_flag || spk_killed || type == KT_SHIFT ) return 0;
+ spk_shut_up &= 0xfe;
+ if (!no_intr ) do_flush( );
+ if ( special_handler ) {
+ int status;
+ if ( type == KT_SPEC && value == 1 ) {
+ value = '\n';
+ type = KT_LATIN;
+ } else if ( type == KT_LETTER ) type = KT_LATIN;
+ else if ( value == 0x7f ) value = 8; /* make del = backspace */
+ status = (*special_handler)(currcons, type, value, keycode );
+ spk_close_press = 0;
+ if ( status < 0 ) bleep( 9 );
+ return status;
+ }
+ last_keycode = 0;
+ return 0;
+}
+
+#ifdef MODULE
+
+extern void proc_speakup_init( void );
+extern void proc_speakup_remove( void );
+extern void speakup_set_addresses ( spk_con_func, spk_con_func, spk_write_func, spk_con_func, spk_key_func);
+
+static void __exit mod_speakup_exit( void )
+{
+ int i;
+ key_handler[KT_LATIN] = do_latin;
+ key_handler[KT_SPEC] = do_spec;
+ key_handler[KT_CUR] = do_cursor;
+ key_handler[KT_SHIFT] = do_shift;
+ speakup_set_addresses( NULL, NULL, NULL, NULL, NULL );
+ synth_release( );
+ proc_speakup_remove( );
+ for (i = 0; i < 256; i++ ) {
+ if (characters[i] != default_chars[i] )
+ kfree (characters[i] );
+ }
+ for ( i = 0; speakup_console[i]; i++) {
+ kfree( speakup_console[i] );
+ speakup_console[i] = NULL;
+ }
+}
+
+static int __init mod_speakup_init( void )
+{
+int i;
+ spk_t *first_console = (spk_t *) kmalloc (spk_size + 1, GFP_KERNEL );
+ speakup_open( fg_console, first_console );
+for ( i = 0; vc_cons[i].d; i++)
+ speakup_allocate(i);
+ speakup_set_addresses( speakup_allocate, speakup_bs,
+ speakup_con_write, speakup_con_update, speakup_key );
+ proc_speakup_init( );
+ return 0;
+}
+
+module_init( mod_speakup_init );
+module_exit( mod_speakup_exit );
+
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_acnt.h linux-2.4.30/drivers/char/speakup/speakup_acnt.h
--- linux-2.4.30.orig/drivers/char/speakup/speakup_acnt.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_acnt.h 2003-04-14 11:37:18.000000000 -0700
@@ -0,0 +1,16 @@
+/* speakup_acntpc.h - header file for speakups Accent-PC driver. */
+
+#define SYNTH_IO_EXTENT 0x02
+
+#define SYNTH_CLEAR 0x18 /* stops speech */
+
+ /* Port Status Flags */
+#define SYNTH_READABLE 0x01 /* mask for bit which is nonzero if a
+ byte can be read from the data port */
+#define SYNTH_WRITABLE 0x02 /* mask for RDY bit, which when set to
+ 1, indicates the data port is ready
+ to accept a byte of data. */
+#define SYNTH_QUIET 'S' /* synth is not speaking */
+#define SYNTH_FULL 'F' /* synth is full. */
+#define SYNTH_ALMOST_EMPTY 'M' /* synth has les than 2 seconds of text left */
+#define SYNTH_SPEAKING 's' /* synth is speaking and has a fare way to go */
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_acntpc.c linux-2.4.30/drivers/char/speakup/speakup_acntpc.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_acntpc.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_acntpc.c 2003-10-07 18:04:35.000000000 -0700
@@ -0,0 +1,160 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "speakup_acnt.h" /* local header file for Accent values */
+
+#define MY_SYNTH synth_acntpc
+#define synth_readable( ) ( inb_p( synth_port_control ) & SYNTH_READABLE )
+#define synth_writable( ) ( inb_p( synth_port_control ) & SYNTH_WRITABLE )
+#define synth_full( ) ( inb_p( synth_port_tts ) == 'F' )
+#define PROCSPEECH '\r'
+
+
+static int synth_port_control;
+static unsigned int synth_portlist[] =
+ { 0x2a8, 0 };
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( synth_full( ) )
+ return buf;
+ while ( synth_writable( ) );
+ outb_p( ch, synth_port_tts );
+ buf++;
+ }
+ return 0;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+ synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ if ( synth_full( ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ while ( synth_writable( ) );
+ ch = *synth_buff_out++;
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ outb_p( ch, synth_port_tts );
+ if ( jiffies >= jiff_max && ch == SPACE ) {
+ while ( synth_writable( ) );
+ outb_p( PROCSPEECH, synth_port_tts );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ while ( synth_writable( ) );
+ outb_p( PROCSPEECH, synth_port_tts );
+ synth_done( );
+}
+
+static void synth_flush( void )
+{
+ outb_p( SYNTH_CLEAR, synth_port_tts );
+}
+
+static int synth_probe( void )
+{
+ unsigned int port_val = 0;
+ int i = 0;
+ pr_info( "Probing for %s.\n", synth->long_name );
+ if ( synth_port_forced ) {
+ synth_port_tts = synth_port_forced;
+ pr_info( "probe forced to %x by kernel command line\n", synth_port_tts );
+ if ( synth_request_region( synth_port_tts-1, SYNTH_IO_EXTENT ) ) {
+ pr_warn( "sorry, port already reserved\n" );
+ return -EBUSY;
+ }
+ port_val = inw( synth_port_tts-1 );
+ synth_port_control = synth_port_tts-1;
+ } else {
+ for( i=0; synth_portlist[i]; i++ ) {
+ if ( synth_request_region( synth_portlist[i], SYNTH_IO_EXTENT ) ) {
+ pr_warn( "request_region: failed with 0x%x, %d\n",
+ synth_portlist[i], SYNTH_IO_EXTENT );
+ continue;
+ }
+ port_val = inw( synth_portlist[i] );
+ if ( ( port_val &= 0xfffc ) == 0x53fc ) { /* 'S' and out&input bits */
+ synth_port_control = synth_portlist[i];
+ synth_port_tts = synth_port_control+1;
+ break;
+ }
+ }
+ }
+ if ( ( port_val &= 0xfffc ) != 0x53fc ) { /* 'S' and out&input bits */
+ pr_info( "%s: not found\n", synth->long_name );
+ synth_release_region( synth_portlist[i], SYNTH_IO_EXTENT );
+ synth_port_control = 0;
+ return -ENODEV;
+ }
+ pr_info( "%s: %03x-%03x, driver version %s,\n", synth->long_name,
+ synth_port_control, synth_port_control+SYNTH_IO_EXTENT-1,
+ synth->version );
+ return 0;
+}
+
+static void accent_release( void )
+{
+ if ( synth_port_tts )
+ synth_release_region( synth_port_tts-1, SYNTH_IO_EXTENT );
+ synth_port_tts = 0;
+}
+
+static int synth_is_alive( void )
+{
+ synth_alive = 1;
+ return 1;
+}
+
+static const char init_string[] = "\033=X \033Oi\033T2\033=M\033N1\n";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\033P8" },
+ { CAPS_STOP, "\033P5" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" },
+ { PITCH, "\033P%d", 5, 0, 9, 0, 0, 0 },
+ { VOL, "\033A%d", 5, 0, 9, 0, 0, 0 },
+ { TONE, "\033V%d", 5, 0, 9, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_acntpc = {"acntpc", "1.1", "Accent PC",
+ init_string, 500, 50, 50, 1000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, accent_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL };
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_acntsa.c linux-2.4.30/drivers/char/speakup/speakup_acntsa.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_acntsa.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_acntsa.c 2003-11-06 11:00:59.000000000 -0800
@@ -0,0 +1,184 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+#include "speakup_acnt.h" /* local header file for Accent values */
+
+#define MY_SYNTH synth_acntsa
+#define synth_full( ) ( inb_p( synth_port_tts ) == 'F' )
+#define PROCSPEECH '\r'
+
+static int timeouts = 0; /* sequential number of timeouts */
+
+static int
+wait_for_xmitr ( void )
+{
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
+ synth_alive = 0;
+ return 0;
+ }
+ do { /* holding register empty? */
+ check = inb_p ( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn ( "%s: timed out\n", synth->long_name );
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
+ tmout = SPK_XMITR_TIMEOUT;
+ do { /* CTS */
+ check = inb_p ( synth_port_tts + UART_MSR );
+ if ( --tmout == 0 ) {
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
+ timeouts = 0;
+ return 1;
+}
+
+static inline int
+spk_serial_out ( const char ch )
+{
+ if ( synth_alive && wait_for_xmitr ( ) ) {
+ outb_p ( ch, synth_port_tts );
+ return 1;
+ }
+ return 0;
+}
+
+static void
+do_catch_up ( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+ synth_stop_timer ( );
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( ch == 0x0a ) ch = 0x0D;
+ if ( !spk_serial_out ( ch ) ) {
+ synth_delay ( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( jiffies >= jiff_max && ch == ' ' ) {
+ spk_serial_out ( PROCSPEECH );
+ synth_delay ( synth_delay_time );
+ return;
+ }
+ }
+ spk_serial_out ( PROCSPEECH );
+ synth_done( );
+}
+
+static char *synth_immediate ( char *buff )
+{
+ u_char ch;
+ while ( ( ch = *buff ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buff;
+ buff++;
+ }
+ return 0;
+}
+
+static void synth_flush ( void )
+{
+ spk_serial_out ( SYNTH_CLEAR );
+}
+
+static int serprobe ( int index )
+{
+ struct serial_state *ser = spk_serial_init( index );
+ if ( ser == NULL ) return -1;
+ outb ( 0x0d, ser->port );
+ // mdelay ( 1 );
+ /* ignore any error results, if port was forced */
+ if ( synth_port_forced ) return 0;
+ /* check for accent s.a now... */
+ if ( !synth_immediate( "\x18" ) )
+ return 0;
+ spk_serial_release( );
+ timeouts = synth_alive = 0; /* not ignoring */
+ return -1;
+}
+
+static int synth_probe ( void )
+{
+ int i = 0, failed=0;
+ pr_info ( "Probing for %s.\n", synth->long_name );
+ for ( i = SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info ( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ pr_info ( "%s: %03x-%03x, Driver Version %s,\n", synth->long_name,
+ synth_port_tts, synth_port_tts + 7, synth->version );
+ synth_immediate( "\033=R\r" );
+ mdelay( 100 );
+ return 0;
+}
+
+static int
+synth_is_alive ( void )
+{
+ if ( synth_alive ) return 1;
+ if ( !synth_alive && wait_for_xmitr ( ) > 0 ) { /* restart */
+ synth_alive = 1;
+ synth_write_string ( synth->init );
+ return 2;
+ }
+ pr_warn ( "%s: can't restart synth\n", synth->long_name );
+ return 0;
+}
+
+static const char init_string[] = "\033T2\033=M\033Oi\033N1\n";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\033P8" },
+ { CAPS_STOP, "\033P5" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" },
+ { PITCH, "\033P%d", 5, 0, 9, 0, 0, 0 },
+ { VOL, "\033A%d", 9, 0, 9, 0, 0, 0 },
+ { TONE, "\033V%d", 5, 0, 9, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_acntsa = { "acntsa", "1.1", "Accent-SA",
+ init_string, 400, 5, 30, 1000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_apollo.c linux-2.4.30/drivers/char/speakup/speakup_apollo.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_apollo.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_apollo.c 2004-03-06 07:55:29.000000000 -0800
@@ -0,0 +1,195 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+
+#define MY_SYNTH synth_apollo
+#define SYNTH_CLEAR 0x18
+#define PROCSPEECH '\r'
+
+static int timeouts = 0; /* sequential number of timeouts */
+
+static int wait_for_xmitr( void )
+{
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
+ synth_alive = 0;
+ timeouts = 0;
+ return 0;
+ }
+ do {
+ check = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn( "APOLLO: timed out\n" );
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
+ tmout = SPK_XMITR_TIMEOUT;
+ do {
+ check = inb( synth_port_tts + UART_MSR );
+ if ( --tmout == 0 ) {
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
+ timeouts = 0;
+ return 1;
+}
+
+static inline int spk_serial_out( const char ch )
+{
+ // int timer = 9000000;
+ if ( synth_alive && wait_for_xmitr( ) ) {
+ outb( ch, synth_port_tts );
+ /*while ( inb( synth_port_tts+UART_MSR ) & UART_MSR_CTS ) if ( --timer == 0 ) break;*/
+ /* outb( UART_MCR_DTR, synth_port_tts + UART_MCR );*/
+ return 1;
+ }
+ return 0;
+}
+
+/*
+static unsigned char spk_serial_in( void )
+{
+ int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
+ do {
+ lsr = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) return 0xff;
+ } while ( !( lsr & UART_LSR_DR ) );
+ c = inb( synth_port_tts + UART_RX );
+ return ( unsigned char ) c;
+}
+*/
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( !spk_serial_out( ch ) ) {
+ outb( UART_MCR_DTR, synth_port_tts + UART_MCR );
+ outb( UART_MCR_DTR | UART_MCR_RTS, synth_port_tts + UART_MCR );
+ synth_delay( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( jiffies >= jiff_max && synth_buff_out-synth_buffer > 10 ) {
+ spk_serial_out( PROCSPEECH );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ spk_serial_out( PROCSPEECH );
+ synth_done( );
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush ( void )
+{
+ spk_serial_out ( SYNTH_CLEAR );
+}
+
+static int serprobe( int index )
+{
+ struct serial_state *ser = spk_serial_init( index );
+ if ( ser == NULL ) return -1;
+ outb( 0x0d, ser->port ); /* wake it up if older BIOS */
+ mdelay( 1 );
+ synth_port_tts = ser->port;
+ if ( synth_port_forced ) return 0;
+ /* check for apollo now... */
+ if ( !synth_immediate( "\x18" ) ) return 0;
+ pr_warn( "port %x failed\n", synth_port_tts );
+ spk_serial_release( );
+ timeouts = synth_alive = synth_port_tts = 0;
+ return -1;
+}
+
+static int synth_probe( void )
+{
+int i, failed=0;
+ pr_info( "Probing for %s.\n", synth->long_name );
+ for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ pr_info( "%s: %03x-%03x, Driver version %s,\n", synth->long_name,
+ synth_port_tts, synth_port_tts + 7, synth->version );
+ return 0;
+}
+
+static int synth_is_alive( void )
+{
+ if ( synth_alive ) return 1;
+ if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
+ synth_alive = 1;
+ synth_write_string( synth->init );
+ return 2; /* reenabled */
+ } else pr_warn( "%s: can't restart synth\n", synth->long_name );
+ return 0;
+}
+
+static const char init_string[] = "@R3@D0@K1\r";
+
+static string_var stringvars[] = {
+ { CAPS_START, "cap, " },
+ { CAPS_STOP, "" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "@W%d", 6, 1, 9, 0, 0, 0 },
+ { PITCH, "@F%x", 10, 0, 15, 0, 0, 0 },
+ { VOL, "@A%x", 10, 0, 15, 0, 0, 0 },
+ { VOICE, "@V%d", 1, 1, 6, 0, 0, 0 },
+ { LANG, "@=%d,", 1, 1, 4, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_apollo = {"apollo", "1.2", "Apollo",
+ init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_audptr.c linux-2.4.30/drivers/char/speakup/speakup_audptr.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_audptr.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_audptr.c 2003-10-07 18:04:35.000000000 -0700
@@ -0,0 +1,201 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+
+#define MY_SYNTH synth_audptr
+#define SYNTH_CLEAR 0x18 /* flush synth buffer */
+#define PROCSPEECH '\r' /* start synth processing speech char */
+
+static int timeouts = 0; /* sequential number of timeouts */
+
+static int wait_for_xmitr( void )
+{
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
+ synth_alive = 0;
+ timeouts = 0;
+ return 0;
+ }
+ do { /* holding register empty? */
+ check = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn( "%s: timed out\n", synth->long_name );
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
+ tmout = SPK_XMITR_TIMEOUT;
+ do { /* CTS */
+ check = inb( synth_port_tts + UART_MSR );
+ if ( --tmout == 0 ) {
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
+ timeouts = 0;
+ return 1;
+}
+
+static inline int spk_serial_out( const char ch )
+{
+ if ( synth_alive && wait_for_xmitr( ) ) {
+ outb( ch, synth_port_tts );
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned char spk_serial_in( void )
+{
+ int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
+ do {
+ lsr = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) return 0xff;
+ } while ( !( lsr & UART_LSR_DR ) );
+ c = inb( synth_port_tts + UART_RX );
+ return ( unsigned char ) c;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( !spk_serial_out( ch ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( jiffies >= jiff_max && ch == SPACE ) {
+ spk_serial_out( PROCSPEECH );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ spk_serial_out( PROCSPEECH );
+ synth_done( );
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush( void )
+{
+ while ( ( inb( synth_port_tts + UART_LSR ) & BOTH_EMPTY ) != BOTH_EMPTY );
+ outb( SYNTH_CLEAR, synth_port_tts );
+ spk_serial_out( PROCSPEECH );
+ }
+
+static char synth_id[40] = "";
+
+static int serprobe( int index )
+{
+ u_char test = 0;
+ struct serial_state *ser = spk_serial_init( index );
+ if ( ser == NULL ) return -1;
+ /* ignore any error results, if port was forced */
+ if ( synth_port_forced )
+ return 0;
+ synth_immediate( "\x05[Q]" );
+ if ( ( synth_id[test] = spk_serial_in( ) ) == 'A' ) {
+ do { /* read version string from synth */
+ synth_id[++test] = spk_serial_in( );
+ } while ( synth_id[test] != '\n' && test < 32 );
+ synth_id[++test] = 0x00;
+ if ( test != 32 )
+ return 0;
+ }
+ spk_serial_release( );
+ timeouts = synth_alive = 0; /* not ignoring */
+ return -1;
+}
+
+static int synth_probe( void )
+{
+int i=0, failed=0;
+ pr_info( "Probing for %s.\n", synth->long_name );
+ for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ pr_info( "%s: %03x-%03x, Driver %s,\n", synth->long_name,
+ synth_port_tts, synth_port_tts + 7, synth->version );
+ if ( synth_id[0] == 'A' )
+ pr_info( "%s version: %s", synth->long_name, synth_id );
+ return 0;
+}
+
+static int synth_is_alive( void )
+{
+ if ( synth_alive ) return 1;
+ if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
+ synth_alive = 1;
+ synth_write_string( synth->init );
+ return 2;
+ }
+ return 0;
+}
+
+static const char init_string[] = "\x05[D1]\x05[Ol]";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\x05[f99]" },
+ { CAPS_STOP, "\x05[f80]" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\x05[r%d]", 10, 0, 20, -100, 10, 0 },
+ { PITCH, "\x05[f%d]", 80, 39, 4500, 0, 0, 0 },
+ { VOL, "\x05[g%d]", 21, 0, 40, 0, 0, 0 },
+ { TONE, "\x05[s%d]", 9, 0,63, 0, 0, 0 },
+ { PUNCT, "\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_audptr = {"audptr", "1.1", "Audapter",
+ init_string, 400, 5, 30, 5000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_bns.c linux-2.4.30/drivers/char/speakup/speakup_bns.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_bns.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_bns.c 2003-11-06 11:00:59.000000000 -0800
@@ -0,0 +1,174 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+
+#define MY_SYNTH synth_bns
+#define SYNTH_CLEAR 0x18
+#define PROCSPEECH '\r'
+
+static int wait_for_xmitr( void )
+{
+ static int timeouts = 0; /* sequential number of timeouts */
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
+ synth_alive = 0;
+ timeouts = 0;
+ return 0;
+ }
+ do {
+ check = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn( "BNS: timed out\n" );
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
+ tmout = SPK_XMITR_TIMEOUT;
+ do {
+ check = inb( synth_port_tts + UART_MSR );
+ if ( --tmout == 0 ) {
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
+ timeouts = 0;
+ return 1;
+}
+
+static inline int spk_serial_out( const char ch )
+{
+ if ( synth_alive && wait_for_xmitr( ) ) {
+ outb( ch, synth_port_tts );
+ return 1;
+ }
+ return 0;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+ synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( ch == '\n' ) ch = PROCSPEECH;
+ if ( !spk_serial_out( ch ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( jiffies >= jiff_max && ch == ' ' ) {
+ spk_serial_out( PROCSPEECH );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ spk_serial_out( PROCSPEECH );
+ synth_done( );
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush ( void )
+{
+ spk_serial_out ( SYNTH_CLEAR );
+}
+
+static int serprobe( int index )
+{
+ struct serial_state *ser = spk_serial_init( index );
+ if ( ser == NULL ) return -1;
+ outb( '\r', ser->port );
+ if ( synth_port_forced ) return 0;
+ /* check for bns now... */
+ if ( !synth_immediate( "\x18" ) ) return 0;
+ spk_serial_release( );
+ synth_alive = 0;
+ return -1;
+}
+
+static int synth_probe( void )
+{
+int i=0, failed=0;
+ pr_info( "Probing for %s.\n", synth->long_name );
+ for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ pr_info( "%s: %03x-%03x, Driver version %s,\n", synth->long_name,
+ synth_port_tts, synth_port_tts + 7, synth->version );
+ return 0;
+}
+
+static int synth_is_alive( void )
+{
+ if ( synth_alive ) return 1;
+ if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
+ synth_alive = 1;
+ synth_write_string( synth->init );
+ return 2;
+ }
+ pr_warn( "%s: can't restart synth\n", synth->long_name );
+ return 0;
+}
+
+static const char init_string[] = "\x05Z\x05\x43";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\x05\x31\x32P" },
+ { CAPS_STOP, "\x05\x38P" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\x05%dE", 8, 1, 16, 0, 0, 0 },
+ { PITCH, "\x05%dP", 8, 0, 16, 0, 0, 0 },
+ { VOL, "\x05%dV", 8, 0, 16, 0, 0, 0 },
+ { TONE, "\x05%dT", 8, 0, 16, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_bns = {"bns", "1.1", "Braille 'N Speak",
+ init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_decext.c linux-2.4.30/drivers/char/speakup/speakup_decext.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_decext.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_decext.c 2003-10-07 18:04:35.000000000 -0700
@@ -0,0 +1,205 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+
+#define MY_SYNTH synth_decext
+#define SYNTH_CLEAR 0x03
+#define PROCSPEECH 0x0b
+#define synth_full( ) ( inb_p( synth_port_tts ) == 0x13 )
+
+static int timeouts = 0;
+static int in_escape = 0;
+
+static int wait_for_xmitr ( void )
+{
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
+ synth_alive = 0;
+ timeouts = 0;
+ return 0;
+ }
+ do { /* holding register empty? */
+ check = inb_p( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn ( "%s: timed out\n", synth->long_name );
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
+ tmout = SPK_XMITR_TIMEOUT;
+ do { /* CTS */
+ check = inb_p ( synth_port_tts + UART_MSR );
+ if ( --tmout == 0 ) {
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
+ timeouts = 0;
+ return 1;
+}
+
+static inline int spk_serial_out ( const char ch )
+{
+ if ( synth_alive && wait_for_xmitr ( ) ) {
+ outb_p ( ch, synth_port_tts );
+ return 1;
+ }
+ return 0;
+}
+
+static u_char
+spk_serial_in ( void )
+{
+ int lsr, tmout = SPK_SERIAL_TIMEOUT, c;
+ do {
+ lsr = inb_p ( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 )
+ return 0xff;
+ } while ( !( lsr & UART_LSR_DR ) );
+ c = inb_p ( synth_port_tts + UART_RX );
+ return ( u_char ) c;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+static u_char last='\0';
+ synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( ch == '\n' ) ch = 0x0D;
+ if ( synth_full( ) || !spk_serial_out( ch ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( ch == '[' ) in_escape = 1;
+ else if ( ch == ']' ) in_escape = 0;
+ else if ( ch <= SPACE ) {
+ if ( !in_escape && strchr( ",.!?;:", last ) )
+ spk_serial_out( PROCSPEECH );
+ if ( jiffies >= jiff_max ) {
+ if ( !in_escape )
+ spk_serial_out( PROCSPEECH );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ last = ch;
+ }
+ if ( synth_done( ) || !in_escape )
+ spk_serial_out( PROCSPEECH );
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush( void )
+{
+ in_escape = 0;
+ synth_immediate( "\033P;10z\033\\" );
+}
+
+static int serprobe( int index )
+{
+ u_char test=0;
+ struct serial_state *ser = spk_serial_init( index );
+ if ( ser == NULL ) return -1;
+ /* ignore any error results, if port was forced */
+ if ( synth_port_forced )
+ return 0;
+ synth_immediate( "\033[;5n\033\\" );
+ if ( ( test = spk_serial_in( ) ) == '\033' )
+ return 0;
+ spk_serial_release( );
+ timeouts = synth_alive = synth_port_tts = 0; /* not ignoring */
+ return -1;
+}
+
+static int synth_probe( void )
+{
+ int i=0, failed=0;
+ pr_info( "Probing for %s.\n", synth->long_name );
+ /* check ttyS0-ttyS3 */
+ for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ pr_info( "%s: %03x-%03x, Driver Version %s,\n", synth->long_name,
+ synth_port_tts, synth_port_tts+7, synth->version );
+ return 0;
+}
+
+static int synth_is_alive( void )
+{
+ if ( synth_alive ) return 1;
+ if ( !synth_alive&& wait_for_xmitr( ) > 0 ) { /* restart */
+ synth_alive = 1;
+ synth_write_string( synth->init );
+ return 2;
+ }
+ pr_warn( "%s: can't restart synth\n", synth->long_name );
+ return 0;
+}
+
+static const char init_string[] = "[:pe -380]";
+
+static string_var stringvars[] = {
+ { CAPS_START, "[:dv ap 222]" },
+ { CAPS_STOP, "[:dv ap 100]" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "[:ra %d]", 7, 0, 9, 150, 25, 0 },
+ { PITCH, "[:dv ap %d]", 100, 0, 100, 0, 0, 0 },
+ { VOL, "[:dv gv %d]", 13, 0, 16, 0, 5, 0 },
+ { PUNCT, "[:pu %c]", 0, 0, 2, 0, 0, "nsa" },
+ { VOICE, "[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_decext = {"decext", "1.1", "Dectalk External",
+ init_string, 500, 50, 50, 1000, 0, SF_DEC, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_decpc.c linux-2.4.30/drivers/char/speakup/speakup_decpc.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_decpc.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_decpc.c 2003-10-28 08:15:27.000000000 -0800
@@ -0,0 +1,242 @@
+/*
+* written by David Borowski, david575@golden.net
+
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "dtpc_reg.h"
+
+#define MY_SYNTH synth_dec_pc
+#define PROCSPEECH 0x0b
+#define SYNTH_IO_EXTENT 8
+
+static int synth_portlist[] = { 0x340, 0x350, 0x240, 0x250, 0 };
+static int in_escape = 0, is_flushing = 0;
+static int dt_stat, dma_state = 0;
+
+static inline int dt_getstatus( void )
+{
+ dt_stat = inb_p( synth_port_tts )|(inb_p( synth_port_tts+1 )<<8);
+ return dt_stat;
+}
+
+static inline void dt_sendcmd( u_int cmd )
+{
+ outb_p( cmd & 0xFF, synth_port_tts );
+ outb_p( (cmd>>8) & 0xFF, synth_port_tts+1 );
+}
+
+static int dt_waitbit( int bit )
+{
+ int timeout = 100;
+ while ( --timeout > 0 ) {
+ if( (dt_getstatus( ) & bit ) == bit ) return 1;
+ udelay( 50 );
+ }
+ return 0;
+}
+
+static int dt_wait_dma( void )
+{
+ int timeout = 100, state = dma_state;
+ if( ! dt_waitbit( STAT_dma_ready ) ) return 0;
+ while ( --timeout > 0 ) {
+ if( (dt_getstatus()&STAT_dma_state) == state ) return 1;
+ udelay( 50 );
+ }
+ dma_state = dt_getstatus( ) & STAT_dma_state;
+ return 1;
+}
+
+int dt_ctrl( u_int cmd )
+{
+ int timeout = 10;
+ if ( !dt_waitbit( STAT_cmd_ready ) ) return -1;
+ outb_p( 0, synth_port_tts+2 );
+ outb_p( 0, synth_port_tts+3 );
+ dt_getstatus( );
+ dt_sendcmd( CMD_control|cmd );
+ outb_p( 0, synth_port_tts+6 );
+ while ( dt_getstatus( ) & STAT_cmd_ready ) {
+ udelay( 20 );
+ if ( --timeout == 0 ) break;
+ }
+ dt_sendcmd( CMD_null );
+ return 0;
+}
+
+static void synth_flush( void )
+{
+ int timeout = 10;
+ if ( is_flushing ) return;
+ is_flushing = 4;
+ in_escape = 0;
+ while ( dt_ctrl( CTRL_flush ) ) {
+ if ( --timeout == 0 ) break;
+udelay( 50 );
+ }
+ for ( timeout = 0; timeout < 10; timeout++ ) {
+ if ( dt_waitbit( STAT_dma_ready ) ) break;
+udelay( 50 );
+ }
+ outb_p( DMA_sync, synth_port_tts+4 );
+ outb_p( 0, synth_port_tts+4 );
+ udelay( 100 );
+ for ( timeout = 0; timeout < 10; timeout++ ) {
+ if ( !( dt_getstatus( ) & STAT_flushing ) ) break;
+udelay( 50 );
+ }
+ dma_state = dt_getstatus( ) & STAT_dma_state;
+ dma_state ^= STAT_dma_state;
+ is_flushing = 0;
+}
+
+static int dt_sendchar( char ch )
+{
+ if( ! dt_wait_dma( ) ) return -1;
+ if( ! (dt_stat & STAT_rr_char) ) return -2;
+ outb_p( DMA_single_in, synth_port_tts+4 );
+ outb_p( ch, synth_port_tts+4 );
+ dma_state ^= STAT_dma_state;
+ return 0;
+}
+
+static int testkernel( void )
+{
+ int status = 0;
+ if ( dt_getstatus( ) == 0xffff ) {
+ status = -1;
+ goto oops;
+ }
+ dt_sendcmd( CMD_sync );
+ if( ! dt_waitbit( STAT_cmd_ready ) ) status = -2;
+ else if ( ( dt_stat&0x8000 ) ) {
+ return 0;
+ } else if ( dt_stat == 0x0dec )
+ pr_warn( "dec_pc at 0x%x, software not loaded\n", synth_port_tts );
+ status = -3;
+oops: synth_release_region( synth_port_tts, SYNTH_IO_EXTENT );
+ synth_port_tts = 0;
+ return status;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+static u_char last='\0';
+ synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( ch == '\n' ) ch = 0x0D;
+ if ( dt_sendchar( ch ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( ch == '[' ) in_escape = 1;
+ else if ( ch == ']' ) in_escape = 0;
+ else if ( ch <= SPACE ) {
+ if ( !in_escape && strchr( ",.!?;:", last ) )
+ dt_sendchar( PROCSPEECH );
+ if ( jiffies >= jiff_max ) {
+ if ( !in_escape )
+ dt_sendchar( PROCSPEECH );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ last = ch;
+ }
+ if ( synth_done( ) || !in_escape )
+ dt_sendchar( PROCSPEECH );
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( dt_sendchar ( ch ) )
+ return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static int synth_probe ( void )
+{
+ int i=0, failed=0;
+ pr_info ( "Probing for %s.\n", synth->long_name );
+ for( i=0; synth_portlist[i]; i++ ) {
+ if ( synth_request_region( synth_portlist[i], SYNTH_IO_EXTENT ) ) {
+ pr_warn( "request_region: failed with 0x%x, %d\n",
+ synth_portlist[i], SYNTH_IO_EXTENT );
+ continue;
+ }
+ synth_port_tts = synth_portlist[i];
+ if (( failed = testkernel( )) == 0 ) break;
+ }
+ if ( failed ) {
+ pr_info ( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ pr_info ( "%s: %03x-%03x, Driver Version %s,\n", synth->long_name,
+ synth_port_tts, synth_port_tts + 7, synth->version );
+ return 0;
+}
+
+static void dtpc_release( void )
+{
+ if ( synth_port_tts )
+ synth_release_region( synth_port_tts, SYNTH_IO_EXTENT );
+ synth_port_tts = 0;
+}
+
+static int synth_is_alive( void )
+{
+ synth_alive = 1;
+ return 1;
+}
+
+static const char init_string[] = "[:pe -380]";
+
+static string_var stringvars[] = {
+ { CAPS_START, "[:dv ap 200]" },
+ { CAPS_STOP, "[:dv ap 100]" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "[:ra %d]", 9, 0, 18, 150, 25, 0 },
+ { PITCH, "[:dv ap %d]", 80, 0, 100, 20, 0, 0 },
+ { VOL, "[:vo se %d]", 5, 0, 9, 5, 10, 0 },
+ { PUNCT, "[:pu %c]", 0, 0, 2, 0, 0, "nsa" },
+ { VOICE, "[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_dec_pc = { "decpc", "1.1", "Dectalk PC",
+ init_string, 500, 50, 50, 1000, 0, SF_DEC, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, dtpc_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_dectlk.c linux-2.4.30/drivers/char/speakup/speakup_dectlk.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_dectlk.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_dectlk.c 2005-03-30 11:02:02.000000000 -0800
@@ -0,0 +1,221 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+
+#define MY_SYNTH synth_dectlk
+#define SYNTH_CLEAR 0x03
+#define PROCSPEECH 0x0b
+#define synth_full( ) ( inb_p( synth_port_tts ) == 0x13 )
+
+static int timeouts = 0;
+static int in_escape = 0, is_flushing = 0;
+
+static int wait_for_xmitr ( void )
+{
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
+ synth_alive = 0;
+ timeouts = 0;
+ return 0;
+ }
+ do { /* holding register empty? */
+ check = inb_p( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn ( "%s: timed out\n", synth->long_name );
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
+ tmout = SPK_XMITR_TIMEOUT;
+ do { /* CTS */
+ check = inb_p ( synth_port_tts + UART_MSR );
+ if ( --tmout == 0 ) {
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
+ timeouts = 0;
+ return 1;
+}
+
+static inline int spk_serial_out ( const char ch )
+{
+ if ( synth_alive && wait_for_xmitr ( ) ) {
+ outb_p ( ch, synth_port_tts );
+ return 1;
+ }
+ return 0;
+}
+
+static u_char
+spk_serial_in ( void )
+{
+ int lsr, tmout = SPK_SERIAL_TIMEOUT, c;
+ do {
+ lsr = inb_p ( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 )
+ return 0xff;
+ } while ( !( lsr & UART_LSR_DR ) );
+ c = inb_p ( synth_port_tts + UART_RX );
+ return ( u_char ) c;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+static u_char last='\0';
+ synth_stop_timer( );
+ if ( is_flushing ) {
+ ch = spk_serial_in( );
+ if ( ch != '\001' ) {
+ if ( --is_flushing == 0 )
+ pr_warn ( "flush timeout\n" );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ is_flushing = 0;
+ }
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( ch == '\n' ) ch = 0x0D;
+ if ( synth_full( ) || !spk_serial_out( ch ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( ch == '[' ) in_escape = 1;
+ else if ( ch == ']' ) in_escape = 0;
+ else if ( ch <= SPACE ) {
+ if ( !in_escape && strchr( ",.!?;:", last ) )
+ spk_serial_out( PROCSPEECH );
+ if ( jiffies >= jiff_max ) {
+ if ( !in_escape )
+ spk_serial_out( PROCSPEECH );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ last = ch;
+ }
+ if ( synth_done( ) || !in_escape )
+ spk_serial_out( PROCSPEECH );
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush( void )
+{
+ in_escape = 0;
+ spk_serial_out ( SYNTH_CLEAR );
+ is_flushing = 4; /* if no ctl-a in 4, send data anyway */
+}
+
+static int serprobe ( int index )
+{
+ struct serial_state *ser = spk_serial_init( index );
+ u_char test, timeout = 20;
+ if ( ser == NULL ) return -1;
+ outb ( 0x0d, ser->port );
+ /* ignore any error results, if port was forced */
+ if ( synth_port_forced ) return 0;
+ /* check for dectalk express now... */
+ if ( !synth_immediate ( "\x03" ) ) {
+ do {
+ test = spk_serial_in ( );
+ if ( test == 0x01 ) return 0;
+ } while ( --timeout > 0 );
+ }
+ spk_serial_release( );
+ timeouts = synth_alive = synth_port_tts = 0; /* not ignoring */
+ return -1;
+}
+
+static int synth_probe ( void )
+{
+ int i = 0, failed=0;
+ pr_info ( "Probing for %s.\n", synth->long_name );
+ /* check ttyS0-ttyS3 */
+ for ( i = SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info ( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ pr_info ( "%s: %03x-%03x, Driver Version %s,\n", synth->long_name,
+ synth_port_tts, synth_port_tts + 7, synth->version );
+ return 0;
+}
+
+static int
+synth_is_alive ( void )
+{
+ if ( synth_alive ) return 1;
+ if ( !synth_alive && wait_for_xmitr ( ) > 0 ) { /* restart */
+ synth_alive = 1;
+ synth_write_string ( synth->init );
+ return 2;
+ } else
+ pr_warn ( "%s: can't restart synth\n", synth->long_name );
+ return 0;
+}
+
+static const char init_string[] = "[:pe -380][:dv ap 100]";
+
+static string_var stringvars[] = {
+ { CAPS_START, "[:dv ap 200]" },
+ { CAPS_STOP, "[:dv ap 100]" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "[:ra %d]", 9, 0, 18, 150, 25, 0 },
+ { PITCH, "[:dv ap %d]", 80, 0, 200, 20, 0, 0 },
+ { VOL, "[:dv gv %d]", 13, 0, 14, 0, 5, 0 },
+ { PUNCT, "[:pu %c]", 0, 0, 2, 0, 0, "nsa" },
+ { VOICE, "[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_dectlk = { "dectlk", "1.3", "Dectalk Express",
+ init_string, 500, 50, 50, 1000, 0, SF_DEC, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_drvcommon.c linux-2.4.30/drivers/char/speakup/speakup_drvcommon.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_drvcommon.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_drvcommon.c 2004-06-07 07:53:20.000000000 -0700
@@ -0,0 +1,877 @@
+#define KERNEL
+#include
+#include
+#include
+#include /* for isdigit( ) and friends */
+#include
+#include /* for verify_area */
+#include /* for -EBUSY */
+#include /* for check_region, request_region */
+#include /* for loops_per_sec */
+#include /* for put_user_byte */
+#include
+#include /* for wait_queue */
+#include /* for misc_register, and SYNTH_MINOR */
+#include "spk_priv.h"
+#include "serialio.h"
+#include
+
+static struct serial_state rs_table[] = {
+ SERIAL_PORT_DFNS
+};
+
+#include "synthlist.h"
+static struct spk_synth *synths[16] = {
+#include "synthlist.h"
+ NULL };
+
+#define synthBufferSize 8192 /* currently 8K bytes */
+struct spk_synth *synth = NULL;
+struct spk_synth *module_synth = NULL;
+int synth_port_tts = 0, synth_port_forced = 0;
+volatile int synth_timer_active = 0; /* indicates when a timer is set */
+ static struct miscdevice synth_device;
+static int misc_registered = 0;
+static char pitch_buff[32] = "";
+static char module_name[32] = "";
+static struct semaphore sem; /* no mo races */
+declare_sleeper( synth_sleeping_list );
+static int module_status = 0;
+declare_timer( synth_timer );
+short synth_delay_time = 500, synth_trigger_time = 50;
+short synth_jiffy_delta = 50, synth_full_time = 1000;
+int synth_alive = 0;
+u_char synth_buffer[synthBufferSize]; /* guess what this is for! */
+u_char *buffer_highwater = synth_buffer+synthBufferSize-100;
+u_char *buffer_end = synth_buffer+synthBufferSize-1;
+volatile u_char *synth_buff_in = synth_buffer, *synth_buff_out = synth_buffer;
+
+struct serial_state *spk_serial_init( int index )
+{
+ int baud = 9600, quot = 0;
+ unsigned int cval = 0;
+ int i, cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8;
+ struct serial_state *ser = NULL;
+ if ( synth_port_forced ) {
+ if ( index > 0 ) return NULL;
+ pr_info ( "probe forced to 0x%x by kernel command line\n",
+ synth_port_forced );
+ for ( i=0; i <= SPK_HI_TTY; i++ )
+ if ( ( rs_table+i )->port == synth_port_forced ) {
+ ser = rs_table+i;
+ break;
+ }
+ } else ser = rs_table + index;
+ /* Divisor, bytesize and parity */
+ quot = ser->baud_base / baud;
+ cval = cflag & ( CSIZE | CSTOPB );
+#if defined( __powerpc__ ) || defined( __alpha__ )
+ cval >>= 8;
+#else /* !__powerpc__ && !__alpha__ */
+ cval >>= 4;
+#endif /* !__powerpc__ && !__alpha__ */
+ if ( cflag & PARENB )
+ cval |= UART_LCR_PARITY;
+ if ( !( cflag & PARODD ) )
+ cval |= UART_LCR_EPAR;
+ if ( synth_request_region( ser->port, 8 ) ) { // try to take it back.
+ __release_region(&ioport_resource, ser->port, 8 );
+ if ( synth_request_region( ser->port, 8 ) ) return NULL;
+ }
+ /* Disable UART interrupts, set DTR and RTS high
+ * and set speed. */
+ outb( cval | UART_LCR_DLAB, ser->port + UART_LCR ); /* set DLAB */
+ outb( quot & 0xff, ser->port + UART_DLL ); /* LS of divisor */
+ outb( quot >> 8, ser->port + UART_DLM ); /* MS of divisor */
+ outb( cval, ser->port + UART_LCR ); /* reset DLAB */
+ outb( 0, ser->port + UART_IER );
+ outb( UART_MCR_DTR | UART_MCR_RTS, ser->port + UART_MCR );
+ /* If we read 0xff from the LSR, there is no UART here. */
+ if ( inb ( ser->port + UART_LSR ) == 0xff ) {
+ synth_release_region( ser->port, 8 );
+ return NULL;
+ }
+ mdelay( 1 );
+ synth_port_tts = ser->port;
+ return ser;
+}
+
+void spk_serial_release( void )
+{
+ if ( synth_port_tts == 0 ) return;
+ synth_release_region( synth_port_tts, 8 );
+ synth_port_tts = 0;
+}
+
+/* sleep for ms milliseconds */
+void
+synth_delay ( int val )
+{
+ if (val == 0) return;
+ synth_timer.expires = jiffies + val;
+ start_timer( synth_timer );
+ synth_timer_active++;
+}
+
+void
+synth_dummy_catchup( unsigned long data )
+{
+ synth_stop_timer( );
+ synth_done( );
+ return;
+} /* a bogus catchup if no synth */
+
+void
+synth_stop_timer ( void )
+{
+ if ( synth_timer_active )
+ stop_timer ( synth_timer );
+ synth_timer_active = 0;
+}
+
+int synth_done( void )
+{
+ synth_buff_out = synth_buff_in = synth_buffer;
+ if (waitqueue_active(&synth_sleeping_list)) {
+ wake_up_interruptible(&synth_sleeping_list);
+ return 0;
+ }
+ return 1;
+}
+
+static inline void synth_start( void )
+{
+ if ( !synth_alive )
+ synth_done( );
+ else if ( synth->start )
+ synth->start( );
+ else if (synth_timer_active == 0)
+ synth_delay( synth_trigger_time );
+}
+
+void do_flush( void )
+{
+ synth_stop_timer( );
+ synth_buff_out = synth_buff_in = synth_buffer;
+ if ( synth_alive ) {
+ synth->flush( );
+ if ( synth->flush_wait )
+ synth_delay( ( synth->flush_wait * HZ ) / 1000 );
+ if ( pitch_shift ) {
+ synth_write_string( pitch_buff );
+ pitch_shift = 0;
+ }
+ }
+ if (waitqueue_active(&synth_sleeping_list))
+ wake_up_interruptible(&synth_sleeping_list);
+}
+
+void
+synth_buffer_add ( char ch )
+{
+ if ( synth_buff_in >= buffer_highwater ) {
+ synth_start ( );
+ if ( !waitqueue_active ( &synth_sleeping_list ) )
+ interruptible_sleep_on ( &synth_sleeping_list );
+ if ( synth_buff_in >= buffer_end ) return;
+ }
+ *synth_buff_in++ = ch;
+}
+
+void
+synth_write ( const char *buf, size_t count )
+{
+ while ( count-- )
+ synth_buffer_add ( *buf++ );
+ synth_start ( );
+}
+
+void
+synth_write_string ( const char *buf )
+{
+ while ( *buf )
+ synth_buffer_add ( *buf++ );
+ synth_start ( );
+}
+
+void
+synth_write_msg ( const char *buf )
+{
+ while ( *buf )
+ synth_buffer_add ( *buf++ );
+ synth_buffer_add ( '\n' );
+ synth_start ( );
+}
+
+static struct resource synth_res;
+
+int synth_request_region ( unsigned long start, unsigned long n )
+{
+ struct resource *parent = &ioport_resource;
+ memset ( &synth_res, 0, sizeof ( synth_res ) );
+ synth_res.name = synth->name;
+ synth_res.start = start;
+ synth_res.end = start + n - 1;
+ synth_res.flags = IORESOURCE_BUSY;
+ return request_resource ( parent, &synth_res );
+}
+
+int synth_release_region ( unsigned long start, unsigned long n )
+{
+ return release_resource ( &synth_res );
+}
+
+#ifdef CONFIG_PROC_FS
+
+// /proc/synth-specific code
+
+#include
+#include
+
+// this is the write handler for /proc/speakup/synth-specific/direct
+static int
+spk_direct_write_proc ( PROC_WRITE_PROTOTYPE )
+{
+ u_char buf[256];
+ int ret = count, bytes;
+ const char *ptr = buffer;
+ if ( synth == NULL ) return -EPERM;
+ while ( count > 0 ) {
+ bytes = MIN ( count, 250 );
+ if ( copy_from_user ( buf, ptr, bytes ) )
+ return -EFAULT;
+ buf[bytes] = '\0';
+ xlate ( buf );
+ synth_write_string ( buf );
+ ptr += bytes;
+ count -= bytes;
+ }
+ return ret;
+}
+
+proc_var synth_direct = { SYNTH_DIRECT, 0, spk_direct_write_proc, 0 };
+
+#endif
+
+static num_var synth_time_vars[] = {
+ { DELAY, 0, 100, 100, 2000, 0, 0, 0 },
+ { TRIGGER, 0, 20, 10, 200, 0, 0, 0 },
+ { JIFFY, 0, 50, 20, 200, 0, 0, 0 },
+ { FULL, 0, 400, 200, 10000, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+int synth_init ( char *synth_name )
+{
+ int i;
+ if ( synth_name == NULL ) return 0;
+ sema_init ( &sem, 1 ); /* not sure where else to put this. */
+ if ( strcmp (synth_name, "none" ) == 0 ){
+ synth_release( );
+ return 0;
+ }
+ for (i = 0; synths[i] != NULL; i++ ) {
+ if (strcmp (synths[i]->name, synth_name ) == 0 )
+ return do_synth_init( synths[i] );
+ }
+ if ( strcmp (synth_name, "reload" ) == 0 ) {
+ if ( module_status == 0 ) return 0;
+ goto try_reload;
+ }
+ sprintf( module_name, "speakup_%s", synth_name );
+try_reload:
+ pr_warn ( "Speakup: loading module \"%s\"\n", module_name );
+ module_status = request_module( module_name );
+ return module_status;
+}
+
+int do_synth_init ( struct spk_synth *in_synth )
+{
+ num_var *n_var;
+ string_var *s_var;
+ synth_release( );
+ if ( in_synth->checkval != SYNTH_CHECK ) return -EINVAL;
+ synth = in_synth;
+ if ( synth->probe ( ) < 0 ) {
+ pr_warn ( "%s: device probe failed\n", in_synth->name );
+ synth = NULL;
+ return -ENODEV;
+ }
+ synth_time_vars[0].default_val = synth->delay;
+ synth_time_vars[1].default_val = synth->trigger;
+ synth_time_vars[2].default_val = synth->jiffies;
+ synth_time_vars[3].default_val = synth->full;
+ synth_timer.function = synth->catch_up;
+#if (LINUX_VERSION_CODE >= 132419)
+ synth_timer.entry.prev = NULL;
+#endif
+ init_timer ( &synth_timer );
+ for ( n_var = synth_time_vars; n_var->var_id >= 0; n_var++ )
+ speakup_register_var( n_var );
+ synth_alive = 1;
+ synth_write_string( synth->init );
+ for ( s_var = synth->string_vars; s_var->var_id >= 0; s_var++ )
+ speakup_register_var( ( num_var * ) s_var );
+ for ( n_var = synth->num_vars; n_var->var_id >= 0; n_var++ )
+ speakup_register_var( n_var );
+ synth_write_string( synth->long_name );
+ synth_write_msg( " found" );
+#ifdef CONFIG_PROC_FS
+ speakup_register_var( (num_var *)&synth_direct );
+#endif
+ synth_flags = synth->flags;
+ return 0;
+}
+
+void
+synth_release ( void )
+{
+ num_var *n_var;
+ string_var *s_var;
+ if ( synth == NULL ) return;
+ if (down_interruptible ( &sem )) return;
+ pr_info ( "releasing synth %s\n", synth->name );
+ for ( s_var = synth->string_vars; s_var->var_id >= 0; s_var++ )
+ speakup_unregister_var( s_var->var_id );
+ for ( n_var = synth_time_vars; n_var->var_id >= 0; n_var++ )
+ speakup_unregister_var( n_var->var_id );
+ for ( n_var = synth->num_vars; n_var->var_id >= 0; n_var++ )
+ speakup_unregister_var( n_var->var_id );
+#ifdef CONFIG_PROC_FS
+ speakup_unregister_var( SYNTH_DIRECT );
+#endif
+ synth_dummy_catchup((unsigned long) NULL );
+ synth_timer.function = synth_dummy_catchup;
+ synth->release( );
+ synth = NULL;
+ up( &sem );
+}
+
+void synth_add ( struct spk_synth *in_synth )
+{
+ int i;
+ for (i = 0; synths[i] != NULL; i++ )
+ if ( in_synth == synths[i] ) return;
+ synths[i++] = in_synth;
+ synths[i] = NULL;
+}
+
+void synth_remove ( struct spk_synth *in_synth )
+{
+ int i;
+ for (i = 0; synths[i] != NULL; i++ ) {
+ if ( in_synth == synths[i] ) break;
+ }
+for ( ;synths[i] != NULL; i++ ) /* compress table */
+ synths[i] = synths[i+1];
+ module_status = 0;
+}
+
+var_header var_headers[] = {
+ { "version", VERSION, VAR_PROC, USER_R, 0, 0, 0 },
+ { "synth_name", SYNTH, VAR_PROC, USER_RW, 0, 0, 0 },
+ { "keymap", KEYMAP, VAR_PROC, USER_RW, 0, 0, 0 },
+ { "silent", SILENT, VAR_PROC, USER_W, 0, 0, 0 },
+ { "punc_some", PUNC_SOME, VAR_PROC, USER_RW, 0, 0, 0 },
+ { "punc_most", PUNC_MOST, VAR_PROC, USER_RW, 0, 0, 0 },
+ { "punc_all", PUNC_ALL, VAR_PROC, USER_R, 0, 0, 0 },
+ { "delimiters", DELIM, VAR_PROC, USER_RW, 0, 0, 0 },
+ { "repeats", REPEATS, VAR_PROC, USER_RW, 0, 0, 0 },
+ { "ex_num", EXNUMBER, VAR_PROC, USER_RW, 0, 0, 0 },
+ { "characters", CHARS, VAR_PROC, USER_RW, 0, 0, 0 },
+ { "synth_direct", SYNTH_DIRECT, VAR_PROC, USER_W, 0, 0, 0 },
+ { "caps_start", CAPS_START, VAR_STRING, USER_RW, 0, str_caps_start, 0 },
+ { "caps_stop", CAPS_STOP, VAR_STRING, USER_RW, 0, str_caps_stop, 0 },
+ { "delay_time", DELAY, VAR_TIME, ROOT_W, 0, &synth_delay_time, 0 },
+ { "trigger_time", TRIGGER, VAR_TIME, ROOT_W, 0, &synth_trigger_time, 0 },
+ { "jiffy_delta", JIFFY, VAR_TIME, ROOT_W, 0, &synth_jiffy_delta, 0 },
+ { "full_time", FULL, VAR_TIME, ROOT_W, 0, &synth_full_time, 0 },
+ { "spell_delay", SPELL_DELAY, VAR_NUM, USER_RW, 0, &spell_delay, 0 },
+ { "bleeps", BLEEPS, VAR_NUM, USER_RW, 0, &bleeps, 0 },
+ { "attrib_bleep", ATTRIB_BLEEP, VAR_NUM, USER_RW, 0, &attrib_bleep, 0 },
+ { "bleep_time", BLEEP_TIME, VAR_NUM, USER_RW, 0, &bleep_time, 0 },
+ { "cursor_time", CURSOR_TIME, VAR_TIME, USER_RW, 0, &cursor_timeout, 0 },
+ { "punc_level", PUNC_LEVEL, VAR_NUM, USER_RW, 0, &punc_level, 0 },
+ { "reading_punc", READING_PUNC, VAR_NUM, USER_RW, 0, &reading_punc, 0 },
+ { "say_control", SAY_CONTROL, VAR_NUM, USER_RW, 0, &say_ctrl, 0 },
+ { "say_word_ctl", SAY_WORD_CTL, VAR_NUM, USER_RW, 0, &say_word_ctl, 0 },
+ { "no_interrupt", NO_INTERRUPT, VAR_NUM, USER_RW, 0, &no_intr, 0 },
+ { "key_echo", KEY_ECHO, VAR_NUM, USER_RW, 0, &key_echo, 0 },
+ { "bell_pos", BELL_POS, VAR_NUM, USER_RW, 0, &bell_pos, 0 },
+ { "rate", RATE, VAR_NUM, USER_RW, 0, 0, 0 },
+ { "pitch", PITCH, VAR_NUM, USER_RW, 0, 0, 0 },
+ { "vol", VOL, VAR_NUM, USER_RW, 0, 0, 0 },
+ { "tone", TONE, VAR_NUM, USER_RW, 0, 0, 0 },
+ { "punct", PUNCT, VAR_NUM, USER_RW, 0, 0, 0 },
+ { "voice", VOICE, VAR_NUM, USER_RW, 0, 0, 0 },
+ { "freq", FREQ, VAR_NUM, USER_RW, 0, 0, 0 },
+ { "lang", LANG, VAR_NUM, USER_RW, 0, 0, 0 }
+};
+
+var_header *var_ptrs[MAXVARS] = { 0, 0, 0 };
+
+char *
+speakup_s2i ( char *start, short *dest )
+{
+ int val;
+ char ch = *start;
+ if ( ch == '-' || ch == '+' ) start++;
+ if ( *start < '0' || *start > '9' ) return start;
+ val = ( *start ) - '0';
+ start++;
+ while ( *start >= '0' && *start <= '9' ) {
+ val *= 10;
+ val += ( *start ) - '0';
+ start++;
+ }
+ if ( ch == '-' ) *dest = -val;
+ else *dest = val;
+ return start;
+}
+
+short punc_masks[] = { 0, SOME, MOST, PUNC, PUNC|B_SYM };
+
+// handlers for setting vars
+int
+set_num_var( short input, var_header *var, int how )
+{
+ short val, ret = 0;
+ short *p_val = var->p_val;
+ int l;
+ char buf[32], *cp;
+ num_var *var_data = var->data;
+ if ( var_data == NULL ) return E_UNDEF;
+ if ( how == E_DEFAULT ) {
+ val = var_data->default_val;
+ ret = SET_DEFAULT;
+ } else {
+ if ( how == E_SET ) val = input;
+ else val = var_data->value;
+ if ( how == E_INC ) val += input;
+ else if ( how == E_DEC ) val -= input;
+ if ( val < var_data->low || val > var_data->high )
+ return E_RANGE;
+ }
+ var_data->value = val;
+ if ( var->var_type == VAR_TIME && p_val != 0 ) {
+ *p_val = ( val * HZ + 1000 - HZ ) / 1000;
+ return ret;
+ }
+ if ( p_val != 0 ) *p_val = val;
+ if ( var->var_id == PUNC_LEVEL ) {
+ punc_mask = punc_masks[val];
+ return ret;
+ }
+ if ( var_data->multiplier != 0 )
+ val *= var_data->multiplier;
+ val += var_data->offset;
+ if ( var->var_id < FIRST_SYNTH_VAR || synth == NULL ) return ret;
+ if ( synth->synth_adjust != NULL ) {
+ int status = synth->synth_adjust( var );
+ return ( status != 0 ) ? status : ret;
+ }
+ if ( !var_data->synth_fmt ) return ret;
+ if ( var->var_id == PITCH ) cp = pitch_buff;
+ else cp = buf;
+ if ( !var_data->out_str )
+ l = sprintf( cp, var_data->synth_fmt, (int)val );
+ else l = sprintf( cp, var_data->synth_fmt, var_data->out_str[val] );
+ synth_write_string( cp );
+ return ret;
+}
+
+static int
+set_string_var( char *page, var_header *var, int len )
+{
+ int ret = 0;
+ string_var *var_data = var->data;
+ if ( var_data == NULL ) return E_UNDEF;
+ if ( len > MAXVARLEN )
+ return -E_TOOLONG;
+ if ( !len ) {
+ if ( !var_data->default_val ) return 0;
+ ret = SET_DEFAULT;
+ if ( !var->p_val ) var->p_val = var_data->default_val;
+ if ( var->p_val != var_data->default_val )
+ strcpy( (char *)var->p_val, var_data->default_val );
+ } else if ( var->p_val )
+ strcpy( (char *)var->p_val, page );
+ else return -E_TOOLONG;
+ return ret;
+}
+
+ var_header * get_var_header( short var_id )
+{
+ var_header *p_header;
+ if ( var_id < 0 || var_id >= MAXVARS ) return NULL;
+ p_header = var_ptrs[var_id];
+ if ( p_header->data == NULL ) return NULL;
+ return p_header;
+}
+
+#ifdef CONFIG_PROC_FS
+// this is the write handler for /proc/speakup vars
+static int
+speakup_vars_write_proc ( PROC_WRITE_PROTOTYPE )
+{
+ var_header *p_header = data;
+ int len = count, ret = 0;
+ char *page = ( char * ) __get_free_page ( GFP_KERNEL );
+ char *v_name = p_header->name, *cp;
+ num_var *var_data;
+ short value;
+ if ( !page ) return -ENOMEM;
+ if ( copy_from_user ( page, buffer, count ) ) {
+ ret = -EFAULT;
+ goto out;
+ }
+ if ( page[len - 1] == '\n' ) --len;
+ page[len] = '\0';
+ cp = xlate( page );
+ switch( p_header->var_type ) {
+ case VAR_NUM:
+ case VAR_TIME:
+ if ( *cp == 'd' || *cp == 'r' || *cp == '\0' )
+ len = E_DEFAULT;
+ else if ( *cp == '+' || *cp == '-' ) len = E_INC;
+ else len = E_SET;
+ speakup_s2i( cp, &value );
+ ret = set_num_var( value, p_header, len );
+ if ( ret != E_RANGE ) break;
+ var_data = p_header->data;
+ pr_warn( "value for %s out of range, expect %d to %d\n",
+ v_name, (int)var_data->low, (int)var_data->high );
+ break;
+ case VAR_STRING:
+ len = strlen( page );
+ ret = set_string_var( page, p_header, len );
+ if ( ret != E_TOOLONG ) break;
+ pr_warn( "value too long for %s\n", v_name );
+ break;
+ default:
+ pr_warn( "%s unknown type %d\n",
+ p_header->name, ( int )p_header->var_type );
+ break;
+ }
+out:
+ if ( ret == SET_DEFAULT )
+ pr_info( "%s reset to default value\n", v_name );
+ free_page ( ( unsigned long ) page );
+ return count;
+}
+
+// this is the read handler for /proc/speakup vars
+static int
+speakup_vars_read_proc ( PROC_READ_PROTOTYPE )
+{
+ var_header *var = ( var_header * )data;
+ num_var *n_var = var->data;
+ char ch, *cp, *cp1;
+ *start = 0;
+ *eof = 1;
+ switch( var->var_type ) {
+ case VAR_NUM:
+ case VAR_TIME:
+ return sprintf( page, "%d\n", ( int )n_var->value );
+ break;
+ case VAR_STRING:
+ cp1 = page;
+ *cp1++ = '"';
+ for ( cp = (char *)var->p_val; ( ch = *cp ); cp++ ) {
+ if ( ch >= ' ' && ch < '~' )
+ *cp1++ = ch;
+ else
+ cp1 += sprintf( cp1, "\\""x%02x", ch );
+ }
+ *cp1++ = '"';
+ *cp1++ = '\n';
+ *cp1 = '\0';
+ return cp1-page;
+ break;
+ default:
+ return sprintf( page, "oops bad type %d\n",
+ ( int )var->var_type );
+ }
+ return 0;
+}
+
+static const char spk_dir[] = "speakup";
+static struct proc_dir_entry *dir_ent = 0;
+
+static int
+spk_make_proc( var_header *p_header )
+{
+ struct proc_dir_entry *ent = p_header->proc_entry;
+ char *name = p_header->name;
+ proc_var *p_var;
+ if ( dir_ent == 0 || p_header->proc_mode == 0 || ent != 0 ) return 0;
+ ent = create_proc_entry ( name, p_header->proc_mode, dir_ent );
+ if ( !ent ) {
+ pr_warn( "Unable to create /proc/%s/%s entry.\n",
+ spk_dir, name );
+ return -1;
+ }
+ if ( p_header->var_type == VAR_PROC ) {
+ p_var = ( proc_var * )p_header->data;
+ if ( p_header->proc_mode&S_IRUSR )
+ ent->read_proc = p_var->read_proc;
+ if ( p_header->proc_mode&S_IWUSR )
+ ent->write_proc = p_var->write_proc;
+ } else {
+ if ( p_header->proc_mode&S_IRUSR )
+ ent->read_proc = speakup_vars_read_proc;
+ if ( p_header->proc_mode&S_IWUSR )
+ ent->write_proc = speakup_vars_write_proc;
+ }
+ ent->data = ( void * )p_header;
+ p_header->proc_entry = ( void * ) ent;
+ return 0;
+}
+
+#endif
+
+int
+speakup_register_var( num_var *var )
+{
+ static char nothing[2] = "\0";
+ int i, var_id = var->var_id;
+ var_header *p_header;
+ string_var *s_var;
+ if ( var_id < 0 || var_id >= MAXVARS ) return -1;
+ if ( var_ptrs[0] == 0 ) {
+ for ( i = 0; i < MAXVARS; i++ ) {
+ p_header = &var_headers[i];
+ var_ptrs[p_header->var_id] = p_header;
+ p_header->data = 0;
+ }
+ }
+ p_header = var_ptrs[var_id];
+ if ( p_header->data != 0 ) return 0;
+ p_header->data = var;
+ switch ( p_header->var_type ) {
+ case VAR_STRING:
+ s_var = ( string_var * )var;
+ set_string_var( nothing, p_header, 0 );
+ break;
+ case VAR_NUM:
+ case VAR_TIME:
+ set_num_var( 0, p_header, E_DEFAULT );
+ break;
+ }
+#ifdef CONFIG_PROC_FS
+ return spk_make_proc( p_header );
+#else
+ return 0;
+#endif
+}
+
+void
+speakup_unregister_var( short var_id )
+{
+ var_header *p_header;
+ if ( var_id < 0 || var_id >= MAXVARS ) return;
+ p_header = var_ptrs[var_id];
+ p_header->data = 0;
+#ifdef CONFIG_PROC_FS
+ if ( dir_ent != 0 && p_header->proc_entry != 0 )
+ remove_proc_entry( p_header->name, dir_ent );
+ p_header->proc_entry = 0;
+#endif
+}
+
+// called by proc_root_init( ) to initialize the /proc/speakup subtree
+void __init
+proc_speakup_init ( void )
+{
+ int i;
+ var_header *p_header;
+ proc_var *pv = spk_proc_vars;
+/* if we requested a module at startup it will not load as root not mounted
+ * so let's try to load here as root should be mounted now */
+ speakup_register_devsynth ( );
+#ifdef CONFIG_PROC_FS
+ dir_ent = create_proc_entry ( spk_dir, S_IFDIR, 0 );
+ if ( !dir_ent ) {
+ pr_warn( "Unable to create /proc/%s entry.\n", spk_dir );
+ return;
+ }
+ while ( pv->var_id >= 0 ) {
+ speakup_register_var( ( void * )pv );
+ pv++;
+ }
+ for ( i = 0; i < MAXVARS; i++ ) {
+ p_header = &var_headers[i];
+ if ( p_header->data != 0 ) spk_make_proc( p_header );
+ }
+#endif
+}
+
+void
+proc_speakup_remove ( void )
+{
+ int i;
+ for ( i = 0; i < MAXVARS; i++ )
+ speakup_unregister_var( i );
+ pr_info( "speakup: unregistering synth device /dev/synth\n" );
+ misc_deregister( &synth_device );
+ misc_registered = 0;
+#ifdef CONFIG_PROC_FS
+ if ( dir_ent != 0 )
+ remove_proc_entry( spk_dir, NULL );
+#endif
+}
+
+// provide a file to users, so people can send to /dev/synth
+
+static ssize_t
+speakup_file_write ( struct file *fp, const char *buffer,
+ size_t nbytes, loff_t * ppos )
+{
+ size_t count = nbytes;
+ const char *ptr = buffer;
+ int bytes;
+ u_char buf[256];
+ if ( synth == NULL ) return -ENODEV;
+ while ( count > 0 ) {
+ bytes = MIN ( count, sizeof ( buf ) );
+ if ( copy_from_user ( buf, ptr, bytes ) )
+ return -EFAULT;
+ count -= bytes;
+ ptr += bytes;
+ synth_write ( buf, bytes );
+ }
+ return ( ssize_t ) nbytes;
+}
+
+static int
+speakup_file_ioctl ( struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg )
+{
+ return 0; // silently ignore
+}
+
+static ssize_t
+speakup_file_read ( struct file *fp, char *buf, size_t nbytes, loff_t * ppos )
+{
+ return 0;
+}
+
+static int synth_file_inuse = 0;
+
+static int
+speakup_file_open ( struct inode *ip, struct file *fp )
+{
+ if ( synth_file_inuse )
+ return -EBUSY;
+ else if ( synth == NULL )
+ return -ENODEV;
+ synth_file_inuse++;
+ return 0;
+}
+
+static int
+speakup_file_release ( struct inode *ip, struct file *fp )
+{
+ synth_file_inuse = 0;
+ return 0;
+}
+
+static struct file_operations synth_fops = {
+ read:speakup_file_read,
+ write:speakup_file_write,
+ ioctl:speakup_file_ioctl,
+ open:speakup_file_open,
+ release:speakup_file_release,
+};
+
+void
+speakup_register_devsynth ( void ) {
+ if ( misc_registered != 0 ) return;
+ misc_registered = 1;
+ memset( &synth_device, 0, sizeof( synth_device ) );
+/* zero it so if register fails, deregister will not ref invalid ptrs */
+ synth_device.minor = SYNTH_MINOR;
+ synth_device.name = "synth";
+ synth_device.fops = &synth_fops;
+ if ( misc_register ( &synth_device ) )
+ pr_warn(
+ "Couldn't initialize miscdevice /dev/synth.\n" );
+ else
+ pr_info(
+ "initialized device: /dev/synth, node ( MAJOR 10, MINOR 25 )\n" );
+}
+
+char *
+xlate ( char *s )
+{
+static const char finds[] = "nrtvafe";
+static const char subs[] = "\n\r\t\013\001\014\033";
+static const char hx[] = "0123456789abcdefABCDEF";
+ char *p = s, *p1, *p2, c;
+ int num;
+ while ( ( p = strchr ( p, '\\' ) ) ) {
+ p1 = p+1;
+ p2 = strchr( finds, *p1 );
+ if ( p2 ) {
+ *p++ = subs[p2-finds];
+ p1++;
+ } else if ( *p1 >= '0' && *p1 <= '7' ) {
+ num = ( *p1++ )&7;
+ while ( num < 256 && *p1 >= '0' && *p1 <= '7' ) {
+ num <<= 3;
+ num = ( *p1++ )&7;
+ }
+ *p++ = num;
+ } else if ( *p1 == 'x'&& strchr( hx, p1[1] ) && strchr( hx, p1[2] ) ) {
+ p1++;
+ c = *p1++;
+ if ( c > '9' )
+ c = ( c-'7' )&0x0f;
+ else
+ c -= '0';
+ num = c<<4;
+ c = *p1++;
+ if ( c > '9' )
+ c = ( c-'7' )&0x0f;
+ else
+ c -= '0';
+ num += c;
+ *p++ = num;
+ } else
+ *p++ = *p1++;
+ p2 = p;
+ while ( *p1 ) *p2++ = *p1++;
+ *p2 = '\0';
+ }
+ return s;
+}
+
+/* exported symbols needed by synth modules */
+EXPORT_SYMBOL(synth_init);
+EXPORT_SYMBOL(do_synth_init);
+EXPORT_SYMBOL(spk_serial_init);
+EXPORT_SYMBOL(spk_serial_release);
+EXPORT_SYMBOL(synth);
+EXPORT_SYMBOL(synth_alive);
+EXPORT_SYMBOL(synth_buffer);
+EXPORT_SYMBOL(synth_buff_in);
+EXPORT_SYMBOL(synth_buff_out);
+EXPORT_SYMBOL(synth_delay);
+EXPORT_SYMBOL(synth_delay_time);
+EXPORT_SYMBOL(synth_done);
+EXPORT_SYMBOL(synth_full_time);
+EXPORT_SYMBOL(synth_jiffy_delta);
+EXPORT_SYMBOL(synth_port_forced);
+EXPORT_SYMBOL(synth_port_tts);
+EXPORT_SYMBOL(synth_request_region);
+EXPORT_SYMBOL(synth_release_region);
+EXPORT_SYMBOL(synth_release);
+EXPORT_SYMBOL(synth_add);
+EXPORT_SYMBOL(synth_remove);
+EXPORT_SYMBOL(synth_stop_timer);
+EXPORT_SYMBOL(synth_write_string);
+EXPORT_SYMBOL(synth_write_msg);
+EXPORT_SYMBOL(synth_write);
+MODULE_AUTHOR("Kirk Reiser ");
+MODULE_DESCRIPTION("Speakup module required by all synthesizer specific modules");
+MODULE_LICENSE("GPL");
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_dtlk.c linux-2.4.30/drivers/char/speakup/speakup_dtlk.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_dtlk.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_dtlk.c 2003-10-07 18:04:35.000000000 -0700
@@ -0,0 +1,219 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "speakup_dtlk.h" /* local header file for DoubleTalk values */
+
+#define MY_SYNTH synth_dtlk
+#define PROCSPEECH 0x00
+#define synth_readable() ((synth_status = inb_p(synth_port_tts)) & TTS_READABLE)
+#define synth_full() ((synth_status = inb_p(synth_port_tts)) & TTS_ALMOST_FULL)
+
+static int synth_lpc;
+static unsigned int synth_portlist[] =
+ { 0x25e, 0x29e, 0x2de, 0x31e, 0x35e, 0x39e, 0 };
+static u_char synth_status = 0;
+
+static inline void spk_out(const char ch)
+{
+ int tmout = 100000;
+ while (((synth_status = inb_p(synth_port_tts)) & TTS_WRITABLE) == 0);
+ outb_p(ch, synth_port_tts);
+ while ((((synth_status = inb_p(synth_port_tts)) & TTS_WRITABLE) != 0)
+ && (--tmout != 0) );
+}
+
+static void do_catch_up(unsigned long data)
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+ synth_stop_timer();
+ synth_status = inb_p(synth_port_tts);
+ while (synth_buff_out < synth_buff_in) {
+ if (synth_status & TTS_ALMOST_FULL) {
+ synth_delay(synth_full_time);
+ return;
+ }
+ ch = *synth_buff_out++;
+ if (ch == 0x0a) ch = PROCSPEECH;
+ spk_out( ch );
+ if (jiffies >= jiff_max && ch == SPACE) {
+ spk_out(PROCSPEECH);
+ synth_delay(synth_delay_time);
+ return;
+ }
+ }
+ spk_out(PROCSPEECH);
+ synth_done( );
+}
+
+static char *synth_immediate(char *buf )
+{
+ u_char ch;
+ synth_status = inb_p(synth_port_tts);
+ while ( (ch = (u_char)*buf ) ) {
+ if (synth_status & TTS_ALMOST_FULL)
+ return buf;
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ spk_out(ch);
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush(void)
+{
+ outb_p(SYNTH_CLEAR, synth_port_tts);
+ while (((synth_status = inb_p(synth_port_tts)) & TTS_WRITABLE) != 0);
+ }
+
+static char synth_read_tts(void)
+{
+ u_char ch;
+ while (((synth_status = inb_p(synth_port_tts)) & TTS_READABLE) == 0);
+ ch = synth_status & 0x7f;
+ outb_p(ch, synth_port_tts);
+ while ((inb_p(synth_port_tts) & TTS_READABLE) != 0);
+return (char) ch;
+}
+
+/* interrogate the DoubleTalk PC and return its settings */
+static struct synth_settings * synth_interrogate(void)
+{
+ u_char *t;
+static char buf[sizeof(struct synth_settings) + 1];
+int total, i;
+static struct synth_settings status;
+ synth_immediate("\x18\x01?");
+ for (total = 0, i = 0; i < 50; i++) {
+ buf[total] = synth_read_tts();
+ if (total > 2 && buf[total] == 0x7f) break;
+ if (total < sizeof(struct synth_settings)) total++;
+ }
+ t = buf;
+ status.serial_number = t[0] + t[1]*256; /* serial number is little endian */
+ t += 2;
+ for ( i = 0; *t != '\r'; t++ ) {
+ status.rom_version[i] = *t;
+ if (i < sizeof(status.rom_version)-1) i++;
+ }
+ status.rom_version[i] = 0;
+ t++;
+ status.mode = *t++;
+ status.punc_level = *t++;
+ status.formant_freq = *t++;
+ status.pitch = *t++;
+ status.speed = *t++;
+ status.volume = *t++;
+ status.tone = *t++;
+ status.expression = *t++;
+ status.ext_dict_loaded = *t++;
+ status.ext_dict_status = *t++;
+ status.free_ram = *t++;
+ status.articulation = *t++;
+ status.reverb = *t++;
+ status.eob = *t++;
+ return &status;
+}
+
+static int synth_probe(void)
+{
+ unsigned int port_val = 0;
+ int i = 0;
+ struct synth_settings *sp;
+ pr_info("Probing for DoubleTalk.\n");
+ if (synth_port_forced) {
+ synth_port_tts = synth_port_forced;
+ pr_info("probe forced to %x by kernel command line\n", synth_port_tts);
+ if (synth_request_region(synth_port_tts-1, SYNTH_IO_EXTENT)) {
+ pr_warn("sorry, port already reserved\n");
+ return -EBUSY;
+ }
+ port_val = inw(synth_port_tts-1);
+ synth_lpc = synth_port_tts-1;
+ } else {
+ for(i=0; synth_portlist[i]; i++) {
+ if (synth_request_region(synth_portlist[i], SYNTH_IO_EXTENT))
+ continue;
+ port_val = inw(synth_portlist[i]);
+ if ((port_val &= 0xfbff) == 0x107f) {
+ synth_lpc = synth_portlist[i];
+ synth_port_tts = synth_lpc+1;
+ break;
+ }
+ synth_release_region(synth_portlist[i], SYNTH_IO_EXTENT);
+ }
+ }
+ if ((port_val &= 0xfbff) != 0x107f) {
+ pr_info("DoubleTalk PC: not found\n");
+ return -ENODEV;
+ }
+ while (inw_p(synth_lpc) != 0x147f ); /* wait until it's ready */
+ sp = synth_interrogate();
+ pr_info("%s: %03x-%03x, ROM ver %s, s/n %u, driver: %s\n",
+ synth->long_name, synth_lpc, synth_lpc+SYNTH_IO_EXTENT - 1,
+ sp->rom_version, sp->serial_number, synth->version);
+ // synth_alive = 1;
+ return 0;
+}
+
+static int synth_is_alive(void)
+{
+ return 1; /* I'm *INVINCIBLE* */
+}
+
+static void
+dtlk_release( void )
+{
+ if ( synth_port_tts )
+ synth_release_region(synth_port_tts-1, SYNTH_IO_EXTENT);
+ synth_port_tts = 0;
+}
+
+static const char init_string[] = "\x01@\x01\x31y";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\x01+35p" },
+ { CAPS_STOP, "\x01-35p" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\x01%ds", 8, 0, 9, 0, 0, 0 },
+ { PITCH, "\x01%dp", 50, 0, 99, 0, 0, 0 },
+ { VOL, "\x01%dv", 5, 0, 9, 0, 0, 0 },
+ { TONE, "\x01%dx", 1, 0, 2, 0, 0, 0 },
+ { PUNCT, "\x01%db", 7, 0, 15, 0, 0, 0 },
+ { VOICE, "\x01%do", 0, 0, 7, 0, 0, 0 },
+ { FREQ, "\x01%df", 5, 0, 9, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_dtlk = {"dtlk", "1.1", "DoubleTalk PC",
+ init_string, 500, 30, 50, 1000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, dtlk_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_dtlk.h linux-2.4.30/drivers/char/speakup/speakup_dtlk.h
--- linux-2.4.30.orig/drivers/char/speakup/speakup_dtlk.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_dtlk.h 2003-04-22 08:06:47.000000000 -0700
@@ -0,0 +1,54 @@
+/* speakup_dtlk.h - header file for speakups DoubleTalk driver. */
+
+#define SYNTH_IO_EXTENT 0x02
+#define SYNTH_CLEAR 0x18 /* stops speech */
+ /* TTS Port Status Flags */
+#define TTS_READABLE 0x80 /* mask for bit which is nonzero if a
+ byte can be read from the TTS port */
+#define TTS_SPEAKING 0x40 /* mask for SYNC bit, which is nonzero
+ while DoubleTalk is producing
+ output with TTS, PCM or CVSD
+ synthesizers or tone generators
+ (that is, all but LPC) */
+#define TTS_SPEAKING2 0x20 /* mask for SYNC2 bit,
+ which falls to zero up to 0.4 sec
+ before speech stops */
+#define TTS_WRITABLE 0x10 /* mask for RDY bit, which when set to
+ 1, indicates the TTS port is ready
+ to accept a byte of data. The RDY
+ bit goes zero 2-3 usec after
+ writing, and goes 1 again 180-190
+ usec later. */
+#define TTS_ALMOST_FULL 0x08 /* mask for AF bit: When set to 1,
+ indicates that less than 300 bytes
+ are available in the TTS input
+ buffer. AF is always 0 in the PCM,
+ TGN and CVSD modes. */
+#define TTS_ALMOST_EMPTY 0x04 /* mask for AE bit: When set to 1,
+ indicates that less than 300 bytes
+ are remaining in DoubleTalk's input
+ (TTS or PCM) buffer. AE is always 1
+ in the TGN and CVSD modes. */
+
+ /* data returned by Interrogate command */
+struct synth_settings {
+ u_short serial_number; /* 0-7Fh:0-7Fh */
+ u_char rom_version[24]; /* null terminated string */
+ u_char mode; /* 0=Character; 1=Phoneme; 2=Text */
+ u_char punc_level; /* nB; 0-7 */
+ u_char formant_freq; /* nF; 0-9 */
+ u_char pitch; /* nP; 0-99 */
+ u_char speed; /* nS; 0-9 */
+ u_char volume; /* nV; 0-9 */
+ u_char tone; /* nX; 0-2 */
+ u_char expression; /* nE; 0-9 */
+ u_char ext_dict_loaded; /* 1=exception dictionary loaded */
+ u_char ext_dict_status; /* 1=exception dictionary enabled */
+ u_char free_ram; /* # pages (truncated) remaining for
+ text buffer */
+ u_char articulation; /* nA; 0-9 */
+ u_char reverb; /* nR; 0-9 */
+ u_char eob; /* 7Fh value indicating end of
+ parameter block */
+ u_char has_indexing; /* nonzero if indexing is implemented */
+};
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_keyhelp.c linux-2.4.30/drivers/char/speakup/speakup_keyhelp.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_keyhelp.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_keyhelp.c 2003-10-08 08:02:11.000000000 -0700
@@ -0,0 +1,294 @@
+/* speakup_keyhelp.c
+ help module for speakup
+
+ written by David Borowski.
+
+ Copyright (C ) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include
+#include
+#include "spk_priv.h"
+
+extern u_char *our_keys[];
+extern special_func special_handler;
+extern special_func help_handler;
+#define MAXFUNCS 130
+#define MAXKEYS 256
+static u_short key_offsets[MAXFUNCS], key_buf[MAXKEYS];
+static u_short masks[] = { 32, 16, 8, 4, 2, 1 };
+static char help_info[] =
+ "press space to leav help, cursor up or down to scroll, or a letter to go to commands in list";
+static char *statenames[] = {
+ " double", " speakup", " alt",
+ " ctrl", " altgr", " shift"
+};
+static char *keynames[] = {
+ "escape", "1", "2", "3", "4",
+ "5", "6", "7", "8", "9",
+ "0", "minus", "equal", "back space", "tab",
+ "q", "w", "e", "r", "t",
+ "y", "u", "i", "o", "p",
+ "left brace", "right brace", "enter", "left control", "a",
+ "s", "d", "f", "g", "h",
+ "j", "k", "l", "semicolon", "apostrophe",
+ "accent", "left shift", "back slash", "z", "x",
+ "c", "v", "b", "n", "m",
+ "comma", "dot", "slash", "right shift", "keypad asterisk",
+ "left alt", "space", "caps lock", "f1", "f2",
+ "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "num lock", "scroll lock",
+ "keypad 7", "keypad 8", "keypad 9", "keypad minus", "keypad 4",
+ "keypad 5", "keypad 6", "keypad plus", "keypad 1", "keypad 2",
+ "keypad 3", "keypad 0", "keypad dot", "103rd", "f13",
+ "102nd", "f11", "f12", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20",
+ "keypad enter", "right control", "keypad slash", "sysrq", "right alt",
+ "line feed", "home", "up", "page up", "left",
+ "right", "end", "down", "page down", "insert",
+ "delete", "macro", "mute", "volume down", "volume up",
+ "power", "keypad equal", "keypad plusminus", "pause", "f21",
+ "f22", "f23", "f24", "keypad comma", "left meta",
+ "right meta", "compose", "stop", "again", "props",
+ "undo", "front", "copy", "open", "paste",
+ "find", "cut", "help", "menu", "calc",
+ "setup", "sleep", "wakeup", "file", "send file",
+ "delete file", "transfer", "prog1", "prog2", "www",
+ "msdos", "coffee", "direction", "cycle windows", "mail",
+ "bookmarks", "computer", "back", "forward", "close cd",
+ "eject cd", "eject close cd", "next song", "play pause", "previous song",
+ "stop cd", "record", "rewind", "phone", "iso",
+ "config", "home page", "refresh", "exit", "move",
+ "edit", "scroll up", "scroll down", "keypad left paren", "keypad right paren",
+};
+
+static short letter_offsets[26];
+
+static u_char funcvals[] = {
+ ATTRIB_BLEEP_DEC, ATTRIB_BLEEP_INC, BLEEPS_DEC, BLEEPS_INC,
+ SAY_FIRST_CHAR, SAY_LAST_CHAR, SAY_CHAR, SAY_CHAR_NUM,
+ SAY_NEXT_CHAR, SAY_PHONETIC_CHAR, SAY_PREV_CHAR, SPEAKUP_PARKED,
+ SPEAKUP_CUT, EDIT_DELIM, EDIT_EXNUM, EDIT_MOST,
+ EDIT_REPEAT, EDIT_SOME, SPEAKUP_GOTO, BOTTOM_EDGE,
+ LEFT_EDGE, RIGHT_EDGE, TOP_EDGE, SPEAKUP_HELP,
+ SAY_LINE, SAY_NEXT_LINE, SAY_PREV_LINE, SAY_LINE_INDENT,
+ SPEAKUP_PASTE, PITCH_DEC, PITCH_INC, PUNCT_DEC,
+ PUNCT_INC, PUNC_LEVEL_DEC, PUNC_LEVEL_INC, SPEAKUP_QUIET,
+ RATE_DEC, RATE_INC, READING_PUNC_DEC, READING_PUNC_INC,
+ SAY_ATTRIBUTES, SAY_FROM_LEFT, SAY_FROM_TOP, SAY_POSITION,
+ SAY_SCREEN, SAY_TO_BOTTOM, SAY_TO_RIGHT, SPK_KEY,
+ SPK_LOCK, SPEAKUP_OFF, SPEECH_KILL, SPELL_DELAY_DEC,
+ SPELL_DELAY_INC, SPELL_WORD, SPELL_PHONETIC, TONE_DEC,
+ TONE_INC, VOICE_DEC, VOICE_INC, VOL_DEC,
+ VOL_INC, CLEAR_WIN, SAY_WIN, SET_WIN,
+ ENABLE_WIN, SAY_WORD, SAY_NEXT_WORD, SAY_PREV_WORD, 0
+};
+
+static char *funcnames[] = {
+ "attribute bleep decrement", "attribute bleep increment",
+ "bleeps decrement", "bleeps increment",
+ "character, first", "character, last",
+ "character, say current",
+ "character, say hex and decimal", "character, say next",
+ "character, say phonetic", "character, say previous",
+ "cursor park", "cut",
+ "edit delimiters", "edit exnum",
+ "edit most", "edit repeats", "edit some",
+ "go to", "go to bottom edge", "go to left edge",
+ "go to right edge", "go to top edge", "help",
+ "line, say current", "line, say next",
+ "line, say previous", "line, say with indent",
+ "paste", "pitch decrement", "pitch increment",
+ "punctuation decrement", "punctuation increment",
+ "punc level decrement", "punc level increment",
+ "quiet",
+ "rate decrement", "rate increment",
+ "reading punctuation decrement", "reading punctuation increment",
+ "say attributes",
+ "say from left", "say from top",
+ "say position", "say screen",
+ "say to bottom", "say to right",
+ "speakup", "speakup lock",
+ "speakup off", "speech kill",
+ "spell delay decrement", "spell delay increment",
+ "spell word", "spell word phoneticly",
+ "tone decrement", "tone increment",
+ "voice decrement", "voice increment",
+ "volume decrement", "volume increment",
+ "window, clear", "window, say",
+ "window, set", "window, silence",
+ "word, say current", "word, say next",
+ "word, say previous", 0
+};
+
+static u_char *state_tbl;
+static int cur_item = 0, nstates = 0;
+
+static void build_key_data( void )
+{
+ u_char *kp, counters[MAXFUNCS], ch, ch1;
+ u_short *p_key = key_buf, key;
+ int i, offset = 1;
+ nstates = (int)( state_tbl[-1] );
+ memset( counters, 0, sizeof( counters ) );
+ memset( key_offsets, 0, sizeof( key_offsets ) );
+ kp = state_tbl + nstates + 1;
+ while ( *kp++ ) { /* count occurrances of each function */
+ for ( i = 0; i < nstates; i++, kp++ ) {
+ if ( !*kp ) continue;
+ if ( (state_tbl[i]&16) != 0 && *kp == SPK_KEY )
+ continue;
+ counters[*kp]++;
+ }
+ }
+ for ( i = 0; i < MAXFUNCS; i++ ) {
+ if ( counters[i] == 0 ) continue;
+ key_offsets[i] = offset;
+ offset += ( counters[i]+1 );
+ if ( offset >= MAXKEYS ) break;
+ }
+/* leave counters set so high keycodes come first.
+ this is done so num pad and other extended keys maps are spoken before
+ the alpha with speakup type mapping. */
+ kp = state_tbl + nstates + 1;
+ while ( ( ch = *kp++ ) ) {
+ for ( i = 0; i < nstates; i++ ) {
+ ch1 = *kp++;
+ if ( !ch1 ) continue;
+ if ( (state_tbl[i]&16) != 0 && ch1 == SPK_KEY )
+ continue;
+ key = ( state_tbl[i]<<8 ) + ch;
+ counters[ch1]--;
+ if ( !(offset = key_offsets[ch1]) ) continue;
+ p_key = key_buf + offset + counters[ch1];
+ *p_key = key;
+ }
+ }
+}
+
+static void say_key( int key )
+{
+ int i, state = key>>8;
+ key &= 0xff;
+ for ( i = 0; i < 6; i++ ) {
+ if ( ( state & masks[i] ) )
+ synth_write_string( statenames[i] );
+ }
+ synth_write_string( " " );
+ synth_write_msg( keynames[--key] );
+}
+
+static int handle_help ( int currcons, u_char type, u_char ch, u_short key )
+{
+ int i, n;
+ char *name;
+ u_char func, *kp;
+ u_short *p_keys, val;
+ if ( type == KT_LATIN ) {
+ if ( ch == SPACE ) {
+ special_handler = NULL;
+#if (LINUX_VERSION_CODE < 132419)
+ MOD_DEC_USE_COUNT;
+#endif
+ synth_write_msg( "leaving help" );
+ return 1;
+ }
+ ch |= 32; /* lower case */
+ if ( ch < 'a' || ch > 'z' ) return -1;
+ if ( letter_offsets[ch-'a'] == -1 ) {
+ synth_write_string( "no commands for " );
+ synth_write( &ch, 1 );
+ synth_write( "\n", 1 );
+ return 1;
+ }
+ cur_item = letter_offsets[ch-'a'];
+ } else if ( type == KT_CUR ) {
+ if ( ch == 0 && funcnames[cur_item+1] != NULL )
+ cur_item++;
+ else if ( ch == 3 && cur_item > 0 )
+ cur_item--;
+ else return -1;
+ } else if (type == KT_SPKUP && ch == SPEAKUP_HELP && !special_handler) {
+ special_handler = help_handler;
+#if (LINUX_VERSION_CODE < 132419)
+ MOD_INC_USE_COUNT;
+#endif
+ synth_write_msg( help_info );
+ build_key_data( ); /* rebuild each time in case new mapping */
+ return 1;
+ } else {
+ name = NULL;
+ if ( type != KT_SPKUP ) {
+ synth_write_msg( keynames[key-1] );
+ return 1;
+ }
+ for ( i = 0; funcvals[i] != 0 && !name; i++ ) {
+ if ( ch == funcvals[i] )
+ name = funcnames[i];
+ }
+ if ( !name ) return -1;
+ kp = our_keys[key]+1;
+ for ( i = 0; i < nstates; i++ ) {
+ if ( ch == kp[i] ) break;
+ }
+ key += ( state_tbl[i]<<8 );
+ say_key( key );
+ synth_write_string( "is " );
+ synth_write_msg( name );
+ return 1;
+ }
+ name = funcnames[cur_item];
+ func = funcvals[cur_item];
+ synth_write_string( name );
+ if ( key_offsets[func] == 0 ) {
+ synth_write_msg( " is unassigned" );
+ return 1;
+ }
+ p_keys = key_buf + key_offsets[func];
+ for ( n = 0; p_keys[n]; n++ ) {
+ val = p_keys[n];
+ if ( n > 0 ) synth_write_string( "or " );
+ say_key( val );
+ }
+ return 1;
+}
+
+static void __exit mod_help_exit( void )
+{
+ help_handler = 0;
+}
+
+static int __init mod_help_init( void )
+{
+ char start = SPACE;
+ int i;
+state_tbl = our_keys[0]+SHIFT_TBL_SIZE+2;
+ for (i = 0; i < 26; i++ ) letter_offsets[i] = -1;
+ for ( i = 0; funcnames[i]; i++ ) {
+ if ( start == *funcnames[i] ) continue;
+ start = *funcnames[i];
+ letter_offsets[(start&31)-1] = i;
+ }
+ help_handler = handle_help;
+ return 0;
+}
+
+module_init( mod_help_init );
+module_exit( mod_help_exit );
+MODULE_AUTHOR("David Borowski");
+MODULE_DESCRIPTION("Speakup keyboard help MODULE");
+MODULE_LICENSE("GPL");
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_keypc.c linux-2.4.30/drivers/char/speakup/speakup_keypc.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_keypc.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_keypc.c 2004-03-10 11:56:25.000000000 -0800
@@ -0,0 +1,189 @@
+/*
+* written by David Borowski
+
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+
+#define MY_SYNTH synth_keypc
+#define SYNTH_IO_EXTENT 0x04
+#define SWAIT udelay( 70 )
+#define synth_writable( ) ( inb_p( synth_port ) & 0x10 )
+#define synth_readable( ) ( inb_p( synth_port ) & 0x10 )
+#define synth_full( ) ( ( inb_p( synth_port ) & 0x80 ) == 0 )
+#define PROCSPEECH 0x1f
+#define SYNTH_CLEAR 0x03
+
+static int synth_port;
+static unsigned int synth_portlist[] =
+ { 0x2a8, 0 };
+
+static int
+oops( void )
+{
+ int s1, s2, s3, s4;
+ s1 = inb_p( synth_port );
+ s2 = inb_p( synth_port+1 );
+ s3 = inb_p( synth_port+2 );
+ s4 = inb_p( synth_port+3 );
+ pr_warn( "synth timeout %d %d %d %d\n", s1, s2, s3, s4 );
+ return 0;
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ int timeout;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( synth_full( ) )
+ return buf;
+ timeout = 1000;
+ while ( synth_writable( ) )
+ if ( --timeout <= 0 ) return (char *) oops( );
+ outb_p( ch, synth_port );
+ SWAIT;
+ buf++;
+ }
+ return 0;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+ int timeout;
+ synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ if ( synth_full( ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ timeout = 1000;
+ while ( synth_writable( ) )
+ if ( --timeout <= 0 ) break;
+ if ( timeout <= 0 ) {
+ oops( );
+ break;
+ }
+ ch = *synth_buff_out++;
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ outb_p( ch, synth_port );
+ SWAIT;
+ if ( jiffies >= jiff_max && ch == SPACE ) {
+ timeout = 1000;
+ while ( synth_writable( ) )
+ if ( --timeout <= 0 ) break;
+ if ( timeout <= 0 ) {
+ oops( );
+ break;
+ }
+ outb_p( PROCSPEECH, synth_port );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ timeout = 1000;
+ while ( synth_writable( ) )
+ if ( --timeout <= 0 ) break;
+ if ( timeout <= 0 ) oops( );
+ else
+ outb_p( PROCSPEECH, synth_port );
+ synth_done( );
+}
+
+static void synth_flush( void )
+{
+ outb_p( SYNTH_CLEAR, synth_port );
+}
+
+static int synth_probe( void )
+{
+ unsigned int port_val = 0;
+ int i = 0;
+ pr_info( "Probing for %s.\n", synth->long_name );
+ if ( synth_port_forced ) {
+ synth_port = synth_port_forced;
+ pr_info( "probe forced to %x by kernel command line\n", synth_port );
+ if ( synth_request_region( synth_port-1, SYNTH_IO_EXTENT ) ) {
+ pr_warn( "sorry, port already reserved\n" );
+ return -EBUSY;
+ }
+ port_val = inb( synth_port );
+ } else {
+ for( i=0; synth_portlist[i]; i++ ) {
+ if ( synth_request_region( synth_portlist[i], SYNTH_IO_EXTENT ) ) {
+ pr_warn( "request_region: failed with 0x%x, %d\n",
+ synth_portlist[i], SYNTH_IO_EXTENT );
+ continue;
+ }
+ port_val = inb( synth_portlist[i] );
+ if ( port_val == 0x80 ) {
+ synth_port = synth_portlist[i];
+ break;
+ }
+ }
+ }
+ if ( port_val != 0x80 ) {
+ pr_info( "%s: not found\n", synth->long_name );
+ synth_release_region( synth_portlist[i], SYNTH_IO_EXTENT );
+ synth_port = 0;
+ return -ENODEV;
+ }
+ pr_info( "%s: %03x-%03x, driver version %s,\n", synth->long_name,
+ synth_port, synth_port+SYNTH_IO_EXTENT-1,
+ synth->version );
+ return 0;
+}
+
+static void keynote_release( void )
+{
+ if ( synth_port )
+ synth_release_region( synth_port, SYNTH_IO_EXTENT );
+ synth_port = 0;
+}
+
+static int synth_is_alive( void )
+{
+ synth_alive = 1;
+ return 1;
+}
+
+static const char init_string[] = "[t][n7,1][n8,0]";
+
+static string_var stringvars[] = {
+ { CAPS_START, "[f130]" },
+ { CAPS_STOP, "[f90]" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\04%c ", 8, 0, 10, 81, -8, 0 },
+ { PITCH, "[f%d]", 5, 0, 9, 40, 10, 0 },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_keypc = {"keypc", "1.1", "Keynote PC",
+ init_string, 500, 50, 50, 1000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, keynote_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL };
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_ltlk.c linux-2.4.30/drivers/char/speakup/speakup_ltlk.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_ltlk.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_ltlk.c 2003-10-07 18:04:35.000000000 -0700
@@ -0,0 +1,215 @@
+/*
+ * originally written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+
+#include "speakup_dtlk.h" /* local header file for LiteTalk values */
+
+#define MY_SYNTH synth_ltlk
+#define PROCSPEECH 0x0d
+#define synth_full( ) ( !( inb( synth_port_tts + UART_MSR ) & UART_MSR_CTS ) )
+
+static inline int wait_for_xmitr( void )
+{
+ static int timeouts = 0; /* sequential number of timeouts */
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
+ synth_alive = 0;
+ timeouts = 0;
+ return 0;
+ }
+ do { /* holding register empty? */
+ check = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn( "%s: register timed out\n", synth->long_name );
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
+ tmout = SPK_XMITR_TIMEOUT;
+ do { /* CTS */
+ check = inb( synth_port_tts + UART_MSR );
+ if ( --tmout == 0 ) {
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
+ timeouts = 0;
+ return 1;
+}
+
+static inline int spk_serial_out( const char ch )
+{
+ if ( synth_alive && wait_for_xmitr( ) ) {
+ outb( ch, synth_port_tts );
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned char spk_serial_in( void )
+{
+ int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
+ do {
+ lsr = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn( "time out while waiting for input.\n" );
+ return 0xff;
+ }
+ } while ( ( lsr & UART_LSR_DR ) != UART_LSR_DR );
+ c = inb( synth_port_tts + UART_RX );
+ return ( unsigned char ) c;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+ synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( !spk_serial_out( ch ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( jiffies >= jiff_max && ch == SPACE ) {
+ spk_serial_out( PROCSPEECH );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ spk_serial_out( PROCSPEECH );
+ synth_done ( );
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush( void )
+{
+ spk_serial_out( SYNTH_CLEAR );
+}
+
+/* interrogate the LiteTalk and print its settings */
+static void synth_interrogate( void )
+{
+ unsigned char *t, i;
+ unsigned char buf[50], rom_v[20];
+ synth_immediate( "\x18\x01?" );
+ for ( i = 0; i < 50; i++ ) {
+ buf[i] = spk_serial_in( );
+ if ( i > 2 && buf[i] == 0x7f ) break;
+ }
+ t = buf+2;
+ for ( i = 0; *t != '\r'; t++ ) {
+ rom_v[i] = *t;
+ if (i++ > 48) break;
+ }
+ rom_v[i] = 0;
+ pr_info( "%s: ROM version: %s\n", synth->long_name, rom_v );
+}
+
+static int serprobe( int index )
+{
+ struct serial_state *ser = spk_serial_init( index );
+ if ( ser == NULL ) return -1;
+ outb( 0, ser->port );
+ mdelay( 1 );
+ outb( '\r', ser->port );
+ /* ignore any error results, if port was forced */
+ if ( synth_port_forced ) return 0;
+ /* check for device... */
+ if ( !synth_immediate( "\x18" ) ) return 0;
+ spk_serial_release( );
+ synth_alive = 0; /* try next port */
+ return -1;
+}
+
+static int synth_probe( void )
+{
+ int i, failed=0;
+ pr_info( "Probing for %s.\n", synth->long_name );
+ for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ synth_interrogate( );
+ pr_info( "%s: at %03x-%03x, driver %s\n", synth->long_name,
+ synth_port_tts, synth_port_tts + 7, synth->version );
+ return 0;
+}
+
+static int synth_is_alive( void )
+{
+ if ( synth_alive ) return 1;
+ if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
+ synth_alive = 1;
+ synth_write_string( synth->init );
+ return 2;
+ } else pr_warn( "%s: can't restart synth\n", synth->long_name );
+ return 0;
+}
+
+static const char init_string[] = "\01@\x01\x31y\n\0";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\x01+35p" },
+ { CAPS_STOP, "\x01-35p" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\x01%ds", 8, 0, 9, 0, 0, 0 },
+ { PITCH, "\x01%dp", 50, 0, 99, 0, 0, 0 },
+ { VOL, "\x01%dv", 5, 0, 9, 0, 0, 0 },
+ { TONE, "\x01%dx", 1, 0, 2, 0, 0, 0 },
+ { PUNCT, "\x01%db", 7, 0, 15, 0, 0, 0 },
+ { VOICE, "\x01%do", 0, 0, 7, 0, 0, 0 },
+ { FREQ, "\x01%df", 5, 0, 9, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_ltlk = { "ltlk", "1.1", "LiteTalk",
+ init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_sftsyn.c linux-2.4.30/drivers/char/speakup/speakup_sftsyn.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_sftsyn.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_sftsyn.c 2004-06-07 07:53:20.000000000 -0700
@@ -0,0 +1,175 @@
+/* speakup_sftsynth.c - speakup driver to register and make available
+ * a user space device for software synthesizers. written by: Kirk
+ * Reiser
+
+ Copyright (C) 2003 Kirk Reiser.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver. */
+
+#include
+#include /* for misc_register, and SYNTH_MINOR */
+#include // for poll_wait()
+#include "spk_priv.h"
+
+#define MY_SYNTH synth_sftsyn
+#define SOFTSYNTH_MINOR 26 // might as well give it one more than /dev/synth
+#define PROCSPEECH 0x0d
+#define CLEAR_SYNTH 0x18
+
+static struct miscdevice synth_device;
+static int misc_registered = 0;
+static int dev_opened = 0;
+static struct semaphore sem;
+DECLARE_WAIT_QUEUE_HEAD ( wait_on_output );
+
+
+static int softsynth_open (struct inode *inode, struct file *fp)
+{
+ if (dev_opened) return -EBUSY;
+ if ((fp->f_flags && O_ACCMODE) != O_RDONLY ) return -EPERM;
+ sema_init( &sem, 1 );
+ dev_opened++;
+ return 0;
+}
+
+static int softsynth_close (struct inode *inode, struct file *fp)
+{
+ fp->f_op = NULL;
+ dev_opened = 0;
+ return 0;
+}
+
+static ssize_t softsynth_read (struct file *fp, char *buf, size_t count, loff_t *pos)
+{
+int chars_sent=0;
+
+ if (down_interruptible( &sem )) return -ERESTARTSYS;
+ while (synth_buff_in == synth_buff_out) {
+ up ( &sem );
+ if (fp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ if (wait_event_interruptible( wait_on_output, (synth_buff_in > synth_buff_out)))
+ return -ERESTARTSYS;
+ if (down_interruptible( &sem )) return -ERESTARTSYS;
+ }
+
+ chars_sent = (count > synth_buff_in-synth_buff_out)
+ ? synth_buff_in-synth_buff_out : count;
+ if (copy_to_user(buf, (char *) synth_buff_out, chars_sent)) {
+ up ( &sem);
+ return -EFAULT;
+ }
+ synth_buff_out += chars_sent;
+ *pos += chars_sent;
+ if (synth_buff_out >= synth_buff_in) {
+ synth_done();
+ *pos = 0;
+ }
+ up ( &sem );
+ return chars_sent;
+}
+
+static unsigned int softsynth_poll (struct file *fp, struct poll_table_struct *wait)
+{
+ poll_wait(fp, &wait_on_output, wait);
+
+ if (synth_buff_out < synth_buff_in)
+ return (POLLIN | POLLRDNORM);
+ return 0;
+}
+
+static void
+softsynth_flush( void )
+{
+ synth_write( "\x18", 1 );
+}
+
+static struct file_operations softsynth_fops = {
+ poll:softsynth_poll,
+ read:softsynth_read,
+ open:softsynth_open,
+ release:softsynth_close,
+};
+
+
+static int
+softsynth_probe( void )
+{
+
+ if ( misc_registered != 0 ) return 0;
+ memset( &synth_device, 0, sizeof( synth_device ) );
+ synth_device.minor = SOFTSYNTH_MINOR;
+ synth_device.name = "softsynth";
+ synth_device.fops = &softsynth_fops;
+ if ( misc_register ( &synth_device ) ) {
+ pr_warn("Couldn't initialize miscdevice /dev/softsynth.\n" );
+ return -ENODEV;
+ }
+
+ misc_registered = 1;
+ pr_info("initialized device: /dev/softsynth, node (MAJOR 10, MINOR 26)\n" );
+ return 0;
+}
+
+static void
+softsynth_release(void)
+{
+ misc_deregister( &synth_device );
+ misc_registered = 0;
+ pr_info("unregistered /dev/softsynth\n");
+}
+
+static void
+softsynth_start ( void )
+{
+ wake_up_interruptible ( &wait_on_output );
+}
+
+static int
+softsynth_is_alive( void )
+{
+ if ( synth_alive ) return 1;
+ return 0;
+}
+
+static const char init_string[] = "\01@\x01\x31y\n";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\x01+3p" },
+ { CAPS_STOP, "\x01-3p" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\x01%ds", 5, 0, 9, 0, 0, 0 },
+ { PITCH, "\x01%dp", 5, 0, 9, 0, 0, 0 },
+ { VOL, "\x01%dv", 5, 0, 9, 0, 0, 0 },
+ { TONE, "\x01%dx", 1, 0, 2, 0, 0, 0 },
+ { PUNCT, "\x01%db", 7, 0, 15, 0, 0, 0 },
+ { VOICE, "\x01%do", 0, 0, 7, 0, 0, 0 },
+ { FREQ, "\x01%df", 5, 0, 9, 0, 0, 0 },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_sftsyn = { "sftsyn", "0.3", "software synth",
+ init_string, 0, 0, 0, 0, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, softsynth_probe, softsynth_release, NULL,
+ NULL, softsynth_start, softsynth_flush, softsynth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_spkout.c linux-2.4.30/drivers/char/speakup/speakup_spkout.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_spkout.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_spkout.c 2003-11-12 12:41:34.000000000 -0800
@@ -0,0 +1,188 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+
+#define MY_SYNTH synth_spkout
+#define SYNTH_CLEAR 0x18
+#define PROCSPEECH '\r'
+
+static int wait_for_xmitr(void)
+{
+ static int timeouts = 0; /* sequential number of timeouts */
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ((synth_alive) && (timeouts >= NUM_DISABLE_TIMEOUTS)) {
+ synth_alive = 0;
+ timeouts = 0;
+ return 0;
+ }
+ do {
+ check = inb(synth_port_tts + UART_LSR);
+ if (--tmout == 0) {
+ pr_warn("SpeakOut: timed out\n");
+ timeouts++;
+ return 0;
+ }
+ } while ((check & BOTH_EMPTY) != BOTH_EMPTY);
+ tmout = SPK_XMITR_TIMEOUT;
+ do {
+ check = inb(synth_port_tts + UART_MSR);
+ if (--tmout == 0) {
+ timeouts++;
+ return 0;
+ }
+ } while ((check & UART_MSR_CTS) != UART_MSR_CTS);
+ timeouts = 0;
+ return 1;
+}
+
+static inline int spk_serial_out(const char ch)
+{
+ if (synth_alive && wait_for_xmitr()) {
+ outb(ch, synth_port_tts);
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned char spk_serial_in(void)
+{
+ int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
+ do {
+ lsr = inb(synth_port_tts + UART_LSR);
+ if (--tmout == 0) return 0xff;
+ } while (!(lsr & UART_LSR_DR));
+ c = inb(synth_port_tts + UART_RX);
+ return (unsigned char) c;
+}
+
+static void do_catch_up(unsigned long data)
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+synth_stop_timer();
+ while (synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if (ch == 0x0a) ch = PROCSPEECH;
+ if (!spk_serial_out(ch )) {
+ synth_delay(synth_full_time);
+ return;
+ }
+ synth_buff_out++;
+ if (jiffies >= jiff_max && ch == SPACE ) {
+ spk_serial_out(PROCSPEECH);
+ synth_delay(synth_delay_time);
+ return;
+ }
+ }
+spk_serial_out(PROCSPEECH);
+ synth_done( );
+}
+
+static char *synth_immediate (char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if (ch == 0x0a) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush(void)
+{
+ while ((inb(synth_port_tts + UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY);
+ outb(SYNTH_CLEAR, synth_port_tts);
+}
+
+static int serprobe(int index)
+{
+ struct serial_state *ser = spk_serial_init(index);
+ if ( ser == NULL ) return -1;
+ /* ignore any error results, if port was forced */
+ if (synth_port_forced) return 0;
+ /* check for speak out now... */
+ synth_immediate( "\x05[\x0f\r" );
+ mdelay( 10 ); //failed with no delay
+ if (spk_serial_in() == 0x0f) return 0;
+ synth_release_region(ser->port,8);
+ synth_alive = 0;
+ return -1;
+}
+
+static int synth_probe(void)
+{
+int i=0, failed=0;
+ pr_info("Probing for %s.\n", synth->long_name);
+ for (i=SPK_LO_TTY; i <= SPK_HI_TTY; i++) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info("%s Out: not found\n", synth->long_name);
+ return -ENODEV;
+ }
+ pr_info("%s Out: %03x-%03x, Driver version %s,\n", synth->long_name,
+ synth_port_tts, synth_port_tts + 7, synth->version);
+ return 0;
+}
+
+static int synth_is_alive(void)
+{
+ if (synth_alive) return 1;
+ if (wait_for_xmitr() > 0) { /* restart */
+ synth_alive = 1;
+ synth_write_string(synth->init );
+ return 2;
+ } else pr_warn("%s Out: can't restart synth\n", synth->long_name);
+ return 0;
+}
+
+static const char init_string[] = "\005W1\005I2\005C3";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\x05P+" },
+ { CAPS_STOP, "\x05P-" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\x05R%d", 7, 0, 9, 0, 0, 0 },
+ { PITCH, "\x05P%d", 3, 0, 9, 0, 0, 0 },
+ { VOL, "\x05V%d", 9, 0, 9, 0, 0, 0 },
+ { TONE, "\x05T%c", 8, 0, 25, 65, 0, 0 },
+ { PUNCT, "\x05M%c", 0, 0, 3, 0, 0, "nsma" },
+ V_LAST_NUM
+};
+
+struct spk_synth synth_spkout = {"spkout", "1.1", "Speakout",
+ init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakup_txprt.c linux-2.4.30/drivers/char/speakup/speakup_txprt.c
--- linux-2.4.30.orig/drivers/char/speakup/speakup_txprt.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakup_txprt.c 2003-10-07 18:04:35.000000000 -0700
@@ -0,0 +1,195 @@
+/*
+ * originially written by: Kirk Reiser
+* this version considerably modified by David Borowski, david575@rogers.com
+
+ Copyright (C) 1998-99 Kirk Reiser.
+ Copyright (C) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ * this code is specificly written as a driver for the speakup screenreview
+ * package and is not a general device driver.
+ */
+#include "spk_priv.h"
+#include "serialio.h"
+
+#define MY_SYNTH synth_txprt
+#define DRV_VERSION "1.2"
+#define SYNTH_CLEAR 0x18
+#define PROCSPEECH '\r' /* process speech char */
+
+static int timeouts = 0; /* sequential number of timeouts */
+
+static int wait_for_xmitr( void )
+{
+ int check, tmout = SPK_XMITR_TIMEOUT;
+ if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
+ synth_alive = 0;
+ timeouts = 0;
+ return 0;
+ }
+ do {
+ check = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) {
+ pr_warn( "TXPRT: timed out\n" );
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
+ tmout = SPK_XMITR_TIMEOUT;
+ do {
+ check = inb( synth_port_tts + UART_MSR );
+ if ( --tmout == 0 ) {
+ timeouts++;
+ return 0;
+ }
+ } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
+ timeouts = 0;
+ return 1;
+}
+
+static inline int spk_serial_out( const char ch )
+{
+ if ( synth_alive && wait_for_xmitr( ) ) {
+ outb( ch, synth_port_tts );
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned char spk_serial_in( void )
+{
+ int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
+ do {
+ lsr = inb( synth_port_tts + UART_LSR );
+ if ( --tmout == 0 ) return 0xff;
+ } while ( !( lsr & UART_LSR_DR ) );
+ c = inb( synth_port_tts + UART_RX );
+ return ( unsigned char ) c;
+}
+
+static void do_catch_up( unsigned long data )
+{
+ unsigned long jiff_max = jiffies+synth_jiffy_delta;
+ u_char ch;
+
+ synth_stop_timer( );
+ while ( synth_buff_out < synth_buff_in ) {
+ ch = *synth_buff_out;
+ if ( ch == '\n' ) ch = PROCSPEECH;
+ if ( !spk_serial_out( ch ) ) {
+ synth_delay( synth_full_time );
+ return;
+ }
+ synth_buff_out++;
+ if ( jiffies >= jiff_max && ch == ' ' ) {
+ spk_serial_out( PROCSPEECH );
+ synth_delay( synth_delay_time );
+ return;
+ }
+ }
+ spk_serial_out( PROCSPEECH );
+ synth_done( );
+}
+
+static char *synth_immediate ( char *buf )
+{
+ u_char ch;
+ while ( ( ch = *buf ) ) {
+ if ( ch == 0x0a ) ch = PROCSPEECH;
+ if ( wait_for_xmitr( ) )
+ outb( ch, synth_port_tts );
+ else return buf;
+ buf++;
+ }
+ return 0;
+}
+
+static void synth_flush ( void )
+{
+ spk_serial_out ( SYNTH_CLEAR );
+}
+
+static int serprobe( int index )
+{
+ u_char test=0;
+ struct serial_state *ser = spk_serial_init( index );
+ if ( ser == NULL ) return -1;
+ if ( synth_port_forced ) return 0;
+ /* check for txprt now... */
+ if (synth_immediate( "\x05$" ))
+ pr_warn("synth_immediate could not unload\n");
+ if (synth_immediate( "\x05Ik" ))
+ pr_warn("synth_immediate could not unload again\n");
+ if (synth_immediate( "\x05Q\r" ))
+ pr_warn("synth_immediate could not unload a third time\n");
+ if ( ( test = spk_serial_in( ) ) == 'k' ) return 0;
+ else pr_warn( "synth returned %x on port %03lx\n", test, ser->port );
+ synth_release_region( ser->port,8 );
+ timeouts = synth_alive = 0;
+ return -1;
+}
+
+static int synth_probe( void )
+{
+ int i, failed=0;
+ pr_info( "Probing for %s.\n", synth->long_name );
+ for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
+ if (( failed = serprobe( i )) == 0 ) break; /* found it */
+ }
+ if ( failed ) {
+ pr_info( "%s: not found\n", synth->long_name );
+ return -ENODEV;
+ }
+ pr_info( "%s: %03x-%03x..\n", synth->long_name, (int) synth_port_tts, (int) synth_port_tts+7 );
+ pr_info( "%s: driver version %s.\n", synth->long_name, synth->version);
+ return 0;
+}
+
+static int synth_is_alive( void )
+{
+ if ( synth_alive ) return 1;
+ if ( wait_for_xmitr( ) > 0 ) { /* restart */
+ synth_alive = 1;
+ synth_write_string( synth->init );
+ return 2;
+ }
+ pr_warn( "%s: can't restart synth\n", synth->long_name );
+ return 0;
+}
+
+static const char init_string[] = "\x05N1";
+
+static string_var stringvars[] = {
+ { CAPS_START, "\x05P8" },
+ { CAPS_STOP, "\x05P5" },
+ V_LAST_STRING
+};
+static num_var numvars[] = {
+ { RATE, "\x05R%d", 5, 0, 9, 0, 0, 0 },
+ { PITCH, "\x05P%d", 5, 0, 9, 0, 0, 0 },
+ { VOL, "\x05V%d", 5, 0, 9, 0, 0, 0 },
+ { TONE, "\x05T%c", 12, 0, 25, 61, 0, 0 },
+ V_LAST_NUM
+ };
+
+struct spk_synth synth_txprt = {"txprt", DRV_VERSION, "Transport",
+ init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
+ stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
+ do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
+
+#ifdef MODULE
+#include "mod_code.c"
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakupconf linux-2.4.30/drivers/char/speakup/speakupconf
--- linux-2.4.30.orig/drivers/char/speakup/speakupconf 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakupconf 2004-05-13 10:38:31.000000000 -0700
@@ -0,0 +1,51 @@
+#!/bin/sh
+# script to load/save all the vars in speakup
+# speakupconf save or speakupconf load
+# if root saves in /etc/speakup/ else in $HOME/.speakup/
+if [ $UID -eq "0" ]; then
+ SAVEDIR="/etc/speakup"
+else
+ SAVEDIR="$HOME/.speakup"
+fi
+if [ ! -d /proc/speakup ]; then
+ echo "no directory /proc/speakup"
+ exit 0
+fi
+SYNTH=`cat /proc/speakup/synth_name`
+case "$1" in
+*save)
+ if [ ! -d $SAVEDIR ] ; then
+ echo creating $SAVEDIR
+ mkdir $SAVEDIR
+ fi
+ if [ ! -d $SAVEDIR/$SYNTH ] ; then
+ echo creating $SAVEDIR/$SYNTH
+ mkdir $SAVEDIR/$SYNTH
+ fi
+ cd /proc/speakup
+ SAVELIST=` find . -perm -6 |sed 's/..//' |fgrep -v synth`
+ for f in $SAVELIST; do
+ cp $f $SAVEDIR/$SYNTH/$f
+ done
+;;
+*load)
+ if [ ! -d $SAVEDIR ] ; then
+ echo no directory $SAVEDIR
+ exit 1
+ fi
+ if [ ! -d $SAVEDIR/$SYNTH ] ; then
+ echo no directory $SAVEDIR/$SYNTH
+ exit 1
+ fi
+ cd $SAVEDIR/$SYNTH
+ for f in *; do
+ if [ -w /proc/speakup/$f ]; then
+ cat $f >/proc/speakup/$f
+ fi
+ done
+;;
+*)
+ echo "usage: speakupconf load/save"
+ exit 1
+;;
+esac
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakupmap.h linux-2.4.30/drivers/char/speakup/speakupmap.h
--- linux-2.4.30.orig/drivers/char/speakup/speakupmap.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakupmap.h 2004-05-13 10:38:31.000000000 -0700
@@ -0,0 +1,64 @@
+ 119, 61, 6,
+ 0, 16, 17, 32, 20, 48, 0,
+ 2, 0, 78, 0, 0, 0, 0,
+ 3, 0, 79, 0, 0, 0, 0,
+ 4, 0, 76, 0, 0, 0, 0,
+ 5, 0, 77, 0, 0, 0, 0,
+ 6, 0, 74, 0, 0, 0, 0,
+ 7, 0, 75, 0, 0, 0, 0,
+ 9, 0, 5, 0, 0, 0, 0,
+ 10, 0, 4, 0, 0, 0, 0,
+ 11, 0, 0, 0, 0, 1, 0,
+ 12, 0, 27, 33, 0, 0, 0,
+ 21, 0, 29, 0, 0, 17, 0,
+ 22, 0, 15, 0, 0, 0, 0,
+ 23, 0, 14, 0, 0, 0, 28,
+ 24, 0, 16, 0, 0, 0, 0,
+ 25, 0, 30, 0, 0, 18, 0,
+ 28, 0, 3, 0, 0, 26, 0,
+ 35, 0, 31, 0, 0, 0, 0,
+ 36, 0, 12, 0, 0, 0, 0,
+ 37, 0, 11, 0, 0, 0, 22,
+ 38, 0, 13, 0, 0, 0, 0,
+ 39, 0, 32, 0, 0, 7, 0,
+ 40, 0, 23, 0, 0, 0, 0,
+ 44, 0, 44, 0, 0, 0, 0,
+ 49, 0, 24, 0, 0, 0, 0,
+ 50, 0, 9, 6, 0, 19, 0,
+ 51, 0, 8, 0, 0, 0, 36,
+ 52, 0, 10, 0, 0, 20, 0,
+ 53, 0, 25, 0, 0, 0, 0,
+ 55, 46, 1, 0, 0, 0, 0,
+ 58, 128, 128, 0, 0, 0, 0,
+ 59, 0, 45, 0, 0, 0, 0,
+ 60, 0, 40, 0, 0, 0, 0,
+ 61, 0, 41, 0, 0, 0, 0,
+ 62, 0, 42, 0, 0, 0, 0,
+ 63, 0, 34, 0, 0, 0, 0,
+ 64, 0, 35, 0, 0, 0, 0,
+ 65, 0, 37, 0, 0, 0, 0,
+ 66, 0, 38, 0, 0, 0, 0,
+ 67, 0, 66, 39, 0, 0, 0,
+ 68, 0, 67, 0, 0, 0, 0,
+ 71, 15, 19, 0, 0, 0, 0,
+ 72, 14, 29, 0, 28, 0, 0,
+ 73, 16, 17, 0, 0, 0, 0,
+ 74, 27, 33, 0, 0, 0, 0,
+ 75, 12, 31, 0, 0, 0, 0,
+ 76, 11, 21, 0, 22, 0, 0,
+ 77, 13, 32, 0, 0, 0, 0,
+ 78, 23, 43, 0, 0, 0, 0,
+ 79, 9, 20, 0, 0, 0, 0,
+ 80, 8, 30, 0, 36, 0, 0,
+ 81, 10, 18, 0, 0, 0, 0,
+ 82, 128, 128, 0, 0, 0, 0,
+ 83, 24, 25, 0, 0, 0, 0,
+ 87, 0, 68, 0, 0, 0, 0,
+ 88, 0, 69, 0, 0, 0, 0,
+ 96, 3, 26, 0, 0, 0, 0,
+ 98, 4, 5, 0, 0, 0, 0,
+ 99, 2, 0, 0, 0, 0, 0,
+ 104, 0, 6, 0, 0, 0, 0,
+ 109, 0, 7, 0, 0, 0, 0,
+ 125, 128, 128, 0, 0, 0, 0,
+ 0, 119
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/speakupmap.map linux-2.4.30/drivers/char/speakup/speakupmap.map
--- linux-2.4.30.orig/drivers/char/speakup/speakupmap.map 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/speakupmap.map 2004-05-13 10:38:31.000000000 -0700
@@ -0,0 +1,91 @@
+spk key_f9 = punc_level_dec
+spk key_f10 = punc_level_inc
+spk key_f11 = reading_punc_dec
+spk key_f12 = reading_punc_inc
+spk key_1 = vol_dec
+spk key_2 = vol_inc
+spk key_3 = pitch_dec
+spk key_4 = pitch_inc
+spk key_5 = rate_dec
+spk key_6 = rate_inc
+key_kpasterisk = toggle_cursoring
+spk key_kpasterisk = speakup_goto
+spk key_f1 = speakup_help
+spk key_f2 = set_win
+spk key_f3 = clear_win
+spk key_f4 = enable_win
+spk key_f5 = edit_some
+spk key_f6 = edit_most
+spk key_f7 = edit_delim
+spk key_f8 = edit_repeat
+shift spk key_f9 = edit_exnum
+ key_kp7 = say_prev_line
+spk key_kp7 = left_edge
+ key_kp8 = say_line
+double key_kp8 = say_line_indent
+spk key_kp8 = say_from_top
+ key_kp9 = say_next_line
+spk key_kp9 = top_edge
+ key_kpminus = speakup_parked
+spk key_kpminus = say_char_num
+ key_kp4 = say_prev_word
+spk key_kp4 = say_from_left
+ key_kp5 = say_word
+double key_kp5 = spell_word
+spk key_kp5 = spell_phonetic
+ key_kp6 = say_next_word
+spk key_kp6 = say_to_right
+ key_kpplus = say_screen
+spk key_kpplus = say_win
+ key_kp1 = say_prev_char
+spk key_kp1 = right_edge
+ key_kp2 = say_char
+spk key_kp2 = say_to_bottom
+double key_kp2 = say_phonetic_char
+ key_kp3 = say_next_char
+spk key_kp3 = bottom_edge
+ key_kp0 = spk_key
+ key_kpdot = say_position
+spk key_kpdot = say_attributes
+key_kpenter = speakup_quiet
+spk key_kpenter = speakup_off
+key_sysrq = speech_kill
+ key_kpslash = speakup_cut
+spk key_kpslash = speakup_paste
+spk key_pageup = say_first_char
+spk key_pagedown = say_last_char
+key_capslock = spk_key
+ spk key_z = spk_lock
+key_leftmeta = spk_key
+ctrl spk key_0 = speakup_goto
+spk key_u = say_prev_line
+spk key_i = say_line
+double spk key_i = say_line_indent
+spk key_o = say_next_line
+spk key_minus = speakup_parked
+shift spk key_minus = say_char_num
+spk key_j = say_prev_word
+spk key_k = say_word
+double spk key_k = spell_word
+spk key_l = say_next_word
+spk key_m = say_prev_char
+spk key_comma = say_char
+double spk key_comma = say_phonetic_char
+spk key_dot = say_next_char
+spk key_n = say_position
+ ctrl spk key_m = left_edge
+ ctrl spk key_y = top_edge
+ ctrl spk key_dot = right_edge
+ctrl spk key_p = bottom_edge
+spk key_apostrophe = say_screen
+spk key_h = say_from_left
+spk key_y = say_from_top
+spk key_semicolon = say_to_right
+spk key_p = say_to_bottom
+spk key_slash = say_attributes
+ spk key_enter = speakup_quiet
+ ctrl spk key_enter = speakup_off
+ spk key_9 = speakup_cut
+spk key_8 = speakup_paste
+shift spk key_m = say_first_char
+ ctrl spk key_semicolon = say_last_char
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/spk_con_module.h linux-2.4.30/drivers/char/speakup/spk_con_module.h
--- linux-2.4.30.orig/drivers/char/speakup/spk_con_module.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/spk_con_module.h 2003-05-09 12:17:56.000000000 -0700
@@ -0,0 +1,43 @@
+/* written bby David Borowski.
+ Copyright (C ) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* included by ../console.c for speakup modularization */
+
+static spk_con_func addr_spk_allocate = NULL;
+static spk_con_func addr_spk_bs = NULL;
+static spk_write_func addr_spk_con_write = NULL;
+static spk_con_func addr_spk_con_update = NULL;
+
+#define speakup_allocate(c) if (addr_spk_allocate) (*addr_spk_allocate)(c)
+#define speakup_bs(c) if (addr_spk_bs) (*addr_spk_bs)(c)
+#define speakup_con_write(c,s,l) if (addr_spk_con_write) (*addr_spk_con_write)(c,s,l)
+#define speakup_con_update(c) if (addr_spk_con_update) (*addr_spk_con_update)(c)
+
+extern spk_key_func addr_spk_key;
+
+void speakup_set_addresses( spk_con_func allocate, spk_con_func bs,
+ spk_write_func con_write, spk_con_func con_update, spk_key_func key )
+{
+ addr_spk_allocate = allocate;
+ addr_spk_bs = bs;
+ addr_spk_con_write = con_write;
+ addr_spk_con_update = con_update;
+ addr_spk_key = key;
+}
+
+EXPORT_SYMBOL(speakup_set_addresses);
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/spk_priv.h linux-2.4.30/drivers/char/speakup/spk_priv.h
--- linux-2.4.30.orig/drivers/char/speakup/spk_priv.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/spk_priv.h 2003-10-10 13:08:42.000000000 -0700
@@ -0,0 +1,258 @@
+/* spk_priv.h
+ review functions for the speakup screen review package.
+ originally written by: Kirk Reiser and Andy Berdan.
+
+ extensively modified by David Borowski.
+
+ Copyright (C ) 1998 Kirk Reiser.
+ Copyright (C ) 2003 David Borowski.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef __SPEAKUP_PRIVATE_H
+#define __SPEAKUP_PRIVATE_H
+
+#define KERNEL
+#include
+#include
+#include
+#include
+#include
+#include /* for inb_p, outb_p, inb, outb, etc... */
+#include
+#include /* for wait_queue */
+#include /* for __init */
+#include
+#ifdef CONFIG_PROC_FS
+#include
+#endif
+#include
+#include "keyinfo.h"
+
+#define SHIFT_TBL_SIZE 64
+/* proc permissions */
+#define USER_R ( S_IFREG|S_IRUGO )
+#define USER_W ( S_IFREG|S_IWUGO )
+#define USER_RW ( S_IFREG|S_IRUGO|S_IWUGO )
+#define ROOT_W ( S_IFREG|S_IRUGO|S_IWUSR )
+
+#define V_LAST_STRING { -1, 0 }
+#define V_LAST_NUM { -1, 0, 0, 0, 0, 0, 0, 0 }
+#define TOGGLE_0 0, 0, 0, 1, 0, 0, 0
+#define TOGGLE_1 0, 1, 0, 1, 0, 0, 0
+#define MAXVARLEN 15
+#define TAB 0x9
+#define SPACE 0x20
+#define CAP_A 'A'
+#define CAP_Z 'Z'
+#define SYNTH_OK 0x0001
+#define B_ALPHA 0x0002
+#define ALPHA 0x0003
+#define B_CAP 0x0004
+#define A_CAP 0x0007
+#define B_NUM 0x0008
+#define NUM 0x0009
+#define ALPHANUM ( B_ALPHA|B_NUM )
+#define SOME 0x0010
+#define MOST 0x0020
+#define PUNC 0x0040
+#define A_PUNC 0x0041
+#define B_WDLM 0x0080
+#define WDLM 0x0081
+#define B_EXNUM 0x0100
+#define CH_RPT 0x0200
+#define B_CTL 0x0400
+#define A_CTL B_CTL+SYNTH_OK
+#define B_SYM 0x0800
+#define B_CAPSYM B_CAP|B_SYM
+#define IS_WDLM( x ) ( spk_chartab[( ( u_char )x )]&B_WDLM )
+#define IS_CHAR( x, type ) ( spk_chartab[( ( u_char )x )]&type )
+#define SET_DEFAULT -4
+#define E_RANGE -3
+#define E_TOOLONG -2
+#define E_UNDEF -1
+enum { VAR_NUM = 0, VAR_TIME, VAR_STRING, VAR_PROC };
+enum { E_DEFAULT = 0, E_SET, E_INC, E_DEC };
+
+#define PROC_READ_PROTOTYPE char *page, char **start, off_t off, \
+ int count, int *eof, void *data
+#define PROC_WRITE_PROTOTYPE struct file *file, const char *buffer, \
+ u_long count, void *data
+
+#ifndef MIN
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
+#endif
+
+typedef int (*special_func)( int currcons, u_char type, u_char ch, u_short key );
+typedef struct st_var_header var_header;
+typedef struct st_num_var num_var;
+typedef struct st_string_var string_var;
+typedef struct st_proc_var proc_var;
+
+struct st_var_header {
+ char *name;
+ short var_id, var_type, proc_mode;
+ void *proc_entry;
+ void *p_val; /* ptr to programs variable to store value */
+ void *data; /* ptr to the vars data */
+};
+
+/* next are data for different var types */
+struct st_num_var {
+ short var_id;
+ char *synth_fmt;
+ short default_val, low, high;
+ short offset, multiplier; /* for fiddling rates etc. */
+ char *out_str; /* if synth needs char representation of number */
+ short value; /* current value */
+};
+struct st_string_var {
+ short var_id;
+ char *default_val;
+};
+struct st_proc_var {
+ short var_id;
+ int ( *read_proc )( PROC_READ_PROTOTYPE );
+ int ( *write_proc )( PROC_WRITE_PROTOTYPE );
+ short value;
+};
+
+typedef struct st_bits_data bits_data;
+struct st_bits_data { /* punc, repeats, word delim bits */
+ char *name;
+ char *value;
+ short mask;
+};
+
+extern var_header *var_ptrs[MAXVARS];
+extern proc_var spk_proc_vars[];
+char *xlate( char * );
+char *speakup_s2i( char *, short * );
+int speakup_register_var( num_var *var );
+void speakup_unregister_var( short var_id );
+extern var_header *get_var_header( short var_id );
+extern int set_num_var( short val, var_header *var, int how );
+
+/* let's develop a structure for keeping our goodies in. */
+typedef struct st_spk_t spk_t;
+#define spk_size (sizeof( spk_t))
+struct st_spk_t {
+ u_long reading_x, cursor_x;
+ u_long reading_y, cursor_y;
+ u_long reading_pos, cursor_pos;
+ u_long go_x, go_pos;
+ u_long w_top, w_bottom, w_left, w_right;
+ u_char w_start, w_enabled;
+ u_char reading_attr, old_attr;
+ char parked, shut_up;
+};
+
+/* now some defines to make these easier to use. */
+#define spk_shut_up speakup_console[currcons]->shut_up
+#define spk_killed ( speakup_console[currcons]->shut_up & 0x40 )
+#define spk_x speakup_console[currcons]->reading_x
+#define spk_cx speakup_console[currcons]->cursor_x
+#define spk_y speakup_console[currcons]->reading_y
+#define spk_cy speakup_console[currcons]->cursor_y
+#define spk_pos ( speakup_console[currcons]->reading_pos )
+#define spk_cp speakup_console[currcons]->cursor_pos
+#define goto_pos ( speakup_console[currcons]->go_pos )
+#define goto_x ( speakup_console[currcons]->go_x )
+#define win_top ( speakup_console[currcons]->w_top )
+#define win_bottom ( speakup_console[currcons]->w_bottom )
+#define win_left ( speakup_console[currcons]->w_left )
+#define win_right ( speakup_console[currcons]->w_right )
+#define win_start ( speakup_console[currcons]->w_start )
+#define win_enabled ( speakup_console[currcons]->w_enabled )
+#define spk_attr speakup_console[currcons]->reading_attr
+#define spk_old_attr speakup_console[currcons]->old_attr
+#define spk_parked speakup_console[currcons]->parked
+#define SYNTH_CHECK 20030716 /* today's date ought to do for check value */
+/* synth flags, for odd synths */
+#define SF_DEC 1 /* to fiddle puncs in alpha strings so it doesn't spell */
+
+struct spk_synth {
+ const char *name;
+ const char *version;
+ const char *long_name;
+ const char *init;
+ short delay, trigger, jiffies, full, flush_wait, flags;
+ const int checkval; /* for validating a proper synth module */
+ string_var *string_vars;
+ num_var *num_vars;
+ int ( *probe )( void );
+ void ( *release )( void );
+ char *( *synth_immediate )( char *buff );
+ void ( *catch_up )( u_long data );
+ void ( *start )( void );
+ void ( *flush )( void );
+ int ( *is_alive )( void );
+ int ( *synth_adjust )( var_header *var );
+};
+
+extern struct spk_synth *synth;
+int synth_request_region( u_long, u_long );
+int synth_release_region( u_long, u_long );
+void spk_serial_release( void );
+extern int synth_port_tts, synth_port_forced;
+extern volatile int synth_timer_active;
+#define declare_timer( name ) struct timer_list name;
+#if (LINUX_VERSION_CODE >= 132419)
+#define start_timer( name ) if ( ! name.entry.prev ) add_timer ( & name )
+#define stop_timer( name ) del_timer ( & name ); name.entry.prev = NULL
+#else
+#define start_timer( name ) if ( ! name.list.prev ) add_timer ( & name )
+#define stop_timer( name ) del_timer ( & name )
+#endif
+#define declare_sleeper( name ) wait_queue_head_t name
+#define init_sleeper( name ) init_waitqueue_head ( &name )
+extern declare_sleeper( synth_sleeping_list );
+extern declare_timer( synth_timer );
+extern char str_caps_start[], str_caps_stop[];
+extern short no_intr, say_ctrl, say_word_ctl, punc_level;
+extern short reading_punc, attrib_bleep, bleeps;
+extern short bleep_time, bell_pos;
+extern short spell_delay, key_echo, punc_mask;
+extern short synth_jiffy_delta, synth_delay_time;
+extern short synth_trigger_time, synth_full_time;
+extern short cursor_timeout, pitch_shift, synth_flags;
+extern int synth_alive;
+extern u_char synth_buffer[]; /* guess what this is for! */
+extern u_char *buffer_highwater;
+extern volatile u_char *synth_buff_in, *synth_buff_out;
+int synth_init( char *name );
+int do_synth_init( struct spk_synth *in_synth );
+void synth_release( void );
+void synth_add( struct spk_synth *in_synth );
+void synth_remove( struct spk_synth *in_synth );
+struct serial_state * spk_serial_init( int index );
+void synth_delay( int ms );
+void synth_stop_timer( void );
+int synth_done( void );
+void do_flush( void );
+void synth_buffer_add( char ch );
+void synth_write( const char *buf, size_t count );
+void synth_write_string( const char *buf );
+void synth_write_msg( const char *buf );
+void speakup_register_devsynth ( void );
+
+#ifndef pr_info
+#define pr_info(fmt,arg...) printk(KERN_INFO fmt,##arg)
+#endif
+#ifndef pr_warn
+#define pr_warn(fmt,arg...) printk(KERN_WARNING fmt,##arg)
+#endif
+
+#endif
diff -u -r --new-file linux-2.4.30.orig/drivers/char/speakup/synthlist.h linux-2.4.30/drivers/char/speakup/synthlist.h
--- linux-2.4.30.orig/drivers/char/speakup/synthlist.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/drivers/char/speakup/synthlist.h 2003-12-10 07:29:56.000000000 -0800
@@ -0,0 +1,54 @@
+/* this is included two times */
+#if defined(PASS2)
+/* table of built in synths */
+#define SYNTH_DECL(who) &synth_##who,
+#define CFG_TEST(name) (name)
+#else
+/* declare extern built in synths */
+#define SYNTH_DECL(who) extern struct spk_synth synth_##who;
+#define PASS2
+#define CFG_TEST(name) (name)
+#endif
+
+#if CFG_TEST(CONFIG_SPEAKUP_ACNTPC)
+SYNTH_DECL(acntpc)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_ACNTSA)
+SYNTH_DECL(acntsa)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_APOLLO)
+SYNTH_DECL(apollo)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_AUDPTR)
+SYNTH_DECL(audptr)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_BNS)
+SYNTH_DECL(bns)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_DECEXT)
+SYNTH_DECL(decext)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_DECTLK)
+SYNTH_DECL(dectlk)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_DTLK)
+SYNTH_DECL(dtlk)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_KEYPC)
+SYNTH_DECL(keypc)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_LTLK)
+SYNTH_DECL(ltlk)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_SFTSYN)
+SYNTH_DECL(sftsyn)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_SPKOUT)
+SYNTH_DECL(spkout)
+#endif
+#if CFG_TEST(CONFIG_SPEAKUP_TXPRT)
+SYNTH_DECL(txprt)
+#endif
+
+#undef SYNTH_DECL
+#undef CFG_TEST
diff -u -r --new-file linux-2.4.30.orig/drivers/char/vt.c linux-2.4.30/drivers/char/vt.c
--- linux-2.4.30.orig/drivers/char/vt.c 2005-01-19 06:09:53.000000000 -0800
+++ linux-2.4.30/drivers/char/vt.c 2005-05-01 19:02:59.000000000 -0700
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -150,6 +151,7 @@
}
void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
+EXPORT_SYMBOL(kd_mksound);
int (*kbd_rate)(struct kbd_repeat *rep) = _kbd_rate;
#define i (tmp.kb_index)
diff -u -r --new-file linux-2.4.30.orig/fs/proc/root.c linux-2.4.30/fs/proc/root.c
--- linux-2.4.30.orig/fs/proc/root.c 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.30/fs/proc/root.c 2005-05-01 19:02:59.000000000 -0700
@@ -57,6 +57,9 @@
proc_mkdir("openprom", 0);
#endif
proc_tty_init();
+#ifdef CONFIG_SPEAKUP /* console speech output */
+ proc_speakup_init();
+#endif /* speakup */
#ifdef CONFIG_PROC_DEVICETREE
proc_device_tree_init();
#endif
diff -u -r --new-file linux-2.4.30.orig/include/linux/keyboard.h linux-2.4.30/include/linux/keyboard.h
--- linux-2.4.30.orig/include/linux/keyboard.h 2005-05-01 18:42:13.000000000 -0700
+++ linux-2.4.30/include/linux/keyboard.h 2005-05-01 19:02:59.000000000 -0700
@@ -44,6 +44,7 @@
#define KT_ASCII 9
#define KT_LOCK 10
#define KT_SLOCK 12
+#define KT_SPKUP 14 // is ignore if synth null
#define K(t,v) (((t)<<8)|(v))
#define KTYP(x) ((x) >> 8)
diff -u -r --new-file linux-2.4.30.orig/include/linux/proc_fs.h linux-2.4.30/include/linux/proc_fs.h
--- linux-2.4.30.orig/include/linux/proc_fs.h 2005-05-01 18:42:04.000000000 -0700
+++ linux-2.4.30/include/linux/proc_fs.h 2005-05-01 19:02:59.000000000 -0700
@@ -123,6 +123,10 @@
extern void proc_tty_register_driver(struct tty_driver *driver);
extern void proc_tty_unregister_driver(struct tty_driver *driver);
+#ifdef CONFIG_SPEAKUP /* console speech output */
+extern void proc_speakup_init(void);
+#endif /* speakup */
+
/*
* proc_devtree.c
*/
diff -u -r --new-file linux-2.4.30.orig/include/linux/speakup.h linux-2.4.30/include/linux/speakup.h
--- linux-2.4.30.orig/include/linux/speakup.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.30/include/linux/speakup.h 2005-05-01 19:02:59.000000000 -0700
@@ -0,0 +1,31 @@
+#ifndef __SPEAKUP_H
+#define __SPEAKUP_H
+
+#include
+struct kbd_struct;
+
+/* how about some prototypes! */
+extern int do_spk_ioctl(int,unsigned char *data,int,void *);
+
+#if defined(CONFIG_SPEAKUP)
+extern void speakup_init(int);
+extern void speakup_allocate(int);
+extern void speakup_bs(int);
+extern void speakup_con_write(int, const char *, int);
+extern void speakup_con_update(int);
+extern int speakup_key(int, u_char, u_short, u_char );
+#elif defined(CONFIG_SPEAKUP_MODULE)
+typedef void (*spk_con_func)(int );
+typedef void (*spk_write_func)(int, const char *, int);
+typedef int (*spk_key_func)(int, u_char, u_short, u_char );
+extern void speakup_set_addresses( spk_con_func allocate, spk_con_func bs,
+ spk_write_func con_write, spk_con_func con_update, spk_key_func key );
+#define speakup_init(currcons)
+#else
+#define speakup_allocate(currcons)
+#define speakup_bs(currcons)
+#define speakup_con_write(currcons, str, len)
+#define speakup_con_update(currcons)
+#define speakup_init(currcons)
+#endif
+#endif