diff options
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/bindings.el | 2 | ||||
-rw-r--r-- | lisp/cus-face.el | 13 | ||||
-rw-r--r-- | lisp/faces.el | 69 | ||||
-rw-r--r-- | lisp/files.el | 2 | ||||
-rw-r--r-- | lisp/font-lock.el | 2 | ||||
-rw-r--r-- | lisp/frame.el | 145 | ||||
-rw-r--r-- | lisp/help-fns.el | 31 | ||||
-rw-r--r-- | lisp/international/mule-cmds.el | 102 | ||||
-rw-r--r-- | lisp/international/mule.el | 26 | ||||
-rw-r--r-- | lisp/loadup.el | 14 | ||||
-rw-r--r-- | lisp/server.el | 834 | ||||
-rw-r--r-- | lisp/simple.el | 10 | ||||
-rw-r--r-- | lisp/startup.el | 96 | ||||
-rw-r--r-- | lisp/subr.el | 12 | ||||
-rw-r--r-- | lisp/talk.el | 39 | ||||
-rw-r--r-- | lisp/term/iris-ansi.el | 2 | ||||
-rw-r--r-- | lisp/term/lk201.el | 139 | ||||
-rw-r--r-- | lisp/term/news.el | 2 | ||||
-rw-r--r-- | lisp/term/rxvt.el | 138 | ||||
-rw-r--r-- | lisp/term/sun.el | 2 | ||||
-rw-r--r-- | lisp/term/x-win.el | 283 | ||||
-rw-r--r-- | lisp/term/xterm.el | 442 | ||||
-rw-r--r-- | lisp/version.el | 5 | ||||
-rw-r--r-- | lisp/x-dnd.el | 5 |
24 files changed, 1543 insertions, 872 deletions
diff --git a/lisp/bindings.el b/lisp/bindings.el index 396e1e49216..1a30313fe54 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -214,7 +214,7 @@ Major modes that edit things other than ordinary files may change this (make-variable-buffer-local 'mode-line-buffer-identification) -(defvar mode-line-frame-identification '("-%F ") +(defvar mode-line-frame-identification '(window-system " " "-%F ") "Mode-line control to describe the current frame.") (defvar mode-line-process nil "\ diff --git a/lisp/cus-face.el b/lisp/cus-face.el index 33c8c995a4c..1a8cce0473a 100644 --- a/lisp/cus-face.el +++ b/lisp/cus-face.el @@ -39,15 +39,18 @@ (when (fboundp 'facep) (unless (facep face) ;; If the user has already created the face, respect that. - (let ((value (or (get face 'saved-face) spec))) + (let ((value (or (get face 'saved-face) spec)) + (have-window-system (memq initial-window-system '(x w32)))) ;; Create global face. (make-empty-face face) ;; Create frame-local faces (dolist (frame (frame-list)) - (face-spec-set face value frame))) - ;; When making a face after frames already exist - (if (memq window-system '(x w32)) - (make-face-x-resource-internal face)))) + (face-spec-set face value frame) + (when (memq (window-system frame) '(x w32)) + (setq have-window-system t))) + ;; When making a face after frames already exist + (if have-window-system + (make-face-x-resource-internal face))))) ;; Don't record SPEC until we see it causes no errors. (put face 'face-defface-spec spec) (push (cons 'defface face) current-load-list) diff --git a/lisp/faces.el b/lisp/faces.el index 74a8a1cbb47..b1b9040dba7 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -910,7 +910,7 @@ an integer value." (let ((valid (case attribute (:family - (if window-system + (if (window-system frame) (mapcar #'(lambda (x) (cons (car x) (car x))) (x-font-family-list)) ;; Only one font on TTYs. @@ -919,7 +919,7 @@ an integer value." (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute))) ((:underline :overline :strike-through :box) - (if window-system + (if (window-system frame) (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute)) (mapcar #'(lambda (c) (cons c c)) @@ -932,7 +932,7 @@ an integer value." ((:height) 'integerp) (:stipple - (and (memq window-system '(x w32 mac)) + (and (memq (window-system frame) '(x w32 mac)) (mapcar #'list (apply #'nconc (mapcar (lambda (dir) @@ -1050,7 +1050,7 @@ of a global face. Value is the new attribute value." ;; explicitly in VALID, using color approximation code ;; in tty-colors.el. (when (and (memq attribute '(:foreground :background)) - (not (memq window-system '(x w32 mac))) + (not (memq (window-system frame) '(x w32 mac))) (not (member new-value '("unspecified" "unspecified-fg" "unspecified-bg")))) @@ -1329,14 +1329,14 @@ If FRAME is nil, the current FRAME is used." req (car conjunct) options (cdr conjunct) match (cond ((eq req 'type) - (or (memq window-system options) + (or (memq (window-system frame) options) ;; FIXME: This should be revisited to use ;; display-graphic-p, provided that the ;; color selection depends on the number ;; of supported colors, and all defface's ;; are changed to look at number of colors ;; instead of (type graphic) etc. - (and (null window-system) + (and (null (window-system frame)) (memq 'tty options)) (and (memq 'motif options) (featurep 'motif)) @@ -1554,22 +1554,32 @@ this won't have the expected effect." Display-dependent faces are those which have different definitions according to the `background-mode' and `display-type' frame parameters." (let* ((bg-resource - (and window-system + (and (window-system frame) (x-get-resource "backgroundMode" "BackgroundMode"))) (bg-color (frame-parameter frame 'background-color)) + (tty-type (frame-parameter frame 'tty-type)) (bg-mode (cond (frame-background-mode) (bg-resource (intern (downcase bg-resource))) - ((and (null window-system) (null bg-color)) - ;; No way to determine this automatically (?). - 'dark) - ;; Unspecified frame background color can only happen - ;; on tty's. - ((member bg-color '(unspecified "unspecified-bg")) - 'dark) + ((and (null (window-system frame)) + ;; Unspecified frame background color can only + ;; happen on tty's. + (member bg-color '(nil unspecified "unspecified-bg"))) + ;; There is no way to determine the background mode + ;; automatically, so we make a guess based on the + ;; terminal type. + (if (and tty-type + (string-match "^\\(xterm\\|rxvt\\|dtterm\\|eterm\\)" + tty-type)) + 'light + 'dark)) ((equal bg-color "unspecified-fg") ; inverted colors - 'light) + (if (and tty-type + (string-match "^\\(xterm\\|rxvt\\|dtterm\\|eterm\\)" + tty-type)) + 'dark + 'light)) ((>= (apply '+ (x-color-values bg-color frame)) ;; Just looking at the screen, colors whose ;; values add up to .6 of the white total @@ -1578,7 +1588,7 @@ according to the `background-mode' and `display-type' frame parameters." 'light) (t 'dark))) (display-type - (cond ((null window-system) + (cond ((null (window-system frame)) (if (tty-display-color-p frame) 'color 'mono)) ((x-display-color-p frame) 'color) @@ -1675,7 +1685,7 @@ Value is the new frame created." (setq parameters (x-handle-named-frame-geometry parameters)) (let ((visibility-spec (assq 'visibility parameters)) (frame-list (frame-list)) - (frame (x-create-frame (cons '(visibility . nil) parameters))) + (frame (x-create-frame `((visibility . nil) . ,parameters))) success) (unwind-protect (progn @@ -1685,6 +1695,11 @@ Value is the new frame created." (if (or (null frame-list) (null visibility-spec)) (make-frame-visible frame) (modify-frame-parameters frame (list visibility-spec))) + ;; Arrange for the kill and yank functions to set and check the clipboard. + (modify-frame-parameters + frame '((interprogram-cut-function . x-select-text))) + (modify-frame-parameters + frame '((interprogram-paste-function . x-cut-buffer-or-selection-value))) (setq success t)) (unless success (delete-frame frame))) @@ -1713,7 +1728,7 @@ Initialize colors of certain faces from frame parameters." (when (not (equal face 'default)) (face-spec-set face (face-user-default-spec face) frame) (internal-merge-in-global-face face frame) - (when (and (memq window-system '(x w32 mac)) + (when (and (memq (window-system frame) '(x w32 mac)) (or (not (boundp 'inhibit-default-face-x-resources)) (not (eq face 'default)))) (make-face-x-resource-internal face frame))) @@ -1764,10 +1779,26 @@ created." (let ((frame (make-terminal-frame parameters)) success) (unwind-protect - (progn + (with-selected-frame frame (tty-handle-reverse-video frame (frame-parameters frame)) (frame-set-background-mode frame) (face-set-after-frame-default frame) + ;; Load library for our terminal type. + ;; User init file can set term-file-prefix to nil to prevent this. + (unless (null term-file-prefix) + (let ((term (cdr (assq 'tty-type parameters))) + hyphend) + (while (and term + (not (load (concat term-file-prefix term) t t))) + ;; Strip off last hyphen and what follows, then try again + (setq term + (if (setq hyphend (string-match "[-_][^-_]+$" term)) + (substring term 0 hyphend) + nil))))) + ;; Make sure the kill and yank functions do not touch the X clipboard. + (modify-frame-parameters frame '((interprogram-cut-function . nil))) + (modify-frame-parameters frame '((interprogram-paste-function . nil))) + (set-locale-environment nil frame) (setq success t)) (unless success (delete-frame frame))) diff --git a/lisp/files.el b/lisp/files.el index d519f041152..302cc793578 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4854,7 +4854,7 @@ With prefix arg, silently save all file-visiting buffers, then kill." (define-key ctl-x-map "i" 'insert-file) (define-key esc-map "~" 'not-modified) (define-key ctl-x-map "\C-d" 'list-directory) -(define-key ctl-x-map "\C-c" 'save-buffers-kill-emacs) +(define-key ctl-x-map "\C-c" 'server-save-buffers-kill-display) (define-key ctl-x-map "\C-q" 'toggle-read-only) (define-key ctl-x-4-map "f" 'find-file-other-window) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index ba42412d8da..86abc2a5f12 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -2012,7 +2012,7 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item." "with-current-buffer" "with-electric-help" "with-local-quit" "with-no-warnings" "with-output-to-string" "with-output-to-temp-buffer" - "with-selected-window" "with-syntax-table" + "with-selected-window" "with-selected-frame" "with-syntax-table" "with-temp-buffer" "with-temp-file" "with-temp-message" "with-timeout" "with-timeout-handler") t) "\\>") diff --git a/lisp/frame.el b/lisp/frame.el index 3693295e819..ec98089cc0e 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -27,10 +27,28 @@ ;;; Code: -(defvar frame-creation-function nil - "Window-system dependent function to call to create a new frame. -The window system startup file should set this to its frame creation -function, which should take an alist of parameters as its argument.") +(defvar frame-creation-function-alist + (list (cons nil + (if (fboundp 'tty-create-frame-with-faces) + 'tty-create-frame-with-faces + (function + (lambda (parameters) + (error "Can't create multiple frames without a window system")))))) + "Alist of window-system dependent functions to call to create a new frame. +The window system startup file should add its frame creation +function to this list, which should take an alist of parameters +as its argument.") + +(defvar window-system-default-frame-alist nil + "Alist of window-system dependent default frame parameters. +These may be set in your init file, like this: + + ;; Disable menubar and toolbar on the console, but enable them under X. + (setq window-system-default-frame-alist + '((x (menu-bar-lines . 1) (tool-bar-lines . 1)) + (nil (menu-bar-lines . 0) (tool-bar-lines . 0)))) + +Also see `default-frame-alist'.") ;; The initial value given here used to ask for a minibuffer. ;; But that's not necessary, because the default is to have one. @@ -189,7 +207,9 @@ Pass it BUFFER as first arg, and (cdr ARGS) gives the rest of the args." (defun frame-initialize () "Create an initial frame if necessary." ;; Are we actually running under a window system at all? - (if (and window-system (not noninteractive) (not (eq window-system 'pc))) + (if (and initial-window-system + (not noninteractive) + (not (eq initial-window-system 'pc))) (progn ;; Turn on special-display processing only if there's a window system. (setq special-display-function 'special-display-popup-frame) @@ -206,6 +226,9 @@ Pass it BUFFER as first arg, and (cdr ARGS) gives the rest of the args." (setq frame-initial-frame-alist (cons '(horizontal-scroll-bars . t) frame-initial-frame-alist))) + (setq frame-initial-frame-alist + (cons (cons 'window-system initial-window-system) + frame-initial-frame-alist)) (setq default-minibuffer-frame (setq frame-initial-frame (make-frame frame-initial-frame-alist))) @@ -218,18 +241,7 @@ Pass it BUFFER as first arg, and (cdr ARGS) gives the rest of the args." ;; At this point, we know that we have a frame open, so we ;; can delete the terminal frame. (delete-frame terminal-frame) - (setq terminal-frame nil)) - - ;; No, we're not running a window system. Use make-terminal-frame if - ;; we support that feature, otherwise arrange to cause errors. - (or (eq window-system 'pc) - (setq frame-creation-function - (if (fboundp 'tty-create-frame-with-faces) - 'tty-create-frame-with-faces - (function - (lambda (parameters) - (error - "Can't create multiple frames without a window system")))))))) + (setq terminal-frame nil)))) (defvar frame-notice-user-settings t "Non-nil means function `frame-notice-user-settings' wasn't run yet.") @@ -279,7 +291,7 @@ React to settings of `default-frame-alist', `initial-frame-alist' there." ;; Can't modify the minibuffer parameter, so don't try. (setq parms (delq (assq 'minibuffer parms) parms)) (modify-frame-parameters nil - (if (null window-system) + (if (null initial-window-system) (append initial-frame-alist default-frame-alist parms @@ -288,7 +300,7 @@ React to settings of `default-frame-alist', `initial-frame-alist' there." ;; default-frame-alist were already ;; applied in pc-win.el. parms)) - (if (null window-system) ;; MS-DOS does this differently in pc-win.el + (if (null initial-window-system) ;; MS-DOS does this differently in pc-win.el (let ((newparms (frame-parameters)) (frame (selected-frame))) (tty-handle-reverse-video frame newparms) @@ -567,12 +579,25 @@ is not considered (see `next-frame')." (select-frame-set-input-focus (selected-frame))) (defun make-frame-on-display (display &optional parameters) - "Make a frame on display DISPLAY. + "Make a frame on X display DISPLAY. The optional second argument PARAMETERS specifies additional frame parameters." (interactive "sMake frame on display: ") (or (string-match "\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" display) (error "Invalid display, not HOST:SERVER or HOST:SERVER.SCREEN")) - (make-frame (cons (cons 'display display) parameters))) + (when (and (boundp 'x-initialized) (not x-initialized)) + (setq x-display-name display) + (x-initialize-window-system)) + (make-frame `((window-system . x) (display . ,display) . ,parameters))) + +(defun make-frame-on-tty (device type &optional parameters) + "Make a frame on terminal DEVICE which is of type TYPE (e.g., \"xterm\"). +The optional third argument PARAMETERS specifies additional frame parameters." + (interactive "fOpen frame on tty device: \nsTerminal type of %s: ") + (unless device + (error "Invalid terminal device")) + (unless type + (error "Invalid terminal type")) + (make-frame `((window-system . nil) (tty . ,device) (tty-type . ,type) . ,parameters))) (defun make-frame-command () "Make a new frame, and select it if the terminal displays only one frame." @@ -612,7 +637,12 @@ You cannot specify either `width' or `height', you must use neither or both. (minibuffer . only) The frame should contain only a minibuffer. (minibuffer . WINDOW) The frame should use WINDOW as its minibuffer window. -Before the frame is created (via `frame-creation-function'), functions on the + (window-system . nil) The frame should be displayed on a terminal device. + (window-system . x) The frame should be displayed in an X window. + + (display-id . ID) The frame should use the display identified by ID. + +Before the frame is created (via `frame-creation-function-alist'), functions on the hook `before-make-frame-hook' are run. After the frame is created, functions on `after-make-frame-functions' are run with one arg, the newly created frame. @@ -622,8 +652,24 @@ window system may select the new frame for its own reasons, for instance if the frame appears under the mouse pointer and your setup is for focus to follow the pointer." (interactive) - (run-hooks 'before-make-frame-hook) - (let ((frame (funcall frame-creation-function parameters))) + (let* ((w (cond + ((assq 'display-id parameters) + (let ((type (display-live-p (cdr (assq 'display-id parameters))))) + (cond + ((eq type t) nil) + ((eq type nil) (error "Display %s does not exist" (cdr (assq 'display-id parameters)))) + (t type)))) + ((assq 'window-system parameters) + (cdr (assq 'window-system parameters))) + (t window-system))) + (frame-creation-function (cdr (assq w frame-creation-function-alist))) + frame) + (unless frame-creation-function + (error "Don't know how to create a frame on window system %s" w)) + (run-hooks 'before-make-frame-hook) + (setq frame (funcall frame-creation-function parameters)) + (modify-frame-parameters frame + (cdr (assq w window-system-default-frame-alist))) (run-hook-with-args 'after-make-frame-functions frame) frame)) @@ -645,20 +691,25 @@ setup is for focus to follow the pointer." (defun frames-on-display-list (&optional display) "Return a list of all frames on DISPLAY. -DISPLAY is a name of a display, a string of the form HOST:SERVER.SCREEN. + +DISPLAY should be a display identifier (an integer), but it may +also be a name of a display, a string of the form HOST:SERVER.SCREEN. + If DISPLAY is omitted or nil, it defaults to the selected frame's display." - (let* ((display (or display (frame-parameter nil 'display))) + (let* ((display (or display (frame-display))) (func #'(lambda (frame) - (equal (frame-parameter frame 'display) display)))) + (or (eq (frame-display frame) display) + (equal (frame-parameter frame 'display) display))))) (filtered-frame-list func))) (defun framep-on-display (&optional display) "Return the type of frames on DISPLAY. -DISPLAY may be a display name or a frame. If it is a frame, its type is -returned. +DISPLAY may be a display id, a display name or a frame. If it is +a frame, its type is returned. If DISPLAY is omitted or nil, it defaults to the selected frame's display. All frames on a given display are of the same type." - (or (framep display) + (or (display-live-p display) + (framep display) (framep (car (frames-on-display-list display))))) (defun frame-remove-geometry-params (param-list) @@ -696,9 +747,9 @@ automatically." (select-frame frame) (raise-frame frame) ;; Ensure, if possible, that frame gets input focus. - (cond ((eq window-system 'x) + (cond ((eq (window-system frame) 'x) (x-focus-frame frame)) - ((eq window-system 'w32) + ((eq (window-system frame) 'w32) (w32-focus-frame frame))) (cond (focus-follows-mouse (set-mouse-position (selected-frame) (1- (frame-width)) 0)))) @@ -735,6 +786,22 @@ Otherwise, that variable should be nil." (iconify-frame) (make-frame-visible))) +(defun suspend-frame () + "Do whatever is right to suspend the current frame. +Calls `suspend-emacs' if invoked from the controlling terminal, +`suspend-tty' from a secondary terminal, and +`iconify-or-deiconify-frame' from an X frame." + (interactive) + (let ((type (framep (selected-frame)))) + (cond + ((eq type 'x) (iconify-or-deiconify-frame)) + ((eq type t) + (if (display-controlling-tty-p) + (suspend-emacs) + (suspend-tty))) + (t (suspend-emacs))))) + + (defun make-frame-names-alist () (let* ((current-frame (selected-frame)) (falist @@ -768,9 +835,9 @@ If there is no frame by that name, signal an error." (raise-frame frame) (select-frame frame) ;; Ensure, if possible, that frame gets input focus. - (cond ((eq window-system 'x) + (cond ((eq (window-system frame) 'x) (x-focus-frame frame)) - ((eq window-system 'w32) + ((eq (window-system frame) 'w32) (w32-focus-frame frame))) (when focus-follows-mouse (set-mouse-position frame (1- (frame-width frame)) 0)))) @@ -980,6 +1047,10 @@ bars (top, bottom, or nil)." (cons vert hor))) ;;;; Frame/display capabilities. +(defun selected-display () + "Return the display that is now selected." + (frame-display (selected-frame))) + (defun display-mouse-p (&optional display) "Return non-nil if DISPLAY has a mouse available. DISPLAY can be a display name, a frame, or nil (meaning the selected @@ -1131,7 +1202,7 @@ the question is inapplicable to a certain kind of display." ((eq frame-type 'pc) 16) (t - (tty-display-color-cells))))) + (tty-display-color-cells display))))) (defun display-visual-class (&optional display) "Returns the visual class of DISPLAY. @@ -1272,7 +1343,7 @@ cursor display. On a text-only terminal, this is not implemented." :init-value (not (or noninteractive (if (boundp 'no-blinking-cursor) no-blinking-cursor) (eq system-type 'ms-dos) - (not (memq window-system '(x w32))))) + (not (memq initial-window-system '(x w32))))) :group 'cursor :global t (if blink-cursor-idle-timer (cancel-timer blink-cursor-idle-timer)) @@ -1354,6 +1425,8 @@ Use Custom to set this variable to get the display updated." (define-key ctl-x-5-map "0" 'delete-frame) (define-key ctl-x-5-map "o" 'other-frame) +(substitute-key-definition 'suspend-emacs 'suspend-frame global-map) + (provide 'frame) ;; arch-tag: 82979c70-b8f2-4306-b2ad-ddbd6b328b56 diff --git a/lisp/help-fns.el b/lisp/help-fns.el index c11aaf6da76..bbf929e3743 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -498,10 +498,11 @@ If ANY-SYMBOL is non-nil, don't insist the symbol be bound." 0)) ;;;###autoload -(defun describe-variable (variable &optional buffer) +(defun describe-variable (variable &optional buffer frame) "Display the full documentation of VARIABLE (a symbol). Returns the documentation as a string, also. -If VARIABLE has a buffer-local value in BUFFER (default to the current buffer), +If VARIABLE has a buffer-local value in BUFFER or FRAME +\(default to the current buffer and current frame), it is displayed along with the global value." (interactive (let ((v (variable-at-point)) @@ -516,13 +517,19 @@ it is displayed along with the global value." (list (if (equal val "") v (intern val))))) (unless (buffer-live-p buffer) (setq buffer (current-buffer))) + (unless (frame-live-p frame) (setq frame (selected-frame))) (if (not (symbolp variable)) (message "You did not specify a variable") (save-excursion - (let* ((valvoid (not (with-current-buffer buffer (boundp variable)))) - ;; Extract the value before setting up the output buffer, - ;; in case `buffer' *is* the output buffer. - (val (unless valvoid (buffer-local-value variable buffer)))) + (let ((valvoid (not (with-current-buffer buffer (boundp variable)))) + val locus) + ;; Extract the value before setting up the output buffer, + ;; in case `buffer' *is* the output buffer. + (unless valvoid + (with-selected-frame frame + (with-current-buffer buffer + (setq val (symbol-value variable) + locus (variable-binding-locus variable))))) (help-setup-xref (list #'describe-variable variable buffer) (interactive-p)) (with-output-to-temp-buffer (help-buffer) @@ -541,11 +548,13 @@ it is displayed along with the global value." (if (< (point) (+ from 20)) (delete-region (1- from) from))))) (terpri) - (when (local-variable-p variable) - (princ (format "%socal in buffer %s; " - (if (get variable 'permanent-local) - "Permanently l" "L") - (buffer-name))) + (when locus + (if (bufferp locus) + (princ (format "%socal in buffer %s; " + (if (get variable 'permanent-local) + "Permanently l" "L") + (buffer-name))) + (princ (format "It is a frame-local variable; "))) (if (not (default-boundp variable)) (princ "globally void") (let ((val (default-value variable))) diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 72bc84762a1..d00aaf3cadc 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -145,7 +145,7 @@ t) (define-key-after set-coding-system-map [set-terminal-coding-system] '(menu-item "For Terminal" set-terminal-coding-system - :enable (null (memq window-system '(x w32 mac))) + :enable (null (memq initial-window-system '(x w32 mac))) :help "How to encode terminal output") t) (define-key-after set-coding-system-map [separator-3] @@ -1740,7 +1740,7 @@ The default status is as follows: (reset-language-environment) -(defun set-display-table-and-terminal-coding-system (language-name &optional coding-system) +(defun set-display-table-and-terminal-coding-system (language-name &optional coding-system display) "Set up the display table and terminal coding system for LANGUAGE-NAME." (let ((coding (get-language-info language-name 'unibyte-display))) (if coding @@ -1754,7 +1754,7 @@ The default status is as follows: (dotimes (i 128) (aset standard-display-table (+ i 128) nil)))) (or (eq window-system 'pc) - (set-terminal-coding-system (or coding-system coding))))) + (set-terminal-coding-system (or coding-system coding) display)))) (defun set-language-environment (language-name) "Set up multi-lingual environment for using LANGUAGE-NAME. @@ -2348,7 +2348,7 @@ is returned. Thus, for instance, if charset \"ISO8859-2\", ;; too, for setting things such as calendar holidays, ps-print paper ;; size, spelling dictionary. -(defun set-locale-environment (&optional locale-name) +(defun set-locale-environment (&optional locale-name display) "Set up multi-lingual environment for using LOCALE-NAME. This sets the language environment, the coding system priority, the default input method and sometimes other things. @@ -2369,6 +2369,11 @@ directory named `/usr/share/locale' or `/usr/lib/locale'. LOCALE-NAME will be translated according to the table specified by `locale-translation-file-name'. +If DISPLAY is non-nil, only set the keyboard coding system and +the terminal coding system for the given display, and don't touch +session-global parameters like the language environment. DISPLAY +may be a display id or a frame. + See also `locale-charset-language-names', `locale-language-names', `locale-preferred-coding-systems' and `locale-coding-system'." (interactive "sSet environment for locale: ") @@ -2457,28 +2462,34 @@ See also `locale-charset-language-names', `locale-language-names', ;; Set up for this character set. This is now the right way ;; to do it for both unibyte and multibyte modes. - (set-language-environment language-name) + (unless display + (set-language-environment language-name)) ;; If default-enable-multibyte-characters is nil, ;; we are using single-byte characters, ;; so the display table and terminal coding system are irrelevant. (when default-enable-multibyte-characters (set-display-table-and-terminal-coding-system - language-name coding-system)) + language-name coding-system display)) ;; Set the `keyboard-coding-system' if appropriate (tty ;; only). At least X and MS Windows can generate ;; multilingual input. - (unless window-system - (let ((kcs (or coding-system - (car (get-language-info language-name - 'coding-system))))) - (if kcs (set-keyboard-coding-system kcs)))) - - (setq locale-coding-system - (car (get-language-info language-name 'coding-priority)))) - - (when (and coding-system + ;; XXX This was disabled unless `window-system', but that + ;; leads to buggy behaviour when a tty frame is opened + ;; later. Setting the keyboard coding system has no adverse + ;; effect on X, so let's do it anyway. -- Lorentey + (let ((kcs (or coding-system + (car (get-language-info language-name + 'coding-system))))) + (if kcs (set-keyboard-coding-system kcs display))) + + (unless display + (setq locale-coding-system + (car (get-language-info language-name 'coding-priority))))) + + (when (and (not display) + coding-system (not (coding-system-equal coding-system locale-coding-system))) (prefer-coding-system coding-system) @@ -2490,9 +2501,9 @@ See also `locale-charset-language-names', `locale-language-names', (when (boundp 'w32-ansi-code-page) (let ((code-page-coding (intern (format "cp%d" w32-ansi-code-page)))) (when (coding-system-p code-page-coding) - (setq locale-coding-system code-page-coding) - (set-keyboard-coding-system code-page-coding) - (set-terminal-coding-system code-page-coding)))) + (unless display (setq locale-coding-system code-page-coding)) + (set-keyboard-coding-system code-page-coding display) + (set-terminal-coding-system code-page-coding display)))) (when (eq system-type 'darwin) ;; On Darwin, file names are always encoded in utf-8, no matter @@ -2507,32 +2518,33 @@ See also `locale-charset-language-names', `locale-language-names', ;; Default to A4 paper if we're not in a C, POSIX or US locale. ;; (See comments in Flocale_info.) - (let ((locale locale) - (paper (locale-info 'paper))) - (if paper - ;; This will always be null at the time of writing. - (cond - ((equal paper '(216 279)) - (setq ps-paper-type 'letter)) - ((equal paper '(210 297)) - (setq ps-paper-type 'a4))) - (let ((vars '("LC_ALL" "LC_PAPER" "LANG"))) - (while (and vars (= 0 (length locale))) - (setq locale (getenv (pop vars))))) - (when locale - ;; As of glibc 2.2.5, these are the only US Letter locales, - ;; and the rest are A4. - (setq ps-paper-type - (or (locale-name-match locale '(("c$" . letter) - ("posix$" . letter) - (".._us" . letter) - (".._pr" . letter) - (".._ca" . letter) - ("enu$" . letter) ; Windows - ("esu$" . letter) - ("enc$" . letter) - ("frc$" . letter))) - 'a4)))))) + (unless display + (let ((locale locale) + (paper (locale-info 'paper))) + (if paper + ;; This will always be null at the time of writing. + (cond + ((equal paper '(216 279)) + (setq ps-paper-type 'letter)) + ((equal paper '(210 297)) + (setq ps-paper-type 'a4))) + (let ((vars '("LC_ALL" "LC_PAPER" "LANG"))) + (while (and vars (= 0 (length locale))) + (setq locale (getenv (pop vars))))) + (when locale + ;; As of glibc 2.2.5, these are the only US Letter locales, + ;; and the rest are A4. + (setq ps-paper-type + (or (locale-name-match locale '(("c$" . letter) + ("posix$" . letter) + (".._us" . letter) + (".._pr" . letter) + (".._ca" . letter) + ("enu$" . letter) ; Windows + ("esu$" . letter) + ("enc$" . letter) + ("frc$" . letter))) + 'a4))))))) nil) ;;; Charset property diff --git a/lisp/international/mule.el b/lisp/international/mule.el index b48ce4698c4..74c4b96c3d4 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -1198,13 +1198,17 @@ see) to CODING-SYSTEM." This is normally set according to the selected language environment. See also the command `set-terminal-coding-system'.") -(defun set-terminal-coding-system (coding-system) - "Set coding system of your terminal to CODING-SYSTEM. -All text output to the terminal will be encoded +(defun set-terminal-coding-system (coding-system &optional display) + "Set coding system of terminal output to CODING-SYSTEM. +All text output to DISPLAY will be encoded with the specified coding system. + For a list of possible values of CODING-SYSTEM, use \\[list-coding-systems]. The default is determined by the selected language environment -or by the previous use of this command." +or by the previous use of this command. + +DISPLAY may be a display id, a frame, or nil for the selected frame's display. +The setting has no effect on graphical displays." (interactive (list (let ((default (if (and (not (terminal-coding-system)) default-terminal-coding-system) @@ -1218,7 +1222,7 @@ or by the previous use of this command." (setq coding-system default-terminal-coding-system)) (if coding-system (setq default-terminal-coding-system coding-system)) - (set-terminal-coding-system-internal coding-system) + (set-terminal-coding-system-internal coding-system display) (redraw-frame (selected-frame))) (defvar default-keyboard-coding-system nil @@ -1226,14 +1230,18 @@ or by the previous use of this command." This is normally set according to the selected language environment. See also the command `set-keyboard-coding-system'.") -(defun set-keyboard-coding-system (coding-system) - "Set coding system for keyboard input to CODING-SYSTEM. +(defun set-keyboard-coding-system (coding-system &optional display) + "Set coding system for keyboard input on DISPLAY to CODING-SYSTEM. In addition, this command enables Encoded-kbd minor mode. \(If CODING-SYSTEM is nil, Encoded-kbd mode is turned off -- see `encoded-kbd-mode'.) + For a list of possible values of CODING-SYSTEM, use \\[list-coding-systems]. The default is determined by the selected language environment -or by the previous use of this command." +or by the previous use of this command. + +DISPLAY may be a display id, a frame, or nil for the selected frame's display. +The setting has no effect on graphical displays." (interactive (list (let ((default (if (and (not (keyboard-coding-system)) default-keyboard-coding-system) @@ -1247,7 +1255,7 @@ or by the previous use of this command." (setq coding-system default-keyboard-coding-system)) (if coding-system (setq default-keyboard-coding-system coding-system)) - (set-keyboard-coding-system-internal coding-system) + (set-keyboard-coding-system-internal coding-system display) (setq keyboard-coding-system coding-system) (encoded-kbd-mode (if coding-system 1 0))) diff --git a/lisp/loadup.el b/lisp/loadup.el index 53d82323feb..d5f97e49245 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -68,6 +68,8 @@ (setq load-source-file-function 'load-with-code-conversion) (load "files") +(load "startup") + (load "cus-face") (load "faces") ; after here, `defface' may be used. @@ -147,7 +149,6 @@ (message "%s" (garbage-collect)) (load "menu-bar") (load "paths.el") ;Don't get confused if someone compiled paths by mistake. -(load "startup") (load "emacs-lisp/lisp") (load "textmodes/page") (load "register") @@ -163,6 +164,7 @@ (load "vmsproc"))) (load "abbrev") (load "buff-menu") +(load "server") ; server-getenv is used throughout the terminal initialization code (if (eq system-type 'vax-vms) (progn (load "vms-patch"))) @@ -190,6 +192,16 @@ (load "emacs-lisp/float-sup"))) (message "%s" (garbage-collect)) +;; Load auxiliary settings for X displays if we support them. +(when (fboundp 'x-create-frame) + (load "mouse") + (load "international/fontset") + (load "dnd") + (load "x-dnd") + (load "term/x-win")) + +(message "%s" (garbage-collect)) + (load "vc-hooks") (load "jka-cmpr-hook") (load "ediff-hook") diff --git a/lisp/server.el b/lisp/server.el index 0a5fc942206..f3f04d26fd5 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -8,6 +8,7 @@ ;; Keywords: processes ;; Changes by peck@sun.com and by rms. +;; Overhaul by Karoly Lorentey <lorentey@elte.hu> for multi-tty support. ;; This file is part of GNU Emacs. @@ -41,7 +42,7 @@ ;; This program transmits the file names to Emacs through ;; the server subprocess, and Emacs visits them and lets you edit them. -;; Note that any number of clients may dispatch files to emacs to be edited. +;; Note that any number of clients may dispatch files to Emacs to be edited. ;; When you finish editing a Server buffer, again call server-edit ;; to mark that buffer as done for the client and switch to the next @@ -102,9 +103,8 @@ (defvar server-clients nil "List of current server clients. -Each element is (CLIENTID BUFFERS...) where CLIENTID is a string -that can be given to the server process to identify a client. -When a buffer is marked as \"done\", it is removed from this list.") +Each element is (PROC PROPERTIES...) where PROC is a process object, +and PROPERTIES is an association list of client properties.") (defvar server-buffer-clients nil "List of client ids for clients requesting editing of current buffer.") @@ -161,57 +161,184 @@ are done with it in the server.") (defvar server-name "server") -(defvar server-socket-dir - (format "/tmp/emacs%d" (user-uid))) +(defvar server-socket-dir nil + "The directory in which to place the server socket. +Initialized by `server-start'.") + +(defun server-client (proc) + "Return the Emacs client corresponding to PROC. +PROC must be a process object. +The car of the result is PROC; the cdr is an association list. +See `server-client-get' and `server-client-set'." + (assq proc server-clients)) + +(defun server-client-get (client property) + "Get the value of PROPERTY in CLIENT. +CLIENT may be a process object, or a client returned by `server-client'. +Return nil if CLIENT has no such property." + (or (listp client) (setq client (server-client client))) + (cdr (assq property (cdr client)))) + +(defun server-client-set (client property value) + "Set the PROPERTY to VALUE in CLIENT, and return VALUE. +CLIENT may be a process object, or a client returned by `server-client'." + (let (p proc) + (if (listp client) + (setq proc (car client)) + (setq proc client + client (server-client client))) + (setq p (assq property client)) + (cond + (p (setcdr p value)) + (client (setcdr client (cons (cons property value) (cdr client)))) + (t (setq server-clients + `((,proc (,property . ,value)) . ,server-clients)))) + value)) + +(defun server-clients-with (property value) + "Return a list of clients with PROPERTY set to VALUE." + (let (result) + (dolist (client server-clients result) + (when (equal value (server-client-get client property)) + (setq result (cons (car client) result)))))) + +(defun server-add-client (proc) + "Create a client for process PROC, if it doesn't already have one. +New clients have no properties." + (unless (server-client proc) + (setq server-clients (cons (cons proc nil) + server-clients)))) + +;;;###autoload +(defun server-getenv (variable &optional frame) + "Get the value of VARIABLE in the client environment of frame FRAME. +VARIABLE should be a string. Value is nil if VARIABLE is undefined in +the environment. Otherwise, value is a string. + +If FRAME is an emacsclient frame, then the variable is looked up +in the environment of the emacsclient process; otherwise the +function consults the environment of the Emacs process. + +If FRAME is nil or missing, then the selected frame is used." + (when (not frame) (setq frame (selected-frame))) + (let ((client (frame-parameter frame 'client)) env) + (if (null client) + (getenv variable) + (setq env (server-client-get client 'environment)) + (if (null env) + (getenv variable) + (cdr (assoc variable env)))))) + +(defmacro server-with-client-environment (client vars &rest body) + "Evaluate BODY with environment variables VARS set to those of CLIENT. +The environment variables are then restored to their previous values. + +VARS should be a list of strings." + (declare (indent 2)) + (let ((oldvalues (make-symbol "oldvalues")) + (var (make-symbol "var")) + (value (make-symbol "value")) + (pair (make-symbol "pair"))) + `(let (,oldvalues) + (dolist (,var (quote ,vars)) + (let ((,value (cdr (assoc ,var (server-client-get ,client 'environment))))) + (setq ,oldvalues (cons (cons ,var (getenv ,var)) ,oldvalues)) + (setenv ,var ,value))) + (unwind-protect + (progn ,@body) + (dolist (,pair ,oldvalues) + (setenv (car ,pair) (cdr ,pair))))))) + +(defun server-delete-client (client &optional noframe) + "Delete CLIENT, including its buffers, displays and frames. +If NOFRAME is non-nil, let the frames live. (To be used from +`delete-frame-functions'." + ;; Force a new lookup of client (prevents infinite recursion). + (setq client (server-client + (if (listp client) (car client) client))) + (let ((proc (car client)) + (buffers (server-client-get client 'buffers))) + (when client + (setq server-clients (delq client server-clients)) + + (dolist (buf buffers) + (when (buffer-live-p buf) + (with-current-buffer buf + ;; Remove PROC from the clients of each buffer. + (setq server-buffer-clients (delq proc server-buffer-clients)) + ;; Kill the buffer if necessary. + (when (and (null server-buffer-clients) + (or (and server-kill-new-buffers + (not server-existing-buffer)) + (server-temp-file-p))) + (kill-buffer (current-buffer)))))) + + ;; Delete the client's tty. + (let ((display-id (server-client-get client 'display))) + (when (eq (display-live-p display-id) t) + (delete-display display-id))) + + ;; Delete the client's frames. + (unless noframe + (dolist (frame (frame-list)) + (if (and (frame-live-p frame) + (equal (car client) (frame-parameter frame 'client))) + (delete-frame frame)))) + + ;; Delete the client's process. + (if (eq (process-status (car client)) 'open) + (delete-process (car client))) + + (server-log "Deleted" proc)))) (defun server-log (string &optional client) - "If a *server* buffer exists, write STRING to it for logging purposes." + "If a *server* buffer exists, write STRING to it for logging purposes. +If CLIENT is non-nil, add a description of it to the logged +message." (if (get-buffer "*server*") (with-current-buffer "*server*" (goto-char (point-max)) (insert (current-time-string) - (if client (format " %s:" client) " ") + (cond + ((null client) " ") + ((listp client) (format " %s: " (car client))) + (t (format " %s: " client))) string) (or (bolp) (newline))))) (defun server-sentinel (proc msg) - (let ((client (assq proc server-clients))) - ;; Remove PROC from the list of clients. - (when client - (setq server-clients (delq client server-clients)) - (dolist (buf (cdr client)) - (with-current-buffer buf - ;; Remove PROC from the clients of each buffer. - (setq server-buffer-clients (delq proc server-buffer-clients)) - ;; Kill the buffer if necessary. - (when (and (null server-buffer-clients) - (or (and server-kill-new-buffers - (not server-existing-buffer)) - (server-temp-file-p))) - (kill-buffer (current-buffer))))))) - (server-log (format "Status changed to %s" (process-status proc)) proc)) - -(defun server-select-display (display) - ;; If the current frame is on `display' we're all set. - (unless (equal (frame-parameter (selected-frame) 'display) display) - ;; Otherwise, look for an existing frame there and select it. - (dolist (frame (frame-list)) - (when (equal (frame-parameter frame 'display) display) - (select-frame frame))) - ;; If there's no frame on that display yet, create a dummy one - ;; and select it. - (unless (equal (frame-parameter (selected-frame) 'display) display) - (select-frame - (make-frame-on-display - display - ;; This frame is only there in place of an actual "current display" - ;; setting, so we want it to be as unobtrusive as possible. That's - ;; what the invisibility is for. The minibuffer setting is so that - ;; we don't end up displaying a buffer in it (which noone would - ;; notice). - '((visibility . nil) (minibuffer . only))))))) + "The process sentinel for Emacs server connections." + (server-log (format "Status changed to %s: %s" (process-status proc) msg) proc) + (server-delete-client proc)) + +(defun server-handle-delete-frame (frame) + "Delete the client connection when the emacsclient frame is deleted." + (let ((proc (frame-parameter frame 'client))) + (when (and proc + (or (window-system frame) + ;; A terminal display must not yet be deleted if + ;; there are other frames on it. + (< 0 (let ((frame-num 0)) + (mapc (lambda (f) + (when (eq (frame-display f) + (frame-display frame)) + (setq frame-num (1+ frame-num)))) + (frame-list)) + frame-num)))) + (server-log (format "server-handle-delete-frame, frame %s" frame) proc) + (server-delete-client proc 'noframe)))) ; Let delete-frame delete the frame later. + +(defun server-handle-suspend-tty (display) + "Notify the emacsclient process to suspend itself when its tty device is suspended." + (dolist (proc (server-clients-with 'display display)) + (server-log (format "server-handle-suspend-tty, display %s" display) proc) + (condition-case err + (server-send-string proc "-suspend \n") + (file-error (condition-case nil (server-delete-client proc) (error nil)))))) (defun server-unquote-arg (arg) + "Remove &-quotation from ARG. +See `server-quote-arg' and `server-process-filter'." (replace-regexp-in-string "&." (lambda (s) (case (aref s 1) @@ -221,6 +348,26 @@ are done with it in the server.") (t " "))) arg t t)) +(defun server-quote-arg (arg) + "In ARG, insert a & before each &, each space, each newline, and -. +Change spaces to underscores, too, so that the return value never +contains a space. + +See `server-unquote-arg' and `server-process-filter'." + (replace-regexp-in-string + "[-&\n ]" (lambda (s) + (case (aref s 0) + (?& "&&") + (?- "&-") + (?\n "&n") + (?\s "&_"))) + arg t t)) + +(defun server-send-string (proc string) + "A wrapper around `proc-send-string' for logging." + (server-log (concat "Sent " string) proc) + (process-send-string proc string)) + (defun server-ensure-safe-dir (dir) "Make sure DIR is a directory with no race-condition issues. Creates the directory if necessary and makes sure: @@ -241,38 +388,53 @@ Creates the directory if necessary and makes sure: (defun server-start (&optional leave-dead) "Allow this Emacs process to be a server for client processes. This starts a server communications subprocess through which -client \"editors\" can send your editing commands to this Emacs job. -To use the server, set up the program `emacsclient' in the +client \"editors\" can send your editing commands to this Emacs +job. To use the server, set up the program `emacsclient' in the Emacs distribution as your standard \"editor\". -Prefix arg means just kill any existing server communications subprocess." +Prefix arg LEAVE-DEAD means just kill any existing server +communications subprocess." (interactive "P") - ;; Make sure there is a safe directory in which to place the socket. - (server-ensure-safe-dir server-socket-dir) - ;; kill it dead! - (if server-process - (condition-case () (delete-process server-process) (error nil))) - ;; Delete the socket files made by previous server invocations. - (condition-case () - (delete-file (expand-file-name server-name server-socket-dir)) - (error nil)) - ;; If this Emacs already had a server, clear out associated status. - (while server-clients - (let ((buffer (nth 1 (car server-clients)))) - (server-buffer-done buffer))) - (unless leave-dead + (when (or + (not server-clients) + (yes-or-no-p + "The current server still has clients; delete them? ")) + ;; It is safe to get the user id now. + (setq server-socket-dir (or server-socket-dir + (format "/tmp/emacs%d" (user-uid)))) + ;; Make sure there is a safe directory in which to place the socket. + (server-ensure-safe-dir server-socket-dir) + ;; kill it dead! (if server-process - (server-log (message "Restarting server"))) - (letf (((default-file-modes) ?\700)) - (setq server-process - (make-network-process - :name "server" :family 'local :server t :noquery t - :service (expand-file-name server-name server-socket-dir) - :sentinel 'server-sentinel :filter 'server-process-filter - ;; We must receive file names without being decoded. - ;; Those are decoded by server-process-filter according - ;; to file-name-coding-system. - :coding 'raw-text))))) + (condition-case () (delete-process server-process) (error nil))) + ;; Delete the socket files made by previous server invocations. + (condition-case () + (delete-file (expand-file-name server-name server-socket-dir)) + (error nil)) + ;; If this Emacs already had a server, clear out associated status. + (while server-clients + (server-delete-client (car server-clients))) + (if leave-dead + (progn + (server-log (message "Server stopped")) + (setq server-process nil)) + (if server-process + (server-log (message "Restarting server")) + (server-log (message "Starting server"))) + (letf (((default-file-modes) ?\700)) + (add-hook 'suspend-tty-functions 'server-handle-suspend-tty) + (add-hook 'delete-frame-functions 'server-handle-delete-frame) + (add-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function) + (add-hook 'kill-emacs-query-functions 'server-kill-emacs-query-function) + (setq server-process + (make-network-process + :name "server" :family 'local :server t :noquery t + :service (expand-file-name server-name server-socket-dir) + :sentinel 'server-sentinel :filter 'server-process-filter + ;; We must receive file names without being decoded. + ;; Those are decoded by server-process-filter according + ;; to file-name-coding-system. + :coding 'raw-text)))))) ;;;###autoload (define-minor-mode server-mode @@ -289,105 +451,334 @@ Server mode runs a process that accepts commands from the (defun server-process-filter (proc string) "Process a request from the server to edit some files. -PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"." - (server-log string proc) +PROC is the server process. STRING consists of a sequence of +commands prefixed by a dash. Some commands have arguments; these +are &-quoted and need to be decoded by `server-unquote-arg'. The +filter parses and executes these commands. + +To illustrate the protocol, here is an example command that +emacsclient sends to create a new X frame (note that the whole +sequence is sent on a single line): + + -version 21.3.50 xterm + -env HOME /home/lorentey + -env DISPLAY :0.0 + ... lots of other -env commands + -display :0.0 + -window-system + +The server normally sends back the single command `-good-version' +as a response. + +The following commands are accepted by the server: + +`-version CLIENT-VERSION' + Check version numbers between server and client, and signal an + error if there is a mismatch. The server replies with + `-good-version' to confirm the match. + +`-env NAME VALUE' + An environment variable on the client side. + +`-nowait' + Request that the next frame created should not be + associated with this client. + +`-display DISPLAY' + Set the display name to open X frames on. + +`-position LINE[:COLUMN]' + Go to the given line and column number + in the next file opened. + +`-file FILENAME' + Load the given file in the current frame. + +`-eval EXPR' + Evaluate EXPR as a Lisp expression and return the + result in -print commands. + +`-window-system' + Open a new X frame. + +`-tty DEVICENAME TYPE' + Open a new tty frame at the client. + +`-resume' + Resume this tty frame. The client sends this string when it + gets the SIGCONT signal and it is the foreground process on its + controlling tty. + +`-suspend' + Suspend this tty frame. The client sends this string in + response to SIGTSTP and SIGTTOU. The server must cease all I/O + on this tty until it gets a -resume command. + +`-ignore COMMENT' + Do nothing, but put the comment in the server + log. Useful for debugging. + + +The following commands are accepted by the client: + +`-good-version' + Signals a version match between the client and the server. + +`-emacs-pid PID' + Describes the process id of the Emacs process; + used to forward window change signals to it. + +`-window-system-unsupported' + Signals that the server does not + support creating X frames; the client must try again with a tty + frame. + +`-print STRING' + Print STRING on stdout. Used to send values + returned by -eval. + +`-error DESCRIPTION' + Signal an error (but continue processing). + +`-suspend' + Suspend this terminal, i.e., stop the client process. Sent + when the user presses C-z." + (server-log (concat "Received " string) proc) (let ((prev (process-get proc 'previous-string))) (when prev (setq string (concat prev string)) (process-put proc 'previous-string nil))) - ;; If the input is multiple lines, - ;; process each line individually. - (while (string-match "\n" string) - (let ((request (substring string 0 (match-beginning 0))) - (coding-system (and default-enable-multibyte-characters - (or file-name-coding-system - default-file-name-coding-system))) - client nowait eval - (files nil) - (lineno 1) - (tmp-frame nil) ; Sometimes used to embody the selected display. - (columnno 0)) - ;; Remove this line from STRING. - (setq string (substring string (match-end 0))) - (setq client (cons proc nil)) - (while (string-match "[^ ]* " request) - (let ((arg (substring request (match-beginning 0) (1- (match-end 0))))) - (setq request (substring request (match-end 0))) - (cond - ((equal "-nowait" arg) (setq nowait t)) - ((equal "-eval" arg) (setq eval t)) - ((and (equal "-display" arg) (string-match "\\([^ ]*\\) " request)) - (let ((display (server-unquote-arg (match-string 1 request)))) - (setq request (substring request (match-end 0))) - (condition-case err - (setq tmp-frame (server-select-display display)) - (error (process-send-string proc (nth 1 err)) - (setq request ""))))) - ;; ARG is a line number option. - ((string-match "\\`\\+[0-9]+\\'" arg) - (setq lineno (string-to-number (substring arg 1)))) - ;; ARG is line number:column option. - ((string-match "\\`+\\([0-9]+\\):\\([0-9]+\\)\\'" arg) - (setq lineno (string-to-number (match-string 1 arg)) - columnno (string-to-number (match-string 2 arg)))) - (t - ;; Undo the quoting that emacsclient does - ;; for certain special characters. - (setq arg (server-unquote-arg arg)) - ;; Now decode the file name if necessary. - (if coding-system - (setq arg (decode-coding-string arg coding-system))) - (if eval - (let ((v (eval (car (read-from-string arg))))) - (when v - (with-temp-buffer - (let ((standard-output (current-buffer))) - (pp v) - ;; Suppress the error rose when the pipe to PROC is closed. - (condition-case err - (process-send-region proc (point-min) (point-max)) - (file-error nil) - (error nil)) - )))) - ;; ARG is a file name. - ;; Collapse multiple slashes to single slashes. - (setq arg (command-line-normalize-file-name arg)) - (push (list arg lineno columnno) files)) - (setq lineno 1) - (setq columnno 0))))) - (when files - (run-hooks 'pre-command-hook) - (server-visit-files files client nowait) - (run-hooks 'post-command-hook)) - ;; CLIENT is now a list (CLIENTNUM BUFFERS...) - (if (null (cdr client)) - ;; This client is empty; get rid of it immediately. - (progn - (delete-process proc) - (server-log "Close empty client" proc)) - ;; We visited some buffer for this client. - (or nowait (push client server-clients)) - (unless (or isearch-mode (minibufferp)) - (server-switch-buffer (nth 1 client)) - (run-hooks 'server-switch-hook) - (unless nowait - (message (substitute-command-keys - "When done with a buffer, type \\[server-edit]"))))) - ;; Avoid preserving the connection after the last real frame is deleted. - (if tmp-frame (delete-frame tmp-frame)))) - ;; Save for later any partial line that remains. - (when (> (length string) 0) - (process-put proc 'previous-string string))) + (condition-case err + (progn + (server-add-client proc) + ;; If the input is multiple lines, + ;; process each line individually. + (while (string-match "\n" string) + (let ((request (substring string 0 (match-beginning 0))) + (coding-system (and default-enable-multibyte-characters + (or file-name-coding-system + default-file-name-coding-system))) + (client (server-client proc)) + nowait ; t if emacsclient does not want to wait for us. + frame ; The frame that was opened for the client (if any). + display ; Open the frame on this display. + dontkill ; t if the client should not be killed. + (files nil) + (lineno 1) + (columnno 0)) + ;; Remove this line from STRING. + (setq string (substring string (match-end 0))) + (while (string-match " *[^ ]* " request) + (let ((arg (substring request (match-beginning 0) (1- (match-end 0))))) + (setq request (substring request (match-end 0))) + (cond + ;; -version CLIENT-VERSION: + ;; Check version numbers, signal an error if there is a mismatch. + ((and (equal "-version" arg) + (string-match "\\([0-9.]+\\) " request)) + (let* ((client-version (match-string 1 request)) + (truncated-emacs-version + (substring emacs-version 0 (length client-version)))) + (setq request (substring request (match-end 0))) + (if (equal client-version truncated-emacs-version) + (progn + (server-send-string proc "-good-version \n") + (server-client-set client 'version client-version)) + (error (concat "Version mismatch: Emacs is " + truncated-emacs-version + ", emacsclient is " client-version))))) + + ;; -nowait: Emacsclient won't wait for a result. + ((equal "-nowait" arg) (setq nowait t)) + + ;; -display DISPLAY: + ;; Open X frames on the given instead of the default. + ((and (equal "-display" arg) (string-match "\\([^ ]*\\) " request)) + (setq display (match-string 1 request) + request (substring request (match-end 0)))) + + ;; -window-system: Open a new X frame. + ((equal "-window-system" arg) + (unless (server-client-get client 'version) + (error "Protocol error; make sure to use the correct version of emacsclient")) + (if (fboundp 'x-create-frame) + (progn + (setq frame (make-frame-on-display + (or display + (frame-parameter nil 'display) + (getenv "DISPLAY") + (error "Please specify display")) + (list (cons 'client proc)))) + ;; XXX We need to ensure the client parameter is + ;; really set because Emacs forgets initialization + ;; parameters for X frames at the moment. + (modify-frame-parameters frame (list (cons 'client proc))) + (select-frame frame) + (server-client-set client 'frame frame) + (server-client-set client 'display (frame-display frame)) + (setq dontkill t)) + ;; This emacs does not support X. + (server-log "Window system unsupported" proc) + (server-send-string proc "-window-system-unsupported \n") + (setq dontkill t))) + + ;; -resume: Resume a suspended tty frame. + ((equal "-resume" arg) + (let ((display-id (server-client-get client 'display))) + (setq dontkill t) + (when (eq (display-live-p display-id) t) + (resume-tty display-id)))) + + ;; -suspend: Suspend the client's frame. (In case we + ;; get out of sync, and a C-z sends a SIGTSTP to + ;; emacsclient.) + ((equal "-suspend" arg) + (let ((display-id (server-client-get client 'display))) + (setq dontkill t) + (when (eq (display-live-p display-id) t) + (suspend-tty display-id)))) + + ;; -ignore COMMENT: Noop; useful for debugging emacsclient. + ;; (The given comment appears in the server log.) + ((and (equal "-ignore" arg) (string-match "\\([^ ]*\\) " request)) + (setq dontkill t + request (substring request (match-end 0)))) + + ;; -tty DEVICE-NAME TYPE: Open a new tty frame at the client. + ((and (equal "-tty" arg) (string-match "\\([^ ]*\\) \\([^ ]*\\) " request)) + (let ((tty (server-unquote-arg (match-string 1 request))) + (type (server-unquote-arg (match-string 2 request)))) + (setq request (substring request (match-end 0))) + (unless (server-client-get client 'version) + (error "Protocol error; make sure you use the correct version of emacsclient")) + (server-with-client-environment proc + ("LANG" "LC_CTYPE" "LC_ALL" + ;; For tgetent(3); list according to ncurses(3). + "BAUDRATE" "COLUMNS" "ESCDELAY" "HOME" "LINES" + "NCURSES_ASSUMED_COLORS" "NCURSES_NO_PADDING" + "NCURSES_NO_SETBUF" "TERM" "TERMCAP" "TERMINFO" + "TERMINFO_DIRS" "TERMPATH") + (setq frame (make-frame-on-tty tty type + `((client . ,proc))))) + (select-frame frame) + (server-client-set client 'frame frame) + (server-client-set client 'tty (display-name frame)) + (server-client-set client 'display (frame-display frame)) + + ;; Reply with our pid. + (server-send-string proc (concat "-emacs-pid " (number-to-string (emacs-pid)) "\n")) + (setq dontkill t))) + + ;; -position LINE: Go to the given line in the next file. + ((and (equal "-position" arg) (string-match "\\(\\+[0-9]+\\) " request)) + (setq request (substring request (match-end 0)) + lineno (string-to-number (substring (match-string 1 request) 1)))) + + ;; -position LINE:COLUMN: Set point to the given position in the next file. + ((and (equal "-position" arg) (string-match "\\+\\([0-9]+\\):\\([0-9]+\\) " request)) + (setq lineno (string-to-number (match-string 1 request)) + columnno (string-to-number (match-string 2 request)) + request (substring request (match-end 0)))) + + ;; -file FILENAME: Load the given file. + ((and (equal "-file" arg) (string-match "\\([^ ]+\\) " request)) + (let ((file (server-unquote-arg (match-string 1 request)))) + (setq request (substring request (match-end 0))) + (if coding-system + (setq file (decode-coding-string file coding-system))) + (setq file (command-line-normalize-file-name file)) + (push (list file lineno columnno) files)) + (setq lineno 1 + columnno 0)) + + ;; -eval EXPR: Evaluate a Lisp expression. + ((and (equal "-eval" arg) (string-match "\\([^ ]+\\) " request)) + (let ((expr (server-unquote-arg (match-string 1 request)))) + (setq request (substring request (match-end 0))) + (if coding-system + (setq expr (decode-coding-string expr coding-system))) + (let ((v (eval (car (read-from-string expr))))) + (when (and (not frame) v) + (with-temp-buffer + (let ((standard-output (current-buffer))) + (pp v) + (server-send-string + proc (format "-print %s\n" + (server-quote-arg + (buffer-substring-no-properties (point-min) + (point-max))))))))) + (setq lineno 1 + columnno 0))) + + ;; -env NAME VALUE: An environment variable. + ((and (equal "-env" arg) (string-match "\\([^ ]+\\) \\([^ ]+\\) " request)) + (let ((name (server-unquote-arg (match-string 1 request))) + (value (server-unquote-arg (match-string 2 request)))) + (when coding-system + (setq name (decode-coding-string name coding-system)) + (setq value (decode-coding-string value coding-system))) + (setq request (substring request (match-end 0))) + (server-client-set + client 'environment + (cons (cons name value) + (server-client-get client 'environment))))) + + ;; Unknown command. + (t (error "Unknown command: %s" arg))))) + + (let (buffers) + (when files + (run-hooks 'pre-command-hook) + (setq buffers (server-visit-files files client nowait)) + (run-hooks 'post-command-hook)) + + ;; Delete the client if necessary. + (cond + (nowait + ;; Client requested nowait; return immediately. + (server-log "Close nowait client" proc) + (server-delete-client proc)) + ((and (not dontkill) (null buffers)) + ;; This client is empty; get rid of it immediately. + (server-log "Close empty client" proc) + (server-delete-client proc))) + (cond + ((or isearch-mode (minibufferp)) + nil) + ((and frame (null buffers)) + (message (substitute-command-keys + "When done with this frame, type \\[delete-frame]"))) + ((not (null buffers)) + (server-switch-buffer (car buffers)) + (run-hooks 'server-switch-hook) + (unless nowait + (message (substitute-command-keys + "When done with a buffer, type \\[server-edit]")))))))) + + ;; Save for later any partial line that remains. + (when (> (length string) 0) + (process-put proc 'previous-string string))) + ;; condition-case + (error (ignore-errors + (server-send-string + proc (concat "-error " (server-quote-arg (error-message-string err)))) + (setq string "") + (server-log (error-message-string err) proc) + (delete-process proc))))) (defun server-goto-line-column (file-line-col) + "Move point to the position indicated in FILE-LINE-COL. +FILE-LINE-COL should be a three-element list as described in +`server-visit-files'." (goto-line (nth 1 file-line-col)) (let ((column-number (nth 2 file-line-col))) (if (> column-number 0) (move-to-column (1- column-number))))) (defun server-visit-files (files client &optional nowait) - "Find FILES and return the list CLIENT with the buffers nconc'd. + "Find FILES and return a list of buffers created. FILES is an alist whose elements are (FILENAME LINENUMBER COLUMNNUMBER). +CLIENT is the client that requested this operation. NOWAIT non-nil means this client is not waiting for the results, so don't mark these buffers specially, just visit them normally." ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries. @@ -410,8 +801,7 @@ so don't mark these buffers specially, just visit them normally." (revert-buffer t nil))) (t (if (y-or-n-p - (concat "File no longer exists: " - filen + (concat "File no longer exists: " filen ", write buffer to file? ")) (write-file filen)))) (setq server-existing-buffer t) @@ -424,7 +814,11 @@ so don't mark these buffers specially, just visit them normally." (add-hook 'kill-buffer-hook 'server-kill-buffer nil t) (push (car client) server-buffer-clients)) (push (current-buffer) client-record))) - (nconc client client-record))) + (unless nowait + (server-client-set + client 'buffers + (nconc (server-client-get client 'buffers) client-record))) + client-record)) (defun server-buffer-done (buffer &optional for-killing) "Mark BUFFER as \"done\" for its client(s). @@ -434,27 +828,24 @@ or nil. KILLED is t if we killed BUFFER (typically, because it was visiting a temp file). FOR-KILLING if non-nil indicates that we are called from `kill-buffer'." (let ((next-buffer nil) - (killed nil) - (old-clients server-clients)) - (while old-clients - (let ((client (car old-clients))) + (killed nil)) + (dolist (client server-clients) + (let ((buffers (server-client-get client 'buffers))) (or next-buffer - (setq next-buffer (nth 1 (memq buffer client)))) - (delq buffer client) - ;; Delete all dead buffers from CLIENT. - (let ((tail client)) - (while tail - (and (bufferp (car tail)) - (null (buffer-name (car tail))) - (delq (car tail) client)) - (setq tail (cdr tail)))) - ;; If client now has no pending buffers, - ;; tell it that it is done, and forget it entirely. - (unless (cdr client) - (delete-process (car client)) - (server-log "Close" (car client)) - (setq server-clients (delq client server-clients)))) - (setq old-clients (cdr old-clients))) + (setq next-buffer (nth 1 (memq buffer buffers)))) + (when buffers ; Ignore bufferless clients. + (setq buffers (delq buffer buffers)) + ;; Delete all dead buffers from CLIENT. + (dolist (b buffers) + (and (bufferp b) + (not (buffer-live-p b)) + (setq buffers (delq b buffers)))) + (server-client-set client 'buffers buffers) + ;; If client now has no pending buffers, + ;; tell it that it is done, and forget it entirely. + (unless buffers + (server-log "Close" client) + (server-delete-client client))))) (if (and (bufferp buffer) (buffer-name buffer)) ;; We may or may not kill this buffer; ;; if we do, do not call server-buffer-done recursively @@ -519,30 +910,32 @@ specifically for the clients and did not exist before their request for it." ;; but I think that is dangerous--the client would proceed ;; using whatever is on disk in that file. -- rms. (defun server-kill-buffer-query-function () + "Ask before killing a server buffer." (or (not server-buffer-clients) + (let ((res t)) + (dolist (proc server-buffer-clients res) + (let ((client (server-client proc))) + (when (and client (eq (process-status proc) 'open)) + (setq res nil))))) (yes-or-no-p (format "Buffer `%s' still has clients; kill it? " (buffer-name (current-buffer)))))) -(add-hook 'kill-buffer-query-functions - 'server-kill-buffer-query-function) - (defun server-kill-emacs-query-function () - (let (live-client - (tail server-clients)) - ;; See if any clients have any buffers that are still alive. - (while tail - (if (memq t (mapcar 'stringp (mapcar 'buffer-name (cdr (car tail))))) - (setq live-client t)) - (setq tail (cdr tail))) - (or (not live-client) - (yes-or-no-p "Server buffers still have clients; exit anyway? ")))) - -(add-hook 'kill-emacs-query-functions 'server-kill-emacs-query-function) + "Ask before exiting Emacs it has live clients." + (or (not server-clients) + (let (live-client) + (dolist (client server-clients live-client) + (if (memq t (mapcar 'buffer-live-p (server-client-get + client 'buffers))) + (setq live-client t)))) + (yes-or-no-p "This Emacs session has clients; exit anyway? "))) (defvar server-kill-buffer-running nil "Non-nil while `server-kill-buffer' or `server-buffer-done' is running.") (defun server-kill-buffer () + "Remove the current buffer from its clients' buffer list. +Designed to be added to `kill-buffer-hook'." ;; Prevent infinite recursion if user has made server-done-hook ;; call kill-buffer. (or server-kill-buffer-running @@ -574,18 +967,26 @@ starts server process and that is all. Invoked by \\[server-edit]." (defun server-switch-buffer (&optional next-buffer killed-one) "Switch to another buffer, preferably one that has a client. -Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it." - ;; KILLED-ONE is t in a recursive call - ;; if we have already killed one temp-file server buffer. - ;; This means we should avoid the final "switch to some other buffer" - ;; since we've already effectively done that. +Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it. + +KILLED-ONE is t in a recursive call if we have already killed one +temp-file server buffer. This means we should avoid the final +\"switch to some other buffer\" since we've already effectively +done that." (if (null next-buffer) - (if server-clients - (server-switch-buffer (nth 1 (car server-clients)) killed-one) - (unless (or killed-one (window-dedicated-p (selected-window))) - (switch-to-buffer (other-buffer)) + (progn + (let ((rest server-clients)) + (while (and rest (not next-buffer)) + (let ((client (car rest))) + ;; Only look at frameless clients. + (when (not (server-client-get client 'frame)) + (setq next-buffer (car (server-client-get client 'buffers)))) + (setq rest (cdr rest))))) + (and next-buffer (server-switch-buffer next-buffer killed-one)) + (unless (or next-buffer killed-one (window-dedicated-p (selected-window))) + ;; (switch-to-buffer (other-buffer)) (message "No server buffers remain to edit"))) - (if (not (buffer-name next-buffer)) + (if (not (buffer-live-p next-buffer)) ;; If NEXT-BUFFER is a dead buffer, remove the server records for it ;; and try the next surviving server buffer. (apply 'server-switch-buffer (server-buffer-done next-buffer)) @@ -625,10 +1026,35 @@ Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it." ;; a minibuffer/dedicated-window (if there's no other). (error (pop-to-buffer next-buffer))))))))) +(defun server-save-buffers-kill-display (&optional arg) + "Offer to save each buffer, then kill the current connection. +If the current frame has no client, kill Emacs itself. + +With prefix arg, silently save all file-visiting buffers, then kill. + +If emacsclient was started with a list of filenames to edit, then +only these files will be asked to be saved." + (interactive "P") + (let ((proc (frame-parameter (selected-frame) 'client))) + (if proc + (let ((buffers (server-client-get proc 'buffers))) + ;; If client is bufferless, emulate a normal Emacs session + ;; exit and offer to save all buffers. Otherwise, offer to + ;; save only the buffers belonging to the client. + (save-some-buffers arg + (if buffers + (lambda () (memq (current-buffer) buffers)) + t)) + (server-delete-client proc)) + (save-buffers-kill-emacs)))) + (global-set-key "\C-x#" 'server-edit) (defun server-unload-hook () + "Unload the server library." (server-start t) + (remove-hook 'suspend-tty-functions 'server-handle-suspend-tty) + (remove-hook 'delete-frame-functions 'server-handle-delete-frame) (remove-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function) (remove-hook 'kill-emacs-query-functions 'server-kill-emacs-query-function) (remove-hook 'kill-buffer-hook 'server-kill-buffer)) diff --git a/lisp/simple.el b/lisp/simple.el index 5a94c28828d..8c73c005e69 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2280,6 +2280,8 @@ the text which should be made available. The second, optional, argument PUSH, has the same meaning as the similar argument to `x-set-cut-buffer', which see.") +(make-variable-frame-local 'interprogram-cut-function) + (defvar interprogram-paste-function nil "Function to call to get text cut from other programs. @@ -2300,6 +2302,8 @@ most recent string, the function should return nil. If it is difficult to tell whether Emacs or some other program provided the current string, it is probably good enough to return nil if the string is equal (according to `string=') to the last text Emacs provided.") + +(make-variable-frame-local 'interprogram-paste-function) @@ -5139,14 +5143,14 @@ the front of the list of recently selected ones." (defcustom normal-erase-is-backspace (and (not noninteractive) (or (memq system-type '(ms-dos windows-nt)) - (eq window-system 'mac) - (and (memq window-system '(x)) + (eq initial-window-system 'mac) + (and (memq initial-window-system '(x)) (fboundp 'x-backspace-delete-keys-p) (x-backspace-delete-keys-p)) ;; If the terminal Emacs is running on has erase char ;; set to ^H, use the Backspace key for deleting ;; backward and, and the Delete key for deleting forward. - (and (null window-system) + (and (null initial-window-system) (eq tty-erase-char ?\^H)))) "If non-nil, Delete key deletes forward and Backspace key deletes backward. diff --git a/lisp/startup.el b/lisp/startup.el index b7d1a1d34df..8ad19623b3b 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -36,6 +36,13 @@ (defvar command-line-processed nil "Non-nil once command line has been processed.") +(defvar window-system initial-window-system + "Name of window system the selected frame is displaying through. +The value is a symbol--for instance, `x' for X windows. +The value is nil if the selected frame is on a text-only-terminal.") + +(make-variable-frame-local 'window-system) + (defgroup initialization nil "Emacs start-up procedure" :group 'internal) @@ -426,37 +433,19 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'." ;; for instance due to a dense colormap. (when (or frame-initial-frame ;; If frame-initial-frame has no meaning, do this anyway. - (not (and window-system + (not (and initial-window-system (not noninteractive) - (not (eq window-system 'pc))))) + (not (eq initial-window-system 'pc))))) ;; Modify the initial frame based on what .emacs puts into ;; ...-frame-alist. (if (fboundp 'frame-notice-user-settings) (frame-notice-user-settings)) + ;; Set the faces for the initial background mode even if + ;; frame-notice-user-settings didn't (such as on a tty). + ;; frame-set-background-mode is idempotent, so it won't + ;; cause any harm if it's already been done. (if (fboundp 'frame-set-background-mode) - ;; Set the faces for the initial background mode even if - ;; frame-notice-user-settings didn't (such as on a tty). - ;; frame-set-background-mode is idempotent, so it won't - ;; cause any harm if it's already been done. - (let ((frame-background-mode frame-background-mode) - (frame (selected-frame)) - term) - (when (and (null window-system) - ;; Don't override a possibly customized value. - (null frame-background-mode) - ;; Don't override user specifications. - (null (frame-parameter frame 'reverse)) - (let ((bg (frame-parameter frame 'background-color))) - (or (null bg) - (member bg '(unspecified "unspecified-bg"))))) - (setq term (getenv "TERM")) - ;; Some files in lisp/term do a better job with the - ;; background mode, but we leave this here anyway, in - ;; case they remove those files. - (if (string-match "^\\(xterm\\|rxvt\\|dtterm\\|eterm\\)" - term) - (setq frame-background-mode 'light))) - (frame-set-background-mode (selected-frame))))) + (frame-set-background-mode (selected-frame)))) ;; Now we know the user's default font, so add it to the menu. (if (fboundp 'font-menu-add-default) @@ -497,6 +486,20 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'." (defvar tool-bar-originally-present nil "Non-nil if tool-bars are present before user and site init files are read.") +(defvar handle-args-function-alist '((nil . tty-handle-args)) + "Functions for processing window-system dependent command-line arguments. +Window system startup files should add their own function to this +alist, which should parse the command line arguments. Those +pertaining to the window system should be processed and removed +from the returned command line.") + +(defvar window-system-initialization-alist '((nil . ignore)) + "Alist of window-system initialization functions. +Window-system startup files should add their own initialization +function to this list. The function should take no arguments, +and initialize the window system environment to prepare for +opening the first frame (e.g. open a connection to the server).") + ;; Handle the X-like command-line arguments "-fg", "-bg", "-name", etc. (defun tty-handle-args (args) (let (rest) @@ -601,16 +604,22 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'." (setq eol-mnemonic-dos "(DOS)" eol-mnemonic-mac "(Mac)"))) - ;; Read window system's init file if using a window system. + ;; Make sure window system's init file was loaded in loadup.el if using a window system. (condition-case error - (if (and window-system (not noninteractive)) - (load (concat term-file-prefix - (symbol-name window-system) - "-win") - ;; Every window system should have a startup file; - ;; barf if we can't find it. - nil t)) - ;; If we can't read it, print the error message and exit. + (unless noninteractive + (if (and initial-window-system + (not (featurep + (intern (concat (symbol-name initial-window-system) "-win"))))) + (error "Unsupported window system `%s'" initial-window-system)) + ;; Process window-system specific command line parameters. + (setq command-line-args + (funcall (or (cdr (assq initial-window-system handle-args-function-alist)) + (error "Unsupported window system `%s'" initial-window-system)) + command-line-args)) + ;; Initialize the window system. (Open connection, etc.) + (funcall (or (cdr (assq initial-window-system window-system-initialization-alist)) + (error "Unsupported window system `%s'" initial-window-system)))) + ;; If there was an error, print the error message and exit. (error (princ (if (eq (car error) 'error) @@ -626,13 +635,9 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'." (cdr error) ", ")))) 'external-debugging-output) (terpri 'external-debugging-output) - (setq window-system nil) + (setq initial-window-system nil) (kill-emacs))) - ;; Windowed displays do this inside their *-win.el. - (unless (or (display-graphic-p) noninteractive) - (setq command-line-args (tty-handle-args command-line-args))) - (set-locale-environment nil) ;; Convert the arguments to Emacs internal representation. @@ -730,7 +735,7 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'." ;; If frame was created with a menu bar, set menu-bar-mode on. (unless (or noninteractive emacs-basic-display - (and (memq window-system '(x w32)) + (and (memq initial-window-system '(x w32)) (<= (frame-parameter nil 'menu-bar-lines) 0))) (menu-bar-mode 1)) @@ -757,11 +762,10 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'." ;; Register default TTY colors for the case the terminal hasn't a ;; terminal init file. - (unless (memq window-system '(x w32)) - ;; We do this regardles of whether the terminal supports colors - ;; or not, since they can switch that support on or off in - ;; mid-session by setting the tty-color-mode frame parameter. - (tty-register-default-colors)) + ;; We do this regardles of whether the terminal supports colors + ;; or not, since they can switch that support on or off in + ;; mid-session by setting the tty-color-mode frame parameter. + (tty-register-default-colors) ;; Record whether the tool-bar is present before the user and site ;; init files are processed. frame-notice-user-settings uses this @@ -967,7 +971,7 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'." ;; Load library for our terminal type. ;; User init file can set term-file-prefix to nil to prevent this. (unless (or noninteractive - window-system + initial-window-system (null term-file-prefix)) (let ((term (getenv "TERM")) hyphend) diff --git a/lisp/subr.el b/lisp/subr.el index ee084e09f14..926d0f3ae48 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1710,6 +1710,18 @@ See also `with-temp-buffer'." (if (window-live-p save-selected-window-window) (select-window save-selected-window-window 'norecord))))) +(defmacro with-selected-frame (frame &rest body) + "Execute the forms in BODY with FRAME as the selected frame. +The value returned is the value of the last form in BODY. +See also `with-temp-buffer'." + (declare (indent 1) (debug t)) + `(let ((save-selected-frame (selected-frame))) + (unwind-protect + (progn (select-frame ,frame) + ,@body) + (if (frame-live-p save-selected-frame) + (select-frame save-selected-frame))))) + (defmacro with-temp-file (file &rest body) "Create a new buffer, evaluate BODY there, and write the buffer to FILE. The value returned is the value of the last form in BODY. diff --git a/lisp/talk.el b/lisp/talk.el index bbe9c949dde..56549431aab 100644 --- a/lisp/talk.el +++ b/lisp/talk.el @@ -45,17 +45,44 @@ Each element has the form (DISPLAY FRAME BUFFER).") ;; Add the new buffers to all talk frames. (talk-update-buffers)) -(defun talk-add-display (display) - (let* ((elt (assoc display talk-display-alist)) - (name (concat "*talk-" display "*")) - buffer frame) - (if (not (and elt (frame-live-p (setq frame (nth 1 elt))))) - (setq frame (make-frame-on-display display (list (cons 'name name))))) +;;;###autoload +(defun talk () + "Connect to the Emacs talk group from the current X display or tty frame." + (interactive) + (let ((type (frame-live-p (selected-frame))) + (display (frame-display (selected-frame)))) + (cond + ((eq type t) + (talk-add-display (selected-frame))) + ((eq type 'x) + (talk-add-display (frame-display (selected-frame)))) + (t + (error "Unknown frame type")))) + (talk-update-buffers)) + +(defun talk-add-display (frame) + (let* ((display (if (frame-live-p frame) + (frame-display frame) + frame)) + (elt (assoc display talk-display-alist)) + (name (concat "*talk-" (display-name display) "*")) + buffer) + (unless (frame-live-p frame) + (setq frame (make-frame-on-display display (list (cons 'name name))))) + (if (and elt (frame-live-p (nth 1 elt))) + (setq frame (nth 1 elt))) (if (not (and elt (buffer-name (get-buffer (setq buffer (nth 2 elt)))))) (setq buffer (get-buffer-create name))) + (add-to-list 'delete-frame-functions 'talk-handle-delete-frame) (setq talk-display-alist (cons (list display frame buffer) (delq elt talk-display-alist))))) +(defun talk-handle-delete-frame (frame) + (dolist (d talk-display-alist) + (when (eq (nth 1 d) frame) + (setq talk-display-alist (delq d talk-display-alist)) + (talk-update-buffers)))) + (defun talk-disconnect () "Disconnect this display from the Emacs talk group." (interactive) diff --git a/lisp/term/iris-ansi.el b/lisp/term/iris-ansi.el index e73c3e19968..05c7e9a5955 100644 --- a/lisp/term/iris-ansi.el +++ b/lisp/term/iris-ansi.el @@ -25,6 +25,8 @@ ;;; Code: +;; XXX We need to find a way to have these define-keys be display-local. -- Lorentey + (define-key function-key-map "\e[120q" [S-escape]) (define-key function-key-map "\e[121q" [C-escape]) diff --git a/lisp/term/lk201.el b/lisp/term/lk201.el index 1f8d9ca77a3..e09b176ba8f 100644 --- a/lisp/term/lk201.el +++ b/lisp/term/lk201.el @@ -1,72 +1,87 @@ ;; -*- no-byte-compile: t -*- ;; Define function key sequences for DEC terminals. -;; Termcap or terminfo should set these. -;; (define-key function-key-map "\e[A" [up]) -;; (define-key function-key-map "\e[B" [down]) -;; (define-key function-key-map "\e[C" [right]) -;; (define-key function-key-map "\e[D" [left]) +(defvar lk201-function-map nil + "Function key definitions for lk201.") -(define-key function-key-map "\e[1~" [find]) -(define-key function-key-map "\e[2~" [insert]) -(define-key function-key-map "\e[3~" [delete]) -(define-key function-key-map "\e[4~" [select]) -(define-key function-key-map "\e[5~" [prior]) -(define-key function-key-map "\e[6~" [next]) -(define-key function-key-map "\e[11~" [f1]) -(define-key function-key-map "\e[12~" [f2]) -(define-key function-key-map "\e[13~" [f3]) -(define-key function-key-map "\e[14~" [f4]) -(define-key function-key-map "\e[15~" [f5]) -(define-key function-key-map "\e[17~" [f6]) -(define-key function-key-map "\e[18~" [f7]) -(define-key function-key-map "\e[19~" [f8]) -(define-key function-key-map "\e[20~" [f9]) -(define-key function-key-map "\e[21~" [f10]) -;; Customarily F11 is used as the ESC key. -;; The file that includes this one, takes care of that. -(define-key function-key-map "\e[23~" [f11]) -(define-key function-key-map "\e[24~" [f12]) -(define-key function-key-map "\e[25~" [f13]) -(define-key function-key-map "\e[26~" [f14]) -(define-key function-key-map "\e[28~" [help]) -(define-key function-key-map "\e[29~" [menu]) -(define-key function-key-map "\e[31~" [f17]) -(define-key function-key-map "\e[32~" [f18]) -(define-key function-key-map "\e[33~" [f19]) -(define-key function-key-map "\e[34~" [f20]) +;; Protect against reloads. +(unless lk201-function-map + (setq lk201-function-map (make-sparse-keymap)) -;; Termcap or terminfo should set these. -;; (define-key function-key-map "\eOA" [up]) -;; (define-key function-key-map "\eOB" [down]) -;; (define-key function-key-map "\eOC" [right]) -;; (define-key function-key-map "\eOD" [left]) + ;; XXX We need to find a way to have these define-keys be display-local. -- Lorentey -;; Termcap or terminfo should set these, but doesn't properly. -;; Termcap sets these to k1-k4, which get mapped to f1-f4 in term.c -(define-key function-key-map "\eOP" [kp-f1]) -(define-key function-key-map "\eOQ" [kp-f2]) -(define-key function-key-map "\eOR" [kp-f3]) -(define-key function-key-map "\eOS" [kp-f4]) + ;; Termcap or terminfo should set these. + ;; (define-key function-key-map "\e[A" [up]) + ;; (define-key function-key-map "\e[B" [down]) + ;; (define-key function-key-map "\e[C" [right]) + ;; (define-key function-key-map "\e[D" [left]) -(define-key function-key-map "\eOI" [kp-tab]) -(define-key function-key-map "\eOj" [kp-multiply]) -(define-key function-key-map "\eOk" [kp-add]) -(define-key function-key-map "\eOl" [kp-separator]) -(define-key function-key-map "\eOM" [kp-enter]) -(define-key function-key-map "\eOm" [kp-subtract]) -(define-key function-key-map "\eOn" [kp-decimal]) -(define-key function-key-map "\eOo" [kp-divide]) -(define-key function-key-map "\eOp" [kp-0]) -(define-key function-key-map "\eOq" [kp-1]) -(define-key function-key-map "\eOr" [kp-2]) -(define-key function-key-map "\eOs" [kp-3]) -(define-key function-key-map "\eOt" [kp-4]) -(define-key function-key-map "\eOu" [kp-5]) -(define-key function-key-map "\eOv" [kp-6]) -(define-key function-key-map "\eOw" [kp-7]) -(define-key function-key-map "\eOx" [kp-8]) -(define-key function-key-map "\eOy" [kp-9]) + (define-key function-key-map "\e[1~" [find]) + (define-key function-key-map "\e[2~" [insert]) + (define-key function-key-map "\e[3~" [delete]) + (define-key function-key-map "\e[4~" [select]) + (define-key function-key-map "\e[5~" [prior]) + (define-key function-key-map "\e[6~" [next]) + (define-key function-key-map "\e[11~" [f1]) + (define-key function-key-map "\e[12~" [f2]) + (define-key function-key-map "\e[13~" [f3]) + (define-key function-key-map "\e[14~" [f4]) + (define-key function-key-map "\e[15~" [f5]) + (define-key function-key-map "\e[17~" [f6]) + (define-key function-key-map "\e[18~" [f7]) + (define-key function-key-map "\e[19~" [f8]) + (define-key function-key-map "\e[20~" [f9]) + (define-key function-key-map "\e[21~" [f10]) + ;; Customarily F11 is used as the ESC key. + ;; The file that includes this one, takes care of that. + (define-key function-key-map "\e[23~" [f11]) + (define-key function-key-map "\e[24~" [f12]) + (define-key function-key-map "\e[25~" [f13]) + (define-key function-key-map "\e[26~" [f14]) + (define-key function-key-map "\e[28~" [help]) + (define-key function-key-map "\e[29~" [menu]) + (define-key function-key-map "\e[31~" [f17]) + (define-key function-key-map "\e[32~" [f18]) + (define-key function-key-map "\e[33~" [f19]) + (define-key function-key-map "\e[34~" [f20]) + + ;; Termcap or terminfo should set these. + ;; (define-key function-key-map "\eOA" [up]) + ;; (define-key function-key-map "\eOB" [down]) + ;; (define-key function-key-map "\eOC" [right]) + ;; (define-key function-key-map "\eOD" [left]) + + ;; Termcap or terminfo should set these, but doesn't properly. + ;; Termcap sets these to k1-k4, which get mapped to f1-f4 in term.c + (define-key function-key-map "\eOP" [kp-f1]) + (define-key function-key-map "\eOQ" [kp-f2]) + (define-key function-key-map "\eOR" [kp-f3]) + (define-key function-key-map "\eOS" [kp-f4]) + + (define-key function-key-map "\eOI" [kp-tab]) + (define-key function-key-map "\eOj" [kp-multiply]) + (define-key function-key-map "\eOk" [kp-add]) + (define-key function-key-map "\eOl" [kp-separator]) + (define-key function-key-map "\eOM" [kp-enter]) + (define-key function-key-map "\eOm" [kp-subtract]) + (define-key function-key-map "\eOn" [kp-decimal]) + (define-key function-key-map "\eOo" [kp-divide]) + (define-key function-key-map "\eOp" [kp-0]) + (define-key function-key-map "\eOq" [kp-1]) + (define-key function-key-map "\eOr" [kp-2]) + (define-key function-key-map "\eOs" [kp-3]) + (define-key function-key-map "\eOt" [kp-4]) + (define-key function-key-map "\eOu" [kp-5]) + (define-key function-key-map "\eOv" [kp-6]) + (define-key function-key-map "\eOw" [kp-7]) + (define-key function-key-map "\eOx" [kp-8]) + (define-key function-key-map "\eOy" [kp-9]) + + ;; Use inheritance to let the main keymap override these defaults. + ;; This way we don't override terminfo-derived settings or settings + ;; made in the .emacs file. + (set-keymap-parent lk201-function-map (keymap-parent function-key-map)) + (set-keymap-parent function-key-map lk201-function-map)) ;;; arch-tag: 7ffb4444-6a23-43e1-b457-43cf4f673c0d ;;; lk201.el ends here diff --git a/lisp/term/news.el b/lisp/term/news.el index a6f7481c422..1b251dae58e 100644 --- a/lisp/term/news.el +++ b/lisp/term/news.el @@ -35,6 +35,8 @@ (if (not (keymapp news-fkey-prefix)) (error "What? Your news termcap/terminfo has no keycaps in it")) + ;; XXX We need to find a way to have these define-keys be display-local. -- Lorentey + ;; Termcap or terminfo will set these ;; (define-key news-fkey-prefix "P" [f1]) ;; (define-key news-fkey-prefix "Q" [f2]) diff --git a/lisp/term/rxvt.el b/lisp/term/rxvt.el index 7839ebba95d..180e0b40946 100644 --- a/lisp/term/rxvt.el +++ b/lisp/term/rxvt.el @@ -26,73 +26,83 @@ ;;; Code: -;; Set up function-key-map entries that termcap and terminfo don't know. -(let ((map (make-sparse-keymap))) - (define-key map "\e[A" [up]) - (define-key map "\e[B" [down]) - (define-key map "\e[C" [right]) - (define-key map "\e[D" [left]) - (define-key map "\e[7~" [home]) - (define-key map "\e[2~" [insert]) - (define-key map "\e[3~" [delete]) - (define-key map "\e[4~" [select]) - (define-key map "\e[5~" [prior]) - (define-key map "\e[6~" [next]) - (define-key map "\e[11~" [f1]) - (define-key map "\e[12~" [f2]) - (define-key map "\e[13~" [f3]) - (define-key map "\e[14~" [f4]) - (define-key map "\e[15~" [f5]) - (define-key map "\e[17~" [f6]) - (define-key map "\e[18~" [f7]) - (define-key map "\e[19~" [f8]) - (define-key map "\e[20~" [f9]) - (define-key map "\e[21~" [f10]) - (define-key map "\e[23~" [f11]) - (define-key map "\e[24~" [f12]) - (define-key map "\e[29~" [print]) - - (define-key map "\e[11^" [C-f1]) - (define-key map "\e[12^" [C-f2]) - (define-key map "\e[13^" [C-f3]) - (define-key map "\e[14^" [C-f4]) - (define-key map "\e[15^" [C-f5]) - (define-key map "\e[17^" [C-f6]) - (define-key map "\e[18^" [C-f7]) - (define-key map "\e[19^" [C-f8]) - (define-key map "\e[20^" [C-f9]) - (define-key map "\e[21^" [C-f10]) - (define-key map "\e[23^" [C-f11]) - (define-key map "\e[24^" [C-f12]) - - (define-key map "\e[29~" [print]) - - (define-key map "\e[2;2~" [S-insert]) - (define-key map "\e[3$" [S-delete]) - - (define-key map "\e[2^" [C-insert]) - (define-key map "\e[3^" [C-delete]) - (define-key map "\e[5^" [C-prior]) - (define-key map "\e[6^" [C-next]) - (define-key map "\eOd" [C-left]) - (define-key map "\eOc" [C-right]) - (define-key map "\eOa" [C-up]) - (define-key map "\eOb" [C-down]) - - (define-key map "\e[5$" [S-prior]) - (define-key map "\e[6$" [S-next]) - (define-key map "\e[8$" [S-end]) - (define-key map "\e[7$" [S-home]) - (define-key map "\e[d" [S-left]) - (define-key map "\e[c" [S-right]) - (define-key map "\e[a" [S-up]) - (define-key map "\e[b" [S-down]) +(require 'server) + +(defvar rxvt-function-map nil + "Function key overrides for rxvt.") + +;; Protect against reloads. +(unless rxvt-function-map + (setq rxvt-function-map (make-sparse-keymap)) + + ;; Set up function-key-map entries that termcap and terminfo don't know. + ;; XXX We need to find a way to have these define-keys be display-local. -- Lorentey + (define-key rxvt-function-map "\e[A" [up]) + (define-key rxvt-function-map "\e[B" [down]) + (define-key rxvt-function-map "\e[C" [right]) + (define-key rxvt-function-map "\e[D" [left]) + (define-key rxvt-function-map "\e[7~" [home]) + (define-key rxvt-function-map "\e[2~" [insert]) + (define-key rxvt-function-map "\e[3~" [delete]) + (define-key rxvt-function-map "\e[4~" [select]) + (define-key rxvt-function-map "\e[5~" [prior]) + (define-key rxvt-function-map "\e[6~" [next]) + (define-key rxvt-function-map "\e[11~" [f1]) + (define-key rxvt-function-map "\e[12~" [f2]) + (define-key rxvt-function-map "\e[13~" [f3]) + (define-key rxvt-function-map "\e[14~" [f4]) + (define-key rxvt-function-map "\e[15~" [f5]) + (define-key rxvt-function-map "\e[17~" [f6]) + (define-key rxvt-function-map "\e[18~" [f7]) + (define-key rxvt-function-map "\e[19~" [f8]) + (define-key rxvt-function-map "\e[20~" [f9]) + (define-key rxvt-function-map "\e[21~" [f10]) + (define-key rxvt-function-map "\e[23~" [f11]) + (define-key rxvt-function-map "\e[24~" [f12]) + (define-key rxvt-function-map "\e[29~" [print]) + + (define-key rxvt-function-map "\e[11^" [C-f1]) + (define-key rxvt-function-map "\e[12^" [C-f2]) + (define-key rxvt-function-map "\e[13^" [C-f3]) + (define-key rxvt-function-map "\e[14^" [C-f4]) + (define-key rxvt-function-map "\e[15^" [C-f5]) + (define-key rxvt-function-map "\e[17^" [C-f6]) + (define-key rxvt-function-map "\e[18^" [C-f7]) + (define-key rxvt-function-map "\e[19^" [C-f8]) + (define-key rxvt-function-map "\e[20^" [C-f9]) + (define-key rxvt-function-map "\e[21^" [C-f10]) + (define-key rxvt-function-map "\e[23^" [C-f11]) + (define-key rxvt-function-map "\e[24^" [C-f12]) + + (define-key rxvt-function-map "\e[29~" [print]) + + (define-key rxvt-function-map "\e[2;2~" [S-insert]) + (define-key rxvt-function-map "\e[3$" [S-delete]) + + (define-key rxvt-function-map "\e[2^" [C-insert]) + (define-key rxvt-function-map "\e[3^" [C-delete]) + (define-key rxvt-function-map "\e[5^" [C-prior]) + (define-key rxvt-function-map "\e[6^" [C-next]) + (define-key rxvt-function-map "\eOd" [C-left]) + (define-key rxvt-function-map "\eOc" [C-right]) + (define-key rxvt-function-map "\eOa" [C-up]) + (define-key rxvt-function-map "\eOb" [C-down]) + + (define-key rxvt-function-map "\e[5$" [S-prior]) + (define-key rxvt-function-map "\e[6$" [S-next]) + (define-key rxvt-function-map "\e[8$" [S-end]) + (define-key rxvt-function-map "\e[7$" [S-home]) + (define-key rxvt-function-map "\e[d" [S-left]) + (define-key rxvt-function-map "\e[c" [S-right]) + (define-key rxvt-function-map "\e[a" [S-up]) + (define-key rxvt-function-map "\e[b" [S-down]) ;; Use inheritance to let the main keymap override those defaults. ;; This way we don't override terminfo-derived settings or settings ;; made in the .emacs file. - (set-keymap-parent map (keymap-parent function-key-map)) - (set-keymap-parent function-key-map map)) + (set-keymap-parent rxvt-function-map (keymap-parent function-key-map)) + (set-keymap-parent function-key-map rxvt-function-map)) + ;; Set up colors, for those versions of rxvt that support it. (defvar rxvt-standard-colors @@ -148,7 +158,7 @@ for the currently selected frame." ;; intelligent way than the default guesswork in startup.el. (defun rxvt-set-background-mode () "Set background mode as appropriate for the default rxvt colors." - (let ((fgbg (getenv "COLORFGBG")) + (let ((fgbg (server-getenv "COLORFGBG")) bg rgb) (setq frame-background-mode 'light) ; default (when (and fgbg diff --git a/lisp/term/sun.el b/lisp/term/sun.el index 238bb2f7212..667762e0aa7 100644 --- a/lisp/term/sun.el +++ b/lisp/term/sun.el @@ -92,6 +92,8 @@ ;; so we ignore them on the way down ;; +;; XXX We need to find a way to have these define-keys be display-local. -- Lorentey + (defvar sun-raw-prefix (make-sparse-keymap)) (define-key function-key-map "\e[" sun-raw-prefix) diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index 5b4ff6d2f7c..5d2cb1afad2 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -24,10 +24,16 @@ ;;; Commentary: -;; X-win.el: this file is loaded from ../lisp/startup.el when it recognizes -;; that X windows are to be used. Command line switches are parsed and those -;; pertaining to X are processed and removed from the command line. The -;; X display is opened and hooks are set for popping up the initial window. +;; X-win.el: this file defines functions to initialize the X window +;; system and process X-specific command line parameters before +;; creating the first X frame. + +;; Note that contrary to previous Emacs versions, the act of loading +;; this file should not have the side effect of initializing the +;; window system or processing command line arguments (this file is +;; now loaded in loadup.el). See the variables +;; `handle-args-function-alist' and +;; `window-system-initialization-alist' for more details. ;; startup.el will then examine startup files, and eventually call the hooks ;; which create the first window(s). @@ -66,7 +72,7 @@ ;; An alist of X options and the function which handles them. See ;; ../startup.el. -(if (not (eq window-system 'x)) +(if (not (fboundp 'x-create-frame)) (error "%s: Loading x-win.el but not compiled for X" (invocation-name))) (require 'frame) @@ -77,6 +83,7 @@ (require 'menu-bar) (require 'fontset) (require 'x-dnd) +(require 'server) (defvar x-invocation-args) @@ -1160,9 +1167,6 @@ XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp") ;;;; Function keys -(substitute-key-definition 'suspend-emacs 'iconify-or-deiconify-frame - global-map) - ;; Map certain keypad keys into ASCII characters ;; that people usually expect. (define-key function-key-map [backspace] [127]) @@ -2334,149 +2338,152 @@ order until succeed.") (or clip-text primary-text cut-text) )) - -;;; Do the actual X Windows setup here; the above code just defines -;;; functions and variables that we use now. - -(setq command-line-args (x-handle-args command-line-args)) - -;;; Make sure we have a valid resource name. -(or (stringp x-resource-name) - (let (i) - (setq x-resource-name (invocation-name)) - - ;; Change any . or * characters in x-resource-name to hyphens, - ;; so as not to choke when we use it in X resource queries. - (while (setq i (string-match "[.*]" x-resource-name)) - (aset x-resource-name i ?-)))) - -(x-open-connection (or x-display-name - (setq x-display-name (getenv "DISPLAY"))) - x-command-line-resources - ;; Exit Emacs with fatal error if this fails. - t) - -(setq frame-creation-function 'x-create-frame-with-faces) - -(setq x-cut-buffer-max (min (- (/ (x-server-max-request-size) 2) 100) - x-cut-buffer-max)) - -;; Setup the default fontset. -(setup-default-fontset) - -;; Create the standard fontset. -(create-fontset-from-fontset-spec standard-fontset-spec t) - -;; Create fontset specified in X resources "Fontset-N" (N is 0, 1, ...). -(create-fontset-from-x-resource) - -;; Try to create a fontset from a font specification which comes -;; from initial-frame-alist, default-frame-alist, or X resource. -;; A font specification in command line argument (i.e. -fn XXXX) -;; should be already in default-frame-alist as a `font' -;; parameter. However, any font specifications in site-start -;; library, user's init file (.emacs), and default.el are not -;; yet handled here. - -(let ((font (or (cdr (assq 'font initial-frame-alist)) - (cdr (assq 'font default-frame-alist)) - (x-get-resource "font" "Font"))) - xlfd-fields resolved-name) - (if (and font - (not (query-fontset font)) - (setq resolved-name (x-resolve-font-name font)) - (setq xlfd-fields (x-decompose-font-name font))) - (if (string= "fontset" (aref xlfd-fields xlfd-regexp-registry-subnum)) - (new-fontset font (x-complement-fontset-spec xlfd-fields nil)) - ;; Create a fontset from FONT. The fontset name is - ;; generated from FONT. - (create-fontset-from-ascii-font font resolved-name "startup")))) - -;; Apply a geometry resource to the initial frame. Put it at the end -;; of the alist, so that anything specified on the command line takes -;; precedence. -(let* ((res-geometry (x-get-resource "geometry" "Geometry")) - parsed) - (if res-geometry - (progn - (setq parsed (x-parse-geometry res-geometry)) - ;; If the resource specifies a position, - ;; call the position and size "user-specified". - (if (or (assq 'top parsed) (assq 'left parsed)) - (setq parsed (cons '(user-position . t) - (cons '(user-size . t) parsed)))) - ;; All geometry parms apply to the initial frame. - (setq initial-frame-alist (append initial-frame-alist parsed)) - ;; The size parms apply to all frames. - (if (assq 'height parsed) - (setq default-frame-alist - (cons (cons 'height (cdr (assq 'height parsed))) - default-frame-alist))) - (if (assq 'width parsed) - (setq default-frame-alist - (cons (cons 'width (cdr (assq 'width parsed))) - default-frame-alist)))))) - -;; Check the reverseVideo resource. -(let ((case-fold-search t)) - (let ((rv (x-get-resource "reverseVideo" "ReverseVideo"))) - (if (and rv - (string-match "^\\(true\\|yes\\|on\\)$" rv)) - (setq default-frame-alist - (cons '(reverse . t) default-frame-alist))))) +(defun x-clipboard-yank () + "Insert the clipboard contents, or the last stretch of killed text." + (interactive) + (let ((clipboard-text + (condition-case nil + (x-get-selection 'CLIPBOARD) + (error nil))) + (x-select-enable-clipboard t)) + (if (and clipboard-text (> (length clipboard-text) 0)) + (kill-new clipboard-text)) + (yank))) -;; Set x-selection-timeout, measured in milliseconds. -(let ((res-selection-timeout - (x-get-resource "selectionTimeout" "SelectionTimeout"))) - (setq x-selection-timeout 20000) - (if res-selection-timeout - (setq x-selection-timeout (string-to-number res-selection-timeout)))) + +;;; Window system initialization. (defun x-win-suspend-error () (error "Suspending an Emacs running under X makes no sense")) -(add-hook 'suspend-hook 'x-win-suspend-error) -;;; Arrange for the kill and yank functions to set and check the clipboard. -(setq interprogram-cut-function 'x-select-text) -(setq interprogram-paste-function 'x-cut-buffer-or-selection-value) +(defvar x-initialized nil + "Non-nil if the X window system has been initialized.") + +(defun x-initialize-window-system () + "Initialize Emacs for X frames and open the first connection to an X server." + ;; Make sure we have a valid resource name. + (or (stringp x-resource-name) + (let (i) + (setq x-resource-name (invocation-name)) + + ;; Change any . or * characters in x-resource-name to hyphens, + ;; so as not to choke when we use it in X resource queries. + (while (setq i (string-match "[.*]" x-resource-name)) + (aset x-resource-name i ?-)))) + + (x-open-connection (or x-display-name + (setq x-display-name (server-getenv "DISPLAY"))) + x-command-line-resources + ;; Exit Emacs with fatal error if this fails and we + ;; are the initial display. + (eq initial-window-system 'x)) + + (setq x-cut-buffer-max (min (- (/ (x-server-max-request-size) 2) 100) + x-cut-buffer-max)) + + ;; Setup the default fontset. + (setup-default-fontset) + + ;; Create the standard fontset. + (create-fontset-from-fontset-spec standard-fontset-spec t) + + ;; Create fontset specified in X resources "Fontset-N" (N is 0, 1, ...). + (create-fontset-from-x-resource) + + ;; Try to create a fontset from a font specification which comes + ;; from initial-frame-alist, default-frame-alist, or X resource. + ;; A font specification in command line argument (i.e. -fn XXXX) + ;; should be already in default-frame-alist as a `font' + ;; parameter. However, any font specifications in site-start + ;; library, user's init file (.emacs), and default.el are not + ;; yet handled here. + + (let ((font (or (cdr (assq 'font initial-frame-alist)) + (cdr (assq 'font default-frame-alist)) + (x-get-resource "font" "Font"))) + xlfd-fields resolved-name) + (if (and font + (not (query-fontset font)) + (setq resolved-name (x-resolve-font-name font)) + (setq xlfd-fields (x-decompose-font-name font))) + (if (string= "fontset" (aref xlfd-fields xlfd-regexp-registry-subnum)) + (new-fontset font (x-complement-fontset-spec xlfd-fields nil)) + ;; Create a fontset from FONT. The fontset name is + ;; generated from FONT. + (create-fontset-from-ascii-font font resolved-name "startup")))) + + ;; Apply a geometry resource to the initial frame. Put it at the end + ;; of the alist, so that anything specified on the command line takes + ;; precedence. + (let* ((res-geometry (x-get-resource "geometry" "Geometry")) + parsed) + (if res-geometry + (progn + (setq parsed (x-parse-geometry res-geometry)) + ;; If the resource specifies a position, + ;; call the position and size "user-specified". + (if (or (assq 'top parsed) (assq 'left parsed)) + (setq parsed (cons '(user-position . t) + (cons '(user-size . t) parsed)))) + ;; All geometry parms apply to the initial frame. + (setq initial-frame-alist (append initial-frame-alist parsed)) + ;; The size parms apply to all frames. + (if (assq 'height parsed) + (setq default-frame-alist + (cons (cons 'height (cdr (assq 'height parsed))) + default-frame-alist))) + (if (assq 'width parsed) + (setq default-frame-alist + (cons (cons 'width (cdr (assq 'width parsed))) + default-frame-alist)))))) + + ;; Check the reverseVideo resource. + (let ((case-fold-search t)) + (let ((rv (x-get-resource "reverseVideo" "ReverseVideo"))) + (if (and rv + (string-match "^\\(true\\|yes\\|on\\)$" rv)) + (setq default-frame-alist + (cons '(reverse . t) default-frame-alist))))) -;;; Turn off window-splitting optimization; X is usually fast enough -;;; that this is only annoying. -(setq split-window-keep-point t) + ;; Set x-selection-timeout, measured in milliseconds. + (let ((res-selection-timeout + (x-get-resource "selectionTimeout" "SelectionTimeout"))) + (setq x-selection-timeout 20000) + (if res-selection-timeout + (setq x-selection-timeout (string-to-number res-selection-timeout)))) -;; Don't show the frame name; that's redundant with X. -(setq-default mode-line-frame-identification " ") + ;; Don't let Emacs suspend under X. + (add-hook 'suspend-hook 'x-win-suspend-error) -;; Motif direct handling of f10 wasn't working right, -;; So temporarily we've turned it off in lwlib-Xm.c -;; and turned the Emacs f10 back on. -;; ;; Motif normally handles f10 itself, so don't try to handle it a second time. -;; (if (featurep 'motif) -;; (global-set-key [f10] 'ignore)) + ;; Turn off window-splitting optimization; X is usually fast enough + ;; that this is only annoying. + (setq split-window-keep-point t) -;; Turn on support for mouse wheels. -(mouse-wheel-mode 1) + ;; Motif direct handling of f10 wasn't working right, + ;; So temporarily we've turned it off in lwlib-Xm.c + ;; and turned the Emacs f10 back on. + ;; ;; Motif normally handles f10 itself, so don't try to handle it a second time. + ;; (if (featurep 'motif) + ;; (global-set-key [f10] 'ignore)) + ;; Turn on support for mouse wheels. + (mouse-wheel-mode 1) -;; Enable CLIPBOARD copy/paste through menu bar commands. -(menu-bar-enable-clipboard) + ;; Enable CLIPBOARD copy/paste through menu bar commands. + (menu-bar-enable-clipboard) -;; Override Paste so it looks at CLIPBOARD first. -(defun x-clipboard-yank () - "Insert the clipboard contents, or the last stretch of killed text." - (interactive) - (let ((clipboard-text - (condition-case nil - (x-get-selection 'CLIPBOARD) - (error nil))) - (x-select-enable-clipboard t)) - (if (and clipboard-text (> (length clipboard-text) 0)) - (kill-new clipboard-text)) - (yank))) + ;; Override Paste so it looks at CLIPBOARD first. + (define-key menu-bar-edit-menu [paste] + (cons "Paste" (cons "Paste text from clipboard or kill ring" + 'x-clipboard-yank))) + + (setq x-initialized t)) + +(add-to-list 'handle-args-function-alist '(x . x-handle-args)) +(add-to-list 'frame-creation-function-alist '(x . x-create-frame-with-faces)) +(add-to-list 'window-system-initialization-alist '(x . x-initialize-window-system)) -(define-key menu-bar-edit-menu [paste] - (cons "Paste" (cons "Paste text from clipboard or kill ring" - 'x-clipboard-yank))) +(provide 'x-win) ;; Initiate drag and drop (add-hook 'after-make-frame-functions 'x-dnd-init-frame) diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index b55f18f6883..f4cdd26a438 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el @@ -26,222 +26,232 @@ ;;; Code: -;;; The terminal intialization C code file might have initialized -;;; function keys F13->F60 from the termcap/terminfo information. On -;;; a PC-style keyboard these keys correspond to -;;; MODIFIER-FUNCTION_KEY, where modifier is S-, C, A-, C-S-. The -;;; code here subsitutes the corresponding defintions in -;;; function-key-map. This substitution is needed because if a key -;;; definition if found in function-key-map, there are no further -;;; lookups in other keymaps. -(substitute-key-definition [f13] [S-f1] function-key-map) -(substitute-key-definition [f14] [S-f2] function-key-map) -(substitute-key-definition [f15] [S-f3] function-key-map) -(substitute-key-definition [f16] [S-f4] function-key-map) -(substitute-key-definition [f17] [S-f5] function-key-map) -(substitute-key-definition [f18] [S-f6] function-key-map) -(substitute-key-definition [f19] [S-f7] function-key-map) -(substitute-key-definition [f20] [S-f8] function-key-map) -(substitute-key-definition [f21] [S-f9] function-key-map) -(substitute-key-definition [f22] [S-f10] function-key-map) -(substitute-key-definition [f23] [S-f11] function-key-map) -(substitute-key-definition [f24] [S-f12] function-key-map) - -(substitute-key-definition [f25] [C-f1] function-key-map) -(substitute-key-definition [f26] [C-f2] function-key-map) -(substitute-key-definition [f27] [C-f3] function-key-map) -(substitute-key-definition [f28] [C-f4] function-key-map) -(substitute-key-definition [f29] [C-f5] function-key-map) -(substitute-key-definition [f30] [C-f6] function-key-map) -(substitute-key-definition [f31] [C-f7] function-key-map) -(substitute-key-definition [f32] [C-f8] function-key-map) -(substitute-key-definition [f33] [C-f9] function-key-map) -(substitute-key-definition [f34] [C-f10] function-key-map) -(substitute-key-definition [f35] [C-f11] function-key-map) -(substitute-key-definition [f36] [C-f12] function-key-map) - -(substitute-key-definition [f37] [C-S-f1] function-key-map) -(substitute-key-definition [f38] [C-S-f2] function-key-map) -(substitute-key-definition [f39] [C-S-f3] function-key-map) -(substitute-key-definition [f40] [C-S-f4] function-key-map) -(substitute-key-definition [f41] [C-S-f5] function-key-map) -(substitute-key-definition [f42] [C-S-f6] function-key-map) -(substitute-key-definition [f43] [C-S-f7] function-key-map) -(substitute-key-definition [f44] [C-S-f8] function-key-map) -(substitute-key-definition [f45] [C-S-f9] function-key-map) -(substitute-key-definition [f46] [C-S-f10] function-key-map) -(substitute-key-definition [f47] [C-S-f11] function-key-map) -(substitute-key-definition [f48] [C-S-f12] function-key-map) - -(substitute-key-definition [f49] [A-f1] function-key-map) -(substitute-key-definition [f50] [A-f2] function-key-map) -(substitute-key-definition [f51] [A-f3] function-key-map) -(substitute-key-definition [f52] [A-f4] function-key-map) -(substitute-key-definition [f53] [A-f5] function-key-map) -(substitute-key-definition [f54] [A-f6] function-key-map) -(substitute-key-definition [f55] [A-f7] function-key-map) -(substitute-key-definition [f56] [A-f8] function-key-map) -(substitute-key-definition [f57] [A-f9] function-key-map) -(substitute-key-definition [f58] [A-f10] function-key-map) -(substitute-key-definition [f59] [A-f11] function-key-map) -(substitute-key-definition [f60] [A-f12] function-key-map) - -(let ((map (make-sparse-keymap))) - (define-key map "\e[A" [up]) - (define-key map "\e[B" [down]) - (define-key map "\e[C" [right]) - (define-key map "\e[D" [left]) - (define-key map "\e[1~" [home]) - (define-key map "\e[2~" [insert]) - (define-key map "\e[3~" [delete]) - (define-key map "\e[4~" [select]) - (define-key map "\e[5~" [prior]) - (define-key map "\e[6~" [next]) - (define-key map "\e[11~" [f1]) - (define-key map "\e[12~" [f2]) - (define-key map "\e[13~" [f3]) - (define-key map "\e[14~" [f4]) - (define-key map "\e[15~" [f5]) - (define-key map "\e[17~" [f6]) - (define-key map "\e[18~" [f7]) - (define-key map "\e[19~" [f8]) - (define-key map "\e[20~" [f9]) - (define-key map "\e[21~" [f10]) - (define-key map "\e[23~" [f11]) - (define-key map "\e[24~" [f12]) - (define-key map "\e[29~" [print]) - - (define-key map "\eOP" [f1]) - (define-key map "\eOQ" [f2]) - (define-key map "\eOR" [f3]) - (define-key map "\eOS" [f4]) - - (define-key map "\eO2P" [S-f1]) - (define-key map "\eO2Q" [S-f2]) - (define-key map "\eO2R" [S-f3]) - (define-key map "\eO2S" [S-f4]) - (define-key map "\e[15;2~" [S-f5]) - (define-key map "\e[17;2~" [S-f6]) - (define-key map "\e[18;2~" [S-f7]) - (define-key map "\e[19;2~" [S-f8]) - (define-key map "\e[20;2~" [S-f9]) - (define-key map "\e[21;2~" [S-f10]) - (define-key map "\e[23;2~" [S-f11]) - (define-key map "\e[24;2~" [S-f12]) - - (define-key map "\eO5P" [C-f1]) - (define-key map "\eO5Q" [C-f2]) - (define-key map "\eO5R" [C-f3]) - (define-key map "\eO5S" [C-f4]) - (define-key map "\e[15;5~" [C-f5]) - (define-key map "\e[17;5~" [C-f6]) - (define-key map "\e[18;5~" [C-f7]) - (define-key map "\e[19;5~" [C-f8]) - (define-key map "\e[20;5~" [C-f9]) - (define-key map "\e[21;5~" [C-f10]) - (define-key map "\e[23;5~" [C-f11]) - (define-key map "\e[24;5~" [C-f12]) - - (define-key map "\eO6P" [C-S-f1]) - (define-key map "\eO6Q" [C-S-f2]) - (define-key map "\eO6R" [C-S-f3]) - (define-key map "\eO6S" [C-S-f4]) - (define-key map "\e[15;6~" [C-S-f5]) - (define-key map "\e[17;6~" [C-S-f6]) - (define-key map "\e[18;6~" [C-S-f7]) - (define-key map "\e[19;6~" [C-S-f8]) - (define-key map "\e[20;6~" [C-S-f9]) - (define-key map "\e[21;6~" [C-S-f10]) - (define-key map "\e[23;6~" [C-S-f11]) - (define-key map "\e[24;6~" [C-S-f12]) - - (define-key map "\eO3P" [A-f1]) - (define-key map "\eO3Q" [A-f2]) - (define-key map "\eO3R" [A-f3]) - (define-key map "\eO3S" [A-f4]) - (define-key map "\e[15;3~" [A-f5]) - (define-key map "\e[17;3~" [A-f6]) - (define-key map "\e[18;3~" [A-f7]) - (define-key map "\e[19;3~" [A-f8]) - (define-key map "\e[20;3~" [A-f9]) - (define-key map "\e[21;3~" [A-f10]) - (define-key map "\e[23;3~" [A-f11]) - (define-key map "\e[24;3~" [A-f12]) - - (define-key map "\e[1;2A" [S-up]) - (define-key map "\e[1;2B" [S-down]) - (define-key map "\e[1;2C" [S-right]) - (define-key map "\e[1;2D" [S-left]) - (define-key map "\e[1;2F" [S-end]) - (define-key map "\e[1;2H" [S-home]) - - (define-key map "\e[1;5A" [C-up]) - (define-key map "\e[1;5B" [C-down]) - (define-key map "\e[1;5C" [C-right]) - (define-key map "\e[1;5D" [C-left]) - (define-key map "\e[1;5F" [C-end]) - (define-key map "\e[1;5H" [C-home]) - - (define-key map "\e[1;6A" [C-S-up]) - (define-key map "\e[1;6B" [C-S-down]) - (define-key map "\e[1;6C" [C-S-right]) - (define-key map "\e[1;6D" [C-S-left]) - (define-key map "\e[1;6F" [C-S-end]) - (define-key map "\e[1;6H" [C-S-home]) - - (define-key map "\e[1;3A" [A-up]) - (define-key map "\e[1;3B" [A-down]) - (define-key map "\e[1;3C" [A-right]) - (define-key map "\e[1;3D" [A-left]) - (define-key map "\e[1;3F" [A-end]) - (define-key map "\e[1;3H" [A-home]) - - (define-key map "\e[2;2~" [S-insert]) - (define-key map "\e[3;2~" [S-delete]) - (define-key map "\e[5;2~" [S-prior]) - (define-key map "\e[6;2~" [S-next]) - - (define-key map "\e[2;5~" [C-insert]) - (define-key map "\e[3;5~" [C-delete]) - (define-key map "\e[5;5~" [C-prior]) - (define-key map "\e[6;5~" [C-next]) - - (define-key map "\e[2;6~" [C-S-insert]) - (define-key map "\e[3;6~" [C-S-delete]) - (define-key map "\e[5;6~" [C-S-prior]) - (define-key map "\e[6;6~" [C-S-next]) - - (define-key map "\e[2;3~" [A-insert]) - (define-key map "\e[3;3~" [A-delete]) - (define-key map "\e[5;3~" [A-prior]) - (define-key map "\e[6;3~" [A-next]) - - (define-key map "\eOA" [up]) - (define-key map "\eOB" [down]) - (define-key map "\eOC" [right]) - (define-key map "\eOD" [left]) - (define-key map "\eOF" [end]) - (define-key map "\eOH" [home]) - - (define-key map "\eO2A" [S-up]) - (define-key map "\eO2B" [S-down]) - (define-key map "\eO2C" [S-right]) - (define-key map "\eO2D" [S-left]) - (define-key map "\eO2F" [S-end]) - (define-key map "\eO2H" [S-home]) - - (define-key map "\eO5A" [C-up]) - (define-key map "\eO5B" [C-down]) - (define-key map "\eO5C" [C-right]) - (define-key map "\eO5D" [C-left]) - (define-key map "\eO5F" [C-end]) - (define-key map "\eO5H" [C-home]) +(require 'server) + +(defvar xterm-function-map nil + "Function key map overrides for xterm.") + +;; Protect against reloads. +(unless xterm-function-map + (setq xterm-function-map (make-sparse-keymap)) + + ;; XXX We need to find a way to make these definitions display-local. -- Lorentey + + ;; The terminal intialization C code file might have initialized + ;; function keys F13->F60 from the termcap/terminfo information. On + ;; a PC-style keyboard these keys correspond to + ;; MODIFIER-FUNCTION_KEY, where modifier is S-, C, A-, C-S-. The + ;; code here subsitutes the corresponding defintions in + ;; function-key-map. This substitution is needed because if a key + ;; definition if found in function-key-map, there are no further + ;; lookups in other keymaps. + (substitute-key-definition [f13] [S-f1] function-key-map) + (substitute-key-definition [f14] [S-f2] function-key-map) + (substitute-key-definition [f15] [S-f3] function-key-map) + (substitute-key-definition [f16] [S-f4] function-key-map) + (substitute-key-definition [f17] [S-f5] function-key-map) + (substitute-key-definition [f18] [S-f6] function-key-map) + (substitute-key-definition [f19] [S-f7] function-key-map) + (substitute-key-definition [f20] [S-f8] function-key-map) + (substitute-key-definition [f21] [S-f9] function-key-map) + (substitute-key-definition [f22] [S-f10] function-key-map) + (substitute-key-definition [f23] [S-f11] function-key-map) + (substitute-key-definition [f24] [S-f12] function-key-map) + + (substitute-key-definition [f25] [C-f1] function-key-map) + (substitute-key-definition [f26] [C-f2] function-key-map) + (substitute-key-definition [f27] [C-f3] function-key-map) + (substitute-key-definition [f28] [C-f4] function-key-map) + (substitute-key-definition [f29] [C-f5] function-key-map) + (substitute-key-definition [f30] [C-f6] function-key-map) + (substitute-key-definition [f31] [C-f7] function-key-map) + (substitute-key-definition [f32] [C-f8] function-key-map) + (substitute-key-definition [f33] [C-f9] function-key-map) + (substitute-key-definition [f34] [C-f10] function-key-map) + (substitute-key-definition [f35] [C-f11] function-key-map) + (substitute-key-definition [f36] [C-f12] function-key-map) + + (substitute-key-definition [f37] [C-S-f1] function-key-map) + (substitute-key-definition [f38] [C-S-f2] function-key-map) + (substitute-key-definition [f39] [C-S-f3] function-key-map) + (substitute-key-definition [f40] [C-S-f4] function-key-map) + (substitute-key-definition [f41] [C-S-f5] function-key-map) + (substitute-key-definition [f42] [C-S-f6] function-key-map) + (substitute-key-definition [f43] [C-S-f7] function-key-map) + (substitute-key-definition [f44] [C-S-f8] function-key-map) + (substitute-key-definition [f45] [C-S-f9] function-key-map) + (substitute-key-definition [f46] [C-S-f10] function-key-map) + (substitute-key-definition [f47] [C-S-f11] function-key-map) + (substitute-key-definition [f48] [C-S-f12] function-key-map) + + (substitute-key-definition [f49] [A-f1] function-key-map) + (substitute-key-definition [f50] [A-f2] function-key-map) + (substitute-key-definition [f51] [A-f3] function-key-map) + (substitute-key-definition [f52] [A-f4] function-key-map) + (substitute-key-definition [f53] [A-f5] function-key-map) + (substitute-key-definition [f54] [A-f6] function-key-map) + (substitute-key-definition [f55] [A-f7] function-key-map) + (substitute-key-definition [f56] [A-f8] function-key-map) + (substitute-key-definition [f57] [A-f9] function-key-map) + (substitute-key-definition [f58] [A-f10] function-key-map) + (substitute-key-definition [f59] [A-f11] function-key-map) + (substitute-key-definition [f60] [A-f12] function-key-map) + + (define-key xterm-function-map "\e[A" [up]) + (define-key xterm-function-map "\e[B" [down]) + (define-key xterm-function-map "\e[C" [right]) + (define-key xterm-function-map "\e[D" [left]) + (define-key xterm-function-map "\e[1~" [home]) + (define-key xterm-function-map "\e[2~" [insert]) + (define-key xterm-function-map "\e[3~" [delete]) + (define-key xterm-function-map "\e[4~" [select]) + (define-key xterm-function-map "\e[5~" [prior]) + (define-key xterm-function-map "\e[6~" [next]) + (define-key xterm-function-map "\e[11~" [f1]) + (define-key xterm-function-map "\e[12~" [f2]) + (define-key xterm-function-map "\e[13~" [f3]) + (define-key xterm-function-map "\e[14~" [f4]) + (define-key xterm-function-map "\e[15~" [f5]) + (define-key xterm-function-map "\e[17~" [f6]) + (define-key xterm-function-map "\e[18~" [f7]) + (define-key xterm-function-map "\e[19~" [f8]) + (define-key xterm-function-map "\e[20~" [f9]) + (define-key xterm-function-map "\e[21~" [f10]) + (define-key xterm-function-map "\e[23~" [f11]) + (define-key xterm-function-map "\e[24~" [f12]) + (define-key xterm-function-map "\e[29~" [print]) + + (define-key xterm-function-map "\eOP" [f1]) + (define-key xterm-function-map "\eOQ" [f2]) + (define-key xterm-function-map "\eOR" [f3]) + (define-key xterm-function-map "\eOS" [f4]) + + (define-key xterm-function-map "\eO2P" [S-f1]) + (define-key xterm-function-map "\eO2Q" [S-f2]) + (define-key xterm-function-map "\eO2R" [S-f3]) + (define-key xterm-function-map "\eO2S" [S-f4]) + (define-key xterm-function-map "\e[15;2~" [S-f5]) + (define-key xterm-function-map "\e[17;2~" [S-f6]) + (define-key xterm-function-map "\e[18;2~" [S-f7]) + (define-key xterm-function-map "\e[19;2~" [S-f8]) + (define-key xterm-function-map "\e[20;2~" [S-f9]) + (define-key xterm-function-map "\e[21;2~" [S-f10]) + (define-key xterm-function-map "\e[23;2~" [S-f11]) + (define-key xterm-function-map "\e[24;2~" [S-f12]) + + (define-key xterm-function-map "\eO5P" [C-f1]) + (define-key xterm-function-map "\eO5Q" [C-f2]) + (define-key xterm-function-map "\eO5R" [C-f3]) + (define-key xterm-function-map "\eO5S" [C-f4]) + (define-key xterm-function-map "\e[15;5~" [C-f5]) + (define-key xterm-function-map "\e[17;5~" [C-f6]) + (define-key xterm-function-map "\e[18;5~" [C-f7]) + (define-key xterm-function-map "\e[19;5~" [C-f8]) + (define-key xterm-function-map "\e[20;5~" [C-f9]) + (define-key xterm-function-map "\e[21;5~" [C-f10]) + (define-key xterm-function-map "\e[23;5~" [C-f11]) + (define-key xterm-function-map "\e[24;5~" [C-f12]) + + (define-key xterm-function-map "\eO6P" [C-S-f1]) + (define-key xterm-function-map "\eO6Q" [C-S-f2]) + (define-key xterm-function-map "\eO6R" [C-S-f3]) + (define-key xterm-function-map "\eO6S" [C-S-f4]) + (define-key xterm-function-map "\e[15;6~" [C-S-f5]) + (define-key xterm-function-map "\e[17;6~" [C-S-f6]) + (define-key xterm-function-map "\e[18;6~" [C-S-f7]) + (define-key xterm-function-map "\e[19;6~" [C-S-f8]) + (define-key xterm-function-map "\e[20;6~" [C-S-f9]) + (define-key xterm-function-map "\e[21;6~" [C-S-f10]) + (define-key xterm-function-map "\e[23;6~" [C-S-f11]) + (define-key xterm-function-map "\e[24;6~" [C-S-f12]) + + (define-key xterm-function-map "\eO3P" [A-f1]) + (define-key xterm-function-map "\eO3Q" [A-f2]) + (define-key xterm-function-map "\eO3R" [A-f3]) + (define-key xterm-function-map "\eO3S" [A-f4]) + (define-key xterm-function-map "\e[15;3~" [A-f5]) + (define-key xterm-function-map "\e[17;3~" [A-f6]) + (define-key xterm-function-map "\e[18;3~" [A-f7]) + (define-key xterm-function-map "\e[19;3~" [A-f8]) + (define-key xterm-function-map "\e[20;3~" [A-f9]) + (define-key xterm-function-map "\e[21;3~" [A-f10]) + (define-key xterm-function-map "\e[23;3~" [A-f11]) + (define-key xterm-function-map "\e[24;3~" [A-f12]) + + (define-key xterm-function-map "\e[1;2A" [S-up]) + (define-key xterm-function-map "\e[1;2B" [S-down]) + (define-key xterm-function-map "\e[1;2C" [S-right]) + (define-key xterm-function-map "\e[1;2D" [S-left]) + (define-key xterm-function-map "\e[1;2F" [S-end]) + (define-key xterm-function-map "\e[1;2H" [S-home]) + + (define-key xterm-function-map "\e[1;5A" [C-up]) + (define-key xterm-function-map "\e[1;5B" [C-down]) + (define-key xterm-function-map "\e[1;5C" [C-right]) + (define-key xterm-function-map "\e[1;5D" [C-left]) + (define-key xterm-function-map "\e[1;5F" [C-end]) + (define-key xterm-function-map "\e[1;5H" [C-home]) + + (define-key xterm-function-map "\e[1;6A" [C-S-up]) + (define-key xterm-function-map "\e[1;6B" [C-S-down]) + (define-key xterm-function-map "\e[1;6C" [C-S-right]) + (define-key xterm-function-map "\e[1;6D" [C-S-left]) + (define-key xterm-function-map "\e[1;6F" [C-S-end]) + (define-key xterm-function-map "\e[1;6H" [C-S-home]) + + (define-key xterm-function-map "\e[1;3A" [A-up]) + (define-key xterm-function-map "\e[1;3B" [A-down]) + (define-key xterm-function-map "\e[1;3C" [A-right]) + (define-key xterm-function-map "\e[1;3D" [A-left]) + (define-key xterm-function-map "\e[1;3F" [A-end]) + (define-key xterm-function-map "\e[1;3H" [A-home]) + + (define-key xterm-function-map "\e[2;2~" [S-insert]) + (define-key xterm-function-map "\e[3;2~" [S-delete]) + (define-key xterm-function-map "\e[5;2~" [S-prior]) + (define-key xterm-function-map "\e[6;2~" [S-next]) + + (define-key xterm-function-map "\e[2;5~" [C-insert]) + (define-key xterm-function-map "\e[3;5~" [C-delete]) + (define-key xterm-function-map "\e[5;5~" [C-prior]) + (define-key xterm-function-map "\e[6;5~" [C-next]) + + (define-key xterm-function-map "\e[2;6~" [C-S-insert]) + (define-key xterm-function-map "\e[3;6~" [C-S-delete]) + (define-key xterm-function-map "\e[5;6~" [C-S-prior]) + (define-key xterm-function-map "\e[6;6~" [C-S-next]) + + (define-key xterm-function-map "\e[2;3~" [A-insert]) + (define-key xterm-function-map "\e[3;3~" [A-delete]) + (define-key xterm-function-map "\e[5;3~" [A-prior]) + (define-key xterm-function-map "\e[6;3~" [A-next]) + + (define-key xterm-function-map "\eOA" [up]) + (define-key xterm-function-map "\eOB" [down]) + (define-key xterm-function-map "\eOC" [right]) + (define-key xterm-function-map "\eOD" [left]) + (define-key xterm-function-map "\eOF" [end]) + (define-key xterm-function-map "\eOH" [home]) + + (define-key xterm-function-map "\eO2A" [S-up]) + (define-key xterm-function-map "\eO2B" [S-down]) + (define-key xterm-function-map "\eO2C" [S-right]) + (define-key xterm-function-map "\eO2D" [S-left]) + (define-key xterm-function-map "\eO2F" [S-end]) + (define-key xterm-function-map "\eO2H" [S-home]) + + (define-key xterm-function-map "\eO5A" [C-up]) + (define-key xterm-function-map "\eO5B" [C-down]) + (define-key xterm-function-map "\eO5C" [C-right]) + (define-key xterm-function-map "\eO5D" [C-left]) + (define-key xterm-function-map "\eO5F" [C-end]) + (define-key xterm-function-map "\eO5H" [C-home]) ;; Use inheritance to let the main keymap override those defaults. ;; This way we don't override terminfo-derived settings or settings ;; made in the .emacs file. - (set-keymap-parent map (keymap-parent function-key-map)) - (set-keymap-parent function-key-map map)) + (set-keymap-parent xterm-function-map (keymap-parent function-key-map)) + (set-keymap-parent function-key-map xterm-function-map)) ;; Set up colors, for those versions of xterm that support it. (defvar xterm-standard-colors @@ -278,7 +288,7 @@ for the currently selected frame. The first 16 colors are taken from `xterm-standard-colors', which see, while the rest are computed assuming either the 88- or 256-color standard color scheme supported by latest versions of xterm." - (let* ((ncolors (display-color-cells)) + (let* ((ncolors (display-color-cells (selected-frame))) (colors xterm-standard-colors) (color (car colors))) (if (> ncolors 0) @@ -364,7 +374,7 @@ versions of xterm." ;; intelligent way than the default guesswork in startup.el. (defun xterm-rxvt-set-background-mode () "Set background mode as appropriate for the default rxvt colors." - (let ((fgbg (getenv "COLORFGBG")) + (let ((fgbg (server-getenv "COLORFGBG")) bg rgb) (setq frame-background-mode 'light) ; default (when (and fgbg @@ -386,8 +396,8 @@ versions of xterm." (xterm-register-default-colors) ;; If this xterm is actually a disguised rxvt, be more intelligent about ;; determining the background mode. -(and (getenv "COLORTERM") - (string-match "\\`rxvt" (getenv "COLORTERM")) +(and (server-getenv "COLORTERM") + (string-match "\\`rxvt" (server-getenv "COLORTERM")) (xterm-rxvt-set-background-mode)) ;; This recomputes all the default faces given the colors we've just set up. (tty-set-up-initial-frame-faces) diff --git a/lisp/version.el b/lisp/version.el index d2d45a361f7..07d59c76dd8 100644 --- a/lisp/version.el +++ b/lisp/version.el @@ -55,8 +55,8 @@ to the system configuration; look at `system-configuration' instead." (interactive "P") (let ((version-string (format (if (not (interactive-p)) - "GNU Emacs %s (%s%s%s)\n of %s on %s" - "GNU Emacs %s (%s%s%s) of %s on %s") + "GNU Emacs %s (%s%s%s%s)\n of %s on %s" + "GNU Emacs %s (%s%s%s%s) of %s on %s") emacs-version system-configuration (cond ((featurep 'motif) @@ -70,6 +70,7 @@ to the system configuration; look at `system-configuration' instead." (format ", %s scroll bars" (capitalize (symbol-name x-toolkit-scroll-bars))) "") + (if (featurep 'multi-tty) ", multi-tty" "") (format-time-string "%Y-%m-%d" emacs-build-time) emacs-build-system))) (if here diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index 78a41d54625..78d0e51ef88 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el @@ -122,8 +122,9 @@ any protocol specific data.") (defun x-dnd-init-frame (&optional frame) "Setup drag and drop for FRAME (i.e. create appropriate properties)." - (x-dnd-init-xdnd-for-frame frame) - (x-dnd-init-motif-for-frame frame)) + (when (eq 'x (window-system frame)) + (x-dnd-init-xdnd-for-frame frame) + (x-dnd-init-motif-for-frame frame))) (defun x-dnd-get-state-cons-for-frame (frame-or-window) "Return the entry in x-dnd-current-state for a frame or window." |