0001
0002 #include <linux/ctype.h>
0003 #include "spk_types.h"
0004 #include "spk_priv.h"
0005 #include "speakup.h"
0006
0007 static struct st_var_header var_headers[] = {
0008 { "version", VERSION, VAR_PROC, NULL, NULL },
0009 { "synth_name", SYNTH, VAR_PROC, NULL, NULL },
0010 { "keymap", KEYMAP, VAR_PROC, NULL, NULL },
0011 { "silent", SILENT, VAR_PROC, NULL, NULL },
0012 { "punc_some", PUNC_SOME, VAR_PROC, NULL, NULL },
0013 { "punc_most", PUNC_MOST, VAR_PROC, NULL, NULL },
0014 { "punc_all", PUNC_ALL, VAR_PROC, NULL, NULL },
0015 { "delimiters", DELIM, VAR_PROC, NULL, NULL },
0016 { "repeats", REPEATS, VAR_PROC, NULL, NULL },
0017 { "ex_num", EXNUMBER, VAR_PROC, NULL, NULL },
0018 { "characters", CHARS, VAR_PROC, NULL, NULL },
0019 { "synth_direct", SYNTH_DIRECT, VAR_PROC, NULL, NULL },
0020 { "caps_start", CAPS_START, VAR_STRING, spk_str_caps_start, NULL },
0021 { "caps_stop", CAPS_STOP, VAR_STRING, spk_str_caps_stop, NULL },
0022 { "delay_time", DELAY, VAR_TIME, NULL, NULL },
0023 { "trigger_time", TRIGGER, VAR_TIME, NULL, NULL },
0024 { "jiffy_delta", JIFFY, VAR_TIME, NULL, NULL },
0025 { "full_time", FULL, VAR_TIME, NULL, NULL },
0026 { "flush_time", FLUSH, VAR_TIME, NULL, NULL },
0027 { "spell_delay", SPELL_DELAY, VAR_NUM, &spk_spell_delay, NULL },
0028 { "bleeps", BLEEPS, VAR_NUM, &spk_bleeps, NULL },
0029 { "attrib_bleep", ATTRIB_BLEEP, VAR_NUM, &spk_attrib_bleep, NULL },
0030 { "bleep_time", BLEEP_TIME, VAR_TIME, &spk_bleep_time, NULL },
0031 { "cursor_time", CURSOR_TIME, VAR_TIME, NULL, NULL },
0032 { "punc_level", PUNC_LEVEL, VAR_NUM, &spk_punc_level, NULL },
0033 { "reading_punc", READING_PUNC, VAR_NUM, &spk_reading_punc, NULL },
0034 { "say_control", SAY_CONTROL, VAR_NUM, &spk_say_ctrl, NULL },
0035 { "say_word_ctl", SAY_WORD_CTL, VAR_NUM, &spk_say_word_ctl, NULL },
0036 { "no_interrupt", NO_INTERRUPT, VAR_NUM, &spk_no_intr, NULL },
0037 { "key_echo", KEY_ECHO, VAR_NUM, &spk_key_echo, NULL },
0038 { "bell_pos", BELL_POS, VAR_NUM, &spk_bell_pos, NULL },
0039 { "rate", RATE, VAR_NUM, NULL, NULL },
0040 { "pitch", PITCH, VAR_NUM, NULL, NULL },
0041 { "inflection", INFLECTION, VAR_NUM, NULL, NULL },
0042 { "vol", VOL, VAR_NUM, NULL, NULL },
0043 { "tone", TONE, VAR_NUM, NULL, NULL },
0044 { "punct", PUNCT, VAR_NUM, NULL, NULL },
0045 { "voice", VOICE, VAR_NUM, NULL, NULL },
0046 { "freq", FREQUENCY, VAR_NUM, NULL, NULL },
0047 { "lang", LANG, VAR_NUM, NULL, NULL },
0048 { "chartab", CHARTAB, VAR_PROC, NULL, NULL },
0049 { "direct", DIRECT, VAR_NUM, NULL, NULL },
0050 { "pause", PAUSE, VAR_STRING, spk_str_pause, NULL },
0051 };
0052
0053 static struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL };
0054
0055 static struct punc_var_t punc_vars[] = {
0056 { PUNC_SOME, 1 },
0057 { PUNC_MOST, 2 },
0058 { PUNC_ALL, 3 },
0059 { DELIM, 4 },
0060 { REPEATS, 5 },
0061 { EXNUMBER, 6 },
0062 { -1, -1 },
0063 };
0064
0065 int spk_chartab_get_value(char *keyword)
0066 {
0067 int value = 0;
0068
0069 if (!strcmp(keyword, "ALPHA"))
0070 value = ALPHA;
0071 else if (!strcmp(keyword, "B_CTL"))
0072 value = B_CTL;
0073 else if (!strcmp(keyword, "WDLM"))
0074 value = WDLM;
0075 else if (!strcmp(keyword, "A_PUNC"))
0076 value = A_PUNC;
0077 else if (!strcmp(keyword, "PUNC"))
0078 value = PUNC;
0079 else if (!strcmp(keyword, "NUM"))
0080 value = NUM;
0081 else if (!strcmp(keyword, "A_CAP"))
0082 value = A_CAP;
0083 else if (!strcmp(keyword, "B_CAPSYM"))
0084 value = B_CAPSYM;
0085 else if (!strcmp(keyword, "B_SYM"))
0086 value = B_SYM;
0087 return value;
0088 }
0089
0090 void speakup_register_var(struct var_t *var)
0091 {
0092 static char nothing[2] = "\0";
0093 int i;
0094 struct st_var_header *p_header;
0095
0096 BUG_ON(!var || var->var_id < 0 || var->var_id >= MAXVARS);
0097 if (!var_ptrs[0]) {
0098 for (i = 0; i < MAXVARS; i++) {
0099 p_header = &var_headers[i];
0100 var_ptrs[p_header->var_id] = p_header;
0101 p_header->data = NULL;
0102 }
0103 }
0104 p_header = var_ptrs[var->var_id];
0105 if (p_header->data)
0106 return;
0107 p_header->data = var;
0108 switch (p_header->var_type) {
0109 case VAR_STRING:
0110 spk_set_string_var(nothing, p_header, 0);
0111 break;
0112 case VAR_NUM:
0113 case VAR_TIME:
0114 spk_set_num_var(0, p_header, E_DEFAULT);
0115 break;
0116 default:
0117 break;
0118 }
0119 }
0120
0121 void speakup_unregister_var(enum var_id_t var_id)
0122 {
0123 struct st_var_header *p_header;
0124
0125 BUG_ON(var_id < 0 || var_id >= MAXVARS);
0126 p_header = var_ptrs[var_id];
0127 p_header->data = NULL;
0128 }
0129
0130 struct st_var_header *spk_get_var_header(enum var_id_t var_id)
0131 {
0132 struct st_var_header *p_header;
0133
0134 if (var_id < 0 || var_id >= MAXVARS)
0135 return NULL;
0136 p_header = var_ptrs[var_id];
0137 if (!p_header->data)
0138 return NULL;
0139 return p_header;
0140 }
0141
0142 struct st_var_header *spk_var_header_by_name(const char *name)
0143 {
0144 int i;
0145
0146 if (!name)
0147 return NULL;
0148
0149 for (i = 0; i < MAXVARS; i++) {
0150 if (strcmp(name, var_ptrs[i]->name) == 0)
0151 return var_ptrs[i];
0152 }
0153 return NULL;
0154 }
0155
0156 struct var_t *spk_get_var(enum var_id_t var_id)
0157 {
0158 BUG_ON(var_id < 0 || var_id >= MAXVARS);
0159 BUG_ON(!var_ptrs[var_id]);
0160 return var_ptrs[var_id]->data;
0161 }
0162 EXPORT_SYMBOL_GPL(spk_get_var);
0163
0164 struct punc_var_t *spk_get_punc_var(enum var_id_t var_id)
0165 {
0166 struct punc_var_t *rv = NULL;
0167 struct punc_var_t *where;
0168
0169 where = punc_vars;
0170 while ((where->var_id != -1) && (!rv)) {
0171 if (where->var_id == var_id)
0172 rv = where;
0173 else
0174 where++;
0175 }
0176 return rv;
0177 }
0178
0179
0180 int spk_set_num_var(int input, struct st_var_header *var, int how)
0181 {
0182 int val;
0183 int *p_val = var->p_val;
0184 char buf[32];
0185 char *cp;
0186 struct var_t *var_data = var->data;
0187
0188 if (!var_data)
0189 return -ENODATA;
0190
0191 val = var_data->u.n.value;
0192 switch (how) {
0193 case E_NEW_DEFAULT:
0194 if (input < var_data->u.n.low || input > var_data->u.n.high)
0195 return -ERANGE;
0196 var_data->u.n.default_val = input;
0197 return 0;
0198 case E_DEFAULT:
0199 val = var_data->u.n.default_val;
0200 break;
0201 case E_SET:
0202 val = input;
0203 break;
0204 case E_INC:
0205 val += input;
0206 break;
0207 case E_DEC:
0208 val -= input;
0209 break;
0210 }
0211
0212 if (val < var_data->u.n.low || val > var_data->u.n.high)
0213 return -ERANGE;
0214
0215 var_data->u.n.value = val;
0216 if (var->var_type == VAR_TIME && p_val) {
0217 *p_val = msecs_to_jiffies(val);
0218 return 0;
0219 }
0220 if (p_val)
0221 *p_val = val;
0222 if (var->var_id == PUNC_LEVEL) {
0223 spk_punc_mask = spk_punc_masks[val];
0224 return 0;
0225 }
0226 if (var_data->u.n.multiplier != 0)
0227 val *= var_data->u.n.multiplier;
0228 val += var_data->u.n.offset;
0229 if (var->var_id < FIRST_SYNTH_VAR || !synth)
0230 return 0;
0231 if (synth->synth_adjust)
0232 return synth->synth_adjust(var);
0233
0234 if (!var_data->u.n.synth_fmt)
0235 return 0;
0236 if (var->var_id == PITCH)
0237 cp = spk_pitch_buff;
0238 else
0239 cp = buf;
0240 if (!var_data->u.n.out_str)
0241 sprintf(cp, var_data->u.n.synth_fmt, (int)val);
0242 else
0243 sprintf(cp, var_data->u.n.synth_fmt,
0244 var_data->u.n.out_str[val]);
0245 synth_printf("%s", cp);
0246 return 0;
0247 }
0248
0249 int spk_set_string_var(const char *page, struct st_var_header *var, int len)
0250 {
0251 struct var_t *var_data = var->data;
0252
0253 if (!var_data)
0254 return -ENODATA;
0255 if (len > MAXVARLEN)
0256 return -E2BIG;
0257 if (!len) {
0258 if (!var_data->u.s.default_val)
0259 return 0;
0260 if (!var->p_val)
0261 var->p_val = var_data->u.s.default_val;
0262 if (var->p_val != var_data->u.s.default_val)
0263 strcpy((char *)var->p_val, var_data->u.s.default_val);
0264 return -ERESTART;
0265 } else if (var->p_val) {
0266 strcpy((char *)var->p_val, page);
0267 } else {
0268 return -E2BIG;
0269 }
0270 return 0;
0271 }
0272
0273
0274
0275
0276
0277
0278
0279 int spk_set_mask_bits(const char *input, const int which, const int how)
0280 {
0281 u_char *cp;
0282 short mask = spk_punc_info[which].mask;
0283
0284 if (how & 1) {
0285 for (cp = (u_char *)spk_punc_info[3].value; *cp; cp++)
0286 spk_chartab[*cp] &= ~mask;
0287 }
0288 cp = (u_char *)input;
0289 if (!cp) {
0290 cp = spk_punc_info[which].value;
0291 } else {
0292 for (; *cp; cp++) {
0293 if (*cp < SPACE)
0294 break;
0295 if (mask < PUNC) {
0296 if (!(spk_chartab[*cp] & PUNC))
0297 break;
0298 } else if (spk_chartab[*cp] & B_NUM) {
0299 break;
0300 }
0301 }
0302 if (*cp)
0303 return -EINVAL;
0304 cp = (u_char *)input;
0305 }
0306 if (how & 2) {
0307 for (; *cp; cp++)
0308 if (*cp > SPACE)
0309 spk_chartab[*cp] |= mask;
0310 } else {
0311 for (; *cp; cp++)
0312 if (*cp > SPACE)
0313 spk_chartab[*cp] &= ~mask;
0314 }
0315 return 0;
0316 }
0317
0318 char *spk_strlwr(char *s)
0319 {
0320 char *p;
0321
0322 if (!s)
0323 return NULL;
0324
0325 for (p = s; *p; p++)
0326 *p = tolower(*p);
0327 return s;
0328 }
0329
0330 char *spk_s2uchar(char *start, char *dest)
0331 {
0332 int val;
0333
0334
0335 val = simple_strtoul(skip_spaces(start), &start, 10);
0336 if (*start == ',')
0337 start++;
0338 *dest = (u_char)val;
0339 return start;
0340 }