Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

speakup: extend synth buffer to 16bit unicode characters

This extends the synth buffer slots to 16bit, so as to hold 16bit
unicode characters.

synth_buffer_getc and synth_buffer_peek now return 16bit characters.
Speech synthesizers which do not support characters beyond latin1 can
use the synth_buffer_skip_nonlatin1() helper to skip the non-latin1
characters before getting or peeking. All synthesizers are made to use
it for now.

This makes synth_buffer_add take a 16bit character. For simplicity for
now, synth_printf is left to using latin1 formats and strings.
synth_putwc, synth_putwc_s, synth_putws and synth_putws_s helpers are
however added to put 16bit characters and strings.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Chris Brannon <chris@the-brannons.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Samuel Thibault and committed by
Greg Kroah-Hartman
89fc2ae8 981b7ae9

+70 -15
+24 -12
drivers/staging/speakup/buffers.c
··· 7 7 8 8 #define SYNTH_BUF_SIZE 8192 /* currently 8K bytes */ 9 9 10 - static u_char synth_buffer[SYNTH_BUF_SIZE]; /* guess what this is for! */ 11 - static u_char *buff_in = synth_buffer; 12 - static u_char *buff_out = synth_buffer; 13 - static u_char *buffer_end = synth_buffer + SYNTH_BUF_SIZE - 1; 10 + static u16 synth_buffer[SYNTH_BUF_SIZE]; /* guess what this is for! */ 11 + static u16 *buff_in = synth_buffer; 12 + static u16 *buff_out = synth_buffer; 13 + static u16 *buffer_end = synth_buffer + SYNTH_BUF_SIZE - 1; 14 14 15 15 /* These try to throttle applications by stopping the TTYs 16 16 * Note: we need to make sure that we will restart them eventually, which is ··· 44 44 45 45 static int synth_buffer_free(void) 46 46 { 47 - int bytes_free; 47 + int chars_free; 48 48 49 49 if (buff_in >= buff_out) 50 - bytes_free = SYNTH_BUF_SIZE - (buff_in - buff_out); 50 + chars_free = SYNTH_BUF_SIZE - (buff_in - buff_out); 51 51 else 52 - bytes_free = buff_out - buff_in; 53 - return bytes_free; 52 + chars_free = buff_out - buff_in; 53 + return chars_free; 54 54 } 55 55 56 56 int synth_buffer_empty(void) ··· 59 59 } 60 60 EXPORT_SYMBOL_GPL(synth_buffer_empty); 61 61 62 - void synth_buffer_add(char ch) 62 + void synth_buffer_add(u16 ch) 63 63 { 64 64 if (!synth->alive) { 65 65 /* This makes sure that we won't stop TTYs if there is no synth ··· 78 78 buff_in = synth_buffer; 79 79 } 80 80 81 - char synth_buffer_getc(void) 81 + u16 synth_buffer_getc(void) 82 82 { 83 - char ch; 83 + u16 ch; 84 84 85 85 if (buff_out == buff_in) 86 86 return 0; ··· 91 91 } 92 92 EXPORT_SYMBOL_GPL(synth_buffer_getc); 93 93 94 - char synth_buffer_peek(void) 94 + u16 synth_buffer_peek(void) 95 95 { 96 96 if (buff_out == buff_in) 97 97 return 0; 98 98 return *buff_out; 99 99 } 100 100 EXPORT_SYMBOL_GPL(synth_buffer_peek); 101 + 102 + void synth_buffer_skip_nonlatin1(void) 103 + { 104 + while (buff_out != buff_in) { 105 + if (*buff_out < 0x100) 106 + return; 107 + buff_out++; 108 + if (buff_out > buffer_end) 109 + buff_out = synth_buffer; 110 + } 111 + } 112 + EXPORT_SYMBOL_GPL(synth_buffer_skip_nonlatin1); 101 113 102 114 void synth_buffer_clear(void) 103 115 {
+1 -1
drivers/staging/speakup/speakup.h
··· 66 66 67 67 void spk_do_flush(void); 68 68 void speakup_start_ttys(void); 69 - void synth_buffer_add(char ch); 69 + void synth_buffer_add(u16 ch); 70 70 void synth_buffer_clear(void); 71 71 void speakup_clear_selection(void); 72 72 int speakup_set_selection(struct tty_struct *tty);
+1
drivers/staging/speakup/speakup_acntpc.c
··· 196 196 synth->flush(synth); 197 197 continue; 198 198 } 199 + synth_buffer_skip_nonlatin1(); 199 200 if (synth_buffer_empty()) { 200 201 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 201 202 break;
+1
drivers/staging/speakup/speakup_apollo.c
··· 160 160 synth->flush(synth); 161 161 continue; 162 162 } 163 + synth_buffer_skip_nonlatin1(); 163 164 if (synth_buffer_empty()) { 164 165 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 165 166 break;
+1
drivers/staging/speakup/speakup_decext.c
··· 175 175 synth->flush(synth); 176 176 continue; 177 177 } 178 + synth_buffer_skip_nonlatin1(); 178 179 if (synth_buffer_empty()) { 179 180 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 180 181 break;
+1
drivers/staging/speakup/speakup_decpc.c
··· 390 390 synth->flush(synth); 391 391 continue; 392 392 } 393 + synth_buffer_skip_nonlatin1(); 393 394 if (synth_buffer_empty()) { 394 395 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 395 396 break;
+1
drivers/staging/speakup/speakup_dectlk.c
··· 239 239 synth->flush(synth); 240 240 continue; 241 241 } 242 + synth_buffer_skip_nonlatin1(); 242 243 if (synth_buffer_empty()) { 243 244 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 244 245 break;
+1
drivers/staging/speakup/speakup_dtlk.c
··· 209 209 synth->flush(synth); 210 210 continue; 211 211 } 212 + synth_buffer_skip_nonlatin1(); 212 213 if (synth_buffer_empty()) { 213 214 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 214 215 break;
+1
drivers/staging/speakup/speakup_keypc.c
··· 198 198 synth->flush(synth); 199 199 continue; 200 200 } 201 + synth_buffer_skip_nonlatin1(); 201 202 if (synth_buffer_empty()) { 202 203 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 203 204 break;
+1
drivers/staging/speakup/speakup_soft.c
··· 213 213 spin_lock_irqsave(&speakup_info.spinlock, flags); 214 214 while (1) { 215 215 prepare_to_wait(&speakup_event, &wait, TASK_INTERRUPTIBLE); 216 + synth_buffer_skip_nonlatin1(); 216 217 if (!synth_buffer_empty() || speakup_info.flushing) 217 218 break; 218 219 spin_unlock_irqrestore(&speakup_info.spinlock, flags);
+7 -2
drivers/staging/speakup/spk_priv.h
··· 48 48 int spk_serial_out(const char ch); 49 49 void spk_serial_release(void); 50 50 51 - char synth_buffer_getc(void); 52 - char synth_buffer_peek(void); 51 + void synth_buffer_skip_nonlatin1(void); 52 + u16 synth_buffer_getc(void); 53 + u16 synth_buffer_peek(void); 53 54 int synth_buffer_empty(void); 54 55 struct var_t *spk_get_var(enum var_id_t var_id); 55 56 ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr, ··· 66 65 int spk_synth_is_alive_restart(struct spk_synth *synth); 67 66 __printf(1, 2) 68 67 void synth_printf(const char *buf, ...); 68 + void synth_putwc(u16 wc); 69 + void synth_putwc_s(u16 wc); 70 + void synth_putws(const u16 *buf); 71 + void synth_putws_s(const u16 *buf); 69 72 int synth_request_region(unsigned long start, unsigned long n); 70 73 int synth_release_region(unsigned long start, unsigned long n); 71 74 int synth_add(struct spk_synth *in_synth);
+30
drivers/staging/speakup/synth.c
··· 109 109 synth->flush(synth); 110 110 continue; 111 111 } 112 + synth_buffer_skip_nonlatin1(); 112 113 if (synth_buffer_empty()) { 113 114 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 114 115 break; ··· 255 254 synth_start(); 256 255 } 257 256 EXPORT_SYMBOL_GPL(synth_printf); 257 + 258 + void synth_putwc(u16 wc) 259 + { 260 + synth_buffer_add(wc); 261 + } 262 + EXPORT_SYMBOL_GPL(synth_putwc); 263 + 264 + void synth_putwc_s(u16 wc) 265 + { 266 + synth_buffer_add(wc); 267 + synth_start(); 268 + } 269 + EXPORT_SYMBOL_GPL(synth_putwc_s); 270 + 271 + void synth_putws(const u16 *buf) 272 + { 273 + const u16 *p; 274 + 275 + for (p = buf; *p; p++) 276 + synth_buffer_add(*p); 277 + } 278 + EXPORT_SYMBOL_GPL(synth_putws); 279 + 280 + void synth_putws_s(const u16 *buf) 281 + { 282 + synth_putws(buf); 283 + synth_start(); 284 + } 285 + EXPORT_SYMBOL_GPL(synth_putws_s); 258 286 259 287 static int index_count; 260 288 static int sentence_count;