Commit 65fa72d3 authored by Samuel Thibault's avatar Samuel Thibault Committed by Greg Kroah-Hartman

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: default avatarSamuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b8461ff7
...@@ -94,7 +94,7 @@ static struct spk_synth synth_dummy = { ...@@ -94,7 +94,7 @@ static struct spk_synth synth_dummy = {
.probe = spk_ttyio_synth_probe, .probe = spk_ttyio_synth_probe,
.release = spk_ttyio_release, .release = spk_ttyio_release,
.synth_immediate = spk_ttyio_synth_immediate, .synth_immediate = spk_ttyio_synth_immediate,
.catch_up = spk_do_catch_up, .catch_up = spk_do_catch_up_unicode,
.flush = spk_synth_flush, .flush = spk_synth_flush,
.is_alive = spk_synth_is_alive_restart, .is_alive = spk_synth_is_alive_restart,
.synth_adjust = NULL, .synth_adjust = NULL,
......
...@@ -57,6 +57,7 @@ int spk_ttyio_synth_probe(struct spk_synth *synth); ...@@ -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_serial_synth_immediate(struct spk_synth *synth, const char *buff);
const char *spk_ttyio_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(struct spk_synth *synth);
void spk_do_catch_up_unicode(struct spk_synth *synth);
void spk_synth_flush(struct spk_synth *synth); void spk_synth_flush(struct spk_synth *synth);
unsigned char spk_synth_get_index(struct spk_synth *synth); unsigned char spk_synth_get_index(struct spk_synth *synth);
int spk_synth_is_alive_nop(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 = { ...@@ -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(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_send_xchar(char ch);
static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear); static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear);
static unsigned char spk_ttyio_in(void); static unsigned char spk_ttyio_in(void);
...@@ -118,6 +119,7 @@ static void spk_ttyio_flush_buffer(void); ...@@ -118,6 +119,7 @@ static void spk_ttyio_flush_buffer(void);
struct spk_io_ops spk_ttyio_ops = { struct spk_io_ops spk_ttyio_ops = {
.synth_out = spk_ttyio_out, .synth_out = spk_ttyio_out,
.synth_out_unicode = spk_ttyio_out_unicode,
.send_xchar = spk_ttyio_send_xchar, .send_xchar = spk_ttyio_send_xchar,
.tiocmset = spk_ttyio_tiocmset, .tiocmset = spk_ttyio_tiocmset,
.synth_in = spk_ttyio_in, .synth_in = spk_ttyio_in,
...@@ -221,6 +223,22 @@ static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) ...@@ -221,6 +223,22 @@ static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
return 0; 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) static int check_tty(struct tty_struct *tty)
{ {
if (!tty) { if (!tty) {
......
...@@ -151,6 +151,7 @@ struct spk_synth; ...@@ -151,6 +151,7 @@ struct spk_synth;
struct spk_io_ops { struct spk_io_ops {
int (*synth_out)(struct spk_synth *synth, const char ch); 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 (*send_xchar)(char ch);
void (*tiocmset)(unsigned int set, unsigned int clear); void (*tiocmset)(unsigned int set, unsigned int clear);
unsigned char (*synth_in)(void); unsigned char (*synth_in)(void);
......
...@@ -52,9 +52,9 @@ static int do_synth_init(struct spk_synth *in_synth); ...@@ -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 * For devices that have a "full" notification mechanism, the driver can
* adapt the loop the way they prefer. * 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 flags;
unsigned long jiff_max; unsigned long jiff_max;
struct var_t *delay_time; struct var_t *delay_time;
...@@ -63,6 +63,7 @@ void spk_do_catch_up(struct spk_synth *synth) ...@@ -63,6 +63,7 @@ void spk_do_catch_up(struct spk_synth *synth)
int jiffy_delta_val; int jiffy_delta_val;
int delay_time_val; int delay_time_val;
int full_time_val; int full_time_val;
int ret;
jiffy_delta = spk_get_var(JIFFY); jiffy_delta = spk_get_var(JIFFY);
full_time = spk_get_var(FULL); full_time = spk_get_var(FULL);
...@@ -81,7 +82,8 @@ void spk_do_catch_up(struct spk_synth *synth) ...@@ -81,7 +82,8 @@ void spk_do_catch_up(struct spk_synth *synth)
synth->flush(synth); synth->flush(synth);
continue; continue;
} }
synth_buffer_skip_nonlatin1(); if (!unicode)
synth_buffer_skip_nonlatin1();
if (synth_buffer_empty()) { if (synth_buffer_empty()) {
spin_unlock_irqrestore(&speakup_info.spinlock, flags); spin_unlock_irqrestore(&speakup_info.spinlock, flags);
break; break;
...@@ -92,7 +94,11 @@ void spk_do_catch_up(struct spk_synth *synth) ...@@ -92,7 +94,11 @@ void spk_do_catch_up(struct spk_synth *synth)
spin_unlock_irqrestore(&speakup_info.spinlock, flags); spin_unlock_irqrestore(&speakup_info.spinlock, flags);
if (ch == '\n') if (ch == '\n')
ch = synth->procspeech; 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)); schedule_timeout(msecs_to_jiffies(full_time_val));
continue; continue;
} }
...@@ -117,8 +123,19 @@ void spk_do_catch_up(struct spk_synth *synth) ...@@ -117,8 +123,19 @@ void spk_do_catch_up(struct spk_synth *synth)
} }
synth->io_ops->synth_out(synth, synth->procspeech); 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); 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) void spk_synth_flush(struct spk_synth *synth)
{ {
synth->io_ops->flush_buffer(); synth->io_ops->flush_buffer();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment