comparison lisp/dos-w32.el @ 24092:d98712ec1252

(find-buffer-file-type-coding-system): Use default-buffer-file-coding-system when file doesn't exist (and isn't covered by a special case) instead of forcing undecided-dos against the user's wishes. (direct-print-region-helper): New function based on direct-print-region-function; sends data to specified printer port without further translation. Recognize and handle specially the standard `print' and `nprint' programs, as well as `lpr' and similar programs. Only write directly to the printer port if no print program is specified. Work around a bug in Windows 9x affecting Win32 version of Emacs by invoking command.com to write to the printer port instead of writing directly. (direct-print-region-function): Use direct-print-region-helper to do most of the work. (direct-ps-print-region-function): New function; analogue of direct-print-region-function for ps-print. (ps-lpr-command): Comment out setq; leave as example usage. (ps-lpr-switches): Ditto.
author Andrew Innes <andrewi@gnu.org>
date Sun, 17 Jan 1999 19:00:24 +0000
parents 4052a2875390
children 3c29f6165eca
comparison
equal deleted inserted replaced
24091:1874c3236349 24092:d98712ec1252
104 If it matches in `file-name-buffer-file-type-alist': 104 If it matches in `file-name-buffer-file-type-alist':
105 If the match is t (for binary): `no-conversion' 105 If the match is t (for binary): `no-conversion'
106 If the match is nil (for dos-text): `undecided-dos' 106 If the match is nil (for dos-text): `undecided-dos'
107 Otherwise: 107 Otherwise:
108 If the file exists: `undecided' 108 If the file exists: `undecided'
109 If the file does not exist: `undecided-dos' 109 If the file does not exist: default-buffer-file-coding-system
110 110
111 If COMMAND is `write-region', the coding system is chosen based upon 111 If COMMAND is `write-region', the coding system is chosen based upon
112 the value of `buffer-file-coding-system' and `buffer-file-type'. If 112 the value of `buffer-file-coding-system' and `buffer-file-type'. If
113 `buffer-file-coding-system' is non-nil, its value is used. If it is 113 `buffer-file-coding-system' is non-nil, its value is used. If it is
114 nil and `buffer-file-type' is t, the coding system is `no-conversion'. 114 nil and `buffer-file-type' is t, the coding system is `no-conversion'.
146 (setq undecided-unix t))) 146 (setq undecided-unix t)))
147 (cond (binary '(no-conversion . no-conversion)) 147 (cond (binary '(no-conversion . no-conversion))
148 (text '(undecided-dos . undecided-dos)) 148 (text '(undecided-dos . undecided-dos))
149 (undecided-unix '(undecided-unix . undecided-unix)) 149 (undecided-unix '(undecided-unix . undecided-unix))
150 (undecided '(undecided . undecided)) 150 (undecided '(undecided . undecided))
151 (t '(undecided-dos . undecided-dos)))) 151 (t (cons default-buffer-file-coding-system
152 default-buffer-file-coding-system))))
152 ((eq op 'write-region) 153 ((eq op 'write-region)
153 (if buffer-file-coding-system 154 (if buffer-file-coding-system
154 (cons buffer-file-coding-system 155 (cons buffer-file-coding-system
155 buffer-file-coding-system) 156 buffer-file-coding-system)
156 ;; Normally this is used only in a non-file-visiting 157 ;; Normally this is used only in a non-file-visiting
254 '(undecided-dos . undecided-dos) 255 '(undecided-dos . undecided-dos)
255 '(raw-text-dos . raw-text-dos)))) 256 '(raw-text-dos . raw-text-dos))))
256 257
257 (add-hook 'before-init-hook 'set-default-process-coding-system) 258 (add-hook 'before-init-hook 'set-default-process-coding-system)
258 259
259 ;; Support for printing under DOS/Windows, see lpr.el and ps-print.el. 260 ;;; Support for printing under DOS/Windows, see lpr.el and ps-print.el.
261
262 ;; Function to actually send data to the printer port.
263 ;; Supports writing directly, and using various programs.
264 (defun direct-print-region-helper (printer
265 start end
266 lpr-prog
267 delete-text buf display
268 rest)
269 (let* ((directory-sep-char ?\\) ; expand file names in DOS format
270 ;; Ignore case when matching known external program names.
271 (case-fold-search t)
272 ;; Convert / to \ in printer name, for sake of external programs.
273 (printer
274 (if (stringp printer)
275 (subst-char-in-string ?/ ?\\ printer)
276 printer))
277 ;; Find a directory that is local, to work-around Windows bug.
278 (safe-dir
279 (let ((safe-dirs (list "c:/" (getenv "windir") (getenv "TMPDIR"))))
280 (while (not (file-attributes (car safe-dirs)))
281 (setq safe-dirs (cdr safe-dirs)))
282 (car safe-dirs)))
283 (tempfile
284 (make-temp-name
285 (expand-file-name "EP" (getenv "TMPDIR"))))
286 ;; capture output for diagnosis
287 (errbuf (list (get-buffer-create " *print-region-helper*") t)))
288 ;; It seems that we must be careful about the directory name that
289 ;; gets added to the printer port name by write-region when using
290 ;; the standard "PRN" or "LPTx" ports, because the write can fail if
291 ;; the directory is on a network drive. The same is true when
292 ;; asking command.com to copy the file.
293 ;; No action is needed for UNC printer names, which is just as well
294 ;; because `expand-file-name' doesn't support UNC names on MS-DOS.
295 (if (not (string-match "^\\\\" printer))
296 (setq printer (expand-file-name printer safe-dir)))
297 ;; Handle known programs specially where necessary.
298 (unwind-protect
299 (cond
300 ;; nprint.exe is the standard print command on Netware
301 ((string-match "^nprint\\(\\.exe\\)?$" (file-name-nondirectory lpr-prog))
302 (write-region start end tempfile nil 0)
303 (call-process lpr-prog nil errbuf nil
304 tempfile (concat "P=" printer)))
305 ;; print.exe is a standard command on NT
306 ((string-match "^print\\(\\.exe\\)?$" (file-name-nondirectory lpr-prog))
307 ;; Be careful not to invoke print.exe on MS-DOS or Windows 9x
308 ;; though, because it is a TSR program there (hangs Emacs).
309 (or (and (eq system-type 'windows-nt)
310 (null (getenv "winbootdir")))
311 (error "Printing via print.exe is not supported on MS-DOS or Windows 9x"))
312 ;; It seems that print.exe always appends a form-feed so we
313 ;; should make sure to omit the last FF in the data.
314 (if (and (> end start)
315 (char-equal (char-before end) ?\C-l))
316 (setq end (1- end)))
317 ;; cancel out annotate function for non-PS case
318 (let ((write-region-annotate-functions nil))
319 (write-region start end tempfile nil 0))
320 (call-process lpr-prog nil errbuf nil
321 (concat "/D:" printer) tempfile))
322 ;; support lpr and similar programs for convenience, but
323 ;; supply an explicit filename because the NT version of lpr
324 ;; can't read from stdin.
325 ((> (length lpr-prog) 0)
326 (write-region start end tempfile nil 0)
327 (setq rest (append rest (list tempfile)))
328 (apply 'call-process lpr-prog nil errbuf nil rest))
329 ;; Run command.com to access printer port on Windows 9x, unless
330 ;; we are supposed to append to an existing (non-empty) file,
331 ;; to work around a bug in Windows 9x that prevents Win32
332 ;; programs from accessing LPT ports reliably.
333 ((and (eq system-type 'windows-nt)
334 (getenv "winbootdir")
335 ;; file-attributes fails on LPT ports on Windows 9x but
336 ;; not on NT, so handle both cases for safety.
337 (eq (or (nth 7 (file-attributes printer)) 0) 0))
338 (write-region start end tempfile nil 0)
339 (let ((w32-quote-process-args nil))
340 (call-process "command.com" nil errbuf nil "/c"
341 (format "copy /b %s %s" tempfile printer))))
342 ;; write directly to the printer port
343 (t
344 (write-region start end printer t 0)))
345 ;; ensure we remove the tempfile if created
346 (if (file-exists-p tempfile)
347 (delete-file tempfile)))))
348
260 (defvar printer-name) 349 (defvar printer-name)
261 350
262 (defun direct-print-region-function (start end 351 (defun direct-print-region-function (start end
263 &optional lpr-prog 352 &optional lpr-prog
264 delete-text buf display 353 delete-text buf display
265 &rest rest) 354 &rest rest)
266 "DOS/Windows-specific function to print the region on a printer. 355 "DOS/Windows-specific function to print the region on a printer.
267 Writes the region to the device or file which is a value of 356 Writes the region to the device or file which is a value of
268 `printer-name' \(which see\). Ignores any arguments beyond 357 `printer-name' \(which see\), unless the value of `lpr-command'
269 START and END." 358 indicates a specific program should be invoked."
270 359
271 ;; DOS printers need the lines to end with CR-LF pairs, so make 360 ;; DOS printers need the lines to end with CR-LF pairs, so make
272 ;; sure it always happens that way, unless the buffer is binary. 361 ;; sure it always happens that way, unless the buffer is binary.
273 (let* ((coding coding-system-for-write) 362 (let* ((coding coding-system-for-write)
274 (coding-base 363 (coding-base
275 (if (null coding) 'undecided (coding-system-base coding))) 364 (if (null coding) 'undecided (coding-system-base coding)))
276 (eol-type (coding-system-eol-type coding-base)) 365 (eol-type (coding-system-eol-type coding-base))
366 ;; Make each print-out eject the final page, but don't waste
367 ;; paper if the file ends with a form-feed already.
277 (write-region-annotate-functions 368 (write-region-annotate-functions
278 (cons 369 (cons
279 (lambda (start end) 370 (lambda (start end)
280 ;; Make each print-out start on a new page, but don't waste 371 (if (not (char-equal (char-before end) ?\C-l))
281 ;; paper if there was a form-feed at the end of this file.
282 (if (not (char-equal (char-after (1- end)) ?\C-l))
283 `((,end . "\f")))) 372 `((,end . "\f"))))
284 write-region-annotate-functions))) 373 write-region-annotate-functions))
374 (printer (or (and (boundp 'dos-printer)
375 (stringp (symbol-value 'dos-printer))
376 (symbol-value 'dos-printer))
377 printer-name)))
285 (or (eq coding-system-for-write 'no-conversion) 378 (or (eq coding-system-for-write 'no-conversion)
286 (setq coding-system-for-write 379 (setq coding-system-for-write
287 (aref eol-type 1))) ; force conversion to DOS EOLs 380 (aref eol-type 1))) ; force conversion to DOS EOLs
288 (let ((printer (or (and (boundp 'dos-printer) 381 (direct-print-region-helper printer start end lpr-prog
289 (stringp (symbol-value 'dos-printer)) 382 delete-text buf display rest)))
290 (symbol-value 'dos-printer)) 383
291 printer-name))
292 ;; It seems that we must be careful about the directory name
293 ;; that gets added by write-region when using the standard
294 ;; "PRN" or "LPTx" ports. The call can fail if the directory
295 ;; is on a network drive.
296 (safe-dir (or (getenv "windir") (getenv "TMPDIR") "c:/")))
297 (write-region start end
298 (expand-file-name printer safe-dir) t 0))))
299
300 ;; Set this to nil if you have a port of the `lpr' program and
301 ;; you want to use it for printing. If the default setting is
302 ;; in effect, `lpr-command' and its switches are ignored when
303 ;; printing with `lpr-xxx' and `print-xxx'.
304 (setq print-region-function 'direct-print-region-function) 384 (setq print-region-function 'direct-print-region-function)
305 385
306 ;; Set this to nil if you have a port of the `pr' program 386 ;; Set this to nil if you have a port of the `pr' program
307 ;; (e.g., from GNU Textutils), or if you have an `lpr' 387 ;; (e.g., from GNU Textutils), or if you have an `lpr'
308 ;; program (see above) that can print page headers. 388 ;; program (see above) that can print page headers.
313 ;; the same output as `lpr-buffer' and `lpr-region', accordingly. 393 ;; the same output as `lpr-buffer' and `lpr-region', accordingly.
314 (setq lpr-headers-switches "(page headers are not supported)") 394 (setq lpr-headers-switches "(page headers are not supported)")
315 395
316 (defvar ps-printer-name) 396 (defvar ps-printer-name)
317 397
318 (setq ps-lpr-command "gs") 398 (defun direct-ps-print-region-function (start end
319 399 &optional lpr-prog
320 (setq ps-lpr-switches '("-q" "-dNOPAUSE" "-sDEVICE=epson" "-r240x60" 400 delete-text buf display
321 "-sOutputFile=LPT1" "-")) 401 &rest rest)
402 "DOS/Windows-specific function to print the region on a PostScript printer.
403 Writes the region to the device or file which is a value of
404 `ps-printer-name' \(which see\), unless the value of `ps-lpr-command'
405 indicates a specific program should be invoked."
406
407 (let ((printer (or (and (boundp 'dos-ps-printer)
408 (stringp (symbol-value 'dos-ps-printer))
409 (symbol-value 'dos-ps-printer))
410 ps-printer-name)))
411 (direct-print-region-helper printer start end lpr-prog
412 delete-text buf display rest)))
413
414 (setq ps-print-region-function 'direct-ps-print-region-function)
415
416 ;(setq ps-lpr-command "gs")
417
418 ;(setq ps-lpr-switches '("-q" "-dNOPAUSE" "-sDEVICE=epson" "-r240x60"
419 ; "-sOutputFile=LPT1"))
322 420
323 (provide 'dos-w32) 421 (provide 'dos-w32)
324 422
325 ;;; dos-w32.el ends here 423 ;;; dos-w32.el ends here