bongo-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bongo-patches] Implement pausing for non-interactive backend players us


From: Daniel Brockman
Subject: [bongo-patches] Implement pausing for non-interactive backend players using SIGSTOP/SIGTSTP and SIGCONT
Date: Thu, 08 Feb 2007 07:48:25 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/23.0.51 (gnu/linux)

2007-02-08  Daniel Brockman  <address@hidden>

        Implement pausing for non-interactive backend players using
        SIGSTOP/SIGTSTP and SIGCONT.

        * NEWS: Document the new functionality.

        * bongo.el (bongo-default-player-running-p): Count stopped
        processes as running.  (Stopped processes are continuable.)
        (bongo-default-player-paused-p): Return non-nil for players that
        have stopped (but continuable) processes.
        (bongo-default-player-pause/resume): Pause or resume the player
        using process signals (instead of signaling an error).
        (bongo-default-player-process-sentinel): When the process enters
        the `run' or the `stop' state, call `bongo-player-paused/resumed'.
        (bongo-start-simple-player): Set `pausing-supported' to t.
        (define-bongo-backend): Add the `:pause-signal' keyword.
        (bongo-mpg123-player-pause/resume): For non-interactive processes,
        call `bongo-default-player-pause/resume' (instead of failing).
        (bongo-start-mpg123-player): Set `pausing-supported' to t
        regardless of the value of `bongo-mpg123-interactive'.
        (bongo-vlc-player-pause/resume): For non-interactive processes,
        call `bongo-default-player-pause/resume' (instead of failing).
        (bongo-start-vlc-player): Set `pausing-supported' to t regardless
        of the value of `bongo-vlc-interactive'.
        (ogg123): Set `pause-signal' to `SIGTSTP' (using `:pause-signal').


diff -rN -u old-bongo/bongo.el new-bongo/bongo.el
--- old-bongo/bongo.el  2007-02-08 07:48:04.000000000 +0100
+++ new-bongo/bongo.el  2007-02-08 07:48:04.000000000 +0100
@@ -4091,6 +4091,10 @@
   (bongo-player-call-with-default
    player 'paused-p 'bongo-default-player-paused-p))
 
+(defun bongo-player-pause-signal (player)
+  "Return the value of PLAYER's backend's `pause-signal' property."
+  (bongo-backend-get (bongo-player-backend player) 'pause-signal))
+
 (defun bongo-player-pause/resume (player)
   "Tell PLAYER to toggle its paused state.
 If PLAYER does not support pausing, signal an error."
@@ -4157,9 +4161,9 @@
   (bongo-player-explicitly-stopped player))
 
 (defun bongo-default-player-running-p (player)
-  "Return non-nil if PLAYER has a running process."
+  "Return non-nil if PLAYER has a running or stopped process."
   (let ((process (bongo-player-process player)))
-    (and process (eq 'run (process-status process)))))
+    (and process (memq (process-status process) '(run stop)) t)))
 
 (defun bongo-default-player-interactive-p (player)
   "Return the value of PLAYER's `interactive' property."
@@ -4170,13 +4174,32 @@
   (bongo-player-get player 'pausing-supported))
 
 (defun bongo-default-player-paused-p (player)
-  "Return the value of PLAYER's `paused' property."
-  (bongo-player-get player 'paused))
+  "Return non-nil if PLAYER has a non-nil `paused' property,
+or a stopped (but continuable) process."
+  (or (bongo-player-get player 'paused)
+      (let ((process (bongo-player-process player)))
+        (and process (eq (process-status process) 'stop)))))
 
 (defun bongo-default-player-pause/resume (player)
-  "Signal an error explaining that PLAYER does not support pausing."
-  (error "Pausing is not supported for %s"
-         (bongo-player-backend-name player)))
+  "Pause/resume PLAYER using SIGSTOP/SIGCONT.
+Some signal other that SIGSTOP may be used for pausing if
+the player's backend has a non-nil `pause-signal' property."
+  (if (bongo-player-paused-p player)
+      ;; We can't use `signal-process' with `cont' here,
+      ;; because that won't change the process status.
+      ;; This could be seen as a bug in Emacs.
+      (continue-process (bongo-player-process player))
+    ;; We _can_ use `signal-process' with `stop', however,
+    ;; because Emacs will update the process status upon
+    ;; handling the SIGCHLD sent when a child is stopped.
+    ;;
+    ;; Some players pause upon receiving a SIGTSTP signal,
+    ;; which gives them an opportunity to prepare first.
+    ;; If they go ahead and stop themselves after preparing,
+    ;; we should be nice and let them.  That's why this code
+    ;; does not assume that it should always send SIGSTOP.
+    (signal-process (bongo-player-process player)
+                    (bongo-player-pause-signal player))))
 
 (defun bongo-default-player-seeking-supported-p (player)
   "Return the value of PLAYER's `seeking-supported' property."
@@ -4215,7 +4238,9 @@
              (bongo-player-failed player)))
           ((eq status 'signal)
            (unless (bongo-player-explicitly-stopped-p player)
-             (bongo-player-killed player))))))
+             (bongo-player-killed player)))
+          ((memq status '(run stop))
+           (bongo-player-paused/resumed player)))))
 
 
 ;;;; Backends
@@ -4252,7 +4277,8 @@
          (player (list backend-name
                        (cons 'process process)
                        (cons 'file-name file-name)
-                       (cons 'buffer (current-buffer)))))
+                       (cons 'buffer (current-buffer))
+                       (cons 'pausing-supported t))))
     (prog1 player
       (set-process-sentinel process 'bongo-default-player-process-sentinel)
       (bongo-process-put process 'bongo-player player))))
@@ -4292,6 +4318,7 @@
                           :program-name
                           :program-arguments
                           :extra-program-arguments
+                          :pause-signal
                           :matcher
                           :file-name-transformer))
         (error "Unsupported keyword `%S' for `define-bongo-backend'"
@@ -4320,6 +4347,8 @@
                     'bongo-extra-arguments 'bongo-file-name)))
          (extra-program-arguments
           (eval (plist-get options :extra-program-arguments)))
+         (pause-signal
+          (or (eval (plist-get options :pause-signal)) 'SIGSTOP))
          (matcher-expressions
           (bongo-plist-get-all options :matcher))
          (file-name-transformers
@@ -4370,6 +4399,7 @@
                                             program-name))
                   (cons 'program-arguments ',program-arguments)
                   (cons 'pretty-name ',pretty-name)
+                  (cons 'pause-signal ',pause-signal)
                   (cons 'file-name-transformers
                         ',file-name-transformers)))
        (add-to-list 'bongo-backends ',name t)
@@ -4470,13 +4500,12 @@
   'bongo-default-player-paused-p)
 
 (defun bongo-mpg123-player-pause/resume (player)
-  (when (not (bongo-player-interactive-p player))
-    (error (concat "This mpg123 process is not interactive "
-                   "and so does not support pausing")))
-  (process-send-string (bongo-player-process player) "PAUSE\n")
-  (bongo-player-put player 'paused
-    (not (bongo-player-get player 'paused)))
-  (bongo-player-paused/resumed player))
+  (if (not (bongo-player-interactive-p player))
+      (bongo-default-player-pause/resume player)
+    (process-send-string (bongo-player-process player) "PAUSE\n")
+    (bongo-player-put player 'paused
+      (not (bongo-player-get player 'paused)))
+    (bongo-player-paused/resumed player)))
 
 (defun bongo-seconds-to-mp3-frames (seconds)
   (round (* seconds 38.3)))
@@ -4545,7 +4574,7 @@
                 (cons 'file-name file-name)
                 (cons 'buffer (current-buffer))
                 (cons 'interactive bongo-mpg123-interactive)
-                (cons 'pausing-supported bongo-mpg123-interactive)
+                (cons 'pausing-supported t)
                 (cons 'seeking-supported bongo-mpg123-interactive)
                 (cons 'time-update-delay-after-seek
                       bongo-mpg123-time-update-delay-after-seek)
@@ -4634,10 +4663,9 @@
   :group 'bongo-vlc)
 
 (defun bongo-vlc-player-pause/resume (player)
-  (when (not (bongo-player-interactive-p player))
-    (error (concat "This VLC process is not interactive "
-                   "and so does not support pausing")))
-  (process-send-string (bongo-player-process player) "pause\n"))
+  (if (bongo-player-interactive-p player)
+      (process-send-string (bongo-player-process player) "pause\n")
+    (bongo-default-player-pause/resume player)))
 
 (defun bongo-vlc-player-seek-to (player seconds)
   (when (not (bongo-player-interactive-p player))
@@ -4749,7 +4777,7 @@
                 (cons 'file-name file-name)
                 (cons 'buffer (current-buffer))
                 (cons 'interactive bongo-vlc-interactive)
-                (cons 'pausing-supported bongo-vlc-interactive)
+                (cons 'pausing-supported t)
                 (cons 'seeking-supported bongo-vlc-interactive)
                 (cons 'time-update-delay-after-seek
                       bongo-vlc-time-update-delay-after-seek)
@@ -4767,6 +4795,7 @@
 ;;;; Simple backends
 
 (define-bongo-backend ogg123
+  :pause-signal 'SIGTSTP
   :matcher '(local-file "ogg" "flac"))
 
 (define-bongo-backend speexdec
diff -rN -u old-bongo/NEWS new-bongo/NEWS
--- old-bongo/NEWS      1970-01-01 01:00:00.000000000 +0100
+++ new-bongo/NEWS      2007-02-08 07:48:04.000000000 +0100
@@ -0,0 +1,10 @@
+Bongo NEWS file listing user-visible changes.
+This file is in the public domain.
+
+
+February 8, 2007
+
+ * All backends now support pausing.  Non-interactive backend
+   players are paused and resumed using SIGSTOP and SIGCONT.
+   In particular, this means that pausing and resuming is now
+   available for ogg123, speexdec, TiMidity and MikMod.
-- 
Daniel Brockman <address@hidden>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]