[kernel] r16310 - in dists/sid/linux-2.6/debian: . patches/features/all/speakup patches/series

Ben Hutchings benh at alioth.debian.org
Sat Sep 18 16:49:03 UTC 2010


Author: benh
Date: Sat Sep 18 16:48:53 2010
New Revision: 16310

Log:
speakup: Update to match Debian package version 3.1.5.dfsg.1-1

Added:
   dists/sid/linux-2.6/debian/patches/features/all/speakup/speakup-3.1.5.dfsg.1-1.patch
   dists/sid/linux-2.6/debian/patches/series/24
Modified:
   dists/sid/linux-2.6/debian/changelog

Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog	Sat Sep 18 16:48:22 2010	(r16309)
+++ dists/sid/linux-2.6/debian/changelog	Sat Sep 18 16:48:53 2010	(r16310)
@@ -1,3 +1,10 @@
+linux-2.6 (2.6.32-24) UNRELEASED; urgency=low
+
+  [ Ben Hutchings ]
+  * speakup: Update to match Debian package version 3.1.5.dfsg.1-1
+
+ -- Ben Hutchings <ben at decadent.org.uk>  Sat, 18 Sep 2010 17:29:34 +0100
+
 linux-2.6 (2.6.32-23) unstable; urgency=low
 
   [ Ben Hutchings ]

Added: dists/sid/linux-2.6/debian/patches/features/all/speakup/speakup-3.1.5.dfsg.1-1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/speakup/speakup-3.1.5.dfsg.1-1.patch	Sat Sep 18 16:48:53 2010	(r16310)
@@ -0,0 +1,1067 @@
+Subject: [PATCH] Update speakup from 3.1.3-3 to 3.1.5.dfsg.1-1
+
+diff -u a/drivers/staging/speakup/i18n.c b/drivers/staging/speakup/i18n.c
+--- a/drivers/staging/speakup/i18n.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/i18n.c	2010-07-22 15:06:52.000000000 +0100
+@@ -1,6 +1,7 @@
+ /* Internationalization implementation.  Includes definitions of English
+  * string arrays, and the i18n pointer. */
+ 
++#include <linux/slab.h>		/* For kmalloc. */
+ #include <linux/ctype.h>
+ #include <linux/module.h>
+ #include <linux/string.h>
+diff -u a/drivers/staging/speakup/Kbuild b/drivers/staging/speakup/Kbuild
+--- a/drivers/staging/speakup/Kbuild	2009-10-04 16:44:13.000000000 +0100
++++ b/drivers/staging/speakup/Kbuild	2010-09-18 17:20:01.000000000 +0100
+@@ -19,6 +19,7 @@
+ 	buffers.o \
+ 	devsynth.o \
+ 	i18n.o \
++	fakekey.o \
+ 	main.o \
+ 	keyhelp.o \
+ 	kobjects.o \
+diff -u a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
+--- a/drivers/staging/speakup/kobjects.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/kobjects.c	2010-07-22 15:06:52.000000000 +0100
+@@ -11,6 +11,7 @@
+  * Released under the GPL version 2 only.
+  *
+  */
++#include <linux/slab.h>		/* For kmalloc. */
+ #include <linux/kernel.h>
+ #include <linux/kobject.h>
+ #include <linux/string.h>
+@@ -643,6 +644,26 @@
+ 			param->name, (int)param->var_type);
+ 	break;
+ 	}
++	/*
++	 * If voice was just changed, we might need to reset our default
++	 * pitch and volume.
++	 */
++	if (strcmp(attr->attr.name, "voice") == 0) {
++		if (synth && synth->default_pitch) {
++			param = var_header_by_name("pitch");
++			if (param)  {
++				set_num_var(synth->default_pitch[value], param, E_NEW_DEFAULT);
++				set_num_var(0, param, E_DEFAULT);
++			}
++		}
++		if (synth && synth->default_vol) {
++			param = var_header_by_name("vol");
++			if (param)  {
++				set_num_var(synth->default_vol[value], param, E_NEW_DEFAULT);
++				set_num_var(0, param, E_DEFAULT);
++			}
++		}
++	}
+ 	spk_unlock(flags);
+ 
+ 	if (ret == SET_DEFAULT)
+diff -u a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
+--- a/drivers/staging/speakup/main.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/main.c	2010-07-22 15:06:52.000000000 +0100
+@@ -115,9 +115,6 @@
+ #define read_all_mode CT_Max
+ 
+ static struct tty_struct *tty;
+-typedef void (*k_handler_fn)(struct vc_data *vc, unsigned char value,
+-			     char up_flag);
+-extern k_handler_fn k_handler[16];
+ 
+ static void spkup_write(const char *in_buf, int count);
+ 
+@@ -220,6 +217,7 @@
+ };
+ 
+ struct task_struct *speakup_task;
++struct bleep unprocessed_sound;
+ static int spk_keydown;
+ static u_char spk_lastkey, spk_close_press, keymap_flags;
+ static u_char last_keycode, this_speakup_key;
+@@ -267,7 +265,10 @@
+ 	freq = vals[val%12];
+ 	if (val > 11)
+ 		freq *= (1 << (val/12));
+-	kd_mksound(freq, msecs_to_jiffies(time));
++	unprocessed_sound.freq = freq;
++	unprocessed_sound.jiffies = msecs_to_jiffies(time);
++	unprocessed_sound.active = 1;
++	/* We can only have 1 active sound at a time. */
+ }
+ 
+ static void speakup_shut_up(struct vc_data *vc)
+@@ -445,7 +446,7 @@
+ 		if (w & vc->vc_hi_font_mask)
+ 			c |= 0x100;
+ 
+-		ch = inverse_translate(vc, c);
++		ch = inverse_translate(vc, c, 0);
+ 		*attribs = (w & 0xff00) >> 8;
+ 	}
+ 	return ch;
+@@ -1307,11 +1308,10 @@
+ };
+ 
+ static void
+-kbd_fakekey2(struct vc_data *vc, int v, int command)
++kbd_fakekey2(struct vc_data *vc, int command)
+ {
+ 	del_timer(&cursor_timer);
+-	k_handler[KT_CUR](vc, v, 0);
+-	k_handler[KT_CUR](vc, v, 1);
++	speakup_fake_down_arrow();
+ 	start_read_all_timer(vc, command);
+ }
+ 
+@@ -1327,7 +1327,7 @@
+ 	cursor_track = read_all_mode;
+ 	reset_index_count(0);
+ 	if (get_sentence_buf(vc, 0) == -1)
+-		kbd_fakekey2(vc, 0, RA_DOWN_ARROW);
++		kbd_fakekey2(vc, RA_DOWN_ARROW);
+ 	else {
+ 		say_sentence_num(0, 0);
+ 		synth_insert_next_index(0);
+@@ -1368,7 +1368,7 @@
+ 		reset_index_count(sentcount+1);
+ 		if (indcount == 1) {
+ 			if (!say_sentence_num(sentcount+1, 0)) {
+-				kbd_fakekey2(vc, 0, RA_FIND_NEXT_SENT);
++				kbd_fakekey2(vc, RA_FIND_NEXT_SENT);
+ 				return;
+ 			}
+ 			synth_insert_next_index(0);
+@@ -1380,7 +1380,7 @@
+ 			} else
+ 				synth_insert_next_index(0);
+ 			if (!say_sentence_num(sn, 0)) {
+-				kbd_fakekey2(vc, 0, RA_FIND_NEXT_SENT);
++				kbd_fakekey2(vc, RA_FIND_NEXT_SENT);
+ 				return;
+ 			}
+ 			synth_insert_next_index(0);
+@@ -1396,7 +1396,7 @@
+ 		break;
+ 	case RA_DOWN_ARROW:
+ 		if (get_sentence_buf(vc, 0) == -1) {
+-			kbd_fakekey2(vc, 0, RA_DOWN_ARROW);
++			kbd_fakekey2(vc, RA_DOWN_ARROW);
+ 		} else {
+ 			say_sentence_num(0, 0);
+ 			synth_insert_next_index(0);
+@@ -1408,7 +1408,7 @@
+ 		if (rv == -1)
+ 			read_all_doc(vc);
+ 		if (rv == 0)
+-			kbd_fakekey2(vc, 0, RA_FIND_NEXT_SENT);
++			kbd_fakekey2(vc, RA_FIND_NEXT_SENT);
+ 		else {
+ 			say_sentence_num(1, 0);
+ 			synth_insert_next_index(0);
+@@ -1420,7 +1420,7 @@
+ 	case RA_TIMER:
+ 		get_index_count(&indcount, &sentcount);
+ 		if (indcount < 2)
+-			kbd_fakekey2(vc, 0, RA_DOWN_ARROW);
++			kbd_fakekey2(vc, RA_DOWN_ARROW);
+ 		else
+ 			start_read_all_timer(vc, RA_TIMER);
+ 		break;
+@@ -2123,6 +2123,19 @@
+ 
+ 	if (vc->vc_mode == KD_GRAPHICS)
+ 		return ret;
++
++	/*
++	 * First, determine whether we are handling a fake keypress on
++	 * the current processor.  If we are, then return NOTIFY_OK,
++	 * to pass the keystroke up the chain.  This prevents us from
++	 * trying to take the Speakup lock while it is held by the
++	 * processor on which the simulated keystroke was generated.
++	 * Also, the simulated keystrokes should be ignored by Speakup.
++	 */
++
++	if (speakup_fake_key_pressed())
++		return ret;
++
+ 	switch (code) {
+ 	case KBD_KEYCODE:
+ 		/* speakup requires keycode and keysym currently */
+@@ -2222,16 +2235,22 @@
+ 	for (i = 0; speakup_console[i]; i++)
+ 		kfree(speakup_console[i]);
+ 	speakup_kobj_exit();
++	speakup_remove_virtual_keyboard();
+ }
+ 
+ /* call by: module_init() */
+ static int __init speakup_init(void)
+ {
+ 	int i;
++	int err;
+ 	struct st_spk_t *first_console;
+ 	struct vc_data *vc = vc_cons[fg_console].d;
+ 	struct var_t *var;
+ 
++	err = speakup_add_virtual_keyboard();
++	if (err)
++		return err;
++
+ 	initialize_msgs(); /* Initialize arrays for i18n. */
+ 	first_console = kzalloc(sizeof(*first_console), GFP_KERNEL);
+ 	if (!first_console)
+@@ -2279,6 +2298,7 @@
+ 	return 0;
+ }
+ 
++
+ module_init(speakup_init);
+ module_exit(speakup_exit);
+ 
+diff -u a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c
+--- a/drivers/staging/speakup/selection.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/selection.c	2010-07-22 15:06:52.000000000 +0100
+@@ -1,3 +1,4 @@
++#include <linux/slab.h> /* for kmalloc */
+ #include <linux/consolemap.h>
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
+@@ -22,7 +23,7 @@
+ 
+ static unsigned char sel_pos(int n)
+ {
+-	return inverse_translate(spk_sel_cons, screen_glyph(spk_sel_cons, n));
++	return inverse_translate(spk_sel_cons, screen_glyph(spk_sel_cons, n), 0);
+ }
+ 
+ void speakup_clear_selection(void)
+diff -u a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c
+--- a/drivers/staging/speakup/serialio.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/serialio.c	2010-07-22 15:06:52.000000000 +0100
+@@ -20,6 +20,7 @@
+ 	unsigned int cval = 0;
+ 	int cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8;
+ 	struct serial_state *ser = NULL;
++	int err;
+ 
+ 	ser = rs_table + index;
+ 	/*	Divisor, bytesize and parity */
+@@ -38,8 +39,11 @@
+ 		/* try to take it back. */
+ 		printk("Ports not available, trying to steal them\n");
+ 		__release_region(&ioport_resource, ser->port, 8);
+-		if (synth_request_region(ser->port, 8))
++		err = synth_request_region(ser->port, 8);
++		if (err) {
++			pr_warn("Unable to allocate port at %x, errno %i", ser->port, err);
+ 			return NULL;
++		}
+ 	}
+ 
+ 	/*	Disable UART interrupts, set DTR and RTS high
+diff -u a/drivers/staging/speakup/speakup_acntpc.c b/drivers/staging/speakup/speakup_acntpc.c
+--- a/drivers/staging/speakup/speakup_acntpc.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_acntpc.c	2010-07-22 15:06:52.000000000 +0100
+@@ -34,7 +34,7 @@
+ #include "speakup.h"
+ #include "speakup_acnt.h" /* local header file for Accent values */
+ 
+-#define DRV_VERSION "2.9"
++#define DRV_VERSION "2.10"
+ #define synth_readable() (inb_p(synth_port_control) & SYNTH_READABLE)
+ #define synth_writable() (inb_p(synth_port_control) & SYNTH_WRITABLE)
+ #define synth_full() (inb_p(speakup_info.port_tts + UART_RX) == 'F')
+@@ -57,6 +57,7 @@
+ 	{ PITCH, .u.n = {"\033P%d", 5, 0, 9, 0, 0, NULL }},
+ 	{ VOL, .u.n = {"\033A%d", 5, 0, 9, 0, 0, NULL }},
+ 	{ TONE, .u.n = {"\033V%d", 5, 0, 9, 0, 0, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -78,6 +79,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -97,6 +100,7 @@
+ 	&tone_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+@@ -279,7 +283,7 @@
+ 	if (port_val != 0x53fc) {
+ 		/* 'S' and out&input bits */
+ 		pr_info("%s: not found\n", synth->long_name);
+-		synth_release_region(synth_portlist[i], SYNTH_IO_EXTENT);
++		synth_release_region(synth_port_control, SYNTH_IO_EXTENT);
+ 		synth_port_control = 0;
+ 		return -ENODEV;
+ 	}
+diff -u a/drivers/staging/speakup/speakup_acntsa.c b/drivers/staging/speakup/speakup_acntsa.c
+--- a/drivers/staging/speakup/speakup_acntsa.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_acntsa.c	2010-07-22 15:06:52.000000000 +0100
+@@ -27,7 +27,7 @@
+ #include "speakup.h"
+ #include "speakup_acnt.h" /* local header file for Accent values */
+ 
+-#define DRV_VERSION "2.10"
++#define DRV_VERSION "2.11"
+ #define synth_full() (inb_p(speakup_info.port_tts + UART_RX) == 'F')
+ #define PROCSPEECH '\r'
+ 
+@@ -40,6 +40,7 @@
+ 	{ PITCH, .u.n = {"\033P%d", 5, 0, 9, 0, 0, NULL }},
+ 	{ VOL, .u.n = {"\033A%d", 9, 0, 9, 0, 0, NULL }},
+ 	{ TONE, .u.n = {"\033V%d", 5, 0, 9, 0, 0, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -61,6 +62,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -80,6 +83,7 @@
+ 	&tone_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/speakup_apollo.c b/drivers/staging/speakup/speakup_apollo.c
+--- a/drivers/staging/speakup/speakup_apollo.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_apollo.c	2010-07-22 15:06:52.000000000 +0100
+@@ -31,7 +31,7 @@
+ #include "serialio.h"
+ #include "speakup.h"
+ 
+-#define DRV_VERSION "2.20"
++#define DRV_VERSION "2.21"
+ #define SYNTH_CLEAR 0x18
+ #define PROCSPEECH '\r'
+ 
+@@ -45,6 +45,7 @@
+ 	{ VOL, .u.n = {"@A%x", 10, 0, 15, 0, 0, NULL }},
+ 	{ VOICE, .u.n = {"@V%d", 1, 1, 6, 0, 0, NULL }},
+ 	{ LANG, .u.n = {"@=%d,", 1, 1, 4, 0, 0, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -68,6 +69,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -88,6 +91,7 @@
+ 	&voice_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/speakup_audptr.c b/drivers/staging/speakup/speakup_audptr.c
+--- a/drivers/staging/speakup/speakup_audptr.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_audptr.c	2010-07-22 15:06:52.000000000 +0100
+@@ -26,7 +26,7 @@
+ #include "speakup.h"
+ #include "serialio.h"
+ 
+-#define DRV_VERSION "2.10"
++#define DRV_VERSION "2.11"
+ #define SYNTH_CLEAR 0x18 /* flush synth buffer */
+ #define PROCSPEECH '\r' /* start synth processing speech char */
+ 
+@@ -41,6 +41,7 @@
+ 	{ VOL, .u.n = {"\x05[g%d]", 21, 0, 40, 0, 0, NULL }},
+ 	{ TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, 0 }},
+ 	{ PUNCT, .u.n = {"\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -64,6 +65,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -84,6 +87,7 @@
+ 	&tone_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/speakup_bns.c b/drivers/staging/speakup/speakup_bns.c
+--- a/drivers/staging/speakup/speakup_bns.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_bns.c	2010-07-22 15:06:52.000000000 +0100
+@@ -25,7 +25,7 @@
+ #include "spk_priv.h"
+ #include "speakup.h"
+ 
+-#define DRV_VERSION "2.10"
++#define DRV_VERSION "2.11"
+ #define SYNTH_CLEAR 0x18
+ #define PROCSPEECH '\r'
+ 
+@@ -36,6 +36,7 @@
+ 	{ PITCH, .u.n = {"\x05%dP", 8, 0, 16, 0, 0, NULL }},
+ 	{ VOL, .u.n = {"\x05%dV", 8, 0, 16, 0, 0, NULL }},
+ 	{ TONE, .u.n = {"\x05%dT", 8, 0, 16, 0, 0, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -57,6 +58,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -76,6 +79,7 @@
+ 	&tone_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/speakup_decext.c b/drivers/staging/speakup/speakup_decext.c
+--- a/drivers/staging/speakup/speakup_decext.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_decext.c	2010-07-22 15:06:52.000000000 +0100
+@@ -31,7 +31,7 @@
+ #include "serialio.h"
+ #include "speakup.h"
+ 
+-#define DRV_VERSION "2.13"
++#define DRV_VERSION "2.14"
+ #define SYNTH_CLEAR 0x03
+ #define PROCSPEECH 0x0b
+ static unsigned char last_char;
+@@ -52,6 +52,7 @@
+ 	{ VOL, .u.n = {"[:dv gv %d]", 13, 0, 16, 0, 5, NULL }},
+ 	{ PUNCT, .u.n = {"[:pu %c]", 0, 0, 2, 0, 0, "nsa" }},
+ 	{ VOICE, .u.n = {"[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -75,6 +76,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -95,6 +98,7 @@
+ 	&voice_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c
+--- a/drivers/staging/speakup/speakup_dectlk.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_dectlk.c	2010-07-22 15:06:52.000000000 +0100
+@@ -33,7 +33,7 @@
+ #include "spk_priv.h"
+ #include "serialio.h"
+ 
+-#define DRV_VERSION "2.15"
++#define DRV_VERSION "2.20"
+ #define SYNTH_CLEAR 0x03
+ #define PROCSPEECH 0x0b
+ static volatile int xoff;
+@@ -51,13 +51,14 @@
+ static DECLARE_WAIT_QUEUE_HEAD(flush);
+ 
+ static struct var_t vars[] = {
+-	{ CAPS_START, .u.s = {"[:dv ap 200]" }},
+-	{ CAPS_STOP, .u.s = {"[:dv ap 100]" }},
+-	{ RATE, .u.n = {"[:ra %d]", 9, 0, 18, 150, 25, NULL }},
+-	{ PITCH, .u.n = {"[:dv ap %d]", 80, 0, 200, 20, 0, NULL }},
+-	{ VOL, .u.n = {"[:dv gv %d]", 13, 0, 14, 0, 5, NULL }},
+-	{ PUNCT, .u.n = {"[:pu %c]", 0, 0, 2, 0, 0, "nsa" }},
+-	{ VOICE, .u.n = {"[:n%c]", 0, 0, 9, 0, 0, "phfdburwkv" }},
++	{ CAPS_START, .u.s = {"[:dv ap 160] " }},
++	{ CAPS_STOP, .u.s = {"[:dv ap 100 ] " }},
++	{ RATE, .u.n = {"[:ra %d] ", 180, 75, 650, 0, 0, NULL }},
++	{ PITCH, .u.n = {"[:dv ap %d] ", 122, 50, 350, 0, 0, NULL }},
++	{ VOL, .u.n = {"[:dv g5 %d] ", 86, 60, 86, 0, 0, NULL }},
++	{ PUNCT, .u.n = {"[:pu %c] ", 0, 0, 2, 0, 0, "nsa" }},
++	{ VOICE, .u.n = {"[:n%c] ", 0, 0, 9, 0, 0, "phfdburwkv" }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -81,6 +82,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -101,17 +104,21 @@
+ 	&voice_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+ 	NULL,	/* need to NULL terminate the list of attributes */
+ };
+ 
++static int ap_defaults[] = {122, 89, 155, 110, 208, 240, 200, 106, 306};
++static int g5_defaults[] = {86, 81, 86, 84, 81, 80, 83, 83, 73};
++
+ static struct spk_synth synth_dectlk = {
+ 	.name = "dectlk",
+ 	.version = DRV_VERSION,
+ 	.long_name = "Dectalk Express",
+-	.init = "[:dv ap 100][:error sp]",
++	.init = "[:error sp :name paul :rate 180 :tsr off] ",
+ 	.procspeech = PROCSPEECH,
+ 	.clear = SYNTH_CLEAR,
+ 	.delay = 500,
+@@ -121,6 +128,8 @@
+ 	.startup = SYNTH_START,
+ 	.checkval = SYNTH_CHECK,
+ 	.vars = vars,
++	.default_pitch = ap_defaults,
++	.default_vol = g5_defaults,
+ 	.probe = serial_synth_probe,
+ 	.release = spk_serial_release,
+ 	.synth_immediate = spk_synth_immediate,
+@@ -131,7 +140,7 @@
+ 	.read_buff_add = read_buff_add,
+ 	.get_index = get_index,
+ 	.indexing = {
+-		.command = "[:in re %d] ",
++		.command = "[:in re %d ] ",
+ 		.lowindex = 1,
+ 		.highindex = 8,
+ 		.currindex = 1,
+diff -u a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c
+--- a/drivers/staging/speakup/speakup_dtlk.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_dtlk.c	2010-07-22 15:06:52.000000000 +0100
+@@ -33,7 +33,7 @@
+ #include "speakup_dtlk.h" /* local header file for DoubleTalk values */
+ #include "speakup.h"
+ 
+-#define DRV_VERSION "2.9"
++#define DRV_VERSION "2.10"
+ #define PROCSPEECH 0x00
+ #define synth_readable() ((synth_status = inb_p(speakup_info.port_tts + UART_RX)) & TTS_READABLE)
+ #define synth_writable() ((synth_status = inb_p(speakup_info.port_tts + UART_RX)) & TTS_WRITABLE)
+@@ -61,6 +61,7 @@
+ 	{ PUNCT, .u.n = {"\x01%db", 7, 0, 15, 0, 0, NULL }},
+ 	{ VOICE, .u.n = {"\x01%do", 0, 0, 7, 0, 0, NULL }},
+ 	{ FREQUENCY, .u.n = {"\x01%df", 5, 0, 9, 0, 0, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -88,6 +89,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -110,6 +113,7 @@
+ 	&voice_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+@@ -309,6 +313,8 @@
+ 		speakup_info.port_tts = port_forced;
+ 		pr_info("probe forced to %x by kernel command line\n",
+ 				speakup_info.port_tts);
++		if ((port_forced & 0xf) != 0xf)
++			pr_info("warning: port base should probably end with f\n");
+ 		if (synth_request_region(speakup_info.port_tts-1,
+ 					SYNTH_IO_EXTENT)) {
+ 			pr_warn("sorry, port already reserved\n");
+@@ -334,6 +340,7 @@
+ 	port_val &= 0xfbff;
+ 	if (port_val != 0x107f) {
+ 		pr_info("DoubleTalk PC: not found\n");
++		synth_release_region(synth_lpc, SYNTH_IO_EXTENT);
+ 		return -ENODEV;
+ 	}
+ 	while (inw_p(synth_lpc) != 0x147f)
+diff -u a/drivers/staging/speakup/speakup_dummy.c b/drivers/staging/speakup/speakup_dummy.c
+--- a/drivers/staging/speakup/speakup_dummy.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_dummy.c	2010-07-22 15:06:52.000000000 +0100
+@@ -28,7 +28,7 @@
+ #include "speakup.h"
+ 
+ #define PROCSPEECH '\n'
+-#define DRV_VERSION "2.10"
++#define DRV_VERSION "2.11"
+ #define SYNTH_CLEAR '!'
+ 
+ static struct var_t vars[] = {
+@@ -38,6 +38,7 @@
+ 	{ PITCH, .u.n = {"PITCH %d\n", 8, 0, 16, 0, 0, NULL }},
+ 	{ VOL, .u.n = {"VOL %d\n", 8, 0, 16, 0, 0, NULL }},
+ 	{ TONE, .u.n = {"TONE %d\n", 8, 0, 16, 0, 0, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -59,6 +60,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -78,6 +81,7 @@
+ 	&tone_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h
+--- a/drivers/staging/speakup/speakup.h	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup.h	2010-07-22 15:06:52.000000000 +0100
+@@ -5,7 +5,7 @@
+ #include "spk_types.h"
+ #include "i18n.h"
+ 
+-#define SPEAKUP_VERSION "3.1.3"
++#define SPEAKUP_VERSION "3.1.5"
+ #define KEY_MAP_VER 119
+ #define SHIFT_TBL_SIZE 64
+ #define MAX_DESC_LEN 72
+@@ -41,10 +41,6 @@
+ #define B_SYM 0x0800
+ #define B_CAPSYM (B_CAP|B_SYM)
+ 
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+-#define inverse_translate(vc, c) inverse_translate(vc, c, 0)
+-#endif
+-
+ #define IS_WDLM(x) (spk_chartab[((u_char)x)]&B_WDLM)
+ #define IS_CHAR(x, type) (spk_chartab[((u_char)x)]&type)
+ #define IS_TYPE(x, type) ((spk_chartab[((u_char)x)]&type) == type)
+@@ -121,4 +117,11 @@
+ extern int quiet_boot;
+ extern char *synth_name;
++extern struct bleep unprocessed_sound;
++
++/* Prototypes from fakekey.c. */
++int speakup_add_virtual_keyboard(void);
++void speakup_remove_virtual_keyboard(void);
++void speakup_fake_down_arrow(void);
++bool speakup_fake_key_pressed(void);
+ 
+ #endif
+diff -u a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c
+--- a/drivers/staging/speakup/speakup_keypc.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_keypc.c	2010-07-22 15:06:52.000000000 +0100
+@@ -30,7 +30,7 @@
+ #include "spk_priv.h"
+ #include "speakup.h"
+ 
+-#define DRV_VERSION "2.9"
++#define DRV_VERSION "2.10"
+ #define SYNTH_IO_EXTENT	0x04
+ #define SWAIT udelay(70)
+ #define synth_writable() (inb_p(synth_port + UART_RX) & 0x10)
+@@ -54,6 +54,7 @@
+ 	{ CAPS_STOP, .u.s = {"[f90]" }},
+ 	{ RATE, .u.n = {"\04%c ", 8, 0, 10, 81, -8, NULL }},
+ 	{ PITCH, .u.n = {"[f%d]", 5, 0, 9, 40, 10, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -71,6 +72,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -88,6 +91,7 @@
+ 	&pitch_attribute.attr,
+ 	&rate_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+@@ -280,7 +284,7 @@
+ 	}
+ 	if (port_val != 0x80) {
+ 		pr_info("%s: not found\n", synth->long_name);
+-		synth_release_region(synth_portlist[i], SYNTH_IO_EXTENT);
++		synth_release_region(synth_port, SYNTH_IO_EXTENT);
+ 		synth_port = 0;
+ 		return -ENODEV;
+ 	}
+diff -u a/drivers/staging/speakup/speakup_ltlk.c b/drivers/staging/speakup/speakup_ltlk.c
+--- a/drivers/staging/speakup/speakup_ltlk.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_ltlk.c	2010-07-22 15:06:52.000000000 +0100
+@@ -27,7 +27,7 @@
+ #include "serialio.h"
+ #include "speakup_dtlk.h" /* local header file for LiteTalk values */
+ 
+-#define DRV_VERSION "2.10"
++#define DRV_VERSION "2.11"
+ #define synth_full( ) ( !( inb( synth_port_tts + UART_MSR ) & UART_MSR_CTS ) )
+ #define PROCSPEECH 0x0d
+ 
+@@ -43,6 +43,7 @@
+ 	{ PUNCT, .u.n = {"\x01%db", 7, 0, 15, 0, 0, NULL }},
+ 	{ VOICE, .u.n = {"\x01%do", 0, 0, 7, 0, 0, NULL }},
+ 	{ FREQUENCY, .u.n = {"\x01%df", 5, 0, 9, 0, 0, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -70,6 +71,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -92,6 +95,7 @@
+ 	&voice_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c
+--- a/drivers/staging/speakup/speakup_soft.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_soft.c	2010-07-22 15:06:52.000000000 +0100
+@@ -24,7 +24,7 @@
+ #include <linux/unistd.h>
+ #include <linux/miscdevice.h> /* for misc_register, and SYNTH_MINOR */
+ #include <linux/poll.h> /* for poll_wait() */
+-#include <linux/sched.h>
++#include <linux/sched.h> /* schedule(), signal_pending(), TASK_INTERRUPTIBLE */
+ 
+ #include "spk_priv.h"
+ #include "speakup.h"
+diff -u a/drivers/staging/speakup/speakup_spkout.c b/drivers/staging/speakup/speakup_spkout.c
+--- a/drivers/staging/speakup/speakup_spkout.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_spkout.c	2010-07-22 15:06:52.000000000 +0100
+@@ -26,7 +26,7 @@
+ #include "speakup.h"
+ #include "serialio.h"
+ 
+-#define DRV_VERSION "2.10"
++#define DRV_VERSION "2.11"
+ #define SYNTH_CLEAR 0x18
+ #define PROCSPEECH '\r'
+ 
+@@ -40,6 +40,7 @@
+ 	{ VOL, .u.n = {"\x05V%d", 9, 0, 9, 0, 0, NULL }},
+ 	{ TONE, .u.n = {"\x05T%c", 8, 0, 25, 65, 0, NULL }},
+ 	{ PUNCT, .u.n = {"\x05M%c", 0, 0, 3, 0, 0, "nsma" }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ };
+ 
+@@ -63,6 +64,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -83,6 +86,7 @@
+ 	&tone_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/speakup_txprt.c b/drivers/staging/speakup/speakup_txprt.c
+--- a/drivers/staging/speakup/speakup_txprt.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/speakup_txprt.c	2010-07-22 15:06:52.000000000 +0100
+@@ -25,7 +25,7 @@
+ #include "spk_priv.h"
+ #include "speakup.h"
+ 
+-#define DRV_VERSION "2.10"
++#define DRV_VERSION "2.11"
+ #define SYNTH_CLEAR 0x18
+ #define PROCSPEECH '\r' /* process speech char */
+ 
+@@ -36,6 +36,7 @@
+ 	{ PITCH, .u.n = {"\x05P%d", 5, 0, 9, 0, 0, NULL }},
+ 	{ VOL, .u.n = {"\x05V%d", 5, 0, 9, 0, 0, NULL }},
+ 	{ TONE, .u.n = {"\x05T%c", 12, 0, 25, 61, 0, NULL }},
++	{ DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL }},
+ 	V_LAST_VAR
+ 	 };
+ 
+@@ -57,6 +58,8 @@
+ 
+ static struct kobj_attribute delay_time_attribute =
+ 	__ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
++static struct kobj_attribute direct_attribute =
++	__ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+ static struct kobj_attribute full_time_attribute =
+ 	__ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+ static struct kobj_attribute jiffy_delta_attribute =
+@@ -76,6 +79,7 @@
+ 	&tone_attribute.attr,
+ 	&vol_attribute.attr,
+ 	&delay_time_attribute.attr,
++	&direct_attribute.attr,
+ 	&full_time_attribute.attr,
+ 	&jiffy_delta_attribute.attr,
+ 	&trigger_time_attribute.attr,
+diff -u a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h
+--- a/drivers/staging/speakup/spk_types.h	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/spk_types.h	2010-07-22 15:06:52.000000000 +0100
+@@ -28,7 +28,8 @@
+ 	E_DEFAULT = 0,
+ 	E_SET,
+ 	E_INC,
+-	E_DEC
++	E_DEC,
++	E_NEW_DEFAULT,
+ };
+ 
+ enum var_id_t {
+@@ -162,6 +163,8 @@
+ 	short startup;
+ 	const int checkval; /* for validating a proper synth module */
+ 	struct var_t *vars;
++	int *default_pitch;
++	int *default_vol;
+ 	int (*probe)(struct spk_synth *synth);
+ 	void (*release)(void);
+ 	const char *(*synth_immediate)(struct spk_synth *synth, const char *buff);
+@@ -184,2 +187,7 @@
+ 
++struct bleep {
++	short freq;
++	unsigned long jiffies;
++	int active;
++};
+ #endif
+diff -u a/drivers/staging/speakup/thread.c b/drivers/staging/speakup/thread.c
+--- a/drivers/staging/speakup/thread.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/thread.c	2010-07-22 15:06:52.000000000 +0100
+@@ -12,14 +12,22 @@
+ {
+ 	unsigned long flags;
+ 	int should_break;
++	struct bleep our_sound;
++
++	our_sound.active = 0;
++	our_sound.freq = 0;
++	our_sound.jiffies = 0;
+ 
+ 	mutex_lock(&spk_mutex);
+ 	while (1) {
+ 		DEFINE_WAIT(wait);
+ 		while(1) {
+ 			spk_lock(flags);
++			our_sound = unprocessed_sound;
++			unprocessed_sound.active = 0;
+ 			prepare_to_wait(&speakup_event, &wait, TASK_INTERRUPTIBLE);
+ 			should_break = kthread_should_stop() ||
++				our_sound.active ||
+ 				(synth && synth->catch_up && synth->alive &&
+ 					(speakup_info.flushing ||
+ 					!synth_buffer_empty()));
+@@ -34,6 +42,9 @@
+ 		if (kthread_should_stop())
+ 			break;
+ 
++		if (our_sound.active) {
++			kd_mksound(our_sound.freq, our_sound.jiffies);
++		}
+ 		if (synth && synth->catch_up && synth->alive) {
+ 			/* It is up to the callee to take the lock, so that it
+ 			 * can sleep whenever it likes */
+diff -u a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c
+--- a/drivers/staging/speakup/varhandlers.c	2009-08-13 01:21:12.000000000 +0100
++++ b/drivers/staging/speakup/varhandlers.c	2010-07-22 15:06:52.000000000 +0100
+@@ -186,6 +186,14 @@
+ 	struct var_t *var_data = var->data;
+ 	if (var_data == NULL)
+ 		return E_UNDEF;
++
++	if (how == E_NEW_DEFAULT) {
++		if (input < var_data->u.n.low || input > var_data->u.n.high)
++			ret = E_RANGE;
++		else
++			var_data->u.n.default_val = input;
++		return ret;
++	}
+ 	if (how == E_DEFAULT) {
+ 		val = var_data->u.n.default_val;
+ 		ret = SET_DEFAULT;
+diff -u /dev/null b/drivers/staging/speakup/varhandlers.c
+--- /dev/null
++++ b/drivers/staging/speakup/fakekey.c	2010-07-22 15:06:52.000000000 +0100
+@@ -0,0 +1,105 @@
++/* fakekey.c
++ * Functions for simulating keypresses.
++ *
++ * Copyright (C) 2010 the Speakup Team
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++#include <linux/types.h>
++#include <linux/slab.h>
++#include <linux/preempt.h>
++#include <linux/percpu.h>
++#include <linux/input.h>
++
++#include "speakup.h"
++
++#define PRESSED 1
++#define RELEASED 0
++
++DEFINE_PER_CPU(bool, reporting_keystroke);
++
++static struct input_dev *virt_keyboard;
++
++int speakup_add_virtual_keyboard(void)
++{
++	int err;
++
++	virt_keyboard = input_allocate_device();
++
++	if (!virt_keyboard)
++		return -ENOMEM;
++
++	virt_keyboard->name = "Speakup";
++	virt_keyboard->id.bustype = BUS_VIRTUAL;
++	virt_keyboard->phys = "speakup/input0";
++	virt_keyboard->dev.parent = NULL;
++
++	__set_bit(EV_KEY, virt_keyboard->evbit);
++	__set_bit(KEY_DOWN, virt_keyboard->keybit);
++
++	err = input_register_device(virt_keyboard);
++	if (err) {
++		input_free_device(virt_keyboard);
++		virt_keyboard = NULL;
++	}
++
++	return err;
++}
++
++void speakup_remove_virtual_keyboard(void)
++{
++	if (virt_keyboard != NULL) {
++		input_unregister_device(virt_keyboard);
++		input_free_device(virt_keyboard);
++		virt_keyboard = NULL;
++	}
++}
++
++/*
++	 * Send a simulated down-arrow to the application.
++	 */
++void speakup_fake_down_arrow(void)
++{
++	unsigned long flags;
++
++	/* disable keyboard interrupts */
++	local_irq_save(flags);
++	/* don't change CPU */
++	preempt_disable();
++
++	__get_cpu_var(reporting_keystroke) = true;
++	input_report_key(virt_keyboard, KEY_DOWN, PRESSED);
++	input_report_key(virt_keyboard, KEY_DOWN, RELEASED);
++	__get_cpu_var(reporting_keystroke) = false;
++
++	/* reenable preemption */
++	preempt_enable();
++	/* reenable keyboard interrupts */
++	local_irq_restore(flags);
++}
++
++/*
++	 * Are we handling a simulated keypress on the current CPU?
++	 * Returns a boolean.
++	 */
++bool speakup_fake_key_pressed(void)
++{
++	bool is_pressed;
++
++	is_pressed = get_cpu_var(reporting_keystroke);
++	put_cpu_var(reporting_keystroke);
++
++	return is_pressed;
++}

Added: dists/sid/linux-2.6/debian/patches/series/24
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/series/24	Sat Sep 18 16:48:53 2010	(r16310)
@@ -0,0 +1 @@
++ features/all/speakup/speakup-3.1.5.dfsg.1-1.patch



More information about the Kernel-svn-changes mailing list