]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
(DECL_ALIGN, USE_LSB_TAG): Move logic to before definition of
[gnu-emacs] / src / keyboard.c
index 686d16a504f7546a7819c617a2b936e584432ecc..0e9dfee877fa1f22b1eae007e0ef5f800955af31 100644 (file)
@@ -7,7 +7,7 @@ This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -108,8 +108,6 @@ int interrupt_input_pending;
 #define KBD_BUFFER_SIZE 4096
 #endif /* No X-windows */
 
-#define abs(x)         ((x) >= 0 ? (x) : -(x))
-
 /* Following definition copied from eval.c */
 
 struct backtrace
@@ -487,7 +485,7 @@ static struct input_event * volatile kbd_store_ptr;
 /* The above pair of variables forms a "queue empty" flag.  When we
    enqueue a non-hook event, we increment kbd_store_ptr.  When we
    dequeue a non-hook event, we increment kbd_fetch_ptr.  We say that
-   there is input available iff the two pointers are not equal.
+   there is input available if the two pointers are not equal.
 
    Why not just have a flag set and cleared by the enqueuing and
    dequeuing functions?  Such a flag could be screwed up by interrupts
@@ -508,7 +506,7 @@ Lisp_Object Qmake_frame_visible;
 Lisp_Object Qselect_window;
 Lisp_Object Qhelp_echo;
 
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 Lisp_Object Qmouse_fixup_help_message;
 #endif
 
@@ -661,7 +659,7 @@ static Lisp_Object read_char_x_menu_prompt ();
 static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int,
                                                      Lisp_Object *));
 static Lisp_Object make_lispy_event P_ ((struct input_event *));
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 static Lisp_Object make_lispy_movement P_ ((struct frame *, Lisp_Object,
                                            enum scroll_bar_part,
                                            Lisp_Object, Lisp_Object,
@@ -678,7 +676,9 @@ static void save_getcjmp ();
 static void restore_getcjmp P_ ((jmp_buf));
 static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));
 static void clear_event P_ ((struct input_event *));
+#ifdef MULTI_KBOARD
 static Lisp_Object restore_kboard_configuration P_ ((Lisp_Object));
+#endif
 static SIGTYPE interrupt_signal P_ ((int signalnum));
 static void handle_interrupt P_ ((void));
 static void timer_start_idle P_ ((void));
@@ -1222,6 +1222,7 @@ record_single_kboard_state ()
 }
 #endif
 
+#ifdef MULTI_KBOARD
 static Lisp_Object
 restore_kboard_configuration (was_locked)
      Lisp_Object was_locked;
@@ -1239,6 +1240,8 @@ restore_kboard_configuration (was_locked)
     }
   return Qnil;
 }
+#endif
+
 \f
 /* Handle errors that are not handled at inner levels
    by printing an error message and returning to the editor command loop.  */
@@ -1322,7 +1325,7 @@ cmd_error_internal (data, context)
   /* Use user's specified output function if any.  */
   if (!NILP (Vcommand_error_function))
     call3 (Vcommand_error_function, data,
-          build_string (context ? context : ""),
+          context ? build_string (context) : empty_unibyte_string,
           Vsignaling_function);
   /* If the window system or terminal frame hasn't been initialized
      yet, or we're not interactive, write the message to stderr and exit.  */
@@ -1461,7 +1464,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
   return Qnil;
 }
 \f
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 
 /* Restore mouse tracking enablement.  See Ftrack_mouse for the only use
    of this function.  */
@@ -1493,7 +1496,7 @@ DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0,
 Within a `track-mouse' form, mouse motion generates input events that
 you can read with `read-event'.
 Normally, mouse motion is ignored.
-usage: (track-mouse BODY ...)  */)
+usage: (track-mouse BODY...)  */)
      (args)
      Lisp_Object args;
 {
@@ -1537,7 +1540,7 @@ some_mouse_moved ()
   return 0;
 }
 
-#endif /* HAVE_MOUSE */
+#endif /* HAVE_MOUSE || HAVE_GPM */
 \f
 /* This is the actual command reading loop,
    sans error-handling encapsulation.  */
@@ -1660,11 +1663,6 @@ command_loop_1 ()
            }
        }
 
-#ifdef C_ALLOCA
-      alloca (0);              /* Cause a garbage collection now */
-                               /* Since we can free the most stuff here.  */
-#endif /* C_ALLOCA */
-
 #if 0
       /* Select the frame that the last event came from.  Usually,
         switch-frame events will take care of this, but if some lisp
@@ -1764,7 +1762,7 @@ command_loop_1 ()
       if (SYMBOLP (cmd))
        {
          Lisp_Object cmd1;
-         if (cmd1 = Fcommand_remapping (cmd, Qnil), !NILP (cmd1))
+         if (cmd1 = Fcommand_remapping (cmd, Qnil, Qnil), !NILP (cmd1))
            cmd = cmd1;
        }
 
@@ -2471,7 +2469,7 @@ show_help_echo (help, window, object, pos, ok_to_overwrite_keystroke_echo)
        return;
     }
 
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   if (!noninteractive && STRINGP (help))
     {
       /* The mouse-fixup-help-message Lisp function can call
@@ -3698,7 +3696,7 @@ restore_getcjmp (temp)
    kbd_buffer_store_event places events in kbd_buffer, and
    kbd_buffer_get_event retrieves them.  */
 
-/* Return true iff there are any events in the queue that read-char
+/* Return true if there are any events in the queue that read-char
    would return.  If this returns false, a read-char would block.  */
 static int
 readable_events (flags)
@@ -3748,7 +3746,7 @@ readable_events (flags)
        return 1;
     }
 
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
       && !NILP (do_mouse_tracking) && some_mouse_moved ())
     return 1;
@@ -4021,8 +4019,12 @@ discard_mouse_events ()
 
       if (sp->kind == MOUSE_CLICK_EVENT
          || sp->kind == WHEEL_EVENT
+          || sp->kind == HORIZ_WHEEL_EVENT
 #ifdef WINDOWSNT
          || sp->kind == W32_SCROLL_BAR_CLICK_EVENT
+#endif
+#ifdef HAVE_GPM
+         || sp->kind == GPM_CLICK_EVENT
 #endif
          || sp->kind == SCROLL_BAR_CLICK_EVENT)
        {
@@ -4098,7 +4100,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
     {
       if (kbd_fetch_ptr != kbd_store_ptr)
        break;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
       if (!NILP (do_mouse_tracking) && some_mouse_moved ())
        break;
 #endif
@@ -4120,7 +4122,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
 #endif /* SIGIO */
       if (kbd_fetch_ptr != kbd_store_ptr)
        break;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
       if (!NILP (do_mouse_tracking) && some_mouse_moved ())
        break;
 #endif
@@ -4356,7 +4358,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
            }
        }
     }
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   /* Try generating a mouse motion event.  */
   else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
     {
@@ -4401,7 +4403,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
       if (!NILP (x) && NILP (obj))
        obj = make_lispy_movement (f, bar_window, part, x, y, time);
     }
-#endif /* HAVE_MOUSE */
+#endif /* HAVE_MOUSE || HAVE GPM */
   else
     /* We were promised by the above while loop that there was
        something for us to read!  */
@@ -5196,7 +5198,7 @@ Lisp_Object Vlispy_mouse_stem;
 
 static char *lispy_wheel_names[] =
 {
-  "wheel-up", "wheel-down"
+  "wheel-up", "wheel-down", "wheel-left", "wheel-right"
 };
 
 /* drag-n-drop events are generated when a set of selected files are
@@ -5833,6 +5835,7 @@ make_lispy_event (event)
       }
 
     case WHEEL_EVENT:
+    case HORIZ_WHEEL_EVENT:
       {
        Lisp_Object position;
        Lisp_Object head;
@@ -5917,6 +5920,9 @@ make_lispy_event (event)
               the up_modifier set.  */
            abort ();
 
+          if (event->kind == HORIZ_WHEEL_EVENT)
+            symbol_num += 2;
+
          /* Get the symbol we should use for the wheel event.  */
          head = modify_event_symbol (symbol_num,
                                      event->modifiers,
@@ -6118,13 +6124,73 @@ make_lispy_event (event)
       }
 #endif
 
+#ifdef HAVE_GPM
+    case GPM_CLICK_EVENT:
+      {
+       FRAME_PTR f = XFRAME (event->frame_or_window);
+       Lisp_Object head, position;
+       Lisp_Object *start_pos_ptr;
+       Lisp_Object start_pos;
+       int button = event->code;
+
+       if (button >= ASIZE (button_down_location))
+         {
+           button_down_location = larger_vector (button_down_location,
+                                                 button + 1, Qnil);
+           mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
+         }
+
+       start_pos_ptr = &AREF (button_down_location, button);
+       start_pos = *start_pos_ptr;
+
+       position = make_lispy_position (f, &event->x, &event->y,
+                                           event->timestamp);
+
+       if (event->modifiers & down_modifier)
+         *start_pos_ptr = Fcopy_alist (position);
+       else if (event->modifiers & (up_modifier | drag_modifier))
+         {
+           if (!CONSP (start_pos))
+             return Qnil;
+           event->modifiers &= ~up_modifier;
+         }
+
+       head = modify_event_symbol (button,
+                                   event->modifiers,
+                                   Qmouse_click, Vlispy_mouse_stem,
+                                   NULL,
+                                   &mouse_syms,
+                                   XVECTOR (mouse_syms)->size);
+
+       if (event->modifiers & drag_modifier)
+         return Fcons (head,
+                       Fcons (start_pos,
+                              Fcons (position,
+                                     Qnil)));
+       else if (event->modifiers & double_modifier)
+         return Fcons (head,
+                       Fcons (position,
+                              Fcons (make_number (2),
+                                     Qnil)));
+       else if (event->modifiers & triple_modifier)
+         return Fcons (head,
+                       Fcons (position,
+                              Fcons (make_number (3),
+                                     Qnil)));
+       else
+         return Fcons (head,
+                       Fcons (position,
+                              Qnil));
+       }
+#endif /* HAVE_GPM */
+
       /* The 'kind' field of the event is something we don't recognize.  */
     default:
       abort ();
     }
 }
 
-#ifdef HAVE_MOUSE
+#if defined(HAVE_MOUSE) || defined(HAVE_GPM)
 
 static Lisp_Object
 make_lispy_movement (frame, bar_window, part, x, y, time)
@@ -6163,7 +6229,7 @@ make_lispy_movement (frame, bar_window, part, x, y, time)
     }
 }
 
-#endif /* HAVE_MOUSE */
+#endif /* HAVE_MOUSE || HAVE GPM */
 
 /* Construct a switch frame event.  */
 static Lisp_Object
@@ -7025,7 +7091,7 @@ tty_read_avail_input (struct terminal *terminal,
   struct tty_display_info *tty = terminal->display_info.tty;
   int nread = 0;
 
-  if (terminal->deleted)        /* Don't read from a deleted terminal. */
+  if (!terminal->name)         /* Don't read from a dead terminal. */
     return;
 
   if (terminal->type != output_termcap)
@@ -7052,7 +7118,27 @@ tty_read_avail_input (struct terminal *terminal,
   if (! tty->input)
     return 0;                   /* The terminal is suspended. */
 
-  /* Determine how many characters we should *try* to read.  */
+#ifdef HAVE_GPM
+  if (gpm_tty == tty)
+  {
+      Gpm_Event event;
+      struct input_event hold_quit;
+      int gpm;
+
+      EVENT_INIT (hold_quit);
+      hold_quit.kind = NO_EVENT;
+
+      while (gpm = Gpm_GetEvent (&event), gpm == 1) {
+         nread += handle_one_term_event (tty, &event, &hold_quit);
+      }
+      if (hold_quit.kind != NO_EVENT)
+         kbd_buffer_store_event (&hold_quit);
+      if (nread)
+         return nread;
+  }
+#endif /* HAVE_GPM */
+
+/* Determine how many characters we should *try* to read.  */
 #ifdef FIONREAD
   /* Find out how much input is available.  */
   if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
@@ -8008,10 +8094,11 @@ static Lisp_Object tool_bar_item_properties;
 
 static int ntool_bar_items;
 
-/* The symbols `tool-bar', and `:image'.  */
+/* The symbols `tool-bar', `:image' and `:rtl'.  */
 
 extern Lisp_Object Qtool_bar;
 Lisp_Object QCimage;
+Lisp_Object Qrtl;
 
 /* Function prototypes.  */
 
@@ -8297,6 +8384,9 @@ parse_tool_bar_item (key, item)
        /* Value is either a single image specification or a vector
           of 4 such specifications for the different button states.  */
        PROP (TOOL_BAR_ITEM_IMAGES) = value;
+      else if (EQ (key, Qrtl))
+        /* ':rtl STRING' */
+       PROP (TOOL_BAR_ITEM_RTL_IMAGE) = value;
     }
 
   /* If got a filter apply it on binding.  */
@@ -9008,9 +9098,9 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
      of the place where a mouse click occurred.  */
   volatile int localized_local_map = 0;
 
-  /* The index in defs[] of the first keymap that has a binding for
+  /* The index in submaps[] of the first keymap that has a binding for
      this key sequence.  In other words, the lowest i such that
-     defs[i] is non-nil.  */
+     submaps[i] is non-nil.  */
   volatile int first_binding;
   /* Index of the first key that has no binding.
      It is useless to try fkey.start larger than that.  */
@@ -11227,7 +11317,8 @@ See also `current-input-mode'.  */)
   Fset_input_interrupt_mode (interrupt);
   Fset_output_flow_control (flow, Qnil);
   Fset_input_meta_mode (meta, Qnil);
-  Fset_quit_char (quit);
+  if (!NILP (quit))
+    Fset_quit_char (quit);
   return Qnil;
 }
 
@@ -11435,7 +11526,7 @@ init_keyboard ()
   recent_keys_index = 0;
   kbd_fetch_ptr = kbd_buffer;
   kbd_store_ptr = kbd_buffer;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   do_mouse_tracking = Qnil;
 #endif
   input_pending = 0;
@@ -11536,6 +11627,9 @@ syms_of_keyboard ()
   staticpro (&Qhelp_echo);
   Qhelp_echo = intern ("help-echo");
 
+  staticpro (&Qrtl);
+  Qrtl = intern (":rtl");
+
   staticpro (&item_properties);
   item_properties = Qnil;
 
@@ -11631,7 +11725,7 @@ syms_of_keyboard ()
   Qmenu_bar = intern ("menu-bar");
   staticpro (&Qmenu_bar);
 
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   Qmouse_fixup_help_message = intern ("mouse-fixup-help-message");
   staticpro (&Qmouse_fixup_help_message);
 #endif
@@ -11704,7 +11798,7 @@ syms_of_keyboard ()
   staticpro (&button_down_location);
   mouse_syms = Fmake_vector (make_number (1), Qnil);
   staticpro (&mouse_syms);
-  wheel_syms = Fmake_vector (make_number (2), Qnil);
+  wheel_syms = Fmake_vector (make_number (4), Qnil);
   staticpro (&wheel_syms);
 
   {
@@ -11763,7 +11857,7 @@ syms_of_keyboard ()
   defsubr (&Sread_key_sequence);
   defsubr (&Sread_key_sequence_vector);
   defsubr (&Srecursive_edit);
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   defsubr (&Strack_mouse);
 #endif
   defsubr (&Sinput_pending_p);