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