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

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

Parent Directory Parent Directory | Revision Log Revision Log


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