diff options
author | William Hubbs <w.d.hubbs@gmail.com> | 2010-10-07 13:20:02 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-07 19:22:31 -0700 |
commit | c6e3fd22cd538365bfeb82997d5b89562e077d42 (patch) | |
tree | 5eaa170c9003abc7b24ab340ccabe889cba47992 /drivers/staging/speakup/fakekey.c | |
parent | e59fe083f683ca2ca56abefad290d110808a6fb5 (diff) |
Staging: add speakup to the staging directory
Speakup is a kernel based screen review package for the linux operating
system. It allows blind users to interact with applications on the
linux console by means of synthetic speech.
The authors and maintainers of this code include the following:
Kirk Reiser, Andy Berdan, John Covici, Brian and
David Borowski, Christopher Brannon, Samuel Thibault and William Hubbs.
Signed-off-by: William Hubbs <w.d.hubbs@gmail.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/speakup/fakekey.c')
-rw-r--r-- | drivers/staging/speakup/fakekey.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/staging/speakup/fakekey.c b/drivers/staging/speakup/fakekey.c new file mode 100644 index 00000000000..adb93f21c0d --- /dev/null +++ b/drivers/staging/speakup/fakekey.c @@ -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; +} |