/[emacs]/emacs/src/keyboard.c
ViewVC logotype

Diff of /emacs/src/keyboard.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.681 by monnier, Tue Jun 11 19:50:45 2002 UTC revision 1.681.2.1 by miles, Fri Apr 4 06:20:59 2003 UTC
# Line 1  Line 1 
1  /* Keyboard and mouse input; editor command loop.  /* Keyboard and mouse input; editor command loop.
2     Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99, 2000, 2001     Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99, 2000, 01, 02
3       Free Software Foundation, Inc.       Free Software Foundation, Inc.
4    
5  This file is part of GNU Emacs.  This file is part of GNU Emacs.
# Line 145  Lisp_Object recent_keys; /* A vector, ho Line 145  Lisp_Object recent_keys; /* A vector, ho
145  Lisp_Object this_command_keys;  Lisp_Object this_command_keys;
146  int this_command_key_count;  int this_command_key_count;
147    
148    /* 1 after calling Freset_this_command_lengths.
149       Usually it is 0.  */
150    int this_command_key_count_reset;
151    
152  /* This vector is used as a buffer to record the events that were actually read  /* This vector is used as a buffer to record the events that were actually read
153     by read_key_sequence.  */     by read_key_sequence.  */
154  Lisp_Object raw_keybuf;  Lisp_Object raw_keybuf;
# Line 169  int this_single_command_key_start; Line 173  int this_single_command_key_start;
173     before this command was read.  */     before this command was read.  */
174  static int before_command_key_count;  static int before_command_key_count;
175  static int before_command_echo_length;  static int before_command_echo_length;
 /* Values of before_command_key_count and before_command_echo_length  
    saved by reset-this-command-lengths.  */  
 static int before_command_key_count_1;  
 static int before_command_echo_length_1;  
 /* Flag set by reset-this-command-lengths,  
    saying to reset the lengths when add_command_key is called.  */  
 static int before_command_restore_flag;  
176    
177  extern int minbuf_level;  extern int minbuf_level;
178    
# Line 412  Lisp_Object Vecho_keystrokes; Line 409  Lisp_Object Vecho_keystrokes;
409  /* Form to evaluate (if non-nil) when Emacs is started.  */  /* Form to evaluate (if non-nil) when Emacs is started.  */
410  Lisp_Object Vtop_level;  Lisp_Object Vtop_level;
411    
412  /* User-supplied string to translate input characters through.  */  /* User-supplied table to translate input characters.  */
413  Lisp_Object Vkeyboard_translate_table;  Lisp_Object Vkeyboard_translate_table;
414    
415  /* Keymap mapping ASCII function key sequences onto their preferred forms.  */  /* Keymap mapping ASCII function key sequences onto their preferred forms.  */
# Line 505  static struct input_event kbd_buffer[KBD Line 502  static struct input_event kbd_buffer[KBD
502     queue.  That way, they'll be dequeued as dead frames or windows,     queue.  That way, they'll be dequeued as dead frames or windows,
503     but still valid Lisp objects.     but still valid Lisp objects.
504    
505     If kbd_buffer[i].kind != no_event, then     If kbd_buffer[i].kind != NO_EVENT, then
506    
507     AREF (kbd_buffer_gcpro, 2 * i) == kbd_buffer[i].frame_or_window.     AREF (kbd_buffer_gcpro, 2 * i) == kbd_buffer[i].frame_or_window.
508     AREF (kbd_buffer_gcpro, 2 * i + 1) == kbd_buffer[i].arg.  */     AREF (kbd_buffer_gcpro, 2 * i + 1) == kbd_buffer[i].arg.  */
# Line 550  Lisp_Object Qhelp_echo; Line 547  Lisp_Object Qhelp_echo;
547  /* Symbols to denote kinds of events.  */  /* Symbols to denote kinds of events.  */
548  Lisp_Object Qfunction_key;  Lisp_Object Qfunction_key;
549  Lisp_Object Qmouse_click;  Lisp_Object Qmouse_click;
550  #ifdef WINDOWSNT  #if defined(WINDOWSNT) || defined(MAC_OSX)
551  Lisp_Object Qmouse_wheel;  Lisp_Object Qmouse_wheel;
552    #endif
553    #ifdef WINDOWSNT
554  Lisp_Object Qlanguage_change;  Lisp_Object Qlanguage_change;
555  #endif  #endif
556  Lisp_Object Qdrag_n_drop;  Lisp_Object Qdrag_n_drop;
# Line 596  Lisp_Object Fthis_command_keys (); Line 595  Lisp_Object Fthis_command_keys ();
595  Lisp_Object Qextended_command_history;  Lisp_Object Qextended_command_history;
596  EMACS_TIME timer_check ();  EMACS_TIME timer_check ();
597    
598  extern Lisp_Object Vhistory_length;  extern Lisp_Object Vhistory_length, Vtranslation_table_for_input;
599    
600  extern char *x_get_keysym_name ();  extern char *x_get_keysym_name ();
601    
602  static void record_menu_key ();  static void record_menu_key ();
603    static int echo_length ();
604    
605  Lisp_Object Qpolling_period;  Lisp_Object Qpolling_period;
606    
# Line 644  int flow_control; Line 644  int flow_control;
644    
645  /* If we support a window system, turn on the code to poll periodically  /* If we support a window system, turn on the code to poll periodically
646     to detect C-g.  It isn't actually used when doing interrupt input.  */     to detect C-g.  It isn't actually used when doing interrupt input.  */
647  #ifdef HAVE_WINDOW_SYSTEM  #if defined(HAVE_WINDOW_SYSTEM) && !defined(USE_ASYNC_EVENTS)
648  #define POLL_FOR_INPUT  #define POLL_FOR_INPUT
649  #endif  #endif
650    
# Line 664  Lisp_Object Vglobal_disable_point_adjust Line 664  Lisp_Object Vglobal_disable_point_adjust
664    
665  static EMACS_TIME timer_idleness_start_time;  static EMACS_TIME timer_idleness_start_time;
666    
667    /* After Emacs stops being idle, this saves the last value
668       of timer_idleness_start_time from when it was idle.  */
669    
670    static EMACS_TIME timer_last_idleness_start_time;
671    
672    
673  /* Global variable declarations.  */  /* Global variable declarations.  */
674    
# Line 672  void (*keyboard_init_hook) (); Line 677  void (*keyboard_init_hook) ();
677    
678  static int read_avail_input P_ ((int));  static int read_avail_input P_ ((int));
679  static void get_input_pending P_ ((int *, int));  static void get_input_pending P_ ((int *, int));
680    static void get_filtered_input_pending P_ ((int *, int, int));
681  static int readable_events P_ ((int));  static int readable_events P_ ((int));
682    static int readable_filtered_events P_ ((int, int));
683  static Lisp_Object read_char_x_menu_prompt P_ ((int, Lisp_Object *,  static Lisp_Object read_char_x_menu_prompt P_ ((int, Lisp_Object *,
684                                                  Lisp_Object, int *));                                                  Lisp_Object, int *));
685  static Lisp_Object read_char_x_menu_prompt ();  static Lisp_Object read_char_x_menu_prompt ();
# Line 697  static void restore_getcjmp P_ ((jmp_buf Line 704  static void restore_getcjmp P_ ((jmp_buf
704  static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));  static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));
705  static void clear_event P_ ((struct input_event *));  static void clear_event P_ ((struct input_event *));
706  static void any_kboard_state P_ ((void));  static void any_kboard_state P_ ((void));
707    static SIGTYPE interrupt_signal P_ ((int signalnum));
708    
709  /* Nonzero means don't try to suspend even if the operating system seems  /* Nonzero means don't try to suspend even if the operating system seems
710     to support it.  */     to support it.  */
# Line 731  echo_char (c) Line 739  echo_char (c)
739        Lisp_Object echo_string;        Lisp_Object echo_string;
740    
741        echo_string = current_kboard->echo_string;        echo_string = current_kboard->echo_string;
742          
743        /* If someone has passed us a composite event, use its head symbol.  */        /* If someone has passed us a composite event, use its head symbol.  */
744        c = EVENT_HEAD (c);        c = EVENT_HEAD (c);
745    
# Line 741  echo_char (c) Line 749  echo_char (c)
749          }          }
750        else if (SYMBOLP (c))        else if (SYMBOLP (c))
751          {          {
752            struct Lisp_String *name = XSTRING (SYMBOL_NAME (c));            Lisp_Object name = SYMBOL_NAME (c);
753            int nbytes = STRING_BYTES (name);            int nbytes = SBYTES (name);
754              
755            if (size - (ptr - buffer) < nbytes)            if (size - (ptr - buffer) < nbytes)
756              {              {
757                int offset = ptr - buffer;                int offset = ptr - buffer;
# Line 752  echo_char (c) Line 760  echo_char (c)
760                ptr = buffer + offset;                ptr = buffer + offset;
761              }              }
762    
763            ptr += copy_text (name->data, ptr, nbytes,            ptr += copy_text (SDATA (name), ptr, nbytes,
764                              name->size_byte >= 0, 1);                              STRING_MULTIBYTE (name), 1);
765          }          }
766    
767        if ((NILP (echo_string) || SCHARS (echo_string) == 0)        if ((NILP (echo_string) || SCHARS (echo_string) == 0)
# Line 761  echo_char (c) Line 769  echo_char (c)
769          {          {
770            const char *text = " (Type ? for further options)";            const char *text = " (Type ? for further options)";
771            int len = strlen (text);            int len = strlen (text);
772              
773            if (size - (ptr - buffer) < len)            if (size - (ptr - buffer) < len)
774              {              {
775                int offset = ptr - buffer;                int offset = ptr - buffer;
# Line 810  echo_dash () Line 818  echo_dash ()
818    if (!current_kboard->immediate_echo    if (!current_kboard->immediate_echo
819        && SCHARS (current_kboard->echo_string) == 0)        && SCHARS (current_kboard->echo_string) == 0)
820      return;      return;
821          
822    /* Do nothing if we just printed a prompt.  */    /* Do nothing if we just printed a prompt.  */
823    if (current_kboard->echo_after_prompt    if (current_kboard->echo_after_prompt
824        == SCHARS (current_kboard->echo_string))        == SCHARS (current_kboard->echo_string))
825      return;      return;
826          
827    /* Put a dash at the end of the buffer temporarily,    /* Put a dash at the end of the buffer temporarily,
828       but make it go away when the next character is added.  */       but make it go away when the next character is added.  */
829    current_kboard->echo_string = concat2 (current_kboard->echo_string,    current_kboard->echo_string = concat2 (current_kboard->echo_string,
# Line 837  echo_now () Line 845  echo_now ()
845        for (i = 0; i < this_command_key_count; i++)        for (i = 0; i < this_command_key_count; i++)
846          {          {
847            Lisp_Object c;            Lisp_Object c;
848    
849              /* Set before_command_echo_length to the value that would
850                 have been saved before the start of this subcommand in
851                 command_loop_1, if we had already been echoing then.  */
852              if (i == this_single_command_key_start)
853                before_command_echo_length = echo_length ();
854    
855            c = XVECTOR (this_command_keys)->contents[i];            c = XVECTOR (this_command_keys)->contents[i];
856            if (! (EVENT_HAS_PARAMETERS (c)            if (! (EVENT_HAS_PARAMETERS (c)
857                   && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))                   && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
858              echo_char (c);              echo_char (c);
859          }          }
860    
861          /* Set before_command_echo_length to the value that would
862             have been saved before the start of this subcommand in
863             command_loop_1, if we had already been echoing then.  */
864          if (this_command_key_count == this_single_command_key_start)
865            before_command_echo_length = echo_length ();
866    
867          /* Put a dash at the end to invite the user to type more.  */
868        echo_dash ();        echo_dash ();
869      }      }
870    
871    echoing = 1;    echoing = 1;
872    message3_nolog (current_kboard->echo_string,    message3_nolog (current_kboard->echo_string,
873                    SBYTES (current_kboard->echo_string),                    SBYTES (current_kboard->echo_string),
874                    SMBP (current_kboard->echo_string));                    STRING_MULTIBYTE (current_kboard->echo_string));
875    echoing = 0;    echoing = 0;
876    
877    /* Record in what buffer we echoed, and from which kboard.  */    /* Record in what buffer we echoed, and from which kboard.  */
# Line 903  static void Line 926  static void
926  add_command_key (key)  add_command_key (key)
927       Lisp_Object key;       Lisp_Object key;
928  {  {
929    #if 0 /* Not needed after we made Freset_this_command_lengths
930             do the job immediately.  */
931    /* If reset-this-command-length was called recently, obey it now.    /* If reset-this-command-length was called recently, obey it now.
932       See the doc string of that function for an explanation of why.  */       See the doc string of that function for an explanation of why.  */
933    if (before_command_restore_flag)    if (before_command_restore_flag)
# Line 913  add_command_key (key) Line 938  add_command_key (key)
938        echo_truncate (before_command_echo_length_1);        echo_truncate (before_command_echo_length_1);
939        before_command_restore_flag = 0;        before_command_restore_flag = 0;
940      }      }
941    #endif
942    
943    if (this_command_key_count >= ASIZE (this_command_keys))    if (this_command_key_count >= ASIZE (this_command_keys))
944      this_command_keys = larger_vector (this_command_keys,      this_command_keys = larger_vector (this_command_keys,
# Line 927  add_command_key (key) Line 953  add_command_key (key)
953  Lisp_Object  Lisp_Object
954  recursive_edit_1 ()  recursive_edit_1 ()
955  {  {
956    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
957    Lisp_Object val;    Lisp_Object val;
958    
959    if (command_loop_level > 0)    if (command_loop_level > 0)
# Line 993  Alternately, `(throw 'exit t)' makes thi Line 1019  Alternately, `(throw 'exit t)' makes thi
1019  This function is called by the editor initialization to begin editing.  */)  This function is called by the editor initialization to begin editing.  */)
1020       ()       ()
1021  {  {
1022    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
1023    Lisp_Object buffer;    Lisp_Object buffer;
1024    
1025    command_loop_level++;    command_loop_level++;
# Line 1022  recursive_edit_unwind (info) Line 1048  recursive_edit_unwind (info)
1048  {  {
1049    if (BUFFERP (XCAR (info)))    if (BUFFERP (XCAR (info)))
1050      Fset_buffer (XCAR (info));      Fset_buffer (XCAR (info));
1051      
1052    if (NILP (XCDR (info)))    if (NILP (XCDR (info)))
1053      any_kboard_state ();      any_kboard_state ();
1054    else    else
1055      single_kboard_state ();      single_kboard_state ();
1056          
1057    command_loop_level--;    command_loop_level--;
1058    update_mode_lines = 1;    update_mode_lines = 1;
1059    return Qnil;    return Qnil;
# Line 1114  cmd_error (data) Line 1140  cmd_error (data)
1140    Lisp_Object old_level, old_length;    Lisp_Object old_level, old_length;
1141    char macroerror[50];    char macroerror[50];
1142    
1143    #ifdef HAVE_X_WINDOWS
1144      if (display_hourglass_p)
1145        cancel_hourglass ();
1146    #endif
1147    
1148    if (!NILP (executing_macro))    if (!NILP (executing_macro))
1149      {      {
1150        if (executing_macro_iterations == 1)        if (executing_macro_iterations == 1)
# Line 1190  cmd_error_internal (data, context) Line 1221  cmd_error_internal (data, context)
1221    else    else
1222      {      {
1223        Fdiscard_input ();        Fdiscard_input ();
1224          message_log_maybe_newline ();
1225        bitch_at_user ();        bitch_at_user ();
1226        stream = Qt;        stream = Qt;
1227      }      }
1228    
1229    if (context != 0)    /* The immediate context is not interesting for Quits,
1230      write_string_1 (context, -1, stream);       since they are asyncronous.  */
1231      if (EQ (XCAR (data), Qquit))
1232        Vsignaling_function = Qnil;
1233    
1234    print_error_message (data, stream);    print_error_message (data, stream, context, Vsignaling_function);
1235    
1236      Vsignaling_function = Qnil;
1237    
1238    /* If the window system or terminal frame hasn't been initialized    /* If the window system or terminal frame hasn't been initialized
1239       yet, or we're in -batch mode, this error should cause Emacs to exit.  */       yet, or we're in -batch mode, this error should cause Emacs to exit.  */
# Line 1315  DEFUN ("abort-recursive-edit", Fabort_re Line 1351  DEFUN ("abort-recursive-edit", Fabort_re
1351  static int read_key_sequence P_ ((Lisp_Object *, int, Lisp_Object,  static int read_key_sequence P_ ((Lisp_Object *, int, Lisp_Object,
1352                                    int, int, int));                                    int, int, int));
1353  void safe_run_hooks P_ ((Lisp_Object));  void safe_run_hooks P_ ((Lisp_Object));
1354  static void adjust_point_for_property P_ ((int));  static void adjust_point_for_property P_ ((int, int));
1355    
1356    /* Cancel hourglass from protect_unwind.
1357       ARG is not used.  */
1358    #ifdef HAVE_X_WINDOWS
1359    static Lisp_Object
1360    cancel_hourglass_unwind (arg)
1361         Lisp_Object arg;
1362    {
1363      cancel_hourglass ();
1364    }
1365    #endif
1366    
1367  Lisp_Object  Lisp_Object
1368  command_loop_1 ()  command_loop_1 ()
# Line 1331  command_loop_1 () Line 1378  command_loop_1 ()
1378  #ifdef MULTI_KBOARD  #ifdef MULTI_KBOARD
1379    int was_locked = single_kboard;    int was_locked = single_kboard;
1380  #endif  #endif
1381      int already_adjusted;
1382    
1383    current_kboard->Vprefix_arg = Qnil;    current_kboard->Vprefix_arg = Qnil;
1384    current_kboard->Vlast_prefix_arg = Qnil;    current_kboard->Vlast_prefix_arg = Qnil;
# Line 1340  command_loop_1 () Line 1388  command_loop_1 ()
1388    
1389    nonundocount = 0;    nonundocount = 0;
1390    this_command_key_count = 0;    this_command_key_count = 0;
1391      this_command_key_count_reset = 0;
1392    this_single_command_key_start = 0;    this_single_command_key_start = 0;
1393    
1394    /* Make sure this hook runs after commands that get errors and    if (NILP (Vmemory_full))
1395       throw to top level.  */      {
1396    /* Note that the value cell will never directly contain nil        /* Make sure this hook runs after commands that get errors and
1397       if the symbol is a local variable.  */           throw to top level.  */
1398    if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))        /* Note that the value cell will never directly contain nil
1399      safe_run_hooks (Qpost_command_hook);           if the symbol is a local variable.  */
1400          if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
1401    /* If displaying a message, resize the echo area window to fit          safe_run_hooks (Qpost_command_hook);
1402       that message's size exactly.  */  
1403    if (!NILP (echo_area_buffer[0]))        /* If displaying a message, resize the echo area window to fit
1404      resize_echo_area_exactly ();           that message's size exactly.  */
1405          if (!NILP (echo_area_buffer[0]))
1406    if (!NILP (Vdeferred_action_list))          resize_echo_area_exactly ();
1407      call0 (Vdeferred_action_function);  
1408          if (!NILP (Vdeferred_action_list))
1409    if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))          call0 (Vdeferred_action_function);
1410      {  
1411        if (NILP (Vunread_command_events)        if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
1412            && NILP (Vunread_input_method_events)          {
1413            && NILP (Vunread_post_input_method_events)            if (NILP (Vunread_command_events)
1414            && NILP (Vexecuting_macro)                && NILP (Vunread_input_method_events)
1415            && !NILP (sit_for (0, post_command_idle_delay, 0, 1, 1)))                && NILP (Vunread_post_input_method_events)
1416          safe_run_hooks (Qpost_command_idle_hook);                && NILP (Vexecuting_macro)
1417                  && !NILP (sit_for (0, post_command_idle_delay, 0, 1, 1)))
1418                safe_run_hooks (Qpost_command_idle_hook);
1419            }
1420      }      }
1421    
1422      Vmemory_full = Qnil;
1423    
1424    /* Do this after running Vpost_command_hook, for consistency.  */    /* Do this after running Vpost_command_hook, for consistency.  */
1425    current_kboard->Vlast_command = Vthis_command;    current_kboard->Vlast_command = Vthis_command;
1426    current_kboard->Vreal_last_command = real_this_command;    current_kboard->Vreal_last_command = real_this_command;
# Line 1400  command_loop_1 () Line 1454  command_loop_1 ()
1454          {          {
1455            /* Bind inhibit-quit to t so that C-g gets read in            /* Bind inhibit-quit to t so that C-g gets read in
1456               rather than quitting back to the minibuffer.  */               rather than quitting back to the minibuffer.  */
1457            int count = specpdl_ptr - specpdl;            int count = SPECPDL_INDEX ();
1458            specbind (Qinhibit_quit, Qt);            specbind (Qinhibit_quit, Qt);
1459    
1460            Fsit_for (Vminibuffer_message_timeout, Qnil, Qnil);            Fsit_for (Vminibuffer_message_timeout, Qnil, Qnil);
# Line 1467  command_loop_1 () Line 1521  command_loop_1 ()
1521          {          {
1522            cancel_echoing ();            cancel_echoing ();
1523            this_command_key_count = 0;            this_command_key_count = 0;
1524              this_command_key_count_reset = 0;
1525            this_single_command_key_start = 0;            this_single_command_key_start = 0;
1526            goto finalize;            goto finalize;
1527          }          }
# Line 1519  command_loop_1 () Line 1574  command_loop_1 ()
1574        if (SYMBOLP (cmd))        if (SYMBOLP (cmd))
1575          {          {
1576            Lisp_Object cmd1;            Lisp_Object cmd1;
1577            if (cmd1 = Fremap_command (cmd), !NILP (cmd1))            if (cmd1 = Fcommand_remapping (cmd), !NILP (cmd1))
1578              cmd = cmd1;              cmd = cmd1;
1579          }          }
1580    
# Line 1531  command_loop_1 () Line 1586  command_loop_1 ()
1586           if the symbol is a local variable.  */           if the symbol is a local variable.  */
1587        if (!NILP (Vpre_command_hook) && !NILP (Vrun_hooks))        if (!NILP (Vpre_command_hook) && !NILP (Vrun_hooks))
1588          safe_run_hooks (Qpre_command_hook);          safe_run_hooks (Qpre_command_hook);
1589          
1590          already_adjusted = 0;
1591    
1592        if (NILP (Vthis_command))        if (NILP (Vthis_command))
1593          {          {
1594            /* nil means key is undefined.  */            /* nil means key is undefined.  */
# Line 1555  command_loop_1 () Line 1612  command_loop_1 ()
1612                      = window_display_table (XWINDOW (selected_window));                      = window_display_table (XWINDOW (selected_window));
1613                    lose = FETCH_CHAR (PT_BYTE);                    lose = FETCH_CHAR (PT_BYTE);
1614                    SET_PT (PT + 1);                    SET_PT (PT + 1);
1615                    if ((dp                    if (! NILP (Vpost_command_hook))
1616                         ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))                      /* Put this before calling adjust_point_for_property
1617                            ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1                         so it will only get called once in any case.  */
1618                            : (NILP (DISP_CHAR_VECTOR (dp, lose))                      goto directly_done;
1619                               && (lose >= 0x20 && lose < 0x7f)))                    if (current_buffer == prev_buffer
1620                         : (lose >= 0x20 && lose < 0x7f))                        && last_point_position != PT
1621                          && NILP (Vdisable_point_adjustment)
1622                          && NILP (Vglobal_disable_point_adjustment))
1623                        adjust_point_for_property (last_point_position, 0);
1624                      already_adjusted = 1;
1625                      if (PT == last_point_position + 1
1626                          && (dp
1627                              ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
1628                                 ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
1629                                 : (NILP (DISP_CHAR_VECTOR (dp, lose))
1630                                    && (lose >= 0x20 && lose < 0x7f)))
1631                              : (lose >= 0x20 && lose < 0x7f))
1632                        /* To extract the case of continuation on                        /* To extract the case of continuation on
1633                           wide-column characters.  */                           wide-column characters.  */
1634                        && (WIDTH_BY_CHAR_HEAD (FETCH_BYTE (PT_BYTE)) == 1)                        && (WIDTH_BY_CHAR_HEAD (FETCH_BYTE (PT_BYTE)) == 1)
# Line 1584  command_loop_1 () Line 1652  command_loop_1 ()
1652                      = window_display_table (XWINDOW (selected_window));                      = window_display_table (XWINDOW (selected_window));
1653                    SET_PT (PT - 1);                    SET_PT (PT - 1);
1654                    lose = FETCH_CHAR (PT_BYTE);                    lose = FETCH_CHAR (PT_BYTE);
1655                    if ((dp                    if (! NILP (Vpost_command_hook))
1656                         ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))                      goto directly_done;
1657                            ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1                    if (current_buffer == prev_buffer
1658                            : (NILP (DISP_CHAR_VECTOR (dp, lose))                        && last_point_position != PT
1659                               && (lose >= 0x20 && lose < 0x7f)))                        && NILP (Vdisable_point_adjustment)
1660                         : (lose >= 0x20 && lose < 0x7f))                        && NILP (Vglobal_disable_point_adjustment))
1661                        adjust_point_for_property (last_point_position, 0);
1662                      already_adjusted = 1;
1663                      if (PT == last_point_position - 1
1664                          && (dp
1665                              ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
1666                                 ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
1667                                 : (NILP (DISP_CHAR_VECTOR (dp, lose))
1668                                    && (lose >= 0x20 && lose < 0x7f)))
1669                              : (lose >= 0x20 && lose < 0x7f))
1670                        && (XFASTINT (XWINDOW (selected_window)->last_modified)                        && (XFASTINT (XWINDOW (selected_window)->last_modified)
1671                            >= MODIFF)                            >= MODIFF)
1672                        && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)                        && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
# Line 1605  command_loop_1 () Line 1682  command_loop_1 ()
1682                    goto directly_done;                    goto directly_done;
1683                  }                  }
1684                else if (EQ (Vthis_command, Qself_insert_command)                else if (EQ (Vthis_command, Qself_insert_command)
1685                         /* Try this optimization only on ascii keystrokes.  */                         /* Try this optimization only on char keystrokes.  */
1686                         && INTEGERP (last_command_char))                         && NATNUMP (last_command_char)
1687                           && CHAR_VALID_P (XFASTINT (last_command_char), 0))
1688                  {                  {
1689                    unsigned int c = XINT (last_command_char);                    unsigned int c
1690                        = translate_char (Vtranslation_table_for_input,
1691                                          XFASTINT (last_command_char), 0, 0, 0);
1692                    int value;                    int value;
1693                    if (NILP (Vexecuting_macro)                    if (NILP (Vexecuting_macro)
1694                        && !EQ (minibuf_window, selected_window))                        && !EQ (minibuf_window, selected_window))
# Line 1620  command_loop_1 () Line 1700  command_loop_1 ()
1700                          }                          }
1701                        nonundocount++;                        nonundocount++;
1702                      }                      }
1703                      
1704                    lose = ((XFASTINT (XWINDOW (selected_window)->last_modified)                    lose = ((XFASTINT (XWINDOW (selected_window)->last_modified)
1705                             < MODIFF)                             < MODIFF)
1706                            || (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)                            || (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
# Line 1633  command_loop_1 () Line 1713  command_loop_1 ()
1713                            || detect_input_pending ()                            || detect_input_pending ()
1714                            || !NILP (XWINDOW (selected_window)->column_number_displayed)                            || !NILP (XWINDOW (selected_window)->column_number_displayed)
1715                            || !NILP (Vexecuting_macro));                            || !NILP (Vexecuting_macro));
1716                      
1717                    value = internal_self_insert (c, 0);                    value = internal_self_insert (c, 0);
1718    
1719                    if (value == 2)                    if (value == 2)
1720                      nonundocount = 0;                      nonundocount = 0;
1721    
1722                      if (! NILP (Vpost_command_hook))
1723                        /* Put this before calling adjust_point_for_property
1724                           so it will only get called once in any case.  */
1725                        goto directly_done;
1726    
1727                    /* VALUE == 1 when AFTER-CHANGE functions are                    /* VALUE == 1 when AFTER-CHANGE functions are
1728                       installed which is the case most of the time                       installed which is the case most of the time
1729                       because FONT-LOCK installs one.  */                       because FONT-LOCK installs one.  */
# Line 1650  command_loop_1 () Line 1735  command_loop_1 ()
1735    
1736            /* Here for a command that isn't executed directly */            /* Here for a command that isn't executed directly */
1737    
1738              {
1739  #ifdef HAVE_X_WINDOWS  #ifdef HAVE_X_WINDOWS
1740            if (display_hourglass_p              int scount = SPECPDL_INDEX ();
1741                && NILP (Vexecuting_macro))  
1742              start_hourglass ();              if (display_hourglass_p
1743                    && NILP (Vexecuting_macro))
1744                  {
1745                    record_unwind_protect (cancel_hourglass_unwind, Qnil);
1746                    start_hourglass ();
1747                  }
1748  #endif  #endif
1749    
1750            nonundocount = 0;              nonundocount = 0;
1751            if (NILP (current_kboard->Vprefix_arg))              if (NILP (current_kboard->Vprefix_arg))
1752              Fundo_boundary ();                Fundo_boundary ();
1753            Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);              Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
1754    
1755  #ifdef HAVE_X_WINDOWS  #ifdef HAVE_X_WINDOWS
1756            /* Do not check display_hourglass_p here, because            /* Do not check display_hourglass_p here, because
# Line 1668  command_loop_1 () Line 1759  command_loop_1 ()
1759               But don't cancel the hourglass within a macro               But don't cancel the hourglass within a macro
1760               just because a command in the macro finishes.  */               just because a command in the macro finishes.  */
1761            if (NILP (Vexecuting_macro))            if (NILP (Vexecuting_macro))
1762              cancel_hourglass ();              unbind_to (scount, Qnil);
1763  #endif  #endif
1764              }
1765          }          }
1766      directly_done: ;      directly_done: ;
1767        current_kboard->Vlast_prefix_arg = Vcurrent_prefix_arg;        current_kboard->Vlast_prefix_arg = Vcurrent_prefix_arg;
# Line 1716  command_loop_1 () Line 1808  command_loop_1 ()
1808            current_kboard->Vreal_last_command = real_this_command;            current_kboard->Vreal_last_command = real_this_command;
1809            cancel_echoing ();            cancel_echoing ();
1810            this_command_key_count = 0;            this_command_key_count = 0;
1811              this_command_key_count_reset = 0;
1812            this_single_command_key_start = 0;            this_single_command_key_start = 0;
1813          }          }
1814    
# Line 1741  command_loop_1 () Line 1834  command_loop_1 ()
1834        if (current_buffer == prev_buffer        if (current_buffer == prev_buffer
1835            && last_point_position != PT            && last_point_position != PT
1836            && NILP (Vdisable_point_adjustment)            && NILP (Vdisable_point_adjustment)
1837            && NILP (Vglobal_disable_point_adjustment))            && NILP (Vglobal_disable_point_adjustment)
1838          adjust_point_for_property (last_point_position);            && !already_adjusted)
1839            adjust_point_for_property (last_point_position, MODIFF != prev_modiff);
1840    
1841        /* Install chars successfully executed in kbd macro.  */        /* Install chars successfully executed in kbd macro.  */
1842    
# Line 1761  extern Lisp_Object Qcomposition, Qdispla Line 1855  extern Lisp_Object Qcomposition, Qdispla
1855    
1856  /* Adjust point to a boundary of a region that has such a property  /* Adjust point to a boundary of a region that has such a property
1857     that should be treated intangible.  For the moment, we check     that should be treated intangible.  For the moment, we check
1858     `composition' and `display' property.  LAST_PT is the last position     `composition', `display' and `invisible' properties.
1859     of point.  */     LAST_PT is the last position of point.  */
1860    
1861    extern Lisp_Object Qafter_string, Qbefore_string;
1862    extern Lisp_Object get_pos_property P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
1863    
1864  static void  static void
1865  adjust_point_for_property (last_pt)  adjust_point_for_property (last_pt, modified)
1866       int last_pt;       int last_pt;
1867         int modified;
1868  {  {
1869    int start, end;    int beg, end;
1870    Lisp_Object val;    Lisp_Object val, overlay, tmp;
1871    int check_composition = 1, check_display = 1;    int check_composition = 1, check_display = 1, check_invisible = 1;
1872    
1873    while (check_composition || check_display)    while (check_composition || check_display || check_invisible)
1874      {      {
1875        if (check_composition        if (check_composition
1876            && PT > BEGV && PT < ZV            && PT > BEGV && PT < ZV
1877            && get_property_and_range (PT, Qcomposition, &val, &start, &end, Qnil)            && get_property_and_range (PT, Qcomposition, &val, &beg, &end, Qnil)
1878            && COMPOSITION_VALID_P (start, end, val)            && COMPOSITION_VALID_P (beg, end, val)
1879            && start < PT && end > PT            && beg < PT /* && end > PT   <- It's always the case.  */
1880            && (last_pt <= start || last_pt >= end))            && (last_pt <= beg || last_pt >= end))
1881          {          {
1882            if (PT < last_pt)            xassert (end > PT);
1883              SET_PT (start);            SET_PT (PT < last_pt ? beg : end);
1884            else            check_display = check_invisible = 1;
             SET_PT (end);  
           check_display = 1;  
1885          }          }
1886        check_composition = 0;        check_composition = 0;
1887        if (check_display        if (check_display
1888            && PT > BEGV && PT < ZV            && PT > BEGV && PT < ZV
1889            && get_property_and_range (PT, Qdisplay, &val, &start, &end, Qnil)            && !NILP (val = get_char_property_and_overlay
1890                                  (make_number (PT), Qdisplay, Qnil, &overlay))
1891            && display_prop_intangible_p (val)            && display_prop_intangible_p (val)
1892            && start < PT && end > PT            && (!OVERLAYP (overlay)
1893            && (last_pt <= start || last_pt >= end))                ? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil)
1894          {                : (beg = OVERLAY_POSITION (OVERLAY_START (overlay)),
1895            if (PT < last_pt)                   end = OVERLAY_POSITION (OVERLAY_END (overlay))))
1896              SET_PT (start);            && beg < PT) /* && end > PT   <- It's always the case.  */
1897            else          {
1898              SET_PT (end);            xassert (end > PT);
1899            check_composition = 1;            SET_PT (PT < last_pt ? beg : end);
1900              check_composition = check_invisible = 1;
1901          }          }
1902        check_display = 0;        check_display = 0;
1903          if (check_invisible && PT > BEGV && PT < ZV)
1904            {
1905              int inv, ellipsis = 0;
1906              beg = end = PT;
1907    
1908              /* Find boundaries `beg' and `end' of the invisible area, if any.  */
1909              while (end < ZV
1910                     && !NILP (val = get_char_property_and_overlay
1911                               (make_number (end), Qinvisible, Qnil, &overlay))
1912                     && (inv = TEXT_PROP_MEANS_INVISIBLE (val)))
1913                {
1914                  ellipsis = ellipsis || inv > 1
1915                    || (OVERLAYP (overlay)
1916                        && (!NILP (Foverlay_get (overlay, Qafter_string))
1917                            || !NILP (Foverlay_get (overlay, Qbefore_string))));
1918                  tmp = Fnext_single_char_property_change
1919                    (make_number (end), Qinvisible, Qnil, Qnil);
1920                  end = NATNUMP (tmp) ? XFASTINT (tmp) : ZV;
1921                }
1922              while (beg > BEGV
1923                     && !NILP (val = get_char_property_and_overlay
1924                               (make_number (beg - 1), Qinvisible, Qnil, &overlay))
1925                     && (inv = TEXT_PROP_MEANS_INVISIBLE (val)))
1926                {
1927                  ellipsis = ellipsis || inv > 1
1928                    || (OVERLAYP (overlay)
1929                        && (!NILP (Foverlay_get (overlay, Qafter_string))
1930                            || !NILP (Foverlay_get (overlay, Qbefore_string))));
1931                  tmp = Fprevious_single_char_property_change
1932                    (make_number (beg), Qinvisible, Qnil, Qnil);
1933                  beg = NATNUMP (tmp) ? XFASTINT (tmp) : BEGV;
1934                }
1935    
1936              /* Move away from the inside area.  */
1937              if (beg < PT && end > PT)
1938                {
1939                  SET_PT (PT < last_pt ? beg : end);
1940                  check_composition = check_display = 1;
1941                }
1942              xassert (PT == beg || PT == end);
1943              /* Pretend the area doesn't exist if the buffer is not
1944                 modified.  */
1945              if (!modified && !ellipsis && beg < end)
1946                {
1947                  if (last_pt == beg && PT == end && end < ZV)
1948                    (check_composition = check_display = 1, SET_PT (end + 1));
1949                  else if (last_pt == end && PT == beg && beg > BEGV)
1950                    (check_composition = check_display = 1, SET_PT (beg - 1));
1951                  else if (PT == ((PT < last_pt) ? beg : end))
1952                    /* We've already moved as far as we can.  Trying to go
1953                       to the other end would mean moving backwards and thus
1954                       could lead to an infinite loop.  */
1955                    ;
1956                  else if (val = get_pos_property (make_number (PT),
1957                                                   Qinvisible, Qnil),
1958                           TEXT_PROP_MEANS_INVISIBLE (val)
1959                           && (val = get_pos_property
1960                               (make_number (PT == beg ? end : beg),
1961                                Qinvisible, Qnil),
1962                               !TEXT_PROP_MEANS_INVISIBLE (val)))
1963                    (check_composition = check_display = 1,
1964                     SET_PT (PT == beg ? end : beg));
1965                }
1966            }
1967          check_invisible = 0;
1968      }      }
1969  }  }
1970    
# Line 1831  void Line 1994  void
1994  safe_run_hooks (hook)  safe_run_hooks (hook)
1995       Lisp_Object hook;       Lisp_Object hook;
1996  {  {
1997    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
1998    specbind (Qinhibit_quit, hook);    specbind (Qinhibit_quit, hook);
1999    
2000    internal_condition_case (safe_run_hooks_1, Qt, safe_run_hooks_error);    internal_condition_case (safe_run_hooks_1, Qt, safe_run_hooks_error);
# Line 1893  start_polling () Line 2056  start_polling ()
2056        /* Turn alarm handling on unconditionally.  It might have        /* Turn alarm handling on unconditionally.  It might have
2057           been turned off in process.c.  */           been turned off in process.c.  */
2058        turn_on_atimers (1);        turn_on_atimers (1);
2059          
2060        /* If poll timer doesn't exist, are we need one with        /* If poll timer doesn't exist, are we need one with
2061           a different interval, start a new one.  */           a different interval, start a new one.  */
2062        if (poll_timer == NULL        if (poll_timer == NULL
# Line 1903  start_polling () Line 2066  start_polling ()
2066    
2067            if (poll_timer)            if (poll_timer)
2068              cancel_atimer (poll_timer);              cancel_atimer (poll_timer);
2069          
2070            EMACS_SET_SECS_USECS (interval, polling_period, 0);            EMACS_SET_SECS_USECS (interval, polling_period, 0);
2071            poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,            poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
2072                                       poll_for_input, NULL);                                       poll_for_input, NULL);
# Line 2064  show_help_echo (help, window, object, po Line 2227  show_help_echo (help, window, object, po
2227          }          }
2228        else        else
2229          help = safe_eval (help);          help = safe_eval (help);
2230          
2231        if (!STRINGP (help))        if (!STRINGP (help))
2232          return;          return;
2233      }      }
# Line 2083  show_help_echo (help, window, object, po Line 2246  show_help_echo (help, window, object, po
2246          {          {
2247            if (STRINGP (help))            if (STRINGP (help))
2248              {              {
2249                int count = BINDING_STACK_SIZE ();                int count = SPECPDL_INDEX ();
2250    
2251                if (!help_echo_showing_p)                if (!help_echo_showing_p)
2252                  Vpre_help_message = current_message ();                  Vpre_help_message = current_message ();
2253                  
2254                specbind (Qmessage_truncate_lines, Qt);                specbind (Qmessage_truncate_lines, Qt);
2255                message3_nolog (help, STRING_BYTES (XSTRING (help)),                message3_nolog (help, SBYTES (help),
2256                                STRING_MULTIBYTE (help));                                STRING_MULTIBYTE (help));
2257                unbind_to (count, Qnil);                unbind_to (count, Qnil);
2258              }              }
2259            else if (STRINGP (Vpre_help_message))            else if (STRINGP (Vpre_help_message))
2260              {              {
2261                message3_nolog (Vpre_help_message,                message3_nolog (Vpre_help_message,
2262                                STRING_BYTES (XSTRING (Vpre_help_message)),                                SBYTES (Vpre_help_message),
2263                                STRING_MULTIBYTE (Vpre_help_message));                                STRING_MULTIBYTE (Vpre_help_message));
2264                Vpre_help_message = Qnil;                Vpre_help_message = Qnil;
2265              }              }
2266            else            else
2267              message (0);              message (0);
2268          }          }
2269          
2270        help_echo_showing_p = STRINGP (help);        help_echo_showing_p = STRINGP (help);
2271      }      }
2272  }  }
# Line 2120  static void record_char (); Line 2283  static void record_char ();
2283  static jmp_buf wrong_kboard_jmpbuf;  static jmp_buf wrong_kboard_jmpbuf;
2284  #endif  #endif
2285    
2286    #define STOP_POLLING                                    \
2287    do { if (! polling_stopped_here) stop_polling ();       \
2288           polling_stopped_here = 1; } while (0)
2289    
2290    #define RESUME_POLLING                                  \
2291    do { if (polling_stopped_here) start_polling ();        \
2292           polling_stopped_here = 0; } while (0)
2293    
2294  /* read a character from the keyboard; call the redisplay if needed */  /* read a character from the keyboard; call the redisplay if needed */
2295  /* commandflag 0 means do not do auto-saving, but do do redisplay.  /* commandflag 0 means do not do auto-saving, but do do redisplay.
2296     -1 means do not do redisplay, but do do autosaving.     -1 means do not do redisplay, but do do autosaving.
# Line 2159  read_char (commandflag, nmaps, maps, pre Line 2330  read_char (commandflag, nmaps, maps, pre
2330    volatile int reread;    volatile int reread;
2331    struct gcpro gcpro1, gcpro2;    struct gcpro gcpro1, gcpro2;
2332    EMACS_TIME last_idle_start;    EMACS_TIME last_idle_start;
2333      int polling_stopped_here = 0;
2334    
2335    also_record = Qnil;    also_record = Qnil;
2336    
2337    #if 0  /* This was commented out as part of fixing echo for C-u left.  */
2338    before_command_key_count = this_command_key_count;    before_command_key_count = this_command_key_count;
2339    before_command_echo_length = echo_length ();    before_command_echo_length = echo_length ();
2340    #endif
2341    c = Qnil;    c = Qnil;
2342    previous_echo_area_message = Qnil;    previous_echo_area_message = Qnil;
2343    
# Line 2209  read_char (commandflag, nmaps, maps, pre Line 2383  read_char (commandflag, nmaps, maps, pre
2383            && EQ (XCDR (c), Qdisabled)            && EQ (XCDR (c), Qdisabled)
2384            && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c))))            && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c))))
2385          c = XCAR (c);          c = XCAR (c);
2386          
2387        /* If the queued event is something that used the mouse,        /* If the queued event is something that used the mouse,
2388           set used_mouse_menu accordingly.  */           set used_mouse_menu accordingly.  */
2389        if (used_mouse_menu        if (used_mouse_menu
2390            && (EQ (c, Qtool_bar) || EQ (c, Qmenu_bar)))            && (EQ (c, Qtool_bar) || EQ (c, Qmenu_bar)))
2391          *used_mouse_menu = 1;          *used_mouse_menu = 1;
2392          
2393        reread = 1;        reread = 1;
2394        goto reread_for_input_method;        goto reread_for_input_method;
2395      }      }
# Line 2235  read_char (commandflag, nmaps, maps, pre Line 2409  read_char (commandflag, nmaps, maps, pre
2409        goto reread_for_input_method;        goto reread_for_input_method;
2410      }      }
2411    
2412    /* If there is no function key translated before    this_command_key_count_reset = 0;
      reset-this-command-lengths takes effect, forget about it.  */  
   before_command_restore_flag = 0;  
2413    
2414    if (!NILP (Vexecuting_macro))    if (!NILP (Vexecuting_macro))
2415      {      {
# Line 2260  read_char (commandflag, nmaps, maps, pre Line 2432  read_char (commandflag, nmaps, maps, pre
2432            || executing_macro_index >= XFASTINT (Flength (Vexecuting_macro)))            || executing_macro_index >= XFASTINT (Flength (Vexecuting_macro)))
2433          {          {
2434            XSETINT (c, -1);            XSETINT (c, -1);
2435            RETURN_UNGCPRO (c);            goto exit;
2436          }          }
2437    
2438        c = Faref (Vexecuting_macro, make_number (executing_macro_index));        c = Faref (Vexecuting_macro, make_number (executing_macro_index));
# Line 2312  read_char (commandflag, nmaps, maps, pre Line 2484  read_char (commandflag, nmaps, maps, pre
2484      }      }
2485    
2486    /* Message turns off echoing unless more keystrokes turn it on again.    /* Message turns off echoing unless more keystrokes turn it on again.
2487        
2488       The code in 20.x for the condition was       The code in 20.x for the condition was
2489    
2490       1. echo_area_glyphs && *echo_area_glyphs       1. echo_area_glyphs && *echo_area_glyphs
# Line 2320  read_char (commandflag, nmaps, maps, pre Line 2492  read_char (commandflag, nmaps, maps, pre
2492       3. && ok_to_echo_at_next_pause != echo_area_glyphs       3. && ok_to_echo_at_next_pause != echo_area_glyphs
2493    
2494       (1) means there's a current message displayed       (1) means there's a current message displayed
2495        
2496       (2) means it's not the message from echoing from the current       (2) means it's not the message from echoing from the current
2497       kboard.       kboard.
2498        
2499       (3) There's only one place in 20.x where ok_to_echo_at_next_pause       (3) There's only one place in 20.x where ok_to_echo_at_next_pause
2500       is set to a non-null value.  This is done in read_char and it is       is set to a non-null value.  This is done in read_char and it is
2501       set to echo_area_glyphs after a call to echo_char.  That means       set to echo_area_glyphs after a call to echo_char.  That means
# Line 2335  read_char (commandflag, nmaps, maps, pre Line 2507  read_char (commandflag, nmaps, maps, pre
2507       must be either null, or the current message isn't from echoing at       must be either null, or the current message isn't from echoing at
2508       all, or it's from echoing from a different kboard than the       all, or it's from echoing from a different kboard than the
2509       current one.  */       current one.  */
2510      
2511    if (/* There currently is something in the echo area.  */    if (/* There currently is something in the echo area.  */
2512        !NILP (echo_area_buffer[0])        !NILP (echo_area_buffer[0])
2513        && (/* And it's either not from echoing.  */        && (/* And it's either not from echoing.  */
# Line 2347  read_char (commandflag, nmaps, maps, pre Line 2519  read_char (commandflag, nmaps, maps, pre
2519      cancel_echoing ();      cancel_echoing ();
2520    else    else
2521      echo_dash ();      echo_dash ();
2522          
2523    /* Try reading a character via menu prompting in the minibuf.    /* Try reading a character via menu prompting in the minibuf.
2524       Try this before the sit-for, because the sit-for       Try this before the sit-for, because the sit-for
2525       would do the wrong thing if we are supposed to do       would do the wrong thing if we are supposed to do
# Line 2422  read_char (commandflag, nmaps, maps, pre Line 2594  read_char (commandflag, nmaps, maps, pre
2594    /* If in middle of key sequence and minibuffer not active,    /* If in middle of key sequence and minibuffer not active,
2595       start echoing if enough time elapses.  */       start echoing if enough time elapses.  */
2596    
2597    if (minibuf_level == 0    if (minibuf_level == 0
2598        && !current_kboard->immediate_echo        && !current_kboard->immediate_echo
2599        && this_command_key_count > 0        && this_command_key_count > 0
2600        && ! noninteractive        && ! noninteractive
# Line 2439  read_char (commandflag, nmaps, maps, pre Line 2611  read_char (commandflag, nmaps, maps, pre
2611            || (!echo_kboard && ok_to_echo_at_next_pause)))            || (!echo_kboard && ok_to_echo_at_next_pause)))
2612      {      {
2613        Lisp_Object tem0;        Lisp_Object tem0;
2614          
2615        /* After a mouse event, start echoing right away.        /* After a mouse event, start echoing right away.
2616           This is because we are probably about to display a menu,           This is because we are probably about to display a menu,
2617           and we don't want to delay before doing so.  */           and we don't want to delay before doing so.  */
# Line 2492  read_char (commandflag, nmaps, maps, pre Line 2664  read_char (commandflag, nmaps, maps, pre
2664        /* Now that we have read an event, Emacs is not idle.  */        /* Now that we have read an event, Emacs is not idle.  */
2665        timer_stop_idle ();        timer_stop_idle ();
2666    
2667        RETURN_UNGCPRO (c);        goto exit;
2668      }      }
2669    
2670    /* Maybe autosave and/or garbage collect due to idleness.  */    /* Maybe autosave and/or garbage collect due to idleness.  */
# Line 2599  read_char (commandflag, nmaps, maps, pre Line 2771  read_char (commandflag, nmaps, maps, pre
2771    
2772   wrong_kboard:   wrong_kboard:
2773    
2774    stop_polling ();    STOP_POLLING;
2775    
2776    /* Finally, we read from the main queue,    /* Finally, we read from the main queue,
2777       and if that gives us something we can't use yet, we put it on the       and if that gives us something we can't use yet, we put it on the
# Line 2668  read_char (commandflag, nmaps, maps, pre Line 2840  read_char (commandflag, nmaps, maps, pre
2840       should the next event read be a help-echo.  */       should the next event read be a help-echo.  */
2841    last_idle_start = timer_idleness_start_time;    last_idle_start = timer_idleness_start_time;
2842    timer_stop_idle ();    timer_stop_idle ();
2843    start_polling ();    RESUME_POLLING;
2844    
2845    if (NILP (c))    if (NILP (c))
2846      {      {
# Line 2685  read_char (commandflag, nmaps, maps, pre Line 2857  read_char (commandflag, nmaps, maps, pre
2857       so don't show them to the user.       so don't show them to the user.
2858       Also, don't record a key if we already did.  */       Also, don't record a key if we already did.  */
2859    if (BUFFERP (c) || key_already_recorded)    if (BUFFERP (c) || key_already_recorded)
2860      RETURN_UNGCPRO (c);      goto exit;
2861    
2862    /* Process special events within read_char    /* Process special events within read_char
2863       and loop around to read another event.  */       and loop around to read another event.  */
# Line 2720  read_char (commandflag, nmaps, maps, pre Line 2892  read_char (commandflag, nmaps, maps, pre
2892      {      {
2893        /* If kbd_buffer_get_event gave us an EOF, return that.  */        /* If kbd_buffer_get_event gave us an EOF, return that.  */
2894        if (XINT (c) == -1)        if (XINT (c) == -1)
2895          RETURN_UNGCPRO (c);          goto exit;
2896    
2897        if ((STRINGP (Vkeyboard_translate_table)        if ((STRINGP (Vkeyboard_translate_table)
2898             && XSTRING (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))             && SCHARS (Vkeyboard_translate_table) > (unsigned) XFASTINT (c))
2899            || (VECTORP (Vkeyboard_translate_table)            || (VECTORP (Vkeyboard_translate_table)
2900                && XVECTOR (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))                && XVECTOR (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
2901            || (CHAR_TABLE_P (Vkeyboard_translate_table)            || (CHAR_TABLE_P (Vkeyboard_translate_table)
2902                && CHAR_TABLE_ORDINARY_SLOTS > (unsigned) XFASTINT (c)))                && CHAR_VALID_P (XINT (c), 0)))
2903          {          {
2904            Lisp_Object d;            Lisp_Object d;
2905            d = Faref (Vkeyboard_translate_table, c);            d = Faref (Vkeyboard_translate_table, c);
# Line 2803  read_char (commandflag, nmaps, maps, pre Line 2975  read_char (commandflag, nmaps, maps, pre
2975        && (unsigned) XINT (c) != 127        && (unsigned) XINT (c) != 127
2976        && (unsigned) XINT (c) < 256)        && (unsigned) XINT (c) < 256)
2977      {      {
2978        Lisp_Object keys;        Lisp_Object keys;
2979        int key_count;        int key_count, key_count_reset;
2980        struct gcpro gcpro1;        struct gcpro gcpro1;
2981        int count = specpdl_ptr - specpdl;        int count = SPECPDL_INDEX ();
2982    
2983        /* Save the echo status.  */        /* Save the echo status.  */
2984        int saved_immediate_echo = current_kboard->immediate_echo;        int saved_immediate_echo = current_kboard->immediate_echo;
2985        struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;        struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
2986        int saved_echo_after_prompt = current_kboard->echo_after_prompt;        int saved_echo_after_prompt = current_kboard->echo_after_prompt;
2987    
2988    #if 0
2989        if (before_command_restore_flag)        if (before_command_restore_flag)
2990          {          {
2991            this_command_key_count = before_command_key_count_1;            this_command_key_count = before_command_key_count_1;
# Line 2821  read_char (commandflag, nmaps, maps, pre Line 2994  read_char (commandflag, nmaps, maps, pre
2994            echo_truncate (before_command_echo_length_1);            echo_truncate (before_command_echo_length_1);
2995            before_command_restore_flag = 0;            before_command_restore_flag = 0;
2996          }          }
2997    #endif
2998    
2999        /* Save the this_command_keys status.  */        /* Save the this_command_keys status.  */
3000        key_count = this_command_key_count;        key_count = this_command_key_count;
3001          key_count_reset = this_command_key_count_reset;
3002    
3003        if (key_count > 0)        if (key_count > 0)
3004          keys = Fcopy_sequence (this_command_keys);          keys = Fcopy_sequence (this_command_keys);
# Line 2833  read_char (commandflag, nmaps, maps, pre Line 3008  read_char (commandflag, nmaps, maps, pre
3008    
3009        /* Clear out this_command_keys.  */        /* Clear out this_command_keys.  */
3010        this_command_key_count = 0;        this_command_key_count = 0;
3011          this_command_key_count_reset = 0;
3012    
3013        /* Now wipe the echo area.  */        /* Now wipe the echo area.  */
3014        if (!NILP (echo_area_buffer[0]))        if (!NILP (echo_area_buffer[0]))
# Line 2855  read_char (commandflag, nmaps, maps, pre Line 3031  read_char (commandflag, nmaps, maps, pre
3031        /* Restore the saved echoing state        /* Restore the saved echoing state
3032           and this_command_keys state.  */           and this_command_keys state.  */
3033        this_command_key_count = key_count;        this_command_key_count = key_count;
3034          this_command_key_count_reset = key_count_reset;
3035        if (key_count > 0)        if (key_count > 0)
3036          this_command_keys = keys;          this_command_keys = keys;
3037    
# Line 2903  read_char (commandflag, nmaps, maps, pre Line 3080  read_char (commandflag, nmaps, maps, pre
3080        timer_idleness_start_time = last_idle_start;        timer_idleness_start_time = last_idle_start;
3081        goto retry;        goto retry;
3082      }      }
3083      
3084    if (this_command_key_count == 0 || ! reread)    if (! reread || this_command_key_count == 0
3085          || this_command_key_count_reset)
3086      {      {
       before_command_key_count = this_command_key_count;  
       before_command_echo_length = echo_length ();  
3087    
3088        /* Don't echo mouse motion events.  */        /* Don't echo mouse motion events.  */
3089        if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))        if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
# Line 2936  read_char (commandflag, nmaps, maps, pre Line 3112  read_char (commandflag, nmaps, maps, pre
3112    if (!NILP (Vhelp_form) && help_char_p (c))    if (!NILP (Vhelp_form) && help_char_p (c))
3113      {      {
3114        Lisp_Object tem0;        Lisp_Object tem0;
3115        count = specpdl_ptr - specpdl;        count = SPECPDL_INDEX ();
3116    
3117        record_unwind_protect (Fset_window_configuration,        record_unwind_protect (Fset_window_configuration,
3118                               Fcurrent_window_configuration (Qnil));                               Fcurrent_window_configuration (Qnil));
# Line 2962  read_char (commandflag, nmaps, maps, pre Line 3138  read_char (commandflag, nmaps, maps, pre
3138          }          }
3139      }      }
3140    
3141     exit:
3142      RESUME_POLLING;
3143    RETURN_UNGCPRO (c);    RETURN_UNGCPRO (c);
3144  }  }
3145    
# Line 2977  record_menu_key (c) Line 3155  record_menu_key (c)
3155    
3156    record_char (c);    record_char (c);
3157    
3158    #if 0
3159    before_command_key_count = this_command_key_count;    before_command_key_count = this_command_key_count;
3160    before_command_echo_length = echo_length ();    before_command_echo_length = echo_length ();
3161    #endif
3162    
3163    /* Don't echo mouse motion events.  */    /* Don't echo mouse motion events.  */
3164    if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))    if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
# Line 3033  record_char (c) Line 3213  record_char (c)
3213    
3214        Lisp_Object ev1, ev2, ev3;        Lisp_Object ev1, ev2, ev3;
3215        int ix1, ix2, ix3;        int ix1, ix2, ix3;
3216          
3217        if ((ix1 = recent_keys_index - 1) < 0)        if ((ix1 = recent_keys_index - 1) < 0)
3218          ix1 = NUM_RECENT_KEYS - 1;          ix1 = NUM_RECENT_KEYS - 1;
3219        ev1 = AREF (recent_keys, ix1);        ev1 = AREF (recent_keys, ix1);
3220          
3221        if ((ix2 = ix1 - 1) < 0)        if ((ix2 = ix1 - 1) < 0)
3222          ix2 = NUM_RECENT_KEYS - 1;          ix2 = NUM_RECENT_KEYS - 1;
3223        ev2 = AREF (recent_keys, ix2);        ev2 = AREF (recent_keys, ix2);
3224          
3225        if ((ix3 = ix2 - 1) < 0)        if ((ix3 = ix2 - 1) < 0)
3226          ix3 = NUM_RECENT_KEYS - 1;          ix3 = NUM_RECENT_KEYS - 1;
3227        ev3 = AREF (recent_keys, ix3);        ev3 = AREF (recent_keys, ix3);
3228        
3229        if (EQ (XCAR (c), Qhelp_echo))        if (EQ (XCAR (c), Qhelp_echo))
3230          {          {
3231            /* Don't record `help-echo' in recent_keys unless it shows some help            /* Don't record `help-echo' in recent_keys unless it shows some help
# Line 3116  record_char (c) Line 3296  record_char (c)
3296      }      }
3297    
3298    num_nonmacro_input_events++;    num_nonmacro_input_events++;
3299          
3300    /* Write c to the dribble file.  If c is a lispy event, write    /* Write c to the dribble file.  If c is a lispy event, write
3301       the event's symbol to the dribble file, in <brackets>.  Bleaugh.       the event's symbol to the dribble file, in <brackets>.  Bleaugh.
3302       If you, dear reader, have a better idea, you've got the source.  :-) */       If you, dear reader, have a better idea, you've got the source.  :-) */
# Line 3139  record_char (c) Line 3319  record_char (c)
3319            if (SYMBOLP (dribblee))            if (SYMBOLP (dribblee))
3320              {              {
3321                putc ('<', dribble);                putc ('<', dribble);
3322                fwrite (XSTRING (SYMBOL_NAME (dribblee))->data, sizeof (char),                fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
3323                        STRING_BYTES (XSTRING (SYMBOL_NAME (dribblee))),                        SBYTES (SYMBOL_NAME (dribblee)),
3324                        dribble);                        dribble);
3325                putc ('>', dribble);                putc ('>', dribble);
3326              }              }
# Line 3216  usage: (track-mouse BODY ...)  */) Line 3396  usage: (track-mouse BODY ...)  */)
3396       (args)       (args)
3397       Lisp_Object args;       Lisp_Object args;
3398  {  {
3399    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
3400    Lisp_Object val;    Lisp_Object val;
3401    
3402    record_unwind_protect (tracking_off, do_mouse_tracking);    record_unwind_protect (tracking_off, do_mouse_tracking);
# Line 3253  some_mouse_moved () Line 3433  some_mouse_moved ()
3433  /* Return true iff there are any events in the queue that read-char  /* Return true iff there are any events in the queue that read-char
3434     would return.  If this returns false, a read-char would block.  */     would return.  If this returns false, a read-char would block.  */
3435  static int  static int
3436  readable_events (do_timers_now)  readable_filtered_events (do_timers_now, filter_events)
3437       int do_timers_now;       int do_timers_now;
3438         int filter_events;
3439  {  {
3440    if (do_timers_now)    if (do_timers_now)
3441      timer_check (do_timers_now);      timer_check (do_timers_now);
3442    
3443    /* If the buffer contains only FOCUS_IN_EVENT events,    /* If the buffer contains only FOCUS_IN_EVENT events,
3444       report it as empty.  */       and FILTER_EVENTS is nonzero, report it as empty.  */
3445    if (kbd_fetch_ptr != kbd_store_ptr)    if (kbd_fetch_ptr != kbd_store_ptr)
3446      {      {
3447        struct input_event *event;        int have_live_event = 1;
3448    
3449        event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)        if (filter_events)
3450                 ? kbd_fetch_ptr          {
3451                 : kbd_buffer);            struct input_event *event;
3452    
3453        while (event->kind == FOCUS_IN_EVENT)            event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
3454          {                     ? kbd_fetch_ptr
3455            event++;                     : kbd_buffer);
3456            if (event == kbd_buffer + KBD_BUFFER_SIZE)  
3457              event = kbd_buffer;            while (have_live_event && event->kind == FOCUS_IN_EVENT)
3458            if (event == kbd_store_ptr)              {
3459              return 0;                event++;
3460          }                if (event == kbd_buffer + KBD_BUFFER_SIZE)
3461        return 1;                  event = kbd_buffer;
3462                  if (event == kbd_store_ptr)
3463                    have_live_event = 0;
3464                }
3465            }
3466          if (have_live_event) return 1;
3467      }      }
3468    
3469  #ifdef HAVE_MOUSE  #ifdef HAVE_MOUSE
# Line 3299  readable_events (do_timers_now) Line 3485  readable_events (do_timers_now)
3485    return 0;    return 0;
3486  }  }
3487    
3488    /* Return true iff there are any events in the queue that read-char
3489       would return.  If this returns false, a read-char would block.  */
3490    static int
3491    readable_events (do_timers_now)
3492         int do_timers_now;
3493    {
3494      return readable_filtered_events (do_timers_now, 0);
3495    }
3496    
3497  /* Set this for debugging, to have a way to get out */  /* Set this for debugging, to have a way to get out */
3498  int stop_character;  int stop_character;
3499    
# Line 3330  void Line 3525  void
3525  kbd_buffer_store_event (event)  kbd_buffer_store_event (event)
3526       register struct input_event *event;       register struct input_event *event;
3527  {  {
3528    if (event->kind == no_event)    if (event->kind == NO_EVENT)
3529      abort ();      abort ();
3530    
3531    if (event->kind == ascii_keystroke)    if (event->kind == ASCII_KEYSTROKE_EVENT)
3532      {      {
3533        register int c = event->code & 0377;        register int c = event->code & 0377;
3534    
# Line 3346  kbd_buffer_store_event (event) Line 3541  kbd_buffer_store_event (event)
3541    
3542        if (c == quit_char)        if (c == quit_char)
3543          {          {
           static SIGTYPE interrupt_signal (int);  
3544  #ifdef MULTI_KBOARD  #ifdef MULTI_KBOARD
3545            KBOARD *kb;            KBOARD *kb;
3546            struct input_event *sp;            struct input_event *sp;
# Line 3366  kbd_buffer_store_event (event) Line 3560  kbd_buffer_store_event (event)
3560    
3561                    if (event_to_kboard (sp) == kb)                    if (event_to_kboard (sp) == kb)
3562                      {                      {
3563                        sp->kind = no_event;                        sp->kind = NO_EVENT;
3564                        sp->frame_or_window = Qnil;                        sp->frame_or_window = Qnil;
3565                        sp->arg = Qnil;                        sp->arg = Qnil;
3566                      }                      }
# Line 3400  kbd_buffer_store_event (event) Line 3594  kbd_buffer_store_event (event)
3594            return;            return;
3595          }          }
3596      }      }
3597    /* Don't insert two buffer_switch_event's in a row.    /* Don't insert two BUFFER_SWITCH_EVENT's in a row.
3598       Just ignore the second one.  */       Just ignore the second one.  */
3599    else if (event->kind == buffer_switch_event    else if (event->kind == BUFFER_SWITCH_EVENT
3600             && kbd_fetch_ptr != kbd_store_ptr             && kbd_fetch_ptr != kbd_store_ptr
3601             && kbd_store_ptr->kind == buffer_switch_event)             && kbd_store_ptr->kind == BUFFER_SWITCH_EVENT)
3602      return;      return;
3603    
3604    if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE)    if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE)
# Line 3417  kbd_buffer_store_event (event) Line 3611  kbd_buffer_store_event (event)
3611    if (kbd_fetch_ptr - 1 != kbd_store_ptr)    if (kbd_fetch_ptr - 1 != kbd_store_ptr)
3612      {      {
3613        int idx;        int idx;
3614          
3615  #if 0 /* The selection_request_event case looks bogus, and it's error  #if 0 /* The SELECTION_REQUEST_EVENT case looks bogus, and it's error
3616           prone to assign individual members for other events, in case           prone to assign individual members for other events, in case
3617           the input_event structure is changed.  --2000-07-13, gerd.  */           the input_event structure is changed.  --2000-07-13, gerd.  */
3618        struct input_event *sp = kbd_store_ptr;        struct input_event *sp = kbd_store_ptr;
3619        sp->kind = event->kind;        sp->kind = event->kind;
3620        if (event->kind == selection_request_event)        if (event->kind == SELECTION_REQUEST_EVENT)
3621          {          {
3622            /* We must not use the ordinary copying code for this case,            /* We must not use the ordinary copying code for this case,
3623               since `part' is an enum and copying it might not copy enough               since `part' is an enum and copying it might not copy enough
# Line 3507  kbd_buffer_store_help_event (frame, help Line 3701  kbd_buffer_store_help_event (frame, help
3701    
3702    
3703  /* Discard any mouse events in the event buffer by setting them to  /* Discard any mouse events in the event buffer by setting them to
3704     no_event.  */     NO_EVENT.  */
3705  void  void
3706  discard_mouse_events ()  discard_mouse_events ()
3707  {  {
# Line 3517  discard_mouse_events () Line 3711  discard_mouse_events ()
3711        if (sp == kbd_buffer + KBD_BUFFER_SIZE)        if (sp == kbd_buffer + KBD_BUFFER_SIZE)
3712          sp = kbd_buffer;          sp = kbd_buffer;
3713    
3714        if (sp->kind == mouse_click        if (sp->kind == MOUSE_CLICK_EVENT
3715  #ifdef WINDOWSNT  #ifdef WINDOWSNT
3716            || sp->kind == w32_scroll_bar_click            || sp->kind == W32_SCROLL_BAR_CLICK_EVENT
3717  #endif  #endif
3718            || sp->kind == scroll_bar_click)            || sp->kind == SCROLL_BAR_CLICK_EVENT)
3719          {          {
3720            sp->kind = no_event;            sp->kind = NO_EVENT;
3721          }          }
3722      }      }
3723  }  }
3724    
3725    
3726  /* Return non-zero if there are any real events waiting in the event  /* Return non-zero if there are any real events waiting in the event
3727     buffer, not counting `no_event's.     buffer, not counting `NO_EVENT's.
3728    
3729     If DISCARD is non-zero, discard no_event events at the front of     If DISCARD is non-zero, discard NO_EVENT events at the front of
3730     the input queue, possibly leaving the input queue empty if there     the input queue, possibly leaving the input queue empty if there
3731     are no real input events.  */     are no real input events.  */
3732    
# Line 3541  kbd_buffer_events_waiting (discard) Line 3735  kbd_buffer_events_waiting (discard)
3735       int discard;       int discard;
3736  {  {
3737    struct input_event *sp;    struct input_event *sp;
3738      
3739    for (sp = kbd_fetch_ptr;    for (sp = kbd_fetch_ptr;
3740         sp != kbd_store_ptr && sp->kind == no_event;         sp != kbd_store_ptr && sp->kind == NO_EVENT;
3741         ++sp)         ++sp)
3742      {      {
3743        if (sp == kbd_buffer + KBD_BUFFER_SIZE)        if (sp == kbd_buffer + KBD_BUFFER_SIZE)
# Line 3553  kbd_buffer_events_waiting (discard) Line 3747  kbd_buffer_events_waiting (discard)
3747    if (discard)    if (discard)
3748      kbd_fetch_ptr = sp;      kbd_fetch_ptr = sp;
3749    
3750    return sp != kbd_store_ptr && sp->kind != no_event;    return sp != kbd_store_ptr && sp->kind != NO_EVENT;
3751  }  }
3752    
3753    
# Line 3566  clear_event (event) Line 3760  clear_event (event)
3760    int idx = 2 * (event - kbd_buffer);    int idx = 2 * (event - kbd_buffer);
3761    ASET (kbd_buffer_gcpro, idx, Qnil);    ASET (kbd_buffer_gcpro, idx, Qnil);
3762    ASET (kbd_buffer_gcpro, idx + 1, Qnil);    ASET (kbd_buffer_gcpro, idx + 1, Qnil);
3763    event->kind = no_event;    event->kind = NO_EVENT;
3764  }  }
3765    
3766    
# Line 3671  kbd_buffer_get_event (kbp, used_mouse_me Line 3865  kbd_buffer_get_event (kbp, used_mouse_me
3865        /* These two kinds of events get special handling        /* These two kinds of events get special handling
3866           and don't actually appear to the command loop.           and don't actually appear to the command loop.
3867           We return nil for them.  */           We return nil for them.  */
3868        if (event->kind == selection_request_event)        if (event->kind == SELECTION_REQUEST_EVENT)
3869          {          {
3870  #ifdef HAVE_X11  #ifdef HAVE_X11
3871            struct input_event copy;            struct input_event copy;
# Line 3690  kbd_buffer_get_event (kbp, used_mouse_me Line 3884  kbd_buffer_get_event (kbp, used_mouse_me
3884  #endif  #endif
3885          }          }
3886    
3887        else if (event->kind == selection_clear_event)        else if (event->kind == SELECTION_CLEAR_EVENT)
3888          {          {
3889  #ifdef HAVE_X11  #ifdef HAVE_X11
3890            struct input_event copy;            struct input_event copy;
# Line 3707  kbd_buffer_get_event (kbp, used_mouse_me Line 3901  kbd_buffer_get_event (kbp, used_mouse_me
3901  #endif  #endif
3902          }          }
3903  #if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS)  #if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS)
3904        else if (event->kind == delete_window_event)        else if (event->kind == DELETE_WINDOW_EVENT)
3905          {          {
3906            /* Make an event (delete-frame (FRAME)).  */            /* Make an event (delete-frame (FRAME)).  */
3907            obj = Fcons (event->frame_or_window, Qnil);            obj = Fcons (event->frame_or_window, Qnil);
# Line 3716  kbd_buffer_get_event (kbp, used_mouse_me Line 3910  kbd_buffer_get_event (kbp, used_mouse_me
3910          }          }
3911  #endif  #endif
3912  #if defined (HAVE_X11) || defined (HAVE_NTGUI)  #if defined (HAVE_X11) || defined (HAVE_NTGUI)
3913        else if (event->kind == iconify_event)        else if (event->kind == ICONIFY_EVENT)
3914          {          {
3915            /* Make an event (iconify-frame (FRAME)).  */            /* Make an event (iconify-frame (FRAME)).  */
3916            obj = Fcons (event->frame_or_window, Qnil);            obj = Fcons (event->frame_or_window, Qnil);
3917            obj = Fcons (Qiconify_frame, Fcons (obj, Qnil));            obj = Fcons (Qiconify_frame, Fcons (obj, Qnil));
3918            kbd_fetch_ptr = event + 1;            kbd_fetch_ptr = event + 1;
3919          }          }
3920        else if (event->kind == deiconify_event)        else if (event->kind == DEICONIFY_EVENT)
3921          {          {
3922            /* Make an event (make-frame-visible (FRAME)).  */            /* Make an event (make-frame-visible (FRAME)).  */
3923            obj = Fcons (event->frame_or_window, Qnil);            obj = Fcons (event->frame_or_window, Qnil);
# Line 3731  kbd_buffer_get_event (kbp, used_mouse_me Line 3925  kbd_buffer_get_event (kbp, used_mouse_me
3925            kbd_fetch_ptr = event + 1;            kbd_fetch_ptr = event + 1;
3926          }          }
3927  #endif  #endif
3928        else if (event->kind == buffer_switch_event)        else if (event->kind == BUFFER_SWITCH_EVENT)
3929          {          {
3930            /* The value doesn't matter here; only the type is tested.  */            /* The value doesn't matter here; only the type is tested.  */
3931            XSETBUFFER (obj, current_buffer);            XSETBUFFER (obj, current_buffer);
3932            kbd_fetch_ptr = event + 1;            kbd_fetch_ptr = event + 1;
3933          }          }
3934  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
3935        else if (event->kind == menu_bar_activate_event)      || defined (USE_GTK)
3936          else if (event->kind == MENU_BAR_ACTIVATE_EVENT)
3937          {          {
3938            kbd_fetch_ptr = event + 1;            kbd_fetch_ptr = event + 1;
3939            input_pending = readable_events (0);            input_pending = readable_events (0);
# Line 3747  kbd_buffer_get_event (kbp, used_mouse_me Line 3942  kbd_buffer_get_event (kbp, used_mouse_me
3942          }          }
3943  #endif  #endif
3944  #ifdef WINDOWSNT  #ifdef WINDOWSNT
3945        else if (event->kind == language_change_event)        else if (event->kind == LANGUAGE_CHANGE_EVENT)
3946          {          {
3947            /* Make an event (language-change (FRAME CHARSET LCID)).  */            /* Make an event (language-change (FRAME CHARSET LCID)).  */
3948            obj = Fcons (event->modifiers, Qnil);            obj = Fcons (event->modifiers, Qnil);
# Line 3757  kbd_buffer_get_event (kbp, used_mouse_me Line 3952  kbd_buffer_get_event (kbp, used_mouse_me
3952            kbd_fetch_ptr = event + 1;            kbd_fetch_ptr = event + 1;
3953          }          }
3954  #endif  #endif
3955        else if (event->kind == save_session_event)        else if (event->kind == SAVE_SESSION_EVENT)
3956          {          {
3957            obj = Fcons (Qsave_session, Qnil);            obj = Fcons (Qsave_session, Qnil);
3958            kbd_fetch_ptr = event + 1;            kbd_fetch_ptr = event + 1;
# Line 3768  kbd_buffer_get_event (kbp, used_mouse_me Line 3963  kbd_buffer_get_event (kbp, used_mouse_me
3963           (They shouldn't otherwise be found in the buffer,           (They shouldn't otherwise be found in the buffer,
3964           but on some machines it appears they do show up           but on some machines it appears they do show up
3965           even without MULTI_KBOARD.)  */           even without MULTI_KBOARD.)  */
3966        /* On Windows NT/9X, no_event is used to delete extraneous        /* On Windows NT/9X, NO_EVENT is used to delete extraneous
3967           mouse events during a popup-menu call.  */           mouse events during a popup-menu call.  */
3968        else if (event->kind == no_event)        else if (event->kind == NO_EVENT)
3969          kbd_fetch_ptr = event + 1;          kbd_fetch_ptr = event + 1;
3970        else if (event->kind == HELP_EVENT)        else if (event->kind == HELP_EVENT)
3971          {          {
# Line 3843  kbd_buffer_get_event (kbp, used_mouse_me Line 4038  kbd_buffer_get_event (kbp, used_mouse_me
4038            if (NILP (obj))            if (NILP (obj))
4039              {              {
4040                obj = make_lispy_event (event);                obj = make_lispy_event (event);
4041                  
4042  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined(MAC_OS) \
4043        || defined (USE_GTK)
4044                /* If this was a menu selection, then set the flag to inhibit                /* If this was a menu selection, then set the flag to inhibit
4045                   writing to last_nonmenu_event.  Don't do this if the event                   writing to last_nonmenu_event.  Don't do this if the event
4046                   we're returning is (menu-bar), though; that indicates the                   we're returning is (menu-bar), though; that indicates the
# Line 3938  swallow_events (do_display) Line 4134  swallow_events (do_display)
4134    
4135        /* These two kinds of events get special handling        /* These two kinds of events get special handling
4136           and don't actually appear to the command loop.  */           and don't actually appear to the command loop.  */
4137        if (event->kind == selection_request_event)        if (event->kind == SELECTION_REQUEST_EVENT)
4138          {          {
4139  #ifdef HAVE_X11  #ifdef HAVE_X11
4140            struct input_event copy;            struct input_event copy;
# Line 3957  swallow_events (do_display) Line 4153  swallow_events (do_display)
4153  #endif  #endif
4154          }          }
4155    
4156        else if (event->kind == selection_clear_event)        else if (event->kind == SELECTION_CLEAR_EVENT)
4157          {          {
4158  #ifdef HAVE_X11  #ifdef HAVE_X11
4159            struct input_event copy;            struct input_event copy;
# Line 3999  timer_start_idle () Line 4195  timer_start_idle ()
4195    
4196    EMACS_GET_TIME (timer_idleness_start_time);    EMACS_GET_TIME (timer_idleness_start_time);
4197    
4198      timer_last_idleness_start_time = timer_idleness_start_time;
4199    
4200    /* Mark all idle-time timers as once again candidates for running.  */    /* Mark all idle-time timers as once again candidates for running.  */
4201    for (timers = Vtimer_idle_list; CONSP (timers); timers = XCDR (timers))    for (timers = Vtimer_idle_list; CONSP (timers); timers = XCDR (timers))
4202      {      {
# Line 4171  timer_check (do_it_now) Line 4369  timer_check (do_it_now)
4369            difference = idle_timer_difference;            difference = idle_timer_difference;
4370          }          }
4371        vector = XVECTOR (chosen_timer)->contents;        vector = XVECTOR (chosen_timer)->contents;
4372            
4373        /* If timer is ripe, run it if it hasn't been run.  */        /* If timer is ripe, run it if it hasn't been run.  */
4374        if (EMACS_TIME_NEG_P (difference)        if (EMACS_TIME_NEG_P (difference)
4375            || (EMACS_SECS (difference) == 0            || (EMACS_SECS (difference) == 0
# Line 4180  timer_check (do_it_now) Line 4378  timer_check (do_it_now)
4378            if (NILP (vector[0]))            if (NILP (vector[0]))
4379              {              {
4380                int was_locked = single_kboard;                int was_locked = single_kboard;
4381                int count = BINDING_STACK_SIZE ();                int count = SPECPDL_INDEX ();
4382                Lisp_Object old_deactivate_mark = Vdeactivate_mark;                Lisp_Object old_deactivate_mark = Vdeactivate_mark;
4383    
4384                /* Mark the timer as triggered to prevent problems if the lisp                /* Mark the timer as triggered to prevent problems if the lisp
# Line 4188  timer_check (do_it_now) Line 4386  timer_check (do_it_now)
4386                vector[0] = Qt;                vector[0] = Qt;
4387    
4388                specbind (Qinhibit_quit, Qt);                specbind (Qinhibit_quit, Qt);
4389                  
4390                call1 (Qtimer_event_handler, chosen_timer);                call1 (Qtimer_event_handler, chosen_timer);
4391                Vdeactivate_mark = old_deactivate_mark;                Vdeactivate_mark = old_deactivate_mark;
4392                timers_run++;                timers_run++;
# Line 4221  timer_check (do_it_now) Line 4419  timer_check (do_it_now)
4419  static Lisp_Object accent_key_syms;  static Lisp_Object accent_key_syms;
4420  static Lisp_Object func_key_syms;  static Lisp_Object func_key_syms;
4421  static Lisp_Object mouse_syms;  static Lisp_Object mouse_syms;
4422  #ifdef WINDOWSNT  #if defined(WINDOWSNT) || defined(MAC_OSX)
4423  static Lisp_Object mouse_wheel_syms;  static Lisp_Object mouse_wheel_syms;
4424  #endif  #endif
4425  static Lisp_Object drag_n_drop_syms;  static Lisp_Object drag_n_drop_syms;
# Line 4296  static int lispy_accent_codes[] = Line 4494  static int lispy_accent_codes[] =
4494  #else  #else
4495    0,    0,
4496  #endif  #endif
4497    #ifdef XK_dead_abovering
4498      XK_dead_abovering,
4499    #else
4500      0,
4501    #endif
4502    #ifdef XK_dead_iota
4503      XK_dead_iota,
4504    #else
4505      0,
4506    #endif
4507    #ifdef XK_dead_belowdot
4508      XK_dead_belowdot,
4509    #else
4510      0,
4511    #endif
4512    #ifdef XK_dead_voiced_sound
4513      XK_dead_voiced_sound,
4514    #else
4515      0,
4516    #endif
4517    #ifdef XK_dead_semivoiced_sound
4518      XK_dead_semivoiced_sound,
4519    #else
4520      0,
4521    #endif
4522    #ifdef XK_dead_hook
4523      XK_dead_hook,
4524    #else
4525      0,
4526    #endif
4527    #ifdef XK_dead_horn
4528      XK_dead_horn,
4529    #else
4530      0,
4531    #endif
4532  };  };
4533    
4534  /* This is a list of Lisp names for special "accent" characters.  /* This is a list of Lisp names for special "accent" characters.
# Line 4316  static char *lispy_accent_keys[] = Line 4549  static char *lispy_accent_keys[] =
4549    "dead-caron",    "dead-caron",
4550    "dead-doubleacute",    "dead-doubleacute",
4551    "dead-abovedot",    "dead-abovedot",
4552      "dead-abovering",
4553      "dead-iota",
4554      "dead-belowdot",
4555      "dead-voiced-sound",
4556      "dead-semivoiced-sound",
4557      "dead-hook",
4558      "dead-horn",
4559  };  };
4560    
4561  #ifdef HAVE_NTGUI  #ifdef HAVE_NTGUI
# Line 4324  static char *lispy_accent_keys[] = Line 4564  static char *lispy_accent_keys[] =
4564  char *lispy_function_keys[] =  char *lispy_function_keys[] =
4565    {    {
4566      0,                /* 0                      */      0,                /* 0                      */
4567        
4568      0,                /* VK_LBUTTON        0x01 */      0,                /* VK_LBUTTON        0x01 */
4569      0,                /* VK_RBUTTON        0x02 */      0,                /* VK_RBUTTON        0x02 */
4570      "cancel",         /* VK_CANCEL         0x03 */      "cancel",         /* VK_CANCEL         0x03 */
4571      0,                /* VK_MBUTTON        0x04 */      0,                /* VK_MBUTTON        0x04 */
4572        
4573      0, 0, 0,          /*    0x05 .. 0x07        */      0, 0, 0,          /*    0x05 .. 0x07        */
4574        
4575      "backspace",      /* VK_BACK           0x08 */      "backspace",      /* VK_BACK           0x08 */
4576      "tab",            /* VK_TAB            0x09 */      "tab",            /* VK_TAB            0x09 */
4577        
4578      0, 0,             /*    0x0A .. 0x0B        */      0, 0,             /*    0x0A .. 0x0B        */
4579        
4580      "clear",          /* VK_CLEAR          0x0C */      "clear",          /* VK_CLEAR          0x0C */
4581      "return",         /* VK_RETURN         0x0D */      "return",         /* VK_RETURN         0x0D */
4582        
4583      0, 0,             /*    0x0E .. 0x0F        */      0, 0,             /*    0x0E .. 0x0F        */
4584      
4585      0,                /* VK_SHIFT          0x10 */      0,                /* VK_SHIFT          0x10 */
4586      0,                /* VK_CONTROL        0x11 */      0,                /* VK_CONTROL        0x11 */
4587      0,                /* VK_MENU           0x12 */      0,                /* VK_MENU           0x12 */
4588      "pause",          /* VK_PAUSE          0x13 */      "pause",          /* VK_PAUSE          0x13 */
4589      "capslock",       /* VK_CAPITAL        0x14 */      "capslock",       /* VK_CAPITAL        0x14 */
4590        
4591      0, 0, 0, 0, 0, 0, /*    0x15 .. 0x1A        */      0, 0, 0, 0, 0, 0, /*    0x15 .. 0x1A        */
4592        
4593      "escape",         /* VK_ESCAPE         0x1B */      "escape",         /* VK_ESCAPE         0x1B */
4594        
4595      0, 0, 0, 0,       /*    0x1C .. 0x1F        */      0, 0, 0, 0,       /*    0x1C .. 0x1F        */
4596        
4597      0,                /* VK_SPACE          0x20 */      0,                /* VK_SPACE          0x20 */
4598      "prior",          /* VK_PRIOR          0x21 */      "prior",          /* VK_PRIOR          0x21 */
4599      "next",           /* VK_NEXT           0x22 */      "next",           /* VK_NEXT           0x22 */
# Line 4370  char *lispy_function_keys[] = Line 4610  char *lispy_function_keys[] =
4610      "insert",         /* VK_INSERT         0x2D */      "insert",         /* VK_INSERT         0x2D */
4611      "delete",         /* VK_DELETE         0x2E */      "delete",         /* VK_DELETE         0x2E */
4612      "help",           /* VK_HELP           0x2F */      "help",           /* VK_HELP           0x2F */
4613      
4614      /* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */      /* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
4615        
4616      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4617        
4618      0, 0, 0, 0, 0, 0, 0, /* 0x3A .. 0x40       */      0, 0, 0, 0, 0, 0, 0, /* 0x3A .. 0x40       */
4619        
4620      /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */      /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
4621        
4622      0, 0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0, 0,
4623      0, 0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0, 0,
4624      0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0,
4625        
4626      "lwindow",       /* VK_LWIN           0x5B */      "lwindow",       /* VK_LWIN           0x5B */
4627      "rwindow",       /* VK_RWIN           0x5C */      "rwindow",       /* VK_RWIN           0x5C */
4628      "apps",          /* VK_APPS           0x5D */      "apps",          /* VK_APPS           0x5D */
4629        
4630      0, 0,            /*    0x5E .. 0x5F        */      0, 0,            /*    0x5E .. 0x5F        */
4631        
4632      "kp-0",          /* VK_NUMPAD0        0x60 */      "kp-0",          /* VK_NUMPAD0        0x60 */
4633      "kp-1",          /* VK_NUMPAD1        0x61 */      "kp-1",          /* VK_NUMPAD1        0x61 */
4634      "kp-2",          /* VK_NUMPAD2        0x62 */      "kp-2",          /* VK_NUMPAD2        0x62 */
# Line 4429  char *lispy_function_keys[] = Line 4669  char *lispy_function_keys[] =
4669      "f22",           /* VK_F22            0x85 */      "f22",           /* VK_F22            0x85 */
4670      "f23",           /* VK_F23            0x86 */      "f23",           /* VK_F23            0x86 */
4671      "f24",           /* VK_F24            0x87 */      "f24",           /* VK_F24            0x87 */
4672        
4673      0, 0, 0, 0,      /*    0x88 .. 0x8B        */      0, 0, 0, 0,      /*    0x88 .. 0x8B        */
4674      0, 0, 0, 0,      /*    0x8C .. 0x8F        */      0, 0, 0, 0,      /*    0x8C .. 0x8F        */
4675        
4676      "kp-numlock",    /* VK_NUMLOCK        0x90 */      "kp-numlock",    /* VK_NUMLOCK        0x90 */
4677      "scroll",        /* VK_SCROLL         0x91 */      "scroll",        /* VK_SCROLL         0x91 */
4678        
4679      "kp-space",      /* VK_NUMPAD_CLEAR   0x92 */      "kp-space",      /* VK_NUMPAD_CLEAR   0x92 */
4680      "kp-enter",      /* VK_NUMPAD_ENTER   0x93 */      "kp-enter",      /* VK_NUMPAD_ENTER   0x93 */
4681      "kp-prior",      /* VK_NUMPAD_PRIOR   0x94 */      "kp-prior",      /* VK_NUMPAD_PRIOR   0x94 */
# Line 4457  char *lispy_function_keys[] = Line 4697  char *lispy_function_keys[] =
4697       * No other API or message will distinguish left and right keys this way.       * No other API or message will distinguish left and right keys this way.
4698       */       */
4699      /* 0xA0 .. 0xEF */      /* 0xA0 .. 0xEF */
4700        
4701      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4702      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4703      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4704      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4705      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4706        
4707      /* 0xF0 .. 0xF5 */      /* 0xF0 .. 0xF5 */
4708        
4709      0, 0, 0, 0, 0, 0,      0, 0, 0, 0, 0, 0,
4710        
4711      "attn",          /* VK_ATTN           0xF6 */      "attn",          /* VK_ATTN           0xF6 */
4712      "crsel",         /* VK_CRSEL          0xF7 */      "crsel",         /* VK_CRSEL          0xF7 */
4713      "exsel",         /* VK_EXSEL          0xF8 */      "exsel",         /* VK_EXSEL          0xF8 */
# Line 4482  char *lispy_function_keys[] = Line 4722  char *lispy_function_keys[] =
4722    
4723  #else /* not HAVE_NTGUI */  #else /* not HAVE_NTGUI */
4724    
4725    /* This should be dealt with in XTread_socket now, and that doesn't
4726       depend on the client system having the Kana syms defined.  See also
4727       the XK_kana_A case below.  */
4728    #if 0
4729  #ifdef XK_kana_A  #ifdef XK_kana_A
4730  static char *lispy_kana_keys[] =  static char *lispy_kana_keys[] =
4731    {    {
# Line 4496  static char *lispy_kana_keys[] = Line 4740  static char *lispy_kana_keys[] =
4740      0,0,0,0,0,0,0,0,0,0,0,0,0,0,"overline",0,      0,0,0,0,0,0,0,0,0,0,0,0,0,0,"overline",0,
4741      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    /* 0x480 .. 0x48f */      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    /* 0x480 .. 0x48f */
4742      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    /* 0x490 .. 0x49f */      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    /* 0x490 .. 0x49f */
4743      0, "kana-fullstop", "kana-openingbracket", "kana-closingbracket",      0, "kana-fullstop", "kana-openingbracket", "kana-closingbracket",
4744      "kana-comma", "kana-conjunctive", "kana-WO", "kana-a",      "kana-comma", "kana-conjunctive", "kana-WO", "kana-a",
4745      "kana-i", "kana-u", "kana-e", "kana-o",      "kana-i", "kana-u", "kana-e", "kana-o",
4746      "kana-ya", "kana-yu", "kana-yo", "kana-tsu",      "kana-ya", "kana-yu", "kana-yo", "kana-tsu",
# Line 4516  static char *lispy_kana_keys[] = Line 4760  static char *lispy_kana_keys[] =
4760      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    /* 0x4f0 .. 0x4ff */      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    /* 0x4f0 .. 0x4ff */
4761    };    };
4762  #endif /* XK_kana_A */  #endif /* XK_kana_A */
4763    #endif /* 0 */
4764    
4765  #define FUNCTION_KEY_OFFSET 0xff00  #define FUNCTION_KEY_OFFSET 0xff00
4766    
# Line 4614  static char *iso_lispy_function_keys[] = Line 4859  static char *iso_lispy_function_keys[] =
4859      0, 0, 0, 0, 0, 0, 0, 0,     /* 0xfe10 */      0, 0, 0, 0, 0, 0, 0, 0,     /* 0xfe10 */
4860      0, 0, 0, 0, 0, 0, 0, 0,     /* 0xfe18 */      0, 0, 0, 0, 0, 0, 0, 0,     /* 0xfe18 */
4861      "iso-lefttab",              /* 0xfe20 */      "iso-lefttab",              /* 0xfe20 */
4862      "iso-move-line-up", "iso-move-line-down",      "iso-move-line-up", "iso-move-line-down",
4863      "iso-partial-line-up", "iso-partial-line-down",      "iso-partial-line-up", "iso-partial-line-down",
4864      "iso-partial-space-left", "iso-partial-space-right",      "iso-partial-space-left", "iso-partial-space-right",
4865      "iso-set-margin-left", "iso-set-margin-right", /* 0xffe27, 28 */      "iso-set-margin-left", "iso-set-margin-right", /* 0xffe27, 28 */
4866      "iso-release-margin-left", "iso-release-margin-right",      "iso-release-margin-left", "iso-release-margin-right",
4867      "iso-release-both-margins",      "iso-release-both-margins",
# Line 4630  static char *iso_lispy_function_keys[] = Line 4875  static char *iso_lispy_function_keys[] =
4875    
4876  Lisp_Object Vlispy_mouse_stem;  Lisp_Object Vlispy_mouse_stem;
4877    
4878  #ifdef WINDOWSNT  #if defined(WINDOWSNT) || defined(MAC_OSX)
4879  /* mouse-wheel events are generated by the wheel on devices such as  /* mouse-wheel events are generated by the wheel on devices such as
4880     the MS Intellimouse.  The wheel sits in between the left and right     the MS Intellimouse.  The wheel sits in between the left and right
4881     mouse buttons, and is typically used to scroll or zoom the window     mouse buttons, and is typically used to scroll or zoom the window
# Line 4638  Lisp_Object Vlispy_mouse_stem; Line 4883  Lisp_Object Vlispy_mouse_stem;
4883     which they operate, and a delta corresponding to the amount and     which they operate, and a delta corresponding to the amount and
4884     direction that the wheel is rotated.  Clicking the mouse-wheel     direction that the wheel is rotated.  Clicking the mouse-wheel
4885     generates a mouse-2 event.  */     generates a mouse-2 event.  */
4886  static char *lispy_mouse_wheel_names[] =  static char *lispy_mouse_wheel_names[] =
4887  {  {
4888    "mouse-wheel"    "mouse-wheel"
4889  };  };
# Line 4724  make_lispy_event (event) Line 4969  make_lispy_event (event)
4969    switch (SWITCH_ENUM_CAST (event->kind))    switch (SWITCH_ENUM_CAST (event->kind))
4970      {      {
4971        /* A simple keystroke.  */        /* A simple keystroke.  */
4972      case ascii_keystroke:      case ASCII_KEYSTROKE_EVENT:
4973        {        {
4974          Lisp_Object lispy_c;          Lisp_Object lispy_c;
4975          int c = event->code & 0377;          int c = event->code & 0377;
# Line 4748  make_lispy_event (event) Line 4993  make_lispy_event (event)
4993          return lispy_c;          return lispy_c;
4994        }        }
4995    
4996      case multibyte_char_keystroke:      case MULTIBYTE_CHAR_KEYSTROKE_EVENT:
4997        {        {
4998          Lisp_Object lispy_c;          Lisp_Object lispy_c;
4999    
# Line 4758  make_lispy_event (event) Line 5003  make_lispy_event (event)
5003    
5004        /* A function key.  The symbol may need to have modifier prefixes        /* A function key.  The symbol may need to have modifier prefixes
5005           tacked onto it.  */           tacked onto it.  */
5006      case non_ascii_keystroke:      case NON_ASCII_KEYSTROKE_EVENT:
5007        button_down_time = 0;        button_down_time = 0;
5008    
5009        for (i = 0; i < sizeof (lispy_accent_codes) / sizeof (int); i++)        for (i = 0; i < sizeof (lispy_accent_codes) / sizeof (int); i++)
# Line 4770  make_lispy_event (event) Line 5015  make_lispy_event (event)
5015                                        (sizeof (lispy_accent_keys)                                        (sizeof (lispy_accent_keys)
5016                                         / sizeof (lispy_accent_keys[0])));                                         / sizeof (lispy_accent_keys[0])));
5017    
5018    #if 0
5019  #ifdef XK_kana_A  #ifdef XK_kana_A
5020        if (event->code >= 0x400 && event->code < 0x500)        if (event->code >= 0x400 && event->code < 0x500)
5021          return modify_event_symbol (event->code - 0x400,          return modify_event_symbol (event->code - 0x400,
# Line 4779  make_lispy_event (event) Line 5025  make_lispy_event (event)
5025                                      (sizeof (lispy_kana_keys)                                      (sizeof (lispy_kana_keys)
5026                                       / sizeof (lispy_kana_keys[0])));                                       / sizeof (lispy_kana_keys[0])));
5027  #endif /* XK_kana_A */  #endif /* XK_kana_A */
5028    #endif /* 0 */
5029    
5030  #ifdef ISO_FUNCTION_KEY_OFFSET  #ifdef ISO_FUNCTION_KEY_OFFSET
5031        if (event->code < FUNCTION_KEY_OFFSET        if (event->code < FUNCTION_KEY_OFFSET
# Line 4820  make_lispy_event (event) Line 5067  make_lispy_event (event)
5067  #ifdef HAVE_MOUSE  #ifdef HAVE_MOUSE
5068        /* A mouse click.  Figure out where it is, decide whether it's        /* A mouse click.  Figure out where it is, decide whether it's
5069           a press, click or drag, and build the appropriate structure.  */           a press, click or drag, and build the appropriate structure.  */
5070      case mouse_click:      case MOUSE_CLICK_EVENT:
5071  #ifndef USE_TOOLKIT_SCROLL_BARS  #ifndef USE_TOOLKIT_SCROLL_BARS
5072      case scroll_bar_click:      case SCROLL_BAR_CLICK_EVENT:
5073  #endif  #endif
5074        {        {
5075          int button = event->code;          int button = event->code;
# Line 4835  make_lispy_event (event) Line 5082  make_lispy_event (event)
5082          position = Qnil;          position = Qnil;
5083    
5084          /* Build the position as appropriate for this mouse click.  */          /* Build the position as appropriate for this mouse click.  */
5085          if (event->kind == mouse_click)          if (event->kind == MOUSE_CLICK_EVENT)
5086            {            {
5087              int part;              enum window_part part;
5088              struct frame *f = XFRAME (event->frame_or_window);              struct frame *f = XFRAME (event->frame_or_window);
5089              Lisp_Object posn;              Lisp_Object posn;
5090              Lisp_Object string_info = Qnil;              Lisp_Object string_info = Qnil;
# Line 4856  make_lispy_event (event) Line 5103  make_lispy_event (event)
5103              pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),              pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
5104                                     &column, &row, NULL, 1);                                     &column, &row, NULL, 1);
5105    
5106  #ifndef USE_X_TOOLKIT  #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
5107              /* In the non-toolkit version, clicks on the menu bar              /* In the non-toolkit version, clicks on the menu bar
5108                 are ordinary button events in the event buffer.                 are ordinary button events in the event buffer.
5109                 Distinguish them, and invoke the menu.                 Distinguish them, and invoke the menu.
# Line 4890  make_lispy_event (event) Line 5137  make_lispy_event (event)
5137                      if (NILP (string))                      if (NILP (string))
5138                        break;                        break;
5139                      if (column >= XINT (pos)                      if (column >= XINT (pos)
5140                          && column < XINT (pos) + XSTRING (string)->size)                          && column < XINT (pos) + SCHARS (string))
5141                        {                        {
5142                          item = AREF (items, i);                          item = AREF (items, i);
5143                          break;                          break;
# Line 4908  make_lispy_event (event) Line 5155  make_lispy_event (event)
5155    
5156                  return Fcons (item, Fcons (position, Qnil));                  return Fcons (item, Fcons (position, Qnil));
5157                }                }
5158  #endif /* not USE_X_TOOLKIT */  #endif /* not USE_X_TOOLKIT && not USE_GTK */
5159    
5160              /* Set `window' to the window under frame pixel coordinates              /* Set `window' to the window under frame pixel coordinates
5161                 event->x/event->y.  */                 event->x/event->y.  */
# Line 4936  make_lispy_event (event) Line 5183  make_lispy_event (event)
5183                  XSETINT (event->x, wx);                  XSETINT (event->x, wx);
5184                  XSETINT (event->y, wy);                  XSETINT (event->y, wy);
5185    
5186                  if (part == 1 || part == 3)                  if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
5187                    {                    {
5188                      /* Mode line or header line.  Look for a string under                      /* Mode line or header line.  Look for a string under
5189                         the mouse that may have a `local-map' property.  */                         the mouse that may have a `local-map' property.  */
5190                      Lisp_Object string;                      Lisp_Object string;
5191                      int charpos;                      int charpos;
5192                        
5193                      posn = part == 1 ? Qmode_line : Qheader_line;                      posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
5194                      string = mode_line_string (w, wx, wy, part == 1, &charpos);                      string = mode_line_string (w, wx, wy, part, &charpos);
5195                      if (STRINGP (string))                      if (STRINGP (string))
5196                        string_info = Fcons (string, make_number (charpos));                        string_info = Fcons (string, make_number (charpos));
5197                    }                    }
5198                  else if (part == 2)                  else if (part == ON_VERTICAL_BORDER)
5199                    posn = Qvertical_line;                    posn = Qvertical_line;
5200                  else if (part == 6 || part == 7)                  else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
5201                    {                    {
5202                      int charpos;                      int charpos;
5203                      Lisp_Object object = marginal_area_string (w, wx, wy, part,                      Lisp_Object object = marginal_area_string (w, wx, wy, part,
5204                                                                 &charpos);                                                                 &charpos);
5205                      posn = (part == 6) ? Qleft_margin : Qright_margin;                      posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
5206                      if (STRINGP (object))                      if (STRINGP (object))
5207                        string_info = Fcons (object, make_number (charpos));                        string_info = Fcons (object, make_number (charpos));
5208                    }                    }
# Line 5007  make_lispy_event (event) Line 5254  make_lispy_event (event)
5254                                                    button + 1, Qnil);                                                    button + 1, Qnil);
5255              mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);              mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
5256            }            }
5257            
5258          start_pos_ptr = &AREF (button_down_location, button);          start_pos_ptr = &AREF (button_down_location, button);
5259          start_pos = *start_pos_ptr;          start_pos = *start_pos_ptr;
5260          *start_pos_ptr = Qnil;          *start_pos_ptr = Qnil;
# Line 5040  make_lispy_event (event) Line 5287  make_lispy_event (event)
5287                                 && ((int)(event->timestamp - button_down_time)                                 && ((int)(event->timestamp - button_down_time)
5288                                     < XINT (Vdouble_click_time)))));                                     < XINT (Vdouble_click_time)))));
5289          }          }
5290            
5291          last_mouse_button = button;          last_mouse_button = button;
5292          last_mouse_x = XINT (event->x);          last_mouse_x = XINT (event->x);
5293          last_mouse_y = XINT (event->y);          last_mouse_y = XINT (event->y);
# Line 5105  make_lispy_event (event) Line 5352  make_lispy_event (event)
5352                      button_down_time = 0;                      button_down_time = 0;
5353                      event->modifiers |= drag_modifier;                      event->modifiers |= drag_modifier;
5354                    }                    }
5355                    
5356                  /* Don't check is_double; treat this as multiple                  /* Don't check is_double; treat this as multiple
5357                     if the down-event was multiple.  */                     if the down-event was multiple.  */
5358                  if (double_click_count > 1)                  if (double_click_count > 1)
# Line 5146  make_lispy_event (event) Line 5393  make_lispy_event (event)
5393          }          }
5394        }        }
5395    
5396  #if USE_TOOLKIT_SCROLL_BARS  #ifdef USE_TOOLKIT_SCROLL_BARS
5397    
5398        /* We don't have down and up events if using toolkit scroll bars,        /* We don't have down and up events if using toolkit scroll bars,
5399           so make this always a click event.  Store in the `part' of           so make this always a click event.  Store in the `part' of
# Line 5164  make_lispy_event (event) Line 5411  make_lispy_event (event)
5411           The incoming input_event contains in its `part' member an           The incoming input_event contains in its `part' member an
5412           index of type `enum scroll_bar_part' which we can use as an           index of type `enum scroll_bar_part' which we can use as an
5413           index in scroll_bar_parts to get the appropriate symbol.  */           index in scroll_bar_parts to get the appropriate symbol.  */
5414            
5415      case scroll_bar_click:      case SCROLL_BAR_CLICK_EVENT:
5416        {        {
5417          Lisp_Object position, head, window, portion_whole, part;          Lisp_Object position, head, window, portion_whole, part;
5418    
# Line 5182  make_lispy_event (event) Line 5429  make_lispy_event (event)
5429    
5430          /* Always treat scroll bar events as clicks. */          /* Always treat scroll bar events as clicks. */
5431          event->modifiers |= click_modifier;          event->modifiers |= click_modifier;
5432            event->modifiers &= ~up_modifier;
5433    
5434            if (event->code >= ASIZE (mouse_syms))
5435              mouse_syms = larger_vector (mouse_syms, event->code + 1, Qnil);
5436    
5437          /* Get the symbol we should use for the mouse click.  */          /* Get the symbol we should use for the mouse click.  */
5438          head = modify_event_symbol (event->code,          head = modify_event_symbol (event->code,
5439                                      event->modifiers,                                      event->modifiers,
5440                                      Qmouse_click,                                      Qmouse_click,
5441                                      Vlispy_mouse_stem,                                      Vlispy_mouse_stem,
5442                                      NULL, &mouse_syms,                                      NULL, &mouse_syms,
5443                                      XVECTOR (mouse_syms)->size);                                      XVECTOR (mouse_syms)->size);
5444          return Fcons (head, Fcons (position, Qnil));          return Fcons (head, Fcons (position, Qnil));
5445        }        }
5446          
5447  #endif /* USE_TOOLKIT_SCROLL_BARS */  #endif /* USE_TOOLKIT_SCROLL_BARS */
5448    
5449  #ifdef WINDOWSNT  #ifdef WINDOWSNT
5450      case w32_scroll_bar_click:      case W32_SCROLL_BAR_CLICK_EVENT:
5451        {        {
5452          int button = event->code;          int button = event->code;
5453          int is_double;          int is_double;
# Line 5230  make_lispy_event (event) Line 5481  make_lispy_event (event)
5481    
5482            head = modify_event_symbol (button,            head = modify_event_symbol (button,
5483                                        event->modifiers,                                        event->modifiers,
5484                                        Qmouse_click,                                        Qmouse_click,
5485                                        Vlispy_mouse_stem,                                        Vlispy_mouse_stem,
5486                                        NULL, &mouse_syms,                                        NULL, &mouse_syms,
5487                                        XVECTOR (mouse_syms)->size);                                        XVECTOR (mouse_syms)->size);
# Line 5239  make_lispy_event (event) Line 5490  make_lispy_event (event)
5490                                 Qnil));                                 Qnil));
5491          }          }
5492        }        }
5493      case mouse_wheel:  #endif /* WINDOWSNT */
5494    #if defined(WINDOWSNT) || defined(MAC_OSX)
5495        case MOUSE_WHEEL_EVENT:
5496        {        {
5497          int part;          enum window_part part;
5498          FRAME_PTR f = XFRAME (event->frame_or_window);          FRAME_PTR f = XFRAME (event->frame_or_window);
5499          Lisp_Object window;          Lisp_Object window;
5500          Lisp_Object posn;          Lisp_Object posn;
# Line 5272  make_lispy_event (event) Line 5525  make_lispy_event (event)
5525              XSETINT (event->x, pixcolumn);              XSETINT (event->x, pixcolumn);
5526              XSETINT (event->y, pixrow);              XSETINT (event->y, pixrow);
5527    
5528              if (part == 1)              if (part == ON_MODE_LINE)
5529                posn = Qmode_line;                posn = Qmode_line;
5530              else if (part == 2)              else if (part == ON_VERTICAL_BORDER)
5531                posn = Qvertical_line;                posn = Qvertical_line;
5532              else if (part == 3)              else if (part == ON_HEADER_LINE)
5533                posn = Qheader_line;                posn = Qheader_line;
5534              else              else
5535                {                {
# Line 5310  make_lispy_event (event) Line 5563  make_lispy_event (event)
5563                                               Qnil))));                                               Qnil))));
5564          }          }
5565        }        }
5566  #endif /* WINDOWSNT */  #endif /* WINDOWSNT || MAC_OSX */
5567    
5568      case drag_n_drop:      case DRAG_N_DROP_EVENT:
5569        {        {
5570          int part;          enum window_part part;
5571          FRAME_PTR f;          FRAME_PTR f;
5572          Lisp_Object window;          Lisp_Object window;
5573          Lisp_Object posn;          Lisp_Object posn;
# Line 5357  make_lispy_event (event) Line 5610  make_lispy_event (event)
5610              XSETINT (event->x, wx);              XSETINT (event->x, wx);
5611              XSETINT (event->y, wy);              XSETINT (event->y, wy);
5612    
5613              if (part == 1)              if (part == ON_MODE_LINE)
5614                posn = Qmode_line;                posn = Qmode_line;
5615              else if (part == 2)              else if (part == ON_VERTICAL_BORDER)
5616                posn = Qvertical_line;                posn = Qvertical_line;
5617              else if (part == 3)              else if (part == ON_HEADER_LINE)
5618                posn = Qheader_line;                posn = Qheader_line;
5619              else              else
5620                {                {
# Line 5394  make_lispy_event (event) Line 5647  make_lispy_event (event)
5647        }        }
5648  #endif /* HAVE_MOUSE */  #endif /* HAVE_MOUSE */
5649    
5650  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
5651        || defined (USE_GTK)
5652      case MENU_BAR_EVENT:      case MENU_BAR_EVENT:
5653        if (EQ (event->arg, event->frame_or_window))        if (EQ (event->arg, event->frame_or_window))
5654          /* This is the prefix key.  We translate this to          /* This is the prefix key.  We translate this to
# Line 5417  make_lispy_event (event) Line 5671  make_lispy_event (event)
5671      case USER_SIGNAL_EVENT:      case USER_SIGNAL_EVENT:
5672        /* A user signal.  */        /* A user signal.  */
5673        return *lispy_user_signals[event->code];        return *lispy_user_signals[event->code];
5674          
5675      case save_session_event:      case SAVE_SESSION_EVENT:
5676        return Qsave_session;        return Qsave_session;
5677          
5678        /* The 'kind' field of the event is something we don't recognize.  */        /* The 'kind' field of the event is something we don't recognize.  */
5679      default:      default:
5680        abort ();        abort ();
# Line 5456  make_lispy_movement (frame, bar_window, Line 5710  make_lispy_movement (frame, bar_window,
5710    /* Or is it an ordinary mouse movement?  */    /* Or is it an ordinary mouse movement?  */
5711    else    else
5712      {      {
5713        int area;        enum window_part area;
5714        Lisp_Object window;        Lisp_Object window;
5715        Lisp_Object posn;        Lisp_Object posn;
5716    
# Line 5470  make_lispy_movement (frame, bar_window, Line 5724  make_lispy_movement (frame, bar_window,
5724          {          {
5725            struct window *w = XWINDOW (window);            struct window *w = XWINDOW (window);
5726            int wx, wy;            int wx, wy;
5727              
5728            /* Get window relative coordinates.  */            /* Get window relative coordinates.  */
5729            wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (x));            wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (x));
5730            wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (y));            wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (y));
5731            XSETINT (x, wx);            XSETINT (x, wx);
5732            XSETINT (y, wy);            XSETINT (y, wy);
5733              
5734            if (area == 1)            if (area == ON_MODE_LINE)
5735              posn = Qmode_line;              posn = Qmode_line;
5736            else if (area == 2)            else if (area == ON_VERTICAL_BORDER)
5737              posn = Qvertical_line;              posn = Qvertical_line;
5738            else if (area == 3)            else if (area == ON_HEADER_LINE)
5739              posn = Qheader_line;              posn = Qheader_line;
5740            else            else
5741              {              {
# Line 5539  parse_modifiers_uncached (symbol, modifi Line 5793  parse_modifiers_uncached (symbol, modifi
5793       Lisp_Object symbol;       Lisp_Object symbol;
5794       int *modifier_end;       int *modifier_end;
5795  {  {
5796    struct Lisp_String *name;    Lisp_Object name;
5797    int i;    int i;
5798    int modifiers;    int modifiers;
5799    
5800    CHECK_SYMBOL (symbol);    CHECK_SYMBOL (symbol);
5801    
5802    modifiers = 0;    modifiers = 0;
5803    name = XSTRING (SYMBOL_NAME (symbol));    name = SYMBOL_NAME (symbol);
5804    
5805    for (i = 0; i+2 <= STRING_BYTES (name); )    for (i = 0; i+2 <= SBYTES (name); )
5806      {      {
5807        int this_mod_end = 0;        int this_mod_end = 0;
5808        int this_mod = 0;        int this_mod = 0;
# Line 5557  parse_modifiers_uncached (symbol, modifi Line 5811  parse_modifiers_uncached (symbol, modifi
5811           Check that the word appears, but don't check what follows it.           Check that the word appears, but don't check what follows it.
5812           Set this_mod and this_mod_end to record what we find.  */           Set this_mod and this_mod_end to record what we find.  */
5813    
5814        switch (name->data[i])        switch (SREF (name, i))
5815          {          {
5816  #define SINGLE_LETTER_MOD(BIT)                          \  #define SINGLE_LETTER_MOD(BIT)                          \
5817            (this_mod_end = i + 1, this_mod = BIT)            (this_mod_end = i + 1, this_mod = BIT)
# Line 5595  parse_modifiers_uncached (symbol, modifi Line 5849  parse_modifiers_uncached (symbol, modifi
5849    
5850        /* Check there is a dash after the modifier, so that it        /* Check there is a dash after the modifier, so that it
5851           really is a modifier.  */           really is a modifier.  */
5852        if (this_mod_end >= STRING_BYTES (name)        if (this_mod_end >= SBYTES (name)
5853            || name->data[this_mod_end] != '-')            || SREF (name, this_mod_end) != '-')
5854          break;          break;
5855    
5856        /* This modifier is real; look for another.  */        /* This modifier is real; look for another.  */
# Line 5607  parse_modifiers_uncached (symbol, modifi Line 5861  parse_modifiers_uncached (symbol, modifi
5861    /* Should we include the `click' modifier?  */    /* Should we include the `click' modifier?  */
5862    if (! (modifiers & (down_modifier | drag_modifier    if (! (modifiers & (down_modifier | drag_modifier
5863                        | double_modifier | triple_modifier))                        | double_modifier | triple_modifier))
5864        && i + 7 == STRING_BYTES (name)        && i + 7 == SBYTES (name)
5865        && strncmp (name->data + i, "mouse-", 6) == 0        && strncmp (SDATA (name) + i, "mouse-", 6) == 0
5866        && ('0' <= name->data[i + 6] && name->data[i + 6] <= '9'))        && ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9'))
5867      modifiers |= click_modifier;      modifiers |= click_modifier;
5868    
5869    if (modifier_end)    if (modifier_end)
# Line 5664  apply_modifiers_uncached (modifiers, bas Line 5918  apply_modifiers_uncached (modifiers, bas
5918    
5919      new_name = make_uninit_multibyte_string (mod_len + base_len,      new_name = make_uninit_multibyte_string (mod_len + base_len,
5920                                               mod_len + base_len_byte);                                               mod_len + base_len_byte);
5921      bcopy (new_mods, XSTRING (new_name)->data,         mod_len);      bcopy (new_mods, SDATA (new_name),         mod_len);
5922      bcopy (base,     XSTRING (new_name)->data + mod_len, base_len_byte);      bcopy (base,     SDATA (new_name) + mod_len, base_len_byte);
5923    
5924      return Fintern (new_name, Qnil);      return Fintern (new_name, Qnil);
5925    }    }
# Line 5723  parse_modifiers (symbol) Line 5977  parse_modifiers (symbol)
5977        Lisp_Object unmodified;        Lisp_Object unmodified;
5978        Lisp_Object mask;        Lisp_Object mask;
5979    
5980        unmodified = Fintern (make_string (XSTRING (SYMBOL_NAME (symbol))->data + end,        unmodified = Fintern (make_string (SDATA (SYMBOL_NAME (symbol)) + end,
5981                                           STRING_BYTES (XSTRING (SYMBOL_NAME (symbol))) - end),                                           SBYTES (SYMBOL_NAME (symbol)) - end),
5982                              Qnil);                              Qnil);
5983    
5984        if (modifiers & ~VALMASK)        if (modifiers & ~VALMASK)
# Line 5777  apply_modifiers (modifiers, base) Line 6031  apply_modifiers (modifiers, base)
6031      {      {
6032        /* We have to create the symbol ourselves.  */        /* We have to create the symbol ourselves.  */
6033        new_symbol = apply_modifiers_uncached (modifiers,        new_symbol = apply_modifiers_uncached (modifiers,
6034                                               XSTRING (SYMBOL_NAME (base))->data,                                               SDATA (SYMBOL_NAME (base)),
6035                                               XSTRING (SYMBOL_NAME (base))->size,                                               SCHARS (SYMBOL_NAME (base)),
6036                                               STRING_BYTES (XSTRING (SYMBOL_NAME (base))));                                               SBYTES (SYMBOL_NAME (base)));
6037    
6038        /* Add the new symbol to the base's cache.  */        /* Add the new symbol to the base's cache.  */
6039        entry = Fcons (index, new_symbol);        entry = Fcons (index, new_symbol);
# Line 5917  modify_event_symbol (symbol_num, modifie Line 6171  modify_event_symbol (symbol_num, modifie
6171          value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));          value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
6172        else if (STRINGP (name_alist_or_stem))        else if (STRINGP (name_alist_or_stem))
6173          {          {
6174            int len = STRING_BYTES (XSTRING (name_alist_or_stem));            int len = SBYTES (name_alist_or_stem);
6175            char *buf = (char *) alloca (len + 50);            char *buf = (char *) alloca (len + 50);
6176            sprintf (buf, "%s-%d", XSTRING (name_alist_or_stem)->data,            if (sizeof (int) == sizeof (EMACS_INT))
6177                     XINT (symbol_int) + 1);              sprintf (buf, "%s-%d", SDATA (name_alist_or_stem),
6178                         XINT (symbol_int) + 1);
6179              else if (sizeof (long) == sizeof (EMACS_INT))
6180                sprintf (buf, "%s-%ld", SDATA (name_alist_or_stem),
6181                         XINT (symbol_int) + 1);
6182            value = intern (buf);            value = intern (buf);
6183          }          }
6184        else if (name_table != 0 && name_table[symbol_num])        else if (name_table != 0 && name_table[symbol_num])
# Line 6000  has the same base event type and all the Line 6258  has the same base event type and all the
6258      }      }
6259    
6260    /* Let the symbol A refer to the character A.  */    /* Let the symbol A refer to the character A.  */
6261    if (SYMBOLP (base) && XSTRING (SYMBOL_NAME (base))->size == 1)    if (SYMBOLP (base) && SCHARS (SYMBOL_NAME (base)) == 1)
6262      XSETINT (base, XSTRING (SYMBOL_NAME (base))->data[0]);      XSETINT (base, SREF (SYMBOL_NAME (base), 0));
6263    
6264    if (INTEGERP (base))    if (INTEGERP (base))
6265      {      {
# Line 6036  static int Line 6294  static int
6294  parse_solitary_modifier (symbol)  parse_solitary_modifier (symbol)
6295       Lisp_Object symbol;       Lisp_Object symbol;
6296  {  {
6297    struct Lisp_String *name = XSTRING (SYMBOL_NAME (symbol));    Lisp_Object name = SYMBOL_NAME (symbol);
6298    
6299    switch (name->data[0])    switch (SREF (name, 0))
6300      {      {
6301  #define SINGLE_LETTER_MOD(BIT)                          \  #define SINGLE_LETTER_MOD(BIT)                          \
6302        if (STRING_BYTES (name) == 1)                     \        if (SBYTES (name) == 1)                           \
6303          return BIT;          return BIT;
6304    
6305  #define MULTI_LETTER_MOD(BIT, NAME, LEN)                \  #define MULTI_LETTER_MOD(BIT, NAME, LEN)                \
6306        if (LEN == STRING_BYTES (name)                    \        if (LEN == SBYTES (name)                          \
6307            && ! strncmp (name->data, NAME, LEN))         \            && ! strncmp (SDATA (name), NAME, LEN))       \
6308          return BIT;          return BIT;
6309    
6310      case 'A':      case 'A':
# Line 6144  lucid_event_type_list_p (object) Line 6402  lucid_event_type_list_p (object)
6402     but works even if FIONREAD does not exist.     but works even if FIONREAD does not exist.
6403     (In fact, this may actually read some input.)     (In fact, this may actually read some input.)
6404    
6405     If DO_TIMERS_NOW is nonzero, actually run timer events that are ripe.  */     If DO_TIMERS_NOW is nonzero, actually run timer events that are ripe.
6406       If FILTER_EVENTS is nonzero, ignore internal events (FOCUS_IN_EVENT). */
6407    
6408  static void  static void
6409  get_input_pending (addr, do_timers_now)  get_filtered_input_pending (addr, do_timers_now, filter_events)
6410       int *addr;       int *addr;
6411       int do_timers_now;       int do_timers_now;
6412         int filter_events;
6413  {  {
6414    /* First of all, have we already counted some input?  */    /* First of all, have we already counted some input?  */
6415    *addr = !NILP (Vquit_flag) || readable_events (do_timers_now);    *addr = (!NILP (Vquit_flag)
6416               || readable_filtered_events (do_timers_now, filter_events));
6417    
6418    /* If input is being read as it arrives, and we have none, there is none.  */    /* If input is being read as it arrives, and we have none, there is none.  */
6419    if (*addr > 0 || (interrupt_input && ! interrupts_deferred))    if (*addr > 0 || (interrupt_input && ! interrupts_deferred))
# Line 6160  get_input_pending (addr, do_timers_now) Line 6421  get_input_pending (addr, do_timers_now)
6421    
6422    /* Try to read some input and see how much we get.  */    /* Try to read some input and see how much we get.  */
6423    gobble_input (0);    gobble_input (0);
6424    *addr = !NILP (Vquit_flag) || readable_events (do_timers_now);    *addr = (!NILP (Vquit_flag)
6425               || readable_filtered_events (do_timers_now, filter_events));
6426    }
6427    
6428    /* Store into *addr a value nonzero if terminal input chars are available.
6429       Serves the purpose of ioctl (0, FIONREAD, addr)
6430       but works even if FIONREAD does not exist.
6431       (In fact, this may actually read some input.)
6432    
6433       If DO_TIMERS_NOW is nonzero, actually run timer events that are ripe.  */
6434    
6435    static void
6436    get_input_pending (addr, do_timers_now)
6437         int *addr;
6438         int do_timers_now;
6439    {
6440      get_filtered_input_pending (addr, do_timers_now, 0);
6441  }  }
6442    
6443  /* Interface to read_avail_input, blocking SIGIO or SIGALRM if necessary.  */  /* Interface to read_avail_input, blocking SIGIO or SIGALRM if necessary.  */
# Line 6194  gobble_input (expected) Line 6471  gobble_input (expected)
6471  #endif  #endif
6472  }  }
6473    
6474  /* Put a buffer_switch_event in the buffer  /* Put a BUFFER_SWITCH_EVENT in the buffer
6475     so that read_key_sequence will notice the new current buffer.  */     so that read_key_sequence will notice the new current buffer.  */
6476    
6477  void  void
# Line 6203  record_asynch_buffer_change () Line 6480  record_asynch_buffer_change ()
6480    struct input_event event;    struct input_event event;
6481    Lisp_Object tem;    Lisp_Object tem;
6482    
6483    event.kind = buffer_switch_event;    event.kind = BUFFER_SWITCH_EVENT;
6484    event.frame_or_window = Qnil;    event.frame_or_window = Qnil;
6485    event.arg = Qnil;    event.arg = Qnil;
6486    
# Line 6295  read_avail_input (expected) Line 6572  read_avail_input (expected)
6572        if (n_to_read > sizeof cbuf)        if (n_to_read > sizeof cbuf)
6573          n_to_read = sizeof cbuf;          n_to_read = sizeof cbuf;
6574  #else /* no FIONREAD */  #else /* no FIONREAD */
6575  #if defined (USG) || defined (DGUX)  #if defined (USG) || defined (DGUX) || defined(CYGWIN)
6576        /* Read some input if available, but don't wait.  */        /* Read some input if available, but don't wait.  */
6577        n_to_read = sizeof cbuf;        n_to_read = sizeof cbuf;
6578        fcntl (input_fd, F_SETFL, O_NDELAY);        fcntl (input_fd, F_SETFL, O_NDELAY);
# Line 6352  read_avail_input (expected) Line 6629  read_avail_input (expected)
6629               );               );
6630    
6631  #ifndef FIONREAD  #ifndef FIONREAD
6632  #if defined (USG) || defined (DGUX)  #if defined (USG) || defined (DGUX) || defined (CYGWIN)
6633        fcntl (input_fd, F_SETFL, 0);        fcntl (input_fd, F_SETFL, 0);
6634  #endif /* USG or DGUX */  #endif /* USG or DGUX or CYGWIN */
6635  #endif /* no FIONREAD */  #endif /* no FIONREAD */
6636        for (i = 0; i < nread; i++)        for (i = 0; i < nread; i++)
6637          {          {
6638            buf[i].kind = ascii_keystroke;            buf[i].kind = ASCII_KEYSTROKE_EVENT;
6639            buf[i].modifiers = 0;            buf[i].modifiers = 0;
6640            if (meta_key == 1 && (cbuf[i] & 0x80))            if (meta_key == 1 && (cbuf[i] & 0x80))
6641              buf[i].modifiers = meta_modifier;              buf[i].modifiers = meta_modifier;
# Line 6377  read_avail_input (expected) Line 6654  read_avail_input (expected)
6654        kbd_buffer_store_event (&buf[i]);        kbd_buffer_store_event (&buf[i]);
6655        /* Don't look at input that follows a C-g too closely.        /* Don't look at input that follows a C-g too closely.
6656           This reduces lossage due to autorepeat on C-g.  */           This reduces lossage due to autorepeat on C-g.  */
6657        if (buf[i].kind == ascii_keystroke        if (buf[i].kind == ASCII_KEYSTROKE_EVENT
6658            && buf[i].code == quit_char)            && buf[i].code == quit_char)
6659          break;          break;
6660      }      }
# Line 6740  menu_item_eval_property_1 (arg) Line 7017  menu_item_eval_property_1 (arg)
7017    return Qnil;    return Qnil;
7018  }  }
7019    
7020  /* Evaluate an expression and return the result (or nil if something  /* Evaluate an expression and return the result (or nil if something
7021     went wrong).  Used to evaluate dynamic parts of menu items.  */     went wrong).  Used to evaluate dynamic parts of menu items.  */
7022  Lisp_Object  Lisp_Object
7023  menu_item_eval_property (sexpr)  menu_item_eval_property (sexpr)
7024       Lisp_Object sexpr;       Lisp_Object sexpr;
7025  {  {
7026    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
7027    Lisp_Object val;    Lisp_Object val;
7028    specbind (Qinhibit_redisplay, Qt);    specbind (Qinhibit_redisplay, Qt);
7029    val = internal_condition_case_1 (Feval, sexpr, Qerror,    val = internal_condition_case_1 (Feval, sexpr, Qerror,
# Line 6793  parse_menu_item (item, notreal, inmenuba Line 7070  parse_menu_item (item, notreal, inmenuba
7070    for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++)    for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++)
7071      AREF (item_properties, i) = Qnil;      AREF (item_properties, i) = Qnil;
7072    AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt;    AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt;
7073            
7074    /* Save the item here to protect it from GC.  */    /* Save the item here to protect it from GC.  */
7075    AREF (item_properties, ITEM_PROPERTY_ITEM) = item;    AREF (item_properties, ITEM_PROPERTY_ITEM) = item;
7076    
# Line 6813  parse_menu_item (item, notreal, inmenuba Line 7090  parse_menu_item (item, notreal, inmenuba
7090            start = item;            start = item;
7091            item = XCDR (item);            item = XCDR (item);
7092          }          }
7093              
7094        /* Maybe key binding cache.  */        /* Maybe key binding cache.  */
7095        if (CONSP (item) && CONSP (XCAR (item))        if (CONSP (item) && CONSP (XCAR (item))
7096            && (NILP (XCAR (XCAR (item)))            && (NILP (XCAR (XCAR (item)))
# Line 6822  parse_menu_item (item, notreal, inmenuba Line 7099  parse_menu_item (item, notreal, inmenuba
7099            cachelist = XCAR (item);            cachelist = XCAR (item);
7100            item = XCDR (item);            item = XCDR (item);
7101          }          }
7102          
7103        /* This is the real definition--the function to run.  */        /* This is the real definition--the function to run.  */
7104        AREF (item_properties, ITEM_PROPERTY_DEF) = item;        AREF (item_properties, ITEM_PROPERTY_DEF) = item;
7105    
# Line 6918  parse_menu_item (item, notreal, inmenuba Line 7195  parse_menu_item (item, notreal, inmenuba
7195          return 0;          return 0;
7196        AREF (item_properties, ITEM_PROPERTY_NAME) = item_string;        AREF (item_properties, ITEM_PROPERTY_NAME) = item_string;
7197      }      }
7198        
7199    /* If got a filter apply it on definition.  */    /* If got a filter apply it on definition.  */
7200    def = AREF (item_properties, ITEM_PROPERTY_DEF);    def = AREF (item_properties, ITEM_PROPERTY_DEF);
7201    if (!NILP (filter))    if (!NILP (filter))
# Line 6946  parse_menu_item (item, notreal, inmenuba Line 7223  parse_menu_item (item, notreal, inmenuba
7223       is OK in a submenu but not in the menubar.  */       is OK in a submenu but not in the menubar.  */
7224    if (NILP (def))    if (NILP (def))
7225      return (inmenubar ? 0 : 1);      return (inmenubar ? 0 : 1);
7226    
7227    /* See if this is a separate pane or a submenu.  */    /* See if this is a separate pane or a submenu.  */
7228    def = AREF (item_properties, ITEM_PROPERTY_DEF);    def = AREF (item_properties, ITEM_PROPERTY_DEF);
7229    tem = get_keymap (def, 0, 1);    tem = get_keymap (def, 0, 1);
# Line 6957  parse_menu_item (item, notreal, inmenuba Line 7234  parse_menu_item (item, notreal, inmenuba
7234        AREF (item_properties, ITEM_PROPERTY_DEF) = tem;        AREF (item_properties, ITEM_PROPERTY_DEF) = tem;
7235        return 1;        return 1;
7236      }      }
7237      
7238    /* At the top level in the menu bar, do likewise for commands also.    /* At the top level in the menu bar, do likewise for commands also.
7239       The menu bar does not display equivalent key bindings anyway.       The menu bar does not display equivalent key bindings anyway.
7240       ITEM_PROPERTY_DEF is already set up properly.  */       ITEM_PROPERTY_DEF is already set up properly.  */
# Line 6984  parse_menu_item (item, notreal, inmenuba Line 7261  parse_menu_item (item, notreal, inmenuba
7261            XSETCAR (cachelist, Qt);            XSETCAR (cachelist, Qt);
7262          }          }
7263      }      }
7264      
7265    tem = XCAR (cachelist);    tem = XCAR (cachelist);
7266    if (!EQ (tem, Qt))    if (!EQ (tem, Qt))
7267      {      {
# Line 7092  parse_menu_item (item, notreal, inmenuba Line 7369  parse_menu_item (item, notreal, inmenuba
7369      }      }
7370    */    */
7371    
7372    /* Handle radio buttons or toggle boxes.  */    /* Handle radio buttons or toggle boxes.  */
7373    tem = AREF (item_properties, ITEM_PROPERTY_SELECTED);    tem = AREF (item_properties, ITEM_PROPERTY_SELECTED);
7374    if (!NILP (tem))    if (!NILP (tem))
7375      AREF (item_properties, ITEM_PROPERTY_SELECTED)      AREF (item_properties, ITEM_PROPERTY_SELECTED)
# Line 7159  tool_bar_items (reuse, nitems) Line 7436  tool_bar_items (reuse, nitems)
7436       avoids risk of specpdl overflow.  */       avoids risk of specpdl overflow.  */
7437    oquit = Vinhibit_quit;    oquit = Vinhibit_quit;
7438    Vinhibit_quit = Qt;    Vinhibit_quit = Qt;
7439      
7440    /* Initialize tool_bar_items_vector and protect it from GC.  */    /* Initialize tool_bar_items_vector and protect it from GC.  */
7441    init_tool_bar_items (reuse);    init_tool_bar_items (reuse);
7442    
7443    /* Build list of keymaps in maps.  Set nmaps to the number of maps    /* Build list of keymaps in maps.  Set nmaps to the number of maps
7444       to process.  */       to process.  */
7445      
7446    /* Should overriding-terminal-local-map and overriding-local-map apply?  */    /* Should overriding-terminal-local-map and overriding-local-map apply?  */
7447    if (!NILP (Voverriding_local_map_menu_flag))    if (!NILP (Voverriding_local_map_menu_flag))
7448      {      {
# Line 7210  tool_bar_items (reuse, nitems) Line 7487  tool_bar_items (reuse, nitems)
7487          if (CONSP (keymap))          if (CONSP (keymap))
7488            {            {
7489              Lisp_Object tail;              Lisp_Object tail;
7490                
7491              /* KEYMAP is a list `(keymap (KEY . BINDING) ...)'.  */              /* KEYMAP is a list `(keymap (KEY . BINDING) ...)'.  */
7492              for (tail = keymap; CONSP (tail); tail = XCDR (tail))              for (tail = keymap; CONSP (tail); tail = XCDR (tail))
7493                {                {
# Line 7248  process_tool_bar_item (key, def) Line 7525  process_tool_bar_item (key, def)
7525        for (i = 0; i < ntool_bar_items; i += TOOL_BAR_ITEM_NSLOTS)        for (i = 0; i < ntool_bar_items; i += TOOL_BAR_ITEM_NSLOTS)
7526          {          {
7527            Lisp_Object *v = XVECTOR (tool_bar_items_vector)->contents + i;            Lisp_Object *v = XVECTOR (tool_bar_items_vector)->contents + i;
7528              
7529            if (EQ (key, v[TOOL_BAR_ITEM_KEY]))            if (EQ (key, v[TOOL_BAR_ITEM_KEY]))
7530              {              {
7531                if (ntool_bar_items > i + TOOL_BAR_ITEM_NSLOTS)                if (ntool_bar_items > i + TOOL_BAR_ITEM_NSLOTS)
# Line 7274  process_tool_bar_item (key, def) Line 7551  process_tool_bar_item (key, def)
7551     invalid.     invalid.
7552    
7553     ITEM is a list `(menu-item CAPTION BINDING PROPS...)'.     ITEM is a list `(menu-item CAPTION BINDING PROPS...)'.
7554      
7555     CAPTION is the caption of the item,  If it's not a string, it is     CAPTION is the caption of the item,  If it's not a string, it is
7556     evaluated to get a string.     evaluated to get a string.
7557      
7558     BINDING is the tool bar item's binding.  Tool-bar items with keymaps     BINDING is the tool bar item's binding.  Tool-bar items with keymaps
7559     as binding are currently ignored.     as binding are currently ignored.
7560    
7561     The following properties are recognized:     The following properties are recognized:
7562    
7563     - `:enable FORM'.     - `:enable FORM'.
7564      
7565     FORM is evaluated and specifies whether the tool bar item is     FORM is evaluated and specifies whether the tool bar item is
7566     enabled or disabled.     enabled or disabled.
7567      
7568     - `:visible FORM'     - `:visible FORM'
7569      
7570     FORM is evaluated and specifies whether the tool bar item is visible.     FORM is evaluated and specifies whether the tool bar item is visible.
7571      
7572     - `:filter FUNCTION'     - `:filter FUNCTION'
7573    
7574     FUNCTION is invoked with one parameter `(quote BINDING)'.  Its     FUNCTION is invoked with one parameter `(quote BINDING)'.  Its
7575     result is stored as the new binding.     result is stored as the new binding.
7576      
7577     - `:button (TYPE SELECTED)'     - `:button (TYPE SELECTED)'
7578    
7579     TYPE must be one of `:radio' or `:toggle'.  SELECTED is evaluated     TYPE must be one of `:radio' or `:toggle'.  SELECTED is evaluated
7580     and specifies whether the button is selected (pressed) or not.     and specifies whether the button is selected (pressed) or not.
7581      
7582     - `:image IMAGES'     - `:image IMAGES'
7583    
7584     IMAGES is either a single image specification or a vector of four     IMAGES is either a single image specification or a vector of four
7585     image specifications.  See enum tool_bar_item_images.     image specifications.  See enum tool_bar_item_images.
7586      
7587     - `:help HELP-STRING'.     - `:help HELP-STRING'.
7588      
7589     Gives a help string to display for the tool bar item.  */     Gives a help string to display for the tool bar item.  */
7590    
7591  static int  static int
# Line 7342  parse_tool_bar_item (key, item) Line 7619  parse_tool_bar_item (key, item)
7619    else    else
7620      tool_bar_item_properties      tool_bar_item_properties
7621        = Fmake_vector (make_number (TOOL_BAR_ITEM_NSLOTS), Qnil);        = Fmake_vector (make_number (TOOL_BAR_ITEM_NSLOTS), Qnil);
7622      
7623    /* Set defaults.  */    /* Set defaults.  */
7624    PROP (TOOL_BAR_ITEM_KEY) = key;    PROP (TOOL_BAR_ITEM_KEY) = key;
7625    PROP (TOOL_BAR_ITEM_ENABLED_P) = Qt;    PROP (TOOL_BAR_ITEM_ENABLED_P) = Qt;
7626            
7627    /* Get the caption of the item.  If the caption is not a string,    /* Get the caption of the item.  If the caption is not a string,
7628       evaluate it to get a string.  If we don't get a string, skip this       evaluate it to get a string.  If we don't get a string, skip this
7629       item.  */       item.  */
# Line 7433  parse_tool_bar_item (key, item) Line 7710  parse_tool_bar_item (key, item)
7710      PROP (TOOL_BAR_ITEM_ENABLED_P)      PROP (TOOL_BAR_ITEM_ENABLED_P)
7711        = menu_item_eval_property (PROP (TOOL_BAR_ITEM_ENABLED_P));        = menu_item_eval_property (PROP (TOOL_BAR_ITEM_ENABLED_P));
7712    
7713    /* Handle radio buttons or toggle boxes.  */    /* Handle radio buttons or toggle boxes.  */
7714    if (!NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)))    if (!NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)))
7715      PROP (TOOL_BAR_ITEM_SELECTED_P)      PROP (TOOL_BAR_ITEM_SELECTED_P)
7716        = menu_item_eval_property (PROP (TOOL_BAR_ITEM_SELECTED_P));        = menu_item_eval_property (PROP (TOOL_BAR_ITEM_SELECTED_P));
7717    
7718    return 1;    return 1;
7719      
7720  #undef PROP  #undef PROP
7721  }  }
7722    
# Line 7466  static void Line 7743  static void
7743  append_tool_bar_item ()  append_tool_bar_item ()
7744  {  {
7745    Lisp_Object *to, *from;    Lisp_Object *to, *from;
7746      
7747    /* Enlarge tool_bar_items_vector if necessary.  */    /* Enlarge tool_bar_items_vector if necessary.  */
7748    if (ntool_bar_items + TOOL_BAR_ITEM_NSLOTS    if (ntool_bar_items + TOOL_BAR_ITEM_NSLOTS
7749        >= XVECTOR (tool_bar_items_vector)->size)        >= XVECTOR (tool_bar_items_vector)->size)
# Line 7521  read_char_x_menu_prompt (nmaps, maps, pr Line 7798  read_char_x_menu_prompt (nmaps, maps, pr
7798       int *used_mouse_menu;       int *used_mouse_menu;
7799  {  {
7800    int mapno;    int mapno;
7801    register Lisp_Object name;    register Lisp_Object name = Qnil;
7802    
7803    if (used_mouse_menu)    if (used_mouse_menu)
7804      *used_mouse_menu = 0;      *used_mouse_menu = 0;
# Line 7623  read_char_minibuf_menu_prompt (commandfl Line 7900  read_char_minibuf_menu_prompt (commandfl
7900    int mapno;    int mapno;
7901    register Lisp_Object name;    register Lisp_Object name;
7902    int nlength;    int nlength;
7903      /* FIXME: Use the minibuffer's frame width.  */
7904    int width = FRAME_WIDTH (SELECTED_FRAME ()) - 4;    int width = FRAME_WIDTH (SELECTED_FRAME ()) - 4;
7905    int idx = -1;    int idx = -1;
7906    int nobindings = 1;    int nobindings = 1;
# Line 7662  read_char_minibuf_menu_prompt (commandfl Line 7940  read_char_minibuf_menu_prompt (commandfl
7940      return Qnil;      return Qnil;
7941    
7942    /* Prompt string always starts with map's prompt, and a space.  */    /* Prompt string always starts with map's prompt, and a space.  */
7943    strcpy (menu, XSTRING (name)->data);    strcpy (menu, SDATA (name));
7944    nlength = STRING_BYTES (XSTRING (name));    nlength = SBYTES (name);
7945    menu[nlength++] = ':';    menu[nlength++] = ':';
7946    menu[nlength++] = ' ';    menu[nlength++] = ' ';
7947    menu[nlength] = 0;    menu[nlength] = 0;
# Line 7741  read_char_minibuf_menu_prompt (commandfl Line 8019  read_char_minibuf_menu_prompt (commandfl
8019    
8020                    upcased_event = Fupcase (event);                    upcased_event = Fupcase (event);
8021                    downcased_event = Fdowncase (event);                    downcased_event = Fdowncase (event);
8022                    char_matches = (XINT (upcased_event) == XSTRING (s)->data[0]                    char_matches = (XINT (upcased_event) == SREF (s, 0)
8023                                    || XINT (downcased_event) == XSTRING (s)->data[0]);                                    || XINT (downcased_event) == SREF (s, 0));
8024                    if (! char_matches)                    if (! char_matches)
8025                      desc = Fsingle_key_description (event, Qnil);                      desc = Fsingle_key_description (event, Qnil);
8026    
# Line 7767  read_char_minibuf_menu_prompt (commandfl Line 8045  read_char_minibuf_menu_prompt (commandfl
8045                          tem = build_string (NILP (selected) ? "[X] " : "[ ] ");                          tem = build_string (NILP (selected) ? "[X] " : "[ ] ");
8046                        s = concat2 (tem, s);                        s = concat2 (tem, s);
8047                      }                      }
8048                      
8049    
8050                    /* If we have room for the prompt string, add it to this line.                    /* If we have room for the prompt string, add it to this line.
8051                       If this is the first on the line, always add it.  */                       If this is the first on the line, always add it.  */
8052                    if ((XSTRING (s)->size + i + 2                    if ((SCHARS (s) + i + 2
8053                         + (char_matches ? 0 : XSTRING (desc)->size + 3))                         + (char_matches ? 0 : SCHARS (desc) + 3))
8054                        < width                        < width
8055                        || !notfirst)                        || !notfirst)
8056                      {                      {
# Line 7792  read_char_minibuf_menu_prompt (commandfl Line 8070  read_char_minibuf_menu_prompt (commandfl
8070                        if (! char_matches)                        if (! char_matches)
8071                          {                          {
8072                            /* Add as much of string as fits.  */                            /* Add as much of string as fits.  */
8073                            thiswidth = XSTRING (desc)->size;                            thiswidth = SCHARS (desc);
8074                            if (thiswidth + i > width)                            if (thiswidth + i > width)
8075                              thiswidth = width - i;                              thiswidth = width - i;
8076                            bcopy (XSTRING (desc)->data, menu + i, thiswidth);                            bcopy (SDATA (desc), menu + i, thiswidth);
8077                            i += thiswidth;                            i += thiswidth;
8078                            strcpy (menu + i, " = ");                            strcpy (menu + i, " = ");
8079                            i += 3;                            i += 3;
8080                          }                          }
8081    
8082                        /* Add as much of string as fits.  */                        /* Add as much of string as fits.  */
8083                        thiswidth = XSTRING (s)->size;                        thiswidth = SCHARS (s);
8084                        if (thiswidth + i > width)                        if (thiswidth + i > width)
8085                          thiswidth = width - i;                          thiswidth = width - i;
8086                        bcopy (XSTRING (s)->data, menu + i, thiswidth);                        bcopy (SDATA (s), menu + i, thiswidth);
8087                        i += thiswidth;                        i += thiswidth;
8088                        menu[i] = 0;                        menu[i] = 0;
8089                      }                      }
# Line 7830  read_char_minibuf_menu_prompt (commandfl Line 8108  read_char_minibuf_menu_prompt (commandfl
8108          }          }
8109    
8110        /* Prompt with that and read response.  */        /* Prompt with that and read response.  */
8111        message2_nolog (menu, strlen (menu),        message2_nolog (menu, strlen (menu),
8112                        ! NILP (current_buffer->enable_multibyte_characters));                        ! NILP (current_buffer->enable_multibyte_characters));
8113    
8114        /* Make believe its not a keyboard macro in case the help char        /* Make believe its not a keyboard macro in case the help char
# Line 7914  follow_key (key, nmaps, current, defs, n Line 8192  follow_key (key, nmaps, current, defs, n
8192    return first_binding;    return first_binding;
8193  }  }
8194    
8195    /* Structure used to keep track of partial application of key remapping
8196       such as Vfunction_key_map and Vkey_translation_map.  */
8197    typedef struct keyremap
8198    {
8199      Lisp_Object map;
8200      int start, end;
8201    } keyremap;
8202    
8203    
8204  /* Read a sequence of keys that ends with a non prefix character,  /* Read a sequence of keys that ends with a non prefix character,
8205     storing it in KEYBUF, a buffer of size BUFSIZE.     storing it in KEYBUF, a buffer of size BUFSIZE.
8206     Prompt with PROMPT.     Prompt with PROMPT.
# Line 7962  read_key_sequence (keybuf, bufsize, prom Line 8249  read_key_sequence (keybuf, bufsize, prom
8249       int fix_current_buffer;       int fix_current_buffer;
8250  {  {
8251    volatile Lisp_Object from_string;    volatile Lisp_Object from_string;
8252    volatile int count = specpdl_ptr - specpdl;    volatile int count = SPECPDL_INDEX ();
8253    
8254    /* How many keys there are in the current key sequence.  */    /* How many keys there are in the current key sequence.  */
8255    volatile int t;    volatile int t;
# Line 8001  read_key_sequence (keybuf, bufsize, prom Line 8288  read_key_sequence (keybuf, bufsize, prom
8288       defs[i] is non-nil.  */       defs[i] is non-nil.  */
8289    volatile int first_binding;    volatile int first_binding;
8290    /* Index of the first key that has no binding.    /* Index of the first key that has no binding.
8291       It is useless to try fkey_start larger than that.  */       It is useless to try fkey.start larger than that.  */
8292    volatile int first_unbound;    volatile int first_unbound;
8293    
8294    /* If t < mock_input, then KEYBUF[t] should be read as the next    /* If t < mock_input, then KEYBUF[t] should be read as the next
# Line 8020  read_key_sequence (keybuf, bufsize, prom Line 8307  read_key_sequence (keybuf, bufsize, prom
8307    volatile int mock_input = 0;    volatile int mock_input = 0;
8308    
8309    /* If the sequence is unbound in submaps[], then    /* If the sequence is unbound in submaps[], then
8310       keybuf[fkey_start..fkey_end-1] is a prefix in Vfunction_key_map,       keybuf[fkey.start..fkey.end-1] is a prefix in Vfunction_key_map,
8311       and fkey_map is its binding.       and fkey.map is its binding.
8312    
8313       These might be > t, indicating that all function key scanning       These might be > t, indicating that all function key scanning
8314       should hold off until t reaches them.  We do this when we've just       should hold off until t reaches them.  We do this when we've just
8315       recognized a function key, to avoid searching for the function       recognized a function key, to avoid searching for the function
8316       key's again in Vfunction_key_map.  */       key's again in Vfunction_key_map.  */
8317    volatile int fkey_start = 0, fkey_end = 0;    volatile keyremap fkey;
   volatile Lisp_Object fkey_map;  
8318    
8319    /* Likewise, for key_translation_map.  */    /* Likewise, for key_translation_map.  */
8320    volatile int keytran_start = 0, keytran_end = 0;    volatile keyremap keytran;
   volatile Lisp_Object keytran_map;  
8321    
8322    /* If we receive a ``switch-frame'' event in the middle of a key sequence,    /* If we receive a ``switch-frame'' event in the middle of a key sequence,
8323       we put it off for later.  While we're reading, we keep the event here.  */       we put it off for later.  While we're reading, we keep the event here.  */
# Line 8051  read_key_sequence (keybuf, bufsize, prom Line 8336  read_key_sequence (keybuf, bufsize, prom
8336    
8337    struct buffer *starting_buffer;    struct buffer *starting_buffer;
8338    
   /* Nonzero if we seem to have got the beginning of a binding  
      in function_key_map.  */  
   volatile int function_key_possible = 0;  
   volatile int key_translation_possible = 0;  
   
8339    /* List of events for which a fake prefix key has been generated.  */    /* List of events for which a fake prefix key has been generated.  */
8340    volatile Lisp_Object fake_prefixed_keys = Qnil;    volatile Lisp_Object fake_prefixed_keys = Qnil;
8341    
# Line 8071  read_key_sequence (keybuf, bufsize, prom Line 8351  read_key_sequence (keybuf, bufsize, prom
8351    last_nonmenu_event = Qnil;    last_nonmenu_event = Qnil;
8352    
8353    delayed_switch_frame = Qnil;    delayed_switch_frame = Qnil;
8354    fkey_map = Vfunction_key_map;    fkey.map = Vfunction_key_map;
8355    keytran_map = Vkey_translation_map;    keytran.map = Vkey_translation_map;
8356      /* If there is no translation-map, turn off scanning.  */
8357    /* If there is no function-key-map, turn off function key scanning.  */    fkey.start = fkey.end = KEYMAPP (fkey.map) ? 0 : bufsize + 1;
8358    if (!KEYMAPP (Vfunction_key_map))    keytran.start = keytran.end = KEYMAPP (keytran.map) ? 0 : bufsize + 1;
     fkey_start = fkey_end = bufsize + 1;  
   
   /* If there is no key-translation-map, turn off scanning.  */  
   if (!KEYMAPP (Vkey_translation_map))  
     keytran_start = keytran_end = bufsize + 1;  
8359    
8360    if (INTERACTIVE)    if (INTERACTIVE)
8361      {      {
# Line 8122  read_key_sequence (keybuf, bufsize, prom Line 8397  read_key_sequence (keybuf, bufsize, prom
8397   replay_sequence:   replay_sequence:
8398    
8399    starting_buffer = current_buffer;    starting_buffer = current_buffer;
   function_key_possible = 0;  
   key_translation_possible = 0;  
8400    first_unbound = bufsize + 1;    first_unbound = bufsize + 1;
8401    
8402    /* Build our list of keymaps.    /* Build our list of keymaps.
# Line 8192  read_key_sequence (keybuf, bufsize, prom Line 8465  read_key_sequence (keybuf, bufsize, prom
8465    /* If the best binding for the current key sequence is a keymap, or    /* If the best binding for the current key sequence is a keymap, or
8466       we may be looking at a function key's escape sequence, keep on       we may be looking at a function key's escape sequence, keep on
8467       reading.  */       reading.  */
8468    while ((first_binding < nmaps && ! NILP (submaps[first_binding]))    while (first_binding < nmaps
8469           || (first_binding >= nmaps           /* Keep reading as long as there's a prefix binding.  */
8470               && fkey_start < t)           ? !NILP (submaps[first_binding])
          || (first_binding >= nmaps  
              && keytran_start < t && key_translation_possible)  
8471           /* Don't return in the middle of a possible function key sequence,           /* Don't return in the middle of a possible function key sequence,
8472              if the only bindings we found were via case conversion.              if the only bindings we found were via case conversion.
8473              Thus, if ESC O a has a function-key-map translation              Thus, if ESC O a has a function-key-map translation
8474              and ESC o has a binding, don't return after ESC O,              and ESC o has a binding, don't return after ESC O,
8475              so that we can translate ESC O plus the next character.  */              so that we can translate ESC O plus the next character.  */
8476           )           : (fkey.start < t || keytran.start < t))
8477      {      {
8478        Lisp_Object key;        Lisp_Object key;
8479        int used_mouse_menu = 0;        int used_mouse_menu = 0;
# Line 8221  read_key_sequence (keybuf, bufsize, prom Line 8492  read_key_sequence (keybuf, bufsize, prom
8492        volatile int echo_local_start, keys_local_start, local_first_binding;        volatile int echo_local_start, keys_local_start, local_first_binding;
8493    
8494        /* key-translation-map is applied *after* function-key-map.  */        /* key-translation-map is applied *after* function-key-map.  */
8495        eassert (keytran_end <= fkey_start);        eassert (keytran.end <= fkey.start);
8496    
8497        if (first_unbound < fkey_start && first_unbound < keytran_start)        if (first_unbound < fkey.start && first_unbound < keytran.start)
8498          { /* The prefix upto first_unbound has no binding and has          { /* The prefix upto first_unbound has no binding and has
8499               no translation left to do either, so we know it's unbound.               no translation left to do either, so we know it's unbound.
8500               If we don't stop now, we risk staying here indefinitely               If we don't stop now, we risk staying here indefinitely
# Line 8233  read_key_sequence (keybuf, bufsize, prom Line 8504  read_key_sequence (keybuf, bufsize, prom
8504            for (i = first_unbound + 1; i < t; i++)            for (i = first_unbound + 1; i < t; i++)
8505              keybuf[i - first_unbound - 1] = keybuf[i];              keybuf[i - first_unbound - 1] = keybuf[i];
8506            mock_input = t - first_unbound - 1;            mock_input = t - first_unbound - 1;
8507            fkey_end = fkey_start -= first_unbound + 1;            fkey.end = fkey.start -= first_unbound + 1;
8508            fkey_map = Vfunction_key_map;            fkey.map = Vfunction_key_map;
8509            keytran_end = keytran_start -= first_unbound + 1;            keytran.end = keytran.start -= first_unbound + 1;
8510            keytran_map = Vkey_translation_map;            keytran.map = Vkey_translation_map;
8511            goto replay_sequence;            goto replay_sequence;
8512          }          }
8513    
# Line 8341  read_key_sequence (keybuf, bufsize, prom Line 8612  read_key_sequence (keybuf, bufsize, prom
8612               keymap may have changed, so replay the sequence.  */               keymap may have changed, so replay the sequence.  */
8613            if (BUFFERP (key))            if (BUFFERP (key))
8614              {              {
8615                  EMACS_TIME initial_idleness_start_time;
8616                  EMACS_SET_SECS_USECS (initial_idleness_start_time,
8617                                        EMACS_SECS (timer_last_idleness_start_time),
8618                                        EMACS_USECS (timer_last_idleness_start_time));
8619    
8620                  /* Resume idle state, using the same start-time as before.  */
8621                  timer_start_idle ();
8622                  timer_idleness_start_time = initial_idleness_start_time;
8623    
8624                mock_input = t;                mock_input = t;
8625                /* Reset the current buffer from the selected window                /* Reset the current buffer from the selected window
8626                   in case something changed the former and not the latter.                   in case something changed the former and not the latter.
# Line 8465  read_key_sequence (keybuf, bufsize, prom Line 8745  read_key_sequence (keybuf, bufsize, prom
8745                    orig_keymap = get_local_map (PT, current_buffer, Qkeymap);                    orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
8746                    goto replay_sequence;                    goto replay_sequence;
8747                  }                  }
8748                  
8749                /* For a mouse click, get the local text-property keymap                /* For a mouse click, get the local text-property keymap
8750                   of the place clicked on, rather than point.  */                   of the place clicked on, rather than point.  */
8751                if (last_real_key_start == 0                if (last_real_key_start == 0
# Line 8476  read_key_sequence (keybuf, bufsize, prom Line 8756  read_key_sequence (keybuf, bufsize, prom
8756    
8757                    localized_local_map = 1;                    localized_local_map = 1;
8758                    start = EVENT_START (key);                    start = EVENT_START (key);
8759                      
8760                    if (CONSP (start) && CONSP (XCDR (start)))                    if (CONSP (start) && CONSP (XCDR (start)))
8761                      {                      {
8762                        pos = POSN_BUFFER_POSN (start);                        pos = POSN_BUFFER_POSN (start);
# Line 8515  read_key_sequence (keybuf, bufsize, prom Line 8795  read_key_sequence (keybuf, bufsize, prom
8795                  {                  {
8796                    if (t + 1 >= bufsize)                    if (t + 1 >= bufsize)
8797                      error ("Key sequence too long");                      error ("Key sequence too long");
8798                      
8799                    keybuf[t]     = posn;                    keybuf[t]     = posn;
8800                    keybuf[t + 1] = key;                    keybuf[t + 1] = key;
8801                    mock_input    = t + 2;                    mock_input    = t + 2;
# Line 8523  read_key_sequence (keybuf, bufsize, prom Line 8803  read_key_sequence (keybuf, bufsize, prom
8803                    /* Record that a fake prefix key has been generated                    /* Record that a fake prefix key has been generated
8804                       for KEY.  Don't modify the event; this would                       for KEY.  Don't modify the event; this would
8805                       prevent proper action when the event is pushed                       prevent proper action when the event is pushed
8806                       back tino unread-command-events.  */                       back into unread-command-events.  */
8807                    fake_prefixed_keys = Fcons (key, fake_prefixed_keys);                    fake_prefixed_keys = Fcons (key, fake_prefixed_keys);
8808    
8809                    /* If on a mode line string with a local keymap,                    /* If on a mode line string with a local keymap,
# Line 8536  read_key_sequence (keybuf, bufsize, prom Line 8816  read_key_sequence (keybuf, bufsize, prom
8816                        pos = XCDR (string);                        pos = XCDR (string);
8817                        string = XCAR (string);                        string = XCAR (string);
8818                        if (XINT (pos) >= 0                        if (XINT (pos) >= 0
8819                            && XINT (pos) < XSTRING (string)->size)                            && XINT (pos) < SCHARS (string))
8820                          {                          {
8821                            map = Fget_text_property (pos, Qlocal_map, string);                            map = Fget_text_property (pos, Qlocal_map, string);
8822                            if (!NILP (map))                            if (!NILP (map))
# Line 8564  read_key_sequence (keybuf, bufsize, prom Line 8844  read_key_sequence (keybuf, bufsize, prom
8844                    pos = XCDR (string);                    pos = XCDR (string);
8845                    string = XCAR (string);                    string = XCAR (string);
8846                    if (XINT (pos) >= 0                    if (XINT (pos) >= 0
8847                        && XINT (pos) < XSTRING (string)->size)                        && XINT (pos) < SCHARS (string))
8848                      {                      {
8849                        map = Fget_text_property (pos, Qlocal_map, string);                        map = Fget_text_property (pos, Qlocal_map, string);
8850                        if (!NILP (map))                        if (!NILP (map))
# Line 8626  read_key_sequence (keybuf, bufsize, prom Line 8906  read_key_sequence (keybuf, bufsize, prom
8906                         + first_binding);                         + first_binding);
8907    
8908        /* If KEY wasn't bound, we'll try some fallbacks.  */        /* If KEY wasn't bound, we'll try some fallbacks.  */
8909        if (first_binding >= nmaps)        if (first_binding < nmaps)
8910            /* This is needed for the following scenario:
8911               event 0: a down-event that gets dropped by calling replay_key.
8912               event 1: some normal prefix like C-h.
8913               After event 0, first_unbound is 0, after event 1 fkey.start
8914               and keytran.start are both 1, so when we see that C-h is bound,
8915               we need to update first_unbound.  */
8916            first_unbound = max (t + 1, first_unbound);
8917          else
8918          {          {
8919            Lisp_Object head;            Lisp_Object head;
8920              
8921            /* Remember the position to put an upper bound on fkey_start.  */            /* Remember the position to put an upper bound on fkey.start.  */
8922            first_unbound = min (t, first_unbound);            first_unbound = min (t, first_unbound);
8923    
8924            head = EVENT_HEAD (key);            head = EVENT_HEAD (key);
# Line 8706  read_key_sequence (keybuf, bufsize, prom Line 8994  read_key_sequence (keybuf, bufsize, prom
8994                               generate mouse events, so it's okay to zero                               generate mouse events, so it's okay to zero
8995                               mock_input in that case too.                               mock_input in that case too.
8996    
8997                                 FIXME: The above paragraph seems just plain
8998                                 wrong, if you consider things like
8999                                 xterm-mouse-mode.  -stef
9000    
9001                               Isn't this just the most wonderful code ever?  */                               Isn't this just the most wonderful code ever?  */
9002                            if (t == last_real_key_start)                            if (t == last_real_key_start)
9003                              {                              {
# Line 8758  read_key_sequence (keybuf, bufsize, prom Line 9050  read_key_sequence (keybuf, bufsize, prom
9050        /* Record what part of this_command_keys is the current key sequence.  */        /* Record what part of this_command_keys is the current key sequence.  */
9051        this_single_command_key_start = this_command_key_count - t;        this_single_command_key_start = this_command_key_count - t;
9052    
9053        /* If the sequence is unbound, see if we can hang a function key        if (first_binding < nmaps && NILP (submaps[first_binding]))
9054           off the end of it.  We only want to scan real keyboard input          /* There is a binding and it's not a prefix.
9055           for function key sequences, so if mock_input says that we're             There is thus no function-key in this sequence.
9056           re-reading old events, don't examine it.  */             Moving fkey.start is important in this case to allow keytran.start
9057        if (first_binding >= nmaps             to go over the sequence before we return (since we keep the
9058            && t >= mock_input)             invariant that keytran.end <= fkey.start).  */
9059          {          {
9060            Lisp_Object fkey_next;            if (fkey.start < t)
9061                (fkey.start = fkey.end = t, fkey.map = Vfunction_key_map);
9062            }
9063          else
9064            /* If the sequence is unbound, see if we can hang a function key
9065               off the end of it.  */
9066            {
9067              Lisp_Object next;
9068    
9069            /* Continue scan from fkey_end until we find a bound suffix.            /* Continue scan from fkey.end until we find a bound suffix.
9070               If we fail, increment fkey_start               If we fail, increment fkey.start and start over from there.  */
9071               and start fkey_end from there.  */            while (fkey.end < t)
           while (fkey_end < t)  
9072              {              {
9073                Lisp_Object key;                Lisp_Object key;
9074    
9075                key = keybuf[fkey_end++];                key = keybuf[fkey.end++];
9076                fkey_next                next = access_keymap (fkey.map, key, 1, 0, 1);
                 = access_keymap (fkey_map, key, 1, 0, 1);  
9077    
9078                /* Handle symbol with autoload definition.  */                /* Handle symbol with autoload definition.  */
9079                if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))                if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9080                    && CONSP (XSYMBOL (fkey_next)->function)                    && CONSP (XSYMBOL (next)->function)
9081                    && EQ (XCAR (XSYMBOL (fkey_next)->function), Qautoload))                    && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
9082                  do_autoload (XSYMBOL (fkey_next)->function,                  do_autoload (XSYMBOL (next)->function, next);
                              fkey_next);  
9083    
9084                /* Handle a symbol whose function definition is a keymap                /* Handle a symbol whose function definition is a keymap
9085                   or an array.  */                   or an array.  */
9086                if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))                if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9087                    && (!NILP (Farrayp (XSYMBOL (fkey_next)->function))                    && (!NILP (Farrayp (XSYMBOL (next)->function))
9088                        || KEYMAPP (XSYMBOL (fkey_next)->function)))                        || KEYMAPP (XSYMBOL (next)->function)))
9089                  fkey_next = XSYMBOL (fkey_next)->function;                  next = XSYMBOL (next)->function;
9090    
9091  #if 0 /* I didn't turn this on, because it might cause trouble  #if 0 /* I didn't turn this on, because it might cause trouble
9092           for the mapping of return into C-m and tab into C-i.  */           for the mapping of return into C-m and tab into C-i.  */
9093                /* Optionally don't map function keys into other things.                /* Optionally don't map function keys into other things.
9094                   This enables the user to redefine kp- keys easily.  */                   This enables the user to redefine kp- keys easily.  */
9095                if (SYMBOLP (key) && !NILP (Vinhibit_function_key_mapping))                if (SYMBOLP (key) && !NILP (Vinhibit_function_key_mapping))
9096                  fkey_next = Qnil;                  next = Qnil;
9097  #endif  #endif
9098    
9099                /* If the function key map gives a function, not an                /* If the function key map gives a function, not an
9100                   array, then call the function with no args and use                   array, then call the function with no args and use
9101                   its value instead.  */                   its value instead.  */
9102                if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))                if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9103                    && fkey_end == t)                    /* If there's a binding (i.e. first_binding >= nmaps)
9104                         we don't want to apply this function-key-mapping.  */
9105                      && fkey.end == t && first_binding >= nmaps)
9106                  {                  {
9107                    struct gcpro gcpro1, gcpro2, gcpro3;                    struct gcpro gcpro1, gcpro2, gcpro3;
9108                    Lisp_Object tem;                    Lisp_Object tem;
9109                    tem = fkey_next;                    tem = next;
9110    
9111                    GCPRO3 (fkey_map, keytran_map, delayed_switch_frame);                    GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
9112                    fkey_next = call1 (fkey_next, prompt);                    next = call1 (next, prompt);
9113                    UNGCPRO;                    UNGCPRO;
9114                    /* If the function returned something invalid,                    /* If the function returned something invalid,
9115                       barf--don't ignore it.                       barf--don't ignore it.
9116                       (To ignore it safely, we would need to gcpro a bunch of                       (To ignore it safely, we would need to gcpro a bunch of
9117                       other variables.)  */                       other variables.)  */
9118                    if (! (VECTORP (fkey_next) || STRINGP (fkey_next)))                    if (! (VECTORP (next) || STRINGP (next)))
9119                      error ("Function in key-translation-map returns invalid key sequence");                      error ("Function in key-translation-map returns invalid key sequence");
9120                  }                  }
9121    
9122                function_key_possible = ! NILP (fkey_next);                /* If keybuf[fkey.start..fkey.end] is bound in the
   
               /* If keybuf[fkey_start..fkey_end] is bound in the  
9123                   function key map and it's a suffix of the current                   function key map and it's a suffix of the current
9124                   sequence (i.e. fkey_end == t), replace it with                   sequence (i.e. fkey.end == t), replace it with
9125                   the binding and restart with fkey_start at the end. */                   the binding and restart with fkey.start at the end. */
9126                if ((VECTORP (fkey_next) || STRINGP (fkey_next))                if ((VECTORP (next) || STRINGP (next))
9127                    && fkey_end == t)                    /* If there's a binding (i.e. first_binding >= nmaps)
9128                         we don't want to apply this function-key-mapping.  */
9129                      && fkey.end == t && first_binding >= nmaps)
9130                  {                  {
9131                    int len = XFASTINT (Flength (fkey_next));                    int len = XFASTINT (Flength (next));
9132    
9133                    t = fkey_start + len;                    t = fkey.start + len;
9134                    if (t >= bufsize)                    if (t >= bufsize)
9135                      error ("Key sequence too long");                      error ("Key sequence too long");
9136    
9137                    if (VECTORP (fkey_next))                    if (VECTORP (next))
9138                      bcopy (XVECTOR (fkey_next)->contents,                      bcopy (XVECTOR (next)->contents,
9139                             keybuf + fkey_start,                             keybuf + fkey.start,
9140                             (t - fkey_start) * sizeof (keybuf[0]));                             (t - fkey.start) * sizeof (keybuf[0]));
9141                    else if (STRINGP (fkey_next))                    else if (STRINGP (next))
9142                      {                      {
9143                        int i;                        int i;
9144    
9145                        for (i = 0; i < len; i++)                        for (i = 0; i < len; i++)
9146                          XSETFASTINT (keybuf[fkey_start + i],                          XSETFASTINT (keybuf[fkey.start + i], SREF (next, i));
                                      XSTRING (fkey_next)->data[i]);  
9147                      }                      }
9148    
9149                    mock_input = t;                    mock_input = t;
9150                    fkey_start = fkey_end = t;                    fkey.start = fkey.end = t;
9151                    fkey_map = Vfunction_key_map;                    fkey.map = Vfunction_key_map;
9152    
9153                    /* Do pass the results through key-translation-map.                    /* Do pass the results through key-translation-map.
9154                       But don't retranslate what key-translation-map                       But don't retranslate what key-translation-map
9155                       has already translated.  */                       has already translated.  */
9156                    keytran_end = keytran_start;                    keytran.end = keytran.start;
9157                    keytran_map = Vkey_translation_map;                    keytran.map = Vkey_translation_map;
9158    
9159                    goto replay_sequence;                    goto replay_sequence;
9160                  }                  }
9161    
9162                fkey_map = get_keymap (fkey_next, 0, 1);                fkey.map = get_keymap (next, 0, 1);
9163    
9164                /* If we no longer have a bound suffix, try a new positions for                /* If we no longer have a bound suffix, try a new positions for
9165                   fkey_start.  */                   fkey.start.  */
9166                if (!CONSP (fkey_map))                if (!CONSP (fkey.map))
9167                  {                  {
9168                    fkey_end = ++fkey_start;                    fkey.end = ++fkey.start;
9169                    fkey_map = Vfunction_key_map;                    fkey.map = Vfunction_key_map;
                   function_key_possible = 0;  
9170                  }                  }
9171              }              }
9172          }          }
       else if (NILP (submaps[first_binding]))  
         /* There is a global binding and it's not a prefix.  
            There is thus no function-key in this sequence.  
            We can probably show that there can't be any afterwards either  
            but I can't seem to find a clear reason why not, so I'll  
            be conservative.  
            Moving fkey.start is important in this case to allow keytran.start  
            to go over the sequence before we return (since we keep the  
            invariant that keytran.end <= fkey.start).  */  
         (fkey_start = max (fkey_start, t), fkey_end = max (fkey_end, t));  
9173    
9174        /* Look for this sequence in key-translation-map.  */        /* Look for this sequence in key-translation-map.  */
9175        {        {
9176          Lisp_Object keytran_next;          Lisp_Object next;
9177    
9178          /* Scan from keytran_end until we find a bound suffix.  */          /* Scan from keytran.end until we find a bound suffix.  */
9179          while (keytran_end < fkey_start)          while (keytran.end < fkey.start)
9180            {            {
9181              Lisp_Object key;              Lisp_Object key;
9182    
9183              key = keybuf[keytran_end++];              key = keybuf[keytran.end++];
9184              keytran_next              next = access_keymap (keytran.map, key, 1, 0, 1);
               = access_keymap (keytran_map, key, 1, 0, 1);  
9185    
9186              /* Handle symbol with autoload definition.  */              /* Handle symbol with autoload definition.  */
9187              if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next))              if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9188                  && CONSP (XSYMBOL (keytran_next)->function)                  && CONSP (XSYMBOL (next)->function)
9189                  && EQ (XCAR (XSYMBOL (keytran_next)->function), Qautoload))                  && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
9190                do_autoload (XSYMBOL (keytran_next)->function,                do_autoload (XSYMBOL (next)->function, next);
                            keytran_next);  
9191    
9192              /* Handle a symbol whose function definition is a keymap              /* Handle a symbol whose function definition is a keymap
9193                 or an array.  */                 or an array.  */
9194              if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next))              if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9195                  && (!NILP (Farrayp (XSYMBOL (keytran_next)->function))                  && (!NILP (Farrayp (XSYMBOL (next)->function))
9196                      || KEYMAPP (XSYMBOL (keytran_next)->function)))                      || KEYMAPP (XSYMBOL (next)->function)))
9197                keytran_next = XSYMBOL (keytran_next)->function;                next = XSYMBOL (next)->function;
9198                
9199              /* If the key translation map gives a function, not an              /* If the key translation map gives a function, not an
9200                 array, then call the function with one arg and use                 array, then call the function with one arg and use
9201                 its value instead.  */                 its value instead.  */
9202              if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next)))              if (SYMBOLP (next) && ! NILP (Ffboundp (next)))
9203                {                {
9204                  struct gcpro gcpro1, gcpro2, gcpro3;                  struct gcpro gcpro1, gcpro2, gcpro3;
9205                  Lisp_Object tem;                  Lisp_Object tem;
9206                  tem = keytran_next;                  tem = next;
9207    
9208                  GCPRO3 (fkey_map, keytran_map, delayed_switch_frame);                  GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
9209                  keytran_next = call1 (keytran_next, prompt);                  next = call1 (next, prompt);
9210                  UNGCPRO;                  UNGCPRO;
9211                  /* If the function returned something invalid,                  /* If the function returned something invalid,
9212                     barf--don't ignore it.                     barf--don't ignore it.
9213                     (To ignore it safely, we would need to gcpro a bunch of                     (To ignore it safely, we would need to gcpro a bunch of
9214                     other variables.)  */                     other variables.)  */
9215                  if (! (VECTORP (keytran_next) || STRINGP (keytran_next)))                  if (! (VECTORP (next) || STRINGP (next)))
9216                    error ("Function in key-translation-map returns invalid key sequence");                    error ("Function in key-translation-map returns invalid key sequence");
9217                }                }
9218    
9219              key_translation_possible = ! NILP (keytran_next);              /* If keybuf[keytran.start..keytran.end] is bound in the
   
             /* If keybuf[keytran_start..keytran_end] is bound in the  
9220                 key translation map and it's a suffix of the current                 key translation map and it's a suffix of the current
9221                 sequence (i.e. keytran_end == t), replace it with                 sequence (i.e. keytran.end == t), replace it with
9222                 the binding and restart with keytran_start at the end. */                 the binding and restart with keytran.start at the end. */
9223              if ((VECTORP (keytran_next) || STRINGP (keytran_next)))              if ((VECTORP (next) || STRINGP (next)))
9224                {                {
9225                  int len = XFASTINT (Flength (keytran_next));                  int len = XFASTINT (Flength (next));
9226                  int i, diff = len - (keytran_end - keytran_start);                  int i, diff = len - (keytran.end - keytran.start);
9227    
9228                  mock_input = max (t, mock_input);                  mock_input = max (t, mock_input);
9229                  if (mock_input + diff >= bufsize)                  if (mock_input + diff >= bufsize)
9230                    error ("Key sequence too long");                    error ("Key sequence too long");
9231    
9232                  /* Shift the keys that are after keytran_end.  */                  /* Shift the keys that are after keytran.end.  */
9233                  if (diff < 0)                  if (diff < 0)
9234                    for (i = keytran_end; i < mock_input; i++)                    for (i = keytran.end; i < mock_input; i++)
9235                      keybuf[i + diff] = keybuf[i];                      keybuf[i + diff] = keybuf[i];
9236                  else if (diff > 0)                  else if (diff > 0)
9237                    for (i = mock_input - 1; i >= keytran_end; i--)                    for (i = mock_input - 1; i >= keytran.end; i--)
9238                      keybuf[i + diff] = keybuf[i];                      keybuf[i + diff] = keybuf[i];
9239                  /* Replace the keys between keytran_start and keytran_end                  /* Replace the keys between keytran.start and keytran.end
9240                     with those from keytran_next.  */                     with those from next.  */
9241                  for (i = 0; i < len; i++)                  for (i = 0; i < len; i++)
9242                    keybuf[keytran_start + i]                    keybuf[keytran.start + i]
9243                      = Faref (keytran_next, make_number (i));                      = Faref (next, make_number (i));
9244    
9245                  mock_input += diff;                  mock_input += diff;
9246                  keytran_start = keytran_end += diff;                  keytran.start = keytran.end += diff;
9247                  keytran_map = Vkey_translation_map;                  keytran.map = Vkey_translation_map;
9248    
9249                  /* Adjust the function-key-map counters.  */                  /* Adjust the function-key-map counters.  */
9250                  fkey_start += diff;                  fkey.start += diff;
9251                  fkey_end += diff;                  fkey.end += diff;
9252    
9253                  goto replay_sequence;                  goto replay_sequence;
9254                }                }
9255    
9256              keytran_map = get_keymap (keytran_next, 0, 1);              keytran.map = get_keymap (next, 0, 1);
9257    
9258              /* If we no longer have a bound suffix, try a new positions for              /* If we no longer have a bound suffix, try a new positions for
9259                 keytran_start.  */                 keytran.start.  */
9260              if (!CONSP (keytran_map))              if (!CONSP (keytran.map))
9261                {                {
9262                  keytran_end = ++keytran_start;                  keytran.end = ++keytran.start;
9263                  keytran_map = Vkey_translation_map;                  keytran.map = Vkey_translation_map;
                 key_translation_possible = 0;  
9264                }                }
9265            }            }
9266        }        }
# Line 8988  read_key_sequence (keybuf, bufsize, prom Line 9269  read_key_sequence (keybuf, bufsize, prom
9269           and cannot be part of a function key or translation,           and cannot be part of a function key or translation,
9270           and is an upper case letter           and is an upper case letter
9271           use the corresponding lower-case letter instead.  */           use the corresponding lower-case letter instead.  */
9272        if (first_binding == nmaps && ! function_key_possible        if (first_binding >= nmaps
9273            && ! key_translation_possible            && fkey.start >= t && keytran.start >= t
9274            && INTEGERP (key)            && INTEGERP (key)
9275            && ((((XINT (key) & 0x3ffff)            && ((((XINT (key) & 0x3ffff)
9276                  < XCHAR_TABLE (current_buffer->downcase_table)->size)                  < XCHAR_TABLE (current_buffer->downcase_table)->size)
# Line 9019  read_key_sequence (keybuf, bufsize, prom Line 9300  read_key_sequence (keybuf, bufsize, prom
9300           and cannot be part of a function key or translation,           and cannot be part of a function key or translation,
9301           and is a shifted function key,           and is a shifted function key,
9302           use the corresponding unshifted function key instead.  */           use the corresponding unshifted function key instead.  */
9303        if (first_binding == nmaps && ! function_key_possible        if (first_binding >= nmaps
9304            && ! key_translation_possible            && fkey.start >= t && keytran.start >= t
9305            && SYMBOLP (key))            && SYMBOLP (key))
9306          {          {
9307            Lisp_Object breakdown;            Lisp_Object breakdown;
# Line 9078  read_key_sequence (keybuf, bufsize, prom Line 9359  read_key_sequence (keybuf, bufsize, prom
9359        add_command_key (keybuf[t]);        add_command_key (keybuf[t]);
9360      }      }
9361    
9362      
9363    
9364    UNGCPRO;    UNGCPRO;
9365    return t;    return t;
# Line 9139  will read just one key sequence.  */) Line 9420  will read just one key sequence.  */)
9420    Lisp_Object keybuf[30];    Lisp_Object keybuf[30];
9421    register int i;    register int i;
9422    struct gcpro gcpro1;    struct gcpro gcpro1;
9423    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
9424    
9425    if (!NILP (prompt))    if (!NILP (prompt))
9426      CHECK_STRING (prompt);      CHECK_STRING (prompt);
# Line 9157  will read just one key sequence.  */) Line 9438  will read just one key sequence.  */)
9438    if (NILP (continue_echo))    if (NILP (continue_echo))
9439      {      {
9440        this_command_key_count = 0;        this_command_key_count = 0;
9441          this_command_key_count_reset = 0;
9442        this_single_command_key_start = 0;        this_single_command_key_start = 0;
9443      }      }
9444    
# Line 9198  DEFUN ("read-key-sequence-vector", Fread Line 9480  DEFUN ("read-key-sequence-vector", Fread
9480    Lisp_Object keybuf[30];    Lisp_Object keybuf[30];
9481    register int i;    register int i;
9482    struct gcpro gcpro1;    struct gcpro gcpro1;
9483    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
9484    
9485    if (!NILP (prompt))    if (!NILP (prompt))
9486      CHECK_STRING (prompt);      CHECK_STRING (prompt);
# Line 9216  DEFUN ("read-key-sequence-vector", Fread Line 9498  DEFUN ("read-key-sequence-vector", Fread
9498    if (NILP (continue_echo))    if (NILP (continue_echo))
9499      {      {
9500        this_command_key_count = 0;        this_command_key_count = 0;
9501          this_command_key_count_reset = 0;
9502        this_single_command_key_start = 0;        this_single_command_key_start = 0;
9503      }      }
9504    
# Line 9320  a special event, so ignore the prefix ar Line 9603  a special event, so ignore the prefix ar
9603              }              }
9604          }          }
9605    
9606        return Fexecute_kbd_macro (final, prefixarg);        return Fexecute_kbd_macro (final, prefixarg, Qnil);
9607      }      }
9608    
9609    if (CONSP (final) || SUBRP (final) || COMPILEDP (final))    if (CONSP (final) || SUBRP (final) || COMPILEDP (final))
# Line 9399  DEFUN ("execute-extended-command", Fexec Line 9682  DEFUN ("execute-extended-command", Fexec
9682                                 Qt, Qnil, Qextended_command_history, Qnil,                                 Qt, Qnil, Qextended_command_history, Qnil,
9683                                 Qnil);                                 Qnil);
9684    
9685    if (STRINGP (function) && XSTRING (function)->size == 0)    if (STRINGP (function) && SCHARS (function) == 0)
9686      error ("No command name given");      error ("No command name given");
9687    
9688    /* Set this_command_keys to the concatenation of saved_keys and    /* Set this_command_keys to the concatenation of saved_keys and
9689       function, followed by a RET.  */       function, followed by a RET.  */
9690    {    {
     struct Lisp_String *str;  
9691      Lisp_Object *keys;      Lisp_Object *keys;
9692      int i;      int i;
9693    
9694      this_command_key_count = 0;      this_command_key_count = 0;
9695        this_command_key_count_reset = 0;
9696      this_single_command_key_start = 0;      this_single_command_key_start = 0;
9697    
9698      keys = XVECTOR (saved_keys)->contents;      keys = XVECTOR (saved_keys)->contents;
9699      for (i = 0; i < XVECTOR (saved_keys)->size; i++)      for (i = 0; i < XVECTOR (saved_keys)->size; i++)
9700        add_command_key (keys[i]);        add_command_key (keys[i]);
9701    
9702      str = XSTRING (function);      for (i = 0; i < SCHARS (function); i++)
     for (i = 0; i < str->size; i++)  
9703        add_command_key (Faref (function, make_number (i)));        add_command_key (Faref (function, make_number (i)));
9704    
9705      add_command_key (make_number ('\015'));      add_command_key (make_number ('\015'));
# Line 9469  DEFUN ("execute-extended-command", Fexec Line 9751  DEFUN ("execute-extended-command", Fexec
9751            Lisp_Object binding;            Lisp_Object binding;
9752            char *newmessage;            char *newmessage;
9753            int message_p = push_message ();            int message_p = push_message ();
9754            int count = BINDING_STACK_SIZE ();            int count = SPECPDL_INDEX ();
9755    
9756            record_unwind_protect (push_message_unwind, Qnil);            record_unwind_protect (pop_message_unwind, Qnil);
9757            binding = Fkey_description (bindings);            binding = Fkey_description (bindings);
9758    
9759            newmessage            newmessage
9760              = (char *) alloca (XSTRING (SYMBOL_NAME (function))->size              = (char *) alloca (SCHARS (SYMBOL_NAME (function))
9761                                 + STRING_BYTES (XSTRING (binding))                                 + SBYTES (binding)
9762                                 + 100);                                 + 100);
9763            sprintf (newmessage, "You can run the command `%s' with %s",            sprintf (newmessage, "You can run the command `%s' with %s",
9764                     XSTRING (SYMBOL_NAME (function))->data,                     SDATA (SYMBOL_NAME (function)),
9765                     XSTRING (binding)->data);                     SDATA (binding));
9766            message2_nolog (newmessage,            message2_nolog (newmessage,
9767                            strlen (newmessage),                            strlen (newmessage),
9768                            STRING_MULTIBYTE (binding));                            STRING_MULTIBYTE (binding));
# Line 9567  if there is a doubt, the value is t.  */ Line 9849  if there is a doubt, the value is t.  */
9849    if (!NILP (Vunread_command_events) || unread_command_char != -1)    if (!NILP (Vunread_command_events) || unread_command_char != -1)
9850      return (Qt);      return (Qt);
9851    
9852    get_input_pending (&input_pending, 1);    get_filtered_input_pending (&input_pending, 1, 1);
9853    return input_pending > 0 ? Qt : Qnil;    return input_pending > 0 ? Qt : Qnil;
9854  }  }
9855    
# Line 9646  The value is always a vector.  */) Line 9928  The value is always a vector.  */)
9928    
9929  DEFUN ("reset-this-command-lengths", Freset_this_command_lengths,  DEFUN ("reset-this-command-lengths", Freset_this_command_lengths,
9930         Sreset_this_command_lengths, 0, 0, 0,         Sreset_this_command_lengths, 0, 0, 0,
9931         doc: /* Used for complicated reasons in `universal-argument-other-key'.         doc: /* Make the unread events replace the last command and echo.
9932    Used in `universal-argument-other-key'.
9933    
9934  `universal-argument-other-key' rereads the event just typed.  `universal-argument-other-key' rereads the event just typed.
9935  It then gets translated through `function-key-map'.  It then gets translated through `function-key-map'.
9936  The translated event gets included in the echo area and in  The translated event has to replace the real events,
9937  the value of `this-command-keys' in addition to the raw original event.  both in the value of (this-command-keys) and in echoing.
9938  That is not right.  To achieve this, `universal-argument-other-key' calls
9939    `reset-this-command-lengths', which discards the record of reading
9940  Calling this function directs the translated event to replace  these events the first time.  */)
 the original event, so that only one version of the event actually  
 appears in the echo area and in the value of `this-command-keys'.  */)  
9941       ()       ()
9942  {  {
9943    before_command_restore_flag = 1;    this_command_key_count = before_command_key_count;
9944    before_command_key_count_1 = before_command_key_count;    if (this_command_key_count < this_single_command_key_start)
9945    before_command_echo_length_1 = before_command_echo_length;      this_single_command_key_start = this_command_key_count;
9946    
9947      echo_truncate (before_command_echo_length);
9948    
9949      /* Cause whatever we put into unread-command-events
9950         to echo as if it were being freshly read from the keyboard.  */
9951      this_command_key_count_reset = 1;
9952    
9953    return Qnil;    return Qnil;
9954  }  }
9955    
9956  DEFUN ("clear-this-command-keys", Fclear_this_command_keys,  DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
9957         Sclear_this_command_keys, 0, 0, 0,         Sclear_this_command_keys, 0, 1, 0,
9958         doc: /* Clear out the vector that `this-command-keys' returns.         doc: /* Clear out the vector that `this-command-keys' returns.
9959  Also clear the record of the last 100 events.  */)  Also clear the record of the last 100 events, unless optional arg
9960       ()  KEEP-RECORD is non-nil.  */)
9961         (keep_record)
9962         Lisp_Object keep_record;
9963  {  {
9964    int i;    int i;
9965      
9966    this_command_key_count = 0;    this_command_key_count = 0;
9967      this_command_key_count_reset = 0;
9968    
9969    for (i = 0; i < XVECTOR (recent_keys)->size; ++i)    if (NILP (keep_record))
9970      XVECTOR (recent_keys)->contents[i] = Qnil;      {
9971    total_keys = 0;        for (i = 0; i < XVECTOR (recent_keys)->size; ++i)
9972    recent_keys_index = 0;          XVECTOR (recent_keys)->contents[i] = Qnil;
9973          total_keys = 0;
9974          recent_keys_index = 0;
9975        }
9976    return Qnil;    return Qnil;
9977  }  }
9978    
# Line 9706  If FILE is nil, close any open dribble f Line 10000  If FILE is nil, close any open dribble f
10000    if (!NILP (file))    if (!NILP (file))
10001      {      {
10002        file = Fexpand_file_name (file, Qnil);        file = Fexpand_file_name (file, Qnil);
10003        dribble = fopen (XSTRING (file)->data, "w");        dribble = fopen (SDATA (file), "w");
10004        if (dribble == 0)        if (dribble == 0)
10005          report_file_error ("Opening dribble", Fcons (file, Qnil));          report_file_error ("Opening dribble", Fcons (file, Qnil));
10006      }      }
# Line 9715  If FILE is nil, close any open dribble f Line 10009  If FILE is nil, close any open dribble f
10009    
10010  DEFUN ("discard-input", Fdiscard_input, Sdiscard_input, 0, 0, 0,  DEFUN ("discard-input", Fdiscard_input, Sdiscard_input, 0, 0, 0,
10011         doc: /* Discard the contents of the terminal input buffer.         doc: /* Discard the contents of the terminal input buffer.
10012  Also cancel any kbd macro being defined.  */)  Also end any kbd macro being defined.  */)
10013       ()       ()
10014  {  {
10015    current_kboard->defining_kbd_macro = Qnil;    if (!NILP (current_kboard->defining_kbd_macro))
10016        {
10017          /* Discard the last command from the macro.  */
10018          Fcancel_kbd_macro_events ();
10019          end_kbd_macro ();
10020        }
10021    
10022    update_mode_lines++;    update_mode_lines++;
10023    
10024    Vunread_command_events = Qnil;    Vunread_command_events = Qnil;
# Line 9749  On such systems, Emacs starts a subshell Line 10049  On such systems, Emacs starts a subshell
10049       (stuffstring)       (stuffstring)
10050       Lisp_Object stuffstring;       Lisp_Object stuffstring;
10051  {  {
10052    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
10053    int old_height, old_width;    int old_height, old_width;
10054    int width, height;    int width, height;
10055    struct gcpro gcpro1;    struct gcpro gcpro1;
# Line 9806  stuff_buffered_input (stuffstring) Line 10106  stuff_buffered_input (stuffstring)
10106      {      {
10107        register int count;        register int count;
10108    
10109        p = XSTRING (stuffstring)->data;        p = SDATA (stuffstring);
10110        count = STRING_BYTES (XSTRING (stuffstring));        count = SBYTES (stuffstring);
10111        while (count-- > 0)        while (count-- > 0)
10112          stuff_char (*p++);          stuff_char (*p++);
10113        stuff_char ('\n');        stuff_char ('\n');
10114      }      }
10115      
10116    /* Anything we have read ahead, put back for the shell to read.  */    /* Anything we have read ahead, put back for the shell to read.  */
10117    /* ?? What should this do when we have multiple keyboards??    /* ?? What should this do when we have multiple keyboards??
10118       Should we ignore anything that was typed in at the "wrong" kboard?  */       Should we ignore anything that was typed in at the "wrong" kboard?  */
10119    for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++)    for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++)
10120      {      {
10121        int idx;        int idx;
10122          
10123        if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)        if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
10124          kbd_fetch_ptr = kbd_buffer;          kbd_fetch_ptr = kbd_buffer;
10125        if (kbd_fetch_ptr->kind == ascii_keystroke)        if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT)
10126          stuff_char (kbd_fetch_ptr->code);          stuff_char (kbd_fetch_ptr->code);
10127          
10128        kbd_fetch_ptr->kind = no_event;        kbd_fetch_ptr->kind = NO_EVENT;
10129        idx = 2 * (kbd_fetch_ptr - kbd_buffer);        idx = 2 * (kbd_fetch_ptr - kbd_buffer);
10130        ASET (kbd_buffer_gcpro, idx, Qnil);        ASET (kbd_buffer_gcpro, idx, Qnil);
10131        ASET (kbd_buffer_gcpro, idx + 1, Qnil);        ASET (kbd_buffer_gcpro, idx + 1, Qnil);
10132      }      }
10133      
10134    input_pending = 0;    input_pending = 0;
10135  #endif  #endif
10136  #endif /* BSD_SYSTEM and not BSD4_1 */  #endif /* BSD_SYSTEM and not BSD4_1 */
# Line 9860  clear_waiting_for_input () Line 10160  clear_waiting_for_input ()
10160  }  }
10161    
10162  /* This routine is called at interrupt level in response to C-g.  /* This routine is called at interrupt level in response to C-g.
10163      
10164     If interrupt_input, this is the handler for SIGINT.  Otherwise, it     If interrupt_input, this is the handler for SIGINT.  Otherwise, it
10165     is called from kbd_buffer_store_event, in handling SIGIO or     is called from kbd_buffer_store_event, in handling SIGIO or
10166     SIGTINT.     SIGTINT.
# Line 9872  clear_waiting_for_input () Line 10172  clear_waiting_for_input ()
10172     eval to throw, when it gets a chance.  If quit-flag is already     eval to throw, when it gets a chance.  If quit-flag is already
10173     non-nil, it stops the job right away.  */     non-nil, it stops the job right away.  */
10174    
10175  SIGTYPE  static SIGTYPE
10176  interrupt_signal (signalnum)    /* If we don't have an argument, */  interrupt_signal (signalnum)    /* If we don't have an argument, */
10177       int signalnum;             /* some compilers complain in signal calls. */       int signalnum;             /* some compilers complain in signal calls. */
10178  {  {
# Line 9950  interrupt_signal (signalnum)   /* If we do Line 10250  interrupt_signal (signalnum)   /* If we do
10250              }              }
10251            while (c != '\n') c = getchar ();            while (c != '\n') c = getchar ();
10252          }          }
10253        else        else
10254          {          {
10255            /* During GC, it must be safe to reenable quitting again.  */            /* During GC, it must be safe to reenable quitting again.  */
10256            Vinhibit_quit = Qnil;            Vinhibit_quit = Qnil;
# Line 10192  delete_kboard (kb) Line 10492  delete_kboard (kb)
10492       KBOARD *kb;       KBOARD *kb;
10493  {  {
10494    KBOARD **kbp;    KBOARD **kbp;
10495      
10496    for (kbp = &all_kboards; *kbp != kb; kbp = &(*kbp)->next_kboard)    for (kbp = &all_kboards; *kbp != kb; kbp = &(*kbp)->next_kboard)
10497      if (*kbp == NULL)      if (*kbp == NULL)
10498        abort ();        abort ();
# Line 10207  delete_kboard (kb) Line 10507  delete_kboard (kb)
10507        if (current_kboard == kb)        if (current_kboard == kb)
10508          abort ();          abort ();
10509      }      }
10510      
10511    wipe_kboard (kb);    wipe_kboard (kb);
10512    xfree (kb);    xfree (kb);
10513  }  }
# Line 10284  init_keyboard () Line 10584  init_keyboard ()
10584    poll_suppress_count = 1;    poll_suppress_count = 1;
10585    start_polling ();    start_polling ();
10586  #endif  #endif
10587    
10588    #ifdef MAC_OSX
10589      /* At least provide an escape route since C-g doesn't work.  */
10590      signal (SIGINT, interrupt_signal);
10591    #endif
10592  }  }
10593    
10594  /* This type's only use is in syms_of_keyboard, to initialize the  /* This type's only use is in syms_of_keyboard, to initialize the
# Line 10309  syms_of_keyboard () Line 10614  syms_of_keyboard ()
10614  {  {
10615    Vpre_help_message = Qnil;    Vpre_help_message = Qnil;
10616    staticpro (&Vpre_help_message);    staticpro (&Vpre_help_message);
10617      
10618    Vlispy_mouse_stem = build_string ("mouse");    Vlispy_mouse_stem = build_string ("mouse");
10619    staticpro (&Vlispy_mouse_stem);    staticpro (&Vlispy_mouse_stem);
10620    
# Line 10371  syms_of_keyboard () Line 10676  syms_of_keyboard ()
10676    staticpro (&Qfunction_key);    staticpro (&Qfunction_key);
10677    Qmouse_click = intern ("mouse-click");    Qmouse_click = intern ("mouse-click");
10678    staticpro (&Qmouse_click);    staticpro (&Qmouse_click);
10679  #ifdef WINDOWSNT  #if defined(WINDOWSNT) || defined(MAC_OSX)
10680    Qmouse_wheel = intern ("mouse-wheel");    Qmouse_wheel = intern ("mouse-wheel");
10681    staticpro (&Qmouse_wheel);    staticpro (&Qmouse_wheel);
10682    #endif
10683    #ifdef WINDOWSNT
10684    Qlanguage_change = intern ("language-change");    Qlanguage_change = intern ("language-change");
10685    staticpro (&Qlanguage_change);    staticpro (&Qlanguage_change);
10686  #endif  #endif
# Line 10382  syms_of_keyboard () Line 10689  syms_of_keyboard ()
10689    
10690    Qsave_session = intern ("save-session");    Qsave_session = intern ("save-session");
10691    staticpro(&Qsave_session);    staticpro(&Qsave_session);
10692      
10693    Qusr1_signal = intern ("usr1-signal");    Qusr1_signal = intern ("usr1-signal");
10694    staticpro (&Qusr1_signal);    staticpro (&Qusr1_signal);
10695    Qusr2_signal = intern ("usr2-signal");    Qusr2_signal = intern ("usr2-signal");
# Line 10521  syms_of_keyboard () Line 10828  syms_of_keyboard ()
10828    func_key_syms = Qnil;    func_key_syms = Qnil;
10829    staticpro (&func_key_syms);    staticpro (&func_key_syms);
10830    
10831  #ifdef WINDOWSNT  #if defined(WINDOWSNT) || defined(MAC_OSX)
10832    mouse_wheel_syms = Qnil;    mouse_wheel_syms = Qnil;
10833    staticpro (&mouse_wheel_syms);    staticpro (&mouse_wheel_syms);
     
10834    drag_n_drop_syms = Qnil;    drag_n_drop_syms = Qnil;
10835    staticpro (&drag_n_drop_syms);    staticpro (&drag_n_drop_syms);
10836  #endif  #endif
# Line 10635  will be in `last-command' during the fol Line 10941  will be in `last-command' during the fol
10941    Vthis_command = Qnil;    Vthis_command = Qnil;
10942    
10943    DEFVAR_LISP ("this-original-command", &Vthis_original_command,    DEFVAR_LISP ("this-original-command", &Vthis_original_command,
10944                 doc: /* If non-nil, the original command bound to the current key sequence.                 doc: /* The command bound to the current key sequence before remapping.
10945  The value of `this-command' is the result of looking up the original  It equals `this-command' if the original command was not remapped through
10946  command in the active keymaps.  */);  any of the active keymaps.  Otherwise, the value of `this-command' is the
10947    result of looking up the original command in the active keymaps.  */);
10948    Vthis_original_command = Qnil;    Vthis_original_command = Qnil;
10949    
10950    DEFVAR_INT ("auto-save-interval", &auto_save_interval,    DEFVAR_INT ("auto-save-interval", &auto_save_interval,
# Line 10681  instead of pixels. Line 10988  instead of pixels.
10988  This variable is also the threshold for motion of the mouse  This variable is also the threshold for motion of the mouse
10989  to count as a drag.  */);  to count as a drag.  */);
10990    double_click_fuzz = 3;    double_click_fuzz = 3;
10991      
10992    DEFVAR_BOOL ("inhibit-local-menu-bar-menus", &inhibit_local_menu_bar_menus,    DEFVAR_BOOL ("inhibit-local-menu-bar-menus", &inhibit_local_menu_bar_menus,
10993                 doc: /* *Non-nil means inhibit local map menu bar menus.  */);                 doc: /* *Non-nil means inhibit local map menu bar menus.  */);
10994    inhibit_local_menu_bar_menus = 0;    inhibit_local_menu_bar_menus = 0;
# Line 10740  Each character is looked up in this stri Line 11047  Each character is looked up in this stri
11047  The value may be a string, a vector, or a char-table.  The value may be a string, a vector, or a char-table.
11048  If it is a string or vector of length N,  If it is a string or vector of length N,
11049  character codes N and up are untranslated.  character codes N and up are untranslated.
11050  In a vector or a char-table, an element which is nil means "no translation".  */);  In a vector or a char-table, an element which is nil means "no translation".
11051    
11052    This is applied to the characters supplied to input methods, not their
11053    output.  See also `translation-table-for-input'.  */);
11054    Vkeyboard_translate_table = Qnil;    Vkeyboard_translate_table = Qnil;
11055    
11056    DEFVAR_BOOL ("cannot-suspend", &cannot_suspend,    DEFVAR_BOOL ("cannot-suspend", &cannot_suspend,
# Line 10803  might happen repeatedly and make Emacs n Line 11113  might happen repeatedly and make Emacs n
11113    
11114    DEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook,    DEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook,
11115                 doc: /* Normal hook run after each command is executed, if idle.                 doc: /* Normal hook run after each command is executed, if idle.
11116  Errors running the hook are caught and ignored.  Errors running the hook are caught and ignored.  */);
 This feature is obsolete; use idle timers instead.  See `etc/NEWS'.  */);  
11117    Vpost_command_idle_hook = Qnil;    Vpost_command_idle_hook = Qnil;
11118    
11119    DEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay,    DEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay,

Legend:
Removed from v.1.681  
changed lines
  Added in v.1.681.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26