branch: externals/greader
commit 8456eb5ed969bbbb5172f09c47df8320644d9ecf
Author: Michelangelo Rodriguez <michelangelo.rodrig...@gmail.com>
Commit: Michelangelo Rodriguez <michelangelo.rodrig...@gmail.com>

    greader-speechd.el: Option `greader-speechd-handle-server'
    implemented.
    
    This is, i hope, only a workaround while i discover the real problem
    in the interaction between speech-dispatcher, spd-say and emacs.
    The variable `greader-speechd-handle-server' enables greader to manage
    the speech-dispatcher server. This implies that if there are an
    instance of the server already running it will be killed and greader
    will start a new one with the appropriate parameters to keep
    speech-dispatcher running properly.
    At this moment, if we don't enable this option, when we use
    `greader-speechd' backend, the reading stops at the end of the first
    sentence spoken.
    I don't know why that happens, but maybe it has to do with timing
    between spd-say, the client, and speech-dispatcher.
    The reason for which i think so is that if we launch speech-dispatcher
    with the flags -s or -d and we disable the timer with -t0, things work
    properly and greader reads as usual.
    But the idea of killing an instance of a process is very very bad, so
    i hope to find another way to fix this.
---
 greader-speechd.el | 52 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/greader-speechd.el b/greader-speechd.el
index 74c230b428..4c5889c69d 100644
--- a/greader-speechd.el
+++ b/greader-speechd.el
@@ -20,13 +20,48 @@
 ;; 
 
 ;;; Code:
-
+(require 'ring)
 ;;; customization variables
 (defgroup greader-speechd
   nil
   "Speech-dispatcher back-end for greader."
   :group 'greader)
 
+(defcustom greader-speechd-handle-server nil
+  "automatically handle of server.
+If this variable is set, greader will check if there is a running
+instance of `speech-dispatcher', kill it and relaunch with the correct
+parameters to make it work properly with greader.
+Alternatively, you can start speech-dispatcher as daemon, and with
+timer disabled as in:
+`$ speech-dispatcher -d -t0'.
+Use this variable with caution, especially if you are using other
+assistive technologies that rely on speech-dispatcher."
+  :type 'boolean)
+
+(defvar greader-speechd-server nil
+  "contains the instance of speech-dispatcher server, or nil if
+`greader-speechd-handle-server' is enabled.")
+
+(defun greader-speechd-start-server ()
+  "Start speech-dispatcher.
+If there are other instances of speech-dispatcher, this function will
+kill them first. This function does nothing when
+`greader-speechd-handle-server' is disabled."
+  (when
+      (and greader-speechd-handle-server (not greader-speechd-server))
+    (call-process "killall" nil 0 nil "speech-dispatcher")
+    ;; Now we start `speech-dispatcher' with -s, that means we want a
+    ;; single application instance, and with `-t0', which stands for
+    ;; timer disabled. In this way speech-dispatcher will keep running
+    ;; even if there no are currently messages to speak.
+    (setq greader-speechd-server
+         (make-process  :name "greader-speechd" :command
+                        '("speech-dispatcher" "-s" "-t0")
+                        :sentinel (lambda (_p _status) (setq
+                                                        greader-speechd-server
+                                                        nil))))))
+
 (defcustom greader-speechd-executable "spd-say"
   "Executable file name."
   :tag "speech-dispatcher client executable file name"
@@ -83,7 +118,7 @@ for further documentation, see the `greader-speechd-rate' 
variable."
 PUNCT must be a numeric value, 0 for no punctuation, 1 for some and 2
 or >2 for all punctuation."
   (setq-local greader-speechd-punctuation
-              (pcase punct
+             (pcase punct
                ('t "all")
                ('0 "none")
                ('1 "some")
@@ -95,6 +130,7 @@ or >2 for all punctuation."
   "Stops speech-dispatcher client."
   (start-process "speechd-client" nil greader-speechd-executable "-S")
   (sleep-for 0.100))
+
 (defvar greader-speechd--punctuation-ring (make-ring 3))
 (ring-insert greader-speechd--punctuation-ring 0)
 (ring-insert greader-speechd--punctuation-ring 1)
@@ -109,12 +145,14 @@ or >2 for all punctuation."
 (defun greader-speechd--ring-next ()
   "Return the next element in the `greader-speechd--punctuation-ring'
 based on `greader-speechd--ring-item'"
-  (setq greader-speechd--ring-item (ring-next greader-speechd--punctuation-ring
-            greader-speechd--ring-item)))
+  (setq greader-speechd--ring-item (ring-next
+                                   greader-speechd--punctuation-ring
+                                             greader-speechd--ring-item)))
 
 ;;;###autoload
 (defun greader-speechd (command &optional arg &rest _)
   "greader speech-dispatcher back-end."
+  (greader-speechd-start-server)
   (pcase command
     ('executable
      greader-speechd-executable)
@@ -133,8 +171,10 @@ based on `greader-speechd--ring-item'"
      (cond
       ((equal arg 'toggle)
        (prog1
-          (greader-speechd-set-punctuation (greader-speechd--ring-next))       
         
-        (message (concat "punctuation set to " greader-speechd-punctuation))))
+          (greader-speechd-set-punctuation
+           (greader-speechd--ring-next))
+        (message
+         (concat "punctuation set to " greader-speechd-punctuation))))
       ((not arg)
        (cond
        ((equal greader-speechd--ring-item 0) "-mnone")

Reply via email to