X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/eabac8252e67333eb565bf6be8cd910173db5b0a..e623859c9604ee1a6994ef05d82cf91053d5aba8:/lisp/gs.el diff --git a/lisp/gs.el b/lisp/gs.el index cbce2002cf..8f9414f0e5 100644 --- a/lisp/gs.el +++ b/lisp/gs.el @@ -1,6 +1,7 @@ ;;; gs.el --- interface to Ghostscript -;; Copyright (C) 1998 Free Software Foundation, Inc. +;; Copyright (C) 1998, 2001, 2002, 2003, 2004, +;; 2005 Free Software Foundation, Inc. ;; Maintainer: FSF ;; Keywords: internal @@ -19,8 +20,8 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;; Commentary: @@ -36,64 +37,56 @@ "The Ghostscript device to use to produce images.") -(defvar gs-options +(defvar gs-options '("-q" ;"-dNOPAUSE" + "-dSAFER" "-dBATCH" "-sDEVICE=" "") "List of command line arguments to pass to Ghostscript. Arguments may contain place-holders `' for the name of the input file, and `' for the device to use.") - - -(defun gs-replace-in-string (string find repl) - "Return STRING with all occurrences of FIND replaced by REPL. -FIND is a regular expression." - (while (string-match find string) - (setq string (replace-match repl nil t string))) - string) - +(put 'gs-options 'risky-local-variable t) (defun gs-options (device file) "Return a list of command line options with place-holders replaced. DEVICE is the value to substitute for the place-holder `', FILE is the value to substitute for the place-holder `'." (mapcar #'(lambda (option) - (setq option (gs-replace-in-string option "" device) - option (gs-replace-in-string option "" file))) + (setq option (replace-regexp-in-string "" device option) + option (replace-regexp-in-string "" file option))) gs-options)) - ;; The GHOSTVIEW property (taken from gv 3.5.8). -;; +;; ;; Type: ;; ;; STRING -;; +;; ;; Parameters: -;; +;; ;; BPIXMAP ORIENT LLX LLY URX URY XDPI YDPI [LEFT BOTTOM TOP RIGHT] -;; +;; ;; Scanf format: "%d %d %d %d %d %d %f %f %d %d %d %d" -;; +;; ;; Explanation of parameters: -;; +;; ;; BPIXMAP: pixmap id of the backing pixmap for the window. If no ;; pixmap is to be used, this parameter should be zero. This ;; parameter must be zero when drawing on a pixmap. -;; +;; ;; ORIENT: orientation of the page. The number represents clockwise ;; rotation of the paper in degrees. Permitted values are 0, 90, 180, ;; 270. -;; +;; ;; LLX, LLY, URX, URY: Bounding box of the drawable. The bounding box ;; is specified in PostScript points in default user coordinates. -;; +;; ;; XDPI, YDPI: Resolution of window. (This can be derived from the ;; other parameters, but not without roundoff error. These values are ;; included to avoid this error.) -;; +;; ;; LEFT, BOTTOM, TOP, RIGHT: (optional) Margins around the window. ;; The margins extend the imageable area beyond the boundaries of the ;; window. This is primarily used for popup zoom windows. I have @@ -116,7 +109,7 @@ FILE is the value to substitute for the place-holder `'." (/ (float (x-display-mm-height frame)) (float (x-display-pixel-height frame)))))) (/ (* 25.4 mm) 72.0))) - + (defun gs-set-ghostview-window-prop (frame spec img-width img-height) "Set the `GHOSTVIEW' window property of FRAME. @@ -124,10 +117,10 @@ SPEC is a GS image specification. IMG-WIDTH is the width of the requested image, and IMG-HEIGHT is the height of the requested image in pixels." (let* ((box (plist-get (cdr spec) :bounding-box)) - (llx (nth 0 box)) - (lly (nth 1 box)) - (urx (nth 2 box)) - (ury (nth 3 box)) + (llx (elt box 0)) + (lly (elt box 1)) + (urx (elt box 2)) + (ury (elt box 3)) (rotation (or (plist-get (cdr spec) :rotate) 0)) ;; The pixel width IMG-WIDTH of the pixmap gives the ;; dots, URX - LLX give the inch. @@ -147,8 +140,9 @@ image in pixels." ((x-display-grayscale-p frame) "Grayscale") (t "Monochrome")))) (x-change-window-property "GHOSTVIEW_COLORS" - (format "%s %s" mode pixel-colors)))) - + (format "%s %s" mode pixel-colors) + frame))) + ; ;;;###autoload @@ -160,13 +154,51 @@ and height of the image in pixels. WINDOW-AND-PIXMAP-ID is a string of the form \"WINDOW-ID PIXMAP-ID\". Value is non-nil if successful." (unwind-protect (let ((file (plist-get (cdr spec) :file)) - gs) + gs + (timeout 40)) + ;; Wait while property gets freed from a previous ghostscript process + ;; sit-for returns nil as soon as input starts being + ;; available, so if we want to give GhostScript a reasonable + ;; chance of starting up, we better use sleep-for. We let + ;; sleep-for wait only half the time because if input is + ;; available, it is more likely that we don't care that much + ;; about garbled redisplay and are in a hurry. + (while (and + ;; Wait while the property is not yet available + (not (zerop (length (x-window-property "GHOSTVIEW" + frame)))) + ;; The following was an alternative condition: wait + ;; while there is still a process running. The idea + ;; was to avoid contention between processes. Turned + ;; out even more sluggish. + ;; (get-buffer-process "*GS*") + (not (zerop timeout))) + (unless (sit-for 0 100 t) + (sleep-for 0 50)) + (setq timeout (1- timeout))) + + ;; No use waiting longer. We might want to try killing off + ;; stuck processes, but there is no point in doing so: either + ;; they are stuck for good, in which case the user would + ;; probably be responsible for that, and killing them off will + ;; make debugging harder, or they are not. In that case, they + ;; will cause incomplete displays. But the same will happen + ;; if they are killed, anyway. The whole is rather + ;; disconcerting, and fast scrolling through a dozen images + ;; will make Emacs freeze for a while. The alternatives are a) + ;; proper implementation not waiting at all but creating + ;; appropriate queues, or b) permanently bad display due to + ;; bad cached images. So remember that this + ;; is just a hack and if people don't like the behaviour, they + ;; will most likely like the easy alternatives even less. + ;; And at least the image cache will make the delay apparent + ;; just once. (gs-set-ghostview-window-prop frame spec img-width img-height) (gs-set-ghostview-colors-window-prop frame pixel-colors) (setenv "GHOSTVIEW" window-and-pixmap-id) (setq gs (apply 'start-process "gs" "*GS*" gs-program (gs-options gs-device file))) - (process-kill-without-query gs) + (set-process-query-on-exit-flag gs nil) gs) nil)) @@ -178,8 +210,9 @@ the form \"WINDOW-ID PIXMAP-ID\". Value is non-nil if successful." ; :bounding-box (22 171 567 738) ; :file ,ps-file))) ; (put-text-property 1 2 'display spec))) -; +; (provide 'gs) -;; gs.el ends here. +;;; arch-tag: 06ab51b8-4932-4cfe-9f60-b924a8edb3f0 +;;; gs.el ends here