(displaying-byte-compile-warnings): Show
[bpt/emacs.git] / src / keyboard.c
index 0303ab4..bf5643d 100644 (file)
@@ -444,6 +444,9 @@ Lisp_Object Qmake_frame_visible;
 /* Symbols to denote kinds of events.  */
 Lisp_Object Qfunction_key;
 Lisp_Object Qmouse_click;
+#ifdef WINDOWSNT
+Lisp_Object Qmouse_wheel;
+#endif
 /* Lisp_Object Qmouse_movement; - also an event header */
 
 /* Properties of event headers.  */
@@ -482,6 +485,8 @@ extern char *x_get_keysym_name ();
 
 static void record_menu_key ();
 
+void swallow_events ();
+
 Lisp_Object Qpolling_period;
 
 /* List of absolute timers.  Appears in order of next scheduled event.  */
@@ -495,6 +500,8 @@ int timers_run;
 
 extern Lisp_Object Vprint_level, Vprint_length;
 
+extern nonascii_insert_offset;
+
 /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
    happens.  */
 EMACS_TIME *input_available_clear_time;
@@ -1146,7 +1153,7 @@ command_loop_1 ()
 
          Fsit_for (make_number (2), Qnil, Qnil);
          /* Clear the echo area.  */
-         message2 (0);
+         message2 (0, 0);
          safe_run_hooks (Qecho_area_clear_hook);
 
          unbind_to (count, Qnil);
@@ -1364,6 +1371,13 @@ command_loop_1 ()
                        = window_display_table (XWINDOW (selected_window));
                      int lose = c;
 
+                     /* Add the offset to the character, for Finsert_char.
+                        We pass internal_self_insert the unmodified character
+                        because it itself does this offsetting.  */
+                     if (lose >= 0200 && lose <= 0377
+                         && ! NILP (current_buffer->enable_multibyte_characters))
+                       lose += nonascii_insert_offset;
+
                      if (dp)
                        {
                          Lisp_Object obj;
@@ -1696,17 +1710,22 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
      Lisp_Object prev_event;
      int *used_mouse_menu;
 {
-  register Lisp_Object c;
+  Lisp_Object c;
   int count;
   jmp_buf local_getcjmp;
   jmp_buf save_jump;
   int key_already_recorded = 0;
   Lisp_Object tem, save;
   Lisp_Object also_record;
+  struct gcpro gcpro1;
+
   also_record = Qnil;
 
   before_command_key_count = this_command_key_count;
   before_command_echo_length = echo_length ();
+  c = Qnil;
+
+  GCPRO1 (c);
 
  retry:
 
@@ -1764,7 +1783,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
          || executing_macro_index >= XFASTINT (Flength (Vexecuting_macro)))
        {
          XSETINT (c, -1);
-         return c;
+         RETURN_UNGCPRO (c);
        }
 
       c = Faref (Vexecuting_macro, make_number (executing_macro_index));
@@ -1787,9 +1806,15 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
       goto reread_first;
     }
 
-  if (commandflag >= 0 && !input_pending
-      && !detect_input_pending_run_timers (0))
-    redisplay ();
+  if (commandflag >= 0)
+    {
+      if (input_pending
+         || detect_input_pending_run_timers (0))
+       swallow_events (0);
+
+      if (!input_pending)
+       redisplay ();
+    }
 
   /* Message turns off echoing unless more keystrokes turn it on again. */
   if (echo_area_glyphs && *echo_area_glyphs
@@ -1853,6 +1878,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
            *tailp = Fcons (c, Qnil);
            kb->kbd_queue_has_data = 1;
            current_kboard = kb;
+           /* This is going to exit from read_char
+              so we had better get rid of this frame's stuff.  */
+           UNGCPRO;
            longjmp (wrong_kboard_jmpbuf, 1);
          }
       }
@@ -1921,7 +1949,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
       /* Now that we have read an event, Emacs is not idle.  */
       timer_stop_idle ();
 
-      return c;
+      RETURN_UNGCPRO (c);
     }
 
   /* Maybe autosave and/or garbage collect due to idleness.  */
@@ -2018,6 +2046,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        if (kb->kbd_queue_has_data)
          {
            current_kboard = kb;
+           /* This is going to exit from read_char
+              so we had better get rid of this frame's stuff.  */
+           UNGCPRO;
            longjmp (wrong_kboard_jmpbuf, 1);
          }
     }
@@ -2055,6 +2086,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
          if (single_kboard)
            goto wrong_kboard;
          current_kboard = kb;
+         /* This is going to exit from read_char
+            so we had better get rid of this frame's stuff.  */
+         UNGCPRO;
          longjmp (wrong_kboard_jmpbuf, 1);
        }
 #endif
@@ -2080,10 +2114,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
  non_reread:
 
-  /* Now that we have read an event, Emacs is not idle--
-     unless the event was a timer event (not used now).  */
-  if (! CONSP (c))
-    timer_stop_idle ();
+  timer_stop_idle ();
 
   start_polling ();
 
@@ -2099,12 +2130,10 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
  non_reread_1:
 
   /* Buffer switch events are only for internal wakeups
-     so don't show them to the user.  */
-  if (BUFFERP (c))
-    return c;
-
-  if (key_already_recorded)
-    return c;
+     so don't show them to the user.
+     Also, don't record a key if we already did.  */
+  if (BUFFERP (c) || key_already_recorded)
+    RETURN_UNGCPRO (c);
 
   /* Process special events within read_char
      and loop around to read another event.  */
@@ -2138,7 +2167,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
     {
       /* If kbd_buffer_get_event gave us an EOF, return that.  */
       if (XINT (c) == -1)
-       return c;
+       RETURN_UNGCPRO (c);
 
       if (STRINGP (Vkeyboard_translate_table)
          && XSTRING (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
@@ -2186,6 +2215,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
  from_macro:
  reread_first:
+
   before_command_key_count = this_command_key_count;
   before_command_echo_length = echo_length ();
 
@@ -2242,7 +2272,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        }
     }
 
-  return c;
+  RETURN_UNGCPRO (c);
 }
 
 /* Record a key that came from a mouse menu.
@@ -2611,6 +2641,28 @@ kbd_buffer_store_event (event)
     }
 }
 \f
+/* Discard any mouse events in the event buffer by setting them to
+   no_event.  */
+void
+discard_mouse_events ()
+{
+  struct input_event *sp;
+  for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
+    {
+      if (sp == kbd_buffer + KBD_BUFFER_SIZE)
+       sp = kbd_buffer;
+
+      if (sp->kind == mouse_click
+#ifdef WINDOWSNT
+         || sp->kind == w32_scroll_bar_click
+#endif
+         || sp->kind == scroll_bar_click)
+       {
+         sp->kind = no_event;
+       }
+    }
+}
+\f
 /* Read one event from the event buffer, waiting if necessary.
    The value is a Lisp object representing the event.
    The value is nil for an event that should be ignored,
@@ -2777,7 +2829,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
          XSETBUFFER (obj, current_buffer);
          kbd_fetch_ptr = event + 1;
        }
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
       else if (event->kind == menu_bar_activate_event)
        {
          kbd_fetch_ptr = event + 1;
@@ -2792,6 +2844,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
         (They shouldn't otherwise be found in the buffer,
         but on some machines it appears they do show up
         even without MULTI_KBOARD.)  */
+      /* On Windows NT/9X, no_event is used to delete extraneous
+         mouse events during a popup-menu call.  */
       else if (event->kind == no_event)
        kbd_fetch_ptr = event + 1;
 
@@ -3202,6 +3256,9 @@ timer_check (do_it_now)
 static Lisp_Object accent_key_syms;
 static Lisp_Object func_key_syms;
 static Lisp_Object mouse_syms;
+#ifdef WINDOWSNT
+static Lisp_Object mouse_wheel_syms;
+#endif
 
 /* This is a list of keysym codes for special "accent" characters.
    It parallels lispy_accent_keys.  */
@@ -3621,6 +3678,20 @@ static char *lispy_mouse_names[] =
   "mouse-1", "mouse-2", "mouse-3", "mouse-4", "mouse-5"
 };
 
+#ifdef WINDOWSNT
+/* mouse-wheel events are generated by the wheel on devices such as
+   the MS Intellimouse.  The wheel sits in between the left and right
+   mouse buttons, and is typically used to scroll or zoom the window
+   underneath the pointer.  mouse-wheel events specify the object on
+   which they operate, and a delta corresponding to the amount and
+   direction that the wheel is rotated.  Clicking the mouse-wheel
+   generates a mouse-2 event.  */
+static char *lispy_mouse_wheel_names[] = 
+{
+  "mouse-wheel"
+};
+#endif /* WINDOWSNT */
+
 /* Scroll bar parts.  */
 Lisp_Object Qabove_handle, Qhandle, Qbelow_handle;
 Lisp_Object Qup, Qdown;
@@ -3694,6 +3765,10 @@ make_lispy_event (event)
        c |= (event->modifiers
              & (meta_modifier | alt_modifier
                 | hyper_modifier | super_modifier));
+       /* Distinguish Shift-SPC from SPC.  */
+       if ((event->code & 0377) == 040
+           && event->modifiers & shift_modifier)
+         c |= shift_modifier;
        button_down_time = 0;
        XSETFASTINT (lispy_c, c);
        return lispy_c;
@@ -3738,6 +3813,7 @@ make_lispy_event (event)
                                     / sizeof (lispy_kana_keys[0])));
 #endif /* XK_kana_A */
 
+#ifdef ISO_FUNCTION_KEY_OFFSET
       if (event->code < FUNCTION_KEY_OFFSET
          && event->code >= ISO_FUNCTION_KEY_OFFSET)
        return modify_event_symbol (event->code - ISO_FUNCTION_KEY_OFFSET,
@@ -3747,6 +3823,7 @@ make_lispy_event (event)
                                    (sizeof (iso_lispy_function_keys)
                                     / sizeof (iso_lispy_function_keys[0])));
       else
+#endif
        return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
                                    event->modifiers,
                                    Qfunction_key, Qnil,
@@ -4045,8 +4122,68 @@ make_lispy_event (event)
                               Qnil));
        }
       }
-#endif
+    case mouse_wheel:
+      {
+       int part;
+       FRAME_PTR f = XFRAME (event->frame_or_window);
+       Lisp_Object window;
+       Lisp_Object posn;
+       Lisp_Object head, position;
+       int row, column;
+
+       /* Ignore mouse events that were made on frame that
+          have been deleted.  */
+       if (! FRAME_LIVE_P (f))
+         return Qnil;
+       pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
+                              &column, &row, NULL, 1);
+       window = window_from_coordinates (f, column, row, &part);
+
+       if (!WINDOWP (window))
+         {
+           window = event->frame_or_window;
+           posn = Qnil;
+         }
+       else
+         {
+           int pixcolumn, pixrow;
+           column -= XINT (XWINDOW (window)->left);
+           row -= XINT (XWINDOW (window)->top);
+           glyph_to_pixel_coords (f, column, row, &pixcolumn, &pixrow);
+           XSETINT (event->x, pixcolumn);
+           XSETINT (event->y, pixrow);
+
+           if (part == 1)
+             posn = Qmode_line;
+           else if (part == 2)
+             posn = Qvertical_line;
+           else
+             XSETINT (posn,
+                      buffer_posn_from_coords (XWINDOW (window),
+                                               column, row));
+         }
 
+       {
+         Lisp_Object head, position;
+
+         position
+           = Fcons (window,
+                    Fcons (posn,
+                           Fcons (Fcons (event->x, event->y),
+                                  Fcons (make_number (event->timestamp),
+                                         Qnil))));
+
+         head = modify_event_symbol (0, event->modifiers,
+                                     Qmouse_wheel, Qnil,
+                                     lispy_mouse_wheel_names,
+                                     &mouse_wheel_syms, 1);
+         return Fcons (head,
+                       Fcons (position,
+                              Fcons (make_number (event->code),
+                                     Qnil)));
+       }
+      }
+#endif /* WINDOWSNT */
 #endif /* HAVE_MOUSE */
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
@@ -5172,7 +5309,7 @@ menu_bar_items (old)
   for (mapno = nmaps - 1; mapno >= 0; mapno--)
     {
       if (! NILP (maps[mapno]))
-       def = get_keyelt (access_keymap (maps[mapno], Qmenu_bar, 1, 0));
+       def = get_keyelt (access_keymap (maps[mapno], Qmenu_bar, 1, 0), 0);
       else
        def = Qnil;
 
@@ -5759,7 +5896,7 @@ follow_key (key, nmaps, current, defs, next)
          {
            Lisp_Object def;
            def = get_keyelt (access_keymap (current[i],
-                                            meta_prefix_char, 1, 0));
+                                            meta_prefix_char, 1, 0), 0);
 
            /* Note that since we pass the resulting bindings through
               get_keymap_1, non-prefix bindings for meta-prefix-char
@@ -5784,7 +5921,7 @@ follow_key (key, nmaps, current, defs, next)
          else
            map = current[i];
 
-         defs[i] = get_keyelt (access_keymap (map, key, 1, 0));
+         defs[i] = get_keyelt (access_keymap (map, key, 1, 0), 0);
          if (! NILP (defs[i]))
            first_binding = i;
        }
@@ -6536,7 +6673,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                  fkey_next
                    = get_keymap_1
                      (get_keyelt
-                      (access_keymap (fkey_map, meta_prefix_char, 1, 0)),
+                      (access_keymap (fkey_map, meta_prefix_char, 1, 0), 0),
                       0, 1);
                  XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
                }
@@ -6544,7 +6681,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                fkey_next = fkey_map;
 
              fkey_next
-               = get_keyelt (access_keymap (fkey_next, key, 1, 0));
+               = get_keyelt (access_keymap (fkey_next, key, 1, 0), 0);
 
 #if 0 /* I didn't turn this on, because it might cause trouble
         for the mapping of return into C-m and tab into C-i.  */
@@ -6644,7 +6781,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                keytran_next
                  = get_keymap_1
                    (get_keyelt
-                    (access_keymap (keytran_map, meta_prefix_char, 1, 0)),
+                    (access_keymap (keytran_map, meta_prefix_char, 1, 0), 0),
                     0, 1);
                XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
              }
@@ -6652,7 +6789,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
              keytran_next = keytran_map;
 
            keytran_next
-             = get_keyelt (access_keymap (keytran_next, key, 1, 0));
+             = get_keyelt (access_keymap (keytran_next, key, 1, 0), 0);
 
            /* If the key translation map gives a function, not an
               array, then call the function with no args and use
@@ -7062,7 +7199,8 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
      history list. */
   function = Fcompleting_read (build_string (buf),
                               Vobarray, Qcommandp,
-                              Qt, Qnil, Qextended_command_history, Qnil);
+                              Qt, Qnil, Qextended_command_history, Qnil,
+                              Qnil);
 
   if (STRINGP (function) && XSTRING (function)->size == 0)
     error ("No command name given");
@@ -7679,7 +7817,7 @@ See also `current-input-mode'.")
   stop_polling ();
 #endif
 
-#ifndef MSDOS
+#ifndef DOS_NT
   /* this causes startup screen to be restored and messes with the mouse */
   reset_sys_modes ();
 #endif
@@ -7718,7 +7856,7 @@ See also `current-input-mode'.")
     /* Don't let this value be out of range.  */
     quit_char = XINT (quit) & (meta_key ? 0377 : 0177);
 
-#ifndef MSDOS
+#ifndef DOS_NT
   init_sys_modes ();
 #endif
 
@@ -7945,6 +8083,10 @@ syms_of_keyboard ()
   staticpro (&Qfunction_key);
   Qmouse_click = intern ("mouse-click");
   staticpro (&Qmouse_click);
+#ifdef WINDOWSNT
+  Qmouse_wheel = intern ("mouse-wheel");
+  staticpro (&Qmouse_wheel);
+#endif
 
   Qmenu_enable = intern ("menu-enable");
   staticpro (&Qmenu_enable);
@@ -8037,6 +8179,11 @@ syms_of_keyboard ()
   mouse_syms = Qnil;
   staticpro (&mouse_syms);
 
+#ifdef WINDOWSNT
+  mouse_wheel_syms = Qnil;
+  staticpro (&mouse_wheel_syms);
+#endif
+
   unread_switch_frame = Qnil;
   staticpro (&unread_switch_frame);