]> code.delx.au - gnu-emacs/blobdiff - src/menu.c
Merge from trunk after a lot of time.
[gnu-emacs] / src / menu.c
index 7a7db9f07ffc64f511c4af7874edb5a4382aea0c..2b199ffdf092a2bd8292ad7b054ddbf781008c3a 100644 (file)
@@ -1,7 +1,7 @@
 /* Platform-independent code for terminal communications.
 
-Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2012
-  Free Software Foundation, Inc.
+Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2013 Free Software
+Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -20,7 +20,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
-#include <setjmp.h>
 #include <limits.h> /* for INT_MAX */
 
 #include "lisp.h"
@@ -36,24 +35,17 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "../lwlib/lwlib.h"
 #endif
 
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#endif
-
-#ifdef HAVE_NS
-#include "nsterm.h"
-#endif
-
-#ifdef USE_GTK
-#include "gtkutil.h"
-#endif
+#ifdef HAVE_WINDOW_SYSTEM
+#include TERM_HEADER
+#endif /* HAVE_WINDOW_SYSTEM */
 
 #ifdef HAVE_NTGUI
-#include "w32term.h"
-
+# ifdef NTGUI_UNICODE
+# define unicode_append_menu AppendMenuW
+# else /* !NTGUI_UNICODE */
 extern AppendMenuW_Proc unicode_append_menu;
+# endif /* NTGUI_UNICODE */
 extern HMENU current_popup_menu;
-
 #endif /* HAVE_NTGUI  */
 
 #include "menu.h"
@@ -110,10 +102,10 @@ finish_menu_items (void)
 {
 }
 
-Lisp_Object
-unuse_menu_items (Lisp_Object dummy)
+void
+unuse_menu_items (void)
 {
-  return menu_items_inuse = Qnil;
+  menu_items_inuse = Qnil;
 }
 
 /* Call when finished using the data for the current menu
@@ -129,22 +121,13 @@ discard_menu_items (void)
       menu_items = Qnil;
       menu_items_allocated = 0;
     }
-  xassert (NILP (menu_items_inuse));
+  eassert (NILP (menu_items_inuse));
 }
 
-#ifdef HAVE_NS
-static Lisp_Object
-cleanup_popup_menu (Lisp_Object arg)
-{
-  discard_menu_items ();
-  return Qnil;
-}
-#endif
-
 /* This undoes save_menu_items, and it is called by the specpdl unwind
    mechanism.  */
 
-static Lisp_Object
+static void
 restore_menu_items (Lisp_Object saved)
 {
   menu_items = XCAR (saved);
@@ -156,7 +139,6 @@ restore_menu_items (Lisp_Object saved)
   menu_items_n_panes = XINT (XCAR (saved));
   saved = XCDR (saved);
   menu_items_submenu_depth = XINT (XCAR (saved));
-  return Qnil;
 }
 
 /* Push the whole state of menu_items processing onto the specpdl.
@@ -181,7 +163,7 @@ static void
 ensure_menu_items (int items)
 {
   int incr = items - (menu_items_allocated - menu_items_used);
-  if (0 < incr)
+  if (incr > 0)
     {
       menu_items = larger_vector (menu_items, incr, INT_MAX);
       menu_items_allocated = ASIZE (menu_items);
@@ -197,7 +179,8 @@ static void
 push_submenu_start (void)
 {
   ensure_menu_items (1);
-  XVECTOR (menu_items)->contents[menu_items_used++] = Qnil;
+  ASET (menu_items, menu_items_used, Qnil);
+  menu_items_used++;
   menu_items_submenu_depth++;
 }
 
@@ -207,7 +190,8 @@ static void
 push_submenu_end (void)
 {
   ensure_menu_items (1);
-  XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda;
+  ASET (menu_items, menu_items_used, Qlambda);
+  menu_items_used++;
   menu_items_submenu_depth--;
 }
 
@@ -219,7 +203,8 @@ static void
 push_left_right_boundary (void)
 {
   ensure_menu_items (1);
-  XVECTOR (menu_items)->contents[menu_items_used++] = Qquote;
+  ASET (menu_items, menu_items_used, Qquote);
+  menu_items_used++;
 }
 
 /* Start a new menu pane in menu_items.
@@ -231,9 +216,12 @@ push_menu_pane (Lisp_Object name, Lisp_Object prefix_vec)
   ensure_menu_items (MENU_ITEMS_PANE_LENGTH);
   if (menu_items_submenu_depth == 0)
     menu_items_n_panes++;
-  XVECTOR (menu_items)->contents[menu_items_used++] = Qt;
-  XVECTOR (menu_items)->contents[menu_items_used++] = name;
-  XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec;
+  ASET (menu_items, menu_items_used, Qt);
+  menu_items_used++;
+  ASET (menu_items, menu_items_used, name);
+  menu_items_used++;
+  ASET (menu_items, menu_items_used, prefix_vec);
+  menu_items_used++;
 }
 
 /* Push one menu item into the current pane.  NAME is the string to
@@ -333,7 +321,7 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
 {
   Lisp_Object map, item_string, enabled;
   struct gcpro gcpro1, gcpro2;
-  int res;
+  bool res;
   struct skp *skp = skp_v;
 
   /* Parse the menu item and leave the result in item_properties.  */
@@ -343,10 +331,10 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
   if (!res)
     return;                    /* Not a menu item.  */
 
-  map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
+  map = AREF (item_properties, ITEM_PROPERTY_MAP);
 
-  enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE];
-  item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
+  enabled = AREF (item_properties, ITEM_PROPERTY_ENABLE);
+  item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
 
   if (!NILP (map) && SREF (item_string, 0) == '@')
     {
@@ -363,11 +351,11 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
      front of them.  */
   {
     Lisp_Object prefix = Qnil;
-    Lisp_Object type = XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE];
+    Lisp_Object type = AREF (item_properties, ITEM_PROPERTY_TYPE);
     if (!NILP (type))
       {
        Lisp_Object selected
-         = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
+         = AREF (item_properties, ITEM_PROPERTY_SELECTED);
 
        if (skp->notbuttons)
          /* The first button. Line up previous items in this menu.  */
@@ -378,7 +366,7 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
            while (idx < menu_items_used)
              {
                tem
-                 = XVECTOR (menu_items)->contents[idx + MENU_ITEMS_ITEM_NAME];
+                 = AREF (menu_items, idx + MENU_ITEMS_ITEM_NAME);
                if (NILP (tem))
                  {
                    idx++;
@@ -397,8 +385,8 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
                  {
                    if (!submenu && SREF (tem, 0) != '\0'
                        && SREF (tem, 0) != '-')
-                     XVECTOR (menu_items)->contents[idx + MENU_ITEMS_ITEM_NAME]
-                       = concat2 (build_string ("    "), tem);
+                     ASET (menu_items, idx + MENU_ITEMS_ITEM_NAME,
+                           concat2 (build_string ("    "), tem));
                    idx += MENU_ITEMS_ITEM_LENGTH;
                  }
              }
@@ -430,11 +418,11 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
 #endif /* HAVE_X_WINDOWS || MSDOS */
 
   push_menu_item (item_string, enabled, key,
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
+                 AREF (item_properties, ITEM_PROPERTY_DEF),
+                 AREF (item_properties, ITEM_PROPERTY_KEYEQ),
+                 AREF (item_properties, ITEM_PROPERTY_TYPE),
+                 AREF (item_properties, ITEM_PROPERTY_SELECTED),
+                 AREF (item_properties, ITEM_PROPERTY_HELP));
 
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
   /* Display a submenu using the toolkit.  */
@@ -521,14 +509,15 @@ list_of_panes (Lisp_Object menu)
 /* Set up data in menu_items for a menu bar item
    whose event type is ITEM_KEY (with string ITEM_NAME)
    and whose contents come from the list of keymaps MAPS.  */
-int
-parse_single_submenu (Lisp_Object item_key, Lisp_Object item_name, Lisp_Object maps)
+bool
+parse_single_submenu (Lisp_Object item_key, Lisp_Object item_name,
+                     Lisp_Object maps)
 {
   Lisp_Object length;
   EMACS_INT len;
   Lisp_Object *mapvec;
   ptrdiff_t i;
-  int top_level_items = 0;
+  bool top_level_items = 0;
   USE_SAFE_ALLOCA;
 
   length = Flength (maps);
@@ -579,9 +568,9 @@ xmalloc_widget_value (void)
 {
   widget_value *value;
 
-  BLOCK_INPUT;
+  block_input ();
   value = malloc_widget_value ();
-  UNBLOCK_INPUT;
+  unblock_input ();
 
   return value;
 }
@@ -608,9 +597,9 @@ free_menubar_widget_value_tree (widget_value *wv)
       free_menubar_widget_value_tree (wv->next);
       wv->next = (widget_value *) 0xDEADBEEF;
     }
-  BLOCK_INPUT;
+  block_input ();
   free_widget_value (wv);
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 /* Create a tree of widget_value objects
@@ -618,16 +607,15 @@ free_menubar_widget_value_tree (widget_value *wv)
    in menu_items starting at index START, up to index END.  */
 
 widget_value *
-digest_single_submenu (int start, int end, int top_level_items)
+digest_single_submenu (int start, int end, bool top_level_items)
 {
   widget_value *wv, *prev_wv, *save_wv, *first_wv;
   int i;
   int submenu_depth = 0;
   widget_value **submenu_stack;
-  int panes_seen = 0;
+  bool panes_seen = 0;
 
-  submenu_stack
-    = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
+  submenu_stack = alloca (menu_items_used * sizeof *submenu_stack);
   wv = xmalloc_widget_value ();
   wv->name = "menu";
   wv->value = 0;
@@ -645,35 +633,35 @@ digest_single_submenu (int start, int end, int top_level_items)
   i = start;
   while (i < end)
     {
-      if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
+      if (EQ (AREF (menu_items, i), Qnil))
        {
          submenu_stack[submenu_depth++] = save_wv;
          save_wv = prev_wv;
          prev_wv = 0;
          i++;
        }
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
+      else if (EQ (AREF (menu_items, i), Qlambda))
        {
          prev_wv = save_wv;
          save_wv = submenu_stack[--submenu_depth];
          i++;
        }
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qt)
+      else if (EQ (AREF (menu_items, i), Qt)
               && submenu_depth != 0)
        i += MENU_ITEMS_PANE_LENGTH;
       /* Ignore a nil in the item list.
         It's meaningful only for dialog boxes.  */
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+      else if (EQ (AREF (menu_items, i), Qquote))
        i += 1;
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+      else if (EQ (AREF (menu_items, i), Qt))
        {
          /* Create a new pane.  */
          Lisp_Object pane_name;
          const char *pane_string;
 
-         panes_seen++;
+         panes_seen = 1;
 
-         pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
+         pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
 
 #ifdef HAVE_NTGUI
          if (STRINGP (pane_name))
@@ -738,8 +726,8 @@ digest_single_submenu (int start, int end, int top_level_items)
          Lisp_Object help;
 
          /* All items should be contained in panes.  */
-         if (panes_seen == 0)
-           abort ();
+         if (! panes_seen)
+           emacs_abort ();
 
          item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
          enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
@@ -813,7 +801,7 @@ digest_single_submenu (int start, int end, int top_level_items)
          else if (EQ (type, QCtoggle))
            wv->button_type = BUTTON_TYPE_TOGGLE;
          else
-           abort ();
+           emacs_abort ();
 
          wv->selected = !NILP (selected);
          if (! STRINGP (help))
@@ -879,7 +867,8 @@ update_submenu_strings (widget_value *first_wv)
    VECTOR is an array of menu events for the whole menu.  */
 
 void
-find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object vector, void *client_data)
+find_and_call_menu_selection (struct frame *f, int menu_bar_items_used,
+                             Lisp_Object vector, void *client_data)
 {
   Lisp_Object prefix, entry;
   Lisp_Object *subprefix_stack;
@@ -887,31 +876,31 @@ find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object
   int i;
 
   entry = Qnil;
-  subprefix_stack = (Lisp_Object *) alloca (menu_bar_items_used * sizeof (Lisp_Object));
+  subprefix_stack = alloca (menu_bar_items_used * sizeof *subprefix_stack);
   prefix = Qnil;
   i = 0;
 
   while (i < menu_bar_items_used)
     {
-      if (EQ (XVECTOR (vector)->contents[i], Qnil))
+      if (EQ (AREF (vector, i), Qnil))
        {
          subprefix_stack[submenu_depth++] = prefix;
          prefix = entry;
          i++;
        }
-      else if (EQ (XVECTOR (vector)->contents[i], Qlambda))
+      else if (EQ (AREF (vector, i), Qlambda))
        {
          prefix = subprefix_stack[--submenu_depth];
          i++;
        }
-      else if (EQ (XVECTOR (vector)->contents[i], Qt))
+      else if (EQ (AREF (vector, i), Qt))
        {
-         prefix = XVECTOR (vector)->contents[i + MENU_ITEMS_PANE_PREFIX];
+         prefix = AREF (vector, i + MENU_ITEMS_PANE_PREFIX);
          i += MENU_ITEMS_PANE_LENGTH;
        }
       else
        {
-         entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE];
+         entry = AREF (vector, i + MENU_ITEMS_ITEM_VALUE);
          /* Treat the pointer as an integer.  There's no problem
             as long as pointers have enough bits to hold small integers.  */
          if ((intptr_t) client_data == i)
@@ -960,9 +949,9 @@ find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object
 
 #ifdef HAVE_NS
 /* As above, but return the menu selection instead of storing in kb buffer.
-   If keymaps==1, return full prefixes to selection. */
+   If KEYMAPS, return full prefixes to selection. */
 Lisp_Object
-find_and_return_menu_selection (FRAME_PTR f, int keymaps, void *client_data)
+find_and_return_menu_selection (struct frame *f, bool keymaps, void *client_data)
 {
   Lisp_Object prefix, entry;
   int i;
@@ -971,43 +960,42 @@ find_and_return_menu_selection (FRAME_PTR f, int keymaps, void *client_data)
 
   prefix = entry = Qnil;
   i = 0;
-  subprefix_stack =
-    (Lisp_Object *)alloca (menu_items_used * sizeof (Lisp_Object));
+  subprefix_stack = alloca (menu_items_used * word_size);
 
   while (i < menu_items_used)
     {
-      if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
+      if (EQ (AREF (menu_items, i), Qnil))
         {
           subprefix_stack[submenu_depth++] = prefix;
           prefix = entry;
           i++;
         }
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
+      else if (EQ (AREF (menu_items, i), Qlambda))
         {
           prefix = subprefix_stack[--submenu_depth];
           i++;
         }
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+      else if (EQ (AREF (menu_items, i), Qt))
         {
           prefix
-            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+            = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
           i += MENU_ITEMS_PANE_LENGTH;
         }
       /* Ignore a nil in the item list.
          It's meaningful only for dialog boxes.  */
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+      else if (EQ (AREF (menu_items, i), Qquote))
         i += 1;
       else
         {
           entry
-            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
-          if (&XVECTOR (menu_items)->contents[i] == client_data)
+            = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+          if (aref_addr (menu_items, i) == client_data)
             {
-              if (keymaps != 0)
+              if (keymaps)
                 {
                   int j;
 
-                  entry = Fcons (entry, Qnil);
+                  entry = list1 (entry);
                   if (!NILP (prefix))
                     entry = Fcons (prefix, entry);
                   for (j = submenu_depth - 1; j >= 0; j--)
@@ -1073,10 +1061,10 @@ no quit occurs and `x-popup-menu' returns nil.  */)
   Lisp_Object title;
   const char *error_name = NULL;
   Lisp_Object selection = Qnil;
-  FRAME_PTR f = NULL;
+  struct frame *f = NULL;
   Lisp_Object x, y, window;
-  int keymaps = 0;
-  int for_click = 0;
+  bool keymaps = 0;
+  bool for_click = 0;
   ptrdiff_t specpdl_count = SPECPDL_INDEX ();
   struct gcpro gcpro1;
 
@@ -1087,8 +1075,9 @@ no quit occurs and `x-popup-menu' returns nil.  */)
 
 #ifdef HAVE_MENUS
   {
-    int get_current_pos_p = 0;
-    /* FIXME!!  check_w32 (); or check_x (); or check_ns (); */
+    bool get_current_pos_p = 0;
+
+    check_window_system (SELECTED_FRAME ());
 
     /* Decode the first argument: find the window and the coordinates.  */
     if (EQ (position, Qt)
@@ -1128,7 +1117,7 @@ no quit occurs and `x-popup-menu' returns nil.  */)
     if (get_current_pos_p)
       {
        /* Use the mouse's current position.  */
-       FRAME_PTR new_f = SELECTED_FRAME ();
+       struct frame *new_f = SELECTED_FRAME ();
 #ifdef HAVE_X_WINDOWS
        /* Can't use mouse_position_hook for X since it returns
           coordinates relative to the window the mouse is in,
@@ -1192,14 +1181,16 @@ no quit occurs and `x-popup-menu' returns nil.  */)
         but I don't want to make one now.  */
       CHECK_WINDOW (window);
 
-    CHECK_RANGED_INTEGER ((xpos < INT_MIN - MOST_NEGATIVE_FIXNUM
+    CHECK_RANGED_INTEGER (x,
+                         (xpos < INT_MIN - MOST_NEGATIVE_FIXNUM
                           ? (EMACS_INT) INT_MIN - xpos
                           : MOST_NEGATIVE_FIXNUM),
-                         x, INT_MAX - xpos);
-    CHECK_RANGED_INTEGER ((ypos < INT_MIN - MOST_NEGATIVE_FIXNUM
+                         INT_MAX - xpos);
+    CHECK_RANGED_INTEGER (y,
+                         (ypos < INT_MIN - MOST_NEGATIVE_FIXNUM
                           ? (EMACS_INT) INT_MIN - ypos
                           : MOST_NEGATIVE_FIXNUM),
-                         y, INT_MAX - ypos);
+                         INT_MAX - ypos);
     xpos += XINT (x);
     ypos += XINT (y);
 
@@ -1213,7 +1204,7 @@ no quit occurs and `x-popup-menu' returns nil.  */)
 #endif /* HAVE_MENUS */
 
   /* Now parse the lisp menus.  */
-  record_unwind_protect (unuse_menu_items, Qnil);
+  record_unwind_protect_void (unuse_menu_items);
 
   title = Qnil;
   GCPRO1 (title);
@@ -1315,11 +1306,11 @@ no quit occurs and `x-popup-menu' returns nil.  */)
 #endif
 
 #ifdef HAVE_NS                 /* FIXME: ns-specific, why? --Stef  */
-  record_unwind_protect (cleanup_popup_menu, Qnil);
+  record_unwind_protect_void (discard_menu_items);
 #endif
 
   /* Display them in a menu.  */
-  BLOCK_INPUT;
+  block_input ();
 
   /* FIXME: Use a terminal hook!  */
 #if defined HAVE_NTGUI
@@ -1349,7 +1340,7 @@ no quit occurs and `x-popup-menu' returns nil.  */)
     selection = tty_menu_show (f, xpos, ypos, for_click,
                               keymaps, title, &error_name);
 
-  UNBLOCK_INPUT;
+  unblock_input ();
 
 #ifdef HAVE_NS
   unbind_to (specpdl_count, Qnil);