1c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* speakup.c 216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * review functions for the speakup screen review package. 316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * originally written by: Kirk Reiser and Andy Berdan. 416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * 516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * extensively modified by David Borowski. 616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * 716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ** Copyright (C) 1998 Kirk Reiser. 816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * Copyright (C) 2003 David Borowski. 916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * 1016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * This program is free software; you can redistribute it and/or modify 1116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * it under the terms of the GNU General Public License as published by 1216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * the Free Software Foundation; either version 2 of the License, or 1316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * (at your option) any later version. 1416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * 1516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * This program is distributed in the hope that it will be useful, 1616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * but WITHOUT ANY WARRANTY; without even the implied warranty of 1716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * GNU General Public License for more details. 1916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * 2016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * You should have received a copy of the GNU General Public License 2116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * along with this program; if not, write to the Free Software 2216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs*/ 24c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 25c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/kernel.h> 26c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/vt.h> 27c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/tty.h> 2816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs#include <linux/mm.h> /* __get_free_page() and friends */ 29c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/vt_kern.h> 30c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/ctype.h> 31c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/selection.h> 32c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/unistd.h> 33c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/jiffies.h> 34c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/kthread.h> 35c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/keyboard.h> /* for KT_SHIFT */ 3616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs#include <linux/kbd_kern.h> /* for vc_kbd_* and friends */ 37c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/input.h> 38c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/kmod.h> 39c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 40c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* speakup_*_selection */ 41c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/module.h> 42c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/sched.h> 43c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/slab.h> 44c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/types.h> 45c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/consolemap.h> 46c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 47c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/spinlock.h> 48c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include <linux/notifier.h> 49c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 5016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs#include <linux/uaccess.h> /* copy_from|to|user() and others */ 51c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 52c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include "spk_priv.h" 53c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include "speakup.h" 54c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 55c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#define MAX_DELAY msecs_to_jiffies(500) 56c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#define MINECHOCHAR SPACE 57c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 58c6e3fd22cd538365bfeb82997d5b89562e077d42William HubbsMODULE_AUTHOR("Kirk Reiser <kirk@braille.uwo.ca>"); 59c6e3fd22cd538365bfeb82997d5b89562e077d42William HubbsMODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>"); 60c6e3fd22cd538365bfeb82997d5b89562e077d42William HubbsMODULE_DESCRIPTION("Speakup console speech"); 61c6e3fd22cd538365bfeb82997d5b89562e077d42William HubbsMODULE_LICENSE("GPL"); 62c6e3fd22cd538365bfeb82997d5b89562e077d42William HubbsMODULE_VERSION(SPEAKUP_VERSION); 63c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 64c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbschar *synth_name; 65c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsmodule_param_named(synth, synth_name, charp, S_IRUGO); 66ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultmodule_param_named(quiet, spk_quiet_boot, bool, S_IRUGO); 67c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 68c6e3fd22cd538365bfeb82997d5b89562e077d42William HubbsMODULE_PARM_DESC(synth, "Synth to start if speakup is built in."); 69c6e3fd22cd538365bfeb82997d5b89562e077d42William HubbsMODULE_PARM_DESC(quiet, "Do not announce when the synthesizer is found."); 70c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 71ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultspecial_func spk_special_handler; 72c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 73ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultshort spk_pitch_shift, synth_flags; 74c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic char buf[256]; 75ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultint spk_attrib_bleep, spk_bleeps, spk_bleep_time = 10; 76ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultint spk_no_intr, spk_spell_delay; 77ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultint spk_key_echo, spk_say_word_ctl; 78ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultint spk_say_ctrl, spk_bell_pos; 79ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultshort spk_punc_mask; 80ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultint spk_punc_level, spk_reading_punc; 81e7027b9b2567cd3050d266bc56a2296840dd7f68Domagoj Trsanchar spk_str_caps_start[MAXVARLEN + 1] = "\0"; 82e7027b9b2567cd3050d266bc56a2296840dd7f68Domagoj Trsanchar spk_str_caps_stop[MAXVARLEN + 1] = "\0"; 83ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultconst struct st_bits_data spk_punc_info[] = { 8416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {"none", "", 0}, 8516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {"some", "/$%&@", SOME}, 8616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {"most", "$%&#()=+*/@^<>|\\", MOST}, 8716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {"all", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", PUNC}, 8816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {"delimiters", "", B_WDLM}, 8916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {"repeats", "()", CH_RPT}, 9016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {"extended numeric", "", B_EXNUM}, 9116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {"symbols", "", B_SYM}, 92ab06e0f20ed4c4eb472a1e16f942d6e0150c00bcShalin Mehta {NULL, NULL} 93c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 9416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs 95c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic char mark_cut_flag; 96c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#define MAX_KEY 160 970012196c165d5158a128e2accd2e511a306a6aa7Sachin Kamatstatic u_char *spk_shift_table; 980012196c165d5158a128e2accd2e511a306a6aa7Sachin Kamatu_char *spk_our_keys[MAX_KEY]; 99ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultu_char spk_key_buf[600]; 100ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultconst u_char spk_key_defaults[] = { 101c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#include "speakupmap.h" 102c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 103c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 104c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* Speakup Cursor Track Variables */ 105c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int cursor_track = 1, prev_cursor_track = 1; 106c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 107c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* cursor track modes, must be ordered same as cursor_msgs */ 108c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsenum { 109c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs CT_Off = 0, 110c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs CT_On, 111c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs CT_Highlight, 112c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs CT_Window, 113c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs CT_Max 114c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 115c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs#define read_all_mode CT_Max 116c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 117c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic struct tty_struct *tty; 118c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 119c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void spkup_write(const char *in_buf, int count); 120c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 121c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic char *phonetic[] = { 122c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs "alfa", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", 12316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "india", "juliett", "keelo", "leema", "mike", "november", "oscar", 12416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "papa", 125c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs "keh beck", "romeo", "sierra", "tango", "uniform", "victer", "whiskey", 126c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs "x ray", "yankee", "zulu" 127c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 128c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 129c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* array of 256 char pointers (one for each character description) 130c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * initialized to default_chars and user selectable via 131c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * /proc/speakup/characters */ 132ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultchar *spk_characters[256]; 133c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 134ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultchar *spk_default_chars[256] = { 13516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*000*/ "null", "^a", "^b", "^c", "^d", "^e", "^f", "^g", 136c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*008*/ "^h", "^i", "^j", "^k", "^l", "^m", "^n", "^o", 137c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*016*/ "^p", "^q", "^r", "^s", "^t", "^u", "^v", "^w", 13816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*024*/ "^x", "^y", "^z", "control", "control", "control", "control", 13916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "control", 14016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*032*/ "space", "bang!", "quote", "number", "dollar", "percent", "and", 14116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "tick", 14216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*040*/ "left paren", "right paren", "star", "plus", "comma", "dash", 14316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "dot", 144c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs "slash", 145c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*048*/ "zero", "one", "two", "three", "four", "five", "six", "seven", 146c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs "eight", "nine", 147c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*058*/ "colon", "semmy", "less", "equals", "greater", "question", "at", 148c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*065*/ "EIGH", "B", "C", "D", "E", "F", "G", 149c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*072*/ "H", "I", "J", "K", "L", "M", "N", "O", 150c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*080*/ "P", "Q", "R", "S", "T", "U", "V", "W", "X", 15116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*089*/ "Y", "ZED", "left bracket", "backslash", "right bracket", 15216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "caret", 153c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs "line", 154c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*096*/ "accent", "a", "b", "c", "d", "e", "f", "g", 155c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*104*/ "h", "i", "j", "k", "l", "m", "n", "o", 156c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*112*/ "p", "q", "r", "s", "t", "u", "v", "w", 157c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*120*/ "x", "y", "zed", "left brace", "bar", "right brace", "tihlduh", 15816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*127*/ "del", "control", "control", "control", "control", "control", 15916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "control", "control", "control", "control", "control", 16016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*138*/ "control", "control", "control", "control", "control", 16116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "control", "control", "control", "control", "control", 16216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "control", "control", 16316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*150*/ "control", "control", "control", "control", "control", 16416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "control", "control", "control", "control", "control", 165c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*160*/ "nbsp", "inverted bang", 16616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*162*/ "cents", "pounds", "currency", "yen", "broken bar", "section", 16716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*168*/ "diaeresis", "copyright", "female ordinal", "double left angle", 168c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*172*/ "not", "soft hyphen", "registered", "macron", 16916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*176*/ "degrees", "plus or minus", "super two", "super three", 17016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*180*/ "acute accent", "micro", "pilcrow", "middle dot", 171c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*184*/ "cedilla", "super one", "male ordinal", "double right angle", 17216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*188*/ "one quarter", "one half", "three quarters", 17316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "inverted question", 17416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*192*/ "A GRAVE", "A ACUTE", "A CIRCUMFLEX", "A TILDE", "A OOMLAUT", 17516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "A RING", 17616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*198*/ "AE", "C CIDELLA", "E GRAVE", "E ACUTE", "E CIRCUMFLEX", 17716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "E OOMLAUT", 17816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*204*/ "I GRAVE", "I ACUTE", "I CIRCUMFLEX", "I OOMLAUT", "ETH", 17916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "N TILDE", 180c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*210*/ "O GRAVE", "O ACUTE", "O CIRCUMFLEX", "O TILDE", "O OOMLAUT", 18116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*215*/ "multiplied by", "O STROKE", "U GRAVE", "U ACUTE", 18216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "U CIRCUMFLEX", 183c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*220*/ "U OOMLAUT", "Y ACUTE", "THORN", "sharp s", "a grave", 184c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*225*/ "a acute", "a circumflex", "a tilde", "a oomlaut", "a ring", 185c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/*230*/ "ae", "c cidella", "e grave", "e acute", 18616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*234*/ "e circumflex", "e oomlaut", "i grave", "i acute", 18716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "i circumflex", 18816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*239*/ "i oomlaut", "eth", "n tilde", "o grave", "o acute", 18916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "o circumflex", 19016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs/*245*/ "o tilde", "o oomlaut", "divided by", "o stroke", "u grave", 19116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs "u acute", 192c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* 251 */ "u circumflex", "u oomlaut", "y acute", "thorn", "y oomlaut" 193c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 194c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 195c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* array of 256 u_short (one for each character) 196c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * initialized to default_chartab and user selectable via 197c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * /sys/module/speakup/parameters/chartab */ 198c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsu_short spk_chartab[256]; 199c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 200c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic u_short default_chartab[256] = { 20116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 0-7 */ 20216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_CTL, B_CTL, A_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 8-15 */ 20316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /*16-23 */ 20416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, B_CTL, /* 24-31 */ 20516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs WDLM, A_PUNC, PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* !"#$%&' */ 20616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs PUNC, PUNC, PUNC, PUNC, A_PUNC, A_PUNC, A_PUNC, PUNC, /* ()*+, -./ */ 20716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs NUM, NUM, NUM, NUM, NUM, NUM, NUM, NUM, /* 01234567 */ 20816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs NUM, NUM, A_PUNC, PUNC, PUNC, PUNC, PUNC, A_PUNC, /* 89:;<=>? */ 20916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs PUNC, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* @ABCDEFG */ 21016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* HIJKLMNO */ 21116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* PQRSTUVW */ 21216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs A_CAP, A_CAP, A_CAP, PUNC, PUNC, PUNC, PUNC, PUNC, /* XYZ[\]^_ */ 21316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs PUNC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* `abcdefg */ 21416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* hijklmno */ 21516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* pqrstuvw */ 21616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ALPHA, ALPHA, ALPHA, PUNC, PUNC, PUNC, PUNC, 0, /* xyz{|}~ */ 21716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 128-134 */ 21816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, /* 135 */ 21916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 136-142 */ 22016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_CAPSYM, /* 143 */ 22116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_CAPSYM, B_CAPSYM, B_SYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, /* 144-150 */ 22216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, /* 151 */ 22316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, B_SYM, B_CAPSYM, B_CAPSYM, B_SYM, B_SYM, B_SYM, /*152-158 */ 22416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, /* 159 */ 22516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs WDLM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_CAPSYM, /* 160-166 */ 22616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, /* 167 */ 22716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 168-175 */ 22816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 176-183 */ 22916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, B_SYM, /* 184-191 */ 23016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* 192-199 */ 23116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, /* 200-207 */ 23216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, B_SYM, /* 208-215 */ 23316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, A_CAP, ALPHA, /* 216-223 */ 23416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* 224-231 */ 23516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /* 232-239 */ 23616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, B_SYM, /* 240-247 */ 23716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA /* 248-255 */ 238c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 239c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 240c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstruct task_struct *speakup_task; 241ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultstruct bleep spk_unprocessed_sound; 242c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int spk_keydown; 243c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic u_char spk_lastkey, spk_close_press, keymap_flags; 244c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic u_char last_keycode, this_speakup_key; 245c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic u_long last_spk_jiffy; 246c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 247c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstruct st_spk_t *speakup_console[MAX_NR_CONSOLES]; 248c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 249c6e3fd22cd538365bfeb82997d5b89562e077d42William HubbsDEFINE_MUTEX(spk_mutex); 250c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 251c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int keyboard_notifier_call(struct notifier_block *, 252c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long code, void *param); 253c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 254d9f5420268ca9b2bbe62f14757fac3e10eaf1ebfSamuel Thibaultstatic struct notifier_block keyboard_notifier_block = { 255c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs .notifier_call = keyboard_notifier_call, 256c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 257c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 258c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int vt_notifier_call(struct notifier_block *, 259c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long code, void *param); 260c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 261d9f5420268ca9b2bbe62f14757fac3e10eaf1ebfSamuel Thibaultstatic struct notifier_block vt_notifier_block = { 262c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs .notifier_call = vt_notifier_call, 263c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 264c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 265c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic unsigned char get_attributes(u16 *pos) 266c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 26716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs return (u_char) (scr_readw(pos) >> 8); 268c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 269c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 270c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_date(struct vc_data *vc) 271c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 272c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = spk_cx = vc->vc_x; 273c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y = spk_cy = vc->vc_y; 274c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos = spk_cp = vc->vc_pos; 275c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_old_attr = spk_attr; 276c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_attr = get_attributes((u_short *) spk_pos); 277c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 278c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 279c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void bleep(u_short val) 280c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 281c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs static const short vals[] = { 282c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 350, 370, 392, 414, 440, 466, 491, 523, 554, 587, 619, 659 283c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs }; 284c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs short freq; 285ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault int time = spk_bleep_time; 2868e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 28716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs freq = vals[val % 12]; 288c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (val > 11) 28916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs freq *= (1 << (val / 12)); 290ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_unprocessed_sound.freq = freq; 291ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_unprocessed_sound.jiffies = msecs_to_jiffies(time); 292ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_unprocessed_sound.active = 1; 293c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* We can only have 1 active sound at a time. */ 294c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 295c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 296c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_shut_up(struct vc_data *vc) 297c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 298c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_killed) 299c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 300c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up |= 0x01; 301c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked &= 0xfe; 302c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_date(vc); 303c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (synth != NULL) 304ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 305c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 306c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 307c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speech_kill(struct vc_data *vc) 308c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 309c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char val = synth->is_alive(synth); 3108e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 311c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (val == 0) 312c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 313c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 314c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* re-enables synth, if disabled */ 315c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (val == 2 || spk_killed) { 316c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* dead */ 317c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= ~0x40; 318ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_IAM_ALIVE)); 319c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 320ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_YOU_KILLED_SPEAKUP)); 321c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up |= 0x40; 322c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 323c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 324c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 325c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_off(struct vc_data *vc) 326c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 327c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_shut_up & 0x80) { 328c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0x7f; 329ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_HEY_THATS_BETTER)); 330c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 331c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up |= 0x80; 332ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_YOU_TURNED_ME_OFF)); 333c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 334c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_date(vc); 335c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 336c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 337c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_parked(struct vc_data *vc) 338c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 339c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_parked & 0x80) { 340c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked = 0; 341ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_UNPARKED)); 342c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 343c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x80; 344ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_PARKED)); 345c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 346c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 347c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 348c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_cut(struct vc_data *vc) 349c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 350c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs static const char err_buf[] = "set selection failed"; 351c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int ret; 352c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 353c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!mark_cut_flag) { 354c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs mark_cut_flag = 1; 355ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_xs = (u_short) spk_x; 356ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_ys = (u_short) spk_y; 357c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_sel_cons = vc; 358ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_MARK)); 359c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 360c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 361ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_xe = (u_short) spk_x; 362ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_ye = (u_short) spk_y; 363c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs mark_cut_flag = 0; 364ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_CUT)); 365c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 366c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_clear_selection(); 367c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ret = speakup_set_selection(tty); 368c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 369c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs switch (ret) { 370c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case 0: 37116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs break; /* no error */ 37216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case -EFAULT: 373c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs pr_warn("%sEFAULT\n", err_buf); 374c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 37516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case -EINVAL: 376c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs pr_warn("%sEINVAL\n", err_buf); 377c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 37816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case -ENOMEM: 379c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs pr_warn("%sENOMEM\n", err_buf); 380c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 381c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 382c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 383c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 384c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_paste(struct vc_data *vc) 385c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 386c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (mark_cut_flag) { 387c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs mark_cut_flag = 0; 388ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_MARK_CLEARED)); 389c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 390ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_PASTE)); 391c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_paste_selection(tty); 392c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 393c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 394c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 395c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_attributes(struct vc_data *vc) 396c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 397c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int fg = spk_attr & 0x0f; 398c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int bg = spk_attr >> 4; 3998e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 400c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (fg > 8) { 401ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s ", spk_msg_get(MSG_BRIGHT)); 402c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs fg -= 8; 403c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 404ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_msg_get(MSG_COLORS_START + fg)); 405c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (bg > 7) { 406ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(" %s ", spk_msg_get(MSG_ON_BLINKING)); 407c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bg -= 8; 408c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else 409ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(" %s ", spk_msg_get(MSG_ON)); 410ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_COLORS_START + bg)); 411c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 412c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 413c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsenum { 414c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_top = 1, 415c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_bottom, 416c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_left, 417c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_right, 418c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_quiet 419c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 420c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 421c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void announce_edge(struct vc_data *vc, int msg_id) 422c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 423ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_bleeps & 1) 424c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bleep(spk_y); 425ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if ((spk_bleeps & 2) && (msg_id < edge_quiet)) 426ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_EDGE_MSGS_START + msg_id - 1)); 427c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 428c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 429c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speak_char(u_char ch) 430c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 431ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault char *cp = spk_characters[ch]; 432ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault struct var_t *direct = spk_get_var(DIRECT); 4338e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 434c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (direct && direct->u.n.value) { 435c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (IS_CHAR(ch, B_CAP)) { 436ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_pitch_shift++; 437ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_str_caps_start); 438c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 439c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%c", ch); 440c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (IS_CHAR(ch, B_CAP)) 441ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_str_caps_stop); 442c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 443c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 444c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cp == NULL) { 445c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs pr_info("speak_char: cp == NULL!\n"); 446c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 447c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 448c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_buffer_add(SPACE); 449c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (IS_CHAR(ch, B_CAP)) { 450ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_pitch_shift++; 451ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_str_caps_start); 452c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%s", cp); 453ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_str_caps_stop); 454c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 455c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (*cp == '^') { 456ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_msg_get(MSG_CTRL)); 457c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cp++; 458c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 459c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%s", cp); 460c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 461c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_buffer_add(SPACE); 462c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 463c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 46469d8ba56594a23af4901e109a5b9178105b863b3Lisa Nguyenstatic u16 get_char(struct vc_data *vc, u16 *pos, u_char *attribs) 465c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 466c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u16 ch = ' '; 4678e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 468c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (vc && pos) { 469c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u16 w = scr_readw(pos); 470c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u16 c = w & 0xff; 471c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 472c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (w & vc->vc_hi_font_mask) 473c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs c |= 0x100; 474c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 475c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch = inverse_translate(vc, c, 0); 476c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs *attribs = (w & 0xff00) >> 8; 477c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 478c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return ch; 479c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 480c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 481c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_char(struct vc_data *vc) 482c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 483c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_short ch; 4848e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 485c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_old_attr = spk_attr; 486c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch = get_char(vc, (u_short *) spk_pos, &spk_attr); 487c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_attr != spk_old_attr) { 488ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_attrib_bleep & 1) 489c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bleep(spk_y); 490ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_attrib_bleep & 2) 491c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_attributes(vc); 492c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 493c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speak_char(ch & 0xff); 494c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 495c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 496c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_phonetic_char(struct vc_data *vc) 497c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 498c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_short ch; 4998e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 500c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_old_attr = spk_attr; 501c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch = get_char(vc, (u_short *) spk_pos, &spk_attr); 502c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (isascii(ch) && isalpha(ch)) { 503c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch &= 0x1f; 504c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%s\n", phonetic[--ch]); 505c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 506c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (IS_CHAR(ch, B_NUM)) 507ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s ", spk_msg_get(MSG_NUMBER)); 508c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speak_char(ch); 509c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 510c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 511c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 512c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_prev_char(struct vc_data *vc) 513c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 514c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 515c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_x == 0) { 516c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs announce_edge(vc, edge_left); 517c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 518c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 519c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x--; 520c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos -= 2; 521c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_char(vc); 522c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 523c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 524c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_next_char(struct vc_data *vc) 525c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 526c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 527c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_x == vc->vc_cols - 1) { 528c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs announce_edge(vc, edge_right); 529c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 530c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 531c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x++; 532c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos += 2; 533c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_char(vc); 534c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 535c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 536c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* get_word - will first check to see if the character under the 537ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault * reading cursor is a space and if spk_say_word_ctl is true it will 538ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault * return the word space. If spk_say_word_ctl is not set it will check to 53916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * see if there is a word starting on the next position to the right 54016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * and return that word if it exists. If it does not exist it will 54116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * move left to the beginning of any previous word on the line or the 54216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * beginning off the line whichever comes first.. */ 543c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 544c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic u_long get_word(struct vc_data *vc) 545c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 546c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_long cnt = 0, tmpx = spk_x, tmp_pos = spk_pos; 547c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char ch; 548c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_short attr_ch; 549c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char temp; 5508e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 551c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_old_attr = spk_attr; 55216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ch = (char)get_char(vc, (u_short *) tmp_pos, &temp); 553c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 554c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* decided to take out the sayword if on a space (mis-information */ 555ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_say_word_ctl && ch == SPACE) { 556c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs *buf = '\0'; 557ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_SPACE)); 558c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 0; 559c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else if ((tmpx < vc->vc_cols - 2) 560c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs && (ch == SPACE || ch == 0 || IS_WDLM(ch)) 56116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs && ((char)get_char(vc, (u_short *) &tmp_pos + 1, &temp) > 56216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs SPACE)) { 563c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs tmp_pos += 2; 564c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs tmpx++; 565c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else 566c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while (tmpx > 0) { 56716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ch = (char)get_char(vc, (u_short *) tmp_pos - 1, &temp); 568c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((ch == SPACE || ch == 0 || IS_WDLM(ch)) 56916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs && ((char)get_char(vc, (u_short *) tmp_pos, &temp) > 57016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs SPACE)) 571c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 572c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs tmp_pos -= 2; 573c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs tmpx--; 574c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 575c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs attr_ch = get_char(vc, (u_short *) tmp_pos, &spk_attr); 576c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs buf[cnt++] = attr_ch & 0xff; 577c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while (tmpx < vc->vc_cols - 1) { 578c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs tmp_pos += 2; 579c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs tmpx++; 58016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ch = (char)get_char(vc, (u_short *) tmp_pos, &temp); 58116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if ((ch == SPACE) || ch == 0 58216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs || (IS_WDLM(buf[cnt - 1]) && (ch > SPACE))) 583c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 584c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs buf[cnt++] = ch; 585c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 586c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs buf[cnt] = '\0'; 587c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return cnt; 588c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 589c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 590c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_word(struct vc_data *vc) 591c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 592c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_long cnt = get_word(vc); 593ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault u_short saved_punc_mask = spk_punc_mask; 5948e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 595c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cnt == 0) 596c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 597ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_punc_mask = PUNC; 598c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs buf[cnt++] = SPACE; 599c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spkup_write(buf, cnt); 600ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_punc_mask = saved_punc_mask; 601c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 602c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 603c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_prev_word(struct vc_data *vc) 604c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 605c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char temp; 606c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char ch; 607c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_short edge_said = 0, last_state = 0, state = 0; 6088e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 609c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 610c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 611c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_x == 0) { 612c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_y == 0) { 613c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs announce_edge(vc, edge_top); 614c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 615c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 616c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y--; 617c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = vc->vc_cols; 618c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_said = edge_quiet; 619c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 620c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while (1) { 621c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_x == 0) { 622c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_y == 0) { 623c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_said = edge_top; 624c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 625c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 626c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (edge_said != edge_quiet) 627c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_said = edge_left; 628c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (state > 0) 629c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 630c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y--; 631c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = vc->vc_cols - 1; 632c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else 633c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x--; 63416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs spk_pos -= 2; 63516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ch = (char)get_char(vc, (u_short *) spk_pos, &temp); 636c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch == SPACE || ch == 0) 637c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs state = 0; 638c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else if (IS_WDLM(ch)) 639c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs state = 1; 640c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 641c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs state = 2; 642c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (state < last_state) { 643c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos += 2; 644c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x++; 645c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 646c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 647c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs last_state = state; 648c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 649c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_x == 0 && edge_said == edge_quiet) 650c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_said = edge_left; 651c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (edge_said > 0 && edge_said < edge_quiet) 652c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs announce_edge(vc, edge_said); 653c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_word(vc); 654c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 655c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 656c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_next_word(struct vc_data *vc) 657c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 658c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char temp; 659c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char ch; 660c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_short edge_said = 0, last_state = 2, state = 0; 661c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 6628e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan spk_parked |= 0x01; 663c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_x == vc->vc_cols - 1 && spk_y == vc->vc_rows - 1) { 664c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs announce_edge(vc, edge_bottom); 665c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 666c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 667c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while (1) { 66816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ch = (char)get_char(vc, (u_short *) spk_pos, &temp); 669c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch == SPACE || ch == 0) 670c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs state = 0; 671c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else if (IS_WDLM(ch)) 672c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs state = 1; 673c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 674c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs state = 2; 675c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (state > last_state) 676c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 677c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_x >= vc->vc_cols - 1) { 678c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_y == vc->vc_rows - 1) { 679c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_said = edge_bottom; 680c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 681c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 682c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs state = 0; 683c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y++; 684c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = 0; 685c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs edge_said = edge_right; 686c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else 687c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x++; 688c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos += 2; 689c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs last_state = state; 690c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 691c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (edge_said > 0) 692c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs announce_edge(vc, edge_said); 693c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_word(vc); 694c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 695c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 696c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void spell_word(struct vc_data *vc) 697c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 698c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs static char *delay_str[] = { "", ",", ".", ". .", ". . ." }; 699ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault char *cp = buf, *str_cap = spk_str_caps_stop; 700ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault char *cp1, *last_cap = spk_str_caps_stop; 701c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char ch; 7028e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 703c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!get_word(vc)) 704c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 705c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while ((ch = (u_char) *cp)) { 706c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cp != buf) 707ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(" %s ", delay_str[spk_spell_delay]); 708c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (IS_CHAR(ch, B_CAP)) { 709ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault str_cap = spk_str_caps_start; 710ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (*spk_str_caps_stop) 711ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_pitch_shift++; 71216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs else /* synth has no pitch */ 713ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault last_cap = spk_str_caps_stop; 714c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else 715ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault str_cap = spk_str_caps_stop; 716c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (str_cap != last_cap) { 717c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%s", str_cap); 718c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs last_cap = str_cap; 719c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 720c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (this_speakup_key == SPELL_PHONETIC 721c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs && (isascii(ch) && isalpha(ch))) { 722c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch &= 31; 723c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cp1 = phonetic[--ch]; 724c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 725ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault cp1 = spk_characters[ch]; 726c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (*cp1 == '^') { 727ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_msg_get(MSG_CTRL)); 728c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cp1++; 729c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 730c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 731c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%s", cp1); 732c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cp++; 733c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 734ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (str_cap != spk_str_caps_stop) 735ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_str_caps_stop); 736c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 737c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 738c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int get_line(struct vc_data *vc) 739c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 740c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_long tmp = spk_pos - (spk_x * 2); 741c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i = 0; 742c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char tmp2; 743c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 744c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_old_attr = spk_attr; 745c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_attr = get_attributes((u_short *) spk_pos); 746c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < vc->vc_cols; i++) { 747c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs buf[i] = (u_char) get_char(vc, (u_short *) tmp, &tmp2); 748c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs tmp += 2; 749c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 750c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (--i; i >= 0; i--) 751c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (buf[i] != SPACE) 752c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 753c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return ++i; 754c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 755c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 756c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_line(struct vc_data *vc) 757c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 758c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i = get_line(vc); 759c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char *cp; 760ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault u_short saved_punc_mask = spk_punc_mask; 7618e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 762c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (i == 0) { 763ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_BLANK)); 764c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 765c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 766c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs buf[i++] = '\n'; 767c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (this_speakup_key == SAY_LINE_INDENT) { 76816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs cp = buf; 76916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs while (*cp == SPACE) 77016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs cp++; 771c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%d, ", (cp - buf) + 1); 772c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 773ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_punc_mask = spk_punc_masks[spk_reading_punc]; 774c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spkup_write(buf, i); 775ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_punc_mask = saved_punc_mask; 776c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 777c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 778c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_prev_line(struct vc_data *vc) 779c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 780c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 781c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_y == 0) { 782c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs announce_edge(vc, edge_top); 783c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 784c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 785c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y--; 786c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos -= vc->vc_size_row; 787c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line(vc); 788c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 789c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 790c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_next_line(struct vc_data *vc) 791c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 792c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 793c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_y == vc->vc_rows - 1) { 794c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs announce_edge(vc, edge_bottom); 795c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 796c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 797c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y++; 798c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos += vc->vc_size_row; 799c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line(vc); 800c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 801c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 802c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int say_from_to(struct vc_data *vc, u_long from, u_long to, 803c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int read_punc) 804c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 805c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i = 0; 806c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char tmp; 807ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault u_short saved_punc_mask = spk_punc_mask; 8088e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 809c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_old_attr = spk_attr; 810c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_attr = get_attributes((u_short *) from); 811c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while (from < to) { 81216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs buf[i++] = (char)get_char(vc, (u_short *) from, &tmp); 813c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs from += 2; 814c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (i >= vc->vc_size_row) 815c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 816c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 817c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (--i; i >= 0; i--) 818c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (buf[i] != SPACE) 819c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 820c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs buf[++i] = SPACE; 821c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs buf[++i] = '\0'; 822c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (i < 1) 823c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return i; 824c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (read_punc) 825ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_punc_mask = spk_punc_info[spk_reading_punc].mask; 826c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spkup_write(buf, i); 827c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (read_punc) 828ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_punc_mask = saved_punc_mask; 829c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return i - 1; 830c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 831c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 832c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_line_from_to(struct vc_data *vc, u_long from, u_long to, 833c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int read_punc) 834c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 835c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_long start = vc->vc_origin + (spk_y * vc->vc_size_row); 836c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_long end = start + (to * 2); 8378e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 838c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start += from * 2; 839c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (say_from_to(vc, start, end, read_punc) <= 0) 840c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track != read_all_mode) 841ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_BLANK)); 842c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 843c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 844c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* Sentence Reading Commands */ 845c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 846c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int currsentence; 847c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int numsentences[2]; 848c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic char *sentbufend[2]; 849c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic char *sentmarks[2][10]; 850c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int currbuf; 851c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int bn; 852c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic char sentbuf[2][256]; 853c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 85416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic int say_sentence_num(int num, int prev) 855c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 856c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bn = currbuf; 857c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs currsentence = num + 1; 858c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (prev && --bn == -1) 859c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bn = 1; 860c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 861c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (num > numsentences[bn]) 862c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 0; 863c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 864c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spkup_write(sentmarks[bn][num], sentbufend[bn] - sentmarks[bn][num]); 865c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 866c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 867c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 868c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int get_sentence_buf(struct vc_data *vc, int read_punc) 869c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 870c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_long start, end; 871c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i, bn; 872c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char tmp; 873c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 874c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs currbuf++; 875c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (currbuf == 2) 876c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs currbuf = 0; 877c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bn = currbuf; 878c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start = vc->vc_origin + ((spk_y) * vc->vc_size_row); 87916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs end = vc->vc_origin + ((spk_y) * vc->vc_size_row) + vc->vc_cols * 2; 880c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 881c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs numsentences[bn] = 0; 882c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs sentmarks[bn][0] = &sentbuf[bn][0]; 883c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs i = 0; 884c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_old_attr = spk_attr; 885c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_attr = get_attributes((u_short *) start); 886c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 887c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while (start < end) { 88816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs sentbuf[bn][i] = (char)get_char(vc, (u_short *) start, &tmp); 889c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (i > 0) { 89016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (sentbuf[bn][i] == SPACE && sentbuf[bn][i - 1] == '.' 891c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs && numsentences[bn] < 9) { 892c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* Sentence Marker */ 893c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs numsentences[bn]++; 894c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs sentmarks[bn][numsentences[bn]] = 89516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs &sentbuf[bn][i]; 896c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 897c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 898c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs i++; 899c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start += 2; 900c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (i >= vc->vc_size_row) 901c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 902c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 903c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 904c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (--i; i >= 0; i--) 905c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (sentbuf[bn][i] != SPACE) 906c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 907c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 908c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (i < 1) 909c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 910c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 911c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs sentbuf[bn][++i] = SPACE; 912c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs sentbuf[bn][++i] = '\0'; 913c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 914c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs sentbufend[bn] = &sentbuf[bn][i]; 915c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return numsentences[bn]; 916c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 917c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 918c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_screen_from_to(struct vc_data *vc, u_long from, u_long to) 919c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 920c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_long start = vc->vc_origin, end; 9218e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 922c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (from > 0) 923c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start += from * vc->vc_size_row; 924c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (to > vc->vc_rows) 925c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs to = vc->vc_rows; 926c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs end = vc->vc_origin + (to * vc->vc_size_row); 927c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (from = start; from < end; from = to) { 928c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs to = from + vc->vc_size_row; 929c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_from_to(vc, from, to, 1); 930c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 931c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 932c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 933c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_screen(struct vc_data *vc) 934c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 935c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_screen_from_to(vc, 0, vc->vc_rows); 936c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 937c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 938c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_win_say(struct vc_data *vc) 939c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 940c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_long start, end, from, to; 9418e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 942c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (win_start < 2) { 943ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_NO_WINDOW)); 944c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 945c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 946c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start = vc->vc_origin + (win_top * vc->vc_size_row); 947c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs end = vc->vc_origin + (win_bottom * vc->vc_size_row); 948c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while (start <= end) { 949c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs from = start + (win_left * 2); 950c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs to = start + (win_right * 2); 951c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_from_to(vc, from, to, 1); 952c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start += vc->vc_size_row; 953c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 954c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 955c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 956c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void top_edge(struct vc_data *vc) 957c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 958c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 959c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos = vc->vc_origin + 2 * spk_x; 960c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y = 0; 961c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line(vc); 962c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 963c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 964c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void bottom_edge(struct vc_data *vc) 965c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 966c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 967c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos += (vc->vc_rows - spk_y - 1) * vc->vc_size_row; 968c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y = vc->vc_rows - 1; 969c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line(vc); 970c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 971c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 972c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void left_edge(struct vc_data *vc) 973c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 974c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 975c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos -= spk_x * 2; 976c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = 0; 977c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_char(vc); 978c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 979c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 980c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void right_edge(struct vc_data *vc) 981c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 982c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 983c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos += (vc->vc_cols - spk_x - 1) * 2; 984c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = vc->vc_cols - 1; 985c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_char(vc); 986c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 987c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 988c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_first_char(struct vc_data *vc) 989c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 990c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i, len = get_line(vc); 991c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char ch; 9928e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 993c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 994c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (len == 0) { 995ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_BLANK)); 996c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 997c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 998c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < len; i++) 999c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (buf[i] != SPACE) 1000c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1001c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch = buf[i]; 1002c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos -= (spk_x - i) * 2; 1003c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = i; 1004c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%d, ", ++i); 1005c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speak_char(ch); 1006c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1007c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1008c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_last_char(struct vc_data *vc) 1009c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1010c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int len = get_line(vc); 1011c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char ch; 10128e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1013c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 1014c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (len == 0) { 1015ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_BLANK)); 1016c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1017c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1018c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch = buf[--len]; 1019c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos -= (spk_x - len) * 2; 1020c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = len; 1021c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%d, ", ++len); 1022c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speak_char(ch); 1023c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1024c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1025c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_position(struct vc_data *vc) 1026c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1027ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(spk_msg_get(MSG_POS_INFO), spk_y + 1, spk_x + 1, 102816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs vc->vc_num + 1); 1029c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("\n"); 1030c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1031c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1032c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* Added by brianb */ 1033c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_char_num(struct vc_data *vc) 1034c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1035c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char tmp; 1036c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_short ch = get_char(vc, (u_short *) spk_pos, &tmp); 10378e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1038c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch &= 0xff; 1039ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(spk_msg_get(MSG_CHAR_INFO), ch, ch); 1040c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1041c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1042c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* these are stub functions to keep keyboard.c happy. */ 1043c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1044c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_from_top(struct vc_data *vc) 1045c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1046c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_screen_from_to(vc, 0, spk_y); 1047c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1048c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1049c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_to_bottom(struct vc_data *vc) 1050c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1051c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_screen_from_to(vc, spk_y, vc->vc_rows); 1052c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1053c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1054c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_from_left(struct vc_data *vc) 1055c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1056c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line_from_to(vc, 0, spk_x, 1); 1057c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1058c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1059c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void say_to_right(struct vc_data *vc) 1060c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1061c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line_from_to(vc, spk_x, vc->vc_cols, 1); 1062c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1063c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1064c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* end of stub functions. */ 1065c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1066c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void spkup_write(const char *in_buf, int count) 1067c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 106816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs static int rep_count; 1069c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs static u_char ch = '\0', old_ch = '\0'; 107016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs static u_short char_type, last_type; 1071c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int in_count = count; 10728e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1073c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown = 0; 1074c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while (count--) { 1075c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == read_all_mode) { 1076c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* Insert Sentence Index */ 1077c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((in_buf == sentmarks[bn][currsentence]) && 107816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs (currsentence <= numsentences[bn])) 1079c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_insert_next_index(currsentence++); 1080c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 108116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ch = (u_char) *in_buf++; 1082c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char_type = spk_chartab[ch]; 108316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (ch == old_ch && !(char_type & B_NUM)) { 1084c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (++rep_count > 2) 1085c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs continue; 1086c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 108716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if ((last_type & CH_RPT) && rep_count > 2) { 1088c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf(" "); 1089ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(spk_msg_get(MSG_REPEAT_DESC), 109016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ++rep_count); 1091c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf(" "); 1092c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1093c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs rep_count = 0; 1094c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1095c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch == spk_lastkey) { 1096c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs rep_count = 0; 1097ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_key_echo == 1 && ch >= MINECHOCHAR) 1098c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speak_char(ch); 1099c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else if (char_type & B_ALPHA) { 1100c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((synth_flags & SF_DEC) && (last_type & PUNC)) 1101c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_buffer_add(SPACE); 1102c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%c", ch); 1103c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else if (char_type & B_NUM) { 1104c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs rep_count = 0; 1105c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%c", ch); 1106ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault } else if (char_type & spk_punc_mask) { 1107c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speak_char(ch); 110816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs char_type &= ~PUNC; /* for dec nospell processing */ 110916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs } else if (char_type & SYNTH_OK) { 111016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs /* these are usually puncts like . and , which synth 111116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * needs for expression. 111216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * suppress multiple to get rid of long pauses and 111316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * clear repeat count 111416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * so if someone has 111516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs * repeats on you don't get nothing repeated count */ 1116c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch != old_ch) 1117c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%c", ch); 1118c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 1119c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs rep_count = 0; 1120c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 1121c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* send space and record position, if next is num overwrite space */ 1122c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (old_ch != ch) 1123c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_buffer_add(SPACE); 1124c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 1125c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs rep_count = 0; 1126c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1127c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs old_ch = ch; 1128c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs last_type = char_type; 1129c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1130c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_lastkey = 0; 1131c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (in_count > 2 && rep_count > 2) { 113216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (last_type & CH_RPT) { 1133c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf(" "); 1134ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(spk_msg_get(MSG_REPEAT_DESC2), ++rep_count); 1135c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf(" "); 1136c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1137c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs rep_count = 0; 1138c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1139c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1140c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1141c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic const int NUM_CTL_LABELS = (MSG_CTL_END - MSG_CTL_START + 1); 1142c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1143c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void read_all_doc(struct vc_data *vc); 1144c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void cursor_done(u_long data); 1145c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic DEFINE_TIMER(cursor_timer, cursor_done, 0, 0); 1146c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1147c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void do_handle_shift(struct vc_data *vc, u_char value, char up_flag) 1148c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1149c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 11508e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1151c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (synth == NULL || up_flag || spk_killed) 1152c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 11533efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_lock_irqsave(&speakup_info.spinlock, flags); 1154c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == read_all_mode) { 1155c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs switch (value) { 1156c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_SHIFT): 1157c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs del_timer(&cursor_timer); 1158c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 1159ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 1160c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs read_all_doc(vc); 1161c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1162c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_CTRL): 1163c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs del_timer(&cursor_timer); 1164c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cursor_track = prev_cursor_track; 1165c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 1166ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 1167c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1168c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1169c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 1170c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 1171ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 1172c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1173ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_say_ctrl && value < NUM_CTL_LABELS) 1174ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s", spk_msg_get(MSG_CTL_START + value)); 11753efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1176c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1177c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1178c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void do_handle_latin(struct vc_data *vc, u_char value, char up_flag) 1179c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1180c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 11818e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 11823efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_lock_irqsave(&speakup_info.spinlock, flags); 1183c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (up_flag) { 1184c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_lastkey = spk_keydown = 0; 11853efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1186c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1187c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1188c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (synth == NULL || spk_killed) { 11893efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1190c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1191c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1192c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 1193c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_lastkey = value; 1194c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown++; 1195c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked &= 0xfe; 1196ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_key_echo == 2 && value >= MINECHOCHAR) 1197c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speak_char(value); 11983efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1199c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1200c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1201ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultint spk_set_key_info(const u_char *key_info, u_char *k_buffer) 1202c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1203c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i = 0, states, key_data_len; 1204c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs const u_char *cp = key_info; 1205c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char *cp1 = k_buffer; 1206c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char ch, version, num_keys; 12078e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1208c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs version = *cp++; 1209c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (version != KEY_MAP_VER) 1210c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 1211c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs num_keys = *cp; 121216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs states = (int)cp[1]; 1213c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs key_data_len = (states + 1) * (num_keys + 1); 1214ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (key_data_len + SHIFT_TBL_SIZE + 4 >= sizeof(spk_key_buf)) 1215c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -2; 1216c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs memset(k_buffer, 0, SHIFT_TBL_SIZE); 1217ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault memset(spk_our_keys, 0, sizeof(spk_our_keys)); 1218ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_shift_table = k_buffer; 1219ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_our_keys[0] = spk_shift_table; 1220c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cp1 += SHIFT_TBL_SIZE; 1221c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs memcpy(cp1, cp, key_data_len + 3); 122216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs /* get num_keys, states and data */ 122316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs cp1 += 2; /* now pointing at shift states */ 1224c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 1; i <= states; i++) { 1225c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch = *cp1++; 1226c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch >= SHIFT_TBL_SIZE) 1227c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -3; 1228ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_shift_table[ch] = i; 1229c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1230c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs keymap_flags = *cp1++; 1231c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while ((ch = *cp1)) { 1232c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch >= MAX_KEY) 1233c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -4; 1234ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_our_keys[ch] = cp1; 1235c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cp1 += states + 1; 1236c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1237c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 0; 1238c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1239c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1240c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic struct var_t spk_vars[] = { 1241c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* bell must be first to set high limit */ 124216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {BELL_POS, .u.n = {NULL, 0, 0, 0, 0, 0, NULL} }, 124316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {SPELL_DELAY, .u.n = {NULL, 0, 0, 4, 0, 0, NULL} }, 124416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {ATTRIB_BLEEP, .u.n = {NULL, 1, 0, 3, 0, 0, NULL} }, 124516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {BLEEPS, .u.n = {NULL, 3, 0, 3, 0, 0, NULL} }, 124616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {BLEEP_TIME, .u.n = {NULL, 30, 1, 200, 0, 0, NULL} }, 124716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {PUNC_LEVEL, .u.n = {NULL, 1, 0, 4, 0, 0, NULL} }, 124816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {READING_PUNC, .u.n = {NULL, 1, 0, 4, 0, 0, NULL} }, 124916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {CURSOR_TIME, .u.n = {NULL, 120, 50, 600, 0, 0, NULL} }, 125016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {SAY_CONTROL, TOGGLE_0}, 125116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {SAY_WORD_CTL, TOGGLE_0}, 125216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {NO_INTERRUPT, TOGGLE_0}, 125316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs {KEY_ECHO, .u.n = {NULL, 1, 0, 2, 0, 0, NULL} }, 1254c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs V_LAST_VAR 1255c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 1256c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1257c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void toggle_cursoring(struct vc_data *vc) 1258c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1259c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == read_all_mode) 1260c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cursor_track = prev_cursor_track; 1261c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (++cursor_track >= CT_Max) 1262c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cursor_track = 0; 1263ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_CURSOR_MSGS_START + cursor_track)); 1264c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1265c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1266ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultvoid spk_reset_default_chars(void) 1267c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1268c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i; 1269c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1270c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* First, free any non-default */ 1271c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < 256; i++) { 1272ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if ((spk_characters[i] != NULL) 1273ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault && (spk_characters[i] != spk_default_chars[i])) 1274ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault kfree(spk_characters[i]); 1275c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1276c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1277ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault memcpy(spk_characters, spk_default_chars, sizeof(spk_default_chars)); 1278c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1279c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1280ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibaultvoid spk_reset_default_chartab(void) 1281c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1282c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs memcpy(spk_chartab, default_chartab, sizeof(default_chartab)); 1283c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1284c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 128516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic const struct st_bits_data *pb_edit; 1286c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1287c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int edit_bits(struct vc_data *vc, u_char type, u_char ch, u_short key) 1288c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1289c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs short mask = pb_edit->mask, ch_type = spk_chartab[ch]; 12908e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 129116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (type != KT_LATIN || (ch_type & B_NUM) || ch < SPACE) 1292c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 1293c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch == SPACE) { 1294ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_EDIT_DONE)); 1295ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_special_handler = NULL; 1296c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 1297c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 129816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (mask < PUNC && !(ch_type & PUNC)) 1299c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 1300c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_chartab[ch] ^= mask; 1301c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speak_char(ch); 1302c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf(" %s\n", 1303ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault (spk_chartab[ch] & mask) ? spk_msg_get(MSG_ON) : 1304ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_msg_get(MSG_OFF)); 1305c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 1306c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1307c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1308c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* Allocation concurrency is protected by the console semaphore */ 13090012196c165d5158a128e2accd2e511a306a6aa7Sachin Kamatstatic int speakup_allocate(struct vc_data *vc) 1310c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1311c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int vc_num; 1312c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1313c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs vc_num = vc->vc_num; 1314c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc_num] == NULL) { 1315c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num] = kzalloc(sizeof(*speakup_console[0]), 131616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs GFP_ATOMIC); 1317c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc_num] == NULL) 1318628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon return -ENOMEM; 1319c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_date(vc); 1320c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else if (!spk_parked) 1321c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_date(vc); 1322628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 1323628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon return 0; 1324c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1325c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 13260012196c165d5158a128e2accd2e511a306a6aa7Sachin Kamatstatic void speakup_deallocate(struct vc_data *vc) 1327c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1328c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int vc_num; 1329c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1330c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs vc_num = vc->vc_num; 133139dd3e5d7b09b5a5010ed1aef512f2d58b65cb99Ilia Mirkin kfree(speakup_console[vc_num]); 133239dd3e5d7b09b5a5010ed1aef512f2d58b65cb99Ilia Mirkin speakup_console[vc_num] = NULL; 1333c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1334c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1335c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic u_char is_cursor; 1336c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic u_long old_cursor_pos, old_cursor_x, old_cursor_y; 1337c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int cursor_con; 1338c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1339c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void reset_highlight_buffers(struct vc_data *); 1340c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1341c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int read_all_key; 1342c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1343c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void start_read_all_timer(struct vc_data *vc, int command); 1344c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1345c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsenum { 1346c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_NOTHING, 1347c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_NEXT_SENT, 1348c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_PREV_LINE, 1349c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_NEXT_LINE, 1350c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_PREV_SENT, 1351c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_DOWN_ARROW, 1352c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_TIMER, 1353c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_FIND_NEXT_SENT, 1354c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs RA_FIND_PREV_SENT, 1355c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 1356c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 135716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void kbd_fakekey2(struct vc_data *vc, int command) 1358c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1359c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs del_timer(&cursor_timer); 1360c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_fake_down_arrow(); 1361c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start_read_all_timer(vc, command); 1362c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1363c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 136416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void read_all_doc(struct vc_data *vc) 1365c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1366c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((vc->vc_num != fg_console) || synth == NULL || spk_shut_up) 1367c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1368c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!synth_supports_indexing()) 1369c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1370c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track != read_all_mode) 1371c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs prev_cursor_track = cursor_track; 1372c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cursor_track = read_all_mode; 1373ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_reset_index_count(0); 1374c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (get_sentence_buf(vc, 0) == -1) 1375c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs kbd_fakekey2(vc, RA_DOWN_ARROW); 1376c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else { 1377c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_sentence_num(0, 0); 1378c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_insert_next_index(0); 1379c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start_read_all_timer(vc, RA_TIMER); 1380c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1381c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1382c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 138316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void stop_read_all(struct vc_data *vc) 1384c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1385c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs del_timer(&cursor_timer); 1386c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cursor_track = prev_cursor_track; 1387c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 1388ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 1389c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1390c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 139116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void start_read_all_timer(struct vc_data *vc, int command) 1392c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1393c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct var_t *cursor_timeout; 1394c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1395c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cursor_con = vc->vc_num; 1396c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs read_all_key = command; 1397ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault cursor_timeout = spk_get_var(CURSOR_TIME); 139816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs mod_timer(&cursor_timer, 139916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs jiffies + msecs_to_jiffies(cursor_timeout->u.n.value)); 1400c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1401c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 140216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void handle_cursor_read_all(struct vc_data *vc, int command) 1403c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1404c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int indcount, sentcount, rv, sn; 1405c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1406c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs switch (command) { 1407c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case RA_NEXT_SENT: 1408c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* Get Current Sentence */ 1409ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_get_index_count(&indcount, &sentcount); 1410c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /*printk("%d %d ", indcount, sentcount); */ 1411ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_reset_index_count(sentcount + 1); 1412c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (indcount == 1) { 141316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (!say_sentence_num(sentcount + 1, 0)) { 1414c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs kbd_fakekey2(vc, RA_FIND_NEXT_SENT); 1415c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1416c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1417c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_insert_next_index(0); 1418c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 1419c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs sn = 0; 142016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (!say_sentence_num(sentcount + 1, 1)) { 1421c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs sn = 1; 1422ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_reset_index_count(sn); 1423c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else 1424c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_insert_next_index(0); 1425c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!say_sentence_num(sn, 0)) { 1426c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs kbd_fakekey2(vc, RA_FIND_NEXT_SENT); 1427c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1428c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1429c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_insert_next_index(0); 1430c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1431c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start_read_all_timer(vc, RA_TIMER); 1432c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1433c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case RA_PREV_SENT: 1434c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1435c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case RA_NEXT_LINE: 1436c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs read_all_doc(vc); 1437c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1438c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case RA_PREV_LINE: 1439c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1440c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case RA_DOWN_ARROW: 1441c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (get_sentence_buf(vc, 0) == -1) { 1442c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs kbd_fakekey2(vc, RA_DOWN_ARROW); 1443c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 1444c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_sentence_num(0, 0); 1445c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_insert_next_index(0); 1446c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start_read_all_timer(vc, RA_TIMER); 1447c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1448c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1449c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case RA_FIND_NEXT_SENT: 1450c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs rv = get_sentence_buf(vc, 0); 1451c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (rv == -1) 1452c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs read_all_doc(vc); 1453c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (rv == 0) 1454c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs kbd_fakekey2(vc, RA_FIND_NEXT_SENT); 1455c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else { 1456c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_sentence_num(1, 0); 1457c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_insert_next_index(0); 1458c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start_read_all_timer(vc, RA_TIMER); 1459c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1460c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1461c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case RA_FIND_PREV_SENT: 1462c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1463c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case RA_TIMER: 1464ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_get_index_count(&indcount, &sentcount); 1465c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (indcount < 2) 1466c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs kbd_fakekey2(vc, RA_DOWN_ARROW); 1467c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 1468c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start_read_all_timer(vc, RA_TIMER); 1469c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1470c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1471c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1472c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1473c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int pre_handle_cursor(struct vc_data *vc, u_char value, char up_flag) 1474c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1475c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 14768e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 14773efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_lock_irqsave(&speakup_info.spinlock, flags); 1478c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == read_all_mode) { 1479c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked &= 0xfe; 1480c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (synth == NULL || up_flag || spk_shut_up) { 14813efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1482c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return NOTIFY_STOP; 1483c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1484c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs del_timer(&cursor_timer); 1485c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 1486ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 148716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs start_read_all_timer(vc, value + 1); 14883efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1489c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return NOTIFY_STOP; 1490c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 14913efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1492c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return NOTIFY_OK; 1493c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1494c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1495c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag) 1496c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1497c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 1498c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct var_t *cursor_timeout; 1499c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 15003efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_lock_irqsave(&speakup_info.spinlock, flags); 1501c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked &= 0xfe; 1502c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (synth == NULL || up_flag || spk_shut_up || cursor_track == CT_Off) { 15033efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1504c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1505c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1506c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 1507ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_no_intr) 1508ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 1509c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* the key press flushes if !no_inter but we want to flush on cursor 1510c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * moves regardless of no_inter state */ 1511c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs is_cursor = value + 1; 1512c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs old_cursor_pos = vc->vc_pos; 1513c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs old_cursor_x = vc->vc_x; 1514c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs old_cursor_y = vc->vc_y; 1515c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc->vc_num]->ht.cy = vc->vc_y; 1516c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cursor_con = vc->vc_num; 1517c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == CT_Highlight) 1518c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs reset_highlight_buffers(vc); 1519ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault cursor_timeout = spk_get_var(CURSOR_TIME); 152016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs mod_timer(&cursor_timer, 152116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs jiffies + msecs_to_jiffies(cursor_timeout->u.n.value)); 15223efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1523c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1524c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 152516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void update_color_buffer(struct vc_data *vc, const char *ic, int len) 1526c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1527c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i, bi, hi; 1528c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int vc_num = vc->vc_num; 1529c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 153016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs bi = ((vc->vc_attr & 0x70) >> 4); 1531c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs hi = speakup_console[vc_num]->ht.highsize[bi]; 1532c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1533c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs i = 0; 1534c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc_num]->ht.highsize[bi] == 0) { 1535c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.rpos[bi] = vc->vc_pos; 1536c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.rx[bi] = vc->vc_x; 1537c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.ry[bi] = vc->vc_y; 1538c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1539c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs while ((hi < COLOR_BUFFER_SIZE) && (i < len)) { 1540c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((ic[i] > 32) && (ic[i] < 127)) { 1541c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.highbuf[bi][hi] = ic[i]; 1542c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs hi++; 1543c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else if ((ic[i] == 32) && (hi != 0)) { 154416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (speakup_console[vc_num]->ht.highbuf[bi][hi - 1] != 154516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs 32) { 1546c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.highbuf[bi][hi] = 154716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ic[i]; 1548c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs hi++; 1549c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1550c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1551c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs i++; 1552c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1553c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.highsize[bi] = hi; 1554c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1555c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 155616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void reset_highlight_buffers(struct vc_data *vc) 1557c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1558c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i; 1559c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int vc_num = vc->vc_num; 15608e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 156116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs for (i = 0; i < 8; i++) 1562c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.highsize[i] = 0; 1563c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1564c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 156516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic int count_highlight_color(struct vc_data *vc) 1566c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1567c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i, bg; 1568c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int cc; 1569c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int vc_num = vc->vc_num; 1570c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u16 ch; 1571c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u16 *start = (u16 *) vc->vc_origin; 1572c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1573c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < 8; i++) 1574c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.bgcount[i] = 0; 1575c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1576c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < vc->vc_rows; i++) { 157716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs u16 *end = start + vc->vc_cols * 2; 1578c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u16 *ptr; 15798e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1580c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (ptr = start; ptr < end; ptr++) { 1581c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch = get_attributes(ptr); 1582c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bg = (ch & 0x70) >> 4; 1583c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc_num]->ht.bgcount[bg]++; 1584c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1585c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs start += vc->vc_size_row; 1586c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1587c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1588c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cc = 0; 1589c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < 8; i++) 1590c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc_num]->ht.bgcount[i] > 0) 1591c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cc++; 1592c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return cc; 1593c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1594c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 159516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic int get_highlight_color(struct vc_data *vc) 1596c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1597c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i, j; 1598c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned int cptr[8], tmp; 1599c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int vc_num = vc->vc_num; 1600c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1601c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < 8; i++) 1602c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cptr[i] = i; 1603c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1604c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < 7; i++) 1605c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (j = i + 1; j < 8; j++) 1606c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc_num]->ht.bgcount[cptr[i]] > 160716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs speakup_console[vc_num]->ht.bgcount[cptr[j]]) { 1608c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs tmp = cptr[i]; 1609c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cptr[i] = cptr[j]; 1610c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs cptr[j] = tmp; 1611c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1612c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1613c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < 8; i++) 1614c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc_num]->ht.bgcount[cptr[i]] != 0) 1615c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc_num]->ht.highsize[cptr[i]] > 0) 1616c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return cptr[i]; 1617c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 1618c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1619c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 162016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic int speak_highlight(struct vc_data *vc) 1621c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1622c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int hc, d; 1623c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int vc_num = vc->vc_num; 16248e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1625c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (count_highlight_color(vc) == 1) 1626c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 0; 1627c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs hc = get_highlight_color(vc); 1628c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (hc != -1) { 162916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs d = vc->vc_y - speakup_console[vc_num]->ht.cy; 1630c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((d == 1) || (d == -1)) 1631c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc_num]->ht.ry[hc] != vc->vc_y) 1632c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 0; 1633c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 1634ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 1635c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spkup_write(speakup_console[vc_num]->ht.highbuf[hc], 163616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs speakup_console[vc_num]->ht.highsize[hc]); 1637c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos = spk_cp = speakup_console[vc_num]->ht.rpos[hc]; 1638c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = spk_cx = speakup_console[vc_num]->ht.rx[hc]; 1639c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y = spk_cy = speakup_console[vc_num]->ht.ry[hc]; 1640c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 1641c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1642c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 0; 1643c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1644c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 164516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void cursor_done(u_long data) 1646c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1647c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct vc_data *vc = vc_cons[cursor_con].d; 1648c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 16498e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1650c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs del_timer(&cursor_timer); 16513efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_lock_irqsave(&speakup_info.spinlock, flags); 1652c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_con != fg_console) { 1653c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs is_cursor = 0; 1654c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 1655c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1656c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_date(vc); 1657c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (win_enabled) { 1658c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (vc->vc_x >= win_left && vc->vc_x <= win_right && 165916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs vc->vc_y >= win_top && vc->vc_y <= win_bottom) { 1660c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown = is_cursor = 0; 1661c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 1662c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1663c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1664c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == read_all_mode) { 1665c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs handle_cursor_read_all(vc, read_all_key); 1666c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 1667c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1668c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == CT_Highlight) { 1669c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speak_highlight(vc)) { 1670c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown = is_cursor = 0; 1671c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 1672c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1673c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1674c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == CT_Window) 1675c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_win_say(vc); 1676c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else if (is_cursor == 1 || is_cursor == 4) 1677c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line_from_to(vc, 0, vc->vc_cols, 0); 1678c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 1679c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_char(vc); 1680c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown = is_cursor = 0; 1681c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsout: 16823efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1683c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1684c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1685c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* called by: vt_notifier_call() */ 1686c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_bs(struct vc_data *vc) 1687c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1688c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 16898e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1690c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!speakup_console[vc->vc_num]) 1691c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 16923efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) 1693c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* Speakup output, discard */ 1694c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1695c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!spk_parked) 1696c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_date(vc); 1697c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_shut_up || synth == NULL) { 16983efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1699c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1700c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1701c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (vc->vc_num == fg_console && spk_keydown) { 1702c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown = 0; 1703c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!is_cursor) 1704c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_char(vc); 1705c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 17063efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1707c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1708c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1709c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* called by: vt_notifier_call() */ 1710c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_con_write(struct vc_data *vc, const char *str, int len) 1711c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1712c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 17138e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1714c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((vc->vc_num != fg_console) || spk_shut_up || synth == NULL) 1715c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 17163efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) 1717c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* Speakup output, discard */ 1718c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1719ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_bell_pos && spk_keydown && (vc->vc_x == spk_bell_pos - 1)) 1720c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bleep(3); 1721c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((is_cursor) || (cursor_track == read_all_mode)) { 1722c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (cursor_track == CT_Highlight) 1723c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs update_color_buffer(vc, str, len); 17243efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1725c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1726c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1727c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (win_enabled) { 1728c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (vc->vc_x >= win_left && vc->vc_x <= win_right && 172916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs vc->vc_y >= win_top && vc->vc_y <= win_bottom) { 17303efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1731c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1732c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1733c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1734c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1735c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spkup_write(str, len); 17363efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1737c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1738c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 17390012196c165d5158a128e2accd2e511a306a6aa7Sachin Kamatstatic void speakup_con_update(struct vc_data *vc) 1740c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1741c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 17428e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1743c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc->vc_num] == NULL || spk_parked) 1744c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 17453efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) 1746c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* Speakup output, discard */ 1747c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1748c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_date(vc); 17493efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1750c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1751c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1752c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void do_handle_spec(struct vc_data *vc, u_char value, char up_flag) 1753c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1754c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 1755c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int on_off = 2; 1756c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char *label; 17578e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1758c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (synth == NULL || up_flag || spk_killed) 1759c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 17603efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_lock_irqsave(&speakup_info.spinlock, flags); 1761c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 1762ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_no_intr) 1763ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 1764c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs switch (value) { 1765c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_CAPS): 1766ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault label = spk_msg_get(MSG_KEYNAME_CAPSLOCK); 1767079c9534a96da9a85a2a2f9715851050fbfbf749Alan Cox on_off = vt_get_leds(fg_console, VC_CAPSLOCK); 1768c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1769c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_NUM): 1770ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault label = spk_msg_get(MSG_KEYNAME_NUMLOCK); 1771079c9534a96da9a85a2a2f9715851050fbfbf749Alan Cox on_off = vt_get_leds(fg_console, VC_NUMLOCK); 1772c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1773c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_HOLD): 1774ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault label = spk_msg_get(MSG_KEYNAME_SCROLLLOCK); 1775079c9534a96da9a85a2a2f9715851050fbfbf749Alan Cox on_off = vt_get_leds(fg_console, VC_SCROLLOCK); 1776c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_console[vc->vc_num]) 1777c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_console[vc->vc_num]->tty_stopped = on_off; 1778c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 1779c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs default: 1780c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked &= 0xfe; 17813efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1782c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1783c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1784c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (on_off < 2) 1785c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%s %s\n", 1786ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault label, spk_msg_get(MSG_STATUS_START + on_off)); 17873efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1788c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1789c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 179016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic int inc_dec_var(u_char value) 1791c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1792c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct st_var_header *p_header; 1793c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct var_t *var_data; 1794c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char num_buf[32]; 1795c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char *cp = num_buf; 1796c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char *pn; 1797c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int var_id = (int)value - VAR_START; 179816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs int how = (var_id & 1) ? E_INC : E_DEC; 17998e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 180016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs var_id = var_id / 2 + FIRST_SET_VAR; 1801ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault p_header = spk_get_var_header(var_id); 1802c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (p_header == NULL) 1803c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 1804c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (p_header->var_type != VAR_NUM) 1805c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 1806c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs var_data = p_header->data; 1807ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_set_num_var(1, p_header, how) != 0) 1808c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 1809c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!spk_close_press) { 1810c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (pn = p_header->name; *pn; pn++) { 1811c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (*pn == '_') 1812c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs *cp = SPACE; 1813c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 1814c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs *cp++ = *pn; 1815c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1816c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1817c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs snprintf(cp, sizeof(num_buf) - (cp - num_buf), " %d ", 181816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs var_data->u.n.value); 1819c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%s", num_buf); 1820c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 0; 1821c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1822c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 182316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void speakup_win_set(struct vc_data *vc) 1824c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1825c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char info[40]; 18268e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1827c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (win_start > 1) { 1828ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_WINDOW_ALREADY_SET)); 1829c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1830c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1831c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_x < win_left || spk_y < win_top) { 1832ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_END_BEFORE_START)); 1833c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1834c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1835c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (win_start && spk_x == win_left && spk_y == win_top) { 1836c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_left = 0; 183716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs win_right = vc->vc_cols - 1; 1838c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_bottom = spk_y; 1839ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault snprintf(info, sizeof(info), spk_msg_get(MSG_WINDOW_LINE), 184016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs (int)win_top + 1); 1841c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 1842c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!win_start) { 1843c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_top = spk_y; 1844c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_left = spk_x; 1845c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 1846c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_bottom = spk_y; 1847c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_right = spk_x; 1848c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1849ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault snprintf(info, sizeof(info), spk_msg_get(MSG_WINDOW_BOUNDARY), 1850ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault (win_start) ? spk_msg_get(MSG_END) : spk_msg_get(MSG_START), 185116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs (int)spk_y + 1, (int)spk_x + 1); 1852c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1853c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_printf("%s\n", info); 1854c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_start++; 1855c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1856c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 185716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void speakup_win_clear(struct vc_data *vc) 1858c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1859c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_top = win_bottom = 0; 1860c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_left = win_right = 0; 1861c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_start = 0; 1862ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_WINDOW_CLEARED)); 1863c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1864c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 186516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void speakup_win_enable(struct vc_data *vc) 1866c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1867c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (win_start < 2) { 1868ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_NO_WINDOW)); 1869c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1870c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1871c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs win_enabled ^= 1; 1872c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (win_enabled) 1873ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_WINDOW_SILENCED)); 1874c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 1875ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_WINDOW_SILENCE_DISABLED)); 1876c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1877c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 187816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void speakup_bits(struct vc_data *vc) 1879c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1880c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int val = this_speakup_key - (FIRST_EDIT_BITS - 1); 18818e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 1882ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_special_handler != NULL || val < 1 || val > 6) { 1883ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_ERROR)); 1884c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1885c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1886ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault pb_edit = &spk_punc_info[val]; 1887ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(spk_msg_get(MSG_EDIT_PROMPT), pb_edit->name); 1888ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_special_handler = edit_bits; 1889c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1890c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1891c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) 1892c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 18934ea418b8b2fa8a70d0fcc8231b65e67b3a72984bChristopher Brannon static u_char goto_buf[8]; 189416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs static int num; 1895ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn int maxlen; 1896c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs char *cp; 1897ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn 1898c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (type == KT_SPKUP && ch == SPEAKUP_GOTO) 1899c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto do_goto; 1900c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (type == KT_LATIN && ch == '\n') 1901c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto do_goto; 1902c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (type != 0) 1903c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto oops; 1904c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch == 8) { 1905c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (num == 0) 1906c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return -1; 1907c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ch = goto_buf[--num]; 1908c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_buf[num] = '\0'; 1909c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spkup_write(&ch, 1); 1910c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 1911c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1912c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch < '+' || ch > 'y') 1913c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto oops; 1914c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_buf[num++] = ch; 1915c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_buf[num] = '\0'; 1916c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spkup_write(&ch, 1); 1917c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs maxlen = (*goto_buf >= '0') ? 3 : 4; 1918c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((ch == '+' || ch == '-') && num == 1) 1919c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 1920c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch >= '0' && ch <= '9' && num < maxlen) 1921c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 192216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (num < maxlen - 1 || num > maxlen) 1923c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto oops; 1924c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ch < 'x' || ch > 'y') { 1925c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsoops: 1926c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!spk_killed) 1927ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf(" %s\n", spk_msg_get(MSG_GOTO_CANCELED)); 1928c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_buf[num = 0] = '\0'; 1929ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_special_handler = NULL; 1930c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 1931c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1932ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn 1933ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn goto_pos = simple_strtoul(goto_buf, &cp, 10); 1934ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn 1935c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (*cp == 'x') { 1936c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (*goto_buf < '0') 1937c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_pos += spk_x; 1938ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn else if (goto_pos > 0) 1939c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_pos--; 1940ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn 1941c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (goto_pos >= vc->vc_cols) 194216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs goto_pos = vc->vc_cols - 1; 1943c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_x = 1; 1944c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 1945c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (*goto_buf < '0') 1946c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_pos += spk_y; 1947ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn else if (goto_pos > 0) 1948c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_pos--; 1949ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98Daeseok Youn 1950c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (goto_pos >= vc->vc_rows) 195116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs goto_pos = vc->vc_rows - 1; 1952c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto_x = 0; 1953c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 195416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs goto_buf[num = 0] = '\0'; 1955c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsdo_goto: 1956ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_special_handler = NULL; 1957c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked |= 0x01; 1958c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (goto_x) { 1959c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos -= spk_x * 2; 1960c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_x = goto_pos; 1961c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos += goto_pos * 2; 1962c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_word(vc); 1963c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 1964c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_y = goto_pos; 1965c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_pos = vc->vc_origin + (goto_pos * vc->vc_size_row); 1966c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line(vc); 1967c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1968c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 1; 1969c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1970c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 197116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void speakup_goto(struct vc_data *vc) 1972c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1973ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_special_handler != NULL) { 1974ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_ERROR)); 1975c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 1976c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 1977ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault synth_printf("%s\n", spk_msg_get(MSG_GOTO)); 1978ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_special_handler = handle_goto; 1979c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1980c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 1981c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void speakup_help(struct vc_data *vc) 1982c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1983ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_handle_help(vc, KT_SPKUP, SPEAKUP_HELP, 0); 1984c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 1985c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 198616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void do_nothing(struct vc_data *vc) 1987c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 198816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs return; /* flush done in do_spkup */ 1989c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 199016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs 1991c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic u_char key_speakup, spk_key_locked; 1992c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 199316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbsstatic void speakup_lock(struct vc_data *vc) 1994c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 1995c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!spk_key_locked) 1996c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_key_locked = key_speakup = 16; 1997c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else 1998c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_key_locked = key_speakup = 0; 1999c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 2000c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 200116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbstypedef void (*spkup_hand) (struct vc_data *); 20020012196c165d5158a128e2accd2e511a306a6aa7Sachin Kamatstatic spkup_hand spkup_handler[] = { 2003c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* must be ordered same as defines in speakup.h */ 2004c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs do_nothing, speakup_goto, speech_kill, speakup_shut_up, 2005c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_cut, speakup_paste, say_first_char, say_last_char, 2006c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_char, say_prev_char, say_next_char, 2007c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_word, say_prev_word, say_next_word, 2008c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_line, say_prev_line, say_next_line, 2009c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs top_edge, bottom_edge, left_edge, right_edge, 2010c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spell_word, spell_word, say_screen, 2011c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_position, say_attributes, 201216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs speakup_off, speakup_parked, say_line, /* this is for indent */ 2013c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_from_top, say_to_bottom, 2014c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_from_left, say_to_right, 2015c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs say_char_num, speakup_bits, speakup_bits, say_phonetic_char, 2016c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_bits, speakup_bits, speakup_bits, 2017c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_win_set, speakup_win_clear, speakup_win_enable, speakup_win_say, 2018c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_lock, speakup_help, toggle_cursoring, read_all_doc, NULL 2019c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs}; 2020c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2021c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void do_spkup(struct vc_data *vc, u_char value) 2022c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 2023c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (spk_killed && value != SPEECH_KILL) 2024c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return; 2025c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown = 0; 2026c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_lastkey = 0; 2027c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 2028c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs this_speakup_key = value; 2029c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (value < SPKUP_MAX_FUNC && spkup_handler[value]) { 2030ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 203116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs (*spkup_handler[value]) (vc); 2032c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else { 2033c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (inc_dec_var(value) < 0) 2034c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bleep(9); 2035c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2036c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 2037c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2038c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic const char *pad_chars = "0123456789+-*/\015,.?()"; 2039c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 20400012196c165d5158a128e2accd2e511a306a6aa7Sachin Kamatstatic int 2041c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsspeakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, 204216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs int up_flag) 2043c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 2044c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unsigned long flags; 2045c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int kh; 2046c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char *key_info; 2047c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char type = KTYP(keysym), value = KVAL(keysym), new_key = 0; 2048c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs u_char shift_info, offset; 2049c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int ret = 0; 20508e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 2051c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (synth == NULL) 2052c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return 0; 2053c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 20543efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_lock_irqsave(&speakup_info.spinlock, flags); 20555b19208a5e236b26357162d6a28ff9e8d4296725Greg Kroah-Hartman tty = vc->port.tty; 2056c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (type >= 0xf0) 2057c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs type -= 0xf0; 205816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs if (type == KT_PAD 2059079c9534a96da9a85a2a2f9715851050fbfbf749Alan Cox && (vt_get_leds(fg_console, VC_NUMLOCK))) { 2060c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (up_flag) { 2061c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown = 0; 2062c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 2063c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2064c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs value = spk_lastkey = pad_chars[value]; 2065c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_keydown++; 2066c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_parked &= 0xfe; 2067c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto no_map; 2068c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2069c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (keycode >= MAX_KEY) 2070c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto no_map; 2071ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault key_info = spk_our_keys[keycode]; 2072ff471ea823d8cdd790759febc358c3776a90c922Sachin Kamat if (!key_info) 2073c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto no_map; 2074c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* Check valid read all mode keys */ 2075c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((cursor_track == read_all_mode) && (!up_flag)) { 2076c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs switch (value) { 2077c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_DOWN): 2078c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_UP): 2079c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_LEFT): 2080c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_RIGHT): 2081c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_PGUP): 2082c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KVAL(K_PGDN): 2083c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2084c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs default: 2085c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs stop_read_all(vc); 2086c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2087c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2088c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 208916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs shift_info = (shift_state & 0x0f) + key_speakup; 2090ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault offset = spk_shift_table[shift_info]; 2091c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (offset) { 2092c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs new_key = key_info[offset]; 2093c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (new_key) { 2094c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ret = 1; 2095c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (new_key == SPK_KEY) { 2096c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (!spk_key_locked) 2097c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs key_speakup = (up_flag) ? 0 : 16; 2098c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (up_flag || spk_killed) 2099c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 2100c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 2101ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 2102c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 2103c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2104c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (up_flag) 2105c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 2106c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (last_keycode == keycode && 21073d3cb1bffde15ee6e69532457bee20b5d424952bRobin Schroer time_after(last_spk_jiffy + MAX_DELAY, jiffies)) { 2108c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_close_press = 1; 2109ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault offset = spk_shift_table[shift_info + 32]; 211016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs /* double press? */ 2111c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (offset && key_info[offset]) 2112c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs new_key = key_info[offset]; 2113c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2114c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs last_keycode = keycode; 2115c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs last_spk_jiffy = jiffies; 2116c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs type = KT_SPKUP; 2117c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs value = new_key; 2118c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2119c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2120c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsno_map: 2121ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (type == KT_SPKUP && spk_special_handler == NULL) { 2122c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs do_spkup(vc, new_key); 2123c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_close_press = 0; 2124c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ret = 1; 2125c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 2126c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2127c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (up_flag || spk_killed || type == KT_SHIFT) 2128c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 2129c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_shut_up &= 0xfe; 2130c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs kh = (value == KVAL(K_DOWN)) 213116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs || (value == KVAL(K_UP)) 213216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs || (value == KVAL(K_LEFT)) 213316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs || (value == KVAL(K_RIGHT)); 2134c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if ((cursor_track != read_all_mode) || !kh) 2135ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (!spk_no_intr) 2136ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_do_flush(); 2137ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_special_handler) { 2138c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (type == KT_SPEC && value == 1) { 2139c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs value = '\n'; 2140c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs type = KT_LATIN; 2141c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } else if (type == KT_LETTER) 2142c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs type = KT_LATIN; 2143c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs else if (value == 0x7f) 214416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs value = 8; /* make del = backspace */ 2145ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault ret = (*spk_special_handler) (vc, type, value, keycode); 2146c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_close_press = 0; 2147c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (ret < 0) 2148c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs bleep(9); 2149c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs goto out; 2150c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2151c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs last_keycode = 0; 2152c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsout: 21533efe810f2322223eca3b3a1dea3ae40500cbd471William Hubbs spin_unlock_irqrestore(&speakup_info.spinlock, flags); 2154c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return ret; 2155c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 2156c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2157c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int keyboard_notifier_call(struct notifier_block *nb, 215816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs unsigned long code, void *_param) 2159c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 2160c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct keyboard_notifier_param *param = _param; 2161c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct vc_data *vc = param->vc; 2162c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int up = !param->down; 2163c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int ret = NOTIFY_OK; 216416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs static int keycode; /* to hold the current keycode */ 2165c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2166c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (vc->vc_mode == KD_GRAPHICS) 2167c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return ret; 2168c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2169c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* 2170c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * First, determine whether we are handling a fake keypress on 2171c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * the current processor. If we are, then return NOTIFY_OK, 2172c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * to pass the keystroke up the chain. This prevents us from 2173c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * trying to take the Speakup lock while it is held by the 2174c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * processor on which the simulated keystroke was generated. 2175c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs * Also, the simulated keystrokes should be ignored by Speakup. 2176c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs */ 2177c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2178c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_fake_key_pressed()) 2179c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return ret; 2180c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2181c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs switch (code) { 2182c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KBD_KEYCODE: 2183c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* speakup requires keycode and keysym currently */ 2184c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs keycode = param->value; 2185c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2186c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KBD_UNBOUND_KEYCODE: 2187c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* not used yet */ 2188c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2189c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KBD_UNICODE: 2190c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs /* not used yet */ 2191c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2192c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case KBD_KEYSYM: 2193c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (speakup_key(vc, param->shift, keycode, param->value, up)) 2194c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs ret = NOTIFY_STOP; 219516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs else if (KTYP(param->value) == KT_CUR) 219616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs ret = pre_handle_cursor(vc, KVAL(param->value), up); 2197c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 219816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case KBD_POST_KEYSYM:{ 219916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs unsigned char type = KTYP(param->value) - 0xf0; 220016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs unsigned char val = KVAL(param->value); 22018e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 220216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs switch (type) { 220316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case KT_SHIFT: 220416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs do_handle_shift(vc, val, up); 220516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs break; 220616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case KT_LATIN: 220716d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case KT_LETTER: 220816d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs do_handle_latin(vc, val, up); 220916d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs break; 221016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case KT_CUR: 221116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs do_handle_cursor(vc, val, up); 221216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs break; 221316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs case KT_SPEC: 221416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs do_handle_spec(vc, val, up); 221516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs break; 221616d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs } 2217c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2218c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2219c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2220c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return ret; 2221c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 2222c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2223c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int vt_notifier_call(struct notifier_block *nb, 222416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs unsigned long code, void *_param) 2225c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 2226c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct vt_notifier_param *param = _param; 2227c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct vc_data *vc = param->vc; 22288e69a8110686572a4b88d006faa8c3c759c4c261Domagoj Trsan 2229c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs switch (code) { 2230c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case VT_ALLOCATE: 2231c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (vc->vc_mode == KD_TEXT) 2232c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_allocate(vc); 2233c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2234c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case VT_DEALLOCATE: 2235c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_deallocate(vc); 2236c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2237c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case VT_WRITE: 2238c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs if (param->c == '\b') 2239c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_bs(vc); 224016d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs else if (param->c < 0x100) { 224116d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs char d = param->c; 22420a3a725adb2c421ea79089ea12004a007fb371ceRoxana Blaj 224316d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs speakup_con_write(vc, &d, 1); 224416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs } 2245c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2246c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs case VT_UPDATE: 2247c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_con_update(vc); 2248c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs break; 2249c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2250c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs return NOTIFY_OK; 2251c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 2252c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2253c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* called by: module_exit() */ 2254c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic void __exit speakup_exit(void) 2255c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 2256c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i; 2257c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2258c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unregister_keyboard_notifier(&keyboard_notifier_block); 2259c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs unregister_vt_notifier(&vt_notifier_block); 2260c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_unregister_devsynth(); 2261d7500135802ca55b3f4e01a16544e8b34082f8c3Ben Hutchings speakup_cancel_paste(); 2262c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs del_timer(&cursor_timer); 2263c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs kthread_stop(speakup_task); 2264c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_task = NULL; 2265c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs mutex_lock(&spk_mutex); 2266c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_release(); 2267c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs mutex_unlock(&spk_mutex); 2268c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2269628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon speakup_kobj_exit(); 2270628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2271628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon for (i = 0; i < MAX_NR_CONSOLES; i++) 2272628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon kfree(speakup_console[i]); 2273628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2274628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon speakup_remove_virtual_keyboard(); 2275628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2276c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < MAXVARS; i++) 2277c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_unregister_var(i); 2278c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2279c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < 256; i++) { 2280ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_characters[i] != spk_default_chars[i]) 2281ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault kfree(spk_characters[i]); 2282c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs } 2283628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2284ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_free_user_msgs(); 2285c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 2286c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2287c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs/* call by: module_init() */ 2288c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsstatic int __init speakup_init(void) 2289c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs{ 2290c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs int i; 2291628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon long err = 0; 2292c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct st_spk_t *first_console; 2293c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct vc_data *vc = vc_cons[fg_console].d; 2294c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs struct var_t *var; 2295c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2296628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon /* These first few initializations cannot fail. */ 2297ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_initialize_msgs(); /* Initialize arrays for i18n. */ 2298ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_reset_default_chars(); 2299ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_reset_default_chartab(); 2300ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_strlwr(synth_name); 2301c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs spk_vars[0].u.n.high = vc->vc_cols; 230216d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs for (var = spk_vars; var->var_id != MAXVARS; var++) 2303c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_register_var(var); 230416d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs for (var = synth_time_vars; 230516d355156ba475c0fefb19133174cdf61a5101baWilliam Hubbs (var->var_id >= 0) && (var->var_id < MAXVARS); var++) 2306c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_register_var(var); 2307ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault for (i = 1; spk_punc_info[i].mask != 0; i++) 2308ff471ea823d8cdd790759febc358c3776a90c922Sachin Kamat spk_set_mask_bits(NULL, i, 2); 2309c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2310ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_set_key_info(spk_key_defaults, spk_key_buf); 2311c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2312628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon /* From here on out, initializations can fail. */ 2313628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon err = speakup_add_virtual_keyboard(); 2314628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon if (err) 2315628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon goto error_virtkeyboard; 2316628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2317628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon first_console = kzalloc(sizeof(*first_console), GFP_KERNEL); 2318628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon if (!first_console) { 2319628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon err = -ENOMEM; 2320628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon goto error_alloc; 2321628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon } 2322628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2323628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon speakup_console[vc->vc_num] = first_console; 2324628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon speakup_date(vc); 2325628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2326c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs for (i = 0; i < MAX_NR_CONSOLES; i++) 2327628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon if (vc_cons[i].d) { 2328628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon err = speakup_allocate(vc_cons[i].d); 2329628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon if (err) 2330628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon goto error_kobjects; 2331628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon } 2332628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2333ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_quiet_boot) 23344afaee1561e207683dbb886b30a842ffcc22e366Christopher Brannon spk_shut_up |= 0x01; 23354afaee1561e207683dbb886b30a842ffcc22e366Christopher Brannon 2336628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon err = speakup_kobj_init(); 2337628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon if (err) 2338628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon goto error_kobjects; 2339c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2340c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs synth_init(synth_name); 2341c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_register_devsynth(); 2342628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon /* 2343628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon * register_devsynth might fail, but this error is not fatal. 2344628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon * /dev/synth is an extra feature; the rest of Speakup 2345628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon * will work fine without it. 2346628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon */ 2347c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2348628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon err = register_keyboard_notifier(&keyboard_notifier_block); 2349628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon if (err) 2350628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon goto error_kbdnotifier; 2351628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon err = register_vt_notifier(&vt_notifier_block); 2352628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon if (err) 2353628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon goto error_vtnotifier; 2354c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2355c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs speakup_task = kthread_create(speakup_thread, NULL, "speakup"); 2356628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 23577959d55679e4360205c9ebc89d40a5503c53bae2William Hubbs if (IS_ERR(speakup_task)) { 2358628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon err = PTR_ERR(speakup_task); 2359628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon goto error_task; 23607959d55679e4360205c9ebc89d40a5503c53bae2William Hubbs } 2361628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2362628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon set_user_nice(speakup_task, 10); 23637959d55679e4360205c9ebc89d40a5503c53bae2William Hubbs wake_up_process(speakup_task); 2364628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2365628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon pr_info("speakup %s: initialized\n", SPEAKUP_VERSION); 2366628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon pr_info("synth name on entry is: %s\n", synth_name); 23677959d55679e4360205c9ebc89d40a5503c53bae2William Hubbs goto out; 23687959d55679e4360205c9ebc89d40a5503c53bae2William Hubbs 2369628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannonerror_task: 2370628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon unregister_vt_notifier(&vt_notifier_block); 2371628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2372628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannonerror_vtnotifier: 2373628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon unregister_keyboard_notifier(&keyboard_notifier_block); 2374628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon del_timer(&cursor_timer); 2375628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2376628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannonerror_kbdnotifier: 2377628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon speakup_unregister_devsynth(); 2378628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon mutex_lock(&spk_mutex); 2379628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon synth_release(); 2380628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon mutex_unlock(&spk_mutex); 2381628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon speakup_kobj_exit(); 2382628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2383628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannonerror_kobjects: 2384628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon for (i = 0; i < MAX_NR_CONSOLES; i++) 2385628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon kfree(speakup_console[i]); 2386628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2387628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannonerror_alloc: 23887959d55679e4360205c9ebc89d40a5503c53bae2William Hubbs speakup_remove_virtual_keyboard(); 2389628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2390628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannonerror_virtkeyboard: 2391628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon for (i = 0; i < MAXVARS; i++) 2392628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon speakup_unregister_var(i); 2393628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2394628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon for (i = 0; i < 256; i++) { 2395ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault if (spk_characters[i] != spk_default_chars[i]) 2396ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault kfree(spk_characters[i]); 2397628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon } 2398628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 2399ca2beaf84d9678c12b17d92623f0e90829d6ca13Samuel Thibault spk_free_user_msgs(); 2400628f34282db49359576dcb8cbaea65b4bf083ebdChristopher Brannon 24017959d55679e4360205c9ebc89d40a5503c53bae2William Hubbsout: 24027959d55679e4360205c9ebc89d40a5503c53bae2William Hubbs return err; 2403c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs} 2404c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbs 2405c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsmodule_init(speakup_init); 2406c6e3fd22cd538365bfeb82997d5b89562e077d42William Hubbsmodule_exit(speakup_exit); 2407