Received: by 10.223.185.111 with SMTP id b44csp1307972wrg; Sat, 10 Mar 2018 03:04:13 -0800 (PST) X-Google-Smtp-Source: AG47ELtbNEM8ujchk2bzv/IGyZ2KubFdBd/LWpf/RH7oZw8mLeh7bXqwylm/flzyZ6S6ET0/Cmlh X-Received: by 2002:a17:902:7008:: with SMTP id y8-v6mr1781131plk.395.1520679853237; Sat, 10 Mar 2018 03:04:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520679853; cv=none; d=google.com; s=arc-20160816; b=UisSEbVskHoBj2KyWOsxQsqR5v8dR9V3m2T/NeSrAUC3P21iGAZtJbjkBRfvGqdPL7 vtMg9aj5+QravY5brXol5H9SdKSo6W5ywQGIxL7kMyqZFxRZC5yldnetgIu1YMWkEC9a u637/8oYViR4m1a6RQ9Cqmct706GQKKKmKkC6Gapq96J5Bs8o9gt2WsaCHIyXfJJE1+R r/XoW/n+Rcw4JcLmUTpuvF7krCUXcsCWR7nFG4WKyX5HVm1p+52yaUcHeuhnKXW2TSAM Fkkay63RyxtGkArGqC1w5jTrY2xGaF7gFShJs79n5gp6sTOX1HvnSfEzQwZBvVpkW0EE wtfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:organization :content-disposition:mime-version:mail-followup-to:message-id :subject:cc:to:from:date:arc-authentication-results; bh=+F9oMyjOAMr9rbc/hiFb/WxYezFdQNG3drLhWJFxk6k=; b=nwsiTvsQpNqAzPdWusRyzDTW99I2qDzl4K/vl7vRx7ORVBGOS7DI1JCOmNkU1pZd6W S3B4wJ85bejcUDz2B5yTaJ37A/ceZc6U0ifl9dMG3JDALjPB2xaqAhC8EyRFL4HZpLGi oX41x+o5YdQ5Ku1Dx6PvbpjkdK66TLtWDzYBqbzvGXmS2Tbmi69fgAwZRce1AXJ2CTSc S0wBThfu57A/5T8pPGkz1x6mJUOBC/6pWb4wH5wfiOdsRNncbzwhg+2TWuGZ6FiM219j Qb6HsykuuWXtevNfdWFZ4kiqy6wKiiO0G1lK4nM0R7zgVAFkL3DiXEinxpKllLzRTx/v MF+w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 18si2540480pfj.366.2018.03.10.03.03.58; Sat, 10 Mar 2018 03:04:13 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752092AbeCJLDG (ORCPT + 99 others); Sat, 10 Mar 2018 06:03:06 -0500 Received: from hera.aquilenet.fr ([185.233.100.1]:45024 "EHLO hera.aquilenet.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751974AbeCJLDF (ORCPT ); Sat, 10 Mar 2018 06:03:05 -0500 X-Greylist: delayed 390 seconds by postgrey-1.27 at vger.kernel.org; Sat, 10 Mar 2018 06:03:04 EST Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 45B0B11E5E; Sat, 10 Mar 2018 11:56:32 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XTD5KweVA-pV; Sat, 10 Mar 2018 11:56:31 +0100 (CET) Received: from var.youpi.perso.aquilenet.fr (static-176-158-111-12.ftth.abo.bbox.fr [176.158.111.12]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 466EFDAF2; Sat, 10 Mar 2018 11:56:31 +0100 (CET) Received: from samy by var.youpi.perso.aquilenet.fr with local (Exim 4.90_1) (envelope-from ) id 1eucAt-0004m6-Fz; Sat, 10 Mar 2018 11:56:27 +0100 Date: Sat, 10 Mar 2018 11:56:27 +0100 From: Samuel Thibault To: gregkh@linuxfoundation.org, w.d.hubbs@gmail.com, chris@the-brannons.com, kirk@reisers.ca Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, speakup@linux-speakup.org Subject: [PATCH] staging: speakup: Add unicode support to the speakup_dummy driver Message-ID: <20180310105627.lzy35if76vedfvv7@var.youpi.perso.aquilenet.fr> Mail-Followup-To: Samuel Thibault , gregkh@linuxfoundation.org, w.d.hubbs@gmail.com, chris@the-brannons.com, kirk@reisers.ca, devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, speakup@linux-speakup.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Organization: I am not organized User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 Index: linux-4.15/drivers/staging/speakup/spk_types.h =================================================================== --- linux-4.15.orig/drivers/staging/speakup/spk_types.h +++ linux-4.15/drivers/staging/speakup/spk_types.h @@ -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); Index: linux-4.15/drivers/staging/speakup/spk_ttyio.c =================================================================== --- linux-4.15.orig/drivers/staging/speakup/spk_ttyio.c +++ linux-4.15/drivers/staging/speakup/spk_ttyio.c @@ -109,6 +109,7 @@ static struct tty_ldisc_ops spk_ttyio_ld }; 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); @@ -117,6 +118,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, @@ -220,6 +222,22 @@ static int spk_ttyio_out(struct spk_synt 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) { Index: linux-4.15/drivers/staging/speakup/synth.c =================================================================== --- linux-4.15.orig/drivers/staging/speakup/synth.c +++ linux-4.15/drivers/staging/speakup/synth.c @@ -51,9 +51,9 @@ static int do_synth_init(struct spk_synt * 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; @@ -62,6 +62,7 @@ void spk_do_catch_up(struct spk_synth *s 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); @@ -80,7 +81,8 @@ void spk_do_catch_up(struct spk_synth *s 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; @@ -91,7 +93,11 @@ void spk_do_catch_up(struct spk_synth *s 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; } @@ -116,8 +122,19 @@ void spk_do_catch_up(struct spk_synth *s } 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(); Index: linux-4.15/drivers/staging/speakup/spk_priv.h =================================================================== --- linux-4.15.orig/drivers/staging/speakup/spk_priv.h +++ linux-4.15/drivers/staging/speakup/spk_priv.h @@ -66,6 +66,7 @@ int spk_ttyio_synth_probe(struct spk_syn 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); Index: linux-4.15/drivers/staging/speakup/speakup_dummy.c =================================================================== --- linux-4.15.orig/drivers/staging/speakup/speakup_dummy.c +++ linux-4.15/drivers/staging/speakup/speakup_dummy.c @@ -103,7 +103,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,