/[linux-patches]/genpatches-2.6/trunk/2.6.13-pre/4900_speakup-20050730-gregkh.patch
Gentoo

Contents of /genpatches-2.6/trunk/2.6.13-pre/4900_speakup-20050730-gregkh.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 128 - (show annotations) (download) (as text)
Mon Aug 1 01:47:40 2005 UTC (15 years, 1 month ago) by eradicator
File MIME type: text/x-diff
File size: 280918 byte(s)
Don't patch the sparc64 Kconfig in speakup.
1 unchanged:
2 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3 +++ gregkh-2.6/drivers/char/speakup/cvsversion.h 2005-07-27 13:02:56.000000000 -0700
4 @@ -0,0 +1 @@
5 +#define CVSVERSION " CVS: Wed Mar 2 20:22:02 EST 2005 "
6 unchanged:
7 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
8 +++ gregkh-2.6/drivers/char/speakup/dtload.c 2005-07-27 13:02:56.000000000 -0700
9 @@ -0,0 +1,554 @@
10 +/*
11 + * This is the DECtalk PC firmware loader for the Linux kernel, version 1.0
12 + *
13 + * Original 386BSD source:
14 + * Copyright ( c ) 1996 Brian Buhrow <buhrow@lothlorien.nfbcal.org>
15 + *
16 + * Adapted for Linux:
17 + * Copyright ( c ) 1997 Nicolas Pitre <nico@cam.org>
18 + *
19 + * Adapted for speakup:
20 + * Copyright ( c ) 2003 David Borowski <david575@golden.net>
21 + *
22 + * All rights reserved.
23 + *
24 + * This program is free software; you can redistribute it and/or modify
25 + * it under the terms of the GNU General Public License as published by
26 + * the Free Software Foundation; either version 2 of the License, or
27 + * ( at your option ) any later version.
28 + *
29 + * This program is distributed in the hope that it will be useful,
30 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 + * GNU General Public License for more details.
33 + *
34 + * You should have received a copy of the GNU General Public License
35 + * along with this program; if not, write to the Free Software
36 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 + *
38 + */
39 +
40 +#include <stdio.h>
41 +#include <stdlib.h>
42 +#include <unistd.h>
43 +#include <string.h>
44 +#include <sys/types.h>
45 +#include <sys/stat.h>
46 +#include <fcntl.h>
47 +#include <malloc.h>
48 +#include <sys/errno.h>
49 +#include <asm/io.h>
50 +#include "dtload.h"
51 +#include "dtpc_reg.h"
52 +
53 +#define dt_delay(x) usleep(x)
54 +int verbose = 0, intest = 0,infd = -1;
55 +int image_len, total_paras;
56 +int dt_stat, dma_state = 0, has_kernel = 0;
57 +struct dos_reloc fixups[512];
58 +char *read_buff = NULL;
59 +struct dos_exe_header header;
60 +u_short iobase = 0x350;
61 +
62 +static inline int dt_getstatus( )
63 +{
64 + dt_stat = inb_p( iobase )|(inb_p( iobase+1 )<<8);
65 + return dt_stat;
66 +}
67 +
68 +static void dt_sendcmd( u_int cmd )
69 +{
70 + outb_p( cmd & 0xFF, iobase );
71 + outb_p( (cmd>>8) & 0xFF, iobase+1 );
72 +}
73 +
74 +static int dt_waitbit( int bit )
75 +{
76 + int timeout = 100;
77 + while ( --timeout > 0 ) {
78 + if( (dt_getstatus( ) & bit ) == bit ) return 1;
79 + usleep( 1000 );
80 + }
81 + return 0;
82 +}
83 +
84 +static int dt_sendcmd_wait( u_int cmd, int bit )
85 +{
86 + int timeout = 1000;
87 + outb_p( cmd & 0xFF, iobase );
88 + outb_p( (cmd>>8) & 0xFF, iobase+1 );
89 + while ( --timeout > 0 ) {
90 + if( (dt_getstatus( ) & bit ) == bit ) return 1;
91 + usleep( 1000 );
92 + }
93 + return 0;
94 +}
95 +
96 +static int dt_waitmode( int pattern )
97 +{
98 + int timeout = 1000;
99 + while ( --timeout > 0 ) {
100 + if( dt_getstatus( ) == pattern ) return 1;
101 + usleep( 1000 );
102 + }
103 + fprintf( stderr, "waitmode p=%x s = %x\n", pattern, dt_stat );
104 + return 0;
105 +}
106 +
107 +static int dt_wait_dma( )
108 +{
109 + int timeout = 1000, state = dma_state;
110 + if( !has_kernel ){
111 + dt_delay( 500 );
112 + return( dt_waitbit( STAT_dma_ready ) );
113 + }
114 + if( ! dt_waitbit( STAT_dma_ready ) ) return 0;
115 + while ( --timeout > 0 ) {
116 + if( (dt_getstatus()&STAT_dma_state) == state ) return 1;
117 + usleep( 1000 );
118 + }
119 + dma_state = dt_getstatus( ) & STAT_dma_state;
120 + return 1;
121 +}
122 +
123 +dt_ctrl( u_int cmd )
124 +{
125 + while ( ! dt_waitbit( STAT_cmd_ready ) ) dt_delay( 100 );
126 + outb_p( 0, iobase+2 );
127 + outb_p( 0, iobase+3 );
128 + dt_getstatus( );
129 + dt_sendcmd( CMD_control|cmd );
130 + outb_p( 0, iobase+6 );
131 + dt_delay( 100 );
132 + dt_sendcmd( CMD_null );
133 + while ( ! dt_waitbit( STAT_cmd_ready ) ) dt_delay( 100 );
134 +}
135 +
136 +int dt_flush( void )
137 +{
138 + dt_ctrl( CTRL_flush );
139 + dt_waitbit( STAT_dma_ready );
140 + outb_p( DMA_sync, iobase+4 );
141 + outb_p( 0, iobase+4 );
142 + dma_state ^= STAT_dma_state;
143 + while( dt_getstatus( ) & STAT_flushing ) dt_delay( 100 );
144 + return 0;
145 +}
146 +
147 +static int dt_sendbuff( char *src, int len )
148 +{
149 + while( len-- ){
150 + if( ! dt_wait_dma( ) ) return -1;
151 + if( ! (dt_getstatus( ) & STAT_rr_char) ) break;
152 + outb_p( DMA_single_in, iobase+4 );
153 + outb_p( *src++, iobase+4 );
154 + dma_state ^= STAT_dma_state;
155 + }
156 + return 0;
157 +}
158 +
159 +unsigned long dt_allocmem( unsigned long paras )
160 +{
161 + unsigned long addr;
162 + if( ! dt_wait_dma( ) ) return 0;
163 + outb_p( DMA_control, iobase+4 );
164 + outb_p( DT_MEM_ALLOC, iobase+4 );
165 + dma_state ^= STAT_dma_state;
166 + if( ! dt_wait_dma( ) ) return 0;
167 + outb_p( paras & 0xFF, iobase+4 );
168 + outb_p( (paras>>8) & 0xFF, iobase+4 );
169 + dma_state ^= STAT_dma_state;
170 + if( ! dt_wait_dma( ) ) return 0;
171 + addr = inb_p( iobase+4 );
172 + addr |= (inb_p( iobase+4 )<<8);
173 + addr += (inb_p( iobase+4 )<<4);
174 + addr += (inb_p( iobase+4 )<<12);
175 + dma_state ^= STAT_dma_state;
176 + return addr;
177 +}
178 +
179 +static int testkernel( void )
180 +{
181 + dt_sendcmd( CMD_sync );
182 + if( ! dt_waitbit( STAT_cmd_ready ) ) return -10;
183 + has_kernel = ( dt_stat&0x8000 ) ? 1 : 0;
184 + if ( verbose ) printf( "testkernel got %x\n", dt_stat );
185 + if ( has_kernel ) return 0;
186 + dt_delay( 100 );
187 + return 1;
188 +}
189 +
190 +static int dt_loadmem( int addr, int len, char *src )
191 +{
192 + char c;
193 + int l;
194 + if ( verbose ) printf( "dt_loadmem: addr = %08X size = %d\n", addr, len );
195 + do {
196 + l = len;
197 + if ( l >= 0xc000 ) l = 0xc000;
198 + len -= l;
199 + if( ! dt_wait_dma( ) ) return -1;
200 + outb_p( DMA_control, iobase+4 );
201 + outb_p( DT_LOAD_MEM, iobase+4 );
202 + dma_state ^= STAT_dma_state;
203 + if( ! dt_wait_dma( ) ) return -2;
204 + outb_p( addr & 0xFF, iobase+4 );
205 + outb_p( (addr>>8) & 0xFF, iobase+4 );
206 + outb_p( (addr>>16) & 0xFF, iobase+4 );
207 + outb_p( (addr>>24) & 0xFF, iobase+4 );
208 + outb_p( l & 0xFF, iobase+4 );
209 + outb_p( (l>>8) & 0xFF, iobase+4 );
210 + dma_state ^= STAT_dma_state;
211 + if( ! dt_wait_dma( ) ) return -3;
212 + addr += l;
213 + while( l-- ){
214 + c = *src++;
215 + outb_p( c, iobase+4 );
216 + }
217 + dma_state ^= STAT_dma_state;
218 + } while ( len > 0 );
219 + return 0;
220 +}
221 +
222 +unsigned int loadfile ( char *filename )
223 +{
224 + int i, header_size;
225 + unsigned int total_paras;
226 + long fix;
227 + infd = open ( filename, O_RDONLY );
228 + if ( infd == -1 ) {
229 + perror ( "Opening file: " );
230 + return 0;
231 + }
232 + read ( infd, &header, sizeof ( struct dos_exe_header ) );
233 + if ( header.id != 0x5a4d ) {
234 + fprintf ( stderr, "Invalid header file format\n" );
235 + fprintf ( stderr, "Want 0x5a4d, got 0x%x\n", header.id );
236 + return 0;
237 + }
238 + if ( header.relen > MAX_FIXUPS ) {
239 + fprintf ( stderr, "Too many fixups\n" );
240 + return 0;
241 + }
242 + lseek ( infd, ( long ) header.reloc, SEEK_SET );
243 + read ( infd, fixups, sizeof ( struct dos_reloc ) * header.relen );
244 + header_size = header.hsize * 16;
245 + lseek ( infd, ( long )header_size, SEEK_SET );
246 + image_len = ( ( header.pages-1 )*512 ) + ( header.rem- header_size );
247 + total_paras = ( image_len >> 4 ) + header.hmin + 16;
248 + read ( infd, read_buff, image_len );
249 + close( infd );
250 + return total_paras;
251 +}
252 +
253 +static int loadkernel( char *filename )
254 +{
255 + int segfix = 0x40, fix, i;
256 + int ipval, csval;
257 + if ( has_kernel ) return 0;
258 + if ( !loadfile( filename ) ) return -1;
259 + header.csval += segfix;
260 + header.ssval += segfix;
261 + if ( verbose ) {
262 + printf ( "Loading kernel of %ld bytes ( %d relocs )\n",
263 + image_len, header.relen );
264 + printf ( " cs:ip == %04x:%04x ss:sp == %04x:%04x\n",
265 + header.csval, header.ipval, header.ssval, header.spval );
266 + }
267 + for ( i = 0; i < header.relen; i++ ) {
268 + fix = ( fixups[i].segment << 4 ) + fixups[i].offset;
269 + ( *( unsigned int * ) &read_buff[fix] ) += segfix;
270 + }
271 + csval = header.csval;
272 + ipval = header.ipval;
273 + dt_sendcmd_wait( MODULE_reset, MODULE_init );
274 + dt_sendcmd( CMD_reset );
275 + if( dt_getstatus( ) == MODULE_self_test ){
276 + if( ! dt_waitmode( MODULE_init ) ) return -1;
277 + }
278 + if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -2;
279 + if ( !dt_sendcmd_wait( CMD_sync, MODE_error ) ) return -3;
280 + if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -4;
281 + if ( verbose ) printf( "card is ready\n" );
282 + dt_sendcmd( CMD_dma );
283 + if( ! dt_waitbit( STAT_dma_ready ) ) return -5;
284 + if( ( i = dt_loadmem( 0x00000400, image_len, read_buff ) ) ) {
285 + fprintf( stderr, "kernel load failed, status %d\n", i );
286 + return -6;
287 + }
288 + dt_delay( 100 );
289 + /* the kernel is loaded, start it */
290 + if ( !dt_sendcmd_wait( CMD_reset, MODE_status ) ) return -7;
291 + dt_sendcmd( CMD_dma+1 ); /**xxx**/
292 + dt_delay( 100 );
293 + if( ! dt_waitbit( STAT_dma_ready ) ) return-8;
294 + outb_p( DMA_control, iobase+4 );
295 + outb_p( DT_START_TASK, iobase+4 );
296 + dt_delay( 100 );
297 + outb_p( ipval & 0xFF, iobase+4 );
298 + outb_p( (ipval>>8) & 0xFF, iobase+4 );
299 + outb_p( csval & 0xFF, iobase+4 );
300 + outb_p( (csval>>8) & 0xFF, iobase+4 );
301 + if( ! dt_waitmode( 0xc001 ) ) return -9;
302 + if ( verbose ) {
303 + printf( "done loading kernel\n" );
304 + }
305 + return testkernel( );
306 +}
307 +
308 +int loaddict ( char *filename, char *name, int type )
309 +{
310 + int i, read_index, read_size, act_size;
311 + unsigned short *index_fix, seg_fix;
312 + unsigned long entries, index, dic_bytes, dic_addr;
313 + unsigned int total_paras;
314 + unsigned long param, l;
315 + infd = open ( filename, O_RDONLY );
316 + if ( infd == -1 ) {
317 + perror ( filename );
318 + return -1;
319 + }
320 +/* read in the entry count and the actual entry size excluding the
321 + * index table ( which is entries * 4 ) ... */
322 + read ( infd, &entries, 4 );
323 + read ( infd, &dic_bytes, 4 );
324 + if ( verbose )
325 + printf ( "Loading %s dictionary of %lu entries, %lu bytes.\n",
326 + name, entries, dic_bytes );
327 + total_paras = ( ( ( entries * 4 ) + dic_bytes ) >> 4 ) + 2;
328 + if ( verbose )
329 + printf ( "Allocating %d paragraphs of free ram ...\n", total_paras );
330 + l = dt_allocmem( total_paras );
331 + if ( l == 0 ) {
332 + perror ( "Error requesting memory from speech device" );
333 + return -1;
334 + }
335 + seg_fix = ( l >> 4 ) & 0xffff;
336 + dic_addr = l;
337 + index = entries;
338 + index_fix = ( unsigned short * ) &read_buff[0];
339 + if ( verbose )
340 + printf ( "Index table starts at %lx\n", l );
341 + read_index = index*4;
342 + act_size = read ( infd, read_buff, read_index );
343 + if ( act_size != read_index ) {
344 + fprintf ( stderr, "\nError reading indexes\n" );
345 + fprintf ( stderr, " exp : %d act : %d\n", read_index * 4, act_size );
346 + return -1;
347 + }
348 + for ( i = 1; i < index * 2; i += 2 )
349 + index_fix[i] += seg_fix;
350 + if( ( i = dt_loadmem( l, read_index, read_buff ) ) ) {
351 + fprintf ( stderr, "\nError loading indexes at 0x%lX: i %d\n",
352 + l, i );
353 + return -1;
354 + }
355 + l += read_index;
356 +/* now, load up the dictionary bytes ... */
357 + if ( verbose )
358 + printf ( "Dictionary text starts at %lx\n", l );
359 + read_size = dic_bytes;
360 + if ( ( act_size = read ( infd, read_buff, read_size ) ) != read_size ) {
361 + fprintf ( stderr, "\nError reading dictionary text!\n" );
362 + fprintf ( stderr, "asked : %d actual : %d\n", act_size, read_size );
363 + return -1;
364 + }
365 + if( ( i = dt_loadmem( l, read_size, read_buff ) ) ) {
366 + fprintf ( stderr, "\nError loading dictionary at 0x%lX: status %d\n",
367 + l, i );
368 + return -1;
369 + }
370 + if( ! dt_wait_dma( ) ) return -1;
371 + outb_p( DMA_control, iobase+4 );
372 + outb_p( DT_SET_DIC, iobase+4 );
373 + dma_state ^= STAT_dma_state;
374 + if( ! dt_wait_dma( ) ) return -1;
375 + l = dic_addr;
376 + l = ((l << 12) & 0xFFFF0000) + (l & 0x0000000F);
377 + outb_p( l & 0xFF, iobase+4 );
378 + outb_p( (l>>8) & 0xFF, iobase+4 );
379 + outb_p( (l>>16) & 0xFF, iobase+4 );
380 + outb_p( (l>>24) & 0xFF, iobase+4 );
381 + l = entries;
382 + outb_p( l & 0xFF, iobase+4 );
383 + outb_p( (l>>8) & 0xFF, iobase+4 );
384 + outb_p( (l>>16) & 0xFF, iobase+4 );
385 + outb_p( (l>>24) & 0xFF, iobase+4 );
386 + l = type;
387 + outb_p( l & 0xFF, iobase+4 );
388 + outb_p( (l>>8) & 0xFF, iobase+4 );
389 + dma_state ^= STAT_dma_state;
390 + close ( infd );
391 + if ( verbose ) printf( "dictionary load complete\n" );
392 + return 0;
393 +}
394 +
395 +int loadexe ( char *filename )
396 +{
397 + unsigned int load_addr = 0, seg_fix;
398 + int i, read_size;
399 + int ipval, csval;
400 + long fix;
401 + unsigned long total_paras;
402 + total_paras = loadfile ( filename );
403 + if ( total_paras == 0 ) return -1;
404 + load_addr = dt_allocmem( total_paras );
405 + if ( load_addr == 0 ) {
406 + fprintf ( stderr, "Error allocating memory on card: " );
407 + return -1;
408 + }
409 + seg_fix = ( load_addr >> 4 ) & 0xffff;
410 + if ( verbose ) {
411 + printf ( "Loading %s %ld bytes ( %d relocs )\n",
412 + filename, image_len, header.relen );
413 + printf ( "Allocating %ld bytes of free ram at %05x\n",
414 + ( long ) header.hmin * 16, load_addr );
415 + printf ( "Total memory taken is %ld bytes\n", ( long ) total_paras * 16 );
416 + printf ( " cs:ip == %04x:%04x ss:sp == %04x:%04x\n",
417 + header.csval + seg_fix, header.ipval, header.ssval + seg_fix, header.spval );
418 + }
419 + for ( i = 0; i < header.relen; i++ ) {
420 + fix = ( ( long ) fixups[i].segment << 4 ) + ( long ) fixups[i].offset;
421 + ( *( unsigned int * ) &read_buff[fix] ) += seg_fix;
422 + }
423 + if( ( i = dt_loadmem( load_addr, image_len, read_buff ) ) ) {
424 + fprintf ( stderr, "Error loading speech device at 0x%lX: status %d\n",
425 + load_addr, i );
426 + return -1;
427 + }
428 + csval = header.csval + seg_fix;
429 + ipval = header.ipval;
430 + if( ! dt_wait_dma( ) ) return -1;
431 + outb_p( DMA_control, iobase+4 );
432 + outb_p( DT_START_TASK, iobase+4 );
433 + dma_state ^= STAT_dma_state;
434 + if( ! dt_wait_dma( ) ) return -1;
435 + outb_p( ipval & 0xFF, iobase+4 );
436 + outb_p( (ipval>>8) & 0xFF, iobase+4 );
437 + outb_p( csval & 0xFF, iobase+4 );
438 + outb_p( (csval>>8) & 0xFF, iobase+4 );
439 + dma_state ^= STAT_dma_state;
440 + return 0;
441 +}
442 +
443 +void release_io( void )
444 +{
445 + ioperm( (long)iobase, 8, 0 );
446 + ioperm( (long)0x0080, 1, 0 );
447 + if ( read_buff ) free( read_buff );
448 +}
449 +
450 +parseparm( char *parm, char *value )
451 +{
452 + char *cp = parm+strlen( parm );
453 + while ( --cp > parm ) if ( *cp > ' ' ) break;
454 + cp[1] = '\0';
455 + if ( !strcmp( parm, "io" ) ) {
456 + long io = strtol( value, 0, 0 );
457 + if ( io >= 0x100 && io <= 0x350 ) {
458 + iobase = (u_short)io;
459 + return;
460 + }
461 + fprintf( stderr, "invalid io value %s\n", value );
462 + exit( 1 );
463 + } else if ( !strcmp( parm,"verbose" ) ) {
464 + verbose = atoi( value );
465 + }
466 +}
467 +
468 +do_test( void )
469 +{
470 + char buffer[512];
471 + int len;
472 + dma_state = dt_getstatus( ) & STAT_dma_state;
473 + while ( fgets( buffer, 510, stdin ) ) {
474 + len = strlen( buffer );
475 + if ( len == 1 ) dt_flush( );
476 + else {
477 + if ( buffer[len-1] == '\n' ) buffer[len-1] = '\013';
478 + dt_sendbuff( buffer, len );
479 + }
480 + }
481 + *buffer = '\013';
482 + dt_sendbuff( buffer, 1 );
483 +}
484 +
485 +int main ( int argc, char **argv )
486 +{
487 + char name[80], *cp;
488 + char *dirname = 0, *confname = "dec_pc.conf";
489 + char *init_msg = "[:ra 360] dec pc initialized\011";
490 + FILE *confile;
491 + struct stat statbuf;
492 + int maxsize = 0, status = 0;
493 + while ( --argc > 0 ) {
494 + argv++;
495 + if ( !strcmp( *argv, "-v" ) ) verbose = 1;
496 + else if ( !strcmp( *argv, "-t" ) ) intest = 1;
497 + else dirname = *argv;
498 + }
499 + if ( !dirname ) dirname = "/usr/local/lib/dec_pc";
500 + if ( chdir( dirname ) != 0 ) {
501 + fprintf( stderr, "cannot chdir to %s\n", dirname );
502 + exit( 1 );
503 + }
504 + if ( !( confile = fopen( confname, "r" ) ) ) {
505 + fprintf( stderr, "could not open %s", confname );
506 + exit( 1 );
507 + }
508 + while ( fgets( name, 80, confile ) ) {
509 + cp = strchr( name, '\n' );
510 + if ( cp ) *cp = '\0';
511 + if ( ( cp = strchr( name, '=' ) ) ) {
512 + *cp++ = '\0';
513 + parseparm( name, cp );
514 + continue;
515 + }
516 + if ( stat( name, &statbuf ) != 0 ) {
517 + fprintf( stderr, "cannot stat %s\n", name );
518 + exit( 1 );
519 + }
520 + if ( statbuf.st_size > maxsize ) maxsize = statbuf.st_size;
521 + }
522 + rewind( confile );
523 + if ( ioperm( (long)0x0080, 1, 1 ) || ioperm( (long)iobase, 8, 1 ) ) {
524 + fprintf( stderr, "could not get ioperm\n" );
525 + exit( 1 );
526 + }
527 + atexit( release_io );
528 + if ( testkernel( ) == 0 ) {
529 + if ( intest ) do_test( );
530 + else fprintf( stderr, "kernel already loaded\n" );
531 + exit( 0 );
532 + }
533 + read_buff = malloc( maxsize );
534 + if ( !read_buff ) {
535 + fprintf( stderr, "cannot malloc %d bytes\n", maxsize );
536 + exit( 1 );
537 + }
538 + while ( fgets( name, 80, confile ) && !status ) {
539 + cp = strchr( name, '\n' );
540 + if ( cp ) *cp = '\0';
541 + if ( strchr( name, '=' ) ) continue; /* a parameter */
542 + if ( !( cp = strchr( name, '.' ) ) ) continue;
543 + cp++;
544 + if ( !strcmp ( cp, "dic" ) ) {
545 + status = loaddict ( name, "primary", PRIMARY_DIC );
546 + } else if ( !strcmp ( cp, "dtu" ) ) {
547 + status = loaddict ( name, "user", USER_DIC );
548 + } else if ( !strcmp ( cp, "dta" ) ) {
549 + status = loaddict ( name, "abbreviation file", ABBREV_DIC );
550 + } else if ( !strcmp ( cp, "exe" ) ) {
551 + status = loadexe ( name );
552 + } else if ( !strcmp ( cp, "sys" ) ) {
553 + status = loadkernel ( name );
554 + }
555 + }
556 + if ( status ) fprintf( stderr, "status %d\n", status );
557 + fclose( confile );
558 + if ( status ) exit( status );
559 + dt_sendbuff( init_msg, strlen( init_msg ) );
560 + sleep( 1 );
561 + if ( intest ) do_test( );
562 + exit( 0 );
563 +}
564 unchanged:
565 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
566 +++ gregkh-2.6/drivers/char/speakup/dtload.h 2005-07-27 13:02:56.000000000 -0700
567 @@ -0,0 +1,57 @@
568 +/*
569 + * This is the DECtalk PC firmware loader for the Linux kernel, version 1.0
570 + *
571 + * Original 386BSD source:
572 + * Copyright (c) 1996 Brian Buhrow <buhrow@lothlorien.nfbcal.org>
573 + *
574 + * Adapted for Linux:
575 + * Copyright (c) 1997 Nicolas Pitre <nico@cam.org>
576 + *
577 + * Adapted for speakup:
578 + * Copyright (c) 2003 David Borowski <david575@golden.net>
579 + *
580 + * All rights reserved.
581 + *
582 + * This program is free software; you can redistribute it and/or modify
583 + * it under the terms of the GNU General Public License as published by
584 + * the Free Software Foundation; either version 2 of the License, or
585 + * (at your option) any later version.
586 + *
587 + * This program is distributed in the hope that it will be useful,
588 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
589 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
590 + * GNU General Public License for more details.
591 + *
592 + * You should have received a copy of the GNU General Public License
593 + * along with this program; if not, write to the Free Software
594 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
595 + *
596 + */
597 +
598 +#define MAX_FIXUPS 512 /* maximum fixups per exe */
599 +/*
600 + * msdos .exe files will look like ...
601 + */
602 +
603 +struct dos_exe_header {
604 + unsigned short id; /* Linker's signature, must be 0x5a4d */
605 + unsigned short rem; /* length of image mod 512 */
606 + unsigned short pages; /* length of image in pages of 512 bytes */
607 + unsigned short relen; /* number of relocation items */
608 + unsigned short hsize; /* header size in paragraphs of 16 bytes */
609 + unsigned short hmin; /* min # of paragraphs above prog end */
610 + unsigned short hmax;
611 + unsigned short ssval;
612 + unsigned short spval; /* to be loaded in sp */
613 + unsigned short checksum;
614 + unsigned short ipval; /* to be loaded in ip */
615 + unsigned short csval; /* segment offset to code */
616 + unsigned short reloc; /* location of relocation items */
617 + unsigned short ovrlay; /* overlay number */
618 +};
619 +
620 +/* a dos relocation element looks like */
621 +
622 +struct dos_reloc {
623 + short int offset, segment;
624 +};
625 unchanged:
626 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
627 +++ gregkh-2.6/drivers/char/speakup/dtpc_reg.h 2005-07-27 13:02:56.000000000 -0700
628 @@ -0,0 +1,132 @@
629 +/*
630 + * This is the DECtalk PC register constants (from DEC's DOS driver)
631 + *
632 + * Original code:
633 + * Copyright (c) by Digital Equipment Corp.
634 + *
635 + * 386BSD DECtalk PC driver:
636 + * Copyright (c) 1996 Brian Buhrow <buhrow@lothlorien.nfbcal.org>
637 + *
638 + * Linux DECtalk PC driver:
639 + * Copyright (c) 1997 Nicolas Pitre <nico@cam.org>
640 + *
641 + * speakup DECtalk PC driver:
642 + * Copyright (c) 2003 David Borowski <david575@golden.net>
643 + *
644 + * All rights reserved.
645 + *
646 + * This program is free software; you can redistribute it and/or modify
647 + * it under the terms of the GNU General Public License as published by
648 + * the Free Software Foundation; either version 2 of the License, or
649 + * (at your option) any later version.
650 + *
651 + * This program is distributed in the hope that it will be useful,
652 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
653 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
654 + * GNU General Public License for more details.
655 + *
656 + * You should have received a copy of the GNU General Public License
657 + * along with this program; if not, write to the Free Software
658 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
659 + *
660 + */
661 +
662 +/*
663 + * port interface defs ... used by dtpc.c
664 + */
665 +
666 +#define MODULE_init 0x0dec /* module in boot code */
667 +#define MODULE_self_test 0x8800 /* module in self-test */
668 +#define MODULE_reset 0xffff /* reinit the whole module */
669 +
670 +#define MODE_mask 0xf000 /* mode bits in high nibble */
671 +#define MODE_null 0x0000
672 +#define MODE_test 0x2000 /* in testing mode */
673 +#define MODE_status 0x8000
674 +#define STAT_int 0x0001 /* running in interrupt mode */
675 +#define STAT_tr_char 0x0002 /* character data to transmit */
676 +#define STAT_rr_char 0x0004 /* ready to receive char data */
677 +#define STAT_cmd_ready 0x0008 /* ready to accept commands */
678 +#define STAT_dma_ready 0x0010 /* dma command ready */
679 +#define STAT_digitized 0x0020 /* spc in digitized mode */
680 +#define STAT_new_index 0x0040 /* new last index ready */
681 +#define STAT_new_status 0x0080 /* new status posted */
682 +#define STAT_dma_state 0x0100 /* dma state toggle */
683 +#define STAT_index_valid 0x0200 /* indexs are valid */
684 +#define STAT_flushing 0x0400 /* flush in progress */
685 +#define STAT_self_test 0x0800 /* module in self test */
686 +#define MODE_ready 0xc000 /* module ready for next phase */
687 +#define READY_boot 0x0000
688 +#define READY_kernel 0x0001
689 +#define MODE_error 0xf000
690 +
691 +#define CMD_mask 0xf000 /* mask for command nibble */
692 +#define CMD_null 0x0000 /* post status */
693 +#define CMD_control 0x1000 /* hard control command */
694 +#define CTRL_mask 0x0F00 /* mask off control nibble */
695 +#define CTRL_data 0x00FF /* madk to get data byte */
696 +#define CTRL_null 0x0000 /* null control */
697 +#define CTRL_vol_up 0x0100 /* increase volume */
698 +#define CTRL_vol_down 0x0200 /* decrease volume */
699 +#define CTRL_vol_set 0x0300 /* set volume */
700 +#define CTRL_pause 0x0400 /* pause spc */
701 +#define CTRL_resume 0x0500 /* resume spc clock */
702 +#define CTRL_resume_spc 0x0001 /* resume spc soft pause */
703 +#define CTRL_flush 0x0600 /* flush all buffers */
704 +#define CTRL_int_enable 0x0700 /* enable status change ints */
705 +#define CTRL_buff_free 0x0800 /* buffer remain count */
706 +#define CTRL_buff_used 0x0900 /* buffer in use */
707 +#define CTRL_speech 0x0a00 /* immediate speech change */
708 +#define CTRL_SP_voice 0x0001 /* voice change */
709 +#define CTRL_SP_rate 0x0002 /* rate change */
710 +#define CTRL_SP_comma 0x0003 /* comma pause change */
711 +#define CTRL_SP_period 0x0004 /* period pause change */
712 +#define CTRL_SP_rate_delta 0x0005 /* delta rate change */
713 +#define CTRL_SP_get_param 0x0006 /* return the desired parameter */
714 +#define CTRL_last_index 0x0b00 /* get last index spoken */
715 +#define CTRL_io_priority 0x0c00 /* change i/o priority */
716 +#define CTRL_free_mem 0x0d00 /* get free paragraphs on module */
717 +#define CTRL_get_lang 0x0e00 /* return bit mask of loaded languages */
718 +#define CMD_test 0x2000 /* self-test request */
719 +#define TEST_mask 0x0F00 /* isolate test field */
720 +#define TEST_null 0x0000 /* no test requested */
721 +#define TEST_isa_int 0x0100 /* assert isa irq */
722 +#define TEST_echo 0x0200 /* make data in == data out */
723 +#define TEST_seg 0x0300 /* set peek/poke segment */
724 +#define TEST_off 0x0400 /* set peek/poke offset */
725 +#define TEST_peek 0x0500 /* data out == *peek */
726 +#define TEST_poke 0x0600 /* *peek == data in */
727 +#define TEST_sub_code 0x00FF /* user defined test sub codes */
728 +#define CMD_id 0x3000 /* return software id */
729 +#define ID_null 0x0000 /* null id */
730 +#define ID_kernel 0x0100 /* kernel code executing */
731 +#define ID_boot 0x0200 /* boot code executing */
732 +#define CMD_dma 0x4000 /* force a dma start */
733 +#define CMD_reset 0x5000 /* reset module status */
734 +#define CMD_sync 0x6000 /* kernel sync command */
735 +#define CMD_char_in 0x7000 /* single character send */
736 +#define CMD_char_out 0x8000 /* single character get */
737 +#define CHAR_count_1 0x0100 /* one char in cmd_low */
738 +#define CHAR_count_2 0x0200 /* the second in data_low */
739 +#define CHAR_count_3 0x0300 /* the third in data_high */
740 +#define CMD_spc_mode 0x9000 /* change spc mode */
741 +#define CMD_spc_to_text 0x0100 /* set to text mode */
742 +#define CMD_spc_to_digit 0x0200 /* set to digital mode */
743 +#define CMD_spc_rate 0x0400 /* change spc data rate */
744 +#define CMD_error 0xf000 /* severe error */
745 +
746 +enum { PRIMARY_DIC = 0, USER_DIC, COMMAND_DIC, ABBREV_DIC };
747 +
748 +#define DMA_single_in 0x01
749 +#define DMA_single_out 0x02
750 +#define DMA_buff_in 0x03
751 +#define DMA_buff_out 0x04
752 +#define DMA_control 0x05
753 +#define DT_MEM_ALLOC 0x03
754 +#define DT_SET_DIC 0x04
755 +#define DT_START_TASK 0x05
756 +#define DT_LOAD_MEM 0x06
757 +#define DT_READ_MEM 0x07
758 +#define DT_DIGITAL_IN 0x08
759 +#define DMA_sync 0x06
760 +#define DMA_sync_char 0x07
761 unchanged:
762 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
763 +++ gregkh-2.6/drivers/char/speakup/genmap.c 2005-07-27 13:02:56.000000000 -0700
764 @@ -0,0 +1,204 @@
765 +#include <stdlib.h>
766 +#include <stdio.h>
767 +#include <libgen.h>
768 +#include <string.h>
769 +#include <linux/version.h>
770 +#include <ctype.h>
771 +
772 +int get_define(void);
773 +
774 +#define MAXKEYS 512
775 +#define MAXKEYVAL 160
776 +#define HASHSIZE 101
777 +#define is_shift -3
778 +#define is_spk -2
779 +#define is_input -1
780 +typedef struct st_key_init t_key_init;
781 +struct st_key_init {
782 + char *name;
783 + int value, shift;
784 +};
785 +typedef struct st_key t_key;
786 +struct st_key {
787 + char *name;
788 + t_key *next;
789 + int value, shift;
790 +};
791 +unsigned char key_data[MAXKEYVAL][16], *kp;
792 +
793 +#include "mapdata.h"
794 +t_key key_table[MAXKEYS];
795 +t_key *extra_keys = key_table+HASHSIZE;
796 +char buffer[256], filename[256];
797 +FILE *infile;
798 +char delims[] = "\t\n ";
799 +char *def_name, *def_val, *cp;
800 +int map_ver = 119; /* an arbitrary number so speakup can check */
801 +int lc, shift_table[17];
802 +int max_states = 1, flags = 0;
803 +/* flags reserved for later, maybe for individual console maps */
804 +
805 +void open_input( char *name )
806 +{
807 + strcpy( filename, name );
808 + if ( ( infile = fopen( filename, "r" ) ) == 0 ) {
809 + fprintf( stderr, "can't open %s, version %d\n", filename, LINUX_VERSION_CODE );
810 + exit( 1 );
811 + }
812 + lc = 0;
813 +}
814 +
815 +int
816 +oops( char *msg, char *info )
817 +{
818 + if ( info == NULL ) info = " ";
819 + fprintf( stderr, "error: file %s line %d\n", filename, lc );
820 + fprintf( stderr, "%s %s\n", msg, info );
821 + exit( 1 );
822 +}
823 +
824 +t_key *hash_name( char *name )
825 +{
826 + u_char *pn = (u_char *)name;
827 + int hash = 0;
828 + while ( *pn ) {
829 + hash = ( hash * 17 ) & 0xfffffff;
830 + if ( isupper( *pn ) ) *pn = tolower( *pn );
831 + hash += ( int )*pn;
832 + pn++;
833 + }
834 + hash %= HASHSIZE;
835 + return &key_table[hash];
836 +}
837 +
838 +t_key *find_key( char *name )
839 +{
840 + t_key *this = hash_name( name );
841 + while ( this ) {
842 + if ( !strcmp( name, this->name ) ) return this;
843 + this = this->next;
844 + }
845 + return this;
846 +}
847 +
848 +t_key *add_key( char *name, int value, int shift )
849 +{
850 + t_key *this = hash_name( name );
851 + if ( extra_keys-key_table >= MAXKEYS )
852 + oops( "out of key table space, enlarge MAXKEYS", NULL );
853 + if ( this->name != NULL ) {
854 + while ( this->next ) {
855 + if ( !strcmp( name, this->name ) )
856 + oops( "attempt to add duplicate key", name );
857 + this = this->next;
858 + }
859 + this->next = extra_keys++;
860 + this = this->next;
861 + }
862 + this->name = strdup( name );
863 + this->value = value;
864 + this->shift = shift;
865 + return this;
866 +}
867 +
868 +int get_shift_value( int state )
869 +{
870 + int i;
871 + for ( i = 0; shift_table[i] != state; i++ ) {
872 + if ( shift_table[i] == -1 ) {
873 + if ( i >= 16 )
874 + oops( "too many shift states", NULL );
875 + shift_table[i] = state;
876 + max_states = i+1;
877 + break;
878 + }
879 + }
880 + return i;
881 +}
882 +
883 +int
884 +main( int argc, char *argv[] )
885 +{
886 + int value, shift_state, i, spk_val = 0, lock_val = 0;
887 + int max_key_used = 0, num_keys_used = 0;
888 + t_key *this;
889 + t_key_init *p_init;
890 +char *argpath, *argname, *argcopy;
891 +
892 + bzero( key_table, sizeof( key_table ) );
893 + bzero( key_data, sizeof( key_data ) );
894 + shift_table[0] = 0;
895 + for ( i = 1; i <= 16; i++ ) shift_table[i] = -1;
896 + if ( argc < 2 ) {
897 + fputs( "usage: genmap filename\n", stderr );
898 + exit( 1 );
899 + }
900 + for ( p_init = init_key_data; p_init->name[0] != '.'; p_init++ )
901 + add_key( p_init->name, p_init->value, p_init->shift );
902 + open_input( argv[1] );
903 + while ( fgets( buffer, 250, infile ) ) {
904 + lc++;
905 + value = shift_state = 0;
906 + cp = strtok( buffer, delims );
907 + if ( *cp == '#' ) continue;
908 + while ( cp ) {
909 + if ( *cp == '=' ) break;
910 + this = find_key( cp );
911 + if ( this == NULL )
912 + oops( "unknown key/modifier", cp );
913 + if ( this->shift == is_shift ) {
914 + if ( value )
915 + oops( "modifiers must come first", cp );
916 + shift_state += this->value;
917 + } else if ( this->shift == is_input )
918 + value = this->value;
919 + else oops( "bad modifier or key", cp );
920 + cp = strtok( 0, delims );
921 + }
922 + if ( !cp ) oops( "no = found", NULL );
923 + cp = strtok( 0, delims );
924 + if ( !cp ) oops( "no speakup function after =", NULL );
925 + this = find_key( cp );
926 + if ( this == NULL || this->shift != is_spk )
927 + oops( "invalid speakup function", cp );
928 + i = get_shift_value( shift_state );
929 + if ( key_data[value][i] ) {
930 + while ( --cp > buffer )
931 + if ( !*cp ) *cp = ' ';
932 + oops( "two functions on same key combination", cp );
933 + }
934 + key_data[value][i] = (char)this->value;
935 + if ( value > max_key_used ) max_key_used = value;
936 + }
937 + fclose( infile );
938 + this = find_key( "spk_key" );
939 + if ( this ) spk_val = this->value;
940 + this = find_key( "spk_lock" );
941 + if ( this ) lock_val = this->value;
942 + for ( lc = 1; lc <= max_key_used; lc++ ) {
943 + kp = key_data[lc];
944 + if ( !memcmp( key_data[0], kp, 16 ) ) continue;
945 + num_keys_used++;
946 + for ( i = 0; i < max_states; i++ ) {
947 + if ( kp[i] != spk_val&& kp[i] != lock_val ) continue;
948 + shift_state = shift_table[i];
949 + if ( ( shift_state&16 ) ) continue;
950 + shift_state = get_shift_value( shift_state+16 );
951 + kp[shift_state] = kp[i];
952 +/* fill in so we can process the key up, as spk bit will be set */
953 + }
954 + }
955 + printf( "\t%d, %d, %d,\n\t", map_ver, num_keys_used, max_states );
956 + for ( i = 0; i < max_states; i++ )
957 + printf( "%d, ", shift_table[i] );
958 + printf( "%d,", flags );
959 + for ( lc = 1; lc <= max_key_used; lc++ ) {
960 + kp = key_data[lc];
961 + if ( !memcmp( key_data[0], kp, 16 ) ) continue;
962 + printf( "\n\t%d,", lc );
963 + for ( i = 0; i < max_states; i++ )
964 + printf( " %d,", (unsigned int)kp[i] );
965 + }
966 + printf( "\n\t0, %d\n", map_ver );
967 + exit( 0 );
968 +}
969 unchanged:
970 --- gregkh-2.6/drivers/char/speakup/Kconfig 2005-07-27 13:02:56.000000000 -0700
971 +++ gregkh-2.6/drivers/char/speakup/Kconfig 2005-07-27 13:36:45.000000000 -0700
972 @@ -0,0 +1,211 @@
973 +menu "Speakup console speech"
974 +config SPEAKUP
975 + tristate "Build speakup console speech"
976 + ---help---
977 +
978 + This is the Speakup screen reader. Think of it as a
979 + video console for blind people. If built in to the
980 + kernel, it can speak evrything on the text console from
981 + boot up to shutdown. For more information on Speakup,
982 + point your browser at http://www.linux-speakup.org/.
983 + There is also a mailing list at the above url that you
984 + can subscribe to.
985 +
986 + Supported synthesizers are accent sa, accent pc, appollo
987 + II., Auddapter, Braille 'n Speak, Dectalk external
988 + (old), Dectalk PC (full length isa board), Dectalk
989 + express, Doubletalk, Doubletalk LT or Litetalk,
990 + Keynote
991 + Gold internal PC, software synthesizers, Speakout, and transport.
992 +
993 + Speakup can either be built in or compiled as a module
994 + by answering y or m. If you answer y here, then you
995 + must answer either y or m to at least one of the
996 + synthesizer drivers below. If you answer m here, then
997 + the synthesizer drivers below can only be built as
998 + modules.
999 +
1000 + These drivers are not standalone drivers, but must be
1001 + used in conjunction with Speakup. Think of them as
1002 + video cards for blind people.
1003 +
1004 +
1005 + The Dectalk pc driver can only be built as a module, and
1006 + requires software to be pre-loaded on to the card before
1007 + the module can be loaded. See the decpc choice below
1008 + for more details.
1009 +
1010 + If you are not a blind person, or don't have access to
1011 + one of the listed synthesizers, you should say n.
1012 +
1013 +config SPEAKUP_ACNTSA
1014 + depends on SPEAKUP
1015 + tristate "Accent SA, acntsa"
1016 + ---help---
1017 +
1018 + This is the Speakup driver for the accent sa
1019 + synthesizer. You can say y to build it into the kernel,
1020 + or m to build it as a module. See the configuration
1021 + help on the Speakup choice above for more info.
1022 +
1023 +config SPEAKUP_ACNTPC
1024 + depends on SPEAKUP
1025 + tristate "Accent PC, acntpc"
1026 + ---help---
1027 +
1028 + This is the Speakup driver for the accent pc
1029 + synthesizer. You can say y to build it into the kernel,
1030 + or m to build it as a module. See the configuration
1031 + help on the Speakup choice above for more info.
1032 +
1033 +config SPEAKUP_APOLLO
1034 + depends on SPEAKUP
1035 + tristate "Apollo, apollo"
1036 + ---help---
1037 +
1038 + This is the Speakup driver for the Apollo II
1039 + synthesizer. You can say y to build it into the kernel,
1040 + or m to build it as a module. See the configuration
1041 + help on the Speakup choice above for more info.
1042 +
1043 +config SPEAKUP_AUDPTR
1044 + depends on SPEAKUP
1045 + tristate "Audapter, audptr"
1046 + ---help---
1047 +
1048 + This is the Speakup driver for the Audapter synthesizer.
1049 + You can say y to build it into the kernel, or m to
1050 + build it as a module. See the configuration help on the
1051 + Speakup choice above for more info.
1052 +
1053 +config SPEAKUP_BNS
1054 + depends on SPEAKUP
1055 + tristate "Braille 'n' Speak, bns"
1056 + ---help---
1057 +
1058 + This is the Speakup driver for the Braille 'n' Speak
1059 + synthesizer. You can say y to build it into the kernel,
1060 + or m to build it as a module. See the configuration
1061 + help on the Speakup choice above for more info.
1062 +
1063 +config SPEAKUP_DECTLK
1064 + depends on SPEAKUP
1065 + tristate "DECtalk Express, dectlk"
1066 + ---help---
1067 +
1068 + This is the Speakup driver for the DecTalk Express
1069 + synthesizer. You can say y to build it into the kernel,
1070 + or m to build it as a module. See the configuration
1071 + help on the Speakup choice above for more info.
1072 +
1073 +config SPEAKUP_DECEXT
1074 + depends on SPEAKUP
1075 + tristate "DECtalk External (old), decext"
1076 + ---help---
1077 +
1078 + This is the Speakup driver for the DecTalk External
1079 + (old) synthesizer. You can say y to build it into the
1080 + kernel, or m to build it as a module. See the
1081 + configuration help on the Speakup choice above for more
1082 + info.
1083 +
1084 +config SPEAKUP_DECPC
1085 + depends on SPEAKUP
1086 + tristate "DECtalk PC (big ISA card), decpc"
1087 + ---help---
1088 +
1089 + This is the Speakup driver for the DecTalk PC (full
1090 + length ISA) synthesizer. You can say m to build it as
1091 + a module. See the configuration help on the Speakup
1092 + choice above for more info.
1093 +
1094 + In order to use the DecTalk PC driver, you must download
1095 + the dec_pc.tgz file from linux-speakup.org. It is in
1096 + the pub/linux/goodies directory. The dec_pc.tgz file
1097 + contains the software which must be pre-loaded on to the
1098 + DecTalk PC board in order to use it with this driver.
1099 + This driver must be built as a module, and can not be
1100 + loaded until the file system is mounted and the DecTalk
1101 + PC software has been pre-loaded on to the board.
1102 +
1103 + See the README file in the dec_pc.tgz file for more
1104 + details.
1105 +
1106 +config SPEAKUP_DTLK
1107 + depends on SPEAKUP
1108 + tristate "DoubleTalk PC, dtlk"
1109 + ---help---
1110 +
1111 + This is the Speakup driver for the internal DoubleTalk
1112 + PC synthesizer. You can say y to build it into the
1113 + kernel, or m to build it as a module. See the
1114 + configuration help on the Speakup choice above for more
1115 + info.
1116 +
1117 +config SPEAKUP_KEYPC
1118 + depends on SPEAKUP
1119 + tristate "Keynote Gold PC, keypc"
1120 + ---help---
1121 +
1122 + This is the Speakup driver for the Keynote Gold
1123 + PC synthesizer. You can say y to build it into the
1124 + kernel, or m to build it as a module. See the
1125 + configuration help on the Speakup choice above for more
1126 + info.
1127 +
1128 +config SPEAKUP_LTLK
1129 + depends on SPEAKUP
1130 + tristate "DoubleTalk LT or LiteTalk, ltlk"
1131 +---help---
1132 +
1133 + This is the Speakup driver for the LiteTalk/DoubleTalk
1134 + LT synthesizer. You can say y to build it into the
1135 + kernel, or m to build it as a module. See the
1136 + configuration help on the Speakup choice above for more
1137 + info.
1138 +
1139 +config SPEAKUP_SFTSYN
1140 + depends on SPEAKUP
1141 + tristate "Software synthesizers, sftsyn"
1142 +---help---
1143 +
1144 + This is the software synthesizer device node. It will
1145 + register a device /dev/sftsyn which midware programs
1146 + and speech
1147 + daemons may open and read to provide kernel output to
1148 + software synths
1149 + such as festival, flite, tuxtalk and so forth. You
1150 + can select 'y' or
1151 + 'm' to have it built-in to the kernel or loaded as a module.
1152 +
1153 +config SPEAKUP_SPKOUT
1154 + depends on SPEAKUP
1155 + tristate "Speak Out, spkout"
1156 + ---help---
1157 +
1158 + This is the Speakup driver for the Speakout synthesizer.
1159 + You can say y to build it into the kernel, or m to
1160 + build it as a module. See the configuration help on the
1161 + Speakup choice above for more info.
1162 +
1163 +config SPEAKUP_TXPRT
1164 + depends on SPEAKUP
1165 + tristate "Transport, txprt"
1166 + ---help---
1167 +
1168 + This is the Speakup driver for the Transport
1169 + synthesizer. You can say y to build it into the kernel,
1170 + or m to build it as a module. See the configuration
1171 + help on the Speakup choice above for more info.
1172 +
1173 +if SPEAKUP != n
1174 + comment 'Enter the 3 to 6 character keyword from the list above, or none for no default synthesizer on boot up.'
1175 + depends on SPEAKUP
1176 +endif
1177 +
1178 +config SPEAKUP_DEFAULT
1179 + depends on SPEAKUP
1180 + string "Choose Default synthesizer for Speakup"
1181 + default "none"
1182 +
1183 +endmenu
1184 unchanged:
1185 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1186 +++ gregkh-2.6/drivers/char/speakup/keyinfo.h 2005-07-27 13:02:56.000000000 -0700
1187 @@ -0,0 +1,119 @@
1188 +/* spk_priv.h
1189 + review functions for the speakup screen review package.
1190 + originally written by: Kirk Reiser and Andy Berdan.
1191 +
1192 + extensively modified by David Borowski.
1193 +
1194 + Copyright (C ) 1998 Kirk Reiser.
1195 + Copyright (C ) 2003 David Borowski.
1196 +
1197 + This program is free software; you can redistribute it and/or modify
1198 + it under the terms of the GNU General Public License as published by
1199 + the Free Software Foundation; either version 2 of the License, or
1200 + (at your option ) any later version.
1201 +
1202 + This program is distributed in the hope that it will be useful,
1203 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1204 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1205 + GNU General Public License for more details.
1206 +
1207 + You should have received a copy of the GNU General Public License
1208 + along with this program; if not, write to the Free Software
1209 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1210 +*/
1211 +
1212 +enum { /* var_ids */
1213 + VERSION = 0, SYNTH, SILENT, SYNTH_DIRECT,
1214 + KEYMAP, CHARS,
1215 + PUNC_SOME, PUNC_MOST, PUNC_ALL,
1216 + DELIM, REPEATS, EXNUMBER,
1217 + DELAY, TRIGGER, JIFFY, FULL, /* all timers must be together */
1218 + BLEEP_TIME, CURSOR_TIME, BELL_POS,
1219 +SAY_CONTROL, SAY_WORD_CTL, NO_INTERRUPT, KEY_ECHO,
1220 + SPELL_DELAY, PUNC_LEVEL, READING_PUNC,
1221 + ATTRIB_BLEEP, BLEEPS,
1222 + RATE, PITCH, VOL, TONE, PUNCT, VOICE, FREQ, LANG,
1223 + CAPS_START, CAPS_STOP,
1224 + MAXVARS
1225 +};
1226 +
1227 +#define FIRST_SYNTH_VAR RATE
1228 +/* 0 is reserved for no remap */
1229 +#define SPEAKUP_GOTO 0x01
1230 +#define SPEECH_KILL 0x02
1231 +#define SPEAKUP_QUIET 0x03
1232 +#define SPEAKUP_CUT 0x04
1233 +#define SPEAKUP_PASTE 0x05
1234 +#define SAY_FIRST_CHAR 0x06
1235 +#define SAY_LAST_CHAR 0x07
1236 +#define SAY_CHAR 0x08
1237 +#define SAY_PREV_CHAR 0x09
1238 +#define SAY_NEXT_CHAR 0x0a
1239 +#define SAY_WORD 0x0b
1240 +#define SAY_PREV_WORD 0x0c
1241 +#define SAY_NEXT_WORD 0x0d
1242 +#define SAY_LINE 0x0e
1243 +#define SAY_PREV_LINE 0x0f
1244 +#define SAY_NEXT_LINE 0x10
1245 +#define TOP_EDGE 0x11
1246 +#define BOTTOM_EDGE 0x12
1247 +#define LEFT_EDGE 0x13
1248 +#define RIGHT_EDGE 0x14
1249 +#define SPELL_PHONETIC 0x15
1250 +#define SPELL_WORD 0x16
1251 +#define SAY_SCREEN 0x17
1252 +#define SAY_POSITION 0x18
1253 +#define SAY_ATTRIBUTES 0x19
1254 +#define SPEAKUP_OFF 0x1a
1255 +#define SPEAKUP_PARKED 0x1b
1256 +#define SAY_LINE_INDENT 0x1c
1257 +#define SAY_FROM_TOP 0x1d
1258 +#define SAY_TO_BOTTOM 0x1e
1259 +#define SAY_FROM_LEFT 0x1f
1260 +#define SAY_TO_RIGHT 0x20
1261 +#define SAY_CHAR_NUM 0x21
1262 +#define EDIT_SOME 0x22
1263 +#define EDIT_MOST 0x23
1264 +#define SAY_PHONETIC_CHAR 0x24
1265 +#define EDIT_DELIM 0x25
1266 +#define EDIT_REPEAT 0x26
1267 +#define EDIT_EXNUM 0x27
1268 +#define SET_WIN 0x28
1269 +#define CLEAR_WIN 0x29
1270 +#define ENABLE_WIN 0x2a
1271 +#define SAY_WIN 0x2b
1272 +#define SPK_LOCK 0x2c
1273 +#define SPEAKUP_HELP 0x2d
1274 +#define TOGGLE_CURSORING 0x2e
1275 +#define SPKUP_MAX_FUNC 0x2f /* one greater than the last func handler */
1276 +
1277 +#define SPK_KEY 0x80
1278 +#define FIRST_EDIT_BITS 0x22
1279 +
1280 +#define FIRST_SET_VAR SPELL_DELAY
1281 +#define VAR_START 0x40 /* increase if adding more than 0x3f functions */
1282 +
1283 +/* keys for setting variables, must be ordered same as the enum for var_ids */
1284 +/* with dec being even and inc being 1 greater */
1285 +#define SPELL_DELAY_DEC VAR_START+0
1286 +#define SPELL_DELAY_INC SPELL_DELAY_DEC+1
1287 +#define PUNC_LEVEL_DEC SPELL_DELAY_DEC+2
1288 +#define PUNC_LEVEL_INC PUNC_LEVEL_DEC+1
1289 +#define READING_PUNC_DEC PUNC_LEVEL_DEC+2
1290 +#define READING_PUNC_INC READING_PUNC_DEC+1
1291 +#define ATTRIB_BLEEP_DEC READING_PUNC_DEC+2
1292 +#define ATTRIB_BLEEP_INC ATTRIB_BLEEP_DEC+1
1293 +#define BLEEPS_DEC ATTRIB_BLEEP_DEC+2
1294 +#define BLEEPS_INC BLEEPS_DEC+1
1295 +#define RATE_DEC BLEEPS_DEC+2
1296 +#define RATE_INC RATE_DEC+1
1297 +#define PITCH_DEC RATE_DEC+2
1298 +#define PITCH_INC PITCH_DEC+1
1299 +#define VOL_DEC PITCH_DEC+2
1300 +#define VOL_INC VOL_DEC+1
1301 +#define TONE_DEC VOL_DEC+2
1302 +#define TONE_INC TONE_DEC+1
1303 +#define PUNCT_DEC TONE_DEC+2
1304 +#define PUNCT_INC PUNCT_DEC+1
1305 +#define VOICE_DEC PUNCT_DEC+2
1306 +#define VOICE_INC VOICE_DEC+1
1307 unchanged:
1308 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1309 +++ gregkh-2.6/drivers/char/speakup/Makefile 2005-07-27 13:02:56.000000000 -0700
1310 @@ -0,0 +1,36 @@
1311 +#
1312 +# Makefile for the speakup speech output system.
1313 +#
1314 +
1315 +obj-m = speakup_keyhelp.o
1316 +speakupmain-objs := speakup.o speakup_drvcommon.o
1317 +
1318 +obj-$(CONFIG_SPEAKUP) += speakupmain.o
1319 +obj-$(CONFIG_SPEAKUP_ACNTPC) += speakup_acntpc.o
1320 +obj-$(CONFIG_SPEAKUP_ACNTSA) += speakup_acntsa.o
1321 +obj-$(CONFIG_SPEAKUP_APOLLO) += speakup_apollo.o
1322 +obj-$(CONFIG_SPEAKUP_AUDPTR) += speakup_audptr.o
1323 +obj-$(CONFIG_SPEAKUP_BNS) += speakup_bns.o
1324 +obj-$(CONFIG_SPEAKUP_DECEXT) += speakup_decext.o
1325 +obj-$(CONFIG_SPEAKUP_DECPC) += speakup_decpc.o
1326 +obj-$(CONFIG_SPEAKUP_DECTLK) += speakup_dectlk.o
1327 +obj-$(CONFIG_SPEAKUP_DTLK) += speakup_dtlk.o
1328 +obj-$(CONFIG_SPEAKUP_KEYPC) += speakup_keypc.o
1329 +obj-$(CONFIG_SPEAKUP_LTLK) += speakup_ltlk.o
1330 +obj-$(CONFIG_SPEAKUP_SFTSYN) += speakup_sftsyn.o
1331 +obj-$(CONFIG_SPEAKUP_SPKOUT) += speakup_spkout.o
1332 +obj-$(CONFIG_SPEAKUP_TXPRT) += speakup_txprt.o
1333 +
1334 +#speakupmain.o:speakup.o speakup_drvcommon.o
1335 +# ld -r -o speakupmain.o speakup.o speakup_drvcommon.o
1336 +
1337 +$(obj)/speakupmap.h: $(src)/speakupmap.map $(src)/genmap
1338 + $(src)/genmap $(src)/speakupmap.map >$@
1339 +
1340 +$(obj)/mapdata.h: $(src)/keyinfo.h $(src)/makemapdata
1341 + $(src)/makemapdata >$@
1342 +
1343 +$(obj)/genmap: $(obj)/mapdata.h
1344 +
1345 +HOSTCFLAGS := -Iinclude -I/usr/include
1346 +hostprogs-y := makemapdata genmap
1347 unchanged:
1348 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1349 +++ gregkh-2.6/drivers/char/speakup/makemapdata.c 2005-07-27 13:02:56.000000000 -0700
1350 @@ -0,0 +1,156 @@
1351 +#include <stdlib.h>
1352 +#include <stdio.h>
1353 +#include <libgen.h>
1354 +#include <string.h>
1355 +#include <linux/version.h>
1356 +#include <ctype.h>
1357 +
1358 +int get_define(void);
1359 +
1360 +#define MAXKEYS 512
1361 +#define MAXKEYVAL 160
1362 +#define HASHSIZE 101
1363 +#define is_shift -3
1364 +#define is_spk -2
1365 +#define is_input -1
1366 +typedef struct st_key t_key;
1367 +struct st_key {
1368 + char *name;
1369 + t_key *next;
1370 + int value, shift;
1371 +};
1372 +
1373 +t_key key_table[MAXKEYS];
1374 +t_key *extra_keys = key_table+HASHSIZE;
1375 +char buffer[256], filename[256];
1376 +FILE *infile;
1377 +char delims[] = "\t\n ";
1378 +char *dir_name, *def_name, *def_val, *cp;
1379 +int lc;
1380 +
1381 +void open_input( char *name )
1382 +{
1383 + sprintf( filename, "%s/%s", dir_name, name );
1384 + if ( ( infile = fopen( filename, "r" ) ) == 0 ) {
1385 + fprintf( stderr, "can't open %s\n", filename );
1386 + exit( 1 );
1387 + }
1388 + lc = 0;
1389 +}
1390 +
1391 +int
1392 +oops( char *msg, char *info )
1393 +{
1394 + if ( info == NULL ) info = " ";
1395 + fprintf( stderr, "error: file %s line %d\n", filename, lc );
1396 + fprintf( stderr, "%s %s\n", msg, info );
1397 + exit( 1 );
1398 +}
1399 +
1400 +int get_define( )
1401 +{
1402 + while ( fgets( buffer, 250, infile ) ) {
1403 + lc++;
1404 + if ( strncmp( buffer, "#define", 7 ) ) continue;
1405 + strtok( buffer, delims );
1406 + def_name = strtok( 0, delims );
1407 + def_val = strtok( 0, delims );
1408 + if ( def_val != NULL ) return 1;
1409 + }
1410 + fclose( infile );
1411 + infile = 0;
1412 + return 0;
1413 +}
1414 +
1415 +t_key *hash_name( char *name )
1416 +{
1417 + u_char *pn = (u_char *)name;
1418 + int hash = 0;
1419 + while ( *pn ) {
1420 + hash = ( hash * 17 ) & 0xfffffff;
1421 + if ( isupper( *pn ) ) *pn = tolower( *pn );
1422 + hash += ( int )*pn;
1423 + pn++;
1424 + }
1425 + hash %= HASHSIZE;
1426 + return &key_table[hash];
1427 +}
1428 +
1429 +t_key *find_key( char *name )
1430 +{
1431 + t_key *this = hash_name( name );
1432 + while ( this ) {
1433 + if ( !strcmp( name, this->name ) ) return this;
1434 + this = this->next;
1435 + }
1436 + return this;
1437 +}
1438 +
1439 +t_key *add_key( char *name, int value, int shift )
1440 +{
1441 + t_key *this = hash_name( name );
1442 + if ( extra_keys-key_table >= MAXKEYS )
1443 + oops( "out of key table space, enlarge MAXKEYS", NULL );
1444 + if ( this->name != NULL ) {
1445 + while ( this->next ) {
1446 + if ( !strcmp( name, this->name ) )
1447 + oops( "attempt to add duplicate key", name );
1448 + this = this->next;
1449 + }
1450 + this->next = extra_keys++;
1451 + this = this->next;
1452 + }
1453 + this->name = strdup( name );
1454 + this->value = value;
1455 + this->shift = shift;
1456 + return this;
1457 +}
1458 +
1459 +int
1460 +main( int argc, char *argv[] )
1461 +{
1462 + int value, i;
1463 + t_key *this;
1464 + dir_name = getenv( "TOPDIR" );
1465 + if ( !dir_name ) dir_name = "/usr/src/linux";
1466 + bzero( key_table, sizeof( key_table ) );
1467 + add_key( "shift", 1, is_shift );
1468 + add_key( "altgr", 2, is_shift );
1469 + add_key( "ctrl", 4, is_shift );
1470 + add_key( "alt", 8, is_shift );
1471 + add_key( "spk", 16, is_shift );
1472 + add_key( "double", 32, is_shift );
1473 + open_input( "include/linux/input.h" );
1474 + while ( get_define( ) ) {
1475 + if ( strncmp( def_name, "KEY_", 4 ) ) continue;
1476 + value = atoi( def_val );
1477 + if ( value > 0 && value < MAXKEYVAL )
1478 + add_key( def_name, value, is_input );
1479 + }
1480 + open_input( "drivers/char/speakup/keyinfo.h" );
1481 + while ( get_define( ) ) {
1482 + if ( strlen( def_val ) > 5 ) {
1483 + if ( !( cp = strchr( def_val, '+' ) ) ) continue;
1484 + *cp++ = '\0';
1485 + this = find_key( def_val );
1486 + if ( !this || *cp < '0' || *cp > '9' ) continue;
1487 + value = this->value+atoi( cp );
1488 + } else if ( !strncmp( def_val, "0x", 2 ) )
1489 + sscanf( def_val+2, "%x", &value );
1490 + else if ( *def_val >= '0' && *def_val <= '9' )
1491 + value = atoi( def_val );
1492 + else continue;
1493 + add_key( def_name, value, is_spk );
1494 + }
1495 + printf( "t_key_init init_key_data[] = {\n" );
1496 + for ( i = 0; i < HASHSIZE; i++ ) {
1497 + this = &key_table[i];
1498 + if ( !this->name ) continue;
1499 + do {
1500 + printf( "\t\"%s\", %d, %d,\n", this->name, this->value, this->shift );
1501 + this = this->next;
1502 + } while ( this );
1503 + }
1504 + printf( "\t\".\", 0, 0\n};\n" );
1505 + exit( 0 );
1506 +}
1507 unchanged:
1508 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1509 +++ gregkh-2.6/drivers/char/speakup/mapdata.h 2005-07-27 13:02:56.000000000 -0700
1510 @@ -0,0 +1,238 @@
1511 +t_key_init init_key_data[] = {
1512 + "key_s", 31, -1,
1513 + "top_edge", 17, -2,
1514 + "key_t", 20, -1,
1515 + "say_first_char", 6, -2,
1516 + "attrib_bleep_inc", 71, -2,
1517 + "key_u", 22, -1,
1518 + "key_grave", 41, -1,
1519 + "key_v", 47, -1,
1520 + "key_w", 17, -1,
1521 + "key_kpasterisk", 55, -1,
1522 + "key_minus", 12, -1,
1523 + "key_x", 45, -1,
1524 + "key_down", 108, -1,
1525 + "key_y", 21, -1,
1526 + "key_kpdot", 83, -1,
1527 + "key_leftmeta", 125, -1,
1528 + "key_z", 44, -1,
1529 + "key_volumedown", 114, -1,
1530 + "say_next_word", 13, -2,
1531 + "clear_win", 41, -2,
1532 + "key_rightbrace", 27, -1,
1533 + "right_edge", 20, -2,
1534 + "key_scrolllock", 70, -1,
1535 + "key_comma", 51, -1,
1536 + "altgr", 2, -3,
1537 + "say_screen", 23, -2,
1538 + "key_cut", 137, -1,
1539 + "say_to_bottom", 30, -2,
1540 + "edit_most", 35, -2,
1541 + "key_sleep", 142, -1,
1542 + "say_phonetic_char", 36, -2,
1543 + "speakup_quiet", 3, -2,
1544 + "key_hanja", 123, -1,
1545 + "say_next_line", 16, -2,
1546 + "vol_dec", 78, -2,
1547 + "key_help", 138, -1,
1548 + "key_xfer", 147, -1,
1549 + "speakup_goto", 1, -2,
1550 + "punct_inc", 83, -2,
1551 + "key_rightctrl", 97, -1,
1552 + "attrib_bleep_dec", 70, -2,
1553 + "key_rightshift", 54, -1,
1554 + "key_linefeed", 101, -1,
1555 + "key_wakeup", 143, -1,
1556 + "key_enter", 28, -1,
1557 + "key_again", 129, -1,
1558 + "key_file", 144, -1,
1559 + "key_tab", 15, -1,
1560 + "speakup_off", 26, -2,
1561 + "set_win", 40, -2,
1562 + "key_insert", 110, -1,
1563 + "key_setup", 141, -1,
1564 + "key_equal", 13, -1,
1565 + "tone_inc", 81, -2,
1566 + "key_hiragana", 91, -1,
1567 + "key_kpjpcomma", 95, -1,
1568 + "key_pause", 119, -1,
1569 + "key_volumeup", 115, -1,
1570 + "key_f1", 59, -1,
1571 + "key_hanguel", 122, -1,
1572 + "double", 32, -3,
1573 + "key_f2", 60, -1,
1574 + "key_computer", 157, -1,
1575 + "key_back", 158, -1,
1576 + "key_leftctrl", 29, -1,
1577 + "key_f3", 61, -1,
1578 + "key_f4", 62, -1,
1579 + "key_0", 11, -1,
1580 + "key_f5", 63, -1,
1581 + "key_yen", 124, -1,
1582 + "key_copy", 133, -1,
1583 + "speakup_paste", 5, -2,
1584 + "key_1", 2, -1,
1585 + "key_f6", 64, -1,
1586 + "toggle_cursoring", 46, -2,
1587 + "key_esc", 1, -1,
1588 + "key_2", 3, -1,
1589 + "key_f7", 65, -1,
1590 + "speakup_parked", 27, -2,
1591 + "punct_dec", 82, -2,
1592 + "key_3", 4, -1,
1593 + "key_f8", 66, -1,
1594 + "key_4", 5, -1,
1595 + "key_f9", 67, -1,
1596 + "key_5", 6, -1,
1597 + "key_calc", 140, -1,
1598 + "spell_phonetic", 21, -2,
1599 + "key_6", 7, -1,
1600 + "key_7", 8, -1,
1601 + "key_coffee", 152, -1,
1602 + "key_mail", 155, -1,
1603 + "say_attributes", 25, -2,
1604 + "say_to_right", 32, -2,
1605 + "key_8", 9, -1,
1606 + "key_mute", 113, -1,
1607 + "key_9", 10, -1,
1608 + "key_katakana", 90, -1,
1609 + "key_zenkakuhankaku", 85, -1,
1610 + "key_forward", 159, -1,
1611 + "key_up", 103, -1,
1612 + "tone_dec", 80, -2,
1613 + "key_leftalt", 56, -1,
1614 + "say_next_char", 10, -2,
1615 + "reading_punc_inc", 69, -2,
1616 + "rate_inc", 75, -2,
1617 + "key_backspace", 14, -1,
1618 + "bottom_edge", 18, -2,
1619 + "key_kp0", 82, -1,
1620 + "key_delete", 111, -1,
1621 + "key_prog1", 148, -1,
1622 + "say_char_num", 33, -2,
1623 + "key_kp1", 79, -1,
1624 + "key_end", 107, -1,
1625 + "key_prog2", 149, -1,
1626 + "key_kp2", 80, -1,
1627 + "say_prev_word", 12, -2,
1628 + "left_edge", 19, -2,
1629 + "key_kp3", 81, -1,
1630 + "key_katakanahiragana", 93, -1,
1631 + "key_right", 106, -1,
1632 + "key_kp4", 75, -1,
1633 + "key_find", 136, -1,
1634 + "key_kp5", 76, -1,
1635 + "speakup_cut", 4, -2,
1636 + "key_kp6", 77, -1,
1637 + "key_kp7", 71, -1,
1638 + "spkup_max_func", 47, -2,
1639 + "key_kp8", 72, -1,
1640 + "key_deletefile", 146, -1,
1641 + "key_f10", 68, -1,
1642 + "key_kp9", 73, -1,
1643 + "key_f11", 87, -1,
1644 + "key_sendfile", 145, -1,
1645 + "say_word", 11, -2,
1646 + "edit_repeat", 38, -2,
1647 + "key_leftbrace", 26, -1,
1648 + "key_f12", 88, -1,
1649 + "say_prev_line", 15, -2,
1650 + "say_from_top", 29, -2,
1651 + "var_start", 64, -2,
1652 + "reading_punc_dec", 68, -2,
1653 + "rate_dec", 74, -2,
1654 + "key_backslash", 43, -1,
1655 + "edit_exnum", 39, -2,
1656 + "key_kpslash", 98, -1,
1657 + "key_pagedown", 109, -1,
1658 + "key_kpplusminus", 118, -1,
1659 + "key_stop", 128, -1,
1660 + "key_props", 130, -1,
1661 + "pitch_inc", 77, -2,
1662 + "key_semicolon", 39, -1,
1663 + "key_rightalt", 100, -1,
1664 + "key_pageup", 104, -1,
1665 + "key_kpplus", 78, -1,
1666 + "say_line", 14, -2,
1667 + "bleeps_inc", 73, -2,
1668 + "key_leftshift", 42, -1,
1669 + "key_kpminus", 74, -1,
1670 + "key_paste", 135, -1,
1671 + "spell_delay_inc", 65, -2,
1672 + "punc_level_inc", 67, -2,
1673 + "key_www", 150, -1,
1674 + "edit_delim", 37, -2,
1675 + "key_capslock", 58, -1,
1676 + "key_muhenkan", 94, -1,
1677 + "key_compose", 127, -1,
1678 + "spk_key", 128, -2,
1679 + "key_sysrq", 99, -1,
1680 + "key_apostrophe", 40, -1,
1681 + "key_left", 105, -1,
1682 + "key_power", 116, -1,
1683 + "key_menu", 139, -1,
1684 + "voice_inc", 85, -2,
1685 + "key_kpcomma", 121, -1,
1686 + "spell_word", 22, -2,
1687 + "enable_win", 42, -2,
1688 + "key_a", 30, -1,
1689 + "key_henkan", 92, -1,
1690 + "key_bookmarks", 156, -1,
1691 + "say_line_indent", 28, -2,
1692 + "key_b", 48, -1,
1693 + "key_space", 57, -1,
1694 + "key_c", 46, -1,
1695 + "edit_some", 34, -2,
1696 + "key_d", 32, -1,
1697 + "key_numlock", 69, -1,
1698 + "key_home", 102, -1,
1699 + "shift", 1, -3,
1700 + "key_e", 18, -1,
1701 + "key_msdos", 151, -1,
1702 + "say_position", 24, -2,
1703 + "pitch_dec", 76, -2,
1704 + "key_f", 33, -1,
1705 + "key_cyclewindows", 154, -1,
1706 + "speakup_help", 45, -2,
1707 + "first_edit_bits", 34, -2,
1708 + "alt", 8, -3,
1709 + "key_g", 34, -1,
1710 + "key_kpenter", 96, -1,
1711 + "key_macro", 112, -1,
1712 + "bleeps_dec", 72, -2,
1713 + "ctrl", 4, -3,
1714 + "key_h", 35, -1,
1715 + "key_direction", 153, -1,
1716 + "key_i", 23, -1,
1717 + "spk_lock", 44, -2,
1718 + "spell_delay_dec", 64, -2,
1719 + "punc_level_dec", 66, -2,
1720 + "key_j", 36, -1,
1721 + "say_prev_char", 9, -2,
1722 + "key_k", 37, -1,
1723 + "key_102nd", 86, -1,
1724 + "key_l", 38, -1,
1725 + "key_ro", 89, -1,
1726 + "key_rightmeta", 126, -1,
1727 + "key_m", 50, -1,
1728 + "key_kpequal", 117, -1,
1729 + "key_undo", 131, -1,
1730 + "speech_kill", 2, -2,
1731 + "key_n", 49, -1,
1732 + "key_front", 132, -1,
1733 + "key_o", 24, -1,
1734 + "key_open", 134, -1,
1735 + "voice_dec", 84, -2,
1736 + "spk", 16, -3,
1737 + "key_p", 25, -1,
1738 + "say_last_char", 7, -2,
1739 + "say_from_left", 31, -2,
1740 + "key_q", 16, -1,
1741 + "key_slash", 53, -1,
1742 + "say_win", 43, -2,
1743 + "key_r", 19, -1,
1744 + "key_dot", 52, -1,
1745 + "say_char", 8, -2,
1746 + "vol_inc", 79, -2,
1747 + ".", 0, 0
1748 +};
1749 unchanged:
1750 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1751 +++ gregkh-2.6/drivers/char/speakup/mod_code.c 2005-07-27 13:02:56.000000000 -0700
1752 @@ -0,0 +1,25 @@
1753 +/* this code is to modularize a synth specific file, included at the end */
1754 +
1755 +static void __exit mod_synth_exit( void )
1756 +{
1757 + if ( synth == &MY_SYNTH )
1758 + synth_release( );
1759 + synth_remove( &MY_SYNTH );
1760 +}
1761 +
1762 +static int __init mod_synth_init( void )
1763 +{
1764 + int status = do_synth_init( &MY_SYNTH );
1765 + if ( status != 0 ) return status;
1766 + synth_add( &MY_SYNTH );
1767 +#if (LINUX_VERSION_CODE < 132419)
1768 +// MOD_INC_USE_COUNT;
1769 +#endif
1770 + return 0;
1771 +}
1772 +
1773 +module_init( mod_synth_init );
1774 +module_exit( mod_synth_exit );
1775 +MODULE_AUTHOR("Kirk Reiser <kirk@braille.uwo.ca>");
1776 +MODULE_DESCRIPTION("Synthesizer driver module for speakup for the synth->long_name");
1777 +MODULE_LICENSE( "GPL" );
1778 unchanged:
1779 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1780 +++ gregkh-2.6/drivers/char/speakup/serialio.h 2005-07-27 13:02:56.000000000 -0700
1781 @@ -0,0 +1,18 @@
1782 +#ifndef SSPK_SERIAL
1783 +#define SSPK_SERIAL
1784 +
1785 +#include <linux/serial.h> /* for rs_table, serial constants &
1786 + serial_uart_config */
1787 +#include <linux/serial_reg.h> /* for more serial constants */
1788 +#include <linux/serialP.h> /* for struct serial_state */
1789 +#include <asm/serial.h>
1790 +
1791 +#define SPK_SERIAL_TIMEOUT 1000000 /* countdown values for serial timeouts */
1792 +#define SPK_XMITR_TIMEOUT 1000000 /* countdown values transmitter/dsr timeouts */
1793 +#define SPK_LO_TTY 0 /* check ttyS0 ... ttyS3 */
1794 +#define SPK_HI_TTY 3
1795 +#define NUM_DISABLE_TIMEOUTS 3 /* # of timeouts permitted before disable */
1796 +#define SPK_TIMEOUT 100 /* buffer timeout in ms */
1797 +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
1798 +
1799 +#endif
1800 unchanged:
1801 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1802 +++ gregkh-2.6/drivers/char/speakup/speakup_acnt.h 2005-07-27 13:02:56.000000000 -0700
1803 @@ -0,0 +1,16 @@
1804 +/* speakup_acntpc.h - header file for speakups Accent-PC driver. */
1805 +
1806 +#define SYNTH_IO_EXTENT 0x02
1807 +
1808 +#define SYNTH_CLEAR 0x18 /* stops speech */
1809 +
1810 + /* Port Status Flags */
1811 +#define SYNTH_READABLE 0x01 /* mask for bit which is nonzero if a
1812 + byte can be read from the data port */
1813 +#define SYNTH_WRITABLE 0x02 /* mask for RDY bit, which when set to
1814 + 1, indicates the data port is ready
1815 + to accept a byte of data. */
1816 +#define SYNTH_QUIET 'S' /* synth is not speaking */
1817 +#define SYNTH_FULL 'F' /* synth is full. */
1818 +#define SYNTH_ALMOST_EMPTY 'M' /* synth has les than 2 seconds of text left */
1819 +#define SYNTH_SPEAKING 's' /* synth is speaking and has a fare way to go */
1820 unchanged:
1821 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1822 +++ gregkh-2.6/drivers/char/speakup/speakup_acntpc.c 2005-07-27 13:02:56.000000000 -0700
1823 @@ -0,0 +1,160 @@
1824 +/*
1825 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
1826 +* this version considerably modified by David Borowski, david575@rogers.com
1827 +
1828 + Copyright (C) 1998-99 Kirk Reiser.
1829 + Copyright (C) 2003 David Borowski.
1830 +
1831 + This program is free software; you can redistribute it and/or modify
1832 + it under the terms of the GNU General Public License as published by
1833 + the Free Software Foundation; either version 2 of the License, or
1834 + (at your option) any later version.
1835 +
1836 + This program is distributed in the hope that it will be useful,
1837 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1838 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1839 + GNU General Public License for more details.
1840 +
1841 + You should have received a copy of the GNU General Public License
1842 + along with this program; if not, write to the Free Software
1843 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1844 +
1845 + * this code is specificly written as a driver for the speakup screenreview
1846 + * package and is not a general device driver.
1847 + */
1848 +#include "spk_priv.h"
1849 +#include "speakup_acnt.h" /* local header file for Accent values */
1850 +
1851 +#define MY_SYNTH synth_acntpc
1852 +#define synth_readable( ) ( inb_p( synth_port_control ) & SYNTH_READABLE )
1853 +#define synth_writable( ) ( inb_p( synth_port_control ) & SYNTH_WRITABLE )
1854 +#define synth_full( ) ( inb_p( synth_port_tts ) == 'F' )
1855 +#define PROCSPEECH '\r'
1856 +
1857 +
1858 +static int synth_port_control;
1859 +static unsigned int synth_portlist[] =
1860 + { 0x2a8, 0 };
1861 +
1862 +static char *synth_immediate ( char *buf )
1863 +{
1864 + u_char ch;
1865 + while ( ( ch = *buf ) ) {
1866 + if ( ch == 0x0a ) ch = PROCSPEECH;
1867 + if ( synth_full( ) )
1868 + return buf;
1869 + while ( synth_writable( ) );
1870 + outb_p( ch, synth_port_tts );
1871 + buf++;
1872 + }
1873 + return 0;
1874 +}
1875 +
1876 +static void do_catch_up( unsigned long data )
1877 +{
1878 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
1879 + u_char ch;
1880 + synth_stop_timer( );
1881 + while ( synth_buff_out < synth_buff_in ) {
1882 + if ( synth_full( ) ) {
1883 + synth_delay( synth_full_time );
1884 + return;
1885 + }
1886 + while ( synth_writable( ) );
1887 + ch = *synth_buff_out++;
1888 + if ( ch == 0x0a ) ch = PROCSPEECH;
1889 + outb_p( ch, synth_port_tts );
1890 + if ( jiffies >= jiff_max && ch == SPACE ) {
1891 + while ( synth_writable( ) );
1892 + outb_p( PROCSPEECH, synth_port_tts );
1893 + synth_delay( synth_delay_time );
1894 + return;
1895 + }
1896 + }
1897 + while ( synth_writable( ) );
1898 + outb_p( PROCSPEECH, synth_port_tts );
1899 + synth_done( );
1900 +}
1901 +
1902 +static void synth_flush( void )
1903 +{
1904 + outb_p( SYNTH_CLEAR, synth_port_tts );
1905 +}
1906 +
1907 +static int synth_probe( void )
1908 +{
1909 + unsigned int port_val = 0;
1910 + int i = 0;
1911 + pr_info( "Probing for %s.\n", synth->long_name );
1912 + if ( synth_port_forced ) {
1913 + synth_port_tts = synth_port_forced;
1914 + pr_info( "probe forced to %x by kernel command line\n", synth_port_tts );
1915 + if ( synth_request_region( synth_port_tts-1, SYNTH_IO_EXTENT ) ) {
1916 + pr_warn( "sorry, port already reserved\n" );
1917 + return -EBUSY;
1918 + }
1919 + port_val = inw( synth_port_tts-1 );
1920 + synth_port_control = synth_port_tts-1;
1921 + } else {
1922 + for( i=0; synth_portlist[i]; i++ ) {
1923 + if ( synth_request_region( synth_portlist[i], SYNTH_IO_EXTENT ) ) {
1924 + pr_warn( "request_region: failed with 0x%x, %d\n",
1925 + synth_portlist[i], SYNTH_IO_EXTENT );
1926 + continue;
1927 + }
1928 + port_val = inw( synth_portlist[i] );
1929 + if ( ( port_val &= 0xfffc ) == 0x53fc ) { /* 'S' and out&input bits */
1930 + synth_port_control = synth_portlist[i];
1931 + synth_port_tts = synth_port_control+1;
1932 + break;
1933 + }
1934 + }
1935 + }
1936 + if ( ( port_val &= 0xfffc ) != 0x53fc ) { /* 'S' and out&input bits */
1937 + pr_info( "%s: not found\n", synth->long_name );
1938 + synth_release_region( synth_portlist[i], SYNTH_IO_EXTENT );
1939 + synth_port_control = 0;
1940 + return -ENODEV;
1941 + }
1942 + pr_info( "%s: %03x-%03x, driver version %s,\n", synth->long_name,
1943 + synth_port_control, synth_port_control+SYNTH_IO_EXTENT-1,
1944 + synth->version );
1945 + return 0;
1946 +}
1947 +
1948 +static void accent_release( void )
1949 +{
1950 + if ( synth_port_tts )
1951 + synth_release_region( synth_port_tts-1, SYNTH_IO_EXTENT );
1952 + synth_port_tts = 0;
1953 +}
1954 +
1955 +static int synth_is_alive( void )
1956 +{
1957 + synth_alive = 1;
1958 + return 1;
1959 +}
1960 +
1961 +static const char init_string[] = "\033=X \033Oi\033T2\033=M\033N1\n";
1962 +
1963 +static string_var stringvars[] = {
1964 + { CAPS_START, "\033P8" },
1965 + { CAPS_STOP, "\033P5" },
1966 + V_LAST_STRING
1967 +};
1968 +static num_var numvars[] = {
1969 + { RATE, "\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" },
1970 + { PITCH, "\033P%d", 5, 0, 9, 0, 0, 0 },
1971 + { VOL, "\033A%d", 5, 0, 9, 0, 0, 0 },
1972 + { TONE, "\033V%d", 5, 0, 9, 0, 0, 0 },
1973 + V_LAST_NUM
1974 +};
1975 +
1976 +struct spk_synth synth_acntpc = {"acntpc", "1.1", "Accent PC",
1977 + init_string, 500, 50, 50, 1000, 0, 0, SYNTH_CHECK,
1978 + stringvars, numvars, synth_probe, accent_release, synth_immediate,
1979 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL };
1980 +
1981 +#ifdef MODULE
1982 +#include "mod_code.c"
1983 +#endif
1984 unchanged:
1985 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1986 +++ gregkh-2.6/drivers/char/speakup/speakup_acntsa.c 2005-07-27 13:02:56.000000000 -0700
1987 @@ -0,0 +1,184 @@
1988 +/*
1989 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
1990 +* this version considerably modified by David Borowski, david575@rogers.com
1991 +
1992 + Copyright (C) 1998-99 Kirk Reiser.
1993 + Copyright (C) 2003 David Borowski.
1994 +
1995 + This program is free software; you can redistribute it and/or modify
1996 + it under the terms of the GNU General Public License as published by
1997 + the Free Software Foundation; either version 2 of the License, or
1998 + (at your option) any later version.
1999 +
2000 + This program is distributed in the hope that it will be useful,
2001 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2002 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2003 + GNU General Public License for more details.
2004 +
2005 + You should have received a copy of the GNU General Public License
2006 + along with this program; if not, write to the Free Software
2007 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008 +
2009 + * this code is specificly written as a driver for the speakup screenreview
2010 + * package and is not a general device driver.
2011 + */
2012 +#include "spk_priv.h"
2013 +#include "serialio.h"
2014 +#include "speakup_acnt.h" /* local header file for Accent values */
2015 +
2016 +#define MY_SYNTH synth_acntsa
2017 +#define synth_full( ) ( inb_p( synth_port_tts ) == 'F' )
2018 +#define PROCSPEECH '\r'
2019 +
2020 +static int timeouts = 0; /* sequential number of timeouts */
2021 +
2022 +static int
2023 +wait_for_xmitr ( void )
2024 +{
2025 + int check, tmout = SPK_XMITR_TIMEOUT;
2026 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
2027 + synth_alive = 0;
2028 + return 0;
2029 + }
2030 + do { /* holding register empty? */
2031 + check = inb_p ( synth_port_tts + UART_LSR );
2032 + if ( --tmout == 0 ) {
2033 + pr_warn ( "%s: timed out\n", synth->long_name );
2034 + timeouts++;
2035 + return 0;
2036 + }
2037 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
2038 + tmout = SPK_XMITR_TIMEOUT;
2039 + do { /* CTS */
2040 + check = inb_p ( synth_port_tts + UART_MSR );
2041 + if ( --tmout == 0 ) {
2042 + timeouts++;
2043 + return 0;
2044 + }
2045 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
2046 + timeouts = 0;
2047 + return 1;
2048 +}
2049 +
2050 +static inline int
2051 +spk_serial_out ( const char ch )
2052 +{
2053 + if ( synth_alive && wait_for_xmitr ( ) ) {
2054 + outb_p ( ch, synth_port_tts );
2055 + return 1;
2056 + }
2057 + return 0;
2058 +}
2059 +
2060 +static void
2061 +do_catch_up ( unsigned long data )
2062 +{
2063 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
2064 + u_char ch;
2065 + synth_stop_timer ( );
2066 + while ( synth_buff_out < synth_buff_in ) {
2067 + ch = *synth_buff_out;
2068 + if ( ch == 0x0a ) ch = 0x0D;
2069 + if ( !spk_serial_out ( ch ) ) {
2070 + synth_delay ( synth_full_time );
2071 + return;
2072 + }
2073 + synth_buff_out++;
2074 + if ( jiffies >= jiff_max && ch == ' ' ) {
2075 + spk_serial_out ( PROCSPEECH );
2076 + synth_delay ( synth_delay_time );
2077 + return;
2078 + }
2079 + }
2080 + spk_serial_out ( PROCSPEECH );
2081 + synth_done( );
2082 +}
2083 +
2084 +static char *synth_immediate ( char *buff )
2085 +{
2086 + u_char ch;
2087 + while ( ( ch = *buff ) ) {
2088 + if ( ch == 0x0a ) ch = PROCSPEECH;
2089 + if ( wait_for_xmitr( ) )
2090 + outb( ch, synth_port_tts );
2091 + else return buff;
2092 + buff++;
2093 + }
2094 + return 0;
2095 +}
2096 +
2097 +static void synth_flush ( void )
2098 +{
2099 + spk_serial_out ( SYNTH_CLEAR );
2100 +}
2101 +
2102 +static int serprobe ( int index )
2103 +{
2104 + struct serial_state *ser = spk_serial_init( index );
2105 + if ( ser == NULL ) return -1;
2106 + outb ( 0x0d, ser->port );
2107 + // mdelay ( 1 );
2108 + /* ignore any error results, if port was forced */
2109 + if ( synth_port_forced ) return 0;
2110 + /* check for accent s.a now... */
2111 + if ( !synth_immediate( "\x18" ) )
2112 + return 0;
2113 + spk_serial_release( );
2114 + timeouts = synth_alive = 0; /* not ignoring */
2115 + return -1;
2116 +}
2117 +
2118 +static int synth_probe ( void )
2119 +{
2120 + int i = 0, failed=0;
2121 + pr_info ( "Probing for %s.\n", synth->long_name );
2122 + for ( i = SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
2123 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
2124 + }
2125 + if ( failed ) {
2126 + pr_info ( "%s: not found\n", synth->long_name );
2127 + return -ENODEV;
2128 + }
2129 + pr_info ( "%s: %03x-%03x, Driver Version %s,\n", synth->long_name,
2130 + synth_port_tts, synth_port_tts + 7, synth->version );
2131 + synth_immediate( "\033=R\r" );
2132 + mdelay( 100 );
2133 + return 0;
2134 +}
2135 +
2136 +static int
2137 +synth_is_alive ( void )
2138 +{
2139 + if ( synth_alive ) return 1;
2140 + if ( !synth_alive && wait_for_xmitr ( ) > 0 ) { /* restart */
2141 + synth_alive = 1;
2142 + synth_write_string ( synth->init );
2143 + return 2;
2144 + }
2145 + pr_warn ( "%s: can't restart synth\n", synth->long_name );
2146 + return 0;
2147 +}
2148 +
2149 +static const char init_string[] = "\033T2\033=M\033Oi\033N1\n";
2150 +
2151 +static string_var stringvars[] = {
2152 + { CAPS_START, "\033P8" },
2153 + { CAPS_STOP, "\033P5" },
2154 + V_LAST_STRING
2155 +};
2156 +static num_var numvars[] = {
2157 + { RATE, "\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" },
2158 + { PITCH, "\033P%d", 5, 0, 9, 0, 0, 0 },
2159 + { VOL, "\033A%d", 9, 0, 9, 0, 0, 0 },
2160 + { TONE, "\033V%d", 5, 0, 9, 0, 0, 0 },
2161 + V_LAST_NUM
2162 +};
2163 +
2164 +struct spk_synth synth_acntsa = { "acntsa", "1.1", "Accent-SA",
2165 + init_string, 400, 5, 30, 1000, 0, 0, SYNTH_CHECK,
2166 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
2167 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
2168 +
2169 +#ifdef MODULE
2170 +#include "mod_code.c"
2171 +#endif
2172 unchanged:
2173 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2174 +++ gregkh-2.6/drivers/char/speakup/speakup_apollo.c 2005-07-27 13:02:56.000000000 -0700
2175 @@ -0,0 +1,195 @@
2176 +/*
2177 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
2178 +* this version considerably modified by David Borowski, david575@rogers.com
2179 +
2180 + Copyright (C) 1998-99 Kirk Reiser.
2181 + Copyright (C) 2003 David Borowski.
2182 +
2183 + This program is free software; you can redistribute it and/or modify
2184 + it under the terms of the GNU General Public License as published by
2185 + the Free Software Foundation; either version 2 of the License, or
2186 + (at your option) any later version.
2187 +
2188 + This program is distributed in the hope that it will be useful,
2189 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2190 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2191 + GNU General Public License for more details.
2192 +
2193 + You should have received a copy of the GNU General Public License
2194 + along with this program; if not, write to the Free Software
2195 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2196 +
2197 + * this code is specificly written as a driver for the speakup screenreview
2198 + * package and is not a general device driver.
2199 + */
2200 +#include "spk_priv.h"
2201 +#include "serialio.h"
2202 +
2203 +#define MY_SYNTH synth_apollo
2204 +#define SYNTH_CLEAR 0x18
2205 +#define PROCSPEECH '\r'
2206 +
2207 +static int timeouts = 0; /* sequential number of timeouts */
2208 +
2209 +static int wait_for_xmitr( void )
2210 +{
2211 + int check, tmout = SPK_XMITR_TIMEOUT;
2212 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
2213 + synth_alive = 0;
2214 + timeouts = 0;
2215 + return 0;
2216 + }
2217 + do {
2218 + check = inb( synth_port_tts + UART_LSR );
2219 + if ( --tmout == 0 ) {
2220 + pr_warn( "APOLLO: timed out\n" );
2221 + timeouts++;
2222 + return 0;
2223 + }
2224 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
2225 + tmout = SPK_XMITR_TIMEOUT;
2226 + do {
2227 + check = inb( synth_port_tts + UART_MSR );
2228 + if ( --tmout == 0 ) {
2229 + timeouts++;
2230 + return 0;
2231 + }
2232 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
2233 + timeouts = 0;
2234 + return 1;
2235 +}
2236 +
2237 +static inline int spk_serial_out( const char ch )
2238 +{
2239 + // int timer = 9000000;
2240 + if ( synth_alive && wait_for_xmitr( ) ) {
2241 + outb( ch, synth_port_tts );
2242 + /*while ( inb( synth_port_tts+UART_MSR ) & UART_MSR_CTS ) if ( --timer == 0 ) break;*/
2243 + /* outb( UART_MCR_DTR, synth_port_tts + UART_MCR );*/
2244 + return 1;
2245 + }
2246 + return 0;
2247 +}
2248 +
2249 +/*
2250 +static unsigned char spk_serial_in( void )
2251 +{
2252 + int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
2253 + do {
2254 + lsr = inb( synth_port_tts + UART_LSR );
2255 + if ( --tmout == 0 ) return 0xff;
2256 + } while ( !( lsr & UART_LSR_DR ) );
2257 + c = inb( synth_port_tts + UART_RX );
2258 + return ( unsigned char ) c;
2259 +}
2260 +*/
2261 +
2262 +static void do_catch_up( unsigned long data )
2263 +{
2264 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
2265 + u_char ch;
2266 +synth_stop_timer( );
2267 + while ( synth_buff_out < synth_buff_in ) {
2268 + ch = *synth_buff_out;
2269 + if ( !spk_serial_out( ch ) ) {
2270 + outb( UART_MCR_DTR, synth_port_tts + UART_MCR );
2271 + outb( UART_MCR_DTR | UART_MCR_RTS, synth_port_tts + UART_MCR );
2272 + synth_delay( synth_full_time );
2273 + return;
2274 + }
2275 + synth_buff_out++;
2276 + if ( jiffies >= jiff_max && synth_buff_out-synth_buffer > 10 ) {
2277 + spk_serial_out( PROCSPEECH );
2278 + synth_delay( synth_delay_time );
2279 + return;
2280 + }
2281 + }
2282 + spk_serial_out( PROCSPEECH );
2283 + synth_done( );
2284 +}
2285 +
2286 +static char *synth_immediate ( char *buf )
2287 +{
2288 + u_char ch;
2289 + while ( ( ch = *buf ) ) {
2290 + if ( ch == 0x0a ) ch = PROCSPEECH;
2291 + if ( wait_for_xmitr( ) )
2292 + outb( ch, synth_port_tts );
2293 + else return buf;
2294 + buf++;
2295 + }
2296 + return 0;
2297 +}
2298 +
2299 +static void synth_flush ( void )
2300 +{
2301 + spk_serial_out ( SYNTH_CLEAR );
2302 +}
2303 +
2304 +static int serprobe( int index )
2305 +{
2306 + struct serial_state *ser = spk_serial_init( index );
2307 + if ( ser == NULL ) return -1;
2308 + outb( 0x0d, ser->port ); /* wake it up if older BIOS */
2309 + mdelay( 1 );
2310 + synth_port_tts = ser->port;
2311 + if ( synth_port_forced ) return 0;
2312 + /* check for apollo now... */
2313 + if ( !synth_immediate( "\x18" ) ) return 0;
2314 + pr_warn( "port %x failed\n", synth_port_tts );
2315 + spk_serial_release( );
2316 + timeouts = synth_alive = synth_port_tts = 0;
2317 + return -1;
2318 +}
2319 +
2320 +static int synth_probe( void )
2321 +{
2322 +int i, failed=0;
2323 + pr_info( "Probing for %s.\n", synth->long_name );
2324 + for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
2325 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
2326 + }
2327 + if ( failed ) {
2328 + pr_info( "%s: not found\n", synth->long_name );
2329 + return -ENODEV;
2330 + }
2331 + pr_info( "%s: %03x-%03x, Driver version %s,\n", synth->long_name,
2332 + synth_port_tts, synth_port_tts + 7, synth->version );
2333 + return 0;
2334 +}
2335 +
2336 +static int synth_is_alive( void )
2337 +{
2338 + if ( synth_alive ) return 1;
2339 + if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
2340 + synth_alive = 1;
2341 + synth_write_string( synth->init );
2342 + return 2; /* reenabled */
2343 + } else pr_warn( "%s: can't restart synth\n", synth->long_name );
2344 + return 0;
2345 +}
2346 +
2347 +static const char init_string[] = "@R3@D0@K1\r";
2348 +
2349 +static string_var stringvars[] = {
2350 + { CAPS_START, "cap, " },
2351 + { CAPS_STOP, "" },
2352 + V_LAST_STRING
2353 +};
2354 +static num_var numvars[] = {
2355 + { RATE, "@W%d", 6, 1, 9, 0, 0, 0 },
2356 + { PITCH, "@F%x", 10, 0, 15, 0, 0, 0 },
2357 + { VOL, "@A%x", 10, 0, 15, 0, 0, 0 },
2358 + { VOICE, "@V%d", 1, 1, 6, 0, 0, 0 },
2359 + { LANG, "@=%d,", 1, 1, 4, 0, 0, 0 },
2360 + V_LAST_NUM
2361 +};
2362 +
2363 +struct spk_synth synth_apollo = {"apollo", "1.2", "Apollo",
2364 + init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
2365 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
2366 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
2367 +
2368 +#ifdef MODULE
2369 +#include "mod_code.c"
2370 +#endif
2371 unchanged:
2372 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2373 +++ gregkh-2.6/drivers/char/speakup/speakup_audptr.c 2005-07-27 13:02:56.000000000 -0700
2374 @@ -0,0 +1,201 @@
2375 +/*
2376 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
2377 +* this version considerably modified by David Borowski, david575@rogers.com
2378 +
2379 + Copyright (C) 1998-99 Kirk Reiser.
2380 + Copyright (C) 2003 David Borowski.
2381 +
2382 + This program is free software; you can redistribute it and/or modify
2383 + it under the terms of the GNU General Public License as published by
2384 + the Free Software Foundation; either version 2 of the License, or
2385 + (at your option) any later version.
2386 +
2387 + This program is distributed in the hope that it will be useful,
2388 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2389 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2390 + GNU General Public License for more details.
2391 +
2392 + You should have received a copy of the GNU General Public License
2393 + along with this program; if not, write to the Free Software
2394 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2395 +
2396 + * this code is specificly written as a driver for the speakup screenreview
2397 + * package and is not a general device driver.
2398 + */
2399 +#include "spk_priv.h"
2400 +#include "serialio.h"
2401 +
2402 +#define MY_SYNTH synth_audptr
2403 +#define SYNTH_CLEAR 0x18 /* flush synth buffer */
2404 +#define PROCSPEECH '\r' /* start synth processing speech char */
2405 +
2406 +static int timeouts = 0; /* sequential number of timeouts */
2407 +
2408 +static int wait_for_xmitr( void )
2409 +{
2410 + int check, tmout = SPK_XMITR_TIMEOUT;
2411 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
2412 + synth_alive = 0;
2413 + timeouts = 0;
2414 + return 0;
2415 + }
2416 + do { /* holding register empty? */
2417 + check = inb( synth_port_tts + UART_LSR );
2418 + if ( --tmout == 0 ) {
2419 + pr_warn( "%s: timed out\n", synth->long_name );
2420 + timeouts++;
2421 + return 0;
2422 + }
2423 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
2424 + tmout = SPK_XMITR_TIMEOUT;
2425 + do { /* CTS */
2426 + check = inb( synth_port_tts + UART_MSR );
2427 + if ( --tmout == 0 ) {
2428 + timeouts++;
2429 + return 0;
2430 + }
2431 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
2432 + timeouts = 0;
2433 + return 1;
2434 +}
2435 +
2436 +static inline int spk_serial_out( const char ch )
2437 +{
2438 + if ( synth_alive && wait_for_xmitr( ) ) {
2439 + outb( ch, synth_port_tts );
2440 + return 1;
2441 + }
2442 + return 0;
2443 +}
2444 +
2445 +static unsigned char spk_serial_in( void )
2446 +{
2447 + int c, lsr, tmout = SPK_SERIAL_TIMEOUT;
2448 + do {
2449 + lsr = inb( synth_port_tts + UART_LSR );
2450 + if ( --tmout == 0 ) return 0xff;
2451 + } while ( !( lsr & UART_LSR_DR ) );
2452 + c = inb( synth_port_tts + UART_RX );
2453 + return ( unsigned char ) c;
2454 +}
2455 +
2456 +static void do_catch_up( unsigned long data )
2457 +{
2458 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
2459 + u_char ch;
2460 +synth_stop_timer( );
2461 + while ( synth_buff_out < synth_buff_in ) {
2462 + ch = *synth_buff_out;
2463 + if ( ch == 0x0a ) ch = PROCSPEECH;
2464 + if ( !spk_serial_out( ch ) ) {
2465 + synth_delay( synth_full_time );
2466 + return;
2467 + }
2468 + synth_buff_out++;
2469 + if ( jiffies >= jiff_max && ch == SPACE ) {
2470 + spk_serial_out( PROCSPEECH );
2471 + synth_delay( synth_delay_time );
2472 + return;
2473 + }
2474 + }
2475 + spk_serial_out( PROCSPEECH );
2476 + synth_done( );
2477 +}
2478 +
2479 +static char *synth_immediate ( char *buf )
2480 +{
2481 + u_char ch;
2482 + while ( ( ch = *buf ) ) {
2483 + if ( ch == 0x0a ) ch = PROCSPEECH;
2484 + if ( wait_for_xmitr( ) )
2485 + outb( ch, synth_port_tts );
2486 + else return buf;
2487 + buf++;
2488 + }
2489 + return 0;
2490 +}
2491 +
2492 +static void synth_flush( void )
2493 +{
2494 + while ( ( inb( synth_port_tts + UART_LSR ) & BOTH_EMPTY ) != BOTH_EMPTY );
2495 + outb( SYNTH_CLEAR, synth_port_tts );
2496 + spk_serial_out( PROCSPEECH );
2497 + }
2498 +
2499 +static char synth_id[40] = "";
2500 +
2501 +static int serprobe( int index )
2502 +{
2503 + u_char test = 0;
2504 + struct serial_state *ser = spk_serial_init( index );
2505 + if ( ser == NULL ) return -1;
2506 + /* ignore any error results, if port was forced */
2507 + if ( synth_port_forced )
2508 + return 0;
2509 + synth_immediate( "\x05[Q]" );
2510 + if ( ( synth_id[test] = spk_serial_in( ) ) == 'A' ) {
2511 + do { /* read version string from synth */
2512 + synth_id[++test] = spk_serial_in( );
2513 + } while ( synth_id[test] != '\n' && test < 32 );
2514 + synth_id[++test] = 0x00;
2515 + if ( test != 32 )
2516 + return 0;
2517 + }
2518 + spk_serial_release( );
2519 + timeouts = synth_alive = 0; /* not ignoring */
2520 + return -1;
2521 +}
2522 +
2523 +static int synth_probe( void )
2524 +{
2525 +int i=0, failed=0;
2526 + pr_info( "Probing for %s.\n", synth->long_name );
2527 + for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
2528 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
2529 + }
2530 + if ( failed ) {
2531 + pr_info( "%s: not found\n", synth->long_name );
2532 + return -ENODEV;
2533 + }
2534 + pr_info( "%s: %03x-%03x, Driver %s,\n", synth->long_name,
2535 + synth_port_tts, synth_port_tts + 7, synth->version );
2536 + if ( synth_id[0] == 'A' )
2537 + pr_info( "%s version: %s", synth->long_name, synth_id );
2538 + return 0;
2539 +}
2540 +
2541 +static int synth_is_alive( void )
2542 +{
2543 + if ( synth_alive ) return 1;
2544 + if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
2545 + synth_alive = 1;
2546 + synth_write_string( synth->init );
2547 + return 2;
2548 + }
2549 + return 0;
2550 +}
2551 +
2552 +static const char init_string[] = "\x05[D1]\x05[Ol]";
2553 +
2554 +static string_var stringvars[] = {
2555 + { CAPS_START, "\x05[f99]" },
2556 + { CAPS_STOP, "\x05[f80]" },
2557 + V_LAST_STRING
2558 +};
2559 +static num_var numvars[] = {
2560 + { RATE, "\x05[r%d]", 10, 0, 20, -100, 10, 0 },
2561 + { PITCH, "\x05[f%d]", 80, 39, 4500, 0, 0, 0 },
2562 + { VOL, "\x05[g%d]", 21, 0, 40, 0, 0, 0 },
2563 + { TONE, "\x05[s%d]", 9, 0,63, 0, 0, 0 },
2564 + { PUNCT, "\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" },
2565 + V_LAST_NUM
2566 +};
2567 +
2568 +struct spk_synth synth_audptr = {"audptr", "1.1", "Audapter",
2569 + init_string, 400, 5, 30, 5000, 0, 0, SYNTH_CHECK,
2570 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
2571 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
2572 +
2573 +#ifdef MODULE
2574 +#include "mod_code.c"
2575 +#endif
2576 unchanged:
2577 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2578 +++ gregkh-2.6/drivers/char/speakup/speakup_bns.c 2005-07-27 13:02:56.000000000 -0700
2579 @@ -0,0 +1,174 @@
2580 +/*
2581 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
2582 +* this version considerably modified by David Borowski, david575@rogers.com
2583 +
2584 + Copyright (C) 1998-99 Kirk Reiser.
2585 + Copyright (C) 2003 David Borowski.
2586 +
2587 + This program is free software; you can redistribute it and/or modify
2588 + it under the terms of the GNU General Public License as published by
2589 + the Free Software Foundation; either version 2 of the License, or
2590 + (at your option) any later version.
2591 +
2592 + This program is distributed in the hope that it will be useful,
2593 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2594 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2595 + GNU General Public License for more details.
2596 +
2597 + You should have received a copy of the GNU General Public License
2598 + along with this program; if not, write to the Free Software
2599 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2600 +
2601 + * this code is specificly written as a driver for the speakup screenreview
2602 + * package and is not a general device driver.
2603 + */
2604 +#include "spk_priv.h"
2605 +#include "serialio.h"
2606 +
2607 +#define MY_SYNTH synth_bns
2608 +#define SYNTH_CLEAR 0x18
2609 +#define PROCSPEECH '\r'
2610 +
2611 +static int wait_for_xmitr( void )
2612 +{
2613 + static int timeouts = 0; /* sequential number of timeouts */
2614 + int check, tmout = SPK_XMITR_TIMEOUT;
2615 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
2616 + synth_alive = 0;
2617 + timeouts = 0;
2618 + return 0;
2619 + }
2620 + do {
2621 + check = inb( synth_port_tts + UART_LSR );
2622 + if ( --tmout == 0 ) {
2623 + pr_warn( "BNS: timed out\n" );
2624 + timeouts++;
2625 + return 0;
2626 + }
2627 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
2628 + tmout = SPK_XMITR_TIMEOUT;
2629 + do {
2630 + check = inb( synth_port_tts + UART_MSR );
2631 + if ( --tmout == 0 ) {
2632 + timeouts++;
2633 + return 0;
2634 + }
2635 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
2636 + timeouts = 0;
2637 + return 1;
2638 +}
2639 +
2640 +static inline int spk_serial_out( const char ch )
2641 +{
2642 + if ( synth_alive && wait_for_xmitr( ) ) {
2643 + outb( ch, synth_port_tts );
2644 + return 1;
2645 + }
2646 + return 0;
2647 +}
2648 +
2649 +static void do_catch_up( unsigned long data )
2650 +{
2651 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
2652 + u_char ch;
2653 + synth_stop_timer( );
2654 + while ( synth_buff_out < synth_buff_in ) {
2655 + ch = *synth_buff_out;
2656 + if ( ch == '\n' ) ch = PROCSPEECH;
2657 + if ( !spk_serial_out( ch ) ) {
2658 + synth_delay( synth_full_time );
2659 + return;
2660 + }
2661 + synth_buff_out++;
2662 + if ( jiffies >= jiff_max && ch == ' ' ) {
2663 + spk_serial_out( PROCSPEECH );
2664 + synth_delay( synth_delay_time );
2665 + return;
2666 + }
2667 + }
2668 + spk_serial_out( PROCSPEECH );
2669 + synth_done( );
2670 +}
2671 +
2672 +static char *synth_immediate ( char *buf )
2673 +{
2674 + u_char ch;
2675 + while ( ( ch = *buf ) ) {
2676 + if ( ch == 0x0a ) ch = PROCSPEECH;
2677 + if ( wait_for_xmitr( ) )
2678 + outb( ch, synth_port_tts );
2679 + else return buf;
2680 + buf++;
2681 + }
2682 + return 0;
2683 +}
2684 +
2685 +static void synth_flush ( void )
2686 +{
2687 + spk_serial_out ( SYNTH_CLEAR );
2688 +}
2689 +
2690 +static int serprobe( int index )
2691 +{
2692 + struct serial_state *ser = spk_serial_init( index );
2693 + if ( ser == NULL ) return -1;
2694 + outb( '\r', ser->port );
2695 + if ( synth_port_forced ) return 0;
2696 + /* check for bns now... */
2697 + if ( !synth_immediate( "\x18" ) ) return 0;
2698 + spk_serial_release( );
2699 + synth_alive = 0;
2700 + return -1;
2701 +}
2702 +
2703 +static int synth_probe( void )
2704 +{
2705 +int i=0, failed=0;
2706 + pr_info( "Probing for %s.\n", synth->long_name );
2707 + for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
2708 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
2709 + }
2710 + if ( failed ) {
2711 + pr_info( "%s: not found\n", synth->long_name );
2712 + return -ENODEV;
2713 + }
2714 + pr_info( "%s: %03x-%03x, Driver version %s,\n", synth->long_name,
2715 + synth_port_tts, synth_port_tts + 7, synth->version );
2716 + return 0;
2717 +}
2718 +
2719 +static int synth_is_alive( void )
2720 +{
2721 + if ( synth_alive ) return 1;
2722 + if ( !synth_alive && wait_for_xmitr( ) > 0 ) { /* restart */
2723 + synth_alive = 1;
2724 + synth_write_string( synth->init );
2725 + return 2;
2726 + }
2727 + pr_warn( "%s: can't restart synth\n", synth->long_name );
2728 + return 0;
2729 +}
2730 +
2731 +static const char init_string[] = "\x05Z\x05\x43";
2732 +
2733 +static string_var stringvars[] = {
2734 + { CAPS_START, "\x05\x31\x32P" },
2735 + { CAPS_STOP, "\x05\x38P" },
2736 + V_LAST_STRING
2737 +};
2738 +static num_var numvars[] = {
2739 + { RATE, "\x05%dE", 8, 1, 16, 0, 0, 0 },
2740 + { PITCH, "\x05%dP", 8, 0, 16, 0, 0, 0 },
2741 + { VOL, "\x05%dV", 8, 0, 16, 0, 0, 0 },
2742 + { TONE, "\x05%dT", 8, 0, 16, 0, 0, 0 },
2743 + V_LAST_NUM
2744 +};
2745 +
2746 +struct spk_synth synth_bns = {"bns", "1.1", "Braille 'N Speak",
2747 + init_string, 500, 50, 50, 5000, 0, 0, SYNTH_CHECK,
2748 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
2749 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
2750 +
2751 +#ifdef MODULE
2752 +#include "mod_code.c"
2753 +#endif
2754 unchanged:
2755 --- gregkh-2.6/drivers/char/speakup/speakup.c 2005-07-27 13:02:56.000000000 -0700
2756 +++ gregkh-2.6/drivers/char/speakup/speakup.c 2005-07-27 13:41:06.000000000 -0700
2757 @@ -0,0 +1,2280 @@
2758 +/* speakup.c
2759 + review functions for the speakup screen review package.
2760 + originally written by: Kirk Reiser and Andy Berdan.
2761 +
2762 + extensively modified by David Borowski.
2763 +
2764 + Copyright (C ) 1998 Kirk Reiser.
2765 + Copyright (C ) 2003 David Borowski.
2766 +
2767 + This program is free software; you can redistribute it and/or modify
2768 + it under the terms of the GNU General Public License as published by
2769 + the Free Software Foundation; either version 2 of the License, or
2770 + (at your option ) any later version.
2771 +
2772 + This program is distributed in the hope that it will be useful,
2773 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2774 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2775 + GNU General Public License for more details.
2776 +
2777 + You should have received a copy of the GNU General Public License
2778 + along with this program; if not, write to the Free Software
2779 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2780 +*/
2781 +
2782 +#define __KERNEL_SYSCALLS__
2783 +
2784 +#include <linux/kernel.h>
2785 +#include <linux/version.h>
2786 +#include <linux/vt.h>
2787 +#include <linux/tty.h>
2788 +#include <linux/mm.h> /* __get_free_page( ) and friends */
2789 +#include <linux/vt_kern.h>
2790 +#if (LINUX_VERSION_CODE < 132419)
2791 +#include <linux/console_struct.h>
2792 +#include <linux/kbd_ll.h>
2793 +#include <asm/keyboard.h>
2794 +#endif
2795 +#include <linux/ctype.h>
2796 +#include <linux/selection.h>
2797 +#include <asm/uaccess.h> /* copy_from|to|user( ) and others */
2798 +#include <linux/unistd.h>
2799 +
2800 +#include <linux/keyboard.h> /* for KT_SHIFT */
2801 +#include <linux/kbd_kern.h> /* for vc_kbd_* and friends */
2802 +#include <linux/vt_kern.h>
2803 +#include <linux/input.h>
2804 +#include <linux/kmod.h>
2805 +#include <linux/speakup.h>
2806 +
2807 +#include "cvsversion.h"
2808 +#include "spk_priv.h"
2809 +#include <linux/bootmem.h> /* for alloc_bootmem */
2810 +
2811 +/* speakup_*_selection */
2812 +#include <linux/module.h>
2813 +#include <linux/sched.h>
2814 +#include <linux/slab.h>
2815 +#include <linux/types.h>
2816 +#include <asm/uaccess.h>
2817 +#include <linux/consolemap.h>
2818 +
2819 +#ifndef MIN
2820 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
2821 +#endif
2822 +
2823 +#define SPEAKUP_VERSION "Speakup v-2.00" CVSVERSION
2824 +#define MAX_DELAY ( (500 * HZ ) / 1000 )
2825 +#define KEY_MAP_VER 119
2826 +#define MINECHOCHAR SPACE
2827 +
2828 +/* these are globals from the kernel code */
2829 +extern void *kmalloc (size_t, unsigned int );
2830 +extern void kfree (const void * );
2831 +extern struct kbd_struct * kbd;
2832 +extern int fg_console;
2833 +extern short punc_masks[];
2834 +
2835 +static special_func special_handler = NULL;
2836 +special_func help_handler = NULL;
2837 +
2838 +int synth_file_inuse = 0;
2839 +short pitch_shift = 0, synth_flags = 0;
2840 +static char buf[256];
2841 +short attrib_bleep = 0, bleeps = 0, bleep_time = 1;
2842 +short no_intr = 0, spell_delay = 0;
2843 +short key_echo = 0, cursor_timeout = 120, say_word_ctl = 0;
2844 +short say_ctrl = 0, bell_pos = 0;
2845 +short punc_mask = 0, punc_level = 0, reading_punc = 0;
2846 +char str_caps_start[MAXVARLEN+1] = "\0", str_caps_stop[MAXVARLEN+1] = "\0";
2847 +bits_data punc_info[] = {
2848 + { "none", "", 0 },
2849 + { "some", "/$%&@", SOME },
2850 + { "most", "$%&#()=+*/@^<>|\\", MOST },
2851 + { "all", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", PUNC },
2852 + { "delimiters", "", B_WDLM },
2853 + { "repeats", "()", CH_RPT },
2854 + { "extended numeric", "", B_EXNUM },
2855 + { "symbols", "", B_SYM },
2856 + { 0, 0 }
2857 +};
2858 +char mark_cut_flag = 0;
2859 +u_short mark_x = 0, mark_y = 0;
2860 +static char synth_name[10] = CONFIG_SPEAKUP_DEFAULT;
2861 +#define MAX_KEY 160
2862 +u_char *our_keys[MAX_KEY], *shift_table;
2863 +static u_char key_buf[600];
2864 +static u_char key_defaults[] = {
2865 +#include "speakupmap.h"
2866 +};
2867 +
2868 +#if (LINUX_VERSION_CODE < 132419)
2869 +extern struct tty_struct *tty;
2870 +typedef void (*k_handler_fn)(unsigned char value, char up_flag);
2871 +#define KBD_PROTO u_char value, char up_flag
2872 +#define KBD_ARGS value, up_flag
2873 +#else
2874 +struct tty_struct *tty;
2875 +#define key_handler k_handler
2876 +typedef void (*k_handler_fn)(struct vc_data *vc, unsigned char value,
2877 + char up_flag, struct pt_regs *regs);
2878 +#define KBD_PROTO struct vc_data *vc, u_char value, char up_flag, struct pt_regs *regs
2879 +#define KBD_ARGS vc, value, up_flag, regs
2880 +#endif
2881 +extern k_handler_fn key_handler[16];
2882 +static k_handler_fn do_shift, do_spec, do_latin, do_cursor;
2883 +EXPORT_SYMBOL( help_handler );
2884 +EXPORT_SYMBOL( special_handler );
2885 +EXPORT_SYMBOL( our_keys );
2886 +
2887 +static void speakup_date (struct vc_data *vc );
2888 +static void spkup_write (const char *in_buf, int count );
2889 +int set_mask_bits( const char *input, const int which, const int how );
2890 +
2891 +char str_ctl[] = "control-";
2892 +char *colors[] = {
2893 + "black", "blue", "green", "cyan", "red", "magenta", "yellow", "white",
2894 + "grey"
2895 +};
2896 +
2897 +char *phonetic[] = {
2898 + "alpha", "beta", "charley", "delta", "echo", "fox", "gamma", "hotel",
2899 + "india", "juleiet", "keelo", "leema", "mike", "november", "oscar",
2900 + "papa",
2901 + "quebec", "romeo", "seeara", "tango", "uniform", "victer", "wiskey",
2902 + "x ray", "yankee", "zooloo"
2903 +};
2904 +
2905 +// array of 256 char pointers (one for each ASCII character description )
2906 +// initialized to default_chars and user selectable via /proc/speakup/characters
2907 +char *characters[256];
2908 +
2909 +char *default_chars[256] = {
2910 + "null", "^a", "^b", "^c", "^d", "^e", "^f", "^g",
2911 + "^h", "^i", "^j", "^k", "^l", "^m", "^n", "^o",
2912 + "^p", "^q", "^r", "^s", "^t", "^u", "^v", "^w",
2913 + "^x", "^y", "^z", NULL, NULL, NULL, NULL, NULL,
2914 + "space", "bang!", "quote", "number", "dollar", "percent", "and",
2915 + "tick",
2916 + "left paren", "right paren", "star", "plus", "comma", "dash", "dot",
2917 + "slash",
2918 + "zero", "one", "two", "three", "four", "five", "six", "seven",
2919 + "eight", "nine",
2920 + "colon", "semmy", "less", "equals", "greater", "question", "at",
2921 + "eigh", "b", "c", "d", "e", "f", "g",
2922 + "h", "i", "j", "k", "l", "m", "n", "o",
2923 + "p", "q", "r", "s", "t", "u", "v", "w", "x",
2924 + "y", "zehd", "left bracket", "backslash", "right bracket", "caret",
2925 + "line",
2926 + "accent", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2927 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2928 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2929 + NULL, NULL, NULL, "left brace", "bar", "right brace", "tihlduh",
2930 + "delta", "see cedilla", "u oomlout", "e acute", /* 128 */
2931 + "eigh circumflex", "eigh oomlout", "eigh grave", "eigh ring", /* 132 */
2932 + "see cedilla", "e circumflex", "e oomlout", "e grave", /* 136 */
2933 + "i oomlout", "i circumflex", "i grave", "eigh oomlout", /* 140 */
2934 + "eigh ring", "e acute", "eigh e dipthong", "eigh e dipthong", /* 144 */
2935 + "o circumflex", "o oomlout", "o grave", "u circumflex", /* 148 */
2936 + "u grave", "y oomlout", "o oomlout", "u oomlout", /* 152 */
2937 + "cents", "pounds", "yen", "peseta", /* 156 */
2938 + "florin", "eigh acute", "i acute", "o acute", /* 160 */
2939 + "u acute", "n tilde", "n tilde", "feminine ordinal", /* 164 */
2940 + "masculin ordinal", "inverted question", "reversed not", "not", /* 168 */
2941 + "half", "quarter", "inverted bang", "much less than", /* 172 */
2942 + "much greater than", "dark shading", "medium shading", /* 176 */
2943 + "light shading", "verticle line", "left tee", /* 179 */
2944 + "double left tee", "left double tee", "double top right", /* 182 */
2945 + "top double right", "double left double tee", /* 185 */
2946 + "double vertical line", "double top double right", /* 187 */
2947 + "double bottom double right", "double bottom right", /* 189 */
2948 + "bottom double right", "top right", "left bottom", /* 191 */
2949 + "up tee", "tee down", "tee right", "horizontal line", /* 194 */
2950 + "cross bars", "tee double right", "double tee right", /* 198 */
2951 + "double left double bottom", "double left double top", /* 201 */
2952 + "double up double tee", "double tee double down", /* 203 */
2953 + "double tee double right", "double horizontal line", /* 205 */
2954 + "double cross bars", "up double tee", "double up tee", /* 207 */
2955 + "double tee down", "tee double down", /* 210 */
2956 + "double left bottom", "left double bottom", /* 212 */
2957 + "double left top", "left double top", /* 214 */
2958 + "double vertical cross", "double horizontal cross", /* 216 */
2959 + "bottom right", "left top", "solid square", /* 218 */
2960 + "solid lower half", "solid left half", "solid right half", /* 221 */
2961 + "solid upper half", "alpha", "beta", "gamma", /* 224 */
2962 + "pie", "sigma", "sigma", "mu", /* 228 */
2963 + "tou", "phigh", "thayta", "ohmega", /* 232 */
2964 + "delta", "infinity", "phigh", "epsilaun", /* 236 */
2965 +"intersection", "identical to", "plus or minus", "equal grater than", /* 240 */
2966 + "less than equal", "upper integral", "lower integral", /* 244 */
2967 + "divided by", "almost equal", "degrees", /* 247 */
2968 + "centre dot", "bullet", "square root", /* 250 */
2969 + "power", "squared", "black square", "white space" /* 252 */
2970 +};
2971 +
2972 +u_short spk_chartab[256] = {
2973 + B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 0-7 */
2974 + B_CTL, B_CTL, A_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 8-15 */
2975 + B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /*16-23 */
2976 + B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 24-31 */
2977 +WDLM, A_PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* !"#$%&' */
2978 +PUNC, PUNC, PUNC, PUNC, A_PUNC, A_PUNC, A_PUNC, PUNC, /* ( )*+, -./ */
2979 +NUM, NUM, NUM, NUM, NUM, NUM, NUM, NUM, /* 01234567 */
2980 +NUM, NUM, A_PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* 89:;<=>? */
2981 +PUNC, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* @ABCDEFG */
2982 +A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* HIJKLMNO */
2983 +A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* PQRSTUVW */
2984 +A_CAP, A_CAP, A_CAP, PUNC, PUNC, PUNC, PUNC, PUNC, /* XYZ[\]^_ */
2985 +PUNC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* `abcdefg */
2986 +ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* hijklmno */
2987 +ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* pqrstuvw */
2988 +ALPHA, ALPHA, ALPHA, PUNC, PUNC, PUNC, PUNC, 0, /* xyz{|}~ */
2989 +B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 128-135 */
2990 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, /* 136-143 */
2991 +B_CAPSYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 144-151 */
2992 +B_SYM, B_SYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 152-159 */
2993 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, B_SYM, /* 160-167 */
2994 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 168-175 */
2995 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 176-183 */
2996 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 184-191 */
2997 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 192-199 */
2998 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 200-207 */
2999 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 208-215 */
3000 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 216-223 */
3001 +B_SYM, B_SYM, B_SYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, /* 224-231 */
3002 +B_SYM, B_CAPSYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 232-239 */
3003 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 240-247 */
3004 +B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM /* 248-255 */
3005 +};
3006 +
3007 +int spk_keydown = 0;
3008 +static u_char spk_lastkey = 0, spk_close_press = 0, keymap_flags = 0;
3009 +static u_char last_keycode = 0, this_speakup_key = 0;
3010 +static u_long last_spk_jiffy = 0;
3011 +
3012 +spk_t *speakup_console[MAX_NR_CONSOLES];
3013 +
3014 +int spk_setup (char *str )
3015 +{
3016 + int ints[4];
3017 + str = get_options (str, ARRAY_SIZE (ints ), ints );
3018 + if (ints[0] > 0 && ints[1] >= 0 )
3019 + synth_port_forced = ints[1];
3020 + return 1;
3021 +}
3022 +
3023 +int spk_ser_setup (char *str )
3024 +{
3025 + int lookup[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
3026 + int ints[4];
3027 + str = get_options (str, ARRAY_SIZE (ints ), ints );
3028 + if (ints[0] > 0 && ints[1] >= 0 )
3029 + synth_port_forced = lookup[ints[1]];
3030 + return 1;
3031 +}
3032 +
3033 +int spk_synth_setup (char *str )
3034 +{
3035 + size_t len = MIN (strlen (str ), 9 );
3036 + memcpy (synth_name, str, len );
3037 + synth_name[len] = '\0';
3038 + return 1;
3039 +}
3040 +
3041 +__setup ("speakup_port=", spk_setup );
3042 +__setup ("speakup_ser=", spk_ser_setup );
3043 +__setup ("speakup_synth=", spk_synth_setup );
3044 +
3045 +char *
3046 +strlwr (char *s )
3047 +{
3048 + char *p;
3049 + for (p = s; *p; p++ ) {
3050 + if (*p >= CAP_A && *p <= CAP_Z ) *p |= 32;
3051 + }
3052 + return s;
3053 +}
3054 +
3055 +static void
3056 +bleep (u_short val )
3057 +{
3058 + static short vals[] = { 350, 370, 392, 414, 440, 466, 491, 523,
3059 +554, 587, 619, 659 };
3060 + short freq;
3061 + int time = bleep_time;
3062 + freq = vals[val%12];
3063 + if (val > 11 )
3064 + freq *= (1<<(val/12 ) );
3065 + kd_mksound (freq, time );
3066 +}
3067 +
3068 +void
3069 +speakup_shut_up (struct vc_data *vc )
3070 +{
3071 + if (spk_killed ) return;
3072 + spk_shut_up |= 0x01;
3073 + spk_parked &= 0xfe;
3074 + speakup_date (vc );
3075 + if (synth == NULL ) return;
3076 + do_flush( );
3077 +}
3078 +
3079 +void
3080 +speech_kill (struct vc_data *vc )
3081 +{
3082 + char val = synth->is_alive ( );
3083 + if (val == 0 ) return;
3084 + /* re-enables synth, if disabled */
3085 + if (val == 2 || spk_killed ) { /* dead */
3086 + spk_shut_up &= ~0x40;
3087 + synth_write_msg ("Eyem a Lighve!" );
3088 + } else {
3089 + synth_write_msg ("You killed speak up!" );
3090 + spk_shut_up |= 0x40;
3091 + }
3092 +}
3093 +
3094 +static void
3095 +speakup_off (struct vc_data *vc )
3096 +{
3097 + if (spk_shut_up & 0x80 ) {
3098 + spk_shut_up &= 0x7f;
3099 + synth_write_msg ("hey. That's better!" );
3100 + } else {
3101 + spk_shut_up |= 0x80;
3102 + synth_write_msg ("You turned me off!" );
3103 + }
3104 + speakup_date (vc );
3105 +}
3106 +
3107 +static void
3108 +speakup_parked (struct vc_data *vc )
3109 +{
3110 + if (spk_parked & 0x80 ) {
3111 + spk_parked = 0;
3112 + synth_write_msg ("unparked!" );
3113 + } else {
3114 + spk_parked |= 0x80;
3115 + synth_write_msg ("parked!" );
3116 + }
3117 +}
3118 +
3119 +/* ------ cut and paste ----- */
3120 +/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */
3121 +#undef isspace
3122 +#define isspace(c) ((c) == ' ')
3123 +/* Variables for selection control. */
3124 +struct vc_data *spk_sel_cons; /* defined in selection.c must not be disallocated */
3125 +static volatile int sel_start = -1; /* cleared by clear_selection */
3126 +static int sel_end;
3127 +static int sel_buffer_lth;
3128 +static char *sel_buffer;
3129 +
3130 +static unsigned char
3131 +sel_pos(int n)
3132 +{
3133 + return inverse_translate(spk_sel_cons, screen_glyph(spk_sel_cons, n));
3134 +}
3135 +
3136 +static void
3137 +speakup_clear_selection(void)
3138 +{
3139 + sel_start = -1;
3140 +}
3141 +
3142 +/* does screen address p correspond to character at LH/RH edge of screen? */
3143 +static inline int atedge(const int p, int size_row)
3144 +{
3145 + return (!(p % size_row) || !((p + 2) % size_row));
3146 +}
3147 +
3148 +/* constrain v such that v <= u */
3149 +static inline unsigned short limit(const unsigned short v, const unsigned short u)
3150 +{
3151 + return (v > u) ? u : v;
3152 +}
3153 +
3154 +unsigned short xs, ys, xe, ye; /* our region points */
3155 +
3156 +static int
3157 +speakup_set_selection( struct tty_struct *tty)
3158 +{
3159 + int new_sel_start, new_sel_end;
3160 + char *bp, *obp;
3161 + int i, ps, pe;
3162 + struct vc_data *vc = vc_cons[fg_console].d;
3163 +
3164 + xs = limit(xs, vc->vc_cols - 1);
3165 + ys = limit(ys, vc->vc_rows - 1);
3166 + xe = limit(xe, vc->vc_cols - 1);
3167 + ye = limit(ye, vc->vc_rows - 1);
3168 + ps = ys * vc->vc_size_row + (xs << 1);
3169 + pe = ye * vc->vc_size_row + (xe << 1);
3170 +
3171 + if (ps > pe) { /* make sel_start <= sel_end */
3172 + int tmp = ps;
3173 + ps = pe;
3174 + pe = tmp;
3175 + }
3176 +
3177 + if (spk_sel_cons != vc_cons[fg_console].d) {
3178 + speakup_clear_selection();
3179 + spk_sel_cons = vc_cons[fg_console].d;
3180 + printk(KERN_WARNING "Selection: mark console not the same as cut\n");
3181 + return -EINVAL;
3182 + }
3183 +
3184 + new_sel_start = ps;
3185 + new_sel_end = pe;
3186 +
3187 + /* select to end of line if on trailing space */
3188 + if (new_sel_end > new_sel_start &&
3189 + !atedge(new_sel_end, vc->vc_size_row) &&
3190 + isspace(sel_pos(new_sel_end))) {
3191 + for (pe = new_sel_end + 2; ; pe += 2)
3192 + if (!isspace(sel_pos(pe)) ||
3193 + atedge(pe, vc->vc_size_row))
3194 + break;
3195 + if (isspace(sel_pos(pe)))
3196 + new_sel_end = pe;
3197 + }
3198 + if ((new_sel_start == sel_start)
3199 + && (new_sel_end == sel_end)) /* no action required */
3200 + return 0;
3201 +
3202 + sel_start = new_sel_start;
3203 + sel_end = new_sel_end;
3204 + /* Allocate a new buffer before freeing the old one ... */
3205 + bp = kmalloc((sel_end-sel_start)/2+1, GFP_ATOMIC);
3206 + if (!bp) {
3207 + printk(KERN_WARNING "selection: kmalloc() failed\n");
3208 + speakup_clear_selection();
3209 + return -ENOMEM;
3210 + }
3211 + if (sel_buffer)
3212 + kfree(sel_buffer);
3213 + sel_buffer = bp;
3214 +
3215 + obp = bp;
3216 + for (i = sel_start; i <= sel_end; i += 2) {
3217 + *bp = sel_pos(i);
3218 + if (!isspace(*bp++))
3219 + obp = bp;
3220 + if (! ((i + 2) % vc->vc_size_row)) {
3221 + /* strip trailing blanks from line and add newline,
3222 + unless non-space at end of line. */
3223 + if (obp != bp) {
3224 + bp = obp;
3225 + *bp++ = '\r';
3226 + }
3227 + obp = bp;
3228 + }
3229 + }
3230 + sel_buffer_lth = bp - sel_buffer;
3231 + return 0;
3232 +}
3233 +
3234 +static int
3235 +speakup_paste_selection(struct tty_struct *tty)
3236 +{
3237 + struct vc_data *vc = (struct vc_data *) tty->driver_data;
3238 + int pasted = 0, count;
3239 + DECLARE_WAITQUEUE(wait, current);
3240 + add_wait_queue(&vc->paste_wait, &wait);
3241 + while (sel_buffer && sel_buffer_lth > pasted) {
3242 + set_current_state(TASK_INTERRUPTIBLE);
3243 + if (test_bit(TTY_THROTTLED, &tty->flags)) {
3244 + schedule();
3245 + continue;
3246 + }
3247 + count = sel_buffer_lth - pasted;
3248 + count = MIN(count, tty->ldisc.receive_room(tty));
3249 + tty->ldisc.receive_buf(tty, sel_buffer + pasted, 0, count);
3250 + pasted += count;
3251 + }
3252 + remove_wait_queue(&vc->paste_wait, &wait);
3253 + current->state = TASK_RUNNING;
3254 + return 0;
3255 +}
3256 +
3257 +static void
3258 +speakup_cut (struct vc_data *vc )
3259 +{
3260 + static const char err_buf[] = "set selection failed";
3261 + int ret;
3262 +
3263 + if (!mark_cut_flag ) {
3264 + mark_cut_flag = 1;
3265 + xs = spk_x;
3266 + ys = spk_y;
3267 + spk_sel_cons = vc;
3268 + synth_write_msg ("mark" );
3269 + return;
3270 + }
3271 + xe = (u_short ) spk_x;
3272 + ye = (u_short )spk_y;
3273 + mark_cut_flag = 0;
3274 + synth_write_msg ("cut" );
3275 +
3276 + speakup_clear_selection( );
3277 + ret = speakup_set_selection ( tty );
3278 +
3279 + switch (ret ) {
3280 + case 0:
3281 + break; /* no error */
3282 + case -EFAULT :
3283 + pr_warn( "%sEFAULT\n", err_buf );
3284 + break;
3285 + case -EINVAL :
3286 + pr_warn( "%sEINVAL\n", err_buf );
3287 + break;
3288 + case -ENOMEM :
3289 + pr_warn( "%sENOMEM\n", err_buf );
3290 + break;
3291 + }
3292 +}
3293 +
3294 +static void
3295 +speakup_paste (struct vc_data *vc )
3296 +{
3297 + if (mark_cut_flag ) {
3298 + mark_cut_flag = 0;
3299 + synth_write_msg ("mark, cleared" );
3300 + } else {
3301 + synth_write_msg ("paste" );
3302 + speakup_paste_selection (tty );
3303 + }
3304 +}
3305 +
3306 +static void
3307 +say_attributes (struct vc_data *vc )
3308 +{
3309 + int fg= spk_attr&0x0f, bg = spk_attr>>4;
3310 + if (fg > 8 ) {
3311 + synth_write_string("bright " );
3312 + fg -= 8;
3313 + }
3314 + synth_write_string(colors[fg] );
3315 + if (bg > 7 ) {
3316 + synth_write_string(" on blinking " );
3317 + bg -= 8;
3318 + } else
3319 + synth_write_string(" on " );
3320 + synth_write_msg(colors[bg] );
3321 +}
3322 +
3323 +static char *blank_msg = "blank";
3324 +static char *edges[] = { "top, ", "bottom, ", "left, ", "right, ", "" };
3325 +enum { edge_top = 1, edge_bottom, edge_left, edge_right, edge_quiet };
3326 +
3327 +static void
3328 +announce_edge (struct vc_data *vc, int msg_id )
3329 +{
3330 + if (bleeps&1 )
3331 + bleep (spk_y );
3332 + if (bleeps&2 )
3333 + synth_write_msg (edges[msg_id-1] );
3334 +}
3335 +
3336 +static void
3337 +speak_char( u_char ch )
3338 +{
3339 + char *cp = characters[ ch];
3340 + synth_buffer_add( SPACE );
3341 + if (IS_CHAR(ch, B_CAP ) ) {
3342 + pitch_shift++;
3343 + synth_write_string(str_caps_start );
3344 + synth_write_string(cp );
3345 + synth_write_string(str_caps_stop );
3346 + } else {
3347 + if (*cp == '^' ) {
3348 + synth_write_string(str_ctl );
3349 + cp++;
3350 + }
3351 + synth_write_string(cp );
3352 + }
3353 + synth_buffer_add( SPACE );
3354 +}
3355 +
3356 +static void
3357 +say_char (struct vc_data *vc )
3358 +{
3359 + u_short ch;
3360 + spk_old_attr = spk_attr;
3361 + ch = scr_readw ((u_short * ) spk_pos );
3362 + spk_attr = ((ch & 0xff00 ) >> 8 );
3363 + if (spk_attr != spk_old_attr ) {
3364 + if ( attrib_bleep&1 ) bleep (spk_y );
3365 + if ( attrib_bleep&2 ) say_attributes( vc );
3366 + }
3367 + speak_char( ch&0xff );
3368 +}
3369 +
3370 +static void
3371 +say_phonetic_char (struct vc_data *vc )
3372 +{
3373 + u_short ch;
3374 + spk_old_attr = spk_attr;
3375 + ch = scr_readw ((u_short * ) spk_pos );
3376 + spk_attr = ((ch & 0xff00 ) >> 8 );
3377 + if ( IS_CHAR(ch, B_ALPHA ) ) {
3378 + ch &= 0x1f;
3379 + synth_write_msg(phonetic[--ch] );
3380 + } else {
3381 + if ( IS_CHAR(ch, B_NUM ) )
3382 + synth_write_string( "number " );
3383 + speak_char( ch );
3384 + }
3385 +}
3386 +
3387 +static void
3388 +say_prev_char (struct vc_data *vc )
3389 +{
3390 + spk_parked |= 0x01;
3391 + if (spk_x == 0 ) {
3392 + announce_edge(vc, edge_left );
3393 + return;
3394 + }
3395 + spk_x--;
3396 + spk_pos -= 2;
3397 + say_char (vc );
3398 +}
3399 +
3400 +static void
3401 +say_next_char (struct vc_data *vc )
3402 +{
3403 + spk_parked |= 0x01;
3404 + if (spk_x == vc->vc_cols - 1 ) {
3405 + announce_edge(vc, edge_right );
3406 + return;
3407 + }
3408 + spk_x++;
3409 + spk_pos += 2;
3410 + say_char (vc );
3411 +}
3412 +
3413 +/* get_word - will first check to see if the character under the
3414 + reading cursor is a space and if say_word_ctl is true it will
3415 + return the word space. If say_word_ctl is not set it will check to
3416 + see if there is a word starting on the next position to the right
3417 + and return that word if it exists. If it does not exist it will
3418 + move left to the beginning of any previous word on the line or the
3419 + beginning off the line whichever comes first.. */
3420 +
3421 +static u_long
3422 +get_word (struct vc_data *vc )
3423 +{
3424 + u_long cnt = 0, tmpx = spk_x, tmp_pos = spk_pos;
3425 + char ch;
3426 + u_short attr_ch;
3427 + spk_old_attr = spk_attr;
3428 + ch = (char ) scr_readw ((u_short * ) tmp_pos );
3429 +
3430 +/* decided to take out the sayword if on a space (mis-information */
3431 + if ( say_word_ctl && ch == SPACE ) {
3432 + *buf = '\0';
3433 + synth_write_msg( "space" );
3434 + return 0;
3435 + } else if ((tmpx < vc->vc_cols-2 )
3436 + && (ch == SPACE || IS_WDLM(ch ))
3437 + && ((char) scr_readw ((u_short * ) tmp_pos+1 ) > SPACE)) {
3438 + tmp_pos += 2;
3439 + tmpx++;
3440 + } else
3441 + while (tmpx > 0 ) {
3442 + if (((ch = (char ) scr_readw ((u_short * ) tmp_pos-1 )) == SPACE
3443 + || IS_WDLM(ch ))
3444 + && ((char) scr_readw ((u_short * ) tmp_pos ) > SPACE))
3445 + break;
3446 + tmp_pos -= 2;
3447 + tmpx--;
3448 + }
3449 + attr_ch = scr_readw ((u_short * ) tmp_pos );
3450 + spk_attr = attr_ch >> 8;
3451 + buf[cnt++] = attr_ch&0xff;
3452 + while (tmpx < vc->vc_cols-1 ) {
3453 + tmp_pos += 2;
3454 + tmpx++;
3455 + ch = (char ) scr_readw ((u_short * ) tmp_pos );
3456 + if ((ch == SPACE )
3457 + || (IS_WDLM(buf[cnt-1] ) && ( ch > SPACE )))
3458 + break;
3459 + buf[cnt++] = ch;
3460 + }
3461 + buf[cnt] = '\0';
3462 + return cnt;
3463 +}
3464 +
3465 +static void
3466 +say_word (struct vc_data *vc )
3467 +{
3468 + u_long cnt = get_word(vc );
3469 + u_short saved_punc_mask = punc_mask;
3470 + if ( cnt == 0 ) return;
3471 + punc_mask = PUNC;
3472 + buf[cnt++] = SPACE;
3473 + spkup_write (buf, cnt );
3474 + punc_mask = saved_punc_mask;
3475 +}
3476 +
3477 +static void
3478 +say_prev_word (struct vc_data *vc )
3479 +{
3480 + char ch;
3481 + u_short edge_said = 0, last_state = 0, state = 0;
3482 + spk_parked |= 0x01;
3483 + if (spk_x == 0 ) {
3484 + if ( spk_y == 0 ) {
3485 + announce_edge(vc, edge_top );
3486 + return;
3487 + }
3488 + spk_y--;
3489 + spk_x = vc->vc_cols;
3490 + edge_said = edge_quiet;
3491 + }
3492 + while ( 1 ) {
3493 + if (spk_x == 0 ) {
3494 + if (spk_y == 0 ) {
3495 + edge_said = edge_top;
3496 + break;
3497 + }
3498 + if ( edge_said != edge_quiet ) edge_said = edge_left;
3499 + if ( state > 0 ) break;
3500 + spk_y--;
3501 + spk_x = vc->vc_cols-1;
3502 + } else spk_x--;
3503 + spk_pos -= 2;
3504 + ch = (char ) scr_readw ((u_short * ) spk_pos );
3505 + if ( ch == SPACE ) state = 0;
3506 + else if (IS_WDLM(ch ) ) state = 1;
3507 + else state = 2;
3508 + if (state < last_state ) {
3509 + spk_pos += 2;
3510 + spk_x++;
3511 + break;
3512 + }
3513 + last_state = state;
3514 + }
3515 + if ( spk_x == 0 && edge_said == edge_quiet )
3516 + edge_said = edge_left;
3517 + if ( edge_said > 0 && edge_said < edge_quiet )
3518 + announce_edge( vc, edge_said );
3519 + say_word (vc );
3520 +}
3521 +
3522 +static void
3523 +say_next_word (struct vc_data *vc )
3524 +{
3525 + char ch;
3526 + u_short edge_said = 0, last_state = 2, state = 0;
3527 + spk_parked |= 0x01;
3528 + if ( spk_x == vc->vc_cols - 1 && spk_y == vc->vc_rows-1 ) {
3529 + announce_edge(vc, edge_bottom );
3530 + return;
3531 + }
3532 + while ( 1 ) {
3533 + ch = (char ) scr_readw ((u_short * ) spk_pos );
3534 + if ( ch == SPACE ) state = 0;
3535 + else if (IS_WDLM(ch ) ) state = 1;
3536 + else state = 2;
3537 + if ( state > last_state ) break;
3538 + if (spk_x >= vc->vc_cols-1 ) {
3539 + if (spk_y == vc->vc_rows-1 ) {
3540 + edge_said = edge_bottom;
3541 + break;
3542 + }
3543 + state = 0;
3544 + spk_y++;
3545 + spk_x = 0;
3546 + edge_said = edge_right;
3547 + } else spk_x++;
3548 + spk_pos += 2;
3549 + last_state = state;
3550 + }
3551 + if ( edge_said > 0 )
3552 + announce_edge( vc, edge_said );
3553 + say_word (vc );
3554 +}
3555 +
3556 +static void
3557 +spell_word (struct vc_data *vc )
3558 +{
3559 + static char *delay_str[] = { " ", ", ", ". ", ". . ", ". . . " };
3560 + char *cp = buf, *str_cap= str_caps_stop;
3561 + char *cp1, *last_cap = str_caps_stop;
3562 + u_char ch;
3563 + if ( !get_word(vc ) ) return;
3564 + while ((ch = (u_char )*cp ) ) {
3565 + if ( cp != buf )
3566 + synth_write_string (delay_str[spell_delay] );
3567 + if (IS_CHAR(ch, B_CAP ) ) {
3568 + str_cap = str_caps_start;
3569 + if ( *str_caps_stop ) pitch_shift++;
3570 + else last_cap = str_caps_stop; /* synth has no pitch */
3571 + } else str_cap = str_caps_stop;
3572 + if ( str_cap !=last_cap ) {
3573 + synth_write_string( str_cap );
3574 + last_cap = str_cap;
3575 + }
3576 + if ( this_speakup_key == SPELL_PHONETIC && ( IS_CHAR( ch, B_ALPHA ) ) ) {
3577 + ch &= 31;
3578 + cp1 = phonetic[--ch];
3579 + } else {
3580 + cp1 = characters[ch];
3581 + if (*cp1 == '^' ) {
3582 + synth_write_string(str_ctl );
3583 + cp1++;
3584 + }
3585 + }
3586 + synth_write_string(cp1 );
3587 + cp++;
3588 + }
3589 + if ( str_cap != str_caps_stop )
3590 + synth_write_string( str_caps_stop );
3591 +}
3592 +
3593 +static int
3594 +get_line (struct vc_data *vc )
3595 +{
3596 + u_long tmp = spk_pos - (spk_x * 2 );
3597 + int i = 0;
3598 + spk_old_attr = spk_attr;
3599 + spk_attr = (u_char ) (scr_readw ((u_short * ) spk_pos ) >> 8 );
3600 + for (i = 0; i < vc->vc_cols; i++ ) {
3601 + buf[i] = (u_char ) scr_readw ((u_short * ) tmp );
3602 + tmp += 2;
3603 + }
3604 + for (--i; i >= 0; i-- )
3605 + if (buf[i] != SPACE ) break;
3606 + return ++i;
3607 +}
3608 +
3609 +static void
3610 +say_line (struct vc_data *vc )
3611 +{
3612 + int i = get_line( vc );
3613 + char *cp;
3614 + char num_buf[8];
3615 + u_short saved_punc_mask = punc_mask;
3616 + if (i == 0 ) {
3617 + synth_write_msg (blank_msg );
3618 + return;
3619 + }
3620 + buf[i++] = '\n';
3621 + if ( this_speakup_key == SAY_LINE_INDENT ) {
3622 + for ( cp = buf; *cp == SPACE; cp++ );
3623 + sprintf( num_buf, "%d, ", ( cp-buf )+1 );
3624 + synth_write_string( num_buf );
3625 + }
3626 + punc_mask = punc_masks[reading_punc];
3627 + spkup_write (buf, i );
3628 + punc_mask = saved_punc_mask;
3629 +}
3630 +
3631 +static void
3632 +say_prev_line (struct vc_data *vc )
3633 +{
3634 + spk_parked |= 0x01;
3635 + if (spk_y == 0 ) {
3636 + announce_edge (vc, edge_top );
3637 + return;
3638 + }
3639 + spk_y--;
3640 + spk_pos -= vc->vc_size_row;
3641 + say_line (vc );
3642 +}
3643 +
3644 +static void
3645 +say_next_line (struct vc_data *vc )
3646 +{
3647 + spk_parked |= 0x01;
3648 + if (spk_y == vc->vc_rows - 1 ) {
3649 + announce_edge (vc, edge_bottom );
3650 + return;
3651 + }
3652 + spk_y++;
3653 + spk_pos += vc->vc_size_row;
3654 + say_line (vc );
3655 +}
3656 +
3657 +static int
3658 +say_from_to (struct vc_data *vc, u_long from, u_long to, int read_punc )
3659 +{
3660 + int i = 0;
3661 + u_short saved_punc_mask = punc_mask;
3662 + spk_old_attr = spk_attr;
3663 + spk_attr = (u_char ) (scr_readw ((u_short * ) from ) >> 8 );
3664 + while (from < to ) {
3665 + buf[i++] = (char ) scr_readw ((u_short * ) from );
3666 + from += 2;
3667 + if ( i >= vc->vc_size_row ) break;
3668 + }
3669 + for (--i; i >= 0; i-- )
3670 + if (buf[i] != SPACE ) break;
3671 + buf[++i] = SPACE;
3672 + buf[++i] = '\0';
3673 + if ( i < 1 ) return i;
3674 + if ( read_punc ) punc_mask = punc_info[reading_punc].mask;
3675 + spkup_write (buf, i );
3676 + if ( read_punc ) punc_mask = saved_punc_mask;
3677 + return i-1;
3678 +}
3679 +
3680 +static void
3681 +say_line_from_to (struct vc_data *vc, u_long from, u_long to, int read_punc )
3682 +{
3683 + u_long start = vc->vc_origin+(spk_y*vc->vc_size_row );
3684 + u_long end = start+( to * 2 );
3685 + start += from*2;
3686 + if ( say_from_to( vc, start, end, read_punc ) <= 0 )
3687 + synth_write_msg (blank_msg );
3688 +}
3689 +
3690 +static void
3691 +say_screen_from_to (struct vc_data *vc, u_long from, u_long to )
3692 +{
3693 + u_long start = vc->vc_origin, end;
3694 + if ( from > 0 ) start += from * vc->vc_size_row;
3695 + if ( to > vc->vc_rows ) to = vc->vc_rows;
3696 + end = vc->vc_origin + ( to * vc->vc_size_row);
3697 + for ( from = start; from < end; from = to ) {
3698 + to = from + vc->vc_size_row;
3699 + say_from_to( vc, from, to, 1 );
3700 + }
3701 +}
3702 +
3703 +static void
3704 +say_screen (struct vc_data *vc )
3705 +{
3706 + say_screen_from_to( vc, 0, vc->vc_rows );
3707 +}
3708 +
3709 +static void
3710 +speakup_win_say (struct vc_data *vc )
3711 +{
3712 + u_long start, end, from, to;
3713 + if ( win_start < 2 ) {
3714 + synth_write_msg( "no window" );
3715 + return;
3716 + }
3717 + start = vc->vc_origin + ( win_top * vc->vc_size_row );
3718 + end = vc->vc_origin + ( win_bottom * vc->vc_size_row );
3719 + while ( start <= end ) {
3720 + from = start + ( win_left * 2 );
3721 + to = start + ( win_right * 2 );
3722 + say_from_to( vc, from, to, 1 );
3723 + start += vc->vc_size_row;
3724 + }
3725 +}
3726 +
3727 +static void
3728 +top_edge (struct vc_data *vc )
3729 +{
3730 + spk_parked |= 0x01;
3731 + spk_pos = vc->vc_origin + 2 * spk_x;
3732 + spk_y = 0;
3733 + say_line (vc );
3734 +}
3735 +
3736 +static void
3737 +bottom_edge (struct vc_data *vc )
3738 +{
3739 + spk_parked |= 0x01;
3740 + spk_pos += (vc->vc_rows - spk_y - 1 ) * vc->vc_size_row;
3741 + spk_y = vc->vc_rows - 1;
3742 + say_line (vc );
3743 +}
3744 +
3745 +static void
3746 +left_edge (struct vc_data *vc )
3747 +{
3748 + spk_parked |= 0x01;
3749 + spk_pos -= spk_x * 2;
3750 + spk_x = 0;
3751 + say_char (vc );
3752 +}
3753 +
3754 +static void
3755 +right_edge (struct vc_data *vc )
3756 +{
3757 + spk_parked |= 0x01;
3758 + spk_pos += (vc->vc_cols - spk_x - 1 ) * 2;
3759 + spk_x = vc->vc_cols - 1;
3760 + say_char (vc );
3761 +}
3762 +
3763 +static void
3764 +say_first_char (struct vc_data *vc )
3765 +{
3766 + int i, len = get_line( vc );
3767 + u_char ch;
3768 + spk_parked |= 0x01;
3769 + if ( len == 0 ) {
3770 + synth_write_msg( blank_msg );
3771 + return;
3772 + }
3773 + for ( i = 0; i < len; i++ ) if ( buf[i] != SPACE ) break;
3774 + ch = buf[i];
3775 + spk_pos -= ( spk_x-i ) * 2;
3776 + spk_x = i;
3777 + sprintf (buf, "%d, ", ++i );
3778 + synth_write_string (buf );
3779 + speak_char( ch );
3780 +}
3781 +
3782 +static void
3783 +say_last_char (struct vc_data *vc )
3784 +{
3785 + int len = get_line( vc );
3786 + u_char ch;
3787 + spk_parked |= 0x01;
3788 + if ( len == 0 ) {
3789 + synth_write_msg( blank_msg );
3790 + return;
3791 + }
3792 + ch = buf[--len];
3793 + spk_pos -= ( spk_x-len ) * 2;
3794 + spk_x = len;
3795 + sprintf (buf, "%d, ", ++len );
3796 + synth_write_string (buf );
3797 + speak_char( ch );
3798 +}
3799 +
3800 +static void
3801 +say_position (struct vc_data *vc )
3802 +{
3803 + sprintf (buf, "line %ld, col %ld, t t y %d\n", spk_y + 1,
3804 + spk_x + 1, vc->vc_num + 1 );
3805 + synth_write_string (buf );
3806 +}
3807 +
3808 +// Added by brianb
3809 +static void
3810 +say_char_num (struct vc_data *vc )
3811 +{
3812 + u_short ch = scr_readw ((u_short * ) spk_pos );
3813 + ch &= 0x0ff;
3814 + sprintf (buf, "hex %02x, decimal %d", ch, ch );
3815 + synth_write_msg (buf );
3816 +}
3817 +
3818 +/* these are stub functions to keep keyboard.c happy. */
3819 +
3820 +static void
3821 +say_from_top (struct vc_data *vc )
3822 +{
3823 + say_screen_from_to (vc, 0, spk_y );
3824 +}
3825 +
3826 +static void
3827 +say_to_bottom (struct vc_data *vc )
3828 +{
3829 + say_screen_from_to (vc, spk_y, vc->vc_rows );
3830 +}
3831 +
3832 +static void
3833 +say_from_left (struct vc_data *vc )
3834 +{
3835 + say_line_from_to (vc, 0, spk_x, 1 );
3836 +}
3837 +
3838 +static void
3839 +say_to_right (struct vc_data *vc )
3840 +{
3841 + say_line_from_to (vc, spk_x, vc->vc_cols, 1 );
3842 +}
3843 +
3844 +/* end of stub functions. */
3845 +
3846 +static void
3847 +spkup_write (const char *in_buf, int count )
3848 +{
3849 + static int rep_count = 0;
3850 + static u_char ch = '\0', old_ch = '\0';
3851 + static u_short char_type = 0, last_type = 0;
3852 + static u_char *exn_ptr = NULL;
3853 + int in_count = count;
3854 + char rpt_buf[32];
3855 + spk_keydown = 0;
3856 + while ( count-- ) {
3857 + ch = (u_char )*in_buf++;
3858 + char_type = spk_chartab[ch];
3859 + if (ch == old_ch && !(char_type&B_NUM ) ) {
3860 + if (++rep_count > 2 ) continue;
3861 + } else {
3862 + if ( (last_type&CH_RPT) && rep_count > 2 ) {
3863 + sprintf (rpt_buf, " times %d . ", ++rep_count );
3864 + synth_write_string (rpt_buf );
3865 + }
3866 + rep_count = 0;
3867 + }
3868 + if ( !( char_type&B_NUM ) )
3869 + exn_ptr = NULL;
3870 + if (ch == spk_lastkey ) {
3871 + rep_count = 0;
3872 + if ( key_echo == 1 && ch >= MINECHOCHAR )
3873 + speak_char( ch );
3874 + } else if ( ( char_type&B_ALPHA ) ) {
3875 + if ( (synth_flags&SF_DEC) && (last_type&PUNC) )
3876 + synth_buffer_add ( SPACE );
3877 + synth_write( &ch, 1 );
3878 + } else if ( ( char_type&B_NUM ) ) {
3879 + rep_count = 0;
3880 + if ( (last_type&B_EXNUM) && synth_buff_in == exn_ptr+1 ) {
3881 + synth_buff_in--;
3882 + synth_buffer_add( old_ch );
3883 + exn_ptr = NULL;
3884 + }
3885 + synth_write( &ch, 1 );
3886 + } else if ( (char_type&punc_mask) ) {
3887 + speak_char( ch );
3888 + char_type &= ~PUNC; /* for dec nospell processing */
3889 + } else if ( ( char_type&SYNTH_OK ) ) {
3890 +/* these are usually puncts like . and , which synth needs for expression.
3891 + * suppress multiple to get rid of long pausesand clear repeat count so if
3892 + *someone has repeats on you don't get nothing repeated count */
3893 + if ( ch != old_ch )
3894 + synth_write( &ch, 1 );
3895 + else rep_count = 0;
3896 + } else {
3897 + if ( ( char_type&B_EXNUM ) )
3898 + exn_ptr = (u_char *)synth_buff_in;
3899 +/* send space and record position, if next is num overwrite space */
3900 + if ( old_ch != ch ) synth_buffer_add ( SPACE );
3901 + else rep_count = 0;
3902 + }
3903 + old_ch = ch;
3904 + last_type = char_type;
3905 + }
3906 + spk_lastkey = 0;
3907 + if (in_count > 2 && rep_count > 2 ) {
3908 + if ( (last_type&CH_RPT) ) {
3909 + sprintf (rpt_buf, " repeated %d . ", ++rep_count );
3910 + synth_write_string (rpt_buf );
3911 + }
3912 + rep_count = 0;
3913 + }
3914 +}
3915 +
3916 +static char *ctl_key_ids[] = {
3917 + "shift", "altgr", "control", "ault", "l shift", "speakup",
3918 +"l control", "r control"
3919 +};
3920 +#define NUM_CTL_LABELS 8
3921 +
3922 +static void
3923 +handle_shift( KBD_PROTO )
3924 +{
3925 + (*do_shift)( KBD_ARGS );
3926 + if ( synth == NULL || up_flag || spk_killed ) return;
3927 + spk_shut_up &= 0xfe;
3928 + do_flush( );
3929 + if ( say_ctrl && value < NUM_CTL_LABELS )
3930 + synth_write_string ( ctl_key_ids[value] );
3931 +}
3932 +
3933 +static void
3934 +handle_latin( KBD_PROTO )
3935 +{
3936 + (*do_latin)( KBD_ARGS );
3937 + if ( up_flag ) {
3938 + spk_lastkey = spk_keydown = 0;
3939 + return;
3940 + }
3941 + if ( synth == NULL || spk_killed ) return;
3942 + spk_shut_up &= 0xfe;
3943 + spk_lastkey = value;
3944 + spk_keydown++;
3945 + spk_parked &= 0xfe;
3946 + if ( key_echo == 2 && value >= MINECHOCHAR )
3947 + speak_char( value );
3948 +}
3949 +
3950 +static int
3951 +set_key_info( u_char *key_info, u_char *k_buffer )
3952 +{
3953 + int i = 0, states, key_data_len;
3954 + u_char *cp = key_info, *cp1 = k_buffer;
3955 + u_char ch, version, num_keys;
3956 + version = *cp++;
3957 + if ( version != KEY_MAP_VER ) return -1;
3958 + num_keys = *cp;
3959 + states = (int)cp[1];
3960 + key_data_len = ( states+1 ) * ( num_keys+1 );
3961 + if ( key_data_len+SHIFT_TBL_SIZE+4 >= sizeof(key_buf ) ) return -2;
3962 + memset( k_buffer, 0, SHIFT_TBL_SIZE );
3963 + memset( our_keys, 0, sizeof( our_keys ) );
3964 + shift_table = k_buffer;
3965 + our_keys[0] = shift_table;
3966 + cp1 += SHIFT_TBL_SIZE;
3967 + memcpy( cp1, cp, key_data_len+3 );
3968 +/* get num_keys, states and data*/
3969 + cp1 += 2; /* now pointing at shift states */
3970 + for ( i = 1; i <= states; i++ ) {
3971 + ch = *cp1++;
3972 + if ( ch >= SHIFT_TBL_SIZE ) return -3;
3973 + shift_table[ch] = i;
3974 + }
3975 + keymap_flags = *cp1++;
3976 + while ( ( ch = *cp1 ) ) {
3977 + if ( ch >= MAX_KEY ) return -4;
3978 + our_keys[ch] = cp1;
3979 + cp1 += states+1;
3980 + }
3981 + return 0;
3982 +}
3983 +
3984 +num_var spk_num_vars[] = { /* bell must be first to set high limit */
3985 + { BELL_POS, 0, 0, 0, 0, 0, 0, 0 },
3986 + { SPELL_DELAY, 0, 0, 0, 5, 0, 0, 0 },
3987 + { ATTRIB_BLEEP, 0, 1, 0, 3, 0, 0, 0 },
3988 + { BLEEPS, 0, 3, 0, 3, 0, 0, 0 },
3989 + { BLEEP_TIME, 0, 4, 1, 20, 0, 0, 0 },
3990 + { PUNC_LEVEL, 0, 1, 0, 4, 0, 0, 0 },
3991 + { READING_PUNC, 0, 1, 0, 4, 0, 0, 0 },
3992 + { CURSOR_TIME, 0, 120, 50, 600, 0, 0, 0 },
3993 + { SAY_CONTROL, TOGGLE_0 },
3994 + { SAY_WORD_CTL, TOGGLE_0 },
3995 + { NO_INTERRUPT, TOGGLE_0 },
3996 + { KEY_ECHO, 0, 1, 0, 2, 0, 0, 0 },
3997 + V_LAST_NUM
3998 +};
3999 +
4000 +static int cursor_track = 1;
4001 +static char *cursor_msgs[] = { "cursoring off", "cursoring on",
4002 + "attribute cursor" };
4003 +#define MAXCURSORTRACK 1
4004 +/* increase when we add more cursor modes */
4005 +/* attribute cursor code coming soon */
4006 +
4007 +static void
4008 +toggle_cursoring( struct vc_data *vc )
4009 +{
4010 + cursor_track++;
4011 + if ( cursor_track > MAXCURSORTRACK )
4012 + cursor_track = 0;
4013 + synth_write_msg (cursor_msgs[cursor_track] );
4014 +}
4015 +
4016 +static void
4017 +reset_default_chars (void )
4018 +{
4019 + int i;
4020 + if (default_chars[(int )'a'] == NULL ) { /* lowers are null first time */
4021 + for (i = (int )'a'; default_chars[i] == NULL; i++ )
4022 + default_chars[i] = default_chars[i-32];
4023 + } else { /* free any non-default */
4024 + for (i = 0; i < 256; i++ ) {
4025 + if (characters[i] != default_chars[i] )
4026 + kfree (characters[i] );
4027 + }
4028 + }
4029 + memcpy( characters, default_chars, sizeof( default_chars ) );
4030 +}
4031 +
4032 +static void
4033 +handle_cursor( KBD_PROTO );
4034 +static void
4035 +handle_spec( KBD_PROTO );
4036 +static void
4037 +cursor_done(u_long data );
4038 +declare_timer( cursor_timer );
4039 +
4040 +void __init speakup_open (struct vc_data *vc, spk_t *first_console )
4041 +{
4042 + int i;
4043 + num_var *n_var;
4044 + reset_default_chars ( );
4045 + memset( speakup_console, 0, sizeof( speakup_console ) );
4046 + if ( first_console == NULL ) return;
4047 + memset( first_console, 0, spk_size );
4048 + speakup_console[vc->vc_num] = first_console;
4049 + speakup_date( vc);
4050 + pr_info ("%s: initialized\n", SPEAKUP_VERSION );
4051 + init_timer (&cursor_timer );
4052 +#if (LINUX_VERSION_CODE >= 132419)
4053 + cursor_timer.entry.prev=NULL;
4054 +#endif
4055 + cursor_timer.function = cursor_done;
4056 + init_sleeper ( synth_sleeping_list );
4057 + strlwr (synth_name );
4058 + synth_init ( synth_name );
4059 + spk_num_vars[0].high = vc->vc_cols;
4060 + for ( n_var = spk_num_vars; n_var->var_id >= 0; n_var++ )
4061 + speakup_register_var( n_var );
4062 + for (i = 1; punc_info[i].mask != 0; i++ )
4063 + set_mask_bits( 0, i, 2 );
4064 + do_latin = key_handler[KT_LATIN];
4065 + key_handler[KT_LATIN] = handle_latin;
4066 + do_spec = key_handler[KT_SPEC];
4067 + key_handler[KT_SPEC] = handle_spec;
4068 + do_cursor = key_handler[KT_CUR];
4069 + key_handler[KT_CUR] = handle_cursor;
4070 + do_shift = key_handler[KT_SHIFT];
4071 + key_handler[KT_SHIFT] = handle_shift;
4072 + set_key_info( key_defaults, key_buf );
4073 +}
4074 +
4075 +#ifdef CONFIG_PROC_FS
4076 +
4077 +// speakup /proc interface code
4078 +
4079 +/* Usage:
4080 +cat /proc/speakup/version
4081 +
4082 +cat /proc/speakup/characters > foo
4083 +less /proc/speakup/characters
4084 +vi /proc/speakup/characters
4085 +
4086 +cat foo > /proc/speakup/characters
4087 +cat > /proc/speakup/characters
4088 +echo 39 apostrophe > /proc/speakup/characters
4089 +echo 87 w > /proc/speakup/characters
4090 +echo 119 w > /proc/speakup/characters
4091 +echo defaults > /proc/speakup/characters
4092 +echo reset > /proc/speakup/characters
4093 +*/
4094 +
4095 +// keymap handlers
4096 +
4097 +static int
4098 +keys_read_proc (PROC_READ_PROTOTYPE )
4099 +{
4100 + char *cp = page;
4101 + int i, n, num_keys, nstates;
4102 + u_char *cp1 = key_buf + SHIFT_TBL_SIZE, ch;
4103 + num_keys = (int)(*cp1);
4104 + nstates = (int)cp1[1];
4105 + cp += sprintf( cp, "%d, %d, %d,\n", KEY_MAP_VER, num_keys, nstates );
4106 + cp1 += 2; /* now pointing at shift states */
4107 +/* dump num_keys+1 as first row is shift states + flags,
4108 + each subsequent row is key + states */
4109 + for ( n = 0; n <= num_keys; n++ ) {
4110 + for ( i = 0; i <= nstates; i++ ) {
4111 + ch = *cp1++;
4112 + cp += sprintf( cp, "%d,", (int)ch );
4113 + *cp++ = ( i < nstates ) ? SPACE : '\n';
4114 + }
4115 + }
4116 + cp += sprintf( cp, "0, %d\n", KEY_MAP_VER );
4117 + *start = 0;
4118 + *eof = 1;
4119 + return (int)(cp-page);
4120 +}
4121 +
4122 +static char *
4123 +s2uchar ( char *start, char *dest )
4124 +{
4125 + int val = 0;
4126 + while ( *start && *start <= SPACE ) start++;
4127 + while ( *start >= '0' && *start <= '9' ) {
4128 + val *= 10;
4129 + val += ( *start ) - '0';
4130 + start++;
4131 + }
4132 + if ( *start == ',' ) start++;
4133 + *dest = (u_char)val;
4134 + return start;
4135 +}
4136 +
4137 +static int
4138 +keys_write_proc (PROC_WRITE_PROTOTYPE )
4139 +{
4140 + int i, ret = count;
4141 + char *in_buff, *cp;
4142 + u_char *cp1;
4143 + if (count < 1 || count > 1800 )
4144 + return -EINVAL;
4145 + in_buff = ( char * ) __get_free_page ( GFP_KERNEL );
4146 + if ( !in_buff ) return -ENOMEM;
4147 + if (copy_from_user (in_buff, buffer, count ) ) {
4148 + free_page ( ( unsigned long ) in_buff );
4149 + return -EFAULT;
4150 + }
4151 + if (in_buff[count - 1] == '\n' ) count--;
4152 + in_buff[count] = '\0';
4153 + if ( count == 1 && *in_buff == 'd' ) {
4154 + free_page ( ( unsigned long ) in_buff );
4155 + set_key_info( key_defaults, key_buf );
4156 + return ret;
4157 + }
4158 + cp = in_buff;
4159 + cp1 = (u_char *)in_buff;
4160 + for ( i = 0; i < 3; i++ ) {
4161 + cp = s2uchar( cp, cp1 );
4162 + cp1++;
4163 + }
4164 + i = (int)cp1[-2]+1;
4165 + i *= (int)cp1[-1]+1;
4166 + i+= 2; /* 0 and last map ver */
4167 + if ( cp1[-3] != KEY_MAP_VER || cp1[-1] > 10 ||
4168 + i+SHIFT_TBL_SIZE+4 >= sizeof(key_buf ) ) {
4169 +pr_warn( "i %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1] );
4170 + free_page ( ( unsigned long ) in_buff );
4171 + return -EINVAL;
4172 + }
4173 + while ( --i >= 0 ) {
4174 + cp = s2uchar( cp, cp1 );
4175 + cp1++;
4176 + if ( !(*cp) ) break;
4177 + }
4178 + if ( i != 0 || cp1[-1] != KEY_MAP_VER || cp1[-2] != 0 ) {
4179 + ret = -EINVAL;
4180 +pr_warn( "end %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1] );
4181 + } else {
4182 + if ( set_key_info( in_buff, key_buf ) ) {
4183 + set_key_info( key_defaults, key_buf );
4184 + ret = -EINVAL;
4185 +pr_warn( "set key failed\n" );
4186 + }
4187 + }
4188 + free_page ( ( unsigned long ) in_buff );
4189 + return ret;
4190 +}
4191 +
4192 +// this is the handler for /proc/speakup/version
4193 +static int
4194 +version_read_proc (PROC_READ_PROTOTYPE )
4195 +{
4196 + int len = sprintf (page, "%s\n", SPEAKUP_VERSION );
4197 + if ( synth != NULL )
4198 + len += sprintf( page+len, "synth %s version %s\n",
4199 + synth->name, synth->version );
4200 + *start = 0;
4201 + *eof = 1;
4202 + return len;
4203 +}
4204 +
4205 +// this is the read handler for /proc/speakup/characters
4206 +static int
4207 +chars_read_proc (PROC_READ_PROTOTYPE )
4208 +{
4209 + int i, len = 0;
4210 + off_t begin = 0;
4211 + char *cp;
4212 + for (i = 0; i < 256; i++ ) {
4213 + cp = (characters[i] ) ? characters[i] : "NULL";
4214 + len += sprintf (page + len, "%d\t%s\n", i, cp );
4215 + if (len + begin > off + count )
4216 + break;
4217 + if (len + begin < off ) {
4218 + begin += len;
4219 + len = 0;
4220 + }
4221 + }
4222 + if (i >= 256 )
4223 + *eof = 1;
4224 + if (off >= len + begin )
4225 + return 0;
4226 + *start = page + (off - begin );
4227 + return ((count < begin + len - off ) ? count : begin + len - off );
4228 +}
4229 +
4230 +static volatile int chars_timer_active = 0; // indicates when timer is set
4231 +static declare_timer( chars_timer );
4232 +
4233 +static inline void
4234 +chars_stop_timer (void )
4235 +{
4236 + if (chars_timer_active )
4237 + stop_timer ( chars_timer );
4238 +}
4239 +
4240 +static int strings, rejects, updates;
4241 +
4242 +static void
4243 +show_char_results (u_long data )
4244 +{
4245 + int len;
4246 + char buf[80];
4247 + chars_stop_timer ( );
4248 + len = sprintf (buf, " updated %d of %d character descriptions\n",
4249 + updates, strings );
4250 + if (rejects )
4251 + sprintf (buf + (len-1), " with %d reject%s\n",
4252 + rejects, rejects > 1 ? "s" : "" );
4253 + printk( buf );
4254 +}
4255 +
4256 +/* this is the write handler for /proc/speakup/silent */
4257 +static int
4258 +silent_write_proc (PROC_WRITE_PROTOTYPE )
4259 +{
4260 + struct vc_data *vc = vc_cons[fg_console].d;
4261 + char ch = 0, shut;
4262 + if (count > 0 || count < 3 ) {
4263 + get_user (ch, buffer );
4264 + if ( ch == '\n' ) ch = '0';
4265 + }
4266 + if ( ch < '0' || ch > '7' ) {
4267 + pr_warn ( "silent value not in range (0,7)\n" );
4268 + return count;
4269 + }
4270 + if ( (ch&2) ) {
4271 + shut = 1;
4272 + do_flush( );
4273 + } else shut = 0;
4274 + if ( (ch&4) ) shut |= 0x40;
4275 + if ( (ch&1) )
4276 + spk_shut_up |= shut;
4277 + else spk_shut_up &= ~shut;
4278 + return count;
4279 +}
4280 +
4281 +// this is the write handler for /proc/speakup/characters
4282 +static int
4283 +chars_write_proc (PROC_WRITE_PROTOTYPE )
4284 +{
4285 +#define max_desc_len 72
4286 + static int cnt = 0, state = 0;
4287 + static char desc[max_desc_len + 1];
4288 + static u_long jiff_last = 0;
4289 + short i = 0, num;
4290 + int len;
4291 + char ch, *cp, *p_new;
4292 + // reset certain vars if enough time has elapsed since last called
4293 + if (jiffies - jiff_last > 10 ) {
4294 + cnt = state = strings = rejects = updates = 0;
4295 + }
4296 + jiff_last = jiffies;
4297 +get_more:
4298 + desc[cnt] = '\0';
4299 + state = 0;
4300 + for (; i < count && state < 2; i++ ) {
4301 + get_user (ch, buffer + i );
4302 + if ( ch == '\n' ) {
4303 + desc[cnt] = '\0';
4304 + state = 2;
4305 + } else if (cnt < max_desc_len )
4306 + desc[cnt++] = ch;
4307 + }
4308 + if (state < 2 ) return count;
4309 + cp = desc;
4310 + while ( *cp && *cp <= SPACE ) cp++;
4311 + if ((!cnt ) || strchr ("dDrR", *cp ) ) {
4312 + reset_default_chars ( );
4313 + pr_info( "character descriptions reset to defaults\n" );
4314 + cnt = 0;
4315 + return count;
4316 + }
4317 + cnt = 0;
4318 + if (*cp == '#' ) goto get_more;
4319 + num = -1;
4320 + cp = speakup_s2i(cp, &num );
4321 + while ( *cp && *cp <= SPACE ) cp++;
4322 + if (num < 0 || num > 255 ) { // not in range
4323 + rejects++;
4324 + strings++;
4325 + goto get_more;
4326 + }
4327 + if (num >= 27 && num <= 31 ) goto get_more;
4328 + if (!strcmp(cp, characters[num] ) ) {
4329 + strings++;
4330 + goto get_more;
4331 + }
4332 + len = strlen(cp );
4333 + if (characters[num] == default_chars[num] )
4334 + p_new = (char * ) kmalloc (sizeof (char ) * len+1, GFP_KERNEL );
4335 + else if ( strlen(characters[num] ) >= len )
4336 + p_new = characters[num];
4337 + else {
4338 + kfree(characters[num] );
4339 + characters[num] = default_chars[num];
4340 + p_new = (char * ) kmalloc (sizeof (char ) * len+1, GFP_KERNEL );
4341 + }
4342 + if (!p_new ) return -ENOMEM;
4343 + strcpy ( p_new, cp );
4344 + characters[num] = p_new;
4345 + updates++;
4346 + strings++;
4347 + if (i < count ) goto get_more;
4348 + chars_stop_timer ( );
4349 + init_timer (&chars_timer );
4350 + chars_timer.function = show_char_results;
4351 + chars_timer.expires = jiffies + 5;
4352 + start_timer (chars_timer );
4353 + chars_timer_active++;
4354 + return count;
4355 +}
4356 +
4357 +static int
4358 +bits_read_proc (PROC_READ_PROTOTYPE )
4359 +{
4360 + int i;
4361 + var_header *p_header = (var_header * )data;
4362 + proc_var *var = p_header->data;
4363 + bits_data *pb = &punc_info[var->value];
4364 + short mask = pb->mask;
4365 + char *cp = page;
4366 + *start = 0;
4367 + *eof = 1;
4368 + for ( i = 33; i < 128; i++ ) {
4369 + if ( !(spk_chartab[i]&mask ) ) continue;
4370 + *cp++ = (char )i;
4371 + }
4372 + *cp++ = '\n';
4373 + return cp-page;
4374 +}
4375 +
4376 +/* set_mask_bits sets or clears the punc/delim/repeat bits,
4377 + * if input is null uses the defaults.
4378 + * values for how: 0 clears bits of chars supplied,
4379 + * 1 clears allk, 2 sets bits for chars */
4380 +
4381 +int
4382 +set_mask_bits( const char *input, const int which, const int how )
4383 +{
4384 + u_char *cp;
4385 + short mask = punc_info[which].mask;
4386 + if ( how&1 ) {
4387 + for ( cp = (u_char * )punc_info[3].value; *cp; cp++ )
4388 + spk_chartab[*cp] &= ~mask;
4389 + }
4390 + cp = (u_char * )input;
4391 + if ( cp == 0 ) cp = punc_info[which].value;
4392 + else {
4393 + for ( ; *cp; cp++ ) {
4394 + if ( *cp < SPACE ) break;
4395 + if ( mask < PUNC ) {
4396 + if ( !(spk_chartab[*cp]&PUNC) ) break;
4397 + } else if ( (spk_chartab[*cp]&B_NUM) ) break;
4398 + }
4399 + if ( *cp ) return -EINVAL;
4400 + cp = (u_char * )input;
4401 + }
4402 + if ( how&2 ) {
4403 + for ( ; *cp; cp++ )
4404 + if ( *cp > SPACE ) spk_chartab[*cp] |= mask;
4405 + } else {
4406 + for ( ; *cp; cp++ )
4407 + if ( *cp > SPACE ) spk_chartab[*cp] &= ~mask;
4408 + }
4409 + return 0;
4410 +}
4411 +
4412 +static bits_data *pb_edit = NULL;
4413 +
4414 +static int edit_bits (struct vc_data *vc, u_char type, u_char ch, u_short key )
4415 +{
4416 + short mask = pb_edit->mask, ch_type = spk_chartab[ch];
4417 + if ( type != KT_LATIN || (ch_type&B_NUM ) || ch < SPACE ) return -1;
4418 + if ( ch == SPACE ) {
4419 + synth_write_msg( "edit done" );
4420 + special_handler = NULL;
4421 + return 1;
4422 + }
4423 + if ( mask < PUNC && !(ch_type&PUNC) ) return -1;
4424 + spk_chartab[ch] ^= mask;
4425 + speak_char( ch );
4426 + synth_write_msg( (spk_chartab[ch]&mask ) ? " on" : " off" );
4427 + return 1;
4428 +}
4429 +
4430 +static int
4431 +bits_write_proc (PROC_WRITE_PROTOTYPE )
4432 +{
4433 + var_header *p_header = (var_header * )data;
4434 + proc_var *var = p_header->data;
4435 + int ret = count;
4436 + char punc_buf[100];
4437 + if (count < 1 || count > 99 )
4438 + return -EINVAL;
4439 + if (copy_from_user (punc_buf, buffer, count ) )
4440 + return -EFAULT;
4441 + if (punc_buf[count - 1] == '\n' )
4442 + count--;
4443 + punc_buf[count] = '\0';
4444 + if ( *punc_buf == 'd' || *punc_buf == 'r' )
4445 + count = set_mask_bits( 0, var->value, 3 );
4446 + else
4447 + count = set_mask_bits( punc_buf, var->value, 3 );
4448 + if ( count < 0 ) return count;
4449 + return ret;
4450 +}
4451 +
4452 +// this is the read handler for /proc/speakup/synth
4453 +static int
4454 +synth_read_proc (PROC_READ_PROTOTYPE )
4455 +{
4456 + int len;
4457 + if ( synth == NULL ) strcpy( synth_name, "none" );
4458 + else strcpy( synth_name, synth->name );
4459 + len = sprintf (page, "%s\n", synth_name );
4460 + *start = 0;
4461 + *eof = 1;
4462 + return len;
4463 +}
4464 +
4465 +// this is the write handler for /proc/speakup/synth
4466 +static int
4467 +synth_write_proc (PROC_WRITE_PROTOTYPE )
4468 +{
4469 + int ret = count;
4470 + char new_synth_name[10];
4471 + const char *old_name = ( synth != NULL ) ? synth->name : "none";
4472 + if (count < 2 || count > 9 )
4473 + return -EINVAL;
4474 + if (copy_from_user (new_synth_name, buffer, count ) )
4475 + return -EFAULT;
4476 + if (new_synth_name[count - 1] == '\n' )
4477 + count--;
4478 + new_synth_name[count] = '\0';
4479 + strlwr (new_synth_name );
4480 + if (!strcmp (new_synth_name, old_name ) ) {
4481 + pr_warn ( "%s already in use\n", new_synth_name );
4482 + return ret;
4483 + }
4484 + if ( synth_init( new_synth_name ) == 0 ) return ret;
4485 + pr_warn( "failed to init synth %s\n", new_synth_name );
4486 + return -ENODEV;
4487 +}
4488 +
4489 +proc_var spk_proc_vars[] = {
4490 + { VERSION, version_read_proc, 0, 0 },
4491 + { SILENT, 0, silent_write_proc, 0 },
4492 + { CHARS, chars_read_proc, chars_write_proc, 0 },
4493 + { SYNTH, synth_read_proc, synth_write_proc, 0 },
4494 + { KEYMAP, keys_read_proc, keys_write_proc, 0 },
4495 + { PUNC_SOME, bits_read_proc, bits_write_proc, 1 },
4496 + { PUNC_MOST, bits_read_proc, bits_write_proc, 2 },
4497 + { PUNC_ALL, bits_read_proc, 0, 3 },
4498 + { DELIM, bits_read_proc, bits_write_proc, 4 },
4499 + { REPEATS, bits_read_proc, bits_write_proc, 5 },
4500 + { EXNUMBER, bits_read_proc, bits_write_proc, 6 },
4501 + { -1, 0, 0, 0 }
4502 +};
4503 +
4504 +#endif // CONFIG_PROC_FS
4505 +
4506 +#ifdef CONFIG_SPEAKUP
4507 +
4508 +void __init
4509 +speakup_init (struct vc_data *vc )
4510 +{
4511 + spk_t *first_console = (spk_t *) alloc_bootmem (spk_size+1 );
4512 + speakup_open( vc, first_console );
4513 +}
4514 +
4515 +#endif
4516 +
4517 +void
4518 +speakup_allocate (struct vc_data *vc )
4519 +{
4520 + int vc_num = vc->vc_num;
4521 + if ( speakup_console[vc_num] == NULL ) {
4522 + speakup_console[vc_num] = (spk_t *) kmalloc (spk_size + 1,
4523 + GFP_KERNEL );
4524 + if ( speakup_console[vc_num] == NULL ) return;
4525 + memset( speakup_console[vc_num], 0, spk_size );
4526 + speakup_date( vc);
4527 + } else if ( !spk_parked ) speakup_date( vc);
4528 +}
4529 +
4530 +static void
4531 +speakup_date (struct vc_data *vc )
4532 +{
4533 + spk_x = spk_cx = vc->vc_x;
4534 + spk_y = spk_cy = vc->vc_y;
4535 + spk_pos = spk_cp = vc->vc_pos;
4536 + spk_old_attr = spk_attr;
4537 + spk_attr = ((scr_readw ((u_short * ) spk_pos ) & 0xff00 ) >> 8 );
4538 +}
4539 +
4540 +static u_char is_cursor = 0;
4541 +static u_long old_cursor_pos, old_cursor_x, old_cursor_y;
4542 +static int cursor_con;
4543 +volatile int cursor_timer_active = 0;
4544 +
4545 +void
4546 +cursor_stop_timer(void )
4547 +{
4548 + if (!cursor_timer_active ) return;
4549 + stop_timer ( cursor_timer );
4550 + cursor_timer_active = 0;
4551 +}
4552 +
4553 +static void
4554 +handle_cursor( KBD_PROTO )
4555 +{
4556 + (*do_cursor)( KBD_ARGS );
4557 + spk_parked &= 0xfe;
4558 + if ( synth == NULL || up_flag || spk_shut_up || cursor_track == 0 )
4559 + return;
4560 + spk_shut_up &= 0xfe;
4561 + if ( no_intr ) do_flush( );
4562 +/* the key press flushes if !no_inter but we want to flush on cursor
4563 + * moves regardless of no_inter state */
4564 + is_cursor = value+1;
4565 + old_cursor_pos = vc->vc_pos;
4566 + old_cursor_x = vc->vc_x;
4567 + old_cursor_y = vc->vc_y;
4568 + cursor_con = vc->vc_num;
4569 + cursor_stop_timer( );
4570 + cursor_timer.expires = jiffies + cursor_timeout;
4571 + start_timer (cursor_timer );
4572 + cursor_timer_active++;
4573 +}
4574 +
4575 +static void
4576 +cursor_done (u_long data )
4577 +{
4578 + struct vc_data *vc = vc_cons[cursor_con].d;
4579 + cursor_stop_timer( );
4580 + if (cursor_con != fg_console ) {
4581 + is_cursor = 0;
4582 + return;
4583 + }
4584 + speakup_date (vc );
4585 + if ( win_enabled ) {
4586 + if ( vc->vc_x >= win_left && vc->vc_x <= win_right &&
4587 + vc->vc_y >= win_top && vc->vc_y <= win_bottom ) {
4588 + spk_keydown = is_cursor = 0;
4589 + return;
4590 + }
4591 + }
4592 + if ( is_cursor == 1 || is_cursor == 4 )
4593 + say_line_from_to (vc, 0, vc->vc_cols, 0 );
4594 + else say_char ( vc );
4595 + spk_keydown = is_cursor = 0;
4596 +}
4597 +
4598 +/* These functions are the interface to speakup from the actual kernel code. */
4599 +
4600 +void
4601 +speakup_bs (struct vc_data *vc )
4602 +{
4603 + if (!spk_parked )
4604 + speakup_date (vc );
4605 + if ( spk_shut_up || synth == NULL ) return;
4606 + if ( vc->vc_num == fg_console && spk_keydown ) {
4607 + spk_keydown = 0;
4608 + if (!is_cursor ) say_char (vc );
4609 + }
4610 +}
4611 +
4612 +void
4613 +speakup_con_write (struct vc_data *vc, const char *str, int len )
4614 +{
4615 + if (spk_shut_up || (vc->vc_num != fg_console ) )
4616 + return;
4617 + if (bell_pos && spk_keydown && (vc->vc_x == bell_pos - 1 ) )
4618 + bleep(3 );
4619 + if (synth == NULL || is_cursor ) return;
4620 + if ( win_enabled ) {
4621 + if ( vc->vc_x >= win_left && vc->vc_x <= win_right &&
4622 + vc->vc_y >= win_top && vc->vc_y <= win_bottom ) return;
4623 + }
4624 + spkup_write (str, len );
4625 +}
4626 +
4627 +void
4628 +speakup_con_update (struct vc_data *vc )
4629 +{
4630 + if ( speakup_console[vc->vc_num] == NULL || spk_parked )
4631 + return;
4632 + speakup_date (vc );
4633 +}
4634 +
4635 +static void
4636 +handle_spec( KBD_PROTO )
4637 +{
4638 + int on_off = 2;
4639 + char *label;
4640 +static const char *lock_status[] = { " off", " on", "" };
4641 + (*do_spec)( KBD_ARGS );
4642 + if ( synth == NULL || up_flag || spk_killed ) return;
4643 + spk_shut_up &= 0xfe;
4644 + if ( no_intr ) do_flush( );
4645 + switch (value ) {
4646 + case KVAL( K_CAPS ):
4647 + label = "caps lock";
4648 + on_off = (vc_kbd_led(kbd , VC_CAPSLOCK ) );
4649 + break;
4650 + case KVAL( K_NUM ):
4651 + label = "num lock";
4652 + on_off = (vc_kbd_led(kbd , VC_NUMLOCK ) );
4653 + break;
4654 + case KVAL( K_HOLD ):
4655 + label = "scroll lock";
4656 + on_off = (vc_kbd_led(kbd , VC_SCROLLOCK ) );
4657 + break;
4658 + default:
4659 + spk_parked &= 0xfe;
4660 + return;
4661 + }
4662 + synth_write_string ( label );
4663 + synth_write_msg ( lock_status[on_off] );
4664 +}
4665 +
4666 +static int
4667 +inc_dec_var( u_char value )
4668 +{
4669 + var_header *p_header;
4670 + num_var *var_data;
4671 + char num_buf[32];
4672 + char *cp = num_buf, *pn;
4673 + int var_id = (int)value - VAR_START;
4674 + int how = (var_id&1) ? E_INC : E_DEC;
4675 + var_id = var_id/2+FIRST_SET_VAR;
4676 + p_header = get_var_header( var_id );
4677 + if ( p_header == NULL ) return -1;
4678 + if ( p_header->var_type != VAR_NUM ) return -1;
4679 + var_data = p_header->data;
4680 + if ( set_num_var( 1, p_header, how ) != 0 )
4681 + return -1;
4682 + if ( !spk_close_press ) {
4683 + for ( pn = p_header->name; *pn; pn++ ) {
4684 + if ( *pn == '_' ) *cp = SPACE;
4685 + else *cp++ = *pn;
4686 + }
4687 + }
4688 + sprintf( cp, " %d ", (int)var_data->value );
4689 + synth_write_string( num_buf );
4690 + return 0;
4691 +}
4692 +
4693 +static void
4694 +speakup_win_set (struct vc_data *vc )
4695 +{
4696 + char info[40];
4697 + if ( win_start > 1 ) {
4698 + synth_write_msg( "window already set, clear then reset" );
4699 + return;
4700 + }
4701 + if ( spk_x < win_left || spk_y < win_top ) {
4702 + synth_write_msg( "error end before start" );
4703 + return;
4704 + }
4705 + if ( win_start && spk_x == win_left && spk_y == win_top ) {
4706 + win_left = 0;
4707 + win_right = vc->vc_cols-1;
4708 + win_bottom = spk_y;
4709 + sprintf( info, "window is line %d", (int)win_top+1 );
4710 + } else {
4711 + if ( !win_start ) {
4712 + win_top = spk_y;
4713 + win_left = spk_x;
4714 + } else {
4715 + win_bottom = spk_y;
4716 + win_right = spk_x;
4717 + }
4718 + sprintf( info, "%s at line %d, column %d",
4719 + (win_start) ? "end" : "start",
4720 + (int)spk_y+1, (int)spk_x+1 );
4721 + }
4722 + synth_write_msg( info );
4723 + win_start++;
4724 +}
4725 +
4726 +static void
4727 +speakup_win_clear (struct vc_data *vc )
4728 +{
4729 + win_top = win_bottom = 0;
4730 + win_left = win_right = 0;
4731 + win_start = 0;
4732 + synth_write_msg( "window cleared" );
4733 +}
4734 +
4735 +static void
4736 +speakup_win_enable (struct vc_data *vc )
4737 +{
4738 + if ( win_start < 2 ) {
4739 + synth_write_msg( "no window" );
4740 + return;
4741 + }
4742 + win_enabled ^= 1;
4743 + if ( win_enabled ) synth_write_msg( "window silenced" );
4744 + else synth_write_msg( "window silence disabled" );
4745 +}
4746 +
4747 +static void
4748 +speakup_bits (struct vc_data *vc )
4749 +{
4750 + int val = this_speakup_key - ( FIRST_EDIT_BITS - 1 );
4751 + if ( special_handler != NULL || val < 1 || val > 6 ) {
4752 + synth_write_msg( "error" );
4753 + return;
4754 + }
4755 + pb_edit = &punc_info[val];
4756 + sprintf( buf, "edit %s, press space when done", pb_edit->name );
4757 + synth_write_msg( buf );
4758 + special_handler = edit_bits;
4759 +}
4760 +
4761 +static int handle_goto (struct vc_data *vc, u_char type, u_char ch, u_short key )
4762 +{
4763 + static u_char *goto_buf = "\0\0\0\0\0\0";
4764 + static int num = 0;
4765 + short maxlen, go_pos;
4766 + char *cp;
4767 + if ( type == KT_SPKUP && ch == SPEAKUP_GOTO ) goto do_goto;
4768 + if ( type == KT_LATIN && ch == '\n' ) goto do_goto;
4769 + if ( type != 0 ) goto oops;
4770 + if (ch == 8 ) {
4771 + if ( num == 0 ) return -1;
4772 + ch = goto_buf[--num];
4773 + goto_buf[num] = '\0';
4774 + spkup_write( &ch, 1 );
4775 + return 1;
4776 +}
4777 + if ( ch < '+' || ch > 'y' ) goto oops;
4778 + goto_buf[num++] = ch;
4779 + goto_buf[num] = '\0';
4780 + spkup_write( &ch, 1 );
4781 + maxlen = ( *goto_buf >= '0' ) ? 3 : 4;
4782 + if ((ch == '+' || ch == '-' ) && num == 1 ) return 1;
4783 + if (ch >= '0' && ch <= '9' && num < maxlen ) return 1;
4784 + if ( num < maxlen-1 || num > maxlen ) goto oops;
4785 + if ( ch < 'x' || ch > 'y' ) {
4786 +oops:
4787 + if (!spk_killed )
4788 + synth_write_msg (" goto canceled" );
4789 + goto_buf[num = 0] = '\0';
4790 + special_handler = NULL;
4791 + return 1;
4792 + }
4793 + cp = speakup_s2i (goto_buf, &go_pos );
4794 + goto_pos = (u_long)go_pos;
4795 + if (*cp == 'x' ) {
4796 + if (*goto_buf < '0' ) goto_pos += spk_x;
4797 + else goto_pos--;
4798 + if (goto_pos < 0 ) goto_pos = 0;
4799 + if (goto_pos >= vc->vc_cols )
4800 + goto_pos = vc->vc_cols-1;
4801 + goto_x = 1;
4802 + } else {
4803 + if (*goto_buf < '0' ) goto_pos += spk_y;
4804 + else goto_pos--;
4805 + if (goto_pos < 0 ) goto_pos = 0;
4806 + if (goto_pos >= vc->vc_rows ) goto_pos = vc->vc_rows-1;
4807 + goto_x = 0;
4808 + }
4809 + goto_buf[num = 0] = '\0';
4810 +do_goto:
4811 + special_handler = NULL;
4812 + spk_parked |= 0x01;
4813 + if ( goto_x ) {
4814 + spk_pos -= spk_x * 2;
4815 + spk_x = goto_pos;
4816 + spk_pos += goto_pos * 2;
4817 + say_word( vc );
4818 + } else {
4819 + spk_y = goto_pos;
4820 + spk_pos = vc->vc_origin + ( goto_pos * vc->vc_size_row );
4821 + say_line( vc );
4822 + }
4823 + return 1;
4824 +}
4825 +
4826 +static void
4827 +speakup_goto (struct vc_data *vc )
4828 +{
4829 + if ( special_handler != NULL ) {
4830 + synth_write_msg( "error" );
4831 + return;
4832 + }
4833 + synth_write_msg( "go to?" );
4834 + special_handler = handle_goto;
4835 + return;
4836 +}
4837 +
4838 +static void
4839 +load_help ( void *dummy )
4840 +{
4841 + request_module( "speakup_keyhelp" );
4842 + if ( help_handler ) {
4843 + (*help_handler)(0, KT_SPKUP, SPEAKUP_HELP, 0 );
4844 + } else synth_write_string( "help module not found" );
4845 +}
4846 +
4847 +#if (LINUX_VERSION_CODE >= 132419)
4848 +static DECLARE_WORK(ld_help, load_help, NULL);
4849 +#define schedule_help schedule_work
4850 +#else
4851 +static struct tq_struct ld_help = { routine: load_help, };
4852 +#define schedule_help schedule_task
4853 +#endif
4854 +
4855 +static void
4856 +speakup_help (struct vc_data *vc )
4857 +{
4858 + if ( help_handler == NULL ) {
4859 +/* we can't call request_module from this context so schedule it*/
4860 +/* **** note kernel hangs and my wrath will be on you */
4861 + schedule_help (&ld_help);
4862 + return;
4863 + }
4864 + (*help_handler)(vc, KT_SPKUP, SPEAKUP_HELP, 0 );
4865 +}
4866 +
4867 +static void
4868 +do_nothing (struct vc_data *vc )
4869 +{
4870 + return; /* flush done in do_spkup */
4871 +}
4872 +static u_char key_speakup = 0, spk_key_locked = 0;
4873 +
4874 +static void
4875 +speakup_lock (struct vc_data *vc )
4876 +{
4877 + if ( !spk_key_locked )
4878 + spk_key_locked = key_speakup = 16;
4879 + else spk_key_locked = key_speakup = 0;
4880 +}
4881 +
4882 +typedef void (*spkup_hand )(struct vc_data * );
4883 +spkup_hand spkup_handler[] = { /* must be ordered same as defines in speakup.h */
4884 + do_nothing, speakup_goto, speech_kill, speakup_shut_up,
4885 + speakup_cut, speakup_paste, say_first_char, say_last_char,
4886 + say_char, say_prev_char, say_next_char,
4887 + say_word, say_prev_word, say_next_word,
4888 + say_line, say_prev_line, say_next_line,
4889 + top_edge, bottom_edge, left_edge, right_edge,
4890 + spell_word, spell_word, say_screen,
4891 + say_position, say_attributes,
4892 + speakup_off, speakup_parked, say_line, // this is for indent
4893 + say_from_top, say_to_bottom,
4894 + say_from_left, say_to_right,
4895 + say_char_num, speakup_bits, speakup_bits, say_phonetic_char,
4896 + speakup_bits, speakup_bits, speakup_bits,
4897 + speakup_win_set, speakup_win_clear, speakup_win_enable, speakup_win_say,
4898 + speakup_lock, speakup_help, toggle_cursoring, NULL
4899 +};
4900 +
4901 +void do_spkup( struct vc_data *vc,u_char value )
4902 +{
4903 + if (spk_killed && value != SPEECH_KILL ) return;
4904 + spk_keydown = 0;
4905 + spk_lastkey = 0;
4906 + spk_shut_up &= 0xfe;
4907 + this_speakup_key = value;
4908 + if (value < SPKUP_MAX_FUNC && spkup_handler[value] ) {
4909 + do_flush( );
4910 + (*spkup_handler[value] )(vc );
4911 + } else {
4912 + if ( inc_dec_var( value ) < 0 )
4913 + bleep( 9 );
4914 + }
4915 +}
4916 +
4917 + static const char *pad_chars = "0123456789+-*/\015,.?()";
4918 +
4919 +int
4920 +#if (LINUX_VERSION_CODE < 132419)
4921 +speakup_key ( int shift_state, u_char keycode, u_short keysym, u_char up_flag )
4922 +#else
4923 +speakup_key (struct vc_data *vc, int shift_state, int keycode, u_short keysym, int up_flag, struct pt_regs *regs )
4924 +#endif
4925 +{
4926 + u_char *key_info;
4927 + u_char type = KTYP( keysym ), value = KVAL( keysym ), new_key = 0;
4928 + u_char shift_info, offset;
4929 +#if (LINUX_VERSION_CODE >= 132419)
4930 + tty = vc->vc_tty;
4931 +#endif
4932 + if ( synth == NULL ) return 0;
4933 + if ( type >= 0xf0 ) type -= 0xf0;
4934 + if ( type == KT_PAD && (vc_kbd_led(kbd , VC_NUMLOCK ) ) ) {
4935 + if ( up_flag ) {
4936 + spk_keydown = 0;
4937 + return 0;
4938 + }
4939 + value = spk_lastkey = pad_chars[value];
4940 + spk_keydown++;
4941 + spk_parked &= 0xfe;
4942 + goto no_map;
4943 + }
4944 + if ( keycode >= MAX_KEY ) goto no_map;
4945 + if ( ( key_info = our_keys[keycode] ) == 0 ) goto no_map;
4946 + shift_info = ( shift_state&0x0f ) + key_speakup;
4947 + offset = shift_table[shift_info];
4948 + if ( offset && ( new_key = key_info[offset] ) ) {
4949 + if ( new_key == SPK_KEY ) {
4950 + if ( !spk_key_locked )
4951 + key_speakup = ( up_flag ) ? 0 : 16;
4952 + if ( up_flag || spk_killed ) return 1;
4953 + spk_shut_up &= 0xfe;
4954 + do_flush( );
4955 + return 1;
4956 + }
4957 + if ( up_flag ) return 1;
4958 + if ( last_keycode == keycode && last_spk_jiffy+MAX_DELAY > jiffies ) {
4959 + spk_close_press = 1;
4960 + offset = shift_table[shift_info+32];
4961 +/* double press? */
4962 + if ( offset && key_info[offset] )
4963 + new_key = key_info[offset];
4964 + }
4965 + last_keycode = keycode;
4966 + last_spk_jiffy = jiffies;
4967 + type = KT_SPKUP;
4968 + value = new_key;
4969 + }
4970 +no_map:
4971 + if ( type == KT_SPKUP && special_handler == NULL ) {
4972 + do_spkup( vc, new_key );
4973 + spk_close_press = 0;
4974 + return 1;
4975 + }
4976 + if ( up_flag || spk_killed || type == KT_SHIFT ) return 0;
4977 + spk_shut_up &= 0xfe;
4978 + if (!no_intr ) do_flush( );
4979 + if ( special_handler ) {
4980 + int status;
4981 + if ( type == KT_SPEC && value == 1 ) {
4982 + value = '\n';
4983 + type = KT_LATIN;
4984 + } else if ( type == KT_LETTER ) type = KT_LATIN;
4985 + else if ( value == 0x7f ) value = 8; /* make del = backspace */
4986 + status = (*special_handler)(vc, type, value, keycode );
4987 + spk_close_press = 0;
4988 + if ( status < 0 ) bleep( 9 );
4989 + return status;
4990 + }
4991 + last_keycode = 0;
4992 + return 0;
4993 +}
4994 +
4995 +#ifdef MODULE
4996 +
4997 +extern void proc_speakup_init( void );
4998 +extern void proc_speakup_remove( void );
4999 +extern void speakup_set_addresses ( spk_con_func, spk_con_func, spk_write_func, spk_con_func, spk_key_func);
5000 +
5001 +static void __exit mod_speakup_exit( void )
5002 +{
5003 + int i;
5004 + key_handler[KT_LATIN] = do_latin;
5005 + key_handler[KT_SPEC] = do_spec;
5006 + key_handler[KT_CUR] = do_cursor;
5007 + key_handler[KT_SHIFT] = do_shift;
5008 + speakup_set_addresses( NULL, NULL, NULL, NULL, NULL );
5009 + synth_release( );
5010 + proc_speakup_remove( );
5011 + for (i = 0; i < 256; i++ ) {
5012 + if (characters[i] != default_chars[i] )
5013 + kfree (characters[i] );
5014 + }
5015 + for ( i = 0; speakup_console[i]; i++) {
5016 + kfree( speakup_console[i] );
5017 + speakup_console[i] = NULL;
5018 + }
5019 +}
5020 +
5021 +static int __init mod_speakup_init( void )
5022 +{
5023 +int i;
5024 + spk_t *first_console = (spk_t *) kmalloc (spk_size + 1, GFP_KERNEL );
5025 + speakup_open( vc_cons[fg_console].d, first_console );
5026 +for ( i = 0; vc_cons[i].d; i++)
5027 + speakup_allocate(vc_cons[i].d);
5028 + speakup_set_addresses( speakup_allocate, speakup_bs,
5029 + speakup_con_write, speakup_con_update, speakup_key );
5030 + proc_speakup_init( );
5031 + return 0;
5032 +}
5033 +
5034 +module_init( mod_speakup_init );
5035 +module_exit( mod_speakup_exit );
5036 +
5037 +#endif
5038 unchanged:
5039 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
5040 +++ gregkh-2.6/drivers/char/speakup/speakupconf 2005-07-27 13:02:56.000000000 -0700
5041 @@ -0,0 +1,51 @@
5042 +#!/bin/sh
5043 +# script to load/save all the vars in speakup
5044 +# speakupconf save or speakupconf load
5045 +# if root saves in /etc/speakup/<synth_name> else in $HOME/.speakup/<synth_name>
5046 +if [ $UID -eq "0" ]; then
5047 + SAVEDIR="/etc/speakup"
5048 +else
5049 + SAVEDIR="$HOME/.speakup"
5050 +fi
5051 +if [ ! -d /proc/speakup ]; then
5052 + echo "no directory /proc/speakup"
5053 + exit 0
5054 +fi
5055 +SYNTH=`cat /proc/speakup/synth_name`
5056 +case "$1" in
5057 +*save)
5058 + if [ ! -d $SAVEDIR ] ; then
5059 + echo creating $SAVEDIR
5060 + mkdir $SAVEDIR
5061 + fi
5062 + if [ ! -d $SAVEDIR/$SYNTH ] ; then
5063 + echo creating $SAVEDIR/$SYNTH
5064 + mkdir $SAVEDIR/$SYNTH
5065 + fi
5066 + cd /proc/speakup
5067 + SAVELIST=` find . -perm -6 |sed 's/..//' |fgrep -v synth`
5068 + for f in $SAVELIST; do
5069 + cp $f $SAVEDIR/$SYNTH/$f
5070 + done
5071 +;;
5072 +*load)
5073 + if [ ! -d $SAVEDIR ] ; then
5074 + echo no directory $SAVEDIR
5075 + exit 1
5076 + fi
5077 + if [ ! -d $SAVEDIR/$SYNTH ] ; then
5078 + echo no directory $SAVEDIR/$SYNTH
5079 + exit 1
5080 + fi
5081 + cd $SAVEDIR/$SYNTH
5082 + for f in *; do
5083 + if [ -w /proc/speakup/$f ]; then
5084 + cat $f >/proc/speakup/$f
5085 + fi
5086 + done
5087 +;;
5088 +*)
5089 + echo "usage: speakupconf load/save"
5090 + exit 1
5091 +;;
5092 +esac
5093 unchanged:
5094 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
5095 +++ gregkh-2.6/drivers/char/speakup/speakup_decext.c 2005-07-27 13:02:56.000000000 -0700
5096 @@ -0,0 +1,205 @@
5097 +/*
5098 + * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
5099 +* this version considerably modified by David Borowski, david575@rogers.com
5100 +
5101 + Copyright (C) 1998-99 Kirk Reiser.
5102 + Copyright (C) 2003 David Borowski.
5103 +
5104 + This program is free software; you can redistribute it and/or modify
5105 + it under the terms of the GNU General Public License as published by
5106 + the Free Software Foundation; either version 2 of the License, or
5107 + (at your option) any later version.
5108 +
5109 + This program is distributed in the hope that it will be useful,
5110 + but WITHOUT ANY WARRANTY; without even the implied warranty of
5111 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5112 + GNU General Public License for more details.
5113 +
5114 + You should have received a copy of the GNU General Public License
5115 + along with this program; if not, write to the Free Software
5116 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5117 +
5118 + * this code is specificly written as a driver for the speakup screenreview
5119 + * package and is not a general device driver.
5120 + */
5121 +#include "spk_priv.h"
5122 +#include "serialio.h"
5123 +
5124 +#define MY_SYNTH synth_decext
5125 +#define SYNTH_CLEAR 0x03
5126 +#define PROCSPEECH 0x0b
5127 +#define synth_full( ) ( inb_p( synth_port_tts ) == 0x13 )
5128 +
5129 +static int timeouts = 0;
5130 +static int in_escape = 0;
5131 +
5132 +static int wait_for_xmitr ( void )
5133 +{
5134 + int check, tmout = SPK_XMITR_TIMEOUT;
5135 + if ( ( synth_alive ) && ( timeouts >= NUM_DISABLE_TIMEOUTS ) ) {
5136 + synth_alive = 0;
5137 + timeouts = 0;
5138 + return 0;
5139 + }
5140 + do { /* holding register empty? */
5141 + check = inb_p( synth_port_tts + UART_LSR );
5142 + if ( --tmout == 0 ) {
5143 + pr_warn ( "%s: timed out\n", synth->long_name );
5144 + timeouts++;
5145 + return 0;
5146 + }
5147 + } while ( ( check & BOTH_EMPTY ) != BOTH_EMPTY );
5148 + tmout = SPK_XMITR_TIMEOUT;
5149 + do { /* CTS */
5150 + check = inb_p ( synth_port_tts + UART_MSR );
5151 + if ( --tmout == 0 ) {
5152 + timeouts++;
5153 + return 0;
5154 + }
5155 + } while ( ( check & UART_MSR_CTS ) != UART_MSR_CTS );
5156 + timeouts = 0;
5157 + return 1;
5158 +}
5159 +
5160 +static inline int spk_serial_out ( const char ch )
5161 +{
5162 + if ( synth_alive && wait_for_xmitr ( ) ) {
5163 + outb_p ( ch, synth_port_tts );
5164 + return 1;
5165 + }
5166 + return 0;
5167 +}
5168 +
5169 +static u_char
5170 +spk_serial_in ( void )
5171 +{
5172 + int lsr, tmout = SPK_SERIAL_TIMEOUT, c;
5173 + do {
5174 + lsr = inb_p ( synth_port_tts + UART_LSR );
5175 + if ( --tmout == 0 )
5176 + return 0xff;
5177 + } while ( !( lsr & UART_LSR_DR ) );
5178 + c = inb_p ( synth_port_tts + UART_RX );
5179 + return ( u_char ) c;
5180 +}
5181 +
5182 +static void do_catch_up( unsigned long data )
5183 +{
5184 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
5185 + u_char ch;
5186 +static u_char last='\0';
5187 + synth_stop_timer( );
5188 + while ( synth_buff_out < synth_buff_in ) {
5189 + ch = *synth_buff_out;
5190 + if ( ch == '\n' ) ch = 0x0D;
5191 + if ( synth_full( ) || !spk_serial_out( ch ) ) {
5192 + synth_delay( synth_full_time );
5193 + return;
5194 + }
5195 + synth_buff_out++;
5196 + if ( ch == '[' ) in_escape = 1;
5197 + else if ( ch == ']' ) in_escape = 0;
5198 + else if ( ch <= SPACE ) {
5199 + if ( !in_escape && strchr( ",.!?;:", last ) )
5200 + spk_serial_out( PROCSPEECH );
5201 + if ( jiffies >= jiff_max ) {
5202 + if ( !in_escape )
5203 + spk_serial_out( PROCSPEECH );
5204 + synth_delay( synth_delay_time );
5205 + return;
5206 + }
5207 + }
5208 + last = ch;
5209 + }
5210 + if ( synth_done( ) || !in_escape )
5211 + spk_serial_out( PROCSPEECH );
5212 +}
5213 +
5214 +static char *synth_immediate ( char *buf )
5215 +{
5216 + u_char ch;
5217 + while ( ( ch = *buf ) ) {
5218 + if ( ch == 0x0a ) ch = PROCSPEECH;
5219 + if ( wait_for_xmitr( ) )
5220 + outb( ch, synth_port_tts );
5221 + else return buf;
5222 + buf++;
5223 + }
5224 + return 0;
5225 +}
5226 +
5227 +static void synth_flush( void )
5228 +{
5229 + in_escape = 0;
5230 + synth_immediate( "\033P;10z\033\\" );
5231 +}
5232 +
5233 +static int serprobe( int index )
5234 +{
5235 + u_char test=0;
5236 + struct serial_state *ser = spk_serial_init( index );
5237 + if ( ser == NULL ) return -1;
5238 + /* ignore any error results, if port was forced */
5239 + if ( synth_port_forced )
5240 + return 0;
5241 + synth_immediate( "\033[;5n\033\\" );
5242 + if ( ( test = spk_serial_in( ) ) == '\033' )
5243 + return 0;
5244 + spk_serial_release( );
5245 + timeouts = synth_alive = synth_port_tts = 0; /* not ignoring */
5246 + return -1;
5247 +}
5248 +
5249 +static int synth_probe( void )
5250 +{
5251 + int i=0, failed=0;
5252 + pr_info( "Probing for %s.\n", synth->long_name );
5253 + /* check ttyS0-ttyS3 */
5254 + for ( i=SPK_LO_TTY; i <= SPK_HI_TTY; i++ ) {
5255 + if (( failed = serprobe( i )) == 0 ) break; /* found it */
5256 + }
5257 + if ( failed ) {
5258 + pr_info( "%s: not found\n", synth->long_name );
5259 + return -ENODEV;
5260 + }
5261 + pr_info( "%s: %03x-%03x, Driver Version %s,\n", synth->long_name,
5262 + synth_port_tts, synth_port_tts+7, synth->version );
5263 + return 0;
5264 +}
5265 +
5266 +static int synth_is_alive( void )
5267 +{
5268 + if ( synth_alive ) return 1;
5269 + if ( !synth_alive&& wait_for_xmitr( ) > 0 ) { /* restart */
5270 + synth_alive = 1;
5271 + synth_write_string( synth->init );
5272 + return 2;
5273 + }
5274 + pr_warn( "%s: can't restart synth\n", synth->long_name );
5275 + return 0;
5276 +}
5277 +
5278 +static const char init_string[] = "[:pe -380]";
5279 +
5280 +static string_var stringvars[] = {
5281 + { CAPS_START, "[:dv ap 222]" },
5282 + { CAPS_STOP, "[:dv ap 100]" },
5283 + V_LAST_STRING
5284 +};
5285 +static num_var numvars[] = {
5286 + { RATE, "[:ra %d]", 7, 0, 9, 150, 25, 0 },
5287 + { PITCH, "[:dv ap %d]", 100, 0, 100, 0, 0, 0 },
5288 + { VOL, "[:dv gv %d]", 13, 0, 16, 0, 5, 0 },
5289 + { PUNCT, "[:pu %c]", 0, 0, 2, 0, 0, "nsa" },
5290 + { VOICE, "[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" },
5291 + V_LAST_NUM
5292 +};
5293 +
5294 +struct spk_synth synth_decext = {"decext", "1.1", "Dectalk External",
5295 + init_string, 500, 50, 50, 1000, 0, SF_DEC, SYNTH_CHECK,
5296 + stringvars, numvars, synth_probe, spk_serial_release, synth_immediate,
5297 + do_catch_up, NULL, synth_flush, synth_is_alive, NULL};
5298 +
5299 +#ifdef MODULE
5300 +#include "mod_code.c"
5301 +#endif
5302 unchanged:
5303 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
5304 +++ gregkh-2.6/drivers/char/speakup/speakup_decpc.c 2005-07-27 13:02:57.000000000 -0700
5305 @@ -0,0 +1,242 @@
5306 +/*
5307 +* written by David Borowski, david575@golden.net
5308 +
5309 + Copyright (C) 2003 David Borowski.
5310 +
5311 + This program is free software; you can redistribute it and/or modify
5312 + it under the terms of the GNU General Public License as published by
5313 + the Free Software Foundation; either version 2 of the License, or
5314 + (at your option) any later version.
5315 +
5316 + This program is distributed in the hope that it will be useful,
5317 + but WITHOUT ANY WARRANTY; without even the implied warranty of
5318 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5319 + GNU General Public License for more details.
5320 +
5321 + You should have received a copy of the GNU General Public License
5322 + along with this program; if not, write to the Free Software
5323 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5324 +
5325 + * this code is specificly written as a driver for the speakup screenreview
5326 + * package and is not a general device driver.
5327 + */
5328 +#include "spk_priv.h"
5329 +#include "dtpc_reg.h"
5330 +
5331 +#define MY_SYNTH synth_dec_pc
5332 +#define PROCSPEECH 0x0b
5333 +#define SYNTH_IO_EXTENT 8
5334 +
5335 +static int synth_portlist[] = { 0x340, 0x350, 0x240, 0x250, 0 };
5336 +static int in_escape = 0, is_flushing = 0;
5337 +static int dt_stat, dma_state = 0;
5338 +
5339 +static inline int dt_getstatus( void )
5340 +{
5341 + dt_stat = inb_p( synth_port_tts )|(inb_p( synth_port_tts+1 )<<8);
5342 + return dt_stat;
5343 +}
5344 +
5345 +static inline void dt_sendcmd( u_int cmd )
5346 +{
5347 + outb_p( cmd & 0xFF, synth_port_tts );
5348 + outb_p( (cmd>>8) & 0xFF, synth_port_tts+1 );
5349 +}
5350 +
5351 +static int dt_waitbit( int bit )
5352 +{
5353 + int timeout = 100;
5354 + while ( --timeout > 0 ) {
5355 + if( (dt_getstatus( ) & bit ) == bit ) return 1;
5356 + udelay( 50 );
5357 + }
5358 + return 0;
5359 +}
5360 +
5361 +static int dt_wait_dma( void )
5362 +{
5363 + int timeout = 100, state = dma_state;
5364 + if( ! dt_waitbit( STAT_dma_ready ) ) return 0;
5365 + while ( --timeout > 0 ) {
5366 + if( (dt_getstatus()&STAT_dma_state) == state ) return 1;
5367 + udelay( 50 );
5368 + }
5369 + dma_state = dt_getstatus( ) & STAT_dma_state;
5370 + return 1;
5371 +}
5372 +
5373 +int dt_ctrl( u_int cmd )
5374 +{
5375 + int timeout = 10;
5376 + if ( !dt_waitbit( STAT_cmd_ready ) ) return -1;
5377 + outb_p( 0, synth_port_tts+2 );
5378 + outb_p( 0, synth_port_tts+3 );
5379 + dt_getstatus( );
5380 + dt_sendcmd( CMD_control|cmd );
5381 + outb_p( 0, synth_port_tts+6 );
5382 + while ( dt_getstatus( ) & STAT_cmd_ready ) {
5383 + udelay( 20 );
5384 + if ( --timeout == 0 ) break;
5385 + }
5386 + dt_sendcmd( CMD_null );
5387 + return 0;
5388 +}
5389 +
5390 +static void synth_flush( void )
5391 +{
5392 + int timeout = 10;
5393 + if ( is_flushing ) return;
5394 + is_flushing = 4;
5395 + in_escape = 0;
5396 + while ( dt_ctrl( CTRL_flush ) ) {
5397 + if ( --timeout == 0 ) break;
5398 +udelay( 50 );
5399 + }
5400 + for ( timeout = 0; timeout < 10; timeout++ ) {
5401 + if ( dt_waitbit( STAT_dma_ready ) ) break;
5402 +udelay( 50 );
5403 + }
5404 + outb_p( DMA_sync, synth_port_tts+4 );
5405 + outb_p( 0, synth_port_tts+4 );
5406 + udelay( 100 );
5407 + for ( timeout = 0; timeout < 10; timeout++ ) {
5408 + if ( !( dt_getstatus( ) & STAT_flushing ) ) break;
5409 +udelay( 50 );
5410 + }
5411 + dma_state = dt_getstatus( ) & STAT_dma_state;
5412 + dma_state ^= STAT_dma_state;
5413 + is_flushing = 0;
5414 +}
5415 +
5416 +static int dt_sendchar( char ch )
5417 +{
5418 + if( ! dt_wait_dma( ) ) return -1;
5419 + if( ! (dt_stat & STAT_rr_char) ) return -2;
5420 + outb_p( DMA_single_in, synth_port_tts+4 );
5421 + outb_p( ch, synth_port_tts+4 );
5422 + dma_state ^= STAT_dma_state;
5423 + return 0;
5424 +}
5425 +
5426 +static int testkernel( void )
5427 +{
5428 + int status = 0;
5429 + if ( dt_getstatus( ) == 0xffff ) {
5430 + status = -1;
5431 + goto oops;
5432 + }
5433 + dt_sendcmd( CMD_sync );
5434 + if( ! dt_waitbit( STAT_cmd_ready ) ) status = -2;
5435 + else if ( ( dt_stat&0x8000 ) ) {
5436 + return 0;
5437 + } else if ( dt_stat == 0x0dec )
5438 + pr_warn( "dec_pc at 0x%x, software not loaded\n", synth_port_tts );
5439 + status = -3;
5440 +oops: synth_release_region( synth_port_tts, SYNTH_IO_EXTENT );
5441 + synth_port_tts = 0;
5442 + return status;
5443 +}
5444 +
5445 +static void do_catch_up( unsigned long data )
5446 +{
5447 + unsigned long jiff_max = jiffies+synth_jiffy_delta;
5448 + u_char ch;
5449 +static u_char last='\0';