mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-15 01:24:33 +00:00
staging: speakup: Add unicode support to the speakup_dummy driver
This extends spk_io_ops with a synth_out_unicode which takes a u16 character instead of just a byte, and extends spk_ttyio to implement it to emit utf-8. spk_do_catch_up_unicode can then be introduced to benefit from synth_out_unicode, and speakup_dummy made to use spk_do_catch_up_unicode instead of spk_do_catch_up. Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b8461ff774
commit
65fa72d343
@ -94,7 +94,7 @@ static struct spk_synth synth_dummy = {
|
||||
.probe = spk_ttyio_synth_probe,
|
||||
.release = spk_ttyio_release,
|
||||
.synth_immediate = spk_ttyio_synth_immediate,
|
||||
.catch_up = spk_do_catch_up,
|
||||
.catch_up = spk_do_catch_up_unicode,
|
||||
.flush = spk_synth_flush,
|
||||
.is_alive = spk_synth_is_alive_restart,
|
||||
.synth_adjust = NULL,
|
||||
|
@ -57,6 +57,7 @@ int spk_ttyio_synth_probe(struct spk_synth *synth);
|
||||
const char *spk_serial_synth_immediate(struct spk_synth *synth, const char *buff);
|
||||
const char *spk_ttyio_synth_immediate(struct spk_synth *synth, const char *buff);
|
||||
void spk_do_catch_up(struct spk_synth *synth);
|
||||
void spk_do_catch_up_unicode(struct spk_synth *synth);
|
||||
void spk_synth_flush(struct spk_synth *synth);
|
||||
unsigned char spk_synth_get_index(struct spk_synth *synth);
|
||||
int spk_synth_is_alive_nop(struct spk_synth *synth);
|
||||
|
@ -110,6 +110,7 @@ static struct tty_ldisc_ops spk_ttyio_ldisc_ops = {
|
||||
};
|
||||
|
||||
static int spk_ttyio_out(struct spk_synth *in_synth, const char ch);
|
||||
static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch);
|
||||
static void spk_ttyio_send_xchar(char ch);
|
||||
static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear);
|
||||
static unsigned char spk_ttyio_in(void);
|
||||
@ -118,6 +119,7 @@ static void spk_ttyio_flush_buffer(void);
|
||||
|
||||
struct spk_io_ops spk_ttyio_ops = {
|
||||
.synth_out = spk_ttyio_out,
|
||||
.synth_out_unicode = spk_ttyio_out_unicode,
|
||||
.send_xchar = spk_ttyio_send_xchar,
|
||||
.tiocmset = spk_ttyio_tiocmset,
|
||||
.synth_in = spk_ttyio_in,
|
||||
@ -221,6 +223,22 @@ static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch)
|
||||
{
|
||||
int ret;
|
||||
if (ch < 0x80)
|
||||
ret = spk_ttyio_out(in_synth, ch);
|
||||
else if (ch < 0x800) {
|
||||
ret = spk_ttyio_out(in_synth, 0xc0 | (ch >> 6));
|
||||
ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
|
||||
} else {
|
||||
ret = spk_ttyio_out(in_synth, 0xe0 | (ch >> 12));
|
||||
ret &= spk_ttyio_out(in_synth, 0x80 | ((ch >> 6) & 0x3f));
|
||||
ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_tty(struct tty_struct *tty)
|
||||
{
|
||||
if (!tty) {
|
||||
|
@ -151,6 +151,7 @@ struct spk_synth;
|
||||
|
||||
struct spk_io_ops {
|
||||
int (*synth_out)(struct spk_synth *synth, const char ch);
|
||||
int (*synth_out_unicode)(struct spk_synth *synth, u16 ch);
|
||||
void (*send_xchar)(char ch);
|
||||
void (*tiocmset)(unsigned int set, unsigned int clear);
|
||||
unsigned char (*synth_in)(void);
|
||||
|
@ -52,9 +52,9 @@ static int do_synth_init(struct spk_synth *in_synth);
|
||||
* For devices that have a "full" notification mechanism, the driver can
|
||||
* adapt the loop the way they prefer.
|
||||
*/
|
||||
void spk_do_catch_up(struct spk_synth *synth)
|
||||
static void _spk_do_catch_up(struct spk_synth *synth, int unicode)
|
||||
{
|
||||
u_char ch;
|
||||
u16 ch;
|
||||
unsigned long flags;
|
||||
unsigned long jiff_max;
|
||||
struct var_t *delay_time;
|
||||
@ -63,6 +63,7 @@ void spk_do_catch_up(struct spk_synth *synth)
|
||||
int jiffy_delta_val;
|
||||
int delay_time_val;
|
||||
int full_time_val;
|
||||
int ret;
|
||||
|
||||
jiffy_delta = spk_get_var(JIFFY);
|
||||
full_time = spk_get_var(FULL);
|
||||
@ -81,7 +82,8 @@ void spk_do_catch_up(struct spk_synth *synth)
|
||||
synth->flush(synth);
|
||||
continue;
|
||||
}
|
||||
synth_buffer_skip_nonlatin1();
|
||||
if (!unicode)
|
||||
synth_buffer_skip_nonlatin1();
|
||||
if (synth_buffer_empty()) {
|
||||
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
|
||||
break;
|
||||
@ -92,7 +94,11 @@ void spk_do_catch_up(struct spk_synth *synth)
|
||||
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
|
||||
if (ch == '\n')
|
||||
ch = synth->procspeech;
|
||||
if (!synth->io_ops->synth_out(synth, ch)) {
|
||||
if (unicode)
|
||||
ret = synth->io_ops->synth_out_unicode(synth, ch);
|
||||
else
|
||||
ret = synth->io_ops->synth_out(synth, ch);
|
||||
if (!ret) {
|
||||
schedule_timeout(msecs_to_jiffies(full_time_val));
|
||||
continue;
|
||||
}
|
||||
@ -117,8 +123,19 @@ void spk_do_catch_up(struct spk_synth *synth)
|
||||
}
|
||||
synth->io_ops->synth_out(synth, synth->procspeech);
|
||||
}
|
||||
|
||||
void spk_do_catch_up(struct spk_synth *synth)
|
||||
{
|
||||
_spk_do_catch_up(synth, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spk_do_catch_up);
|
||||
|
||||
void spk_do_catch_up_unicode(struct spk_synth *synth)
|
||||
{
|
||||
_spk_do_catch_up(synth, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spk_do_catch_up_unicode);
|
||||
|
||||
void spk_synth_flush(struct spk_synth *synth)
|
||||
{
|
||||
synth->io_ops->flush_buffer();
|
||||
|
Loading…
x
Reference in New Issue
Block a user