]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
(get_adstyle_property): Fix previous change.
[gnu-emacs] / src / keyboard.c
index ed95c3fce5048cc757d045fc9aa3b565f0db3f91..527a82b55ff089a9887e7df925a2e6e6372777fc 100644 (file)
@@ -1,7 +1,7 @@
 /* Keyboard and mouse input; editor command loop.
    Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995,
                  1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -91,6 +91,15 @@ volatile int interrupt_input_blocked;
    during the current critical section.  */
 int interrupt_input_pending;
 
+/* This var should be (interrupt_input_pending || pending_atimers).
+   The QUIT macro checks this instead of interrupt_input_pending and
+   pending_atimers separately, to reduce code size.  So, any code that
+   changes interrupt_input_pending or pending_atimers should update
+   this too.  */
+#ifdef SYNC_INPUT
+int pending_signals;
+#endif
+
 #define KBD_BUFFER_SIZE 4096
 
 KBOARD *initial_kboard;
@@ -259,15 +268,15 @@ int command_loop_level;
 /* Total number of times command_loop has read a key sequence.  */
 EMACS_INT num_input_keys;
 
-/* Last input character read as a command.  */
-Lisp_Object last_command_char;
+/* Last input event read as a command.  */
+Lisp_Object last_command_event;
 
 /* Last input character read as a command, not counting menus
    reached by the mouse.  */
 Lisp_Object last_nonmenu_event;
 
-/* Last input character read for any purpose.  */
-Lisp_Object last_input_char;
+/* Last input event read for any purpose.  */
+Lisp_Object last_input_event;
 
 /* If not Qnil, a list of objects to be read as subsequent command input.  */
 Lisp_Object Vunread_command_events;
@@ -462,6 +471,8 @@ Lisp_Object Qmake_frame_visible;
 Lisp_Object Qselect_window;
 Lisp_Object Qhelp_echo;
 
+extern Lisp_Object Qremap;
+
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 Lisp_Object Qmouse_fixup_help_message;
 #endif
@@ -1265,7 +1276,17 @@ 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
-          || FRAME_INITIAL_P (sf)
+          /* The initial frame is a special non-displaying frame. It
+             will be current in daemon mode when there are no frames
+             to display, and in non-daemon mode before the real frame
+             has finished initializing.  If an error is thrown in the
+             latter case while creating the frame, then the frame
+             will never be displayed, so the safest thing to do is
+             write to stderr and quit.  In daemon mode, there are
+             many other potential errors that do not prevent frames
+             from being created, so continuing as normal is better in
+             that case.  */
+          || (!IS_DAEMON && FRAME_INITIAL_P (sf))
           || noninteractive)
     {
       print_error_message (data, Qexternal_debugging_output,
@@ -1361,7 +1382,8 @@ top_level_1 ()
 }
 
 DEFUN ("top-level", Ftop_level, Stop_level, 0, 0, "",
-       doc: /* Exit all recursive editing levels.  */)
+       doc: /* Exit all recursive editing levels.
+This also exits all active minibuffers.  */)
      ()
 {
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1544,7 +1566,7 @@ command_loop_1 ()
   /* Do this after running Vpost_command_hook, for consistency.  */
   current_kboard->Vlast_command = Vthis_command;
   current_kboard->Vreal_last_command = real_this_command;
-  if (!CONSP (last_command_char))
+  if (!CONSP (last_command_event))
     current_kboard->Vlast_repeatable_command = real_this_command;
 
   while (1)
@@ -1600,7 +1622,7 @@ command_loop_1 ()
         Is this a good idea?  */
       if (FRAMEP (internal_last_event_frame)
          && !EQ (internal_last_event_frame, selected_frame))
-       Fselect_frame (internal_last_event_frame);
+       Fselect_frame (internal_last_event_frame, Qnil);
 #endif
       /* If it has changed current-menubar from previous value,
         really recompute the menubar from the value.  */
@@ -1644,7 +1666,7 @@ command_loop_1 ()
          goto finalize;
        }
 
-      last_command_char = keybuf[i - 1];
+      last_command_event = keybuf[i - 1];
 
       /* If the previous command tried to force a specific window-start,
         forget about that, in case this command moves point far away
@@ -1809,12 +1831,12 @@ command_loop_1 ()
                }
              else if (EQ (Vthis_command, Qself_insert_command)
                       /* Try this optimization only on char keystrokes.  */
-                      && NATNUMP (last_command_char)
-                      && CHAR_VALID_P (XFASTINT (last_command_char), 0))
+                      && NATNUMP (last_command_event)
+                      && CHAR_VALID_P (XFASTINT (last_command_event), 0))
                {
                  unsigned int c
                    = translate_char (Vtranslation_table_for_input,
-                                     XFASTINT (last_command_char));
+                                     XFASTINT (last_command_event));
                  int value;
                  if (NILP (Vexecuting_kbd_macro)
                      && !EQ (minibuf_window, selected_window))
@@ -1918,11 +1940,11 @@ command_loop_1 ()
         If the command didn't actually create a prefix arg,
         but is merely a frame event that is transparent to prefix args,
         then the above doesn't apply.  */
-      if (NILP (current_kboard->Vprefix_arg) || CONSP (last_command_char))
+      if (NILP (current_kboard->Vprefix_arg) || CONSP (last_command_event))
        {
          current_kboard->Vlast_command = Vthis_command;
          current_kboard->Vreal_last_command = real_this_command;
-         if (!CONSP (last_command_char))
+         if (!CONSP (last_command_event))
            current_kboard->Vlast_repeatable_command = real_this_command;
          cancel_echoing ();
          this_command_key_count = 0;
@@ -1994,13 +2016,9 @@ adjust_point_for_property (last_pt, modified)
       /* FIXME: check `intangible'.  */
       if (check_composition
          && PT > BEGV && PT < ZV
-         && get_property_and_range (PT, Qcomposition, &val, &beg, &end, Qnil)
-         && COMPOSITION_VALID_P (beg, end, val)
-         && beg < PT /* && end > PT   <- It's always the case.  */
-         && (last_pt <= beg || last_pt >= end))
+         && (beg = composition_adjust_point (last_pt)) != PT)
        {
-         xassert (end > PT);
-         SET_PT (PT < last_pt ? beg : end);
+         SET_PT (beg);
          check_display = check_invisible = 1;
        }
       check_composition = 0;
@@ -2030,6 +2048,20 @@ adjust_point_for_property (last_pt, modified)
 
          /* Find boundaries `beg' and `end' of the invisible area, if any.  */
          while (end < ZV
+                /* Stop if we find a spot between two runs of
+                   `invisible' where inserted text would be visible.
+                   This is important when we have two invisible
+                   boundaries that enclose an area: if the area is
+                   empty, we need this test in order to make it
+                   possible to place point in the middle rather than
+                   skip both boundaries.
+                   Note that this will stop anywhere in a non-sticky
+                   text-property, but I don't think there's much we
+                   can do about that.  */
+                && (val = get_pos_property (make_number (end),
+                                            Qinvisible, Qnil),
+                    TEXT_PROP_MEANS_INVISIBLE (val))
+                /* FIXME: write and then use get_pos_property_and_overlay.  */
                 && !NILP (val = get_char_property_and_overlay
                           (make_number (end), Qinvisible, Qnil, &overlay))
                 && (inv = TEXT_PROP_MEANS_INVISIBLE (val)))
@@ -2043,6 +2075,9 @@ adjust_point_for_property (last_pt, modified)
              end = NATNUMP (tmp) ? XFASTINT (tmp) : ZV;
            }
          while (beg > BEGV
+                && (val = get_pos_property (make_number (beg),
+                                            Qinvisible, Qnil),
+                    TEXT_PROP_MEANS_INVISIBLE (val))
                 && !NILP (val = get_char_property_and_overlay
                           (make_number (beg - 1), Qinvisible, Qnil, &overlay))
                 && (inv = TEXT_PROP_MEANS_INVISIBLE (val)))
@@ -2166,16 +2201,24 @@ struct atimer *poll_timer;
 
 #ifdef POLL_FOR_INPUT
 
-/* Poll for input, so what we catch a C-g if it comes in.  This
+/* Poll for input, so that we catch a C-g if it comes in.  This
    function is called from x_make_frame_visible, see comment
    there.  */
 
 void
 poll_for_input_1 ()
 {
+/* Tell ns_read_socket() it is being called asynchronously so it can avoid
+   doing anything dangerous. */
+#ifdef HAVE_NS
+  ++handling_signal;
+#endif
   if (interrupt_input_blocked == 0
       && !waiting_for_input)
     read_avail_input (0);
+#ifdef HAVE_NS
+  --handling_signal;
+#endif
 }
 
 /* Timer callback function for poll_timer.  TIMER is equal to
@@ -2186,11 +2229,14 @@ poll_for_input (timer)
      struct atimer *timer;
 {
   if (poll_suppress_count == 0)
+    {
 #ifdef SYNC_INPUT
-    interrupt_input_pending = 1;
+      interrupt_input_pending = 1;
+      pending_signals = 1;
 #else
-    poll_for_input_1 ();
+      poll_for_input_1 ();
 #endif
+    }
 }
 
 #endif /* POLL_FOR_INPUT */
@@ -2432,7 +2478,7 @@ static void record_char ();
 
 static Lisp_Object help_form_saved_window_configs;
 static Lisp_Object
-read_char_help_form_unwind (arg)
+read_char_help_form_unwind (Lisp_Object arg)
 {
   Lisp_Object window_config = XCAR (help_form_saved_window_configs);
   help_form_saved_window_configs = XCDR (help_form_saved_window_configs);
@@ -2540,6 +2586,8 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
 
   if (CONSP (Vunread_command_events))
     {
+      int was_disabled = 0;
+
       c = XCAR (Vunread_command_events);
       Vunread_command_events = XCDR (Vunread_command_events);
 
@@ -2560,12 +2608,17 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
       if (CONSP (c)
          && EQ (XCDR (c), Qdisabled)
          && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c))))
-       c = XCAR (c);
+       {
+         was_disabled = 1;
+         c = XCAR (c);
+       }
 
       /* If the queued event is something that used the mouse,
          set used_mouse_menu accordingly.  */
       if (used_mouse_menu
-         && (EQ (c, Qtool_bar) || EQ (c, Qmenu_bar)))
+         /* Also check was_disabled so last-nonmenu-event won't return
+            a bad value when submenus are involved.  (Bug#447)  */
+         && (EQ (c, Qtool_bar) || EQ (c, Qmenu_bar) || was_disabled))
        *used_mouse_menu = 1;
 
       goto reread_for_input_method;
@@ -3086,8 +3139,8 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
       record_single_kboard_state ();
 #endif
 
-      last_input_char = c;
-      Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt);
+      last_input_event = c;
+      Fcommand_execute (tem, Qnil, Fvector (1, &last_input_event), Qt);
 
       if (CONSP (c) && EQ (XCAR (c), Qselect_window) && !end_time)
        /* We stopped being idle for this event; undo that.  This
@@ -3328,7 +3381,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
        add_command_key (also_record);
     }
 
-  last_input_char = c;
+  last_input_event = c;
   num_input_events++;
 
   /* Process the help character specially if enabled */
@@ -3405,7 +3458,7 @@ record_menu_key (c)
   add_command_key (c);
 
   /* Re-reading in the middle of a command */
-  last_input_char = c;
+  last_input_event = c;
   num_input_events++;
 }
 
@@ -3981,7 +4034,10 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
   register int c;
   Lisp_Object obj;
 
-  if (noninteractive)
+  if (noninteractive
+      /* In case we are running as a daemon, only do this before
+        detaching from the terminal.  */
+      || (IS_DAEMON && daemon_pipe[1] >= 0))
     {
       c = getchar ();
       XSETINT (obj, c);
@@ -4096,6 +4152,18 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
 #endif
        }
 
+#if defined (HAVE_NS)
+      else if (event->kind == NS_TEXT_EVENT)
+        {
+          if (event->code == KEY_NS_PUT_WORKING_TEXT)
+            obj = Fcons (intern ("ns-put-working-text"), Qnil);
+          else
+            obj = Fcons (intern ("ns-unput-working-text"), Qnil);
+         kbd_fetch_ptr = event + 1;
+         *used_mouse_menu = 1;
+        }
+#endif
+
 #if defined (HAVE_X11) || defined (HAVE_NTGUI) \
     || defined (HAVE_NS)
       else if (event->kind == DELETE_WINDOW_EVENT)
@@ -4247,6 +4315,11 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
                      || event->kind == TOOL_BAR_EVENT))
                *used_mouse_menu = 1;
 #endif
+#ifdef HAVE_NS
+             /* certain system events are non-key events */
+             if (event->kind == NS_NONKEY_EVENT)
+               *used_mouse_menu = 1;
+#endif
 
              /* Wipe out this event, to catch bugs.  */
              clear_event (event);
@@ -4588,11 +4661,6 @@ timer_check (do_it_now)
              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;
@@ -4625,10 +4693,9 @@ timer_check (do_it_now)
 
 DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
        doc: /* Return the current length of Emacs idleness, or nil.
-The value when Emacs is idle is a list of three integers.  The first has the
-most significant 16 bits of the seconds, while the second has the
-least significant 16 bits.  The third integer gives the microsecond
-count.
+The value when Emacs is idle is a list of three integers.  The first has
+the most significant 16 bits of the seconds, while the second has the least
+significant 16 bits.  The third integer gives the microsecond count.
 
 The value when Emacs is not idle is nil.
 
@@ -5312,7 +5379,8 @@ make_lispy_position (f, x, y, time)
                                     &object, &dx, &dy, &width, &height);
          if (STRINGP (string))
            string_info = Fcons (string, make_number (charpos));
-         if (w == XWINDOW (selected_window))
+         if (w == XWINDOW (selected_window)
+             && current_buffer == XBUFFER (w->buffer))
            textpos = PT;
          else
            textpos = XMARKER (w->pointm)->charpos;
@@ -5491,6 +5559,12 @@ make_lispy_event (event)
        return lispy_c;
       }
 
+#ifdef HAVE_NS
+      /* NS_NONKEY_EVENTs are just like NON_ASCII_KEYSTROKE_EVENTs,
+        except that they are non-key events (last-nonmenu-event is nil). */
+    case NS_NONKEY_EVENT:
+#endif
+
       /* A function key.  The symbol may need to have modifier prefixes
         tacked onto it.  */
     case NON_ASCII_KEYSTROKE_EVENT:
@@ -6306,6 +6380,11 @@ parse_modifiers_uncached (symbol, modifier_end)
       && ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9'))
     modifiers |= click_modifier;
 
+  if (! (modifiers & (double_modifier | triple_modifier))
+      && i + 6 < SBYTES (name)
+      && strncmp (SDATA (name) + i, "wheel-", 6) == 0)
+    modifiers |= click_modifier;
+
   if (modifier_end)
     *modifier_end = i;
 
@@ -7033,7 +7112,7 @@ read_avail_input (expected)
                    alone in its group.  */
                 kill (getpid (), SIGHUP);
 
-              /* XXX Is calling delete_terminal safe here?  It calls Fdelete_frame. */
+              /* XXX Is calling delete_terminal safe here?  It calls delete_frame. */
              {
                Lisp_Object tmp;
                XSETTERMINAL (tmp, t);
@@ -7076,7 +7155,8 @@ tty_read_avail_input (struct terminal *terminal,
   if (!terminal->name)         /* Don't read from a dead terminal. */
     return 0;
 
-  if (terminal->type != output_termcap)
+  if (terminal->type != output_termcap
+      && terminal->type != output_msdos_raw)
     abort ();
 
   /* XXX I think the following code should be moved to separate hook
@@ -7084,6 +7164,12 @@ tty_read_avail_input (struct terminal *terminal,
 #ifdef WINDOWSNT
   return 0;
 #else /* not WINDOWSNT */
+  if (! tty->term_initted)      /* In case we get called during bootstrap. */
+    return 0;
+
+  if (! tty->input)
+    return 0;                   /* The terminal is suspended. */
+
 #ifdef MSDOS
   n_to_read = dos_keysns ();
   if (n_to_read == 0)
@@ -7093,26 +7179,28 @@ tty_read_avail_input (struct terminal *terminal,
   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 (gpm_tty == tty)
   {
       Gpm_Event event;
       struct input_event hold_quit;
-      int gpm;
+      int gpm, fd = gpm_fd;
 
       EVENT_INIT (hold_quit);
       hold_quit.kind = NO_EVENT;
 
+      /* gpm==1 if event received.
+         gpm==0 if the GPM daemon has closed the connection, in which case
+                Gpm_GetEvent closes gpm_fd and clears it to -1, which is why
+               we save it in `fd' so close_gpm can remove it from the
+               select masks.
+         gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal. */
       while (gpm = Gpm_GetEvent (&event), gpm == 1) {
          nread += handle_one_term_event (tty, &event, &hold_quit);
       }
+      if (gpm == 0)
+       /* Presumably the GPM daemon has closed the connection.  */
+       close_gpm (fd);
       if (hold_quit.kind != NO_EVENT)
          kbd_buffer_store_event (&hold_quit);
       if (nread)
@@ -7229,7 +7317,14 @@ void
 handle_async_input ()
 {
   interrupt_input_pending = 0;
-
+#ifdef SYNC_INPUT
+  pending_signals = pending_atimers;
+#endif
+/* Tell ns_read_socket() it is being called asynchronously so it can avoid
+   doing anything dangerous. */
+#ifdef HAVE_NS
+  ++handling_signal;
+#endif
   while (1)
     {
       int nread;
@@ -7240,6 +7335,17 @@ handle_async_input ()
       if (nread <= 0)
        break;
     }
+#ifdef HAVE_NS
+  --handling_signal;
+#endif
+}
+
+void
+process_pending_signals ()
+{
+  if (interrupt_input_pending)
+    handle_async_input ();
+  do_pending_atimers ();
 }
 
 #ifdef SIGIO   /* for entire page */
@@ -7259,6 +7365,7 @@ input_available_signal (signo)
 
 #ifdef SYNC_INPUT
   interrupt_input_pending = 1;
+  pending_signals = 1;
 #else
   SIGNAL_THREAD_CHECK (signo);
 #endif
@@ -7967,6 +8074,11 @@ parse_menu_item (item, notreal, inmenubar)
              && ! NILP (Fget (def, Qmenu_alias)))
            def = XSYMBOL (def)->function;
          tem = Fwhere_is_internal (def, Qnil, Qt, Qnil, Qt);
+
+         /* Don't display remap bindings.*/
+         if (VECTORP (tem) && ASIZE (tem) > 0 && EQ (AREF (tem, 0), Qremap))
+           tem = Qnil;
+
          XSETCAR (cachelist, tem);
          if (NILP (tem))
            {
@@ -8558,7 +8670,20 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
   if (! menu_prompting)
     return Qnil;
 
+  /* Get the menu name from the first map that has one (a prompt string).  */
+  for (mapno = 0; mapno < nmaps; mapno++)
+    {
+      name = Fkeymap_prompt (maps[mapno]);
+      if (!NILP (name))
+       break;
+    }
+
+  /* If we don't have any menus, just read a character normally.  */
+  if (!STRINGP (name))
+    return Qnil;
+
   /* Make sure we have a big enough buffer for the menu text.  */
+  width = max (width, SBYTES (name));
   if (read_char_minibuf_menu_text == 0)
     {
       read_char_minibuf_menu_width = width + 4;
@@ -8572,18 +8697,6 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
     }
   menu = read_char_minibuf_menu_text;
 
-  /* Get the menu name from the first map that has one (a prompt string).  */
-  for (mapno = 0; mapno < nmaps; mapno++)
-    {
-      name = Fkeymap_prompt (maps[mapno]);
-      if (!NILP (name))
-       break;
-    }
-
-  /* If we don't have any menus, just read a character normally.  */
-  if (!STRINGP (name))
-    return Qnil;
-
   /* Prompt string always starts with map's prompt, and a space.  */
   strcpy (menu, SDATA (name));
   nlength = SBYTES (name);
@@ -9157,16 +9270,10 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
   orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
   from_string = Qnil;
 
-  /* The multi-tty merge moved the code below to right after
-   `replay_sequence' which caused all these translation maps to be applied
-   repeatedly, even tho their doc says very clearly they are not applied to
-   their own output.
-   The reason for this move was: "We may switch keyboards between rescans,
-   so we need to reinitialize fkey and keytran before each replay".
-   This move was wrong (even if we switch keyboards, keybuf still holds the
-   keys we've read already from the original keyboard and some of those keys
-   may have already been translated).  So there may still be a bug out there
-   lurking.  */
+  /* We jump here when we need to reinitialize fkey and keytran; this
+     happens if we switch keyboards between rescans.  */
+ replay_entire_sequence:
+
   indec.map = indec.parent = current_kboard->Vinput_decode_map;
   fkey.map = fkey.parent = current_kboard->Vlocal_function_key_map;
   keytran.map = keytran.parent = Vkey_translation_map;
@@ -9363,7 +9470,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                    /* Don't touch interrupted_kboard when it's been
                       deleted. */
                    delayed_switch_frame = Qnil;
-                   goto replay_sequence;
+                   goto replay_entire_sequence;
                  }
 
                if (!NILP (delayed_switch_frame))
@@ -9395,7 +9502,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                mock_input = 0;
                orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
                orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
-               goto replay_sequence;
+               goto replay_entire_sequence;
              }
          }
 
@@ -10972,11 +11079,7 @@ handle_interrupt ()
   cancel_echoing ();
 
   /* XXX This code needs to be revised for multi-tty support. */
-  if (!NILP (Vquit_flag)
-#ifndef MSDOS
-      && get_named_tty ("/dev/tty")
-#endif
-      )
+  if (!NILP (Vquit_flag) && get_named_tty ("/dev/tty"))
     {
       /* If SIGINT isn't blocked, don't let us be interrupted by
         another SIGINT, it might be harmful due to non-reentrancy
@@ -11005,7 +11108,7 @@ handle_interrupt ()
 #ifdef MSDOS
       /* We must remain inside the screen area when the internal terminal
         is used.  Note that [Enter] is not echoed by dos.  */
-      cursor_to (0, 0);
+      cursor_to (SELECTED_FRAME (), 0, 0);
 #endif
       /* It doesn't work to autosave while GC is in progress;
         the code used for auto-saving doesn't cope with the mark bit.  */
@@ -11078,8 +11181,17 @@ handle_interrupt ()
        Vquit_flag = Qt;
     }
 
+/* TODO: The longjmp in this call throws the NS event loop integration off,
+         and it seems to do fine without this.  Probably some attention
+        needs to be paid to the setting of waiting_for_input in
+         wait_reading_process_output() under HAVE_NS because of the call
+         to ns_select there (needed because otherwise events aren't picked up
+         outside of polling since we don't get SIGIO like X and we don't have a
+         separate event loop thread like W32. */
+#ifndef HAVE_NS
   if (waiting_for_input && !echoing)
       quit_throw_to_read_char ();
+#endif
 }
 
 /* Handle a C-g by making read_char return C-g.  */
@@ -11107,7 +11219,7 @@ quit_throw_to_read_char ()
   if (FRAMEP (internal_last_event_frame)
       && !EQ (internal_last_event_frame, selected_frame))
     do_switch_frame (make_lispy_switch_frame (internal_last_event_frame),
-                    0, 0);
+                    0, 0, Qnil);
 
   _longjmp (getcjmp, 1);
 }
@@ -11136,7 +11248,7 @@ See also `current-input-mode'.  */)
 #endif /* NO_SOCK_SIGIO */
     }
   else
-#endif
+#endif /* HAVE_X_WINDOWS */
     new_interrupt_input = !NILP (interrupt);
 #else /* not SIGIO */
   new_interrupt_input = 0;
@@ -11178,7 +11290,7 @@ See also `current-input-mode'.  */)
 {
   struct terminal *t = get_terminal (terminal, 1);
   struct tty_display_info *tty;
-  if (t == NULL || t->type != output_termcap)
+  if (t == NULL || (t->type != output_termcap && t->type != output_msdos_raw))
     return Qnil;
   tty = t->display_info.tty;
 
@@ -11223,7 +11335,7 @@ See also `current-input-mode'.  */)
   struct tty_display_info *tty;
   int new_meta;
 
-  if (t == NULL || t->type != output_termcap)
+  if (t == NULL || (t->type != output_termcap && t->type != output_msdos_raw))
     return Qnil;
   tty = t->display_info.tty;
 
@@ -11263,7 +11375,7 @@ See also `current-input-mode'.  */)
 {
   struct terminal *t = get_named_tty ("/dev/tty");
   struct tty_display_info *tty;
-  if (t == NULL || t->type != output_termcap)
+  if (t == NULL || (t->type != output_termcap && t->type != output_msdos_raw))
     return Qnil;
   tty = t->display_info.tty;
 
@@ -11327,7 +11439,7 @@ The elements of this list correspond to the arguments of
   struct frame *sf = XFRAME (selected_frame);
 
   val[0] = interrupt_input ? Qt : Qnil;
-  if (FRAME_TERMCAP_P (sf))
+  if (FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
     {
       val[1] = FRAME_TTY (sf)->flow_control ? Qt : Qnil;
       val[2] = (FRAME_TTY (sf)->meta_key == 2
@@ -11513,6 +11625,9 @@ init_keyboard ()
   input_pending = 0;
   interrupt_input_blocked = 0;
   interrupt_input_pending = 0;
+#ifdef SYNC_INPUT
+  pending_signals = 0;
+#endif
 
   /* This means that command_loop_1 won't try to select anything the first
      time through.  */
@@ -11864,10 +11979,7 @@ syms_of_keyboard ()
   defsubr (&Sposn_at_point);
   defsubr (&Sposn_at_x_y);
 
-  DEFVAR_LISP ("last-command-char", &last_command_char,
-              doc: /* Last input event that was part of a command.  */);
-
-  DEFVAR_LISP_NOPRO ("last-command-event", &last_command_char,
+  DEFVAR_LISP ("last-command-event", &last_command_event,
                     doc: /* Last input event that was part of a command.  */);
 
   DEFVAR_LISP ("last-nonmenu-event", &last_nonmenu_event,
@@ -11876,12 +11988,9 @@ Mouse menus give back keys that don't look like mouse events;
 this variable holds the actual mouse event that led to the menu,
 so that you can determine whether the command was run by mouse or not.  */);
 
-  DEFVAR_LISP ("last-input-char", &last_input_char,
+  DEFVAR_LISP ("last-input-event", &last_input_event,
               doc: /* Last input event.  */);
 
-  DEFVAR_LISP_NOPRO ("last-input-event", &last_input_char,
-                    doc: /* Last input event.  */);
-
   DEFVAR_LISP ("unread-command-events", &Vunread_command_events,
               doc: /* List of events to be read as the command input.
 These events are processed first, before actual keyboard input.
@@ -12111,7 +12220,7 @@ Buffer modification stores t in this variable.  */);
   staticpro (&Qdeactivate_mark);
 
   DEFVAR_LISP ("command-hook-internal", &Vcommand_hook_internal,
-              doc: /* Temporary storage of pre-command-hook or post-command-hook.  */);
+              doc: /* Temporary storage of `pre-command-hook' or `post-command-hook'.  */);
   Vcommand_hook_internal = Qnil;
 
   DEFVAR_LISP ("pre-command-hook", &Vpre_command_hook,
@@ -12222,7 +12331,7 @@ 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.  Contrary to `function-key-map',
+`input-key-map' with its binding.  Contrary to `function-key-map',
 this map applies its rebinding regardless of the presence of an ordinary
 binding.  So it is more like `key-translation-map' except that it applies
 before `function-key-map' rather than after.
@@ -12288,7 +12397,7 @@ to be used as input.  If it wants to put back some events
 to be reconsidered, separately, by the input method,
 it can add them to the beginning of `unread-command-events'.
 
-The input method function can find in `input-method-previous-method'
+The input method function can find in `input-method-previous-message'
 the previous echo area message.
 
 The input method function should refer to the variables
@@ -12376,6 +12485,10 @@ keys_of_keyboard ()
 
   initial_define_lispy_key (Vspecial_event_map, "delete-frame",
                            "handle-delete-frame");
+  initial_define_lispy_key (Vspecial_event_map, "ns-put-working-text",
+                           "ns-put-working-text");
+  initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text",
+                           "ns-unput-working-text");
   /* Here we used to use `ignore-event' which would simple set prefix-arg to
      current-prefix-arg, as is done in `handle-switch-frame'.
      But `handle-switch-frame is not run from the special-map.