diff options
| author | Stefan Monnier | 2013-03-11 00:24:15 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-03-11 00:24:15 -0400 |
| commit | 9b5939800615a4e08ac389813a70faf4b9e57bba (patch) | |
| tree | 945d3d7f81194ac0b774cc911d88326d70b20850 | |
| parent | e18e61cf276880f658ab8cdf1f242a675b58cd71 (diff) | |
| download | emacs-9b5939800615a4e08ac389813a70faf4b9e57bba.tar.gz emacs-9b5939800615a4e08ac389813a70faf4b9e57bba.zip | |
* lisp/term/xterm.el: Don't discard input. Use lexical-binding.
(xterm--report-background-handler, xterm--query): New functions.
(terminal-init-xterm): Use them.
Fixes: debbugs:6758
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/term/xterm.el | 178 |
2 files changed, 97 insertions, 87 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a21989ad0e2..60e01ae2d71 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2013-03-11 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * term/xterm.el: Don't discard input (bug#6758). Use lexical-binding. | ||
| 4 | (xterm--report-background-handler, xterm--query): New functions. | ||
| 5 | (terminal-init-xterm): Use them. | ||
| 6 | |||
| 1 | 2013-03-11 Michael R. Mauger <michael@mauger.com> | 7 | 2013-03-11 Michael R. Mauger <michael@mauger.com> |
| 2 | 8 | ||
| 3 | * progmodes/sql.el Version 3.2 | 9 | * progmodes/sql.el Version 3.2 |
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index ecaff7fe3a4..a7e137bee99 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; xterm.el --- define function key sequences and standard colors for xterm | 1 | ;;; xterm.el --- define function key sequences and standard colors for xterm -*- lexical-binding: t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1995, 2001-2013 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1995, 2001-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -37,8 +37,7 @@ If a list, assume that the listed features are supported, without checking. | |||
| 37 | 37 | ||
| 38 | The relevant features are: | 38 | The relevant features are: |
| 39 | modifyOtherKeys -- if supported, more key bindings work (e.g., \"\\C-,\") | 39 | modifyOtherKeys -- if supported, more key bindings work (e.g., \"\\C-,\") |
| 40 | reportBackground -- if supported, Xterm reports its background color | 40 | reportBackground -- if supported, Xterm reports its background color" |
| 41 | " | ||
| 42 | :version "24.1" | 41 | :version "24.1" |
| 43 | :group 'xterm | 42 | :group 'xterm |
| 44 | :type '(choice (const :tag "No" nil) | 43 | :type '(choice (const :tag "No" nil) |
| @@ -467,6 +466,58 @@ The relevant features are: | |||
| 467 | ;; List of terminals for which modify-other-keys has been turned on. | 466 | ;; List of terminals for which modify-other-keys has been turned on. |
| 468 | (defvar xterm-modify-other-keys-terminal-list nil) | 467 | (defvar xterm-modify-other-keys-terminal-list nil) |
| 469 | 468 | ||
| 469 | (defun xterm--report-background-handler () | ||
| 470 | (let ((str "") | ||
| 471 | chr) | ||
| 472 | ;; The reply should be: \e ] 11 ; rgb: NUMBER1 / NUMBER2 / NUMBER3 \e \\ | ||
| 473 | (while (not (equal (setq chr (read-event nil nil 2)) ?\\)) | ||
| 474 | (setq str (concat str (string chr)))) | ||
| 475 | (when (string-match | ||
| 476 | "rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str) | ||
| 477 | (let ((recompute-faces | ||
| 478 | (xterm-maybe-set-dark-background-mode | ||
| 479 | (string-to-number (match-string 1 str) 16) | ||
| 480 | (string-to-number (match-string 2 str) 16) | ||
| 481 | (string-to-number (match-string 3 str) 16)))) | ||
| 482 | |||
| 483 | ;; Recompute faces here in case the background mode was | ||
| 484 | ;; set to dark. We used to call | ||
| 485 | ;; `tty-set-up-initial-frame-faces' only once, but that | ||
| 486 | ;; caused the light background faces to be computed | ||
| 487 | ;; incorrectly. See: | ||
| 488 | ;; http://permalink.gmane.org/gmane.emacs.devel/119627 | ||
| 489 | (when recompute-faces | ||
| 490 | (tty-set-up-initial-frame-faces)))))) | ||
| 491 | |||
| 492 | (defun xterm--query (query reply-prefix handler) | ||
| 493 | ;; We used to query synchronously, but the need to use `discard-input' is | ||
| 494 | ;; rather annoying (bug#6758). Maybe we could always use the asynchronous | ||
| 495 | ;; approach, but it's less tested. | ||
| 496 | ;; FIXME: Merge the two branches. | ||
| 497 | (if (input-pending-p) | ||
| 498 | (progn | ||
| 499 | (message "Doing %S asynchronously" query) | ||
| 500 | (define-key input-decode-map reply-prefix | ||
| 501 | (lambda (&optional _prompt) | ||
| 502 | ;; Unregister the handler, since we don't expect further answers. | ||
| 503 | (define-key input-decode-map reply-prefix nil) | ||
| 504 | (funcall handler) | ||
| 505 | [])) | ||
| 506 | (send-string-to-terminal query)) | ||
| 507 | ;; Pending input can be mistakenly returned by the calls to | ||
| 508 | ;; read-event below. Discard it. | ||
| 509 | (message "Doing %S synchronously" query) | ||
| 510 | (send-string-to-terminal query) | ||
| 511 | (let ((i 0)) | ||
| 512 | (while (and (< i (length reply-prefix)) | ||
| 513 | (eq (read-event nil nil 2) (aref reply-prefix i))) | ||
| 514 | (setq i (1+ i))) | ||
| 515 | (if (= i (length reply-prefix)) | ||
| 516 | (funcall handler) | ||
| 517 | (push last-input-event unread-command-events) | ||
| 518 | (while (> i 0) | ||
| 519 | (push (aref reply-prefix (setq i (1- i))) unread-command-events)))))) | ||
| 520 | |||
| 470 | (defun terminal-init-xterm () | 521 | (defun terminal-init-xterm () |
| 471 | "Terminal initialization function for xterm." | 522 | "Terminal initialization function for xterm." |
| 472 | ;; rxvt terminals sometimes set the TERM variable to "xterm", but | 523 | ;; rxvt terminals sometimes set the TERM variable to "xterm", but |
| @@ -491,92 +542,45 @@ The relevant features are: | |||
| 491 | (xterm-register-default-colors) | 542 | (xterm-register-default-colors) |
| 492 | (tty-set-up-initial-frame-faces) | 543 | (tty-set-up-initial-frame-faces) |
| 493 | 544 | ||
| 494 | ;; Try to turn on the modifyOtherKeys feature on modern xterms. | 545 | (if (eq xterm-extra-capabilities 'check) |
| 495 | ;; When it is turned on many more key bindings work: things like | ||
| 496 | ;; C-. C-, etc. | ||
| 497 | ;; To do that we need to find out if the current terminal supports | ||
| 498 | ;; modifyOtherKeys. At this time only xterm does. | ||
| 499 | (when xterm-extra-capabilities | ||
| 500 | (let ((coding-system-for-read 'binary) | ||
| 501 | (chr nil) | ||
| 502 | (str "") | ||
| 503 | (recompute-faces nil) | ||
| 504 | ;; If `xterm-extra-capabilities' is 'check, we don't know | ||
| 505 | ;; the capabilities. We need to check for those defined | ||
| 506 | ;; as `xterm-extra-capabilities' set options. Otherwise, | ||
| 507 | ;; we don't need to check for any capabilities because | ||
| 508 | ;; they are given by setting `xterm-extra-capabilities' to | ||
| 509 | ;; a list (which could be empty). | ||
| 510 | (tocheck-capabilities (if (eq 'check xterm-extra-capabilities) | ||
| 511 | '(modifyOtherKeys reportBackground))) | ||
| 512 | ;; The given capabilities are either the contents of | ||
| 513 | ;; `xterm-extra-capabilities', if it's a list, or an empty list. | ||
| 514 | (given-capabilities (if (consp xterm-extra-capabilities) | ||
| 515 | xterm-extra-capabilities)) | ||
| 516 | version) | ||
| 517 | ;; 1. Set `version' | ||
| 518 | |||
| 519 | ;; Pending input can be mistakenly returned by the calls to | ||
| 520 | ;; read-event below. Discard it. | ||
| 521 | (discard-input) | ||
| 522 | ;; Try to find out the type of terminal by sending a "Secondary | 546 | ;; Try to find out the type of terminal by sending a "Secondary |
| 523 | ;; Device Attributes (DA)" query. | 547 | ;; Device Attributes (DA)" query. |
| 524 | (send-string-to-terminal "\e[>0c") | 548 | (xterm--query |
| 525 | 549 | "\e[>0c" "\e[>" | |
| 526 | ;; The reply should be: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c | 550 | (lambda () |
| 527 | ;; If the timeout is completely removed for read-event, this | 551 | (let ((str "") |
| 528 | ;; might hang for terminals that pretend to be xterm, but don't | 552 | chr) |
| 529 | ;; respond to this escape sequence. RMS' opinion was to remove | 553 | ;; The reply should be: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c |
| 530 | ;; it completely. That might be right, but let's first try to | 554 | ;; If the timeout is completely removed for read-event, this |
| 531 | ;; see if by using a longer timeout we get rid of most issues. | 555 | ;; might hang for terminals that pretend to be xterm, but don't |
| 532 | (when (and (equal (read-event nil nil 2) ?\e) | 556 | ;; respond to this escape sequence. RMS' opinion was to remove |
| 533 | (equal (read-event nil nil 2) ?\[)) | 557 | ;; it completely. That might be right, but let's first try to |
| 534 | (while (not (equal (setq chr (read-event nil nil 2)) ?c)) | 558 | ;; see if by using a longer timeout we get rid of most issues. |
| 535 | (setq str (concat str (string chr)))) | 559 | (while (not (equal (setq chr (read-event nil nil 2)) ?c)) |
| 536 | (if (string-match ">0;\\([0-9]+\\);0" str) | 560 | (setq str (concat str (string chr)))) |
| 537 | (setq version (string-to-number (match-string 1 str))))) | 561 | (when (string-match "0;\\([0-9]+\\);0" str) |
| 538 | ;; 2. If reportBackground is known to be supported, or the | 562 | (let ((version (string-to-number (match-string 1 str)))) |
| 539 | ;; version is 242 or higher, assume the xterm supports | 563 | ;; If version is 242 or higher, assume the xterm supports |
| 540 | ;; reporting the background color (TODO: maybe earlier | 564 | ;; reporting the background color (TODO: maybe earlier |
| 541 | ;; versions do too...) | 565 | ;; versions do too...) |
| 542 | (when (or (memq 'reportBackground given-capabilities) | 566 | (when (>= version 242) |
| 543 | (and (memq 'reportBackground tocheck-capabilities) | 567 | (xterm--query "\e]11;?\e\\" "\e]11;" |
| 544 | version | 568 | #'xterm--report-background-handler)) |
| 545 | (>= version 242))) | 569 | |
| 546 | (discard-input) | 570 | ;; If version is 216 (the version when modifyOtherKeys was |
| 547 | (send-string-to-terminal "\e]11;?\e\\") | 571 | ;; introduced) or higher, initialize the |
| 548 | (when (and (equal (read-event nil nil 2) ?\e) | 572 | ;; modifyOtherKeys support. |
| 549 | (equal (read-event nil nil 2) ?\])) | 573 | (when (>= version 216) |
| 550 | (setq str "") | 574 | (terminal-init-xterm-modify-other-keys))))))) |
| 551 | (while (not (equal (setq chr (read-event nil nil 2)) ?\\)) | 575 | |
| 552 | (setq str (concat str (string chr)))) | 576 | (when (memq 'reportBackground xterm-extra-capabilities) |
| 553 | (if (string-match | 577 | (xterm--query "\e]11;?\e\\" "\e]11;" |
| 554 | "11;rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str) | 578 | #'xterm--report-background-handler)) |
| 555 | (setq recompute-faces | 579 | |
| 556 | (xterm-maybe-set-dark-background-mode | 580 | (when (memq 'modifyOtherKeys xterm-extra-capabilities) |
| 557 | (string-to-number (match-string 1 str) 16) | 581 | (terminal-init-xterm-modify-other-keys))) |
| 558 | (string-to-number (match-string 2 str) 16) | 582 | |
| 559 | (string-to-number (match-string 3 str) 16)))))) | 583 | (run-hooks 'terminal-init-xterm-hook)) |
| 560 | |||
| 561 | ;; 3. If modifyOtherKeys is known to be supported or the | ||
| 562 | ;; version is 216 (the version when modifyOtherKeys was | ||
| 563 | ;; introduced) or higher, initialize the modifyOtherKeys support. | ||
| 564 | (if (or (memq 'modifyOtherKeys given-capabilities) | ||
| 565 | (and (memq 'modifyOtherKeys tocheck-capabilities) | ||
| 566 | version | ||
| 567 | (>= version 216))) | ||
| 568 | (terminal-init-xterm-modify-other-keys)) | ||
| 569 | |||
| 570 | ;; Recompute faces here in case the background mode was | ||
| 571 | ;; set to dark. We used to call | ||
| 572 | ;; `tty-set-up-initial-frame-faces' only once, but that | ||
| 573 | ;; caused the light background faces to be computed | ||
| 574 | ;; incorrectly. See: | ||
| 575 | ;; http://permalink.gmane.org/gmane.emacs.devel/119627 | ||
| 576 | (when recompute-faces | ||
| 577 | (tty-set-up-initial-frame-faces)))) | ||
| 578 | |||
| 579 | (run-hooks 'terminal-init-xterm-hook)) | ||
| 580 | 584 | ||
| 581 | (defun terminal-init-xterm-modify-other-keys () | 585 | (defun terminal-init-xterm-modify-other-keys () |
| 582 | "Terminal initialization for xterm's modifyOtherKeys support." | 586 | "Terminal initialization for xterm's modifyOtherKeys support." |