On Thu, Mar 02, 2017 at 02:53:55AM +0100, Samuel Thibault wrote: > This adds 16bit character support to most of the screen reading by > extending characters to u16 throughout the code. > > Non-latin1 characters are assumed to be alphabetic type for now. > > non-latin1 vt_notifier_call-provided characters are not ignored any > more, and the 16bit character returned by get_char is not truncated any > more. For simplicity, speak_char still only supports latin1 characters. > Its direct mode however does support 16bit characters, so in practice > this will not be a limitation, non-latin1 languages will be handled by > the synthesizer. spelling words does not support direct mode yet, for > simplicity for now it will ignore 16bit characters. > > For simplicity again, speakup messages are left in latin1 for now. > > Some coding style is fixed along the way. > > Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> > > Index: linux-4.10/drivers/staging/speakup/main.c > =================================================================== > --- linux-4.10.orig/drivers/staging/speakup/main.c > +++ linux-4.10/drivers/staging/speakup/main.c > @@ -67,7 +67,7 @@ MODULE_PARM_DESC(quiet, "Do not announce > special_func spk_special_handler; > > short spk_pitch_shift, synth_flags; > -static char buf[256]; > +static u16 buf[256]; > int spk_attrib_bleep, spk_bleeps, spk_bleep_time = 10; > int spk_no_intr, spk_spell_delay; > int spk_key_echo, spk_say_word_ctl; > @@ -112,7 +112,7 @@ enum { > > static struct tty_struct *tty; > > -static void spkup_write(const char *in_buf, int count); > +static void spkup_write(const u16 *in_buf, int count); > > static char *phonetic[] = { > "alfa", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", > @@ -238,7 +238,8 @@ static u_short default_chartab[256] = { > struct task_struct *speakup_task; > struct bleep spk_unprocessed_sound; > static int spk_keydown; > -static u_char spk_lastkey, spk_close_press, keymap_flags; > +static u16 spk_lastkey; > +static u_char spk_close_press, keymap_flags; > static u_char last_keycode, this_speakup_key; > static u_long last_spk_jiffy; > > @@ -426,9 +427,9 @@ static void announce_edge(struct vc_data > spk_msg_get(MSG_EDGE_MSGS_START + msg_id - 1)); > } > > -static void speak_char(u_char ch) > +static void speak_char(u16 ch) > { > - char *cp = spk_characters[ch]; > + char *cp; > struct var_t *direct = spk_get_var(DIRECT); > > if (direct && direct->u.n.value) { > @@ -436,11 +437,15 @@ static void speak_char(u_char ch) > spk_pitch_shift++; > synth_printf("%s", spk_str_caps_start); > } > - synth_printf("%c", ch); > + synth_putwc_s(ch); > if (IS_CHAR(ch, B_CAP)) > synth_printf("%s", spk_str_caps_stop); > return; > } > + > + if (ch >= 0x100) > + return; > + cp = spk_characters[ch]; > if (cp == NULL) { > pr_info("speak_char: cp == NULL!\n"); > return; > @@ -486,7 +491,7 @@ static u16 get_char(struct vc_data *vc, > > static void say_char(struct vc_data *vc) > { > - u_short ch; > + u16 ch; > > spk_old_attr = spk_attr; > ch = get_char(vc, (u_short *)spk_pos, &spk_attr); > @@ -496,20 +501,20 @@ static void say_char(struct vc_data *vc) > if (spk_attrib_bleep & 2) > say_attributes(vc); > } > - speak_char(ch & 0xff); > + speak_char(ch); > } > > static void say_phonetic_char(struct vc_data *vc) > { > - u_short ch; > + u16 ch; > > spk_old_attr = spk_attr; > ch = get_char(vc, (u_short *)spk_pos, &spk_attr); > - if (isascii(ch) && isalpha(ch)) { > + if (ch <= 0x7f && isalpha(ch)) { > ch &= 0x1f; > synth_printf("%s\n", phonetic[--ch]); > } else { > - if (IS_CHAR(ch, B_NUM)) > + if (ch < 0x100 && IS_CHAR(ch, B_NUM)) > synth_printf("%s ", spk_msg_get(MSG_NUMBER)); > speak_char(ch); > } > @@ -551,42 +556,42 @@ static void say_next_char(struct vc_data > static u_long get_word(struct vc_data *vc) > { > u_long cnt = 0, tmpx = spk_x, tmp_pos = spk_pos; > - char ch; > - u_short attr_ch; > + u16 ch; > + u16 attr_ch; > u_char temp; > > spk_old_attr = spk_attr; > - ch = (char)get_char(vc, (u_short *)tmp_pos, &temp); > + ch = get_char(vc, (u_short *)tmp_pos, &temp); > > /* decided to take out the sayword if on a space (mis-information */ > if (spk_say_word_ctl && ch == SPACE) { > *buf = '\0'; > synth_printf("%s\n", spk_msg_get(MSG_SPACE)); > return 0; > - } else if ((tmpx < vc->vc_cols - 2) > - && (ch == SPACE || ch == 0 || IS_WDLM(ch)) > - && ((char)get_char(vc, (u_short *)&tmp_pos + 1, &temp) > > - SPACE)) { > + } else if (tmpx < vc->vc_cols - 2 && > + (ch == SPACE || ch == 0 || (ch < 0x100 && IS_WDLM(ch))) && > + get_char(vc, (u_short *)&tmp_pos + 1, &temp) > SPACE) { > tmp_pos += 2; > tmpx++; > } else > while (tmpx > 0) { > - ch = (char)get_char(vc, (u_short *)tmp_pos - 1, &temp); > - if ((ch == SPACE || ch == 0 || IS_WDLM(ch)) > - && ((char)get_char(vc, (u_short *)tmp_pos, &temp) > > - SPACE)) > + ch = get_char(vc, (u_short *)tmp_pos - 1, &temp); > + if ((ch == SPACE || ch == 0 || > + (ch < 0x100 && IS_WDLM(ch))) && > + get_char(vc, (u_short *)tmp_pos, &temp) > SPACE) > break; > tmp_pos -= 2; > tmpx--; > } > attr_ch = get_char(vc, (u_short *)tmp_pos, &spk_attr); > - buf[cnt++] = attr_ch & 0xff; > + buf[cnt++] = attr_ch; > while (tmpx < vc->vc_cols - 1) { > tmp_pos += 2; > tmpx++; > - ch = (char)get_char(vc, (u_short *)tmp_pos, &temp); > - if ((ch == SPACE) || ch == 0 > - || (IS_WDLM(buf[cnt - 1]) && (ch > SPACE))) > + ch = get_char(vc, (u_short *)tmp_pos, &temp); > + if (ch == SPACE || ch == 0 || > + (buf[cnt - 1] < 0x100 && IS_WDLM(buf[cnt - 1]) && > + ch > SPACE)) > break; > buf[cnt++] = ch; > } > @@ -610,7 +615,7 @@ static void say_word(struct vc_data *vc) > static void say_prev_word(struct vc_data *vc) > { > u_char temp; > - char ch; > + u16 ch; > u_short edge_said = 0, last_state = 0, state = 0; > > spk_parked |= 0x01; > @@ -639,10 +644,10 @@ static void say_prev_word(struct vc_data > } else > spk_x--; > spk_pos -= 2; > - ch = (char)get_char(vc, (u_short *)spk_pos, &temp); > + ch = get_char(vc, (u_short *)spk_pos, &temp); > if (ch == SPACE || ch == 0) > state = 0; > - else if (IS_WDLM(ch)) > + else if (ch < 0x100 && IS_WDLM(ch)) > state = 1; > else > state = 2; > @@ -663,7 +668,7 @@ static void say_prev_word(struct vc_data > static void say_next_word(struct vc_data *vc) > { > u_char temp; > - char ch; > + u16 ch; > u_short edge_said = 0, last_state = 2, state = 0; > > spk_parked |= 0x01; > @@ -672,10 +677,10 @@ static void say_next_word(struct vc_data > return; > } > while (1) { > - ch = (char)get_char(vc, (u_short *)spk_pos, &temp); > + ch = get_char(vc, (u_short *)spk_pos, &temp); > if (ch == SPACE || ch == 0) > state = 0; > - else if (IS_WDLM(ch)) > + else if (ch < 0x100 && IS_WDLM(ch)) > state = 1; > else > state = 2; > @@ -703,13 +708,18 @@ static void say_next_word(struct vc_data > static void spell_word(struct vc_data *vc) > { > static char const *delay_str[] = { "", ",", ".", ". .", ". . ." }; > - char *cp = buf, *str_cap = spk_str_caps_stop; > - char *cp1, *last_cap = spk_str_caps_stop; > - u_char ch; > + u16 *cp = buf; > + char *cp1; > + char *str_cap = spk_str_caps_stop; > + char *last_cap = spk_str_caps_stop; > + u16 ch; > > if (!get_word(vc)) > return; > - while ((ch = (u_char)*cp)) { > + while ((ch = *cp)) { > + if (ch >= 0x100) > + /* FIXME */ > + continue; > if (cp != buf) > synth_printf(" %s ", delay_str[spk_spell_delay]); > if (IS_CHAR(ch, B_CAP)) { > @@ -724,9 +734,9 @@ static void spell_word(struct vc_data *v > synth_printf("%s", str_cap); > last_cap = str_cap; > } > - if (this_speakup_key == SPELL_PHONETIC > - && (isascii(ch) && isalpha(ch))) { > - ch &= 31; > + if (this_speakup_key == SPELL_PHONETIC && > + ch <= 0x7f && isalpha(ch)) { > + ch &= 0x1f; > cp1 = phonetic[--ch]; > } else { > cp1 = spk_characters[ch]; > @@ -751,7 +761,7 @@ static int get_line(struct vc_data *vc) > spk_old_attr = spk_attr; > spk_attr = get_attributes(vc, (u_short *)spk_pos); > for (i = 0; i < vc->vc_cols; i++) { > - buf[i] = (u_char)get_char(vc, (u_short *)tmp, &tmp2); > + buf[i] = get_char(vc, (u_short *)tmp, &tmp2); > tmp += 2; > } > for (--i; i >= 0; i--) > @@ -763,7 +773,7 @@ static int get_line(struct vc_data *vc) > static void say_line(struct vc_data *vc) > { > int i = get_line(vc); > - char *cp; > + u16 *cp; > u_short saved_punc_mask = spk_punc_mask; > > if (i == 0) { > @@ -816,7 +826,7 @@ static int say_from_to(struct vc_data *v > spk_old_attr = spk_attr; > spk_attr = get_attributes(vc, (u_short *)from); > while (from < to) { > - buf[i++] = (char)get_char(vc, (u_short *)from, &tmp); > + buf[i++] = get_char(vc, (u_short *)from, &tmp); > from += 2; > if (i >= vc->vc_size_row) > break; > @@ -852,11 +862,11 @@ static void say_line_from_to(struct vc_d > > static int currsentence; > static int numsentences[2]; > -static char *sentbufend[2]; > -static char *sentmarks[2][10]; > +static u16 *sentbufend[2]; > +static u16 *sentmarks[2][10]; > static int currbuf; > static int bn; > -static char sentbuf[2][256]; > +static u16 sentbuf[2][256]; > > static int say_sentence_num(int num, int prev) > { > @@ -892,7 +902,7 @@ static int get_sentence_buf(struct vc_da > spk_attr = get_attributes(vc, (u_short *)start); > > while (start < end) { > - sentbuf[bn][i] = (char)get_char(vc, (u_short *)start, &tmp); > + sentbuf[bn][i] = get_char(vc, (u_short *)start, &tmp); > if (i > 0) { > if (sentbuf[bn][i] == SPACE && sentbuf[bn][i - 1] == '.' > && numsentences[bn] < 9) { > @@ -995,7 +1005,7 @@ static void right_edge(struct vc_data *v > static void say_first_char(struct vc_data *vc) > { > int i, len = get_line(vc); > - u_char ch; > + u16 ch; > > spk_parked |= 0x01; > if (len == 0) { > @@ -1015,7 +1025,7 @@ static void say_first_char(struct vc_dat > static void say_last_char(struct vc_data *vc) > { > int len = get_line(vc); > - u_char ch; > + u16 ch; > > spk_parked |= 0x01; > if (len == 0) { > @@ -1040,9 +1050,8 @@ static void say_position(struct vc_data > static void say_char_num(struct vc_data *vc) > { > u_char tmp; > - u_short ch = get_char(vc, (u_short *)spk_pos, &tmp); > + u16 ch = get_char(vc, (u_short *)spk_pos, &tmp); > > - ch &= 0xff; > synth_printf(spk_msg_get(MSG_CHAR_INFO), ch, ch); > } > > @@ -1070,10 +1079,10 @@ static void say_to_right(struct vc_data > > /* end of stub functions. */ > > -static void spkup_write(const char *in_buf, int count) > +static void spkup_write(const u16 *in_buf, int count) > { > static int rep_count; > - static u_char ch = '\0', old_ch = '\0'; > + static u16 ch = '\0', old_ch = '\0'; > static u_short char_type, last_type; > int in_count = count; > > @@ -1085,8 +1094,11 @@ static void spkup_write(const char *in_b > (currsentence <= numsentences[bn])) > synth_insert_next_index(currsentence++); > } > - ch = (u_char)*in_buf++; > - char_type = spk_chartab[ch]; > + ch = *in_buf++; > + if (ch < 0x100) > + char_type = spk_chartab[ch]; > + else > + char_type = ALPHA; > if (ch == old_ch && !(char_type & B_NUM)) { > if (++rep_count > 2) > continue; > @@ -1106,10 +1118,10 @@ static void spkup_write(const char *in_b > } else if (char_type & B_ALPHA) { > if ((synth_flags & SF_DEC) && (last_type & PUNC)) > synth_buffer_add(SPACE); > - synth_printf("%c", ch); > + synth_putwc_s(ch); > } else if (char_type & B_NUM) { > rep_count = 0; > - synth_printf("%c", ch); > + synth_putwc_s(ch); > } else if (char_type & spk_punc_mask) { > speak_char(ch); > char_type &= ~PUNC; /* for dec nospell processing */ > @@ -1122,7 +1134,7 @@ static void spkup_write(const char *in_b > * repeats on you don't get nothing repeated count > */ > if (ch != old_ch) > - synth_printf("%c", ch); > + synth_putwc_s(ch); > else > rep_count = 0; > } else { > @@ -1533,7 +1545,7 @@ static void do_handle_cursor(struct vc_d > spin_unlock_irqrestore(&speakup_info.spinlock, flags); > } > > -static void update_color_buffer(struct vc_data *vc, const char *ic, int len) > +static void update_color_buffer(struct vc_data *vc, const u16 *ic, int len) > { > int i, bi, hi; > int vc_num = vc->vc_num; > @@ -1548,7 +1560,7 @@ static void update_color_buffer(struct v > speakup_console[vc_num]->ht.ry[bi] = vc->vc_y; > } > while ((hi < COLOR_BUFFER_SIZE) && (i < len)) { > - if ((ic[i] > 32) && (ic[i] < 127)) { > + if (ic[i] > 32) { > speakup_console[vc_num]->ht.highbuf[bi][hi] = ic[i]; > hi++; > } else if ((ic[i] == 32) && (hi != 0)) { > @@ -1718,7 +1730,7 @@ static void speakup_bs(struct vc_data *v > } > > /* called by: vt_notifier_call() */ > -static void speakup_con_write(struct vc_data *vc, const char *str, int len) > +static void speakup_con_write(struct vc_data *vc, u16 *str, int len) > { > unsigned long flags; > > @@ -1908,6 +1920,7 @@ static int handle_goto(struct vc_data *v > static int num; > int maxlen; > char *cp; > + u16 wch; > > if (type == KT_SPKUP && ch == SPEAKUP_GOTO) > goto do_goto; > @@ -1916,18 +1929,20 @@ static int handle_goto(struct vc_data *v > if (type != 0) > goto oops; > if (ch == 8) { > + u16 wch; > if (num == 0) > return -1; > - ch = goto_buf[--num]; > + wch = goto_buf[--num]; > goto_buf[num] = '\0'; > - spkup_write(&ch, 1); > + spkup_write(&wch, 1); > return 1; > } > if (ch < '+' || ch > 'y') > goto oops; > + wch = ch; > goto_buf[num++] = ch; > goto_buf[num] = '\0'; > - spkup_write(&ch, 1); > + spkup_write(&wch, 1); > maxlen = (*goto_buf >= '0') ? 3 : 4; > if ((ch == '+' || ch == '-') && num == 1) > return 1; > @@ -2254,9 +2269,8 @@ static int vt_notifier_call(struct notif > case VT_WRITE: > if (param->c == '\b') > speakup_bs(vc); > - else if (param->c < 0x100) { > - char d = param->c; > - > + else { > + u16 d = param->c; > speakup_con_write(vc, &d, 1); > } > break; > Index: linux-4.10/drivers/staging/speakup/spk_types.h > =================================================================== > --- linux-4.10.orig/drivers/staging/speakup/spk_types.h > +++ linux-4.10/drivers/staging/speakup/spk_types.h > @@ -55,7 +55,7 @@ struct spk_highlight_color_track { > /* Count of each background color */ > unsigned int bgcount[8]; > /* Buffer for characters drawn with each background color */ > - char highbuf[8][COLOR_BUFFER_SIZE]; > + u16 highbuf[8][COLOR_BUFFER_SIZE]; > /* Current index into highbuf */ > unsigned int highsize[8]; > /* Reading Position for each color */ > Index: linux-4.10/drivers/staging/speakup/speakup.h > =================================================================== > --- linux-4.10.orig/drivers/staging/speakup/speakup.h > +++ linux-4.10/drivers/staging/speakup/speakup.h > @@ -38,6 +38,7 @@ > #define B_SYM 0x0800 > #define B_CAPSYM (B_CAP|B_SYM) > > +/* FIXME: u16 */ > #define IS_WDLM(x) (spk_chartab[((u_char)x)]&B_WDLM) > #define IS_CHAR(x, type) (spk_chartab[((u_char)x)]&type) > #define IS_TYPE(x, type) ((spk_chartab[((u_char)x)]&type) == type) Reviewed-by: Okash Khawaja <okash.khawaja@xxxxxxxxx> _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel