Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/accessibility/speakup/buffers.c
26282 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <linux/console.h>
3
#include <linux/types.h>
4
#include <linux/wait.h>
5
6
#include "speakup.h"
7
#include "spk_priv.h"
8
9
#define SYNTH_BUF_SIZE 8192 /* currently 8K bytes */
10
11
static u16 synth_buffer[SYNTH_BUF_SIZE]; /* guess what this is for! */
12
static u16 *buff_in = synth_buffer;
13
static u16 *buff_out = synth_buffer;
14
static u16 *buffer_end = synth_buffer + SYNTH_BUF_SIZE - 1;
15
16
/* These try to throttle applications by stopping the TTYs
17
* Note: we need to make sure that we will restart them eventually, which is
18
* usually not possible to do from the notifiers. TODO: it should be possible
19
* starting from linux 2.6.26.
20
*
21
* So we only stop when we know alive == 1 (else we discard the data anyway),
22
* and the alive synth will eventually call start_ttys from the thread context.
23
*/
24
void speakup_start_ttys(void)
25
{
26
int i;
27
28
for (i = 0; i < MAX_NR_CONSOLES; i++) {
29
if (speakup_console[i] && speakup_console[i]->tty_stopped)
30
continue;
31
if (vc_cons[i].d && vc_cons[i].d->port.tty)
32
start_tty(vc_cons[i].d->port.tty);
33
}
34
}
35
EXPORT_SYMBOL_GPL(speakup_start_ttys);
36
37
static void speakup_stop_ttys(void)
38
{
39
int i;
40
41
for (i = 0; i < MAX_NR_CONSOLES; i++)
42
if (vc_cons[i].d && vc_cons[i].d->port.tty)
43
stop_tty(vc_cons[i].d->port.tty);
44
}
45
46
static int synth_buffer_free(void)
47
{
48
int chars_free;
49
50
if (buff_in >= buff_out)
51
chars_free = SYNTH_BUF_SIZE - (buff_in - buff_out);
52
else
53
chars_free = buff_out - buff_in;
54
return chars_free;
55
}
56
57
int synth_buffer_empty(void)
58
{
59
return (buff_in == buff_out);
60
}
61
EXPORT_SYMBOL_GPL(synth_buffer_empty);
62
63
void synth_buffer_add(u16 ch)
64
{
65
if (!synth->alive) {
66
/* This makes sure that we won't stop TTYs if there is no synth
67
* to restart them
68
*/
69
return;
70
}
71
if (synth_buffer_free() <= 100) {
72
synth_start();
73
speakup_stop_ttys();
74
}
75
if (synth_buffer_free() <= 1)
76
return;
77
*buff_in++ = ch;
78
if (buff_in > buffer_end)
79
buff_in = synth_buffer;
80
/* We have written something to the speech synthesis, so we are not
81
* paused any more.
82
*/
83
spk_paused = false;
84
}
85
86
u16 synth_buffer_getc(void)
87
{
88
u16 ch;
89
90
if (buff_out == buff_in)
91
return 0;
92
ch = *buff_out++;
93
if (buff_out > buffer_end)
94
buff_out = synth_buffer;
95
return ch;
96
}
97
EXPORT_SYMBOL_GPL(synth_buffer_getc);
98
99
u16 synth_buffer_peek(void)
100
{
101
if (buff_out == buff_in)
102
return 0;
103
return *buff_out;
104
}
105
EXPORT_SYMBOL_GPL(synth_buffer_peek);
106
107
void synth_buffer_skip_nonlatin1(void)
108
{
109
while (buff_out != buff_in) {
110
if (*buff_out < 0x100)
111
return;
112
buff_out++;
113
if (buff_out > buffer_end)
114
buff_out = synth_buffer;
115
}
116
}
117
EXPORT_SYMBOL_GPL(synth_buffer_skip_nonlatin1);
118
119
void synth_buffer_clear(void)
120
{
121
buff_in = synth_buffer;
122
buff_out = synth_buffer;
123
}
124
EXPORT_SYMBOL_GPL(synth_buffer_clear);
125
126