Function: w32-direct-print-region-helper
w32-direct-print-region-helper is a byte-compiled function defined in
dos-w32.el.gz.
Signature
(w32-direct-print-region-helper PRINTER START END LPR-PROG DELETE-TEXT BUF DISPLAY REST)
Source Code
;; Defined in /usr/src/emacs/lisp/dos-w32.el.gz
;; Function to actually send data to the printer port.
;; Supports writing directly, and using various programs.
(defun w32-direct-print-region-helper (printer
start end
lpr-prog
_delete-text _buf _display
rest)
(let* (;; Ignore case when matching known external program names.
(case-fold-search t)
;; Convert / to \ in printer name, for sake of external programs.
(printer
(if (stringp printer)
(subst-char-in-string ?/ ?\\ printer)
printer))
;; Find a directory that is local, to work-around Windows bug.
(safe-dir
(let ((safe-dirs (list "c:/" (getenv "windir") (getenv "TMPDIR"))))
(while (not (file-attributes (car safe-dirs)))
(setq safe-dirs (cdr safe-dirs)))
(car safe-dirs)))
(tempfile
(subst-char-in-string
?/ ?\\
(make-temp-name
(expand-file-name "EP" temporary-file-directory))))
;; capture output for diagnosis
(errbuf (list (get-buffer-create " *print-region-helper*") t)))
;; It seems that we must be careful about the directory name that
;; gets added to the printer port name by write-region when using
;; the standard "PRN" or "LPTx" ports, because the write can fail if
;; the directory is on a network drive. The same is true when
;; asking command.com to copy the file.
;; No action is needed for UNC printer names, which is just as well
;; because `expand-file-name' doesn't support UNC names on MS-DOS.
(if (and (stringp printer) (not (string-match-p "^\\\\" printer)))
(setq printer
(subst-char-in-string ?/ ?\\ (expand-file-name printer safe-dir))))
;; Handle known programs specially where necessary.
(unwind-protect
(cond
;; nprint.exe is the standard print command on Netware
((string-match-p "\\`nprint\\(\\.exe\\)?\\'"
(file-name-nondirectory lpr-prog))
(write-region start end tempfile nil 0)
(call-process lpr-prog nil errbuf nil
tempfile (concat "P=" printer)))
;; print.exe is a standard command on NT
((string-match-p "\\`print\\(\\.exe\\)?\\'"
(file-name-nondirectory lpr-prog))
;; Be careful not to invoke print.exe on MS-DOS or Windows 9x
;; though, because it is a TSR program there (hangs Emacs).
(or (and (eq system-type 'windows-nt)
(null (getenv "winbootdir")))
(error "Printing via print.exe is not supported on MS-DOS or Windows 9x"))
;; It seems that print.exe always appends a form-feed so we
;; should make sure to omit the last FF in the data.
(if (and (> end start)
(char-equal (char-before end) ?\C-l))
(setq end (1- end)))
;; cancel out annotate function for non-PS case
(let ((write-region-annotate-functions nil))
(write-region start end tempfile nil 0))
(call-process lpr-prog nil errbuf nil
(concat "/D:" printer) tempfile))
;; support lpr and similar programs for convenience, but
;; supply an explicit filename because the NT version of lpr
;; can't read from stdin.
((> (length lpr-prog) 0)
(write-region start end tempfile nil 0)
(setq rest (append rest (list tempfile)))
(apply 'call-process lpr-prog nil errbuf nil rest))
;; Run command.com to access printer port on Windows 9x, unless
;; we are supposed to append to an existing (non-empty) file,
;; to work around a bug in Windows 9x that prevents Windows
;; programs from accessing LPT ports reliably.
((and (eq system-type 'windows-nt)
(getenv "winbootdir")
;; Allow cop-out so command.com isn't invoked
w32-direct-print-region-use-command-dot-com
;; file-attributes fails on LPT ports on Windows 9x but
;; not on NT, so handle both cases for safety.
(eq (or (file-attribute-size (file-attributes printer)) 0) 0))
(write-region start end tempfile nil 0)
(let ((w32-quote-process-args nil))
(call-process "command.com" nil errbuf nil "/c"
(format "copy /b %s %s" tempfile printer))))
;; write directly to the printer port
(t
(write-region start end printer t 0)))
;; ensure we remove the tempfile if created
(if (file-exists-p tempfile)
(delete-file tempfile)))))