[mcclim-devel] Poor man's print dialog

Paolo Amoroso amoroso at mclink.it
Fri Jul 22 16:24:56 UTC 2005


The KDE Linux desktop environment provides a standard dialog for
printing a document to a printer, faxing it, generating a
PDF/PostScript file or emailing a PDF file.  This functionality is
accessible from the shell via the `kprinter' command, which accepts a
PostScript file from stdin.

I tried to use kprinter with McCLIM's PostScript backend and CMUCL
Snapshot 2005-07 (19B) under Slackware Linux 10.0 with code like this:

;;; Requires CMUCL and KDE

(in-package :clim-user)

(define-application-frame kprinter ()
  ()
  (:panes
   (display :application
            :scroll-bars t
            :display-function 'display-graphics))
  (:layouts
   (default display)))

(defun display-graphics (frame stream)
  (declare (ignore frame))
  (draw-rectangle* stream 20 50 120 100 :filled t :ink +red+)
  (draw-circle* stream 220 150 30 :filled t :ink +green+)
  (draw-text* stream "CLIMz rulez" 320 250 :text-size :huge :ink +blue+))

(define-kprinter-command (com-quit :menu t :name t) ()
  (frame-exit *application-frame*))

(define-kprinter-command (com-print :menu t :name t) ()
  (let* ((process (ext:run-program "kprinter" nil :input :stream :wait nil))
         (process-stream (ext:process-input process)))
    (unwind-protect (with-output-to-postscript-stream (stream process-stream)
                      (display-graphics *application-frame* stream))
      (finish-output process-stream)
      (ext:process-close process)
      (ext:process-wait process t))))

(defun print-dialog ()
 (run-frame-top-level (make-application-frame 'kprinter :width 550 :height 350)))

This doesn't work as expected.  If I confirm the dialog with the
"Print" button, the print jobs is correctly generated, but the McCLIM
application freezes and I have to abort the session.  If I dismiss the
dialog with "Cancel", I get this error:

* (clim-user::print-dialog)


Error in function UNIX::SIGPIPE-HANDLER:  SIGPIPE at #x4011EC58.
   [Condition of type SIMPLE-ERROR]

Restarts:
  0: [ABORT] Return to application command loop
  1:         Return to Top-Level.

Debug  (type H for help)

(UNIX::SIGPIPE-HANDLER #<unused-arg>
                       #<unused-arg>
                       #.(SYSTEM:INT-SAP #x3FFFC5A0))
Source: Error finding source:
Error in function DEBUG::GET-FILE-TOP-LEVEL-FORM:  Source file no longer exists:
  target:code/signal.lisp.
0] backtrace

0: (UNIX::SIGPIPE-HANDLER #<unused-arg>
                          #<unused-arg>
                          #.(SYSTEM:INT-SAP #x3FFFC5A0))
1: (UNIX::SIGPIPE-HANDLER 3
                          #<unused-arg>
                          #<unused-arg>
                          #.(SYSTEM:INT-SAP #x3FFFC5A0))[:EXTERNAL]
2: ("call_into_lisp+#x8C [#x805529C] cmucl")
3: ("funcall3+#x29 [#x805508D] cmucl")
4: ("interrupt_handle_now+#xFF [#x8050A03] cmucl")
5: ("NIL+#x8050E1B [#x8050E1B] cmucl")
6: ("NIL+#x4007A0A8 [#x4007A0A8] /lib/libc.so.6")
7: (LISP::DO-OUTPUT #<Stream for descriptor 7>
                    #.(SYSTEM:INT-SAP #x4030C000)
                    0
                    3972
                    ...)
8: (LISP::FLUSH-OUTPUT-BUFFER #<Stream for descriptor 7>)
9: (LISP::FD-STREAM-MISC-ROUTINE #<Stream for descriptor 7>
                                 :FINISH-OUTPUT NIL
                                 #<unused-arg>)
10: (FINISH-OUTPUT #<Stream for descriptor 7>)
11: ((FLET #:G0
       CLIM-POSTSCRIPT::INVOKE-WITH-OUTPUT-TO-POSTSCRIPT-STREAM))[:CLEANUP]
12: (CLIM-POSTSCRIPT::INVOKE-WITH-OUTPUT-TO-POSTSCRIPT-STREAM
     #<Function (FLET #:G26
                  CLIM-USER::COM-PRINT)
       {58D0D9B1}>
     #<Stream for descriptor 7>
     :DEVICE-TYPE NIL
     ...)
13: (CLIM-USER::COM-PRINT)
14: ((METHOD CLIM:DEFAULT-FRAME-TOP-LEVEL NIL (CLIM:APPLICATION-FRAME))
     (#() . #(# # # # # ...)) #<unused-arg> #<CLIM-USER::KPRINTER {58143915}>
     NIL)
15: ("LAMBDA (.KEYARGS-START. .VALID-KEYS. G5411)" #<unused-arg> #<unused-arg>
     #<CLIM-USER::KPRINTER {58143915}> NIL)
16: ((METHOD CLIM:RUN-FRAME-TOP-LEVEL NIL (CLIM:APPLICATION-FRAME))
     (#(20) . #()) #<unused-arg> #<CLIM-USER::KPRINTER {58143915}>
     #<unused-arg>)
17: ((METHOD CLIM:RUN-FRAME-TOP-LEVEL (:AROUND) (CLIM:APPLICATION-FRAME))
     (#(16 15) . #(#))
     #S(PCL::FAST-METHOD-CALL
          :FUNCTION #<Function # {116ABFF9}>
          :PV-CELL (# . #)
          :NEXT-METHOD-CALL NIL
          :ARG-INFO (1 . T))
     #<CLIM-USER::KPRINTER {58143915}> NIL)
18: (INTERACTIVE-EVAL (CLIM-USER::PRINT-DIALOG))
19: (LISP::%TOP-LEVEL)
20: ((LABELS LISP::RESTART-LISP
       SAVE-LISP))

0]

Is there any way of returning control back to the McCLIM application
after printing?  There's probably something fundamental about spawning
external processes and their I/O streams I don't understand.


Paolo
-- 
Lisp Propulsion Laboratory log - http://www.paoloamoroso.it/log



More information about the mcclim-devel mailing list