]> code.delx.au - gnu-emacs/commitdiff
Merge multi-tty branch
authorMiles Bader <miles@gnu.org>
Wed, 29 Aug 2007 05:28:10 +0000 (05:28 +0000)
committerMiles Bader <miles@gnu.org>
Wed, 29 Aug 2007 05:28:10 +0000 (05:28 +0000)
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-866

1  2 
lib-src/ChangeLog
lisp/ChangeLog
lisp/simple.el
lisp/term/x-win.el
lispref/ChangeLog
lwlib/ChangeLog
mac/ChangeLog
src/ChangeLog
src/dispextern.h
src/gtkutil.c
src/keyboard.c

diff --combined lib-src/ChangeLog
index 9d7d076ca4687952999aee938ed6b8854a4e2f87,9d7d076ca4687952999aee938ed6b8854a4e2f87..266453ae9758e9704b1d2d6f7beece2dfe82744f
@@@ -1,3 -1,3 +1,57 @@@
++2007-08-29  Dan Nicolaescu  <dann@ics.uci.edu>
++
++      * emacsclient.c (w32_execvp): Move definition before use.
++      (decode_options): Don't use a tty on mac carbon or windows.
++
++2007-08-29  Jason Rumney  <jasonr@gnu.org>
++
++      * emacsclient.c (SEND_STRING, SEND_QUOTED): Remove obfuscation
++      macros.
++      (quote_argument, set_tcp_socket, handle_sigcont, handle_sigtstp):
++      (main): Expand removed macros inline.
++      (main) [WINDOWSNT]: Don't call ttyname.  Don't recognize -suspend
++      option.
++      (main) [NO_SOCKETS_IN_FILE_SYSTEM]: Don't call init_signals.
++
++2007-08-29  Karoly Lorentey  <lorentey@elte.hu>
++
++      * emacsclient.c (signal.h): New include.
++      (sys/stat.h, errno.h): Always include, even on WINDOWSNT.
++      (DIRECTORY_SEP, IS_DIRECTORY_SEP, IS_DEVICE_SEP, IS_ANY_SEP): Copy
++      definitions here from src/lisp.h.
++      (main_argc, main_argv, current_frame, window_system, tty): New
++      variables.
++      (longopts): Add tty, current-frame.
++      (xmalloc, xstrdup): New functions.
++      (get_current_dir_name): New function, copied from src/sysdep.c.
++      (decode_options): Set display from environment.  Add tty and
++      current_frame options.  Make --no-wait imply --current-frame,
++      except when it is the only option given.  Make sure no frame is
++      opened when --current-frame is set.
++      (print_help_and_exit): Document tty and current-frame options.
++      (fail): Change arguments to void.
++      (main): When sockets are not defined, set main_argc, main_argv,
++      and call fail() with no arguments.
++      (emacs_socket): New variable (moved out from main `s').
++      (quote_file_name): Rename to quote_argument.
++      (quote_argument): New name for old quote_file_name.
++      (unquote_argument, strprefix, pass_signal_to_emacs)
++      (handle_sigcont, handle_sigtstp, init_signals): New functions.
++      (set_local_socket): Initialize saved_errno to 0.  If socket-name
++      is too long, call `fail' rather than `exit'.
++      (main): Doc update.  Set main_argc, main_argv.  New var `str'.
++      Don't need a filename or argument if tty or window_system set.
++      Call fail with no arguments.  Use get_current_dir_name to send
++      over the current directory.  Send version number to Emacs for
++      verification.  If tty is set, check TERM, and pass name and type
++      to Emacs.  Pass window_system to Emacs.  Move sending of eval to
++      optind loop.  Send -position, -file to Emacs.  Call fsync after
++      fflush.  Check for a client/server version match. Handle
++      -emacs-pid, -window-system-unsupported, -print, -error, -suspend
++      commands.  Don't exit prematurely on --no-wait, let Emacs close
++      the connection for us.  When creating a new frame, send
++      environment and pwd to Emacs.  Send current-frame to Emacs.
++
  2007-08-25  Eli Zaretskii  <eliz@gnu.org>
  
        * Makefile.in (rcs2log, rcs-checkin, grep-changelog, vcdiff):
diff --combined lisp/ChangeLog
index 06ceba6a157678069fc65a86ea948d30b24ad2e3,3ae13538fd5f5ef9e1535466dec1433f2b503c93..df84a75267806eb4b6741dd4d56b69e8b490f0ce
@@@ -1,58 -1,3 +1,367 @@@
++2007-08-29  Juri Linkov  <juri@jurta.org>
++
++      * loadup.el: Add "button" loading after "faces" and move "startup"
++      to load after "button".
++
++2007-08-29  Dan Nicolaescu  <dann@ics.uci.edu>
++
++      * loadup.el: Load term/mac-win on a Mac using Carbon.
++
++      * term/mac-win.el: Provide mac-win.
++      (mac-initialized): New variable.
++      (mac-initialize-window-system): New function.  Move global setup
++      here.
++      (handle-args-function-alist, frame-creation-function-alist):
++      (window-system-initialization-alist): Add mac entries.
++      (x-setup-function-keys): New function containing all the
++      top level function key definitions.
++
++      * term/x-win.el (x-menu-bar-open): Use accelerate-menu.
++
++        * env.el (read-envvar-name): Don't consider the environment frame
++        param.
++
++        * env.el (setenv):
++        * frame.el (frame-initialize, make-frame):
++        * faces.el (tty-set-up-initial-frame-faces):
++        * server.el (server-process-filter):  Set
++      display-environment-variable and term-environment-variable.
++
++      * server.el (server-process-filter): Set COLORFGBG and COLORTERM.
++
++2007-08-29  Jason Rumney  <jasonr@gnu.org>
++
++      * loadup.el: Only load term/x-win when X is compiled in.
++      Load term/w32-win and dependencies on windows-nt.
++
++      * term/w32-win.el: Reorder to match x-win.el more closely.
++      Provide w32-win.  Don't throw error when global window-system not
++      w32.
++      (internal-face-interactive): Remove obsolete function.
++      (x-setup-function-keys): Use local-function-key-map.
++      (w32-initialized): New variable.
++      (w32-initialize-window-system): Set it.
++      Move more global setup here.
++      (x-setup-function-keys): New function.
++      (w32-initialize-window-system): Move non function key global setup
++      here.
++      (x-cut-buffer-max): Remove.
++      (w32-initialize-window-system): New function.
++      (handle-args-function-alist, frame-creation-function-alist):
++      (window-system-initialization-alist): Add w32 entries.
++
++2007-08-29  David Kastrup  <dak@gnu.org>
++
++      * env.el (getenv): Pass frame to getenv-internal.
++
++2007-08-29  Karoly Lorentey  <lorentey@elte.hu>
++
++      * loadup.el: Delay loading env; mule-conf gets confused by cl
++      during bootstrap.  Also load termdev and term/x-win.
++
++      * bindings.el (mode-line-client): New variable.
++      (help-echo): Add it to the default mode-line format.
++
++      * cus-start.el: Remove bogus window-system reference from GTK test.
++
++      * ebrowse.el (ebrowse-electric-list-mode-map)
++      (ebrowse-electric-position-mode-map):
++      * ebuff-menu.el (electric-buffer-menu-mode-map):
++      * echistory.el (electric-history-map): Bind C-z to `suspend-frame',
++      not `suspend-emacs'.
++
++      * ediff-wind.el (ediff-setup-windows-automatic): New function.
++      (ediff-window-setup-function): Use it as default.
++
++      * files.el (save-buffers-kill-terminal): New function.
++      (ctl-x-map): Change binding of C-x C-c to save-buffers-kill-terminal.
++
++      * font-lock.el (lisp-font-lock-keywords-2): Add `let-environment'
++      and `with-selected-frame'.
++
++      * help-fns.el (describe-variable): Describe frame-local variables
++      correctly.
++
++      * simple.el (normal-erase-is-backspace-mode): Rewrite for multiple
++      display support.
++      (normal-erase-is-backspace-setup-frame): New function.
++
++      * subr.el (with-selected-frame): New function.
++      (read-quoted-char): Use terminal-local binding of
++      local-function-key-map instead of function-key-map.
++
++      * talk.el (talk): New function.
++      (talk-handle-delete-frame): New function.
++      (talk-add-display): Open a new frame only if FRAME was not a frame.
++
++      * termdev.el: New file.
++
++      * menu-bar.el (menu-bar-open): New function.  Bind it to f10.
++      * term/x-win.el: Don't bind f10.
++      * tmm.el: Remove autoload binding for f10.
++
++      * international/encoded-kb.el (encoded-kbd-setup-display): Use
++      `set-input-meta-mode'.  Fix broken condition before set-input-mode.
++      Store the saved input method as a terminal parameter.  Add keymap
++      parameter.  Use it instead of changing key-translation-map directly.
++      (saved-key-translation-map, encoded-kbd-mode, saved-input-mode):
++      Remove.
++      (encoded-kbd-setup-display): New function.
++
++      * international/mule-cmds.el (set-locale-environment): Fix getenv
++      call.  Use save-buffers-kill-terminal.  Ignore window-system; always
++      set the keyboard coding system.  Add DISPLAY parameter.
++      (set-display-table-and-terminal-coding-system): Add DISPLAY
++      parameter.  Pass it to set-terminal-coding-system.
++
++      * international/mule.el (keyboard-coding-system): Test for
++      encoded-kbd-setup-display, not encoded-kbd-mode.
++      (set-terminal-coding-system, set-keyboard-coding-system): Add
++      DISPLAY parameter.
++      (set-keyboard-coding-system): Use encoded-kbd-setup-display.
++
++      * term/README: Update.
++
++      * term/linux.el (terminal-init-linux): Use `set-input-meta-mode'.
++
++      * term/x-win.el (x-setup-function-keys): New function.  Move
++      function-key-map tweaks here.  Protect against multiple calls on
++      the same terminal.  Use terminal-local binding of
++      local-function-key-map instead of function-key-map.
++      (x-initialize-window-system): Make a copy of pure list.  Pass a
++      frame getenv.
++
++      * term/vt200.el, term/vt201.el, term/vt220.el, term/vt240.el:
++      * term/vt300.el, term/vt320.el, term/vt400.el, term/vt420.el:
++      * term/AT386.el, term/internal.el, term/iris-ansi.el, term/lk201.el:
++      * term/mac-win.el, term/news.el, term/rxvt.el, term/sun.el:
++      * term/tvi970.el, term/wyse50.el: Use terminal-local binding of
++      local-function-key-map instead of function-key-map.
++
++      * term/rxvt.el, term/xterm.el: Speed up load time by protecting
++      `substitute-key-definition' and `define-key' calls against
++      multiple execution.  Use terminal-local binding of
++      local-function-key-map instead of function-key-map.  Pass a frame
++      to getenv.
++
++      * edmacro.el (edmacro-format-keys):
++      * emulation/cua-base.el (cua--pre-command-handler):
++      * isearch.el (isearch-other-meta-char):
++      * xt-mouse.el: Use terminal-local binding of
++      local-function-key-map instead of function-key-map.
++
++      * fringe.el (set-fringe-mode): Simplify and fix using
++      `modify-all-frames-parameters'.
++      * scroll-bar.el (set-scroll-bar-mode): Ditto.
++      * tool-bar.el (tool-bar-mode): Ditto.  Remove 'tool-bar-map length
++      check before calling `tool-bar-setup'.
++      (tool-bar-setup): New variable.
++      (tool-bar-setup): Use it to guard against multiple calls.  Add
++      optional frame parameter, and select that frame before adding items.
++      (toggle-tool-bar-mode-from-frame): New function.
++
++      * menu-bar.el (toggle-menu-bar-mode-from-frame): New function.
++      (menu-bar-showhide-menu): Use toggle-menu-bar-mode-from-frame and
++      toggle-tool-bar-mode-from-frame to change "Menu-bar" and
++      "Tool-bar" toggles to reflect the state of the current frame.
++      (menu-bar-mode): Simplify and fix using `modify-all-frames-parameters'.
++
++      * env.el Require cl for byte compilation (for `block' and `return').
++      (environment, setenv-internal): New functions.
++      (let-environment): New macro.
++      (setenv, getenv): Add optional terminal parameter.  Update docs.
++      (setenv): Use setenv-internal.  Always set process-environment.
++      Handle `local-environment-variables'.
++      (read-envvar-name, setenv, getenv): Use frame parameters
++      to store the local environment, not terminal parameters.  Include
++      `process-environment' as well.
++
++      * faces.el (tty-run-terminal-initialization): New function.
++      (tty-create-frame-with-faces): Use it.  Set up faces and
++      background mode only after the terminal has been initialized.
++      Call terminal-init-*.  Don't load the initialization file more
++      than once.  Call set-locale-environment.
++      (frame-set-background-mode): Handle the 'background-mode terminal
++      parameter.
++      (tty-find-type): New function.
++      (x-create-frame-with-faces): Remove bogus check for
++      first frame.  Call `tool-bar-setup'.  Don't make frame visible
++      until we are done setting up all its parameters.  Call
++      x-setup-function-keys.
++
++      * frame.el (make-frame): Always inherit 'environment and 'client
++      parameters.  Set up the 'environment frame parameter, when needed.
++      Also inherit 'client parameter.  Don't override explicitly
++      specified values with inherited ones.  Add 'terminal frame
++      parameter.  Append window-system-default-frame-alist to parameters
++      before calling frame-creation-function.
++      (frame-initialize): Copy the environment from the initial frame.
++      (window-system-default-frame-alist): Enhance doc string.
++      (frame-notice-user-settings): Don't put 'tool-bar-lines in
++      `default-frame-alist' when initial frame is on a tty.
++      (modify-all-frames-parameters): Simplify using `assq-delete-all'.
++      Remove specified parameters from `window-system-default-frame-alist'.
++      (make-frame-on-tty, framep-on-display, suspend-frame):
++      Extend doc string, update parameter names.
++      (frames-on-display-list): Use terminal-id to get the display id.
++      (frame-notice-user-settings): Extend to apply
++      settings in `window-system-default-frame-alist' as well.
++      (terminal-id, terminal-parameters, terminal-parameter)
++      (set-terminal-parameter, terminal-handle-delete-frame): New functions.
++      (delete-frame-functions): Add to `delete-frame-functions' hook.
++      (blink-cursor-mode): Adapt blink-cursor-mode default
++      value from startup.el.
++      (make-frame-on-display): Protect condition on x-initialized when
++      x-win.el is not loaded.  Update doc.
++      (suspend-frame): Use display-controlling-tty-p to decide between
++      suspend-emacs and suspend-tty.
++      (frames-on-display-list): Update for display ids.
++      (framep-on-display): Ditto.
++      (suspend-frame): Use display-name, not frame-tty-name.
++      (selected-terminal): New function.
++
++      * server.el: Use `device' instead of `display' or `display-id' in
++      variable and client parameter names.
++      (server-select-display): Remove (unused).
++      (server-tty-live-p, server-handle-delete-tty): Remove.
++      (server-unquote-arg, server-quote-arg, server-buffer-clients):
++      Update docs.
++      (server-getenv-from, server-with-environment, server-send-string)
++      (server-save-buffers-kill-terminal): New functions.
++      (server-delete-client): Handle quits in kill-buffer.  Don't kill
++      modified buffers.  Add extra logging.  Delete frames after
++      deleting the tty.  Clear 'client parameter before deleting a frame.
++      Use delete-display, not delete-tty.
++      (server-visit-files): Don't set `server-existing-buffer' if the
++      buffer already has other clients.  Return list of buffers
++      created.  Update doc.  Don't set client-record when nowait.
++      (server-handle-delete-frame): Delete the client if this was its
++      last frame.  Check that the frame is alive.  Remove bogus comment.
++      Add note on possible race condition.  Delete tty clients, if needed.
++      (server-handle-suspend-tty): Use server-send-string.  Kill the
++      client in case of errors from process-send-string.  Use the display
++      parameter.
++      (server-unload-hook): Remove obsolete delete-tty hook.
++      (server-start): Ask before restarting if the old server still has
++      clients.  Add feedback messages.  Remove obsolete delete-tty hook.
++      (server-process-filter): Use server-send-string.  Accept `-dir'
++      command.  Switch to *scratch* immediately after creating the frame,
++      before evaluating any -evals.  Protect `display-splash-screen'
++      call in a condition-case.  Explain why.  Call
++      `display-startup-echo-area-message' before
++      `display-splash-screen'.  Don't display the splash screen when no
++      frame was created.  Show the Emacs splash screen and startup echo
++      area message.  Display the *scratch* buffer by default.  Store the
++      local environment in a frame (not terminal) parameter.  Do not try
++      to decode environment strings.  Fix reference to the 'display
++      frame parameter.  Change syntax of environment variables.  Put
++      environment into terminal parameters, not client parameters.  Use
++      a dummy client with --no-wait's X frames.  In `-position LINE'
++      handler, don't ruin the request string until the line number is
++      extracted.  Log opened files.  Handle -current-frame command.
++      Don't create frames when it is given.  Don't bind X frames to the
++      client when we are in -no-wait mode.  Set locale environment
++      variables from client while creating tty frames.  Disable call to
++      configure-display-for-locale.  When processing -position command,
++      don't change the request string until the parameters are
++      extracted.  Don't try to create an X frame when Emacs does not
++      support it.  Improve logging.  Temporarily set ncurses-related
++      environment variables to those of the client while creating a new
++      tty frame.  Select buffers opened by nowait clients, don't leave
++      them buried under others.  Set the display parameter, and use it
++      when appropriate.
++
++      * startup.el (display-startup-echo-area-message): Handle
++      `inhibit-startup-echo-area-message' here.
++      (command-line-1): Moved from here.
++      (fancy-splash-screens): Use `overriding-local-map' instead of
++      `overriding-terminal-local-map' for now; the latter doesn't work
++      right, it looses keypresses to another terminal.  Use
++      `overriding-terminal-local-map' to set up keymap.  Install a
++      `delete-frame-functions' hook to catch `delete-frame' events.
++      Ignore `select-window' events to cope better with
++      `focus-follows-mouse'.  Don't switch back to the original buffer
++      if the splash frame has been killed.  Restore previous buffer, even
++      if it's *scratch*.
++      (normal-splash-screen): Don't let-bind `mode-line-format'; it
++      changes the global binding - setq it instead.  Use
++      `save-buffers-kill-terminal'.
++      (display-splash-screen): Don't do anything if the splash screen is
++      already displayed elsewhere.
++      (fancy-splash-exit, fancy-splash-delete-frame): New functions.
++      (command-line): Replace duplicated code with a call to
++      tty-run-terminal-initialization.  Don't load the terminal
++      initialization file more than once.  Remove call to nonexistent
++      function `set-locale-translation-file-name'.
++
++      * xt-mouse.el (xterm-mouse-x, xterm-mouse-y): Convert to terminal
++      parameters.
++      (xterm-mouse-position-function, xterm-mouse-event): Update.
++      (xterm-mouse-mode): Don't depend on current value of window-system.
++      (turn-on-xterm-mouse-tracking, turn-off-xterm-mouse-tracking):
++      Update for multi-tty.
++      (turn-on-xterm-mouse-tracking-on-terminal)
++      (turn-off-xterm-mouse-tracking-on-terminal)
++      (xterm-mouse-handle-delete-frame): New functions.
++      (delete-frame-functions, after-make-frame-functions)
++      (suspend-tty-functions, resume-tty-functions): Install extra hooks
++      for multi-tty.
++
 +2007-08-29  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * simple.el (invisible-p): Remove: implemented in C now.
 +      (line-move-invisible-p): Remove obsolete alias.
 +
 +2007-08-28  Juri Linkov  <juri@jurta.org>
 +
 +      * image-mode.el (image-type): New variable.
 +      (image-mode): Set default major mode name to "Image[text]".
 +      (image-minor-mode): Change LIGHTER to display image-type in the
 +      mode line.
 +      (image-minor-mode): Set default image-type to "text".
 +      (image-toggle-display): After switching to text mode, set
 +      image-type to "text" and major mode name to "Image[text]".
 +      After switching to image mode, set image-type to actual image
 +      type, and add image type to major mode name.  Let-bind the same
 +      variable names as arguments of `image-type' and `create-image'.
 +      Bind `type' to the result of `image-type' and use it as arg
 +      of `create-image' to not determine the image type twice.
 +
 +2007-08-28  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * net/tramp.el (tramp-handle-set-file-times): Flush the file
 +      properties.
 +      (tramp-set-file-uid-gid, tramp-get-local-uid)
 +      (tramp-get-local-gid): New defuns.
 +      (tramp-handle-copy-file): Handle new parameter PRESERVE-UID-GID.
 +      (tramp-do-copy-or-rename-file): New parameter PRESERVE-UID-GID.
 +      Improve fast track.
 +      (tramp-do-copy-or-rename-file-directly): Sync parameter list with
 +      the other tramp-do-copy-or-rename-file-* functions.  Major rewrite.
 +      (tramp-handle-file-local-copy, tramp-handle-insert-file-contents)
 +      (tramp-handle-write-region): Improve fast track.
 +      (tramp-handle-file-remote-p): IDENTIFICATION can also be `localname'.
 +      (tramp-maybe-open-connection): Let `process-adaptive-read-buffering'
 +      be nil.
 +
 +2007-08-28  Ivan Kanis  <apple@kanis.eu>
 +
 +      * time.el: New feature to display several time zones in a buffer.
 +      (display-time-world-mode, display-time-world-display)
 +      (display-time-world, display-time-world-timer): New functions.
 +      (display-time-world-list, display-time-world-time-format)
 +      (display-time-world-buffer-name, display-time-world-timer-enable)
 +      (display-time-world-timer-second, display-time-world-mode-map):
 +      New variables.
 +
 +2007-08-28  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
 +
 +      * term/x-win.el (x-gtk-stock-map): New variable.
 +      (x-gtk-map-stock): New function.
 +
 +      * info.el (info-tool-bar-map): Add :rtl keyword to right/left-arrow and
 +      prev/next-node.
 +
  2007-08-28  Johan Bockg\e,Ae\e(Brd  <bojohan@dd.chalmers.se>  (tiny change)
  
        * play/gamegrid.el (gamegrid-init): Set line-spacing to 0.
diff --combined lisp/simple.el
index 5989d9cc61fe033a1700500a8e04523ffa667930,7c5bd13ef7768633faba94f019da1038cefec647..264bb7aa6e1b99ef4d7468c11644446aed0bba35
@@@ -85,34 -85,22 +85,22 @@@ If the optional third argument FRAME i
  buffer list instead of the selected frame's buffer list.
  If no other buffer exists, the buffer `*scratch*' is returned."
    (setq frame (or frame (selected-frame)))
-   (or (get-next-valid-buffer (frame-parameter frame 'buried-buffer-list)
-                            buffer visible-ok frame)
-       (get-next-valid-buffer (nreverse (buffer-list frame))
-                            buffer visible-ok frame)
+   (or (get-next-valid-buffer (nreverse (buffer-list frame))
+                            buffer visible-ok frame)
        (progn
        (set-buffer-major-mode (get-buffer-create "*scratch*"))
        (get-buffer "*scratch*"))))
  (defun next-buffer ()
    "Switch to the next buffer in cyclic order."
    (interactive)
-   (let ((buffer (current-buffer))
-       (bbl (frame-parameter nil 'buried-buffer-list)))
+   (let ((buffer (current-buffer)))
      (switch-to-buffer (other-buffer buffer t))
-     (bury-buffer buffer)
-     (set-frame-parameter nil 'buried-buffer-list
-                        (cons buffer (delq buffer bbl)))))
+     (bury-buffer buffer)))
  
  (defun previous-buffer ()
    "Switch to the previous buffer in cyclic order."
    (interactive)
-   (let ((buffer (last-buffer (current-buffer) t))
-       (bbl (frame-parameter nil 'buried-buffer-list)))
-     (switch-to-buffer buffer)
-     ;; Clean up buried-buffer-list up to and including the chosen buffer.
-     (while (and bbl (not (eq (car bbl) buffer)))
-       (setq bbl (cdr bbl)))
-     (set-frame-parameter nil 'buried-buffer-list bbl)))
+   (switch-to-buffer (last-buffer (current-buffer) t)))
  
  \f
  ;;; next-error support framework
@@@ -2557,6 -2545,8 +2545,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.
  
@@@ -2577,6 -2567,8 +2567,8 @@@ most recent string, the function shoul
  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)
  \f
  
  
@@@ -3639,6 -3631,16 +3631,6 @@@ Outline mode sets this.
    :type 'boolean
    :group 'editing-basics)
  
 -(defun invisible-p (pos)
 -  "Return non-nil if the character after POS is currently invisible."
 -  (let ((prop
 -       (get-char-property pos 'invisible)))
 -    (if (eq buffer-invisibility-spec t)
 -      prop
 -      (or (memq prop buffer-invisibility-spec)
 -        (assq prop buffer-invisibility-spec)))))
 -(define-obsolete-function-alias 'line-move-invisible-p 'invisible-p)
 -
  ;; Returns non-nil if partial move was done.
  (defun line-move-partial (arg noerror to-end)
    (if (< arg 0)
@@@ -5626,36 -5628,33 +5618,33 @@@ front of the list of recently selected 
  \f
  ;;; Handling of Backspace and Delete keys.
  
- (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))
-               (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)
-               (eq tty-erase-char ?\^H))))
-   "If non-nil, Delete key deletes forward and Backspace key deletes backward.
- On window systems, the default value of this option is chosen
- according to the keyboard used.  If the keyboard has both a Backspace
- key and a Delete key, and both are mapped to their usual meanings, the
- option's default value is set to t, so that Backspace can be used to
- delete backward, and Delete can be used to delete forward.
- If not running under a window system, customizing this option accomplishes
- a similar effect by mapping C-h, which is usually generated by the
- Backspace key, to DEL, and by mapping DEL to C-d via
- `keyboard-translate'.  The former functionality of C-h is available on
- the F1 key.  You should probably not use this setting if you don't
- have both Backspace, Delete and F1 keys.
+ (defcustom normal-erase-is-backspace 'maybe
+   "Set the default behaviour of the Delete and Backspace keys.
+ If set to t, Delete key deletes forward and Backspace key deletes
+ backward.
+ If set to nil, both Delete and Backspace keys delete backward.
+ If set to 'maybe (which is the default), Emacs automatically
+ selects a behaviour.  On window systems, the behaviour depends on
+ the keyboard used.  If the keyboard has both a Backspace key and
+ a Delete key, and both are mapped to their usual meanings, the
+ option's default value is set to t, so that Backspace can be used
+ to delete backward, and Delete can be used to delete forward.
+ If not running under a window system, customizing this option
+ accomplishes a similar effect by mapping C-h, which is usually
+ generated by the Backspace key, to DEL, and by mapping DEL to C-d
+ via `keyboard-translate'.  The former functionality of C-h is
+ available on the F1 key.  You should probably not use this
+ setting if you don't have both Backspace, Delete and F1 keys.
  
  Setting this variable with setq doesn't take effect.  Programmatically,
  call `normal-erase-is-backspace-mode' (which see) instead."
-   :type 'boolean
+   :type '(choice (const :tag "Off" nil)
+                (const :tag "Maybe" maybe)
+                (other :tag "On" t))
    :group 'editing-basics
    :version "21.1"
    :set (lambda (symbol value)
             (normal-erase-is-backspace-mode (or value 0))
           (set-default symbol value))))
  
+ (defun normal-erase-is-backspace-setup-frame (&optional frame)
+   "Set up `normal-erase-is-backspace-mode' on FRAME, if necessary."
+   (unless frame (setq frame (selected-frame)))
+   (with-selected-frame frame
+     (unless (terminal-parameter nil 'normal-erase-is-backspace)
+       (if (cond ((eq normal-erase-is-backspace 'maybe)
+                (and (not noninteractive)
+                     (or (memq system-type '(ms-dos windows-nt))
+                         (eq window-system 'mac)
+                         (and (memq 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)
+                              (eq tty-erase-char ?\^H)))))
+               (t
+                normal-erase-is-backspace))
+         (normal-erase-is-backspace-mode 1)
+       (normal-erase-is-backspace-mode 0)))))
  
  (defun normal-erase-is-backspace-mode (&optional arg)
    "Toggle the Erase and Delete mode of the Backspace and Delete keys.
  
  With numeric arg, turn the mode on if and only if ARG is positive.
  
- On window systems, when this mode is on, Delete is mapped to C-d and
- Backspace is mapped to DEL; when this mode is off, both Delete and
- Backspace are mapped to DEL.  (The remapping goes via
- `function-key-map', so binding Delete or Backspace in the global or
- local keymap will override that.)
+ On window systems, when this mode is on, Delete is mapped to C-d
+ and Backspace is mapped to DEL; when this mode is off, both
Delete and Backspace are mapped to DEL.  (The remapping goes via
+ `local-function-key-map', so binding Delete or Backspace in the
global or local keymap will override that.)
  
  In addition, on window systems, the bindings of C-Delete, M-Delete,
  C-M-Delete, C-Backspace, M-Backspace, and C-M-Backspace are changed in
@@@ -5697,54 -5717,57 +5707,57 @@@ have both Backspace, Delete and F1 keys
  
  See also `normal-erase-is-backspace'."
    (interactive "P")
-   (setq normal-erase-is-backspace
-       (if arg
-           (> (prefix-numeric-value arg) 0)
-         (not normal-erase-is-backspace)))
-   (cond ((or (memq window-system '(x w32 mac pc))
-            (memq system-type '(ms-dos windows-nt)))
-        (let ((bindings
-               `(([C-delete] [C-backspace])
-                 ([M-delete] [M-backspace])
-                 ([C-M-delete] [C-M-backspace])
-                 (,esc-map
-                  [C-delete] [C-backspace])))
-              (old-state (lookup-key function-key-map [delete])))
-          (if normal-erase-is-backspace
+   (let ((enabled (or (and arg (> (prefix-numeric-value arg) 0))
+                    (and (not arg)
+                         (not (eq 1 (terminal-parameter
+                                     nil 'normal-erase-is-backspace)))))))
+     (set-terminal-parameter nil 'normal-erase-is-backspace
+                           (if enabled 1 0))
+     (cond ((or (memq window-system '(x w32 mac pc))
+              (memq system-type '(ms-dos windows-nt)))
+          (let* ((bindings
+                  `(([C-delete] [C-backspace])
+                    ([M-delete] [M-backspace])
+                    ([C-M-delete] [C-M-backspace])
+                    (,esc-map
+                     [C-delete] [C-backspace])))
+                 (old-state (lookup-key local-function-key-map [delete])))
+            (if enabled
+                (progn
+                  (define-key local-function-key-map [delete] [?\C-d])
+                  (define-key local-function-key-map [kp-delete] [?\C-d])
+                  (define-key local-function-key-map [backspace] [?\C-?]))
+              (define-key local-function-key-map [delete] [?\C-?])
+              (define-key local-function-key-map [kp-delete] [?\C-?])
+              (define-key local-function-key-map [backspace] [?\C-?]))
+            ;; Maybe swap bindings of C-delete and C-backspace, etc.
+            (unless (equal old-state (lookup-key local-function-key-map [delete]))
+              (dolist (binding bindings)
+                (let ((map global-map))
+                  (when (keymapp (car binding))
+                    (setq map (car binding) binding (cdr binding)))
+                  (let* ((key1 (nth 0 binding))
+                         (key2 (nth 1 binding))
+                         (binding1 (lookup-key map key1))
+                         (binding2 (lookup-key map key2)))
+                    (define-key map key1 binding2)
+                    (define-key map key2 binding1)))))))
+         (t
+          (if enabled
               (progn
-                (define-key function-key-map [delete] [?\C-d])
-                (define-key function-key-map [kp-delete] [?\C-d])
-                (define-key function-key-map [backspace] [?\C-?]))
-            (define-key function-key-map [delete] [?\C-?])
-            (define-key function-key-map [kp-delete] [?\C-?])
-            (define-key function-key-map [backspace] [?\C-?]))
-          ;; Maybe swap bindings of C-delete and C-backspace, etc.
-          (unless (equal old-state (lookup-key function-key-map [delete]))
-            (dolist (binding bindings)
-              (let ((map global-map))
-                (when (keymapp (car binding))
-                  (setq map (car binding) binding (cdr binding)))
-                (let* ((key1 (nth 0 binding))
-                       (key2 (nth 1 binding))
-                       (binding1 (lookup-key map key1))
-                       (binding2 (lookup-key map key2)))
-                  (define-key map key1 binding2)
-                  (define-key map key2 binding1)))))))
-        (t
-         (if normal-erase-is-backspace
-             (progn
-               (keyboard-translate ?\C-h ?\C-?)
-               (keyboard-translate ?\C-? ?\C-d))
-           (keyboard-translate ?\C-h ?\C-h)
-           (keyboard-translate ?\C-? ?\C-?))))
-   (run-hooks 'normal-erase-is-backspace-hook)
-   (if (interactive-p)
-       (message "Delete key deletes %s"
-              (if normal-erase-is-backspace "forward" "backward"))))
+                (keyboard-translate ?\C-h ?\C-?)
+                (keyboard-translate ?\C-? ?\C-d))
+            (keyboard-translate ?\C-h ?\C-h)
+            (keyboard-translate ?\C-? ?\C-?))))
+     (run-hooks 'normal-erase-is-backspace-hook)
+     (if (interactive-p)
+       (message "Delete key deletes %s"
+                (if (terminal-parameter nil 'normal-erase-is-backspace)
+                    "forward" "backward")))))
  \f
  (defvar vis-mode-saved-buffer-invisibility-spec nil
    "Saved value of `buffer-invisibility-spec' when Visible mode is on.")
diff --combined lisp/term/x-win.el
index ed4330ee969a995be106281e00c44def2e8014c7,926356f49a8f3354b6ee694c662a714dd076504e..478d63d60573fb0c72a89866177055865357928a
  
  ;;; 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).
@@@ -65,7 -71,7 +71,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)
@@@ -1170,27 -1176,30 +1176,30 @@@ XConsortium: rgb.txt,v 10.41 94/02/20 1
  \f
  ;;;; 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])
- (define-key function-key-map [delete] [127])
- (define-key function-key-map [tab] [?\t])
- (define-key function-key-map [linefeed] [?\n])
- (define-key function-key-map [clear] [?\C-l])
- (define-key function-key-map [return] [?\C-m])
- (define-key function-key-map [escape] [?\e])
- (define-key function-key-map [M-backspace] [?\M-\d])
- (define-key function-key-map [M-delete] [?\M-\d])
- (define-key function-key-map [M-tab] [?\M-\t])
- (define-key function-key-map [M-linefeed] [?\M-\n])
- (define-key function-key-map [M-clear] [?\M-\C-l])
- (define-key function-key-map [M-return] [?\M-\C-m])
- (define-key function-key-map [M-escape] [?\M-\e])
- (define-key function-key-map [iso-lefttab] [backtab])
- (define-key function-key-map [S-iso-lefttab] [backtab])
+ (defun x-setup-function-keys (frame)
+   "Set up `function-key-map' on FRAME for the X window system."
+   ;; Don't do this twice on the same display, or it would break
+   ;; normal-erase-is-backspace-mode.
+   (unless (terminal-parameter frame 'x-setup-function-keys)
+     ;; Map certain keypad keys into ASCII characters that people usually expect.
+     (with-selected-frame frame
+       (define-key local-function-key-map [backspace] [127])
+       (define-key local-function-key-map [delete] [127])
+       (define-key local-function-key-map [tab] [?\t])
+       (define-key local-function-key-map [linefeed] [?\n])
+       (define-key local-function-key-map [clear] [?\C-l])
+       (define-key local-function-key-map [return] [?\C-m])
+       (define-key local-function-key-map [escape] [?\e])
+       (define-key local-function-key-map [M-backspace] [?\M-\d])
+       (define-key local-function-key-map [M-delete] [?\M-\d])
+       (define-key local-function-key-map [M-tab] [?\M-\t])
+       (define-key local-function-key-map [M-linefeed] [?\M-\n])
+       (define-key local-function-key-map [M-clear] [?\M-\C-l])
+       (define-key local-function-key-map [M-return] [?\M-\C-m])
+       (define-key local-function-key-map [M-escape] [?\M-\e])
+       (define-key local-function-key-map [iso-lefttab] [backtab])
+       (define-key local-function-key-map [S-iso-lefttab] [backtab]))
+     (set-terminal-parameter frame 'x-setup-function-keys t)))
  
  ;; These tell read-char how to convert
  ;; these special chars to ASCII.
@@@ -2393,205 -2402,169 +2402,216 @@@ order until succeed."
      (or clip-text primary-text cut-text)
      ))
  
\f
- ;; 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.  Don't set it if there are
-       ;; sizes there already (from command line).
-       (if (and (assq 'height parsed)
-                (not (assq 'height default-frame-alist)))
-           (setq default-frame-alist
-                 (cons (cons 'height (cdr (assq 'height parsed)))
-                       default-frame-alist)))
-       (if (and (assq 'width parsed)
-                (not (assq 'width default-frame-alist)))
-           (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 (x-selection-value 'CLIPBOARD))
+       (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))))
+ (defun x-menu-bar-open (&optional frame)
+   "Open the menu bar if `menu-bar-mode' is on. otherwise call `tmm-menubar'."
+   (interactive "i")
+   (if menu-bar-mode (accelerate-menu frame)
+     (tmm-menubar)))
  
- ;; Set scroll bar mode to right if set by X resources. Default is left.
- (if (equal (x-get-resource "verticalScrollBars" "ScrollBars") "right")
-     (customize-set-variable 'scroll-bar-mode 'right))
\f
+ ;;; 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 (or (getenv "DISPLAY" (selected-frame))
+                                                 (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"))))
+   ;; Set scroll bar mode to right if set by X resources. Default is left.
+   (if (equal (x-get-resource "verticalScrollBars" "ScrollBars") "right")
+       (customize-set-variable 'scroll-bar-mode 'right))
+   ;; 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.  Don't set it if there are 
+         ;; sizes there already (from command line).
+         (if (and (assq 'height parsed)
+                  (not (assq 'height default-frame-alist)))
+             (setq default-frame-alist
+                   (cons (cons 'height (cdr (assq 'height parsed)))
+                         default-frame-alist)))
+         (if (and (assq 'width parsed)
+                  (not (assq 'width default-frame-alist)))
+             (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 (x-selection-value 'CLIPBOARD))
-       (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]
+     (append '(menu-item "Paste" x-clipboard-yank
+                       :enable (not buffer-read-only)
+                       :help "Paste (yank) text most recently cut/copied")
+           nil))
+   (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]
-   '(menu-item "Paste" x-clipboard-yank
-             :enable (not buffer-read-only)
-             :help "Paste (yank) text most recently cut/copied"))
+ (provide 'x-win)
  
  ;; Initiate drag and drop
  (add-hook 'after-make-frame-functions 'x-dnd-init-frame)
  (define-key special-event-map [drag-n-drop] 'x-dnd-handle-drag-n-drop-event)
  
 +;; Let F10 do menu bar navigation.
 +(defun x-menu-bar-open (&optional frame)
 +  "Open the menu bar if `menu-bar-mode' is on. otherwise call `tmm-menubar'."
 +  (interactive "i")
 +  (if menu-bar-mode (menu-bar-open frame)
 +    (tmm-menubar)))
 +                 
 +(and (fboundp 'menu-bar-open)
 +     (global-set-key [f10] 'x-menu-bar-open))
 +
 +(defcustom x-gtk-stock-map
 +  '(
 +    ("new" . "gtk-new")
 +    ("open" . "gtk-open")
 +    ("diropen" . "gtk-directory")
 +    ("close" . "gtk-close")
 +    ("save" . "gtk-save")
 +    ("saveas" . "gtk-save-as")
 +    ("undo" . "gtk-undo")
 +    ("cut" . "gtk-cut")
 +    ("copy" . "gtk-copy")
 +    ("paste" . "gtk-paste")
 +    ("search" . "gtk-find")
 +    ("print" . "gtk-print")
 +    ("preferences" . "gtk-preferences")
 +    ("help" . "gtk-help")
 +    ("left-arrow" . "gtk-go-back")
 +    ("right-arrow" . "gtk-go-forward")
 +    ("home" . "gtk-home")
 +    ("jump-to" . "gtk-jump-to")
 +    ("index" . "gtk-index")
 +    ("search" . "gtk-find")
 +    ("exit" . "gtk-quit"))
 +  "How icons for tool bars are mapped to Gtk+ stock items.
 +Emacs must be compiled with the Gtk+ toolkit for this to have any effect."
 +  :version "23.0"
 +  :type 'alist
 +  :group 'x)
 +
 +(defun x-gtk-map-stock (file)
 +  "Map icon with file name FILE to a Gtk+ stock name, using `x-gtk-stock-map'."
 +  (let ((value (and file
 +                  (assoc-string (file-name-sans-extension 
 +                                 (file-name-nondirectory file))
 +                                x-gtk-stock-map))))
 +    (and value (cdr value))))
 +
  ;; arch-tag: f1501302-db8b-4d95-88e3-116697d89f78
  ;;; x-win.el ends here
diff --combined lispref/ChangeLog
index 7816c993e2e5d0f1a032749987c1f27f5400c6ed,8e6c8abd3ef14f6344a5fc4d828fb6d9cf7625c4..7abc1e0b9bb82a97350ed3fdd73fc384349843db
@@@ -1,13 -1,3 +1,18 @@@
++2007-08-29  Dan Nicolaescu  <dann@ics.uci.edu>
++
++      * frames.texi (Basic Parameters): Add display-environment-variable
++      and term-environment-variable.
++
 +2007-08-28  Juri Linkov  <juri@jurta.org>
 +
 +      * display.texi (Image Formats, Other Image Types): Add SVG.
 +
 +2007-08-28  Juri Linkov  <juri@jurta.org>
 +
 +      * display.texi (Images): Move formats-related text to new node
 +      "Image Formats".
 +      (Image Formats): New node.
 +
  2007-08-25  Richard Stallman  <rms@gnu.org>
  
        * display.texi (Images): Delete redundant @findex.
diff --combined lwlib/ChangeLog
index 6079a3af84ac5d2fa4fa5f3d4a49ac98e8b8ad9f,6079a3af84ac5d2fa4fa5f3d4a49ac98e8b8ad9f..75597a9549e66d27a10d86ee5e9365661e16d421
@@@ -1,3 -1,3 +1,8 @@@
++2007-08-29  Karoly Lorentey  <lorentey@elte.hu>
++
++      * xlwmenu.c (XlwMenuRealize): Ignore X errors while setting up
++      cursor shape.
++
  2007-07-25  Glenn Morris  <rgm@gnu.org>
  
        * Relicense all FSF files to GPLv3 or later.
diff --combined mac/ChangeLog
index c25d89a83bab08343c3a25a331461e55a09778ea,c25d89a83bab08343c3a25a331461e55a09778ea..8b00774471e294a16580f06db230cc557bed904f
@@@ -1,3 -1,3 +1,10 @@@
++2007-08-29  Karoly Lorentey  <lorentey@elte.hu>
++
++      * makefile.MPW (EmacsObjects): Add terminal.c.x.
++      (callproc.c.x): Add dependencies frame.h, termhooks.h.
++      ({Src}terminal.c.x): New.
++      (shortlisp): Add server.elc and termdev.elc.
++
  2007-07-25  Glenn Morris  <rgm@gnu.org>
  
        * Relicense all FSF files to GPLv3 or later.
diff --combined src/ChangeLog
index 231f18dd312409d392da35da00917b670372bc97,b402b1c7646965ae5abf574236226033af2b44f4..029f84945d59563e5e2cd9ad803a9e7ace3f4d1b
@@@ -1,18 -1,3 +1,624 @@@
++2007-08-29  Dan Nicolaescu  <dann@ics.uci.edu>
++
++      * callproc.c (child_setup, getenv_internal): Use the
++      display-environment-variable and term-environment-variable frame
++      params.
++      (set_initial_environment): Initialise Vprocess_environment.
++
++      * config.in: Disable multi-keyboard support on a mac.
++
++      * frame.c (Qterm_environment_variable)
++      (Qdisplay_environment_variable): New variables.
++      (syms_of_frame): Intern and staticpro them.
++      (Fmake_terminal_frame): Disable output method test.
++
++      * frame.h: Declare them here.
++
++      * macfns.c (x_set_mouse_color): Get rif from the frame.
++      (x_set_tool_bar_lines): Don't use updating_frame.
++      (mac_window): Add 2 new parameters for consistency with other systems.
++      (Fx_create_frame): Fix doc string.  Rename the parameter.  Set the
++      frame parameters following what is done in X11 and w32.  Don't use
++      FRAME_MAC_DISPLAY_INFO.
++      (Fx_open_connection, start_hourglass): Remove window-system check.
++      (x_create_tip_frame): Get the keyboard from the terminal.
++
++      * macmenu.c: Reorder includes.
++      (Fx_popup_menu): Use terminal specific mouse_position_hook.
++
++      * macterm.c (XTset_terminal_modes, XTreset_terminal_modes): Add a
++      terminal parameter.
++      (x_clear_frame): Add a frame parameter.
++      (note_mouse_movement): Get rif from the frame.
++      (mac_term_init): Initialize the terminal.
++      (mac_initialize): Make static and move terminal initialization ...
++      (mac_create_terminal): ... to this new function.
++
++      * macterm.h (struct mac_display_info): Add terminal.
++
++      * puresize.h (BASE_PURESIZE): Increase base value to 1158000.
++
++      * sysdep.c: Comment out text after #endif.
++
++      * term.c (init_tty): Only use terminal->kboard when MULTI_KBOARD
++      is defined.  Better initialize ttys in windows.  Use terminal
++      specific mouse_position_hook.
++
++      * termhooks.h (union display_info): Add mac_display_info.
++
++      * w32fns.c (Fx_create_frame): Use kboard from the terminal.  Set
++      the default minibuffer frame, window_system and the rest of the
++      frame parameters following what is done in X11.
++
++      * w32term.c (w32_initialize): Make static.
++
++      * xselect.c (x_handle_selection_clear): Only access
++      terminal->kboard when MULTI_KBOARD is defined.
++
++      * s/darwin.h (SYSTEM_PURESIZE_EXTRA): Define here.
++      (SYSTEM_PURESIZE_EXTRA): Only define on Carbon.
++
++2007-08-29  Jason Rumney  <jasonr@gnu.org>
++
++      * frame.c (Fdelete_frame): Only get kboard when MULTI_KBOARD defined.
++      (make_terminal_frame) [WINDOWSNT]: Initialize terminal.
++
++      * fringe.c (w32_init_fringe w32_reset_fringes) [HAVE_NTGUI]:
++      (mac_init_fringe) [MAC_OS]: Get rif from selected_frame.
++
++      * keyboard.c (restore_kboard_configuration): Only define when
++      MULTI_KBOARD defined.
++
++      * makefile.w32-in: Update dependancies from Makefile.in
++      (OBJ1): Add terminal.$(O)
++
++      * term.c (dissociate_if_controlling_tty) [WINDOWSNT]: Don't
++      define function body.
++      (init_tty) [WINDOWSNT]: Use selected_frame for initializing.
++
++      * termhooks.h (display_info) [WINDOWSNT]: Add w32.
++
++      * w32.c (request_sigio, unrequest_sigio): Remove.
++
++      * w32console.c (w32con_move_cursor, w32con_clear_to_end)
++      (w32con_clear_frame, w32con_clear_end_of_line)
++      (w32con_ins_del_lines, w32con_insert_glyphs, w32con_write_glyphs)
++      (w32con_delete_glyphs, w32con_set_terminal_window)
++      (scroll_line, w32_sys_ring_bell): Add frame arg.
++      (w32con_set_terminal_modes, w32con_reset_terminal_modes): Add
++      terminal arg.
++      (PICK_FRAME): Remove.
++      (w32con_write_glyphs): Use frame specific terminal coding.
++      (one_and_only_w32cons): New global variable.
++      (initialize_w32_display): Use it for storing hooks.
++      (create_w32cons_output): New function.
++
++      * w32inevt.c, w32inevt.h (w32_console_read_socket): Make first
++      arg a frame.
++
++      * w32fns.c (x_create_tip_frame): Set terminal and ref count.  Set
++      window_system.
++      (x_set_tool_bar_lines): Don't use updating_frame.
++      (Fx_create_frame): Set terminal and ref count.
++      (Fx_open_connection): Remove window-system check.
++
++      * w32menu.c (Fx_popup_menu): Use terminal specific mouse_position_hook.
++
++      * w32term.c (w32_term_init): Call add_keyboard_wait_descriptor.
++      (w32_set_terminal_modes, w32_reset_terminal_modes): Add terminal arg.
++      (x_clear_frame, x_delete_glyphs, w32_ring_bell, x_ins_del_lines):
++      Add frame arg.
++      (x_delete_terminal, w32_create_terminal): New functions.
++      (w32_term_init): Create a terminal.
++      (w32_initialize): Move terminal specific initialization to
++      w32_create_terminal.
++
++      * w32term.h (x_output): Remove foreground_pixel and
++      background_pixel.
++      (w32_clear_rect, w32_clear_area): Use background from frame.
++      (w32_display_info): Add terminal.
++      (w32_sys_ring_bell, x_delete_display): Declare here.
++
++      * xdisp.c (display_menu_bar) [HAVE_NTGUI]: Check frame type.
++
++      * s/ms-w32.h (SYSTEM_PURESIZE_EXTRA): Bump to 50k.
++
++2007-08-29  Kalle Olavi Niemitalo  <kon@iki.fi>  (tiny change)
++
++      * keyboard.c (interrupt_signal, handle_interrupt, Fset_quit_char):
++      Fix get_named_tty calls for the controlling tty.
++
++2007-08-29  ARISAWA Akihiro  <ari@mbf.ocn.ne.jp>  (tiny change)
++
++      * term.c (dissociate_if_controlling_tty)[USG]: Fix parse error.
++
++2007-08-29  Yoshiaki Kasahara  <kasahara@nc.kyushu-u.ac.jp>  (tiny change)
++
++      * term.c (tty_insert_glyphs): Add missing first parameter.
++
++2007-08-29  Karoly Lorentey  <karoly@lorentey.hu>
++
++      * buffer.c (Fbuffer_list, Fbury_buffer): Take
++      frame->buried_buffer_list into account.
++
++      * cm.c (current_tty): New variable, for cmputc().
++      (cmputc): Use it.
++      (cmcheckmagic): Add tty parameter, look up terminal streams there.
++      (calccost): Add tty parameter.  Use emacs_tputs() instead of tputs().
++      (cmgoto): Add tty parameter.  Pass it on to calccost().  Use
++      emacs_tputs() instead of tputs().
++
++      * cm.h (emacs_tputs): New macro to set current_tty, and then call
++      tputs().
++      (current_tty): New variable, for cmputc().
++      (cmcheckmagic, cmputc, cmgoto): Add prototypes.
++
++      * eval.c (unwind_to_catch): Don't call x_fully_uncatch_errors.
++      (internal_condition_case, internal_condition_case_1)
++      (internal_condition_case_2): Don't abort when x_catching_errors.
++
++      * fns.c (Fyes_or_no_p): Don't try to open an X dialog on tty terminals.
++      (Fy_or_n_p): Likewise.  Use temporarily_switch_to_single_kboard to
++      prevent crashes caused by bogus longjmps in read_char.
++
++      * keymap.h (Fset_keymap_parent): Add EXFUN.
++
++      * macterm.h (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL)
++      * w32term.h (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL):
++      Remove redundant definition.
++
++      * macfns.c (x_set_mouse_color,x_make_gc): Use
++      FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
++
++      * w32term.c (x_free_frame_resources): Use
++      FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
++      (w32_initialize): Use the accessor macros for terminal characteristics.
++
++      * macterm.c (mac_initialize): Use Fset_input_interrupt_mode.
++      Use the accessor macros for terminal characteristics.
++      * msdos.c (internal_terminal_init): Use the accessor macros for
++      terminal characteristics.
++      (ScreenVisualBell,internal_terminal_init): Use
++      FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
++
++      * termopts.h (no_redraw_on_reenter): Declare.
++
++      * alloc.c (emacs_blocked_malloc): Disable mallopt call.
++      (mark_terminals,mark_ttys): Declare.
++      (Fgarbage_collect): Call them.
++      (mark_object): Mark buried_buffer_list;
++
++      * prefix-args.c: Include stdlib.h for exit.
++
++      * syssignal.h: Add comment.
++
++      * indent.c: Include stdio.h.
++
++      * window.h (Vinitial_window_system): Declare.
++      (Vwindow_system): Delete declaration.
++
++      * fontset.c (Finternal_char_font): Use FRAME_RIF.
++
++      * image.c (lookup_image): Don't initialize `c' until the xasserts
++      have been run.
++
++      * gtkutil.c (xg_create_frame_widgets): Use FRAME_BACKGROUND_PIXEL and
++      FRAME_FOREGROUND_PIXEL.
++
++      * print.c (print_preprocess): Don't lose print_depth levels while
++      iterating.
++
++      * widget.c (update_from_various_frame_slots): Use
++      FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
++
++      * window.c (set_window_buffer): Don't call clear_mouse_face on tty
++      frames.
++      (window_internal_height): Remove bogus make_number call.
++      (init_window_once): Call make_terminal_frame with two zero
++      parameters.
++
++      * fileio.c (Fread_file_name): Update comment.
++
++      * callint.c (Fcall_interactively): Use
++      temporarily_switch_to_single_kboard instead of single_kboard_state.
++      Make sure it is correctly unwound.
++
++      * xsmfns.c (x_session_close): New function.
++
++      * coding.h (terminal_coding,safe_terminal_coding,keyboard_coding):
++      Delete declarations.
++
++      * xterm.h: Remove declaration for x_fully_uncatch_errors.
++      (x_output): Remove background_pixel and foreground_pixel fields.
++      (x_display_info): Add new field TERMINAL. Remove KBOARD field.
++      (x_delete_device):
++      (x_session_close): Declare.
++
++      * lread.c: Include setjmp.h.  Update declaration of `read_char'.
++      (read_filtered_event): Call `read_char' with a local
++      `wrong_kboard_jmpbuf'.
++
++      * minibuf.c (read_minibuf): Call
++      temporarily_switch_to_single_kboard. Don't call
++      single_kboard_state. Use FRAME_RIF.
++
++      * process.c (Fmake_network_process): Don't unrequest_sigio on modern
++      systems.
++
++      * lisp.h (set_process_environment): Rename to
++      `set_global_environment'.
++      (Fframe_with_environment,Fset_input_meta_mode)
++      (Fset_quit_char): EXFUN.
++      (x_create_device,tty_output,terminal,tty_display_info): Declare.
++      (init_sys_modes, reset_sys_modes): Update prototypes.
++      (init_all_sys_modes, reset_all_sys_modes): New prototypes.
++
++      * keyboard.h (struct kboard): Add new fields:
++      Vlocal_function_key_map, Vlocal_key_translation_map,
++      Vkeyboard_translate_table.
++      (Vfunction_key_map,Vkeyboard_translate_table,single_kboard_state):
++      Delete declarations.
++      (Vfunction_key_map,Vkey_translation_map,push_kboard,pop_kboard)
++      (temporarily_switch_to_single_kboard,tty_read_avail_input):
++      New declarations.
++
++      * emacs.c (main): Don't call init_sys_modes(), the new term_init()
++      already does that during init_display().  Call syms_of_keymap
++      before syms_of_keyboard.  Call `syms_of_terminal'.  Call
++      set_initial_environment, not set_process_environment.
++      (shut_down_emacs): Call reset_all_sys_modes() instead of
++      reset_sys_modes().
++
++      * xfaces.c (x_free_gc): Protect xassert with GLYPH_DEBUG.
++      (internal_resolve_face_name, resolve_face_name_error): New
++      functions.
++      (resolve_face_name): Protect against loops and errors thrown by
++      Fget.
++      (realize_default_face): Don't use FRAME_FONT unless frame is an X
++      frame.
++      (Ftty_supports_face_attributes_p): Update tty_capable_p call.
++
++      * scroll.c: Replace CURTTY() with local variables throughout the
++      file (where applicable).
++      (calculate_scrolling, calculate_direct_scrolling)
++      (scrolling_1, scroll_cost): Use the accessor macros for terminal
++      characteristics.
++
++      * keymap.c (Vfunction_key_map): Remove.
++      (Fdescribe_buffer_bindings): Update references to
++      Vfunction_key_map.
++      (syms_of_keymap): Remove DEFVAR for Vfunction_key_map.
++      (Vkey_translation_map): Remove.
++      (syms_of_keymap): Remove DEFVAR for key-translation-map.
++      (Fdescribe_buffer_bindings):
++      (read_key_sequence, init_kboard, syms_of_keyboard, mark_kboards):
++      Update for terminal-local key-translation-map.
++
++      * Makefile.in (callproc.o): Update dependencies.
++      (lisp, shortlisp): Add termdev.elc.
++      (obj): Add terminal.o.
++      (terminal.o): Add dependencies.
++      [HAVE_CARBON]: Make terminal.o depend on macgui.h.
++      (data.o, fns.o): Add termhooks.h dependency.
++      (SOME_MACHINE_LISP): Add dnd.elc.
++      (minibuf.o): Fix typo.
++      Update dependencies.
++
++      * data.c (do_symval_forwarding, store_symval_forwarding)
++      (find_symbol_value): Use the selected frame's keyboard, not
++      current_kboard.
++
++      * .gdbinit (init_sys_modes): Use Vinitial_window_system instead of
++      Vwindow_system.
++
++      * xmenu.c (Fx_menu_bar_open) [USE_X_TOOLKIT, USE_GTK]: Rename from
++      Fmenu_bar_open.
++      (syms_of_xmenu): Update defsubr.
++      (mouse_position_for_popup, Fx_popup_menu)
++      (Fx_popup_dialog, x_activate_menubar, update_frame_menubar)
++      (set_frame_menubar, free_frame_menubar)
++      (create_and_show_popup_menu, xmenu_show, )
++      (create_and_show_dialog, xdialog_show, xmenu_show): Abort if not
++      an X frame.
++
++      * xselect.c (x_own_selection): Abort if not an X frame.
++      (some_frame_on_display): Check if it is an X frame.
++      (x_handle_selection_clear): Deal with MULTI_KBOARD.
++
++      * coding.c: Include frame.h and termhooks.h.
++      (terminal_coding,keyboard_coding): Delete.
++      (Fset_terminal_coding_system_internal):
++      (Fset_keyboard_coding_system_internal):
++      (Fkeyboard_coding_system):
++      (Fterminal_coding_system): Add a terminal parameter. Get
++      terminal_coding from the terminal.
++      (init_coding_once): Don't call setup_coding_system here.
++
++      * dispextern.h (set_scroll_region, turn_off_insert)
++      (turn_off_highlight, background_highlight, clear_end_of_line_raw)
++      (tty_clear_end_of_line, tty_setup_colors)
++      (delete_tty,updating_frame)
++      (produce_special_glyphs, produce_glyphs, write_glyphs)
++      (insert_glyphs): Remove.
++      (raw_cursor_to, clear_to_end, tty_turn_off_insert)
++      (tty_turn_off_highlight,get_tty_size): Add declaration.
++      (tabs_safe_p, init_baud_rate, get_tty_terminal): Update
++      prototypes.
++
++      * frame.h (enum output_method): Add output_initial.
++      (struct x_output): Delete.
++      (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL): Access
++      foreground_pixel and background_pixel directly from the frame.
++      (tty_display): Delete.
++      (struct frame): Add buried_buffer_list, foreground_pixel,
++      background_pixel and terminal. Delete kboard
++      (union output_data): Add tty.
++      (FRAME_KBOARD): Get the kboard from the terminal.
++      (FRAME_INITIAL_P): New macro.
++      (Qtty, Qtty_type, Qterminal, Qterminal_live_p, Qenvironment)
++      (Qterm_environment_variable, Qdisplay_environment_variable)
++      (make_terminal_frame, Qburied_buffer_list, Qwindow_system): New
++      declarations.
++
++      * termchar.h (tty_output, tty_display_info): New structures.
++      (tty_list): Declare.
++      (FRAME_TTY, CURTTY): New macros.
++      (must_write_spaces, min_padding_speed, fast_clear_end_of_line)
++      (line_ins_del_ok, char_ins_del_ok, scroll_region_ok)
++      (scroll_region_cost, memory_below_frame, fast_clear_end_of_line)
++      (dont_calculate_costs, no_redraw_on_reenter): Remove declarations.
++
++      * callproc.c: Include frame.h and termhooks.h, for terminal
++      parameters.
++      (add_env): New function.
++      (child_setup): Use it.
++      (child_setup, getenv_internal): Handle the new
++      Vprocess_environment.
++      (getenv_internal): Fix get_terminal_param call.
++      (Fgetenv_internal, egetenv): Update doc.
++      (syms_of_callproc): Initialize Vprocess_environment to nil.
++      Register and initialize them. Remove obsolete defvars. Update doc
++      strings.
++      (child_setup): Handle Vlocal_environment_variables.
++      (getenv_internal): Add terminal parameter.  Handle
++      Vlocal_environment_variables.
++      (Fgetenv_internal): Add terminal parameter.
++      (child_setup, getenv_internal, Fgetenv_internal): Store the local
++      environment in a frame (not terminal) parameter.  Update doc
++      strings.
++      (set_initial_environment): Rename from set_global_environment.
++      Store Emacs environment in initial frame parameter.
++
++      * xdisp.c (redisplay_internal): Update references to
++      `previous_terminal_frame'.
++      (display_mode_line, Fformat_mode_line): Replace calls to
++      `push_frame_kboard' with `push_kboard'.
++      (get_glyph_string_clip_rects): Add extra parentheses and
++      braces to prevent compiler warnings.
++      (calc_pixel_width_or_height): Add xassert to check that the
++      frame is alive.  Don't call `lookup_image' on a termcap frame.
++      (message2_nolog, message3_nolog, redisplay_internal)
++      (set_vertical_scroll_bar, redisplay_window, check_x_display_info)
++      (x_set_scroll_bar_foreground, x_set_scroll_bar_background)
++      (Fx_create_frame, Fxw_display_color_p, Fx_display_grayscale_p)
++      (Fx_display_pixel_width, Fx_display_pixel_height)
++      (Fx_display_planes, Fx_display_color_cells)
++      (Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
++      (Fx_display_screens, Fx_display_mm_height, Fx_display_mm_width)
++      (Fx_display_backing_store, Fx_display_visual_class)
++      (Fx_display_save_under, Fx_close_connection, x_create_tip_frame):
++      Use FRAME_TERMINAL_P, FRAME_WINDOW_P,  FRAME_TTY and FRAME_RIF.
++
++      * xfns.c (x_set_foreground_color x_set_background_color)
++      (x_set_mouse_color, x_set_cursor_color, x_make_gc): Use
++      FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
++      (Fx_create_frame, x_create_tip_frame, build_string, x_window)
++      (Fx_create_frame, x_create_tip_frame): Don't create frames on a
++      terminal that is being deleted.
++      (Fx_create_frame): Use `store_frame_param' to set `window-system'
++      frame parameter, and make sure it overrides any user-supplied
++      setting.
++      (Fx_close_connection, Fx_synchronize): Unify argument names with
++      the rest of the DEFUNs.
++
++      * dispnew.c (Fsend_string_to_terminal): Update call to
++      `get_tty_terminal'.
++      (Fredraw_frame, Fsend_string_to_terminal)
++      (Fsend_string_to_terminal, init_display): User FRAME_RIF,
++      FRAME_TERMCAP_P and FRAME_TTY.
++      (window_change_signal): Don't believe width/height values that are
++      impossibly small.
++      (Vinitial_window_system): Rename from Vwindow_system.
++      (termscript, Wcm, rif): Delete.
++
++      * termhooks.h (struct terminal): New struct containing the
++      previously global text display hooks and new members NAME,
++      DELETED and PARAM_ALIST.
++      (FRAME_TERMINAL, TERMINAL_TERMINAL_CODING)
++      (TERMINAL_KEYBOARD_CODING, TERMINAL_ACTIVE_P, FRAME_WINDOW_P)
++      (FRAME_RIF): New macros.
++      (get_terminal_param, get_device): New declarations.
++      (termscript): Delete declaration.
++
++      * xterm.c (x_initialize): Use Fset_input_interrupt_mode.
++      (XTflash, x_free_frame_resources, x_scroll_bar_create)
++      (x_scroll_bar_set_handle): Use FRAME_BACKGROUND_PIXEL and
++      FRAME_FOREGROUND_PIXEL.
++      (x_fully_uncatch_errors): Disable definition.
++      (x_scroll_bar_expose): Fix reference to foreground pixel.
++      (XTread_socket): Disable loop on all X displays.
++      (x_delete_terminal): Don't set terminal->deleted and let
++      delete_terminal delete the frames on the terminal.
++      (x_delete_display): Doc update to reflect changes in
++      delete_terminal.
++      (x_display_info) <terminal>: Move member earlier in the struct.
++      (x_delete_terminal): Use terminal->deleted.  Delete all frames on
++      the display explicitly.
++      (deleting_tty): Remove old variable.
++      (Fsuspend_tty): Call clear_tty_hooks.
++      (Fresume_tty, init_tty): Call set_tty_hooks.
++      (clear_tty_hooks, set_tty_hooks): New functions.
++      (Ftty_display_color_p, Ftty_display_color_cells): Don't throw
++      errors on X frames.
++      (x_catch_errors_unwind): Abort if x_error_message is NULL.
++      (handle_one_xevent): Initialize `f' to NULL.
++      (x_delete_device, x_create_device): New functions.
++      (XTset_terminal_modes, XTreset_terminal_modes)
++      (XTread_socket, x_connection_closed, x_term_init)
++      (x_term_init, x_delete_display): Add terminal parameter.
++      (x_term_init) [!HAVE_GTK_MULTIDISPLAY]: Refuse to create secondary
++      X connections.
++
++      * frame.c (Fframep): Deal with output_initial.
++      (Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list, Qtty)
++      (Qtty_type, Qwindow_system, Qenvironment)
++      (Qterm_environment_variable, Qdisplay_environment_variable): New
++      variables.
++      (x_set_screen_gamma, store_frame_param): Fix compilation errors.
++      (make_terminal_frame): Don't create frames on a terminal that is
++      being deleted.
++      (make_terminal_frame): Use FRAME_BACKGROUND_PIXEL and
++      FRAME_FOREGROUND_PIXEL.
++      (store_frame_param): Check for found_for_frame before calling
++      XFRAME.
++      (Fmake_terminal_frame): Handle NULL tty names correctly.
++      (syms_of_frame): Enhance doc string of `default-frame-alist'.
++      (Fdelete_frame): Remove unused variable `count'.
++      (Qenvironment): New variable.
++      (Fdelete_frame): Don't allow other frames to refer to a deleted
++      frame in their 'environment parameter.
++      (Fframe_with_environment): New function.
++      (syms_of_frame): Defsubr it.  Initialize and staticpro
++      Qenvironment.
++      (get_future_frame_param): New function.
++      (Fmake_terminal_frame): Use it.
++
++      * sysdep.c (init_sys_modes, reset_sys_modes): Update for renames.
++      * sysdep.c (reset_sys_modes): Update for renames.
++
++      * keyboard.c (tty_read_avail_input): New function.
++      (Fset_input_interrupt_mode,Fset_output_flow_control): New
++      functions.
++      (syms_of_keyboard): Defsubr them.
++      (Fset_input_meta_mode, Fset_quit_char): New functions.
++      (Fset_input_mode): Split to above functions.
++
++      (read_char_minibuf_menu_prompt): Add wrong_kboard_jmpbuf
++      parameter.  Use it in call to `read_char'.
++      (read_char): Declare.  Update call to
++      `read_char_minibuf_menu_prompt'.  Set wrong_kboard_jmpbuf
++      correctly in recursive calls.  Use current_kboard to access
++      Vkeyboard_translate_table.  Enhance comment before extra longjmp
++      to wrong_kboard_jmpbuf.  Add wrong_kboard_jmpbuf parameter to
++      allow for recursive calls.  Update longjmp invocations.  Remember
++      the original current_kboard, and longjmp to `wrong_kboard_jmpbuf'
++      when a filter, timer or sentinel changes it.  Comment out
++      unnecessary calls to `record_single_kboard_state' and
++      `any_kboard_state'.  Update recursive calls.
++      (wrong_kboard_jmpbuf): Remove global variable.
++      (read_key_sequence): Remove unused variable wrong_kboard_jmpbuf.
++      Handle deleted interrupted_kboards correctly; that is a legal
++      case.  Add `wrong_kboard_jmpbuf' local variable.  Update setjmp
++      and read_char calls.  Abort if interrupted_kboard died in
++      read_char.
++      (any_kboard_state, single_kboard_state)
++      (push_frame_kboard): Remove function.
++      (pop_kboard): Switch out of single_kboard mode if the kboard has
++      been deleted. Remove unused variable. Help debugging by not
++      changing current_kboard unnecessarily. Set current_kboard to the
++      kboard of the selected frame when the stored kboard object has
++      been deleted before pop_kboard.
++      (temporarily_switch_to_single_kboard): Change first parameter to a
++      frame pointer.  Throw an error when caller wants to change kboards
++      while in single_kboard mode.  Don't push_kboard if we weren't in
++      single kboard state.  Don't pop_kboard if we popped into any
++      kboard state.
++      (restore_kboard_configuration): Abort if pop_kboard changed the
++      kboard in single_kboard mode. Call pop_kboard only after setting
++      up single_kboard mode.
++      (Frecursive_edit): Switch to single_kboard mode only in nested
++      command loops.
++      (cmd_error, command_loop, command_loop_1, timer_check): Comment
++      out unnecessary call to `any_kboard_state' and
++      `record_single_kboard_state'.
++      (delete_kboard): Exit single_kboard mode if we have just deleted
++      that kboard. Use FRAME_KBOARD.
++      (interrupt_signal): Use `Fkill_emacs' to exit Emacs, not
++      `fatal_error_signal'.
++      (record_single_kboard_state): Don't push_kboard if we weren't in
++      single kboard state.  Don't pop_kboard if we popped into any
++      kboard state.
++      (push_frame_kboard): Rename to push_kboard.
++      (kbd_buffer_get_event): Use FRAME_TERMINAL.
++      (read_avail_input): Read input from all terminals.
++      (mark_kboards): Also mark Vkeyboard_translate_table.
++      (kbd_buffer_store_event_hold): Simplify condition.
++      (read_key_sequence): Reinitialize fkey and keytran at each replay.
++      (Vkeyboard_translate_table): Move to struct kboard.
++      (init_kboard): Initialize Vkeyboard_translate_table.
++      (syms_of_keyboard): Use DEFVAR_KBOARD to define
++      Vkeyboard_translate_table.  Update doc strings.  Update docs of
++      local-function-key-map and function-key-map.
++
++      * terminal.c: New file.
++
++      * term.c: Include errno.h.
++      (Vring_bell_function, device_list, initial_device)
++      (next_device_id, ring_bell, update_begin, update_end)
++      (set_terminal_window, cursor_to, raw_cursor_to)
++      (clear_to_end, clear_frame, clear_end_of_line)
++      (write_glyphs, insert_glyphs, delete_glyphs, ins_del_lines)
++      (Fdisplay_name, create_device, delete_device): Move to terminal.c.
++      (syms_of_term): Move their initialization to terminal.c.
++      (get_tty_terminal, Fdisplay_tty_type, Ftty_display_color_p)
++      (Ftty_display_color_cells)
++      (Ftty_no_underline, Fsuspend_tty, Fresume_tty, create_tty_output)
++      (init_tty, maybe_fatal): New functions.
++      (Ftty_type): Return nil if terminal is not on a tty instead of
++      throwing an error.  Doc update.
++      (syms_of_term) <Vsuspend_tty_functions, Vresume_tty_functions>:
++      Doc update. Initialize new subrs and variables.
++      (delete_tty): Use terminal->deleted.
++      (tty_set_terminal_modes): Rename from set_terminal_modes.
++      (tty_reset_terminal_modes): Rename from reset_terminal_modes.
++      (set_scroll_region): Rename to `tty_set_scroll_region'.
++      (turn_on_insert): Rename to `tty_turn_on_insert'.
++      (turn_off_insert): Rename to `tty_turn_off_insert'.
++      (turn_off_highlight): Rename to `tty_turn_off_highlight'.
++      (turn_on_highlight): Rename to `tty_turn_on_highlight'.
++      (toggle_highligh): Rename to `tty_toggle_highlight'.
++      (background_highlight): Rename to `tty_background_highlight'.
++      (highlight_if_desired): Rename to `tty_highlight_if_desired'.
++      (tty_ring_bell, tty_update_end, tty_set_terminal_window)
++      (tty_set_scroll_region, tty_background_highlight)
++      (tty_cursor_to, tty_raw_cursor_to, tty_clear_to_end)
++      (tty_clear_frame, tty_clear_end_of_line, tty_write_glyphs)
++      (tty_insert_glyphs, tty_delete_glyphs, tty_ins_del_lines)
++      (term_get_fkeys, tty_setup_colors, dissociate_if_controlling_tty):
++      Add static modifier.
++      (tty_reset_terminal_modes, tty_set_terminal_window)
++      (tty_set_scroll_region, tty_background_highlight)
++      (tty_highlight_if_desired, tty_cursor_to)
++      (tty_raw_cursor_to, tty_clear_to_end, tty_clear_frame)
++      (tty_clear_end_of_line, tty_write_glyphs, tty_insert_glyphs)
++      (tty_delete_glyphs, tty_ins_del_lines, turn_on_face): Update for
++      renames.
++
 +2007-08-28  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
 +
 +      * keyboard.c: Qrtl is new.
 +      (parse_tool_bar_item): Handle :rtl keyword.
 +      (syms_of_keyboard): Intern :rtl keyword.
 +
 +      * dispextern.h (enum tool_bar_item_idx): Add TOOL_BAR_ITEM_RTL_IMAGE.
 +
 +      * gtkutil.c (xg_tool_bar_expose_callback): Just do SET_FRAME_GARBAGED
 +      so no Lisp code is executed.
 +      (file_for_image, find_rtl_image): New functions.
 +      (xg_get_image_for_pixmap): Use file_for_image
 +      (update_frame_tool_bar): If direction is RTL, use RTL image if
 +      defined.  Use Gtk stock images if defined.
 +
  2007-08-27  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
  
        * macterm.c (x_draw_composite_glyph_string_foreground): Draw rectangle
diff --combined src/dispextern.h
index 9e899f9ccb2f3466a4957733dba513831bbf54fd,a127cbe3737628c5588b37d23f5f39afb845db30..de9dadec6bca9f8acb8481a5b36bcad270abf41e
@@@ -1029,13 -1029,8 +1029,8 @@@ extern int fonts_changed_p
  
  extern struct glyph space_glyph;
  
- /* Frame being updated by update_window/update_frame.  */
- extern struct frame *updating_frame;
  /* Window being updated by update_window.  This is non-null as long as
-    update_window has not finished, and null otherwise.  It's role is
-    analogous to updating_frame.  */
+    update_window has not finished, and null otherwise.  */
  
  extern struct window *updated_window;
  
@@@ -1355,7 -1350,7 +1350,7 @@@ struct glyph_strin
        DESCENT = FONT->descent
        HEIGHT = FONT_HEIGHT (FONT)
        F_DESCENT = (FRAME_FONT (F)->descent
-                    - F->output_data.x->baseline_offset)
+                    - F->terminal->output_data.x->baseline_offset)
        F_HEIGHT = FRAME_LINE_HEIGHT (F)
  */
  
@@@ -2184,16 -2179,16 +2179,16 @@@ struct i
  /* Call produce_glyphs or produce_glyphs_hook, if set.  Shortcut to
     avoid the function call overhead.  */
  
- #define PRODUCE_GLYPHS(IT)                    \
-      do {                                     \
-        extern int inhibit_free_realized_faces;        \
-        if (rif != NULL)                               \
-        rif->produce_glyphs ((IT));            \
-        else                                   \
-        produce_glyphs ((IT));                 \
-        if ((IT)->glyph_row != NULL)           \
-        inhibit_free_realized_faces = 1;       \
-      } while (0)
+ #define PRODUCE_GLYPHS(IT)                              \
+   do {                                                  \
+     extern int inhibit_free_realized_faces;             \
+     if (FRAME_RIF ((IT)->f) != NULL)                    \
+       FRAME_RIF ((IT)->f)->produce_glyphs ((IT));       \
+     else                                                \
+       produce_glyphs ((IT));                            \
+     if ((IT)->glyph_row != NULL)                        \
+       inhibit_free_realized_faces = 1;                  \
+   } while (0)
  
  /* Bit-flags indicating what operation move_it_to should perform.  */
  
@@@ -2367,10 -2362,6 +2362,6 @@@ struct redisplay_interfac
  #endif /* HAVE_WINDOW_SYSTEM */
  };
  
- /* The current interface for window-based redisplay.  */
- extern struct redisplay_interface *rif;
  \f
  /***********************************************************************
                                Images
@@@ -2579,9 -2570,6 +2570,9 @@@ enum tool_bar_item_id
    /* Help string.  */
    TOOL_BAR_ITEM_HELP,
  
 +  /* Icon file name of right to left image when an RTL locale is used.  */
 +  TOOL_BAR_ITEM_RTL_IMAGE,
 +
    /* Sentinel = number of slots in tool_bar_items occupied by one
       tool-bar item.  */
    TOOL_BAR_ITEM_NSLOTS
@@@ -2674,8 -2662,6 +2665,6 @@@ void init_iterator_to_row_start P_ ((st
                                     struct glyph_row *));
  int get_next_display_element P_ ((struct it *));
  void set_iterator_to_next P_ ((struct it *, int));
- void produce_glyphs P_ ((struct it *));
- void produce_special_glyphs P_ ((struct it *, enum display_element_type));
  void start_display P_ ((struct it *, struct window *, struct text_pos));
  void move_it_to P_ ((struct it *, int, int, int, int, int));
  void move_it_vertically P_ ((struct it *, int));
@@@ -2822,11 -2808,11 +2811,11 @@@ int image_ascent P_ ((struct image *, s
  
  /* Defined in sysdep.c */
  
- void get_frame_size P_ ((int *, int *));
+ void get_tty_size P_ ((int, int *, int *));
  void request_sigio P_ ((void));
  void unrequest_sigio P_ ((void));
- int tabs_safe_p P_ ((void));
- void init_baud_rate P_ ((void));
+ int tabs_safe_p P_ ((int));
+ void init_baud_rate P_ ((int));
  void init_sigio P_ ((int));
  
  /* Defined in xfaces.c */
@@@ -2965,8 -2951,6 +2954,6 @@@ void clear_glyph_row P_ ((struct glyph_
  void prepare_desired_row P_ ((struct glyph_row *));
  int line_hash_code P_ ((struct glyph_row *));
  void set_window_update_flags P_ ((struct window *, int));
- void write_glyphs P_ ((struct glyph *, int));
- void insert_glyphs P_ ((struct glyph *, int));
  void redraw_frame P_ ((struct frame *));
  void redraw_garbaged_frames P_ ((void));
  int scroll_cost P_ ((struct frame *, int, int, int));
@@@ -2983,31 -2967,44 +2970,44 @@@ void syms_of_display P_ ((void))
  extern Lisp_Object Qredisplay_dont_pause;
  GLYPH spec_glyph_lookup_face P_ ((struct window *, GLYPH));
  
- /* Defined in term.c */
+ /* Defined in terminal.c */
  
- extern void ring_bell P_ ((void));
- extern void set_terminal_modes P_ ((void));
- extern void reset_terminal_modes P_ ((void));
+ extern void ring_bell P_ ((struct frame *));
  extern void update_begin P_ ((struct frame *));
  extern void update_end P_ ((struct frame *));
- extern void set_terminal_window P_ ((int));
- extern void set_scroll_region P_ ((int, int));
- extern void turn_off_insert P_ ((void));
- extern void turn_off_highlight P_ ((void));
- extern void background_highlight P_ ((void));
- extern void clear_frame P_ ((void));
- extern void clear_end_of_line P_ ((int));
- extern void clear_end_of_line_raw P_ ((int));
- extern void delete_glyphs P_ ((int));
- extern void ins_del_lines P_ ((int, int));
+ extern void set_terminal_window P_ ((struct frame *, int));
+ extern void cursor_to P_ ((struct frame *, int, int));
+ extern void raw_cursor_to P_ ((struct frame *, int, int));
+ extern void clear_to_end P_ ((struct frame *));
+ extern void clear_frame P_ ((struct frame *));
+ extern void clear_end_of_line P_ ((struct frame *, int));
+ extern void write_glyphs P_ ((struct frame *, struct glyph *, int));
+ extern void insert_glyphs P_ ((struct frame *, struct glyph *, int));
+ extern void delete_glyphs P_ ((struct frame *, int));
+ extern void ins_del_lines P_ ((struct frame *, int, int));
+ extern struct terminal *init_initial_terminal P_ ((void));
+ /* Defined in term.c */
+ extern void tty_set_terminal_modes P_ ((struct terminal *));
+ extern void tty_reset_terminal_modes P_ ((struct terminal *));
+ extern void tty_turn_off_insert P_ ((struct tty_display_info *));
+ extern void tty_turn_off_highlight P_ ((struct tty_display_info *));
  extern int string_cost P_ ((char *));
  extern int per_line_cost P_ ((char *));
  extern void calculate_costs P_ ((struct frame *));
+ extern void produce_glyphs P_ ((struct it *));
+ extern void produce_special_glyphs P_ ((struct it *, enum display_element_type));
+ extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long));
  extern void set_tty_color_mode P_ ((struct frame *, Lisp_Object));
- extern void tty_setup_colors P_ ((int));
- extern void term_init P_ ((char *));
- void cursor_to P_ ((int, int));
- extern int tty_capable_p P_ ((struct frame *, unsigned, unsigned long, unsigned long));
+ extern struct terminal *get_tty_terminal P_ ((Lisp_Object, int));
+ extern struct terminal *get_named_tty P_ ((char *));
+ EXFUN (Ftty_type, 1);
+ extern void create_tty_output P_ ((struct frame *));
+ extern struct terminal *init_tty P_ ((char *, char *, int));
  
  /* Defined in scroll.c */
  
diff --combined src/gtkutil.c
index 9fb011de919852c454916eb7ca7dc2eb383d5a09,0f95acaa2c7f96f93c6a89e537d0b6ee7107765e..2af1e03cc28938a6cc8737358570f304389f1b2e
@@@ -298,23 -298,6 +298,23 @@@ xg_get_pixbuf_from_pix_and_mask (gpix, 
    return icon_buf;
  }
  
 +static Lisp_Object
 +file_for_image(image)
 +     Lisp_Object image;
 +{
 +  Lisp_Object specified_file = Qnil;
 +  Lisp_Object tail;
 +  extern Lisp_Object QCfile;
 +
 +  for (tail = XCDR (image);
 +       NILP (specified_file) && CONSP (tail) && CONSP (XCDR (tail));
 +       tail = XCDR (XCDR (tail)))
 +    if (EQ (XCAR (tail), QCfile))
 +      specified_file = XCAR (XCDR (tail));
 +
 +  return specified_file;
 +}
 +
  /* For the image defined in IMG, make and return a GtkImage.  For displays with
     8 planes or less we must make a GdkPixbuf and apply the mask manually.
     Otherwise the highlightning and dimming the tool bar code in GTK does
@@@ -340,8 -323,16 +340,8 @@@ xg_get_image_for_pixmap (f, img, widget
    /* If we have a file, let GTK do all the image handling.
       This seems to be the only way to make insensitive and activated icons
       look good in all cases.  */
 -  Lisp_Object specified_file = Qnil;
 -  Lisp_Object tail;
 +  Lisp_Object specified_file = file_for_image (img->spec);
    Lisp_Object file;
 -  extern Lisp_Object QCfile;
 -
 -  for (tail = XCDR (img->spec);
 -       NILP (specified_file) && CONSP (tail) && CONSP (XCDR (tail));
 -       tail = XCDR (XCDR (tail)))
 -    if (EQ (XCAR (tail), QCfile))
 -      specified_file = XCAR (XCDR (tail));
  
    /* We already loaded the image once before calling this
       function, so this only fails if the image file has been removed.
@@@ -874,7 -865,7 +874,7 @@@ xg_create_frame_widgets (f
  
    /* Since GTK clears its window by filling with the background color,
       we must keep X and GTK background in sync.  */
-   xg_pix_to_gcolor (wfixed, f->output_data.x->background_pixel, &bg);
+   xg_pix_to_gcolor (wfixed, FRAME_BACKGROUND_PIXEL (f), &bg);
    gtk_widget_modify_bg (wfixed, GTK_STATE_NORMAL, &bg);
  
    /* Also, do not let any background pixmap to be set, this looks very
@@@ -2043,7 -2034,7 +2043,7 @@@ xg_create_one_menuitem (item, f, select
    return w;
  }
  
- /* Callback called when keyboard traversal (started by menu-bar-open) ends.
+ /* Callback called when keyboard traversal (started by x-menu-bar-open) ends.
     WMENU is the menu for which traversal has been done.  DATA points to the
     frame for WMENU.  We must release grabs, some bad interaction between GTK
     and Emacs makes the menus keep the grabs.  */
@@@ -3341,16 -3332,6 +3341,16 @@@ xg_set_toolkit_scroll_bar_thumb (bar, p
  /* The key for storing the button widget in its proxy menu item. */
  #define XG_TOOL_BAR_PROXY_BUTTON "emacs-tool-bar-proxy-button"
  
 +/* The key for the data we put in the GtkImage widgets.  The data is
 +   the stock name used by Emacs.  We use this to see if we need to update
 +   the GtkImage with a new image.  */
 +#define XG_TOOL_BAR_STOCK_NAME "emacs-tool-bar-stock-name"
 +
 +/* Callback function invoked when a tool bar item is pressed.
 +   W is the button widget in the tool bar that got pressed,
 +   CLIENT_DATA is an integer that is the index of the button in the
 +   tool bar.  0 is the first button.  */
 +
  static gboolean
  xg_tool_bar_button_cb (widget, event, user_data)
      GtkWidget      *widget;
@@@ -3633,10 -3614,8 +3633,10 @@@ xg_tool_bar_item_expose_callback (w, ev
    return FALSE;
  }
  
 +#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
 +
  /* This callback is called when a tool bar shall be redrawn.
 -   We need to update the tool bar from here in case the image cache
 +   We need to update the images in case the image cache
     has deleted the pixmaps used in the tool bar.
     W is the GtkToolbar to be redrawn.
     EVENT is the expose event for W.
@@@ -3650,8 -3629,7 +3650,8 @@@ xg_tool_bar_expose_callback (w, event, 
       GdkEventExpose *event;
       gpointer client_data;
  {
 -  update_frame_tool_bar ((FRAME_PTR) client_data);
 +  FRAME_PTR f = (FRAME_PTR) client_data;
 +  SET_FRAME_GARBAGED (f);
    return FALSE;
  }
  
@@@ -3712,40 -3690,6 +3712,40 @@@ xg_create_tool_bar (f
    SET_FRAME_GARBAGED (f);
  }
  
 +/* Find the right-to-left image named by RTL in the tool bar images for F.
 +   Returns IMAGE if RTL is not found.  */
 +
 +static Lisp_Object
 +find_rtl_image (f, image, rtl)
 +     FRAME_PTR f;
 +     Lisp_Object image;
 +     Lisp_Object rtl;
 +{
 +  int i;
 +  Lisp_Object file, rtl_name;
 +  struct gcpro gcpro1, gcpro2;
 +  GCPRO2 (file, rtl_name);
 +
 +  rtl_name = Ffile_name_nondirectory (rtl);
 +
 +  for (i = 0; i < f->n_tool_bar_items; ++i)
 +    {
 +      Lisp_Object rtl_image = PROP (TOOL_BAR_ITEM_IMAGES);
 +      if (!NILP (file = file_for_image (rtl_image))) 
 +        {
 +          file = call1 (intern ("file-name-sans-extension"),
 +                       Ffile_name_nondirectory (file));
 +          if (EQ (Fequal (file, rtl_name), Qt))
 +            {
 +              image = rtl_image;
 +              break;
 +            }
 +        }
 +    }
 +
 +  return image;
 +}
 +
  /* Update the tool bar for frame F.  Add new buttons and remove old.  */
  
  void
@@@ -3756,9 -3700,7 +3756,9 @@@ update_frame_tool_bar (f
    GtkRequisition old_req, new_req;
    struct x_output *x = f->output_data.x;
    int hmargin = 0, vmargin = 0;
 +  GtkToolbar *wtoolbar;
    GtkToolItem *ti;
 +  GtkTextDirection dir;
  
    if (! FRAME_GTK_WIDGET (f))
      return;
    if (! x->toolbar_widget)
      xg_create_tool_bar (f);
  
 -  gtk_widget_size_request (x->toolbar_widget, &old_req);
 +  wtoolbar = GTK_TOOLBAR (x->toolbar_widget);
 +  gtk_widget_size_request (GTK_WIDGET (wtoolbar), &old_req);
 +  dir = gtk_widget_get_direction (x->toolbar_widget);
  
    for (i = 0; i < f->n_tool_bar_items; ++i)
      {
 -#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
  
        int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
        int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
        int idx;
        int img_id;
 -      struct image *img;
 +      int icon_size = 0;
 +      struct image *img = NULL;
        Lisp_Object image;
 +      Lisp_Object stock;
 +      GtkStockItem stock_item;
 +      char *stock_name = NULL;
 +      Lisp_Object rtl;
        GtkWidget *wbutton;
        GtkWidget *weventbox;
 +      Lisp_Object func = intern ("x-gtk-map-stock");
  
        ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (x->toolbar_widget), i);
  
            wbutton = gtk_bin_get_child (GTK_BIN (weventbox));
          }
  
 -      /* If image is a vector, choose the image according to the
 -       button state.  */
        image = PROP (TOOL_BAR_ITEM_IMAGES);
 -      if (VECTORP (image))
 -      {
 -        if (enabled_p)
 -          idx = (selected_p
 -                 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
 -                 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
 -        else
 -          idx = (selected_p
 -                 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
 -                 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
 -
 -        xassert (ASIZE (image) >= idx);
 -        image = AREF (image, idx);
 -      }
 -      else
 -      idx = -1;
  
        /* Ignore invalid image specifications.  */
        if (!valid_image_p (image))
          {
 -          if (ti) gtk_widget_hide_all (GTK_WIDGET (ti));
 +          if (wbutton) gtk_widget_hide (wbutton);
            continue;
          }
  
 -      img_id = lookup_image (f, image);
 -      img = IMAGE_FROM_ID (f, img_id);
 -      prepare_image_for_display (f, img);
 +      if (EQ (Qt, Ffboundp (func))) 
 +        stock = call1 (func, file_for_image (image));
  
 -      if (img->load_failed_p || img->pixmap == None)
 +      if (! NILP (stock) && STRINGP (stock)
 +          && gtk_stock_lookup (SSDATA (stock), &stock_item))
 +        {
 +          stock_name = SSDATA (stock);
 +          icon_size = gtk_toolbar_get_icon_size (wtoolbar);
 +        }
 +      else
          {
 -          if (ti)
 -          gtk_widget_hide_all (GTK_WIDGET (ti));
 -        else
 +          /* No stock image, or stock item not known.  Try regular image.  */
 +
 +          /* If image is a vector, choose the image according to the
 +             button state.  */
 +          if (dir == GTK_TEXT_DIR_RTL
 +              && !NILP (rtl = PROP (TOOL_BAR_ITEM_RTL_IMAGE))
 +              && STRINGP (rtl))
              {
 -              /* Insert an empty (non-image) button */
 -              weventbox = gtk_event_box_new ();
 -              wbutton = gtk_button_new ();
 -              gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE);
 -              gtk_button_set_relief (GTK_BUTTON (wbutton), GTK_RELIEF_NONE);
 -              gtk_container_add (GTK_CONTAINER (weventbox), wbutton);
 -              ti = gtk_tool_item_new ();
 -              gtk_container_add (GTK_CONTAINER (ti), weventbox);
 -              gtk_toolbar_insert (GTK_TOOLBAR (x->toolbar_widget), ti, -1);
 +              image = find_rtl_image (f, image, rtl);
 +            }
 +
 +          if (VECTORP (image))
 +            {
 +              if (enabled_p)
 +                idx = (selected_p
 +                       ? TOOL_BAR_IMAGE_ENABLED_SELECTED
 +                       : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
 +              else
 +                idx = (selected_p
 +                       ? TOOL_BAR_IMAGE_DISABLED_SELECTED
 +                       : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
 +
 +              xassert (ASIZE (image) >= idx);
 +              image = AREF (image, idx);
 +            }
 +          else
 +            idx = -1;
 +
 +          img_id = lookup_image (f, image);
 +          img = IMAGE_FROM_ID (f, img_id);
 +          prepare_image_for_display (f, img);
 +      
 +          if (img->load_failed_p || img->pixmap == None)
 +            {
 +                if (ti)
 +                    gtk_widget_hide_all (GTK_WIDGET (ti));
 +                else
 +                {
 +                    /* Insert an empty (non-image) button */
 +                    weventbox = gtk_event_box_new ();
 +                    wbutton = gtk_button_new ();
 +                    gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE);
 +                    gtk_button_set_relief (GTK_BUTTON (wbutton),
 +                                           GTK_RELIEF_NONE);
 +                    gtk_container_add (GTK_CONTAINER (weventbox), wbutton);
 +                    ti = gtk_tool_item_new ();
 +                    gtk_container_add (GTK_CONTAINER (ti), weventbox);
 +                    gtk_toolbar_insert (GTK_TOOLBAR (x->toolbar_widget), ti, -1);
 +                }
 +                continue;
              }
 -          continue;
          }
  
        if (ti == NULL)
          {
 -          GtkWidget *w = xg_get_image_for_pixmap (f, img, x->widget, NULL);
 +          GtkWidget *w;
 +          if (stock_name)
 +            {
 +              w = gtk_image_new_from_stock (stock_name, icon_size);
 +              g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_STOCK_NAME,
 +                                      (gpointer) xstrdup (stock_name),
 +                                      (GDestroyNotify) xfree);
 +            }
 +          else
 +            {
 +              w = xg_get_image_for_pixmap (f, img, x->widget, NULL);
 +              /* Save the image so we can see if an update is needed when
 +                 this function is called again.  */
 +              g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA,
 +                                 (gpointer)img->pixmap);
 +            }
 +
            gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
            wbutton = gtk_button_new ();
            gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE);
  
            gtk_widget_show_all (GTK_WIDGET (ti));
  
 -          /* Save the image so we can see if an update is needed when
 -             this function is called again.  */
 -          g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA,
 -                             (gpointer)img->pixmap);
  
            g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f);
  
            GtkWidget *wimage = gtk_bin_get_child (GTK_BIN (wbutton));
            Pixmap old_img = (Pixmap)g_object_get_data (G_OBJECT (wimage),
                                                        XG_TOOL_BAR_IMAGE_DATA);
 -          gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin);
 +          gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage),
 +                                                       XG_TOOL_BAR_STOCK_NAME);
 +          if (stock_name &&
 +              (! old_stock_name || strcmp (old_stock_name, stock_name) != 0))
 +            {
 +              gtk_image_set_from_stock (GTK_IMAGE (wimage),
 +                                        stock_name, icon_size);
 +              g_object_set_data_full (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
 +                                      (gpointer) xstrdup (stock_name),
 +                                      (GDestroyNotify) xfree);
 +              g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
 +                                 NULL);
 +            }
 +          else if (img && old_img != img->pixmap)
 +            {
 +              (void) xg_get_image_for_pixmap (f, img, x->widget, wimage);
 +              g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
 +                                 (gpointer)img->pixmap);
  
 -          if (old_img != img->pixmap)
 -            (void) xg_get_image_for_pixmap (f, img, x->widget, wimage);
 +              g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
 +                                 NULL);
 +            }
  
 -          g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
 -                             (gpointer)img->pixmap);
 +          gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin);
  
            gtk_widget_set_sensitive (wbutton, enabled_p);
            gtk_widget_show_all (GTK_WIDGET (ti));
        if (ti) gtk_widget_hide_all (GTK_WIDGET (ti));
      } while (ti != NULL);
  
 -  gtk_widget_size_request (x->toolbar_widget, &new_req);
 +  gtk_widget_size_request (GTK_WIDGET (wtoolbar), &new_req);
    if (old_req.height != new_req.height
        && ! FRAME_X_OUTPUT (f)->toolbar_detached)
      {
diff --combined src/keyboard.c
index adbbbcf85ddf00bcb8299c4bb16b2d41cf057c11,626748b6c1259e98038799e9f3c25a51c7f15ed9..95a4aecfe395916392af650a62a4d3e81a92917e
@@@ -23,13 -23,13 +23,13 @@@ Boston, MA 02110-1301, USA.  *
  #include <config.h>
  #include <signal.h>
  #include <stdio.h>
+ #include "lisp.h"
  #include "termchar.h"
  #include "termopts.h"
- #include "lisp.h"
+ #include "frame.h"
  #include "termhooks.h"
  #include "macros.h"
  #include "keyboard.h"
- #include "frame.h"
  #include "window.h"
  #include "commands.h"
  #include "buffer.h"
@@@ -59,7 -59,6 +59,6 @@@
  #endif /* not MSDOS */
  
  #include "syssignal.h"
- #include "systty.h"
  
  #include <sys/types.h>
  #ifdef HAVE_UNISTD_H
@@@ -97,9 -96,6 +96,6 @@@ volatile int interrupt_input_blocked
  int interrupt_input_pending;
  
  
- /* File descriptor to use for input.  */
- extern int input_fd;
  #ifdef HAVE_WINDOW_SYSTEM
  /* Make all keyboard buffers much bigger when using X windows.  */
  #ifdef MAC_OS8
@@@ -425,16 -421,6 +421,6 @@@ Lisp_Object Vecho_keystrokes
  /* Form to evaluate (if non-nil) when Emacs is started.  */
  Lisp_Object Vtop_level;
  
- /* User-supplied table to translate input characters.  */
- Lisp_Object Vkeyboard_translate_table;
- /* Keymap mapping ASCII function key sequences onto their preferred forms.  */
- extern Lisp_Object Vfunction_key_map;
- /* Another keymap that maps key sequences into key sequences.
-    This one takes precedence over ordinary definitions.  */
- extern Lisp_Object Vkey_translation_map;
  /* If non-nil, this implements the current input method.  */
  Lisp_Object Vinput_method_function;
  Lisp_Object Qinput_method_function;
@@@ -458,6 -444,12 +444,12 @@@ Lisp_Object Qpre_command_hook, Vpre_com
  Lisp_Object Qpost_command_hook, Vpost_command_hook;
  Lisp_Object Qcommand_hook_internal, Vcommand_hook_internal;
  
+ /* Parent keymap of terminal-local function-key-map instances.  */
+ Lisp_Object Vfunction_key_map;
+ /* Parent keymap of terminal-local key-translation-map instances.  */
+ Lisp_Object Vkey_translation_map;
  /* List of deferred actions to be performed at a later time.
     The precise format isn't relevant here; we just check whether it is nil.  */
  Lisp_Object Vdeferred_action_list;
@@@ -475,11 -467,6 +467,6 @@@ FILE *dribble
  /* Nonzero if input is available.  */
  int input_pending;
  
- /* 1 if should obey 0200 bit in input chars as "Meta", 2 if should
-    keep 0200 bit in input chars.  0 to ignore the 0200 bit.  */
- int meta_key;
  extern char *pending_malloc_warning;
  
  /* Circular buffer for pre-read keyboard input.  */
@@@ -609,9 -596,6 +596,6 @@@ int interrupt_input
  /* Nonzero while interrupts are temporarily deferred during redisplay.  */
  int interrupts_deferred;
  
- /* Nonzero means use ^S/^Q for flow control.  */
- int flow_control;
  /* Allow m- file to inhibit use of FIONREAD.  */
  #ifdef BROKEN_FIONREAD
  #undef FIONREAD
@@@ -694,8 -678,11 +678,11 @@@ static void save_getcjmp ()
  static void restore_getcjmp P_ ((jmp_buf));
  static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));
  static void clear_event P_ ((struct input_event *));
- static void any_kboard_state P_ ((void));
+ #ifdef MULTI_KBOARD
+ static Lisp_Object restore_kboard_configuration P_ ((Lisp_Object));
+ #endif
  static SIGTYPE interrupt_signal P_ ((int signalnum));
+ static void handle_interrupt P_ ((void));
  static void timer_start_idle P_ ((void));
  static void timer_stop_idle P_ ((void));
  static void timer_resume_idle P_ ((void));
@@@ -1061,24 -1048,20 +1048,20 @@@ This function is called by the editor i
       like it is done in the splash screen display, we have to
       make sure that we restore single_kboard as command_loop_1
       would have done if it were left normally.  */
-   record_unwind_protect (recursive_edit_unwind,
-                        Fcons (buffer, single_kboard ? Qt : Qnil));
+   if (command_loop_level > 0)
+     temporarily_switch_to_single_kboard (SELECTED_FRAME ());
+   record_unwind_protect (recursive_edit_unwind, buffer);
  
    recursive_edit_1 ();
    return unbind_to (count, Qnil);
  }
  
  Lisp_Object
- recursive_edit_unwind (info)
-      Lisp_Object info;
+ recursive_edit_unwind (buffer)
+      Lisp_Object buffer;
  {
-   if (BUFFERP (XCAR (info)))
-     Fset_buffer (XCAR (info));
-   if (NILP (XCDR (info)))
-     any_kboard_state ();
-   else
-     single_kboard_state ();
+   if (BUFFERP (buffer))
+     Fset_buffer (buffer);
  
    command_loop_level--;
    update_mode_lines = 1;
  }
  
  \f
+ #if 0  /* These two functions are now replaced with
+           temporarily_switch_to_single_kboard. */
  static void
  any_kboard_state ()
  {
@@@ -1116,6 -1101,7 +1101,7 @@@ single_kboard_state (
    single_kboard = 1;
  #endif
  }
+ #endif
  
  /* If we're in single_kboard state for kboard KBOARD,
     get out of it.  */
@@@ -1143,8 -1129,8 +1129,8 @@@ struct kboard_stac
  static struct kboard_stack *kboard_stack;
  
  void
- push_frame_kboard (f)
-      FRAME_PTR f;
+ push_kboard (k)
+      struct kboard *k;
  {
  #ifdef MULTI_KBOARD
    struct kboard_stack *p
    p->kboard = current_kboard;
    kboard_stack = p;
  
-   current_kboard = FRAME_KBOARD (f);
+   current_kboard = k;
  #endif
  }
  
  void
- pop_frame_kboard ()
+ pop_kboard ()
  {
  #ifdef MULTI_KBOARD
+   struct terminal *t;
    struct kboard_stack *p = kboard_stack;
-   current_kboard = p->kboard;
+   int found = 0;
+   for (t = terminal_list; t; t = t->next_terminal)
+     {
+       if (t->kboard == p->kboard)
+         {
+           current_kboard = p->kboard;
+           found = 1;
+           break;
+         }
+     }
+   if (!found)
+     {
+       /* The terminal we remembered has been deleted.  */
+       current_kboard = FRAME_KBOARD (SELECTED_FRAME ());
+       single_kboard = 0;
+     }
    kboard_stack = p->next;
    xfree (p);
  #endif
  }
+ /* Switch to single_kboard mode, making current_kboard the only KBOARD
+   from which further input is accepted.  If F is non-nil, set its
+   KBOARD as the current keyboard.
+   This function uses record_unwind_protect to return to the previous
+   state later.
+   If Emacs is already in single_kboard mode, and F's keyboard is
+   locked, then this function will throw an errow.  */
+ void
+ temporarily_switch_to_single_kboard (f)
+      struct frame *f;
+ {
+ #ifdef MULTI_KBOARD
+   int was_locked = single_kboard;
+   if (was_locked)
+     {
+       if (f != NULL && FRAME_KBOARD (f) != current_kboard)
+         /* We can not switch keyboards while in single_kboard mode.
+            In rare cases, Lisp code may call `recursive-edit' (or
+            `read-minibuffer' or `y-or-n-p') after it switched to a
+            locked frame.  For example, this is likely to happen
+            when server.el connects to a new terminal while Emacs is in
+            single_kboard mode.  It is best to throw an error instead
+            of presenting the user with a frozen screen.  */
+         error ("Terminal %d is locked, cannot read from it",
+                FRAME_TERMINAL (f)->id);
+       else
+         /* This call is unnecessary, but helps
+            `restore_kboard_configuration' discover if somebody changed
+            `current_kboard' behind our back.  */
+         push_kboard (current_kboard);
+     }
+   else if (f != NULL)
+     current_kboard = FRAME_KBOARD (f);
+   single_kboard = 1;
+   record_unwind_protect (restore_kboard_configuration,
+                          (was_locked ? Qt : Qnil));
+ #endif
+ }
+ #if 0 /* This function is not needed anymore.  */
+ void
+ record_single_kboard_state ()
+ {
+   if (single_kboard)
+     push_kboard (current_kboard);
+   record_unwind_protect (restore_kboard_configuration,
+                          (single_kboard ? Qt : Qnil));
+ }
+ #endif
+ #ifdef MULTI_KBOARD
+ static Lisp_Object
+ restore_kboard_configuration (was_locked)
+      Lisp_Object was_locked;
+ {
+   if (NILP (was_locked))
+     single_kboard = 0;
+   else
+     {
+       struct kboard *prev = current_kboard;
+       single_kboard = 1;
+       pop_kboard ();
+       /* The pop should not change the kboard.  */
+       if (single_kboard && current_kboard != prev)
+         abort ();
+     }
+   return Qnil;
+ }
+ #endif
  \f
  /* Handle errors that are not handled at inner levels
     by printing an error message and returning to the editor command loop.  */
@@@ -1215,9 -1291,11 +1291,11 @@@ cmd_error (data
    Vquit_flag = Qnil;
  
    Vinhibit_quit = Qnil;
+ #if 0 /* This shouldn't be necessary anymore. --lorentey */
  #ifdef MULTI_KBOARD
    if (command_loop_level == 0 && minibuf_level == 0)
      any_kboard_state ();
+ #endif
  #endif
  
    return make_number (0);
@@@ -1254,11 -1332,7 +1332,7 @@@ cmd_error_internal (data, context
    /* If the window system or terminal frame hasn't been initialized
       yet, or we're not interactive, write the message to stderr and exit.  */
    else if (!sf->glyphs_initialized_p
-          /* This is the case of the frame dumped with Emacs, when we're
-             running under a window system.  */
-          || (!NILP (Vwindow_system)
-              && !inhibit_window_system
-              && FRAME_TERMCAP_P (sf))
+          || FRAME_INITIAL_P (sf)
           || noninteractive)
      {
        print_error_message (data, Qexternal_debugging_output,
@@@ -1301,10 -1375,12 +1375,12 @@@ command_loop (
      while (1)
        {
        internal_catch (Qtop_level, top_level_1, Qnil);
-       /* Reset single_kboard in case top-level set it while
-          evaluating an -f option, or we are stuck there for some
-          other reason.  */
-       any_kboard_state ();
+ #if 0 /* This shouldn't be necessary anymore.  --lorentey  */
+         /* Reset single_kboard in case top-level set it while
+            evaluating an -f option, or we are stuck there for some
+            other reason. */
+         any_kboard_state ();
+ #endif
        internal_catch (Qtop_level, command_loop_2, Qnil);
        executing_kbd_macro = Qnil;
  
@@@ -1499,10 -1575,12 +1575,12 @@@ command_loop_1 (
    int no_direct;
    int prev_modiff = 0;
    struct buffer *prev_buffer = NULL;
+ #if 0 /* This shouldn't be necessary anymore.  --lorentey  */
  #ifdef MULTI_KBOARD
    int was_locked = single_kboard;
  #endif
-   int already_adjusted;
+ #endif  
+   int already_adjusted = 0;
  
    current_kboard->Vprefix_arg = Qnil;
    current_kboard->Vlast_prefix_arg = Qnil;
        if (!NILP (current_kboard->defining_kbd_macro)
          && NILP (current_kboard->Vprefix_arg))
        finalize_kbd_macro_chars ();
+ #if 0 /* This shouldn't be necessary anymore.  --lorentey  */
  #ifdef MULTI_KBOARD
        if (!was_locked)
-       any_kboard_state ();
+         any_kboard_state ();
+ #endif
  #endif
      }
  }
  start_polling ()
  {
  #ifdef POLL_FOR_INPUT
-   if (read_socket_hook && !interrupt_input)
+   /* XXX This condition was (read_socket_hook && !interrupt_input),
+      but read_socket_hook is not global anymore.  Let's pretend that
+      it's always set. */
+   if (!interrupt_input)
      {
        /* Turn alarm handling on unconditionally.  It might have
         been turned off in process.c.  */
  input_polling_used ()
  {
  #ifdef POLL_FOR_INPUT
-   return read_socket_hook && !interrupt_input;
+   /* XXX This condition was (read_socket_hook && !interrupt_input),
+      but read_socket_hook is not global anymore.  Let's pretend that
+      it's always set. */
+   return !interrupt_input;
  #else
    return 0;
  #endif
  stop_polling ()
  {
  #ifdef POLL_FOR_INPUT
-   if (read_socket_hook && !interrupt_input)
+   /* XXX This condition was (read_socket_hook && !interrupt_input),
+      but read_socket_hook is not global anymore.  Let's pretend that
+      it's always set. */
+   if (!interrupt_input)
      ++poll_suppress_count;
  #endif
  }
@@@ -2461,10 -2549,6 +2549,6 @@@ read_char_help_form_unwind (arg
    return Qnil;
  }
  
- #ifdef MULTI_KBOARD
- static jmp_buf wrong_kboard_jmpbuf;
- #endif
  #define STOP_POLLING                                  \
  do { if (! polling_stopped_here) stop_polling ();     \
         polling_stopped_here = 1; } while (0)
@@@ -2491,6 -2575,9 +2575,9 @@@ do { if (polling_stopped_here) start_po
     if we used a mouse menu to read the input, or zero otherwise.  If
     USED_MOUSE_MENU is null, we don't dereference it.
  
+    Value is -2 when we find input on another keyboard.  A second call
+    to read_char will read it. 
     If END_TIME is non-null, it is a pointer to an EMACS_TIME
     specifying the maximum time to wait until.  If no input arrives by
     that time, stop waiting and return nil.
@@@ -2517,6 -2604,7 +2604,7 @@@ read_char (commandflag, nmaps, maps, pr
    volatile int reread;
    struct gcpro gcpro1, gcpro2;
    int polling_stopped_here = 0;
+   struct kboard *orig_kboard = current_kboard;
  
    also_record = Qnil;
  
        && !detect_input_pending_run_timers (0))
      {
        c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps);
+       if (INTEGERP (c) && XINT (c) == -2)
+         return c;               /* wrong_kboard_jmpbuf */
        if (! NILP (c))
        {
          key_already_recorded = 1;
    jmpcount = SPECPDL_INDEX ();
    if (_setjmp (local_getcjmp))
      {
+       /* Handle quits while reading the keyboard.  */
        /* We must have saved the outer value of getcjmp here,
         so restore it now.  */
        restore_getcjmp (save_jump);
            /* This is going to exit from read_char
               so we had better get rid of this frame's stuff.  */
            UNGCPRO;
-           longjmp (wrong_kboard_jmpbuf, 1);
+             return make_number (-2); /* wrong_kboard_jmpbuf */
          }
        }
  #endif
        }
      }
  
+   /* Notify the caller if an autosave hook, or a timer, sentinel or
+      filter in the sit_for calls above have changed the current
+      kboard.  This could happen if they use the minibuffer or start a
+      recursive edit, like the fancy splash screen in server.el's
+      filter.  If this longjmp wasn't here, read_key_sequence would
+      interpret the next key sequence using the wrong translation
+      tables and function keymaps.  */
+   if (NILP (c) && current_kboard != orig_kboard)
+     {
+       UNGCPRO;
+       return make_number (-2);  /* wrong_kboard_jmpbuf */
+     }
    /* If this has become non-nil here, it has been set by a timer
       or sentinel or filter.  */
    if (CONSP (Vunread_command_events))
            /* This is going to exit from read_char
               so we had better get rid of this frame's stuff.  */
            UNGCPRO;
-           longjmp (wrong_kboard_jmpbuf, 1);
+             return make_number (-2); /* wrong_kboard_jmpbuf */
          }
      }
  #endif
          /* This is going to exit from read_char
             so we had better get rid of this frame's stuff.  */
          UNGCPRO;
-         longjmp (wrong_kboard_jmpbuf, 1);
+           return make_number (-2);
        }
  #endif
      }
  
    if (!NILP (tem))
      {
+ #if 0 /* This shouldn't be necessary anymore. --lorentey  */
        int was_locked = single_kboard;
+       int count = SPECPDL_INDEX ();
+       record_single_kboard_state ();
+ #endif
+       
        last_input_char = c;
        Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt);
  
           example banishing the mouse under mouse-avoidance-mode.  */
        timer_resume_idle ();
  
+ #if 0 /* This shouldn't be necessary anymore. --lorentey  */
        /* Resume allowing input from any kboard, if that was true before.  */
        if (!was_locked)
        any_kboard_state ();
+       unbind_to (count, Qnil);
+ #endif
  
        goto retry;
      }
        if (XINT (c) == -1)
        goto exit;
  
-       if ((STRINGP (Vkeyboard_translate_table)
-          && SCHARS (Vkeyboard_translate_table) > (unsigned) XFASTINT (c))
-         || (VECTORP (Vkeyboard_translate_table)
-             && XVECTOR (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
-         || (CHAR_TABLE_P (Vkeyboard_translate_table)
+       if ((STRINGP (current_kboard->Vkeyboard_translate_table)
+          && SCHARS (current_kboard->Vkeyboard_translate_table) > (unsigned) XFASTINT (c))
+         || (VECTORP (current_kboard->Vkeyboard_translate_table)
+             && XVECTOR (current_kboard->Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
+         || (CHAR_TABLE_P (current_kboard->Vkeyboard_translate_table)
              && CHAR_VALID_P (XINT (c), 0)))
        {
          Lisp_Object d;
-         d = Faref (Vkeyboard_translate_table, c);
+         d = Faref (current_kboard->Vkeyboard_translate_table, c);
          /* nil in keyboard-translate-table means no translation.  */
          if (!NILP (d))
            c = d;
@@@ -3734,12 -3847,10 +3847,10 @@@ kbd_buffer_store_event_hold (event, hol
        if (c == quit_char)
        {
  #ifdef MULTI_KBOARD
-         KBOARD *kb;
+         KBOARD *kb = FRAME_KBOARD (XFRAME (event->frame_or_window));
          struct input_event *sp;
  
-         if (single_kboard
-             && (kb = FRAME_KBOARD (XFRAME (event->frame_or_window)),
-                 kb != current_kboard))
+         if (single_kboard && kb != current_kboard)
            {
              kb->kbd_queue
                = Fcons (make_lispy_switch_frame (event->frame_or_window),
          }
  
          last_event_timestamp = event->timestamp;
-         interrupt_signal (0 /* dummy */);
+         handle_interrupt ();
          return;
        }
  
@@@ -4264,11 -4375,15 +4375,15 @@@ kbd_buffer_get_event (kbp, used_mouse_m
        unsigned long time;
  
        *kbp = current_kboard;
-       /* Note that this uses F to determine which display to look at.
+       /* Note that this uses F to determine which terminal to look at.
         If there is no valid info, it does not store anything
         so x remains nil.  */
        x = Qnil;
-       (*mouse_position_hook) (&f, 0, &bar_window, &part, &x, &y, &time);
+       /* XXX Can f or mouse_position_hook be NULL here? */
+       if (f && FRAME_TERMINAL (f)->mouse_position_hook)
+         (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, 0, &bar_window,
+                                                     &part, &x, &y, &time);
  
        obj = Qnil;
  
@@@ -4565,10 -4680,14 +4680,14 @@@ timer_check (do_it_now
        {
          if (NILP (vector[0]))
            {
-             int was_locked = single_kboard;
              int count = SPECPDL_INDEX ();
              Lisp_Object old_deactivate_mark = Vdeactivate_mark;
  
+ #if 0 /* This shouldn't be necessary anymore.  --lorentey  */
+             /* On unbind_to, resume allowing input from any kboard, if that
+                  was true before.  */
+               record_single_kboard_state ();
+ #endif
              /* Mark the timer as triggered to prevent problems if the lisp
                 code fails to reschedule it right.  */
              vector[0] = Qt;
              timers_run++;
              unbind_to (count, Qnil);
  
-             /* Resume allowing input from any kboard, if that was true before.  */
-             if (!was_locked)
-               any_kboard_state ();
              /* Since we have handled the event,
                 we don't need to tell the caller to wake up and do it.  */
            }
@@@ -6544,8 -6659,8 +6659,8 @@@ modify_event_symbol (symbol_num, modifi
        {
          int len = SBYTES (name_alist_or_stem);
          char *buf = (char *) alloca (len + 50);
-         sprintf (buf, "%s-%ld", SDATA (name_alist_or_stem),
-                  (long) XINT (symbol_int) + 1);
+           sprintf (buf, "%s-%ld", SDATA (name_alist_or_stem),
+                    (long) XINT (symbol_int) + 1);
          value = intern (buf);
        }
        else if (name_table != 0 && name_table[symbol_num])
@@@ -6810,7 -6925,10 +6925,10 @@@ gobble_input (expected
      }
    else
  #ifdef POLL_FOR_INPUT
-   if (read_socket_hook && !interrupt_input && poll_suppress_count == 0)
+   /* XXX This condition was (read_socket_hook && !interrupt_input),
+      but read_socket_hook is not global anymore.  Let's pretend that
+      it's always set. */
+   if (!interrupt_input && poll_suppress_count == 0)
      {
        SIGMASKTYPE mask;
        mask = sigblock (sigmask (SIGALRM));
@@@ -6887,170 -7005,241 +7005,241 @@@ static in
  read_avail_input (expected)
       int expected;
  {
-   register int i;
    int nread = 0;
+   int err = 0;
+   struct terminal *t;
  
    /* Store pending user signal events, if any.  */
    if (store_user_signal_events ())
      expected = 0;
  
-   if (read_socket_hook)
+   /* Loop through the available terminals, and call their input hooks. */
+   t = terminal_list;
+   while (t)
      {
-       int nr;
-       struct input_event hold_quit;
+       struct terminal *next = t->next_terminal;
  
-       EVENT_INIT (hold_quit);
-       hold_quit.kind = NO_EVENT;
+       if (t->read_socket_hook)
+         {
+           int nr;
+           struct input_event hold_quit;
+           EVENT_INIT (hold_quit);
+           hold_quit.kind = NO_EVENT;
+           /* No need for FIONREAD or fcntl; just say don't wait.  */
+           while (nr = (*t->read_socket_hook) (t, expected, &hold_quit), nr > 0)
+             {
+               nread += nr;
+               expected = 0;
+             }
+           
+           if (nr == -1)          /* Not OK to read input now. */
+             {
+               err = 1;
+             }
+           else if (nr == -2)          /* Non-transient error. */
+             {
+               /* The terminal device terminated; it should be closed. */
+               
+               /* Kill Emacs if this was our last terminal. */
+               if (!terminal_list->next_terminal)
+                 /* Formerly simply reported no input, but that
+                    sometimes led to a failure of Emacs to terminate.
+                    SIGHUP seems appropriate if we can't reach the
+                    terminal.  */
+                 /* ??? Is it really right to send the signal just to
+                    this process rather than to the whole process
+                    group?  Perhaps on systems with FIONREAD Emacs is
+                    alone in its group.  */
+                 kill (getpid (), SIGHUP);
+               
+               /* XXX Is calling delete_terminal safe here?  It calls Fdelete_frame. */
+               if (t->delete_terminal_hook)
+                 (*t->delete_terminal_hook) (t);
+               else
+                 delete_terminal (t);
+             }
+           if (hold_quit.kind != NO_EVENT)
+             kbd_buffer_store_event (&hold_quit);
+         }
  
-       /* No need for FIONREAD or fcntl; just say don't wait.  */
-       while (nr = (*read_socket_hook) (input_fd, expected, &hold_quit), nr > 0)
-       {
-         nread += nr;
-         expected = 0;
-       }
-       if (hold_quit.kind != NO_EVENT)
-       kbd_buffer_store_event (&hold_quit);
+       t = next;
      }
-   else
-     {
-       /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
-        the kbd_buffer can really hold.  That may prevent loss
-        of characters on some systems when input is stuffed at us.  */
-       unsigned char cbuf[KBD_BUFFER_SIZE - 1];
-       int n_to_read;
  
-       /* Determine how many characters we should *try* to read.  */
+   if (err && !nread)
+     nread = -1;
+   return nread;
+ }
+ /* This is the tty way of reading available input.
+    Note that each terminal device has its own `struct terminal' object,
+    and so this function is called once for each individual termcap
+    terminal.  The first parameter indicates which terminal to read from.  */
+ int
+ tty_read_avail_input (struct terminal *terminal,
+                       int expected,
+                       struct input_event *hold_quit)
+ {
+   /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
+      the kbd_buffer can really hold.  That may prevent loss
+      of characters on some systems when input is stuffed at us.  */
+   unsigned char cbuf[KBD_BUFFER_SIZE - 1];
+   int n_to_read, i;
+   struct tty_display_info *tty = terminal->display_info.tty;
+   int nread = 0;
+   if (terminal->deleted)        /* Don't read from a deleted terminal. */
+     return;
+   if (terminal->type != output_termcap)
+     abort ();
+   /* XXX I think the following code should be moved to separate hook
+      functions in system-dependent files. */
  #ifdef WINDOWSNT
-       return 0;
+   return 0;
  #else /* not WINDOWSNT */
  #ifdef MSDOS
-       n_to_read = dos_keysns ();
-       if (n_to_read == 0)
-       return 0;
+   n_to_read = dos_keysns ();
+   if (n_to_read == 0)
+     return 0;
+   cbuf[0] = dos_keyread ();
+   nread = 1;
  #else /* not MSDOS */
+   if (! tty->term_initted)      /* In case we get called during bootstrap. */
+     return 0;
+   if (! tty->input)
+     return 0;                   /* The terminal is suspended. */
  #ifdef HAVE_GPM
-       if (term_gpm)
-       {
-         Gpm_Event event;
-         struct input_event hold_quit;
-         int gpm;
+   if (term_gpm && gpm_tty == tty->terminal->id)
+   {
+       Gpm_Event event;
+       struct input_event hold_quit;
+       int gpm;
  
-         EVENT_INIT (hold_quit);
-         hold_quit.kind = NO_EVENT;
+       EVENT_INIT (hold_quit);
+       hold_quit.kind = NO_EVENT;
  
-         while (gpm = Gpm_GetEvent (&event), gpm == 1) {
-           nread += handle_one_term_event (&event, &hold_quit);
-         }
-         if (hold_quit.kind != NO_EVENT)
-           kbd_buffer_store_event (&hold_quit);
-         if (nread)
-           return nread;
-       }
+       while (gpm = Gpm_GetEvent (&event), gpm == 1) {
+         nread += handle_one_term_event (tty, &event, &hold_quit);
+       }
+       if (hold_quit.kind != NO_EVENT)
+         kbd_buffer_store_event (&hold_quit);
+       if (nread)
+         return nread;
+   }
  #endif /* HAVE_GPM */
- #ifdef FIONREAD
  
-      /* Find out how much input is available.  */
-       if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
-       /* Formerly simply reported no input, but that sometimes led to
-          a failure of Emacs to terminate.
-          SIGHUP seems appropriate if we can't reach the terminal.  */
-       /* ??? Is it really right to send the signal just to this process
-          rather than to the whole process group?
-          Perhaps on systems with FIONREAD Emacs is alone in its group.  */
-       {
-         if (! noninteractive)
-           kill (getpid (), SIGHUP);
-         else
-           n_to_read = 0;
-       }
-       if (n_to_read == 0)
-       return 0;
-       if (n_to_read > sizeof cbuf)
-       n_to_read = sizeof cbuf;
+ /* Determine how many characters we should *try* to read.  */
+ #ifdef FIONREAD
+   /* Find out how much input is available.  */
+   if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
+     {
+       if (! noninteractive)
+         return -2;          /* Close this terminal. */
+       else
+         n_to_read = 0;
+     }
+   if (n_to_read == 0)
+     return 0;
+   if (n_to_read > sizeof cbuf)
+     n_to_read = sizeof cbuf;
  #else /* no FIONREAD */
  #if defined (USG) || defined (DGUX) || defined(CYGWIN)
-       /* Read some input if available, but don't wait.  */
-       n_to_read = sizeof cbuf;
-       fcntl (input_fd, F_SETFL, O_NDELAY);
+   /* Read some input if available, but don't wait.  */
+   n_to_read = sizeof cbuf;
+   fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
  #else
-       you lose;
+   you lose;
  #endif
  #endif
- #endif /* not MSDOS */
- #endif /* not WINDOWSNT */
  
-       /* Now read; for one reason or another, this will not block.
-        NREAD is set to the number of chars read.  */
-       do
-       {
- #ifdef MSDOS
-         cbuf[0] = dos_keyread ();
-         nread = 1;
- #else
-         nread = emacs_read (input_fd, cbuf, n_to_read);
- #endif
-         /* POSIX infers that processes which are not in the session leader's
-            process group won't get SIGHUP's at logout time.  BSDI adheres to
-            this part standard and returns -1 from read (0) with errno==EIO
-            when the control tty is taken away.
-            Jeffrey Honig <jch@bsdi.com> says this is generally safe.  */
-         if (nread == -1 && errno == EIO)
-           kill (0, SIGHUP);
+   /* Now read; for one reason or another, this will not block.
+      NREAD is set to the number of chars read.  */
+   do
+     {
+       nread = emacs_read (fileno (tty->input), cbuf, n_to_read);
+       /* POSIX infers that processes which are not in the session leader's
+          process group won't get SIGHUP's at logout time.  BSDI adheres to
+          this part standard and returns -1 from read (0) with errno==EIO
+          when the control tty is taken away.
+          Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
+       if (nread == -1 && errno == EIO)
+         return -2;          /* Close this terminal. */
  #if defined (AIX) && (! defined (aix386) && defined (_BSD))
-         /* The kernel sometimes fails to deliver SIGHUP for ptys.
-            This looks incorrect, but it isn't, because _BSD causes
-            O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
-            and that causes a value other than 0 when there is no input.  */
-         if (nread == 0)
-           kill (0, SIGHUP);
- #endif
-       }
-       while (
-            /* We used to retry the read if it was interrupted.
-               But this does the wrong thing when O_NDELAY causes
-               an EAGAIN error.  Does anybody know of a situation
-               where a retry is actually needed?  */
+       /* The kernel sometimes fails to deliver SIGHUP for ptys.
+          This looks incorrect, but it isn't, because _BSD causes
+          O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
+          and that causes a value other than 0 when there is no input.  */
+       if (nread == 0)
+         return -2;          /* Close this terminal. */
+ #endif
+     }
+   while (
+          /* We used to retry the read if it was interrupted.
+             But this does the wrong thing when O_NDELAY causes
+             an EAGAIN error.  Does anybody know of a situation
+             where a retry is actually needed?  */
  #if 0
-            nread < 0 && (errno == EAGAIN
+          nread < 0 && (errno == EAGAIN
  #ifdef EFAULT
-                          || errno == EFAULT
+                        || errno == EFAULT
  #endif
  #ifdef EBADSLT
-                          || errno == EBADSLT
+                        || errno == EBADSLT
  #endif
-                          )
+                        )
  #else
-            0
+          0
  #endif
-            );
+          );
  
  #ifndef FIONREAD
  #if defined (USG) || defined (DGUX) || defined (CYGWIN)
-       fcntl (input_fd, F_SETFL, 0);
+   fcntl (fileno (tty->input), F_SETFL, 0);
  #endif /* USG or DGUX or CYGWIN */
  #endif /* no FIONREAD */
-       for (i = 0; i < nread; i++)
-       {
-         struct input_event buf;
-         EVENT_INIT (buf);
-         buf.kind = ASCII_KEYSTROKE_EVENT;
-         buf.modifiers = 0;
-         if (meta_key == 1 && (cbuf[i] & 0x80))
-           buf.modifiers = meta_modifier;
-         if (meta_key != 2)
-           cbuf[i] &= ~0x80;
-         buf.code = cbuf[i];
-         buf.frame_or_window = selected_frame;
-         buf.arg = Qnil;
-         kbd_buffer_store_event (&buf);
-         /* Don't look at input that follows a C-g too closely.
-            This reduces lossage due to autorepeat on C-g.  */
-         if (buf.kind == ASCII_KEYSTROKE_EVENT
-             && buf.code == quit_char)
-           break;
-       }
+   if (nread <= 0)
+     return nread;
+ #endif /* not MSDOS */
+ #endif /* not WINDOWSNT */
+   for (i = 0; i < nread; i++)
+     {
+       struct input_event buf;
+       EVENT_INIT (buf);
+       buf.kind = ASCII_KEYSTROKE_EVENT;
+       buf.modifiers = 0;
+       if (tty->meta_key == 1 && (cbuf[i] & 0x80))
+         buf.modifiers = meta_modifier;
+       if (tty->meta_key != 2)
+         cbuf[i] &= ~0x80;
+       
+       buf.code = cbuf[i];
+       /* Set the frame corresponding to the active tty.  Note that the
+          value of selected_frame is not reliable here, redisplay tends
+          to temporarily change it. */
+       buf.frame_or_window = tty->top_frame;
+       buf.arg = Qnil;
+       
+       kbd_buffer_store_event (&buf);
+       /* Don't look at input that follows a C-g too closely.
+          This reduces lossage due to autorepeat on C-g.  */
+       if (buf.kind == ASCII_KEYSTROKE_EVENT
+           && buf.code == quit_char)
+         break;
      }
  
    return nread;
@@@ -7907,11 -8096,10 +8096,11 @@@ static Lisp_Object tool_bar_item_proper
  
  static int ntool_bar_items;
  
 -/* The symbols `tool-bar', and `:image'.  */
 +/* The symbols `tool-bar', `:image' and `:rtl'.  */
  
  extern Lisp_Object Qtool_bar;
  Lisp_Object QCimage;
 +Lisp_Object Qrtl;
  
  /* Function prototypes.  */
  
@@@ -8197,9 -8385,6 +8386,9 @@@ parse_tool_bar_item (key, item
        /* Value is either a single image specification or a vector
           of 4 such specifications for the different button states.  */
        PROP (TOOL_BAR_ITEM_IMAGES) = value;
 +      else if (EQ (key, Qrtl))
 +        /* ':rtl STRING' */
 +      PROP (TOOL_BAR_ITEM_RTL_IMAGE) = value;
      }
  
    /* If got a filter apply it on binding.  */
@@@ -8632,6 -8817,8 +8821,8 @@@ read_char_minibuf_menu_prompt (commandf
  
        if (!INTEGERP (obj))
        return obj;
+       else if (XINT (obj) == -2)
+         return obj;
        else
        ch = XINT (obj);
  
@@@ -8978,11 -9165,7 +9169,7 @@@ read_key_sequence (keybuf, bufsize, pro
    last_nonmenu_event = Qnil;
  
    delayed_switch_frame = Qnil;
-   fkey.map = fkey.parent = Vfunction_key_map;
-   keytran.map = keytran.parent = Vkey_translation_map;
-   fkey.start = fkey.end = 0;
-   keytran.start = keytran.end = 0;
+   
    if (INTERACTIVE)
      {
        if (!NILP (prompt))
       keybuf[0..mock_input] holds the sequence we should reread.  */
   replay_sequence:
  
+   /* We may switch keyboards between rescans, so we need to
+      reinitialize fkey and keytran before each replay.  */
+   fkey.map = fkey.parent = current_kboard->Vlocal_function_key_map;
+   keytran.map = keytran.parent = current_kboard->Vlocal_key_translation_map;
+   fkey.start = fkey.end = 0;
+   keytran.start = keytran.end = 0;
    starting_buffer = current_buffer;
    first_unbound = bufsize + 1;
  
  #ifdef MULTI_KBOARD
            KBOARD *interrupted_kboard = current_kboard;
            struct frame *interrupted_frame = SELECTED_FRAME ();
-           if (setjmp (wrong_kboard_jmpbuf))
+ #endif
+           key = read_char (NILP (prompt), nmaps,
+                            (Lisp_Object *) submaps, last_nonmenu_event,
+                            &used_mouse_menu, NULL);
+ #ifdef MULTI_KBOARD
+           if (INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
              {
+               int found = 0;
+               struct kboard *k;
+               for (k = all_kboards; k; k = k->next_kboard)
+                 if (k == interrupted_kboard)
+                   found = 1;
+               if (!found)
+                 {
+                   /* Don't touch interrupted_kboard when it's been
+                      deleted. */
+                   delayed_switch_frame = Qnil;
+                   goto replay_sequence;
+                 }
                if (!NILP (delayed_switch_frame))
                  {
                    interrupted_kboard->kbd_queue
                               interrupted_kboard->kbd_queue);
                    delayed_switch_frame = Qnil;
                  }
                while (t > 0)
                  interrupted_kboard->kbd_queue
                    = Fcons (keybuf[--t], interrupted_kboard->kbd_queue);
                goto replay_sequence;
              }
  #endif
-           key = read_char (NILP (prompt), nmaps,
-                            (Lisp_Object *) submaps, last_nonmenu_event,
-                            &used_mouse_menu, NULL);
          }
  
          /* read_char returns t when it shows a menu and the user rejects it.
@@@ -10333,8 -10541,12 +10545,12 @@@ detect_input_pending_run_timers (do_dis
         from an idle timer function.  The symptom of the bug is that
         the cursor sometimes doesn't become visible until the next X
         event is processed.  --gerd.  */
-       if (rif)
-       rif->flush_display (NULL);
+       {
+         Lisp_Object tail, frame;
+         FOR_EACH_FRAME (tail, frame)
+           if (FRAME_RIF (XFRAME (frame)))
+             FRAME_RIF (XFRAME (frame))->flush_display (XFRAME (frame));
+       }
      }
  
    return input_pending;
@@@ -10586,6 -10798,9 +10802,9 @@@ On such systems, Emacs starts a subshel
    int width, height;
    struct gcpro gcpro1;
  
+   if (tty_list && tty_list->next)
+     error ("There are other tty frames open; close them before suspending Emacs");
    if (!NILP (stuffstring))
      CHECK_STRING (stuffstring);
  
      call1 (Vrun_hooks, intern ("suspend-hook"));
  
    GCPRO1 (stuffstring);
-   get_frame_size (&old_width, &old_height);
-   reset_sys_modes ();
+   get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height);
+   reset_all_sys_modes ();
    /* sys_suspend can get an error if it tries to fork a subshell
       and the system resources aren't available for that.  */
-   record_unwind_protect ((Lisp_Object (*) P_ ((Lisp_Object))) init_sys_modes,
+   record_unwind_protect ((Lisp_Object (*) P_ ((Lisp_Object))) init_all_sys_modes,
                         Qnil);
    stuff_buffered_input (stuffstring);
    if (cannot_suspend)
    /* Check if terminal/window size has changed.
       Note that this is not useful when we are running directly
       with a window system; but suspend should be disabled in that case.  */
-   get_frame_size (&width, &height);
+   get_tty_size (fileno (CURTTY ()->input), &width, &height);
    if (width != old_width || height != old_height)
      change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
  
@@@ -10670,10 -10885,10 +10889,10 @@@ set_waiting_for_input (time_to_clear
  {
    input_available_clear_time = time_to_clear;
  
-   /* Tell interrupt_signal to throw back to read_char,  */
+   /* Tell handle_interrupt to throw back to read_char,  */
    waiting_for_input = 1;
  
-   /* If interrupt_signal was called before and buffered a C-g,
+   /* If handle_interrupt was called before and buffered a C-g,
       make it run again now, to avoid timing error. */
    if (!NILP (Vquit_flag))
      quit_throw_to_read_char ();
  void
  clear_waiting_for_input ()
  {
-   /* Tell interrupt_signal not to throw back to read_char,  */
+   /* Tell handle_interrupt not to throw back to read_char,  */
    waiting_for_input = 0;
    input_available_clear_time = 0;
  }
  
- /* This routine is called at interrupt level in response to C-g.
-    If interrupt_input, this is the handler for SIGINT.  Otherwise, it
-    is called from kbd_buffer_store_event, in handling SIGIO or
-    SIGTINT.
+ /* The SIGINT handler.
  
-    If `waiting_for_input' is non zero, then unless `echoing' is
-    nonzero, immediately throw back to read_char.
-    Otherwise it sets the Lisp variable quit-flag not-nil.  This causes
-    eval to throw, when it gets a chance.  If quit-flag is already
-    non-nil, it stops the job right away.  */
+    If we have a frame on the controlling tty, we assume that the
+    SIGINT was generated by C-g, so we call handle_interrupt.
+    Otherwise, the handler kills Emacs.  */
  
  static SIGTYPE
  interrupt_signal (signalnum)  /* If we don't have an argument, */
       int signalnum;           /* some compilers complain in signal calls. */
  {
-   char c;
    /* Must preserve main program's value of errno.  */
    int old_errno = errno;
-   struct frame *sf = SELECTED_FRAME ();
+   struct terminal *terminal;
  
  #if defined (USG) && !defined (POSIX_SIGNALS)
-   if (!read_socket_hook && NILP (Vwindow_system))
-     {
-       /* USG systems forget handlers when they are used;
-        must reestablish each time */
-       signal (SIGINT, interrupt_signal);
-       signal (SIGQUIT, interrupt_signal);
-     }
+   /* USG systems forget handlers when they are used;
+      must reestablish each time */
+   signal (SIGINT, interrupt_signal);
+   signal (SIGQUIT, interrupt_signal);
  #endif /* USG */
  
    SIGNAL_THREAD_CHECK (signalnum);
+   /* See if we have an active terminal on our controlling tty. */
+   terminal = get_named_tty ("/dev/tty");
+   if (!terminal)
+     {
+       /* If there are no frames there, let's pretend that we are a
+          well-behaving UN*X program and quit. */
+       Fkill_emacs (Qnil);
+     }
+   else
+     {
+       /* Otherwise, the SIGINT was probably generated by C-g.  */
+       /* Set internal_last_event_frame to the top frame of the
+          controlling tty, if we have a frame there.  We disable the
+          interrupt key on secondary ttys, so the SIGINT must have come
+          from the controlling tty.  */
+       internal_last_event_frame = terminal->display_info.tty->top_frame;
+       handle_interrupt ();
+     }
+   errno = old_errno;
+ }
+ /* This routine is called at interrupt level in response to C-g.
+    It is called from the SIGINT handler or kbd_buffer_store_event.
+    If `waiting_for_input' is non zero, then unless `echoing' is
+    nonzero, immediately throw back to read_char.
+    Otherwise it sets the Lisp variable quit-flag not-nil.  This causes
+    eval to throw, when it gets a chance.  If quit-flag is already
+    non-nil, it stops the job right away. */
+ static void
+ handle_interrupt ()
+ {
+   char c;
    cancel_echoing ();
  
+   /* XXX This code needs to be revised for multi-tty support. */
    if (!NILP (Vquit_flag)
-       && (FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf)))
+ #ifndef MSDOS
+       && get_named_tty ("/dev/tty")
+ #endif
+       )
      {
        /* If SIGINT isn't blocked, don't let us be interrupted by
         another SIGINT, it might be harmful due to non-reentrancy
        sigblock (sigmask (SIGINT));
  
        fflush (stdout);
-       reset_sys_modes ();
+       reset_all_sys_modes ();
  
  #ifdef SIGTSTP                        /* Support possible in later USG versions */
  /*
        printf ("Continuing...\n");
  #endif /* not MSDOS */
        fflush (stdout);
-       init_sys_modes ();
+       init_all_sys_modes ();
        sigfree ();
      }
    else
      }
  
    if (waiting_for_input && !echoing)
-     quit_throw_to_read_char ();
-   errno = old_errno;
+       quit_throw_to_read_char ();
  }
  
  /* Handle a C-g by making read_char return C-g.  */
@@@ -10873,75 -11120,202 +11124,202 @@@ quit_throw_to_read_char (
    _longjmp (getcjmp, 1);
  }
  \f
- DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0,
-        doc: /* Set mode of reading keyboard input.
- First arg INTERRUPT non-nil means use input interrupts;
-  nil means use CBREAK mode.
- Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal
-  (no effect except in CBREAK mode).
- Third arg META t means accept 8-bit input (for a Meta key).
-  META nil means ignore the top bit, on the assumption it is parity.
-  Otherwise, accept 8-bit input and don't use the top bit for Meta.
- Optional fourth arg QUIT if non-nil specifies character to use for quitting.
+ DEFUN ("set-input-interrupt-mode", Fset_input_interrupt_mode, Sset_input_interrupt_mode, 1, 1, 0,
+        doc: /* Set interrupt mode of reading keyboard input.
+ If INTERRUPT is non-nil, Emacs will use input interrupts;
+ otherwise Emacs uses CBREAK mode.
  See also `current-input-mode'.  */)
-      (interrupt, flow, meta, quit)
-      Lisp_Object interrupt, flow, meta, quit;
+      (interrupt)
+      Lisp_Object interrupt;
  {
-   if (!NILP (quit)
-       && (!INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400))
-     error ("set-input-mode: QUIT must be an ASCII character");
- #ifdef POLL_FOR_INPUT
-   stop_polling ();
- #endif
- #ifndef DOS_NT
-   /* this causes startup screen to be restored and messes with the mouse */
-   reset_sys_modes ();
- #endif
+   int new_interrupt_input;
  #ifdef SIGIO
  /* Note SIGIO has been undef'd if FIONREAD is missing.  */
-   if (read_socket_hook)
+ #ifdef HAVE_X_WINDOWS
+   if (x_display_list != NULL)
      {
        /* When using X, don't give the user a real choice,
         because we haven't implemented the mechanisms to support it.  */
  #ifdef NO_SOCK_SIGIO
-       interrupt_input = 0;
+       new_interrupt_input = 0;
  #else /* not NO_SOCK_SIGIO */
-       interrupt_input = 1;
+       new_interrupt_input = 1;
  #endif /* NO_SOCK_SIGIO */
      }
    else
-     interrupt_input = !NILP (interrupt);
+ #endif
+     new_interrupt_input = !NILP (interrupt);
  #else /* not SIGIO */
-   interrupt_input = 0;
+   new_interrupt_input = 0;
  #endif /* not SIGIO */
  
  /* Our VMS input only works by interrupts, as of now.  */
  #ifdef VMS
-   interrupt_input = 1;
+   new_interrupt_input = 1;
  #endif
  
-   flow_control = !NILP (flow);
+   if (new_interrupt_input != interrupt_input) 
+     {
+ #ifdef POLL_FOR_INPUT
+       stop_polling ();
+ #endif
+ #ifndef DOS_NT
+       /* this causes startup screen to be restored and messes with the mouse */
+       reset_all_sys_modes ();
+ #endif
+       interrupt_input = new_interrupt_input;
+ #ifndef DOS_NT
+       init_all_sys_modes ();
+ #endif
+ #ifdef POLL_FOR_INPUT
+       poll_suppress_count = 1;
+       start_polling ();
+ #endif
+     }
+   return Qnil;
+ }
+ DEFUN ("set-output-flow-control", Fset_output_flow_control, Sset_output_flow_control, 1, 2, 0,
+        doc: /* Enable or disable ^S/^Q flow control for output to TERMINAL.
+ If FLOW is non-nil, flow control is enabled and you cannot use C-s or
+ C-q in key sequences.
+ This setting only has an effect on tty terminals and only when
+ Emacs reads input in CBREAK mode; see `set-input-interrupt-mode'.
+ See also `current-input-mode'.  */)
+        (flow, terminal)
+        Lisp_Object flow, terminal;
+ {
+   struct terminal *t = get_terminal (terminal, 1);
+   struct tty_display_info *tty;
+   if (t == NULL || t->type != output_termcap)
+     return Qnil;
+   tty = t->display_info.tty;
+   if (tty->flow_control != !NILP (flow))
+     {
+ #ifndef DOS_NT
+       /* this causes startup screen to be restored and messes with the mouse */
+       reset_sys_modes (tty);
+ #endif
+       tty->flow_control = !NILP (flow);
+ #ifndef DOS_NT
+       init_sys_modes (tty);
+ #endif
+     }
+   return Qnil;
+ }
+ DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0,
+        doc: /* Enable or disable 8-bit input on TERMINAL.
+ If META is t, Emacs will accept 8-bit input, and interpret the 8th
+ bit as the Meta modifier.
+ If META is nil, Emacs will ignore the top bit, on the assumption it is
+ parity.
+ Otherwise, Emacs will accept and pass through 8-bit input without
+ specially interpreting the top bit.
+ This setting only has an effect on tty terminal devices.
+ Optional parameter TERMINAL specifies the tty terminal device to use.
+ It may be a terminal id, a frame, or nil for the terminal used by the
+ currently selected frame.
+ See also `current-input-mode'.  */)
+        (meta, terminal)
+        Lisp_Object meta, terminal;
+ {
+   struct terminal *t = get_terminal (terminal, 1);
+   struct tty_display_info *tty;
+   int new_meta;
+   
+   if (t == NULL || t->type != output_termcap)
+     return Qnil;
+   tty = t->display_info.tty;
    if (NILP (meta))
-     meta_key = 0;
+     new_meta = 0;
    else if (EQ (meta, Qt))
-     meta_key = 1;
+     new_meta = 1;
    else
-     meta_key = 2;
-   if (!NILP (quit))
-     /* Don't let this value be out of range.  */
-     quit_char = XINT (quit) & (meta_key ? 0377 : 0177);
+     new_meta = 2;
  
+   if (tty->meta_key != new_meta) 
+     {
  #ifndef DOS_NT
-   init_sys_modes ();
+       /* this causes startup screen to be restored and messes with the mouse */
+       reset_sys_modes (tty);
  #endif
  
- #ifdef POLL_FOR_INPUT
-   poll_suppress_count = 1;
-   start_polling ();
+       tty->meta_key = new_meta;
+   
+ #ifndef DOS_NT
+       init_sys_modes (tty);
  #endif
+     }
+   return Qnil;
+ }
+ DEFUN ("set-quit-char", Fset_quit_char, Sset_quit_char, 1, 1, 0,
+        doc: /* Specify character used for quitting.
+ QUIT must be an ASCII character.
+ This function only has an effect on the controlling tty of the Emacs
+ process.
+ See also `current-input-mode'.  */)
+        (quit)
+        Lisp_Object quit;
+ {
+   struct terminal *t = get_named_tty ("/dev/tty");
+   struct tty_display_info *tty;
+   if (t == NULL || t->type != output_termcap)
+     return Qnil;
+   tty = t->display_info.tty;
+   if (NILP (quit) || !INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400)
+     error ("QUIT must be an ASCII character");
+ #ifndef DOS_NT
+   /* this causes startup screen to be restored and messes with the mouse */
+   reset_sys_modes (tty);
+ #endif
+   
+   /* Don't let this value be out of range.  */
+   quit_char = XINT (quit) & (tty->meta_key == 0 ? 0177 : 0377);
+ #ifndef DOS_NT
+   init_sys_modes (tty);
+ #endif
+   return Qnil;
+ }
+        
+ DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0,
+        doc: /* Set mode of reading keyboard input.
+ First arg INTERRUPT non-nil means use input interrupts;
+  nil means use CBREAK mode.
+ Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal
+  (no effect except in CBREAK mode).
+ Third arg META t means accept 8-bit input (for a Meta key).
+  META nil means ignore the top bit, on the assumption it is parity.
+  Otherwise, accept 8-bit input and don't use the top bit for Meta.
+ Optional fourth arg QUIT if non-nil specifies character to use for quitting.
+ See also `current-input-mode'.  */)
+      (interrupt, flow, meta, quit)
+      Lisp_Object interrupt, flow, meta, quit;
+ {
+   Fset_input_interrupt_mode (interrupt);
+   Fset_output_flow_control (flow, Qnil);
+   Fset_input_meta_mode (meta, Qnil);
+   Fset_quit_char (quit);
    return Qnil;
  }
  
@@@ -10962,10 -11336,21 +11340,21 @@@ The elements of this list correspond t
       ()
  {
    Lisp_Object val[4];
+   struct frame *sf = XFRAME (selected_frame);
  
    val[0] = interrupt_input ? Qt : Qnil;
-   val[1] = flow_control ? Qt : Qnil;
-   val[2] = meta_key == 2 ? make_number (0) : meta_key == 1 ? Qt : Qnil;
+   if (FRAME_TERMCAP_P (sf))
+     {
+       val[1] = FRAME_TTY (sf)->flow_control ? Qt : Qnil;
+       val[2] = (FRAME_TTY (sf)->meta_key == 2
+                 ? make_number (0)
+                 : (CURTTY ()->meta_key == 1 ? Qt : Qnil));
+     }
+   else
+     {
+       val[1] = Qnil;
+       val[2] = Qt;
+     }
    XSETFASTINT (val[3], quit_char);
  
    return Flist (sizeof (val) / sizeof (val[0]), val);
@@@ -11057,6 -11442,7 +11446,7 @@@ init_kboard (kb
    kb->Voverriding_terminal_local_map = Qnil;
    kb->Vlast_command = Qnil;
    kb->Vreal_last_command = Qnil;
+   kb->Vkeyboard_translate_table = Qnil;
    kb->Vprefix_arg = Qnil;
    kb->Vlast_prefix_arg = Qnil;
    kb->kbd_queue = Qnil;
    kb->reference_count = 0;
    kb->Vsystem_key_alist = Qnil;
    kb->system_key_syms = Qnil;
+   kb->Vlocal_function_key_map = Fmake_sparse_keymap (Qnil);
+   Fset_keymap_parent (kb->Vlocal_function_key_map, Vfunction_key_map);
+   kb->Vlocal_key_translation_map = Fmake_sparse_keymap (Qnil);
+   Fset_keymap_parent (kb->Vlocal_key_translation_map, Vkey_translation_map);
    kb->Vdefault_minibuffer_frame = Qnil;
  }
  
@@@ -11107,7 -11497,8 +11501,8 @@@ delete_kboard (kb
        && FRAMEP (selected_frame)
        && FRAME_LIVE_P (XFRAME (selected_frame)))
      {
-       current_kboard = XFRAME (selected_frame)->kboard;
+       current_kboard = FRAME_KBOARD (XFRAME (selected_frame));
+       single_kboard = 0;
        if (current_kboard == kb)
        abort ();
      }
@@@ -11150,8 -11541,14 +11545,14 @@@ init_keyboard (
    wipe_kboard (current_kboard);
    init_kboard (current_kboard);
  
-   if (!noninteractive && !read_socket_hook && NILP (Vwindow_system))
+   if (!noninteractive)
      {
+       /* Before multi-tty support, these handlers used to be installed
+          only if the current session was a tty session.  Now an Emacs
+          session may have multiple display types, so we always handle
+          SIGINT.  There is special code in interrupt_signal to exit
+          Emacs on SIGINT when there are no termcap frames on the
+          controlling terminal. */
        signal (SIGINT, interrupt_signal);
  #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
        /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
@@@ -11227,9 -11624,6 +11628,9 @@@ syms_of_keyboard (
    staticpro (&Qhelp_echo);
    Qhelp_echo = intern ("help-echo");
  
 +  staticpro (&Qrtl);
 +  Qrtl = intern (":rtl");
 +
    staticpro (&item_properties);
    item_properties = Qnil;
  
    defsubr (&Stop_level);
    defsubr (&Sdiscard_input);
    defsubr (&Sopen_dribble_file);
+   defsubr (&Sset_input_interrupt_mode);
+   defsubr (&Sset_output_flow_control);
+   defsubr (&Sset_input_meta_mode);
+   defsubr (&Sset_quit_char);
    defsubr (&Sset_input_mode);
    defsubr (&Scurrent_input_mode);
    defsubr (&Sexecute_extended_command);
@@@ -11542,7 -11940,10 +11947,10 @@@ In other words, the present command is 
  command exit.
  
  The value `kill-region' is special; it means that the previous command
- was a kill command.  */);
+ was a kill command.
+ `last-command' has a separate binding for each terminal device.
+ See Info node `(elisp)Multiple displays'.  */);
  
    DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
                 doc: /* Same as `last-command', but never altered by Lisp code.  */);
@@@ -11654,8 -12055,8 +12062,8 @@@ for that character after that prefix ke
  Useful to set before you dump a modified Emacs.  */);
    Vtop_level = Qnil;
  
-   DEFVAR_LISP ("keyboard-translate-table", &Vkeyboard_translate_table,
-              doc: /* Translate table for keyboard input, or nil.
+   DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table,
+                  doc: /* Translate table for local keyboard input, or nil.
  If non-nil, the value should be a char-table.  Each character read
  from the keyboard is looked up in this char-table.  If the value found
  there is non-nil, then it is used instead of the actual input character.
@@@ -11665,8 -12066,10 +12073,10 @@@ If it is a string or vector of length N
  untranslated.  In a vector, an element which is nil means "no translation".
  
  This is applied to the characters supplied to input methods, not their
- output.  See also `translation-table-for-input'.  */);
-   Vkeyboard_translate_table = Qnil;
+ output.  See also `translation-table-for-input'.
+ This variable has a separate binding for each terminal.  See Info node
+ `(elisp)Multiple displays'.  */);
  
    DEFVAR_BOOL ("cannot-suspend", &cannot_suspend,
               doc: /* Non-nil means to always spawn a subshell instead of suspending.
@@@ -11751,7 -12154,11 +12161,11 @@@ buffer's local map, and the minor mode 
  It also replaces `overriding-local-map'.
  
  This variable is intended to let commands such as `universal-argument'
- set up a different keymap for reading the next command.  */);
+ set up a different keymap for reading the next command.
+ `overriding-terminal-local-map' has a separate binding for each
+ terminal device.
+ See Info node `(elisp)Multiple displays'.  */);
  
    DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map,
               doc: /* Keymap that overrides all other local keymaps.
@@@ -11776,7 -12183,61 +12190,61 @@@ and the minor mode maps regardless of `
                 doc: /* Alist of system-specific X windows key symbols.
  Each element should have the form (N . SYMBOL) where N is the
  numeric keysym code (sans the \"system-specific\" bit 1<<28)
- and SYMBOL is its name.  */);
+ and SYMBOL is its name.
+ `system-key-alist' has a separate binding for each terminal device.
+ See Info node `(elisp)Multiple displays'.  */);
+   DEFVAR_KBOARD ("local-function-key-map", Vlocal_function_key_map,
+                  doc: /* Keymap that translates key sequences to key sequences during input.
+ This is used mainly for mapping ASCII function key sequences into
+ real Emacs function key events (symbols).
+ The `read-key-sequence' function replaces any subsequence bound by
+ `local-function-key-map' with its binding.  More precisely, when the
+ active keymaps have no binding for the current key sequence but
+ `local-function-key-map' binds a suffix of the sequence to a vector or
+ string, `read-key-sequence' replaces the matching suffix with its
+ binding, and continues with the new sequence.
+ If the binding is a function, it is called with one argument (the prompt)
+ and its return value (a key sequence) is used.
+ The events that come from bindings in `local-function-key-map' are not
+ themselves looked up in `local-function-key-map'.
+ For example, suppose `local-function-key-map' binds `ESC O P' to [f1].
+ Typing `ESC O P' to `read-key-sequence' would return [f1].  Typing
+ `C-x ESC O P' would return [?\\C-x f1].  If [f1] were a prefix key,
+ typing `ESC O P x' would return [f1 x].
+ `local-function-key-map' has a separate binding for each terminal
+ device.  See Info node `(elisp)Multiple displays'.  If you need to
+ define a binding on all terminals, change `function-key-map'
+ instead.  Initially, `local-function-key-map' is an empty keymap that
+ has `function-key-map' as its parent on all terminal devices.  */);
+   DEFVAR_LISP ("function-key-map", &Vfunction_key_map,
+                doc: /* The parent keymap of all `local-function-key-map' instances.
+ Function key definitions that apply to all terminal devices should go
+ here.  If a mapping is defined in both the current
+ `local-function-key-map' binding and this variable, then the local
+ definition will take precendence.  */);
+   Vfunction_key_map = Fmake_sparse_keymap (Qnil);
+                     
+   DEFVAR_KBOARD ("local-key-translation-map", Vlocal_key_translation_map,
+              doc: /* Keymap of key translations that can override keymaps.
+ This keymap works like `function-key-map', but comes after that,
+ and its non-prefix bindings override ordinary bindings.
+ `key-translation-map' has a separate binding for each terminal device.
+ (See Info node `(elisp)Multiple displays'.)  If you need to set a key
+ translation on all terminals, change `global-key-translation-map' instead.  */);
+   DEFVAR_LISP ("key-translation-map", &Vkey_translation_map,
+                doc: /* The parent keymap of all `local-key-translation-map' instances.
+ Key translations that apply to all terminal devices should go here.  */);
+   Vkey_translation_map = Fmake_sparse_keymap (Qnil);
  
    DEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list,
               doc: /* List of deferred actions to be performed at a later time.
@@@ -11945,6 -12406,7 +12413,7 @@@ mark_kboards (
        mark_object (kb->Voverriding_terminal_local_map);
        mark_object (kb->Vlast_command);
        mark_object (kb->Vreal_last_command);
+       mark_object (kb->Vkeyboard_translate_table);
        mark_object (kb->Vprefix_arg);
        mark_object (kb->Vlast_prefix_arg);
        mark_object (kb->kbd_queue);
        mark_object (kb->Vlast_kbd_macro);
        mark_object (kb->Vsystem_key_alist);
        mark_object (kb->system_key_syms);
+       mark_object (kb->Vlocal_function_key_map);
+       mark_object (kb->Vlocal_key_translation_map);
        mark_object (kb->Vdefault_minibuffer_frame);
        mark_object (kb->echo_string);
      }