struct speakup_info_t speakup_info = { /* * This spinlock is used to protect the entire speakup machinery, and * must be taken at each kernel->speakup transition and released at * each corresponding speakup->kernel transition. * * The progression thread only interferes with the speakup machinery * through the synth buffer, so only needs to take the lock * while tinkering with the buffer. * * We use spin_lock/trylock_irqsave and spin_unlock_irqrestore with this * spinlock because speakup needs to disable the keyboard IRQ.
*/
.spinlock = __SPIN_LOCK_UNLOCKED(speakup_info.spinlock),
.flushing = 0,
};
EXPORT_SYMBOL_GPL(speakup_info);
/* * Main loop of the progression thread: keep eating from the buffer * and push to the serial port, waiting as needed * * For devices that have a "full" notification mechanism, the driver can * adapt the loop the way they prefer.
*/ staticvoid _spk_do_catch_up(struct spk_synth *synth, int unicode)
{
u16 ch; unsignedlong flags; unsignedlong jiff_max; struct var_t *delay_time; struct var_t *full_time; struct var_t *jiffy_delta; int jiffy_delta_val; int delay_time_val; int full_time_val; int ret;
while (count--)
synth_buffer_add(*buf++);
synth_start();
}
/* Consume one utf-8 character from buf (that contains up to count bytes), * returns the unicode codepoint if valid, -1 otherwise. * In all cases, returns the number of consumed bytes in *consumed, * and the minimum number of bytes that would be needed for the next character * in *want.
*/
s32 synth_utf8_get(constchar *buf, size_t count, size_t *consumed, size_t *want)
{ unsignedchar c = buf[0]; int nbytes = 8 - fls(c ^ 0xff);
u32 value;
size_t i;
switch (nbytes) { case 8: /* 0xff */ case 7: /* 0xfe */ case 1: /* 0x80 */ /* Invalid, drop */
*consumed = 1;
*want = 1; return -1;
case 0: /* ASCII, take as such */
*consumed = 1;
*want = 1; return c;
default: /* 2..6-byte UTF-8 */
if (count < nbytes) { /* We don't have it all */
*consumed = 0;
*want = nbytes; return -1;
}
/* First byte */
value = c & ((1u << (7 - nbytes)) - 1);
/* Other bytes */ for (i = 1; i < nbytes; i++) {
c = buf[i]; if ((c & 0xc0) != 0x80) { /* Invalid, drop the head */
*consumed = i;
*want = 1; return -1;
}
value = (value << 6) | (c & 0x3f);
}
*consumed = nbytes;
*want = 1; return value;
}
}
void synth_writeu(constchar *buf, size_t count)
{
size_t i, consumed, want;
/* Convert to u16 */ for (i = 0; i < count; i++) {
s32 value;
value = synth_utf8_get(buf + i, count - i, &consumed, &want); if (value == -1) { /* Invalid or incomplete */
if (want > count - i) /* We don't have it all, stop */
count = i;
mutex_lock(&spk_mutex); /* First, check if we already have it loaded. */
list_for_each_entry(tmp, &synths, node) { if (strcmp(tmp->name, synth_name) == 0)
synth = tmp;
}
/* If we got one, initialize it now. */ if (synth)
ret = do_synth_init(synth); else
ret = -ENODEV;
mutex_unlock(&spk_mutex);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.12Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.