]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
* keyboard.c (read_char): New arg END_TIME specifying timeout.
[gnu-emacs] / src / keyboard.c
index 56419ef567909961032de971188ee50fb45c75f5..23e10aefac1f5c2b0e259490ee57dbba615e523b 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 Free Software Foundation, Inc.
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -242,6 +242,9 @@ static int inhibit_local_menu_bar_menus;
 /* Nonzero means C-g should cause immediate error-signal.  */
 int immediate_quit;
 
+/* The user's hook function for outputting an error message.  */
+Lisp_Object Vcommand_error_function;
+
 /* The user's ERASE setting.  */
 Lisp_Object Vtty_erase_char;
 
@@ -381,12 +384,15 @@ Lisp_Object real_this_command;
    command is stored in this-original-command.  It is nil otherwise.  */
 Lisp_Object Vthis_original_command;
 
-/* The value of point when the last command was executed.  */
+/* The value of point when the last command was started.  */
 int last_point_position;
 
 /* The buffer that was current when the last command was started.  */
 Lisp_Object last_point_position_buffer;
 
+/* The window that was selected when the last command was started.  */
+Lisp_Object last_point_position_window;
+
 /* The frame in which the last input event occurred, or Qmacro if the
    last event came from a macro.  We use this to determine when to
    generate switch-frame events.  This may be cleared by functions
@@ -527,6 +533,9 @@ Lisp_Object Qlanguage_change;
 #endif
 Lisp_Object Qdrag_n_drop;
 Lisp_Object Qsave_session;
+#ifdef MAC_OS
+Lisp_Object Qmac_apple_event;
+#endif
 
 /* Lisp_Object Qmouse_movement; - also an event header */
 
@@ -643,6 +652,11 @@ static EMACS_TIME timer_idleness_start_time;
 
 static EMACS_TIME timer_last_idleness_start_time;
 
+/* If non-nil, events produced by disabled menu items and tool-bar
+   buttons are not ignored.  Help functions bind this to allow help on
+   those items and buttons.  */
+Lisp_Object Venable_disabled_menus_and_buttons;
+
 \f
 /* Global variable declarations.  */
 
@@ -784,6 +798,8 @@ echo_char (c)
          else
            echo_string = concat2 (echo_string, build_string (" "));
        }
+      else if (STRINGP (echo_string))
+       echo_string = concat2 (echo_string, build_string (" "));
 
       current_kboard->echo_string
        = concat2 (echo_string, make_string (buffer, ptr - buffer));
@@ -814,16 +830,16 @@ echo_dash ()
   /* Do nothing if we have already put a dash at the end.  */
   if (SCHARS (current_kboard->echo_string) > 1)
     {
-         Lisp_Object last_char, prev_char, idx;
+      Lisp_Object last_char, prev_char, idx;
 
-         idx = make_number (SCHARS (current_kboard->echo_string) - 2);
-         prev_char = Faref (current_kboard->echo_string, idx);
+      idx = make_number (SCHARS (current_kboard->echo_string) - 2);
+      prev_char = Faref (current_kboard->echo_string, idx);
 
-         idx = make_number (SCHARS (current_kboard->echo_string) - 1);
-         last_char = Faref (current_kboard->echo_string, idx);
+      idx = make_number (SCHARS (current_kboard->echo_string) - 1);
+      last_char = Faref (current_kboard->echo_string, idx);
 
-         if (XINT (last_char) == '-' && XINT (prev_char) != ' ')
-           return;
+      if (XINT (last_char) == '-' && XINT (prev_char) != ' ')
+       return;
     }
 
   /* Put a dash at the end of the buffer temporarily,
@@ -990,7 +1006,7 @@ recursive_edit_1 ()
   /* Handle throw from read_minibuf when using minibuffer
      while it's active but we're in another window.  */
   if (STRINGP (val))
-    Fsignal (Qerror, Fcons (val, Qnil));
+    xsignal1 (Qerror, val);
 
   return unbind_to (count, Qnil);
 }
@@ -1217,52 +1233,47 @@ cmd_error_internal (data, context)
      Lisp_Object data;
      char *context;
 {
-  Lisp_Object stream;
-  int kill_emacs_p = 0;
   struct frame *sf = SELECTED_FRAME ();
 
+  /* The immediate context is not interesting for Quits,
+     since they are asyncronous.  */
+  if (EQ (XCAR (data), Qquit))
+    Vsignaling_function = Qnil;
+
   Vquit_flag = Qnil;
   Vinhibit_quit = Qt;
-  clear_message (1, 0);
 
+  /* Use user's specified output function if any.  */
+  if (!NILP (Vcommand_error_function))
+    call3 (Vcommand_error_function, data,
+          build_string (context ? context : ""),
+          Vsignaling_function);
   /* If the window system or terminal frame hasn't been initialized
-     yet, or we're not interactive, it's best to dump this message out
-     to stderr and exit.  */
-  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))
-      || noninteractive)
-    {
-      stream = Qexternal_debugging_output;
-      kill_emacs_p = 1;
+     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))
+          || noninteractive)
+    {
+      print_error_message (data, Qexternal_debugging_output,
+                          context, Vsignaling_function);
+      Fterpri (Qexternal_debugging_output);
+      Fkill_emacs (make_number (-1));
     }
   else
     {
+      clear_message (1, 0);
       Fdiscard_input ();
       message_log_maybe_newline ();
       bitch_at_user ();
-      stream = Qt;
-    }
-
-  /* The immediate context is not interesting for Quits,
-     since they are asyncronous.  */
-  if (EQ (XCAR (data), Qquit))
-    Vsignaling_function = Qnil;
 
-  print_error_message (data, stream, context, Vsignaling_function);
+      print_error_message (data, Qt, context, Vsignaling_function);
+    }
 
   Vsignaling_function = Qnil;
-
-  /* If the window system or terminal frame hasn't been initialized
-     yet, or we're in -batch mode, this error should cause Emacs to exit.  */
-  if (kill_emacs_p)
-    {
-      Fterpri (stream);
-      Fkill_emacs (make_number (-1));
-    }
 }
 \f
 Lisp_Object command_loop_1 ();
@@ -1405,7 +1416,7 @@ command_loop_1 ()
   Lisp_Object keybuf[30];
   int i;
   int no_direct;
-  int prev_modiff;
+  int prev_modiff = 0;
   struct buffer *prev_buffer = NULL;
 #ifdef MULTI_KBOARD
   int was_locked = single_kboard;
@@ -1441,8 +1452,6 @@ command_loop_1 ()
        safe_run_hooks (Qdeferred_action_function);
     }
 
-  Vmemory_full = Qnil;
-
   /* Do this after running Vpost_command_hook, for consistency.  */
   current_kboard->Vlast_command = Vthis_command;
   current_kboard->Vreal_last_command = real_this_command;
@@ -1479,7 +1488,8 @@ command_loop_1 ()
          int count = SPECPDL_INDEX ();
          specbind (Qinhibit_quit, Qt);
 
-         Fsit_for (Vminibuffer_message_timeout, Qnil, Qnil);
+         sit_for (Vminibuffer_message_timeout, 0, 2);
+
          /* Clear the echo area.  */
          message2 (0, 0, 0);
          safe_run_hooks (Qecho_area_clear_hook);
@@ -1580,6 +1590,7 @@ command_loop_1 ()
       prev_buffer = current_buffer;
       prev_modiff = MODIFF;
       last_point_position = PT;
+      last_point_position_window = selected_window;
       XSETBUFFER (last_point_position_buffer, prev_buffer);
 
       /* By default, we adjust point to a boundary of a region that
@@ -2374,15 +2385,20 @@ do { if (polling_stopped_here) start_polling ();        \
    if we used a mouse menu to read the input, or zero otherwise.  If
    USED_MOUSE_MENU is null, we don't dereference 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.
+
    Value is t if we showed a menu and the user rejected it.  */
 
 Lisp_Object
-read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
+read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
      int commandflag;
      int nmaps;
      Lisp_Object *maps;
      Lisp_Object prev_event;
      int *used_mouse_menu;
+     EMACS_TIME *end_time;
 {
   volatile Lisp_Object c;
   int count;
@@ -2662,6 +2678,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
      start echoing if enough time elapses.  */
 
   if (minibuf_level == 0
+      && !end_time
       && !current_kboard->immediate_echo
       && this_command_key_count > 0
       && ! noninteractive
@@ -2677,8 +2694,6 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
          /* Or not echoing before and echoing allowed.  */
          || (!echo_kboard && ok_to_echo_at_next_pause)))
     {
-      Lisp_Object tem0;
-
       /* After a mouse event, start echoing right away.
         This is because we are probably about to display a menu,
         and we don't want to delay before doing so.  */
@@ -2686,13 +2701,11 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        echo_now ();
       else
        {
-         int sec, usec;
-         double duration = extract_float (Vecho_keystrokes);
-         sec = (int) duration;
-         usec = (duration - sec) * 1000000;
+         Lisp_Object tem0;
+
          save_getcjmp (save_jump);
          restore_getcjmp (local_getcjmp);
-         tem0 = sit_for (sec, usec, 1, 1, 0);
+         tem0 = sit_for (Vecho_keystrokes, 1, 1);
          restore_getcjmp (save_jump);
          if (EQ (tem0, Qt)
              && ! CONSP (Vunread_command_events))
@@ -2759,11 +2772,11 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
          && XINT (Vauto_save_timeout) > 0)
        {
          Lisp_Object tem0;
+         int timeout = delay_level * XFASTINT (Vauto_save_timeout) / 4;
 
          save_getcjmp (save_jump);
          restore_getcjmp (local_getcjmp);
-         tem0 = sit_for (delay_level * XFASTINT (Vauto_save_timeout) / 4,
-                         0, 1, 1, 0);
+         tem0 = sit_for (make_number (timeout), 1, 1);
          restore_getcjmp (save_jump);
 
          if (EQ (tem0, Qt)
@@ -2848,11 +2861,19 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
     {
       KBOARD *kb;
 
+      if (end_time)
+       {
+         EMACS_TIME now;
+         EMACS_GET_TIME (now);
+         if (EMACS_TIME_GE (now, *end_time))
+           goto exit;
+       }
+
       /* Actually read a character, waiting if necessary.  */
       save_getcjmp (save_jump);
       restore_getcjmp (local_getcjmp);
       timer_start_idle ();
-      c = kbd_buffer_get_event (&kb, used_mouse_menu);
+      c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
       restore_getcjmp (save_jump);
 
 #ifdef MULTI_KBOARD
@@ -3189,7 +3210,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
       cancel_echoing ();
       do
-       c = read_char (0, 0, 0, Qnil, 0);
+       c = read_char (0, 0, 0, Qnil, 0, NULL);
       while (BUFFERP (c));
       /* Remove the help from the frame */
       unbind_to (count, Qnil);
@@ -3199,7 +3220,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        {
          cancel_echoing ();
          do
-           c = read_char (0, 0, 0, Qnil, 0);
+           c = read_char (0, 0, 0, Qnil, 0, NULL);
          while (BUFFERP (c));
        }
     }
@@ -3878,9 +3899,10 @@ clear_event (event)
    We always read and discard one event.  */
 
 static Lisp_Object
-kbd_buffer_get_event (kbp, used_mouse_menu)
+kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
      KBOARD **kbp;
      int *used_mouse_menu;
+     EMACS_TIME *end_time;
 {
   register int c;
   Lisp_Object obj;
@@ -3924,13 +3946,24 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
       if (!NILP (do_mouse_tracking) && some_mouse_moved ())
        break;
 #endif
-      {
+      if (end_time)
+       {
+         EMACS_TIME duration;
+         EMACS_GET_TIME (duration);
+         EMACS_SUB_TIME (duration, *end_time, duration);
+         if (EMACS_TIME_NEG_P (duration))
+           return Qnil;
+         else
+           wait_reading_process_output (EMACS_SECS (duration),
+                                        EMACS_USECS (duration), 
+                                        -1, 1, Qnil, NULL, 0);
+       }
+      else
        wait_reading_process_output (0, 0, -1, 1, Qnil, NULL, 0);
 
-       if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
-         /* Pass 1 for EXPECT since we just waited to have input.  */
-         read_avail_input (1);
-      }
+      if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
+       /* Pass 1 for EXPECT since we just waited to have input.  */
+       read_avail_input (1);
 #endif /* not VMS */
     }
 
@@ -5054,7 +5087,11 @@ make_lispy_position (f, x, y, time)
       XSETINT (*x, wx);
       XSETINT (*y, wy);
 
-      if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
+      if (part == ON_TEXT)
+       {
+         wx += WINDOW_LEFT_MARGIN_WIDTH (w);
+       }
+      else if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
        {
          /* Mode line or header line.  Look for a string under
             the mouse that may have a `local-map' property.  */
@@ -5800,14 +5837,8 @@ make_lispy_event (event)
        Lisp_Object head, position;
        Lisp_Object files;
 
-       /* The frame_or_window field should be a cons of the frame in
-          which the event occurred and a list of the filenames
-          dropped.  */
-       if (! CONSP (event->frame_or_window))
-         abort ();
-
-       f = XFRAME (XCAR (event->frame_or_window));
-       files = XCDR (event->frame_or_window);
+       f = XFRAME (event->frame_or_window);
+       files = event->arg;
 
        /* Ignore mouse events that were made on frames that
           have been deleted.  */
@@ -5862,6 +5893,19 @@ make_lispy_event (event)
     case SAVE_SESSION_EVENT:
       return Qsave_session;
 
+#ifdef MAC_OS
+    case MAC_APPLE_EVENT:
+      {
+       Lisp_Object spec[2];
+
+       spec[0] = event->x;
+       spec[1] = event->y;
+       return Fcons (Qmac_apple_event,
+                     Fcons (Fvector (2, spec),
+                            Fcons (event->arg, Qnil)));
+      }
+#endif
+
       /* The 'kind' field of the event is something we don't recognize.  */
     default:
       abort ();
@@ -7252,7 +7296,9 @@ parse_menu_item (item, notreal, inmenubar)
       if (SYMBOLP (item))
        {
          tem = Fget (item, Qmenu_enable);
-         if (!NILP (tem))
+         if (!NILP (Venable_disabled_menus_and_buttons))
+           AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt;
+         else if (!NILP (tem))
            AREF (item_properties, ITEM_PROPERTY_ENABLE) = tem;
        }
     }
@@ -7281,7 +7327,12 @@ parse_menu_item (item, notreal, inmenubar)
              item = XCDR (item);
 
              if (EQ (tem, QCenable))
-               AREF (item_properties, ITEM_PROPERTY_ENABLE) = XCAR (item);
+               {
+                 if (!NILP (Venable_disabled_menus_and_buttons))
+                   AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt;
+                 else
+                   AREF (item_properties, ITEM_PROPERTY_ENABLE) = XCAR (item);
+               }
              else if (EQ (tem, QCvisible) && !notreal)
                {
                  /* If got a visible property and that evaluates to nil
@@ -7550,7 +7601,7 @@ Lisp_Object QCimage;
 /* Function prototypes.  */
 
 static void init_tool_bar_items P_ ((Lisp_Object));
-static void process_tool_bar_item P_ ((Lisp_Object, Lisp_Object));
+static void process_tool_bar_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, void*));
 static int parse_tool_bar_item P_ ((Lisp_Object, Lisp_Object));
 static void append_tool_bar_item P_ ((void));
 
@@ -7628,17 +7679,7 @@ tool_bar_items (reuse, nitems)
 
        keymap = get_keymap (access_keymap (maps[i], Qtool_bar, 1, 0, 1), 0, 1);
        if (CONSP (keymap))
-         {
-           Lisp_Object tail;
-
-           /* KEYMAP is a list `(keymap (KEY . BINDING) ...)'.  */
-           for (tail = keymap; CONSP (tail); tail = XCDR (tail))
-             {
-               Lisp_Object keydef = XCAR (tail);
-               if (CONSP (keydef))
-                 process_tool_bar_item (XCAR (keydef), XCDR (keydef));
-             }
-         }
+         map_keymap (keymap, process_tool_bar_item, Qnil, NULL, 1);
       }
 
   Vinhibit_quit = oquit;
@@ -7650,8 +7691,9 @@ tool_bar_items (reuse, nitems)
 /* Process the definition of KEY which is DEF.  */
 
 static void
-process_tool_bar_item (key, def)
-     Lisp_Object key, def;
+process_tool_bar_item (key, def, data, args)
+     Lisp_Object key, def, data;
+     void *args;
 {
   int i;
   extern Lisp_Object Qundefined;
@@ -7801,8 +7843,13 @@ parse_tool_bar_item (key, item)
       value = XCAR (XCDR (item));
 
       if (EQ (key, QCenable))
-       /* `:enable FORM'.  */
-       PROP (TOOL_BAR_ITEM_ENABLED_P) = value;
+       {
+         /* `:enable FORM'.  */
+         if (!NILP (Venable_disabled_menus_and_buttons))
+           PROP (TOOL_BAR_ITEM_ENABLED_P) = Qt;
+         else
+           PROP (TOOL_BAR_ITEM_ENABLED_P) = value;
+       }
       else if (EQ (key, QCvisible))
        {
          /* `:visible FORM'.  If got a visible property and that
@@ -8261,7 +8308,7 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
       orig_defn_macro = current_kboard->defining_kbd_macro;
       current_kboard->defining_kbd_macro = Qnil;
       do
-       obj = read_char (commandflag, 0, 0, Qt, 0);
+       obj = read_char (commandflag, 0, 0, Qt, 0, NULL);
       while (BUFFERP (obj));
       current_kboard->defining_kbd_macro = orig_defn_macro;
 
@@ -8361,7 +8408,7 @@ access_keymap_keyremap (map, key, prompt, do_funcall)
   /* Handle a symbol whose function definition is a keymap
      or an array.  */
   if (SYMBOLP (next) && !NILP (Ffboundp (next))
-      && (!NILP (Farrayp (XSYMBOL (next)->function))
+      && (ARRAYP (XSYMBOL (next)->function)
          || KEYMAPP (XSYMBOL (next)->function)))
     next = XSYMBOL (next)->function;
 
@@ -8634,7 +8681,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
   /* Read the first char of the sequence specially, before setting
      up any keymaps, in case a filter runs and switches buffers on us.  */
   first_event = read_char (NILP (prompt), 0, submaps, last_nonmenu_event,
-                          &junk);
+                          &junk, NULL);
 #endif /* GOBBLE_FIRST_EVENT */
 
   orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
@@ -8837,7 +8884,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
 #endif
            key = read_char (NILP (prompt), nmaps,
                             (Lisp_Object *) submaps, last_nonmenu_event,
-                            &used_mouse_menu);
+                            &used_mouse_menu, NULL);
          }
 
          /* read_char returns t when it shows a menu and the user rejects it.
@@ -9452,6 +9499,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
   /* Don't downcase the last character if the caller says don't.
      Don't downcase it if the result is undefined, either.  */
   if ((dont_downcase_last || first_binding >= nmaps)
+      && t > 0
       && t - 1 == original_uppercase_position)
     keybuf[t - 1] = original_uppercase;
 
@@ -9681,7 +9729,7 @@ a special event, so ignore the prefix argument and don't clear it.  */)
 
   while (1)
     {
-      final = Findirect_function (cmd);
+      final = Findirect_function (cmd, Qnil);
 
       if (CONSP (final) && (tem = Fcar (final), EQ (tem, Qautoload)))
        {
@@ -9741,7 +9789,13 @@ a special event, so ignore the prefix argument and don't clear it.  */)
 \f
 DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command,
        1, 1, "P",
-       doc: /* Read function name, then read its arguments and call it.  */)
+       doc: /* Read function name, then read its arguments and call it.
+
+To pass a numeric argument to the command you are invoking with, specify
+the numeric argument to this command.
+
+Noninteractively, the argument PREFIXARG is the prefix argument to
+give to the command you invoke, if it asks for an argument.  */)
      (prefixarg)
      Lisp_Object prefixarg;
 {
@@ -9847,19 +9901,18 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
                                      Qmouse_movement)))
     {
       /* But first wait, and skip the message if there is input.  */
-      int delay_time;
-      if (!NILP (echo_area_buffer[0]))
-       /* This command displayed something in the echo area;
-          so wait a few seconds, then display our suggestion message.  */
-       delay_time = (NUMBERP (Vsuggest_key_bindings)
-                     ? XINT (Vsuggest_key_bindings) : 2);
+      Lisp_Object waited;
+
+      /* If this command displayed something in the echo area;
+        wait a few seconds, then display our suggestion message.  */
+      if (NILP (echo_area_buffer[0]))
+       waited = sit_for (make_number (0), 0, 2);
+      else if (NUMBERP (Vsuggest_key_bindings))
+       waited = sit_for (Vminibuffer_message_timeout, 0, 2);
       else
-       /* This command left the echo area empty,
-          so display our message immediately.  */
-       delay_time = 0;
+       waited = sit_for (make_number (2), 0, 2);
 
-      if (!NILP (Fsit_for (make_number (delay_time), Qnil, Qnil))
-         && ! CONSP (Vunread_command_events))
+      if (!NILP (waited) && ! CONSP (Vunread_command_events))
        {
          Lisp_Object binding;
          char *newmessage;
@@ -9879,10 +9932,12 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
          message2_nolog (newmessage,
                          strlen (newmessage),
                          STRING_MULTIBYTE (binding));
-         if (!NILP (Fsit_for ((NUMBERP (Vsuggest_key_bindings)
-                               ? Vsuggest_key_bindings : make_number (2)),
-                              Qnil, Qnil))
-             && message_p)
+         if (NUMBERP (Vsuggest_key_bindings))
+           waited = sit_for (Vsuggest_key_bindings, 0, 2);
+         else
+           waited = sit_for (make_number (2), 0, 2);
+
+         if (!NILP (waited) && message_p)
            restore_message ();
 
          unbind_to (count, Qnil);
@@ -10592,11 +10647,11 @@ The `posn-' functions access elements of such lists.  */)
       CHECK_LIVE_WINDOW (frame_or_window);
 
       w = XWINDOW (frame_or_window);
-      XSETINT (x, (WINDOW_TO_FRAME_PIXEL_X (w, XINT (x))
+      XSETINT (x, (XINT (x)
+                  + WINDOW_LEFT_EDGE_X (w)
                   + (NILP (whole)
                      ? window_box_left_offset (w, TEXT_AREA)
-                     : - (WINDOW_LEFT_SCROLL_BAR_COLS (w)
-                          * WINDOW_FRAME_COLUMN_WIDTH (w)))));
+                     : 0)));
       XSETINT (y, WINDOW_TO_FRAME_PIXEL_Y (w, XINT (y)));
       frame_or_window = w->frame;
     }
@@ -10622,9 +10677,21 @@ The `posn-' functions access elements of such lists.  */)
 {
   Lisp_Object tem;
 
+  if (NILP (window))
+    window = selected_window;
+
   tem = Fpos_visible_in_window_p (pos, window, Qt);
   if (!NILP (tem))
-    tem = Fposn_at_x_y (XCAR (tem), XCAR (XCDR (tem)), window, Qnil);
+    {
+      Lisp_Object x = XCAR (tem);
+      Lisp_Object y = XCAR (XCDR (tem));
+
+      /* Point invisible due to hscrolling?  */
+      if (XINT (x) < 0)
+       return Qnil;
+      tem = Fposn_at_x_y (x, y, window, Qnil);
+    }
+
   return tem;
 }
 
@@ -10865,6 +10932,11 @@ syms_of_keyboard ()
   Qsave_session = intern ("save-session");
   staticpro (&Qsave_session);
 
+#ifdef MAC_OS
+  Qmac_apple_event = intern ("mac-apple-event");
+  staticpro (&Qmac_apple_event);
+#endif
+
   Qusr1_signal = intern ("usr1-signal");
   staticpro (&Qusr1_signal);
   Qusr2_signal = intern ("usr2-signal");
@@ -10955,6 +11027,7 @@ syms_of_keyboard ()
   Fset (Qinput_method_use_echo_area, Qnil);
 
   last_point_position_buffer = Qnil;
+  last_point_position_window = Qnil;
 
   {
     struct event_head *p;
@@ -11434,6 +11507,23 @@ If the value is not a number, such messages don't time out.  */);
 The value of that variable is passed to `quit-flag' and later causes a
 peculiar kind of quitting.  */);
   Vthrow_on_input = Qnil;
+
+  DEFVAR_LISP ("command-error-function", &Vcommand_error_function,
+              doc: /* If non-nil, function to output error messages.
+The arguments are the error data, a list of the form
+ (SIGNALED-CONDITIONS . SIGNAL-DATA)
+such as just as `condition-case' would bind its variable to,
+the context (a string which normally goes at the start of the message),
+and the Lisp function within which the error was signaled.  */);
+  Vcommand_error_function = Qnil;
+
+  DEFVAR_LISP ("enable-disabled-menus-and-buttons",
+              &Venable_disabled_menus_and_buttons,
+              doc: /* If non-nil, don't ignore events produced by disabled menu items and tool-bar.
+
+Help functions bind this to allow help on disabled menu items
+and tool-bar buttons.  */);
+  Venable_disabled_menus_and_buttons = Qnil;
 }
 
 void