[elinks-dev] Reading out documents using festival
Witold Filipczyk
witekfl at poczta.onet.pl
Fri Dec 1 16:35:27 MST 2006
Hi!
If you apply this patch ELinks will read out documents.
Simply press 'R' (r with SHIFT) and 'R' again to switch off.
For speech the festival program is required.
I hope it will be included in 0.12.
Don't ask me to cleanup the code. Do it yourself!
Witek
--
Szukam pracy
-------------- next part --------------
diff --git a/src/config/actions-main.inc b/src/config/actions-main.inc
index 9626c9d..939943d 100644
--- a/src/config/actions-main.inc
+++ b/src/config/actions-main.inc
@@ -85,6 +85,7 @@ ACTION_(MAIN, "save-as", SAVE_AS, N__("S
ACTION_(MAIN, "save-formatted", SAVE_FORMATTED, N__("Save the current document in formatted form"), ACTION_RESTRICT_ANONYMOUS | ACTION_REQUIRE_VIEW_STATE | ACTION_REQUIRE_LOCATION),
ACTION_(MAIN, "save-options", SAVE_OPTIONS, N__("Save options"), ACTION_RESTRICT_ANONYMOUS),
ACTION_(MAIN, "save-url-as", SAVE_URL_AS, N__("Save URL as"), ACTION_RESTRICT_ANONYMOUS),
+ACTION_(MAIN, "say-text", SAY_TEXT, N__("Reads out the document"), ACTION_REQUIRE_VIEW_STATE),
ACTION_(MAIN, "scroll-down", SCROLL_DOWN, N__("Scroll down"), ACTION_REQUIRE_VIEW_STATE),
ACTION_(MAIN, "scroll-left", SCROLL_LEFT, N__("Scroll left"), ACTION_REQUIRE_VIEW_STATE),
ACTION_(MAIN, "scroll-right", SCROLL_RIGHT, N__("Scroll right"), ACTION_REQUIRE_VIEW_STATE),
diff --git a/src/config/kbdbind.c b/src/config/kbdbind.c
index 378ba8f..1aafe61 100644
--- a/src/config/kbdbind.c
+++ b/src/config/kbdbind.c
@@ -662,6 +662,7 @@ static struct default_kb default_main_ke
{ { 'N', KBD_MOD_CTRL }, ACT_MAIN_SCROLL_DOWN },
{ { 'P', KBD_MOD_CTRL }, ACT_MAIN_SCROLL_UP },
{ { 'Q', KBD_MOD_NONE }, ACT_MAIN_REALLY_QUIT },
+ { { 'R', KBD_MOD_NONE }, ACT_MAIN_SAY_TEXT },
{ { 'R', KBD_MOD_CTRL }, ACT_MAIN_RELOAD },
{ { 'T', KBD_MOD_NONE }, ACT_MAIN_OPEN_LINK_IN_NEW_TAB_IN_BACKGROUND },
{ { 'W', KBD_MOD_NONE }, ACT_MAIN_TOGGLE_WRAP_TEXT },
diff --git a/src/main/main.c b/src/main/main.c
index 5901665..d8f2029 100644
--- a/src/main/main.c
+++ b/src/main/main.c
@@ -52,6 +52,7 @@ #include "util/file.h"
#include "util/memdebug.h"
#include "util/memory.h"
#include "viewer/dump/dump.h"
+#include "viewer/text/festival.h"
#include "viewer/text/marks.h"
struct program program;
@@ -109,6 +110,9 @@ init(void)
int fd = -1;
enum retval ret;
+ festival.in = -1;
+ festival.out = -1;
+
init_osdep();
check_cwd();
diff --git a/src/viewer/action.c b/src/viewer/action.c
index 3089a19..7d3a3ab 100644
--- a/src/viewer/action.c
+++ b/src/viewer/action.c
@@ -39,6 +39,7 @@ #include "session/session.h"
#include "session/task.h"
#include "viewer/action.h"
#include "viewer/text/draw.h"
+#include "viewer/text/festival.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/search.h"
@@ -472,6 +473,10 @@ #endif
save_url_as(ses);
break;
+ case ACT_MAIN_SAY_TEXT:
+ run_festival(ses, doc_view);
+ break;
+
case ACT_MAIN_SCROLL_DOWN:
status = scroll_down(ses, doc_view);
break;
diff --git a/src/viewer/text/Makefile b/src/viewer/text/Makefile
index 06190f1..1a843a7 100644
--- a/src/viewer/text/Makefile
+++ b/src/viewer/text/Makefile
@@ -3,6 +3,6 @@ include $(top_builddir)/Makefile.config
OBJS-$(CONFIG_MARKS) += marks.o
-OBJS = draw.o form.o link.o search.o textarea.o view.o vs.o
+OBJS = draw.o festival.o form.o link.o search.o textarea.o view.o vs.o
include $(top_srcdir)/Makefile.lib
--- /dev/null 2004-07-16 04:05:52.000000000 +0200
+++ b/src/viewer/text/festival.c 2006-12-02 00:15:05.000000000 +0100
@@ -0,0 +1,141 @@
+/* festival */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "elinks.h"
+
+#include "document/document.h"
+#include "document/view.h"
+#include "main/select.h"
+#include "osdep/osdep.h"
+#include "protocol/common.h"
+#include "util/string.h"
+#include "viewer/action.h"
+#include "viewer/text/festival.h"
+#include "viewer/text/vs.h"
+
+struct fest festival;
+
+static void read_from_festival(struct fest *);
+static void write_to_festival(struct fest *);
+
+static void
+read_from_festival(struct fest *fest)
+{
+ while (1) {
+ unsigned char input[512];
+ int r = safe_read(fest->in, input, 512);
+
+ if (r <= 0) break;
+ if (input[r - 1] == ' ') {
+ write_to_festival(fest);
+ break;
+ }
+ }
+ set_handlers(fest->in, (select_handler_T) read_from_festival,
+ NULL, NULL, fest);
+}
+
+static void
+write_to_festival(struct fest *fest)
+{
+ struct string buf;
+ int i, w;
+ int len;
+ struct document *doc = fest->doc_view->document;
+ struct screen_char *data;
+
+ if (fest->line >= fest->doc_view->document->height)
+ fest->running = 0;
+ if (!fest->running)
+ return;
+
+ len = doc->data[fest->line].length;
+ int_upper_bound(&len, 512);
+
+ if (!init_string(&buf))
+ return;
+
+ data = doc->data[fest->line].chars;
+ add_to_string(&buf, "(SayText \"");
+ for (i = 0; i < len; i++) {
+ unsigned char ch = (data[i].data == '"' ? ' ' : (unsigned char)data[i].data);
+
+ add_char_to_string(&buf, ch);
+ }
+ add_to_string(&buf, "\")\n");
+
+ w = safe_write(fest->out, buf.source, buf.length);
+ if (w >= 0) {
+ fest->line++;
+ }
+ done_string(&buf);
+}
+
+static int
+init_festival(void)
+{
+ int in_pipe[2] = {-1, -1};
+ int out_pipe[2] = {-1, -1};
+ pid_t cpid;
+
+ if (access("/usr/bin/festival", X_OK))
+ return 1;
+
+ if (c_pipe(in_pipe) || c_pipe(out_pipe)) {
+ if (in_pipe[0] >= 0) close(in_pipe[0]);
+ if (in_pipe[1] >= 0) close(in_pipe[1]);
+ if (out_pipe[0] >= 0) close(out_pipe[0]);
+ if (out_pipe[1] >= 0) close(out_pipe[1]);
+ return 1;
+ }
+
+ cpid = fork();
+ if (cpid == -1) {
+ close(in_pipe[0]);
+ close(in_pipe[1]);
+ close(out_pipe[0]);
+ close(out_pipe[1]);
+ return 1;
+ }
+ if (!cpid) {
+ dup2(out_pipe[1], 1);
+ dup2(in_pipe[0], 0);
+ close(out_pipe[0]);
+ close(in_pipe[1]);
+ close(2);
+ close_all_non_term_fd();
+ execl("/usr/bin/festival", "festival", "-i", NULL);
+ _exit(0);
+ } else {
+ close(out_pipe[1]);
+ close(in_pipe[0]);
+ festival.in = out_pipe[0];
+ festival.out = in_pipe[1];
+ set_handlers(festival.in, (select_handler_T) read_from_festival,
+ NULL, NULL, &festival);
+ return 0;
+ }
+}
+
+void
+run_festival(struct session *ses, struct document_view *doc_view)
+{
+ if (festival.in == -1 && init_festival())
+ return;
+
+ festival.doc_view = doc_view;
+ festival.line = doc_view->vs->y;
+ festival.running = !festival.running;
+
+ if (festival.running) {
+ write_to_festival(&festival);
+ }
+}
--- /dev/null 2004-07-16 04:05:52.000000000 +0200
+++ b/src/viewer/text/festival.h 2006-12-02 00:15:50.000000000 +0100
@@ -0,0 +1,19 @@
+
+#ifndef EL__VIEWER_TEXT_FESTIVAL_H
+#define EL__VIEWER_TEXT_FESTIVAL_H
+
+struct session;
+struct document_view;
+
+struct fest {
+ struct document_view *doc_view;
+ int line;
+ int in;
+ int out;
+ unsigned int running:1;
+};
+
+extern struct fest festival;
+void run_festival(struct session *, struct document_view *);
+
+#endif
More information about the elinks-dev
mailing list