]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
(print_error_message): Print data of `end-of-file'
[gnu-emacs] / src / keyboard.c
index 19f4ef0ea9ad6457e0aee41d8f0c9ea660f021cb..47fb2bc5b394f58a60017581d387343f811b909b 100644 (file)
@@ -203,13 +203,18 @@ static int echoing;
 
 static struct kboard *ok_to_echo_at_next_pause;
 
-/* The kboard currently echoing, or null for none.  Set in echo_now to
-   the kboard echoing.  Reset to 0 in cancel_echoing.  If non-null,
-   and a current echo area message exists, we know that it comes from
-   echoing.  */
+/* The kboard last echoing, or null for none.  Reset to 0 in
+   cancel_echoing.  If non-null, and a current echo area message
+   exists, and echo_message_buffer is eq to the current message
+   buffer, we know that the message comes from echo_kboard.  */
 
 static struct kboard *echo_kboard;
 
+/* The buffer used for echoing.  Set in echo_now, reset in
+   cancel_echoing.  */
+
+static Lisp_Object echo_message_buffer;
+
 /* Nonzero means disregard local maps for the menu bar.  */
 static int inhibit_local_menu_bar_menus;
 
@@ -770,11 +775,14 @@ echo_now ()
     }
 
   echoing = 1;
-  echo_kboard = current_kboard;
   message2_nolog (current_kboard->echobuf, strlen (current_kboard->echobuf),
                  ! NILP (current_buffer->enable_multibyte_characters));
   echoing = 0;
 
+  /* Record in what buffer we echoed, and from which kboard.  */
+  echo_message_buffer = echo_area_buffer[0];
+  echo_kboard = current_kboard;
+
   if (waiting_for_input && !NILP (Vquit_flag))
     quit_throw_to_read_char ();
 }
@@ -787,8 +795,9 @@ cancel_echoing ()
   current_kboard->immediate_echo = 0;
   current_kboard->echoptr = current_kboard->echobuf;
   current_kboard->echo_after_prompt = -1;
-  ok_to_echo_at_next_pause = 0;
-  echo_kboard = 0;
+  ok_to_echo_at_next_pause = NULL;
+  echo_kboard = NULL;
+  echo_message_buffer = Qnil;
 }
 
 /* Return the length of the current echo string.  */
@@ -858,6 +867,14 @@ recursive_edit_1 ()
       specbind (Qstandard_input, Qt);
     }
 
+#ifdef HAVE_X_WINDOWS
+  /* The command loop has started a busy-cursor timer, so we have to
+     cancel it here, otherwise it will fire because the recursive edit
+     can take some time.  */
+  if (display_busy_cursor_p)
+    cancel_busy_cursor ();
+#endif
+
   val = command_loop ();
   if (EQ (val, Qt))
     Fsignal (Qquit, Qnil);
@@ -1167,6 +1184,10 @@ DEFUN ("top-level", Ftop_level, Stop_level, 0, 0, "",
   "Exit all recursive editing levels.")
   ()
 {
+#ifdef HAVE_X_WINDOWS
+  if (display_busy_cursor_p)
+    cancel_busy_cursor ();
+#endif
   Fthrow (Qtop_level, Qnil);
 }
 
@@ -1519,18 +1540,18 @@ command_loop_1 ()
 
 #ifdef HAVE_X_WINDOWS
          if (display_busy_cursor_p)
-           {
-             if (inhibit_busy_cursor != 2)
-               inhibit_busy_cursor = 0;
-             if (!inhibit_busy_cursor)
-               Fx_show_busy_cursor ();
-           }
+           start_busy_cursor ();
 #endif
 
          nonundocount = 0;
          if (NILP (current_kboard->Vprefix_arg))
            Fundo_boundary ();
          Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
+
+#ifdef HAVE_X_WINDOWS
+         if (display_busy_cursor_p)
+           cancel_busy_cursor ();
+#endif
        }
     directly_done: ;
       current_kboard->Vlast_prefix_arg = Vcurrent_prefix_arg;
@@ -2066,19 +2087,43 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        }
     }
 
-  /* Message turns off echoing unless more keystrokes turn it on again. */
-  if (/* There is a current message.  */
+  /* Message turns off echoing unless more keystrokes turn it on again.
+     
+     The code in 20.x for the condition was
+
+     1. echo_area_glyphs && *echo_area_glyphs
+     2. && echo_area_glyphs != current_kboard->echobuf
+     3. && ok_to_echo_at_next_pause != echo_area_glyphs
+
+     (1) means there's a current message displayed
+     
+     (2) means it's not the message from echoing from the current
+     kboard.
+     
+     (3) There's only one place in 20.x where ok_to_echo_at_next_pause
+     is set to a non-null value.  This is done in read_char and it is
+     set to echo_area_glyphs after a call to echo_char.  That means
+     ok_to_echo_at_next_pause is either null or
+     current_kboard->echobuf with the appropriate current_kboard at
+     that time.
+
+     So, condition (3) means in clear text ok_to_echo_at_next_pause
+     must be either null, or the current message isn't from echoing at
+     all, or it's from echoing from a different kboard than the
+     current one.  */
+  
+  if (/* There currently something in the echo area  */
       !NILP (echo_area_buffer[0])
-      /* And we're not echoing from this kboard.  */
-      && echo_kboard != current_kboard
-      /* And it's either not ok to echo (ok_to_echo == NULL), or the
-        last char echoed was from a different kboard.  */
-      && ok_to_echo_at_next_pause != echo_kboard)
+      && (/* And it's either not from echoing.  */
+         !EQ (echo_area_buffer[0], echo_message_buffer)
+         /* Or it's an echo from a different kboard.  */
+         || echo_kboard != current_kboard
+         /* Or we explicitly allow overwriting whatever there is.  */
+         || ok_to_echo_at_next_pause == NULL))
     cancel_echoing ();
   else
-    /* If already echoing, continue.  */
     echo_dash ();
-
+      
   /* Try reading a character via menu prompting in the minibuf.
      Try this before the sit-for, because the sit-for
      would do the wrong thing if we are supposed to do
@@ -2175,7 +2220,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
          int sec, usec;
          double duration = extract_float (Vecho_keystrokes);
          sec = (int) duration;
-         usec += (duration - sec) * 1000000;
+         usec = (duration - sec) * 1000000;
          save_getcjmp (save_jump);
          restore_getcjmp (local_getcjmp);
          tem0 = sit_for (sec, usec, 1, 1, 0);
@@ -3618,7 +3663,7 @@ timer_check (do_it_now)
        }
       vector = XVECTOR (chosen_timer)->contents;
        
-      /* If timer is rupe, run it if it hasn't been run.  */
+      /* If timer is ripe, run it if it hasn't been run.  */
       if (EMACS_TIME_NEG_P (difference)
          || (EMACS_SECS (difference) == 0
              && EMACS_USECS (difference) == 0))
@@ -3627,9 +3672,6 @@ timer_check (do_it_now)
            {
              int was_locked = single_kboard;
              int count = specpdl_ptr - specpdl;
-#ifdef HAVE_WINDOW_SYSTEM
-             int old_inhibit_busy_cursor = inhibit_busy_cursor;
-#endif
 
              /* Mark the timer as triggered to prevent problems if the lisp
                 code fails to reschedule it right.  */
@@ -3637,17 +3679,9 @@ timer_check (do_it_now)
 
              specbind (Qinhibit_quit, Qt);
 
-#ifdef HAVE_WINDOW_SYSTEM
-             inhibit_busy_cursor = 2;
-#endif
-             
              call1 (Qtimer_event_handler, chosen_timer);
              timers_run++;
 
-#ifdef HAVE_WINDOW_SYSTEM
-             inhibit_busy_cursor = old_inhibit_busy_cursor;
-#endif
-
              unbind_to (count, Qnil);
 
              /* Resume allowing input from any kboard, if that was true before.  */
@@ -4084,10 +4118,7 @@ static char *iso_lispy_function_keys[] =
 
 #endif /* not HAVE_NTGUI */
 
-static char *lispy_mouse_names[] =
-{
-  "mouse-1", "mouse-2", "mouse-3", "mouse-4", "mouse-5"
-};
+Lisp_Object Vlispy_mouse_stem;
 
 #ifdef WINDOWSNT
 /* mouse-wheel events are generated by the wheel on devices such as
@@ -4273,9 +4304,6 @@ make_lispy_event (event)
        Lisp_Object *start_pos_ptr;
        Lisp_Object start_pos;
 
-       if (button < 0 || button >= NUM_MOUSE_BUTTONS)
-         abort ();
-
        /* Build the position as appropriate for this mouse click.  */
        if (event->kind == mouse_click)
          {
@@ -4427,6 +4455,13 @@ make_lispy_event (event)
          }
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 
+       if (button >= XVECTOR (button_down_location)->size)
+         {
+           button_down_location = larger_vector (button_down_location,
+                                                 button + 1, Qnil);
+           mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
+         }
+       
        start_pos_ptr = &XVECTOR (button_down_location)->contents[button];
 
        start_pos = *start_pos_ptr;
@@ -4516,10 +4551,10 @@ make_lispy_event (event)
 
          head = modify_event_symbol (button,
                                      event->modifiers,
-                                     Qmouse_click, Qnil,
-                                     lispy_mouse_names, &mouse_syms,
-                                     (sizeof (lispy_mouse_names)
-                                      / sizeof (lispy_mouse_names[0])));
+                                     Qmouse_click, Vlispy_mouse_stem,
+                                     NULL,
+                                     &mouse_syms,
+                                     XVECTOR (mouse_syms)->size);
          if (event->modifiers & drag_modifier)
            return Fcons (head,
                          Fcons (start_pos,
@@ -4577,10 +4612,10 @@ make_lispy_event (event)
        /* Get the symbol we should use for the mouse click.  */
        head = modify_event_symbol (event->code,
                                    event->modifiers,
-                                   Qmouse_click, Qnil,
-                                   lispy_mouse_names, &mouse_syms,
-                                   (sizeof (lispy_mouse_names)
-                                    / sizeof (lispy_mouse_names[0])));
+                                   Qmouse_click, 
+                                   Vlispy_mouse_stem,
+                                   NULL, &mouse_syms,
+                                   XVECTOR (mouse_syms)->size);
        return Fcons (head, Fcons (position, Qnil));
       }
       
@@ -4595,9 +4630,6 @@ make_lispy_event (event)
        Lisp_Object *start_pos_ptr;
        Lisp_Object start_pos;
 
-       if (button < 0 || button >= NUM_MOUSE_BUTTONS)
-         abort ();
-
        {
          Lisp_Object window;
          Lisp_Object portion_whole;
@@ -4624,10 +4656,10 @@ make_lispy_event (event)
 
          head = modify_event_symbol (button,
                                      event->modifiers,
-                                     Qmouse_click, Qnil,
-                                     lispy_mouse_names, &mouse_syms,
-                                     (sizeof (lispy_mouse_names)
-                                      / sizeof (lispy_mouse_names[0])));
+                                     Qmouse_click, 
+                                     Vlispy_mouse_stem,
+                                     NULL, &mouse_syms,
+                                     XVECTOR (mouse_syms)->size);
          return Fcons (head,
                        Fcons (position,
                               Qnil));
@@ -4673,7 +4705,7 @@ make_lispy_event (event)
            else
              XSETINT (posn,
                       buffer_posn_from_coords (XWINDOW (window),
-                                               column, row));
+                                               &column, &row));
          }
 
        {
@@ -5217,8 +5249,11 @@ reorder_modifiers (symbol)
    is the name of the i'th symbol.  TABLE_SIZE is the number of elements
    in the table.
 
-   Alternatively, NAME_ALIST is an alist mapping codes into symbol names.
-   NAME_ALIST is used if it is non-nil; otherwise NAME_TABLE is used.
+   Alternatively, NAME_ALIST_OR_STEM is either an alist mapping codes
+   into symbol names, or a string specifying a name stem used to
+   contruct a symbol name or the form `STEM-N', where N is the decimal
+   representation of SYMBOL_NUM.  NAME_ALIST_OR_STEM is used if it is
+   non-nil; otherwise NAME_TABLE is used.
 
    SYMBOL_TABLE should be a pointer to a Lisp_Object whose value will
    persist between calls to modify_event_symbol that it can use to
@@ -5238,12 +5273,12 @@ reorder_modifiers (symbol)
    in the symbol's name.  */
 
 static Lisp_Object
-modify_event_symbol (symbol_num, modifiers, symbol_kind, name_alist,
+modify_event_symbol (symbol_num, modifiers, symbol_kind, name_alist_or_stem,
                      name_table, symbol_table, table_size)
      int symbol_num;
      unsigned modifiers;
      Lisp_Object symbol_kind;
-     Lisp_Object name_alist;
+     Lisp_Object name_alist_or_stem;
      char **name_table;
      Lisp_Object *symbol_table;
      unsigned int table_size;
@@ -5283,8 +5318,16 @@ modify_event_symbol (symbol_num, modifiers, symbol_kind, name_alist,
   if (NILP (value))
     {
       /* No; let's create it.  */
-      if (!NILP (name_alist))
-       value = Fcdr_safe (Fassq (symbol_int, name_alist));
+      if (CONSP (name_alist_or_stem))
+       value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
+      else if (STRINGP (name_alist_or_stem))
+       {
+         int len = STRING_BYTES (XSTRING (name_alist_or_stem));
+         char *buf = (char *) alloca (len + 50);
+         sprintf (buf, "%s-%d", XSTRING (name_alist_or_stem)->data,
+                  XINT (symbol_int) + 1);
+         value = intern (buf);
+       }
       else if (name_table != 0 && name_table[symbol_num])
        value = intern (name_table[symbol_num]);
 
@@ -7853,8 +7896,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                      pos = XCDR (string);
                      string = XCAR (string);
                      
-                     if (pos >= 0
-                         && pos < XSTRING (string)->size
+                     if (XINT (pos) >= 0
+                         && XINT (pos) < XSTRING (string)->size
                          && (map = Fget_text_property (pos, Qlocal_map,
                                                        string),
                              !NILP (map)))
@@ -8493,10 +8536,20 @@ DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0,
       this_single_command_key_start = 0;
     }
 
+#ifdef HAVE_X_WINDOWS
+  if (display_busy_cursor_p)
+    cancel_busy_cursor ();
+#endif
+
   i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
                         prompt, ! NILP (dont_downcase_last),
                         ! NILP (can_return_switch_frame), 0);
 
+#ifdef HAVE_X_WINDOWS
+  if (display_busy_cursor_p)
+    start_busy_cursor ();
+#endif
+
   if (i == -1)
     {
       Vquit_flag = Qt;
@@ -8538,10 +8591,20 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
       this_single_command_key_start = 0;
     }
 
+#ifdef HAVE_X_WINDOWS
+  if (display_busy_cursor_p)
+    cancel_busy_cursor ();
+#endif
+
   i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
                         prompt, ! NILP (dont_downcase_last),
                         ! NILP (can_return_switch_frame), 0);
 
+#ifdef HAVE_X_WINDOWS
+  if (display_busy_cursor_p)
+    start_busy_cursor ();
+#endif
+
   if (i == -1)
     {
       Vquit_flag = Qt;
@@ -9615,6 +9678,9 @@ struct event_head head_table[] = {
 void
 syms_of_keyboard ()
 {
+  Vlispy_mouse_stem = build_string ("mouse");
+  staticpro (&Vlispy_mouse_stem);
+  
   /* Tool-bars.  */
   QCimage = intern (":image");
   staticpro (&QCimage);
@@ -9780,8 +9846,10 @@ syms_of_keyboard ()
       }
   }
 
-  button_down_location = Fmake_vector (make_number (NUM_MOUSE_BUTTONS), Qnil);
+  button_down_location = Fmake_vector (make_number (1), Qnil);
   staticpro (&button_down_location);
+  mouse_syms = Fmake_vector (make_number (1), Qnil);
+  staticpro (&mouse_syms);
 
   {
     int i;
@@ -9817,9 +9885,6 @@ syms_of_keyboard ()
   func_key_syms = Qnil;
   staticpro (&func_key_syms);
 
-  mouse_syms = Qnil;
-  staticpro (&mouse_syms);
-
 #ifdef WINDOWSNT
   mouse_wheel_syms = Qnil;
   staticpro (&mouse_wheel_syms);