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

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

Parent Directory Parent Directory | Revision Log Revision Log


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