From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Jim Paris Newsgroups: gmane.emacs.bugs Subject: bug#6758: 23.2; xterm.el: please provide an option to not discard input in terminal-init-xterm Date: Tue, 3 Aug 2010 16:14:56 -0400 Message-ID: <20100803201456.GA8182@psychosis.jim.sh> References: <20100802205959.GA1974@psychosis.jim.sh> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1280867939 19037 80.91.229.12 (3 Aug 2010 20:38:59 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 3 Aug 2010 20:38:59 +0000 (UTC) Cc: 6758@debbugs.gnu.org, Johan =?UTF-8?Q?Bockg=C3=A5rd?= To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Aug 03 22:38:57 2010 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1OgOGF-0001kM-3C for geb-bug-gnu-emacs@m.gmane.org; Tue, 03 Aug 2010 22:38:55 +0200 Original-Received: from localhost ([127.0.0.1]:36688 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OgOGE-00055k-7I for geb-bug-gnu-emacs@m.gmane.org; Tue, 03 Aug 2010 16:38:54 -0400 Original-Received: from [140.186.70.92] (port=47203 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OgOFz-000516-UL for bug-gnu-emacs@gnu.org; Tue, 03 Aug 2010 16:38:48 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OgOFu-0002mO-FB for bug-gnu-emacs@gnu.org; Tue, 03 Aug 2010 16:38:39 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:45043) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OgOFu-0002mJ-By for bug-gnu-emacs@gnu.org; Tue, 03 Aug 2010 16:38:34 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1OgNt8-0004d3-8P; Tue, 03 Aug 2010 16:15:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Jim Paris Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 03 Aug 2010 20:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 6758 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 6758-submit@debbugs.gnu.org id=B6758.128086647417769 (code B ref 6758); Tue, 03 Aug 2010 20:15:02 +0000 Original-Received: (at 6758) by debbugs.gnu.org; 3 Aug 2010 20:14:34 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OgNsf-0004cX-Bv for submit@debbugs.gnu.org; Tue, 03 Aug 2010 16:14:33 -0400 Original-Received: from jim.sh ([75.150.123.25] helo=psychosis.jim.sh) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OgNsc-0004cS-Nz for 6758@debbugs.gnu.org; Tue, 03 Aug 2010 16:14:31 -0400 Original-Received: from psychosis.jim.sh (localhost [127.0.0.1]) by psychosis.jim.sh (8.14.3/8.14.3/Debian-5+lenny1) with ESMTP id o73KEvYZ008614 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 3 Aug 2010 16:14:57 -0400 Original-Received: (from jim@localhost) by psychosis.jim.sh (8.14.3/8.14.3/Submit) id o73KEuJM008613; Tue, 3 Aug 2010 16:14:56 -0400 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) X-Virus-Scanned: clamav-milter 0.96 at psychosis X-Virus-Status: Clean X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Tue, 03 Aug 2010 16:15:02 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:39217 Archived-At: Stefan Monnier wrote: > > Forget the time-dependent part of what I said, let's just send the > > query and handle the response whenever it happens to come in. See > > the below patch. This fixes everything -- it still detects both > > modifyOtherKeys and the background color, but doesn't require flushing > > input or rely on any timeouts at all, unlike the existing code. > > And there's nothing tricky. What do you think? > > Looks pretty good from here, thank you. > We may want to get rid of the "\e[>" (and "\e]11;") decode rules after > they've been used, just in case (or better yet: make them more > robust). > > Any objection? I found a problem: the Mac OS X terminal sets TERM=xterm-color, but it responds to the "Secondary DA" query as if it were a "Primary DA" query. Instead of a response like xterm's "\e[>0;253;0c", it sends "\e[?1;2c". The below patch accounts for this. It also adds the 2-second timeout when reading responses, and unsets the decode rules once they're unused. -jim --- xterm.el-orig 2010-04-03 18:26:04.000000000 -0400 +++ xterm.el 2010-08-03 16:05:49.000000000 -0400 @@ -440,6 +440,86 @@ ;; List of terminals for which modify-other-keys has been turned on. (defvar xterm-modify-other-keys-terminal-list nil) +(defun xterm-osc-translate (event) + "Read and handle a Operating System Controls response" + (let* ((str "") + (chr nil) + (recompute-faces nil)) + + ;; The reply should be of the form: \e ] 11 ; rgb: NUMBER1 / NUMBER2 / NUMBER3 \e \\ + (while (not (equal (setq chr (read-event nil nil 2)) ?\\)) + (setq str (concat str (string chr)))) + + (when (string-match "rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str) + (setq recompute-faces + (xterm-maybe-set-dark-background-mode + (string-to-number (match-string 1 str) 16) + (string-to-number (match-string 2 str) 16) + (string-to-number (match-string 3 str) 16)))) + + (when recompute-faces + (tty-set-up-initial-frame-faces)) + + ;; We no longer expect the OSC response + (define-key input-decode-map "\e]11;" nil) + "")) + +(defun xterm-primary-da-translate (event) + "Read and handle a Primary Device Attributes response" + (let* ((str "") + (chr nil)) + + ;; The reply should be of the form: \e [ ? Pd c + (while (not (equal (setq chr (read-event nil nil 2)) ?c)) + (setq str (concat str (string chr)))) + + ;; No need to do anything with this response. + + ;; Undefine both DA responses, as we don't expect either anymore + (define-key input-decode-map "\e[?" nil) + (define-key input-decode-map "\e[>" nil) + "")) + +(defun xterm-secondary-da-translate (event) + "Read and handle a Secondary Device Attributes response" + (let* ((str "") + (chr nil) + version) + + ;; The reply should be of the form: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c + (while (not (equal (setq chr (read-event nil nil 2)) ?c)) + (setq str (concat str (string chr)))) + + (when (string-match "0;\\([0-9]+\\);0" str) + (setq version (string-to-number + (substring str (match-beginning 1) (match-end 1)))) + ;; NUMBER2 is the xterm version number, look for something + ;; greater than 216, the version when modifyOtherKeys was + ;; introduced. + (when (>= version 216) + ;; Make sure that the modifyOtherKeys state is restored when + ;; suspending, resuming and exiting. + (add-hook 'suspend-hook 'xterm-turn-off-modify-other-keys) + (add-hook 'suspend-resume-hook 'xterm-turn-on-modify-other-keys) + (add-hook 'kill-emacs-hook 'xterm-remove-modify-other-keys) + (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys) + ;; Add the selected frame to the list of frames that + ;; need to deal with modify-other-keys. + (push (frame-terminal (selected-frame)) + xterm-modify-other-keys-terminal-list) + (xterm-turn-on-modify-other-keys)) + + ;; xterm version 235 supports reporting the background + ;; color, maybe earlier versions do too... + (when (>= version 235) + (define-key input-decode-map "\e]11;" 'xterm-osc-translate) + (send-string-to-terminal "\e]11;?\e\\"))) + + ;; Undefine both DA responses, as we don't expect either anymore + (define-key input-decode-map "\e[?" nil) + (define-key input-decode-map "\e[>" nil) + "")) + (defun terminal-init-xterm () "Terminal initialization function for xterm." ;; rxvt terminals sometimes set the TERM variable to "xterm", but @@ -469,71 +549,15 @@ ;; C-. C-, etc. ;; To do that we need to find out if the current terminal supports ;; modifyOtherKeys. At this time only xterm does. - (let ((coding-system-for-read 'binary) - (chr nil) - (str nil) - (recompute-faces nil) - version) - ;; Pending input can be mistakenly returned by the calls to - ;; read-event below. Discard it. - (discard-input) - ;; Try to find out the type of terminal by sending a "Secondary - ;; Device Attributes (DA)" query. - (send-string-to-terminal "\e[>0c") - - ;; The reply should be of the form: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c - ;; If the timeout is completely removed for read-event, this - ;; might hang for terminals that pretend to be xterm, but don't - ;; respond to this escape sequence. RMS' opinion was to remove - ;; it completely. That might be right, but let's first try to - ;; see if by using a longer timeout we get rid of most issues. - (when (equal (read-event nil nil 2) ?\e) - (when (equal (read-event nil nil 2) ?\[) - (while (not (equal (setq chr (read-event nil nil 2)) ?c)) - (setq str (concat str (string chr)))) - (when (string-match ">0;\\([0-9]+\\);0" str) - (setq version (string-to-number - (substring str (match-beginning 1) (match-end 1)))) - ;; xterm version 242 supports reporting the background - ;; color, maybe earlier versions do too... - (when (>= version 242) - (send-string-to-terminal "\e]11;?\e\\") - (when (equal (read-event nil nil 2) ?\e) - (when (equal (read-event nil nil 2) ?\]) - (setq str "") - (while (not (equal (setq chr (read-event nil nil 2)) ?\\)) - (setq str (concat str (string chr)))) - (when (string-match "11;rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str) - (setq recompute-faces - (xterm-maybe-set-dark-background-mode - (string-to-number (match-string 1 str) 16) - (string-to-number (match-string 2 str) 16) - (string-to-number (match-string 3 str) 16))))))) - ;; NUMBER2 is the xterm version number, look for something - ;; greater than 216, the version when modifyOtherKeys was - ;; introduced. - (when (>= version 216) - ;; Make sure that the modifyOtherKeys state is restored when - ;; suspending, resuming and exiting. - (add-hook 'suspend-hook 'xterm-turn-off-modify-other-keys) - (add-hook 'suspend-resume-hook 'xterm-turn-on-modify-other-keys) - (add-hook 'kill-emacs-hook 'xterm-remove-modify-other-keys) - (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys) - ;; Add the selected frame to the list of frames that - ;; need to deal with modify-other-keys. - (push (frame-terminal (selected-frame)) - xterm-modify-other-keys-terminal-list) - (xterm-turn-on-modify-other-keys)) - - ;; Recompute faces here in case the background mode was - ;; set to dark. We used to call - ;; `tty-set-up-initial-frame-faces' only once, but that - ;; caused the light background faces to be computed - ;; incorrectly. See: - ;; http://permalink.gmane.org/gmane.emacs.devel/119627 - (when recompute-faces - (tty-set-up-initial-frame-faces)))))) + ;; Try to find out the type of terminal by sending a "Secondary + ;; Device Attributes (DA)" query. Some terminals (like OS X's + ;; Terminal.app) respond to this query as if it were a "Primary + ;; Device Attributes" query instead, so we should handle that too. + (define-key input-decode-map "\e[?" 'xterm-primary-da-translate) + (define-key input-decode-map "\e[>" 'xterm-secondary-da-translate) + (send-string-to-terminal "\e[>0c") + (run-hooks 'terminal-init-xterm-hook)) ;; Set up colors, for those versions of xterm that support it.