]> code.delx.au - gnu-emacs/blobdiff - src/xmenu.c
* nt/config.nt: Complete rework to bring it in sync with autogen/config.in.
[gnu-emacs] / src / xmenu.c
index eab25d709f6ed9ad0e23e1ec82c5bb4d1a6a6d35..5a6390449c4513b87a4fd4f9a5669fd5afb82881 100644 (file)
@@ -1,6 +1,6 @@
 /* X Communication module for terminals which understand the X protocol.
 
 /* X Communication module for terminals which understand the X protocol.
 
-Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2011
+Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2012
   Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
   Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -47,6 +47,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "termhooks.h"
 #include "window.h"
 #include "blockinput.h"
 #include "termhooks.h"
 #include "window.h"
 #include "blockinput.h"
+#include "character.h"
 #include "buffer.h"
 #include "charset.h"
 #include "coding.h"
 #include "buffer.h"
 #include "charset.h"
 #include "coding.h"
@@ -102,6 +103,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifdef USE_GTK
 #include "gtkutil.h"
 
 #ifdef USE_GTK
 #include "gtkutil.h"
+#ifdef HAVE_GTK3
+#include "xgselect.h"
+#endif
 #endif
 
 #include "menu.h"
 #endif
 
 #include "menu.h"
@@ -388,8 +392,6 @@ x_menu_wait_for_event (void *data)
          )
     {
       EMACS_TIME next_time = timer_check (), *ntp;
          )
     {
       EMACS_TIME next_time = timer_check (), *ntp;
-      long secs = EMACS_SECS (next_time);
-      long usecs = EMACS_USECS (next_time);
       SELECT_TYPE read_fds;
       struct x_display_info *dpyinfo;
       int n = 0;
       SELECT_TYPE read_fds;
       struct x_display_info *dpyinfo;
       int n = 0;
@@ -403,12 +405,19 @@ x_menu_wait_for_event (void *data)
           XFlush (dpyinfo->display);
         }
 
           XFlush (dpyinfo->display);
         }
 
-      if (secs < 0 && usecs < 0)
+      if (! EMACS_TIME_VALID_P (next_time))
         ntp = 0;
       else
         ntp = &next_time;
 
         ntp = 0;
       else
         ntp = &next_time;
 
-      select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, ntp);
+#ifdef HAVE_GTK3
+      /* Gtk3 have arrows on menus when they don't fit.  When the
+        pointer is over an arrow, a timeout scrolls it a bit.  Use
+        xg_select so that timeout gets triggered.  */
+      xg_select (n + 1, &read_fds, NULL, NULL, ntp, NULL);
+#else
+      pselect (n + 1, &read_fds, NULL, NULL, ntp, NULL);
+#endif
     }
 }
 #endif /* ! MSDOS */
     }
 }
 #endif /* ! MSDOS */
@@ -952,7 +961,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
   else if (!f->output_data.x->saved_menu_event && !deep_p)
     {
       deep_p = 1;
   else if (!f->output_data.x->saved_menu_event && !deep_p)
     {
       deep_p = 1;
-      f->output_data.x->saved_menu_event = (XEvent*)xmalloc (sizeof (XEvent));
+      f->output_data.x->saved_menu_event = xmalloc (sizeof (XEvent));
       f->output_data.x->saved_menu_event->type = 0;
     }
 
       f->output_data.x->saved_menu_event->type = 0;
     }
 
@@ -971,8 +980,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
       ptrdiff_t specpdl_count = SPECPDL_INDEX ();
       int previous_menu_items_used = f->menu_bar_items_used;
       Lisp_Object *previous_items
       ptrdiff_t specpdl_count = SPECPDL_INDEX ();
       int previous_menu_items_used = f->menu_bar_items_used;
       Lisp_Object *previous_items
-       = (Lisp_Object *) alloca (previous_menu_items_used
-                                 * sizeof (Lisp_Object));
+       = alloca (previous_menu_items_used * sizeof *previous_items);
       int subitems;
 
       /* If we are making a new widget, its contents are empty,
       int subitems;
 
       /* If we are making a new widget, its contents are empty,
@@ -1019,18 +1027,19 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
       menu_items = f->menu_bar_vector;
       menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
       subitems = ASIZE (items) / 4;
       menu_items = f->menu_bar_vector;
       menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
       subitems = ASIZE (items) / 4;
-      submenu_start = (int *) alloca ((subitems + 1) * sizeof (int));
-      submenu_end = (int *) alloca (subitems * sizeof (int));
-      submenu_n_panes = (int *) alloca (subitems * sizeof (int));
-      submenu_top_level_items = (int *) alloca (subitems * sizeof (int));
+      submenu_start = alloca ((subitems + 1) * sizeof *submenu_start);
+      submenu_end = alloca (subitems * sizeof *submenu_end);
+      submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes);
+      submenu_top_level_items = alloca (subitems
+                                       * sizeof *submenu_top_level_items);
       init_menu_items ();
       for (i = 0; i < subitems; i++)
        {
          Lisp_Object key, string, maps;
 
       init_menu_items ();
       for (i = 0; i < subitems; i++)
        {
          Lisp_Object key, string, maps;
 
-         key = XVECTOR (items)->contents[4 * i];
-         string = XVECTOR (items)->contents[4 * i + 1];
-         maps = XVECTOR (items)->contents[4 * i + 2];
+         key = AREF (items, 4 * i);
+         string = AREF (items, 4 * i + 1);
+         maps = AREF (items, 4 * i + 2);
          if (NILP (string))
            break;
 
          if (NILP (string))
            break;
 
@@ -1081,7 +1090,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
       /* Compare the new menu items with the ones computed last time.  */
       for (i = 0; i < previous_menu_items_used; i++)
        if (menu_items_used == i
       /* Compare the new menu items with the ones computed last time.  */
       for (i = 0; i < previous_menu_items_used; i++)
        if (menu_items_used == i
-           || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i])))
+           || (!EQ (previous_items[i], AREF (menu_items, i))))
          break;
       if (i == menu_items_used && i == previous_menu_items_used && i != 0)
        {
          break;
       if (i == menu_items_used && i == previous_menu_items_used && i != 0)
        {
@@ -1106,7 +1115,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
       for (i = 0; i < ASIZE (items); i += 4)
        {
          Lisp_Object string;
       for (i = 0; i < ASIZE (items); i += 4)
        {
          Lisp_Object string;
-         string = XVECTOR (items)->contents[i + 1];
+         string = AREF (items, i + 1);
          if (NILP (string))
             break;
           wv->name = SSDATA (string);
          if (NILP (string))
             break;
           wv->name = SSDATA (string);
@@ -1133,7 +1142,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
        {
          Lisp_Object string;
 
        {
          Lisp_Object string;
 
-         string = XVECTOR (items)->contents[i + 1];
+         string = AREF (items, i + 1);
          if (NILP (string))
            break;
 
          if (NILP (string))
            break;
 
@@ -1304,7 +1313,7 @@ free_frame_menubar (FRAME_PTR f)
 #ifdef USE_MOTIF
       /* Removing the menu bar magically changes the shell widget's x
         and y position of (0, 0) which, when the menu bar is turned
 #ifdef USE_MOTIF
       /* Removing the menu bar magically changes the shell widget's x
         and y position of (0, 0) which, when the menu bar is turned
-        on again, leads to pull-down menuss appearing in strange
+        on again, leads to pull-down menus appearing in strange
         positions near the upper-left corner of the display.  This
         happens only with some window managers like twm and ctwm,
         but not with other like Motif's mwm or kwm, because the
         positions near the upper-left corner of the display.  This
         happens only with some window managers like twm and ctwm,
         but not with other like Motif's mwm or kwm, because the
@@ -1435,6 +1444,13 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y,
   GtkMenuPositionFunc pos_func = 0;  /* Pop up at pointer.  */
   struct next_popup_x_y popup_x_y;
   ptrdiff_t specpdl_count = SPECPDL_INDEX ();
   GtkMenuPositionFunc pos_func = 0;  /* Pop up at pointer.  */
   struct next_popup_x_y popup_x_y;
   ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  int use_pos_func = ! for_click;
+
+#ifdef HAVE_GTK3
+  /* Always use position function for Gtk3.  Otherwise menus may become
+     too small to show anything.  */
+  use_pos_func = 1;
+#endif
 
   if (! FRAME_X_P (f))
     abort ();
 
   if (! FRAME_X_P (f))
     abort ();
@@ -1446,7 +1462,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y,
                            G_CALLBACK (menu_highlight_callback));
   xg_crazy_callback_abort = 0;
 
                            G_CALLBACK (menu_highlight_callback));
   xg_crazy_callback_abort = 0;
 
-  if (! for_click)
+  if (use_pos_func)
     {
       /* Not invoked by a click.  pop up at x/y.  */
       pos_func = menu_position_func;
     {
       /* Not invoked by a click.  pop up at x/y.  */
       pos_func = menu_position_func;
@@ -1461,7 +1477,8 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y,
 
       i = 0;  /* gtk_menu_popup needs this to be 0 for a non-button popup.  */
     }
 
       i = 0;  /* gtk_menu_popup needs this to be 0 for a non-button popup.  */
     }
-  else
+
+  if (for_click)
     {
       for (i = 0; i < 5; i++)
         if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
     {
       for (i = 0; i < 5; i++)
         if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
@@ -1604,6 +1621,17 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
 
 #endif /* not USE_GTK */
 
 
 #endif /* not USE_GTK */
 
+static Lisp_Object
+cleanup_widget_value_tree (Lisp_Object arg)
+{
+  struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+  widget_value *wv = p->pointer;
+
+  free_menubar_widget_value_tree (wv);
+
+  return Qnil;
+}
+
 Lisp_Object
 xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
            Lisp_Object title, const char **error_name, Time timestamp)
 Lisp_Object
 xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
            Lisp_Object title, const char **error_name, Time timestamp)
@@ -1611,13 +1639,15 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
   int i;
   widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
   widget_value **submenu_stack
   int i;
   widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
   widget_value **submenu_stack
-    = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
+    = alloca (menu_items_used * sizeof *submenu_stack);
   Lisp_Object *subprefix_stack
   Lisp_Object *subprefix_stack
-    = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
+    = alloca (menu_items_used * sizeof *subprefix_stack);
   int submenu_depth = 0;
 
   int first_pane;
 
   int submenu_depth = 0;
 
   int first_pane;
 
+  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
   if (! FRAME_X_P (f))
     abort ();
 
   if (! FRAME_X_P (f))
     abort ();
 
@@ -1644,7 +1674,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
   i = 0;
   while (i < menu_items_used)
     {
   i = 0;
   while (i < menu_items_used)
     {
-      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;
        {
          submenu_stack[submenu_depth++] = save_wv;
          save_wv = prev_wv;
@@ -1652,21 +1682,21 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
          first_pane = 1;
          i++;
        }
          first_pane = 1;
          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];
          first_pane = 0;
          i++;
        }
        {
          prev_wv = save_wv;
          save_wv = submenu_stack[--submenu_depth];
          first_pane = 0;
          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.  */
               && 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;
        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, prefix;
        {
          /* Create a new pane.  */
          Lisp_Object pane_name, prefix;
@@ -1699,7 +1729,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
                save_wv->next = wv;
              else
                first_wv->contents = wv;
                save_wv->next = wv;
              else
                first_wv->contents = wv;
-             wv->name = pane_string;
+             wv->name = (char *) pane_string;
              if (keymaps && !NILP (prefix))
                wv->name++;
              wv->value = 0;
              if (keymaps && !NILP (prefix))
                wv->name++;
              wv->value = 0;
@@ -1756,7 +1786,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
             make the call_data null so that it won't display a box
             when the mouse is on it.  */
          wv->call_data
             make the call_data null so that it won't display a box
             when the mouse is on it.  */
          wv->call_data
-           = (!NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0);
+           = (!NILP (def) ? (void *) &AREF (menu_items, i) : 0);
          wv->enabled = !NILP (enable);
 
          if (NILP (type))
          wv->enabled = !NILP (enable);
 
          if (NILP (type))
@@ -1812,11 +1842,15 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
   /* No selection has been chosen yet.  */
   menu_item_selection = 0;
 
   /* No selection has been chosen yet.  */
   menu_item_selection = 0;
 
+  /* Make sure to free the widget_value objects we used to specify the
+     contents even with longjmp.  */
+  record_unwind_protect (cleanup_widget_value_tree,
+                        make_save_value (first_wv, 0));
+
   /* Actually create and show the menu until popped down.  */
   create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp);
 
   /* Actually create and show the menu until popped down.  */
   create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp);
 
-  /* Free the widget_value objects we used to specify the contents.  */
-  free_menubar_widget_value_tree (first_wv);
+  unbind_to (specpdl_count, Qnil);
 
   /* Find the selected item, and its pane, to return
      the proper value.  */
 
   /* Find the selected item, and its pane, to return
      the proper value.  */
@@ -1828,32 +1862,32 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
       i = 0;
       while (i < menu_items_used)
        {
       i = 0;
       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++;
            }
            {
              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++;
            }
            {
              prefix = subprefix_stack[--submenu_depth];
              i++;
            }
-         else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+         else if (EQ (AREF (menu_items, i), Qt))
            {
              prefix
            {
              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.  */
              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
            i += 1;
          else
            {
              entry
-               = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
-             if (menu_item_selection == &XVECTOR (menu_items)->contents[i])
+               = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+             if (menu_item_selection == &AREF (menu_items, i))
                {
                  if (keymaps != 0)
                    {
                {
                  if (keymaps != 0)
                    {
@@ -2003,6 +2037,8 @@ xdialog_show (FRAME_PTR f,
   /* 1 means we've seen the boundary between left-hand elts and right-hand.  */
   int boundary_seen = 0;
 
   /* 1 means we've seen the boundary between left-hand elts and right-hand.  */
   int boundary_seen = 0;
 
+  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
   if (! FRAME_X_P (f))
     abort ();
 
   if (! FRAME_X_P (f))
     abort ();
 
@@ -2019,12 +2055,12 @@ xdialog_show (FRAME_PTR f,
   {
     Lisp_Object pane_name, prefix;
     const char *pane_string;
   {
     Lisp_Object pane_name, prefix;
     const char *pane_string;
-    pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME];
-    prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX];
+    pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
+    prefix = AREF (menu_items, MENU_ITEMS_PANE_PREFIX);
     pane_string = (NILP (pane_name)
                   ? "" : SSDATA (pane_name));
     prev_wv = xmalloc_widget_value ();
     pane_string = (NILP (pane_name)
                   ? "" : SSDATA (pane_name));
     prev_wv = xmalloc_widget_value ();
-    prev_wv->value = pane_string;
+    prev_wv->value = (char *) pane_string;
     if (keymaps && !NILP (prefix))
       prev_wv->name++;
     prev_wv->enabled = 1;
     if (keymaps && !NILP (prefix))
       prev_wv->name++;
     prev_wv->enabled = 1;
@@ -2039,10 +2075,10 @@ xdialog_show (FRAME_PTR f,
 
        /* Create a new item within current pane.  */
        Lisp_Object item_name, enable, descrip;
 
        /* Create a new item within current pane.  */
        Lisp_Object item_name, enable, descrip;
-       item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
-       enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
+       item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+       enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
        descrip
        descrip
-         = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
+         = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
 
        if (NILP (item_name))
          {
 
        if (NILP (item_name))
          {
@@ -2071,7 +2107,7 @@ xdialog_show (FRAME_PTR f,
        if (!NILP (descrip))
          wv->key = SSDATA (descrip);
        wv->value = SSDATA (item_name);
        if (!NILP (descrip))
          wv->key = SSDATA (descrip);
        wv->value = SSDATA (item_name);
-       wv->call_data = (void *) &XVECTOR (menu_items)->contents[i];
+       wv->call_data = (void *) &AREF (menu_items, i);
        wv->enabled = !NILP (enable);
        wv->help = Qnil;
        prev_wv = wv;
        wv->enabled = !NILP (enable);
        wv->help = Qnil;
        prev_wv = wv;
@@ -2116,11 +2152,15 @@ xdialog_show (FRAME_PTR f,
   /* No selection has been chosen yet.  */
   menu_item_selection = 0;
 
   /* No selection has been chosen yet.  */
   menu_item_selection = 0;
 
+  /* Make sure to free the widget_value objects we used to specify the
+     contents even with longjmp.  */
+  record_unwind_protect (cleanup_widget_value_tree,
+                        make_save_value (first_wv, 0));
+
   /* Actually create and show the dialog.  */
   create_and_show_dialog (f, first_wv);
 
   /* Actually create and show the dialog.  */
   create_and_show_dialog (f, first_wv);
 
-  /* Free the widget_value objects we used to specify the contents.  */
-  free_menubar_widget_value_tree (first_wv);
+  unbind_to (specpdl_count, Qnil);
 
   /* Find the selected item, and its pane, to return
      the proper value.  */
 
   /* Find the selected item, and its pane, to return
      the proper value.  */
@@ -2134,13 +2174,13 @@ xdialog_show (FRAME_PTR f,
        {
          Lisp_Object entry;
 
        {
          Lisp_Object entry;
 
-         if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+         if (EQ (AREF (menu_items, i), Qt))
            {
              prefix
            {
              prefix
-               = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+               = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
              i += MENU_ITEMS_PANE_LENGTH;
            }
              i += MENU_ITEMS_PANE_LENGTH;
            }
-         else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+         else if (EQ (AREF (menu_items, i), Qquote))
            {
              /* This is the boundary between left-side elts and
                 right-side elts.  */
            {
              /* This is the boundary between left-side elts and
                 right-side elts.  */
@@ -2149,8 +2189,8 @@ xdialog_show (FRAME_PTR f,
          else
            {
              entry
          else
            {
              entry
-               = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
-             if (menu_item_selection == &XVECTOR (menu_items)->contents[i])
+               = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+             if (menu_item_selection == &AREF (menu_items, i))
                {
                  if (keymaps != 0)
                    {
                {
                  if (keymaps != 0)
                    {
@@ -2310,7 +2350,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
   lpane = XM_FAILURE;
   while (i < menu_items_used)
     {
   lpane = XM_FAILURE;
   while (i < menu_items_used)
     {
-      if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+      if (EQ (AREF (menu_items, i), Qt))
        {
          /* Create a new pane.  */
          Lisp_Object pane_name, prefix;
        {
          /* Create a new pane.  */
          Lisp_Object pane_name, prefix;
@@ -2318,8 +2358,8 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
 
           maxlines = max (maxlines, lines);
           lines = 0;
 
           maxlines = max (maxlines, lines);
           lines = 0;
-         pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
-         prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+         pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
+         prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
          pane_string = (NILP (pane_name)
                         ? "" : SSDATA (pane_name));
          if (keymaps && !NILP (prefix))
          pane_string = (NILP (pane_name)
                         ? "" : SSDATA (pane_name));
          if (keymaps && !NILP (prefix))
@@ -2339,7 +2379,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
          while (j < menu_items_used)
            {
              Lisp_Object item;
          while (j < menu_items_used)
            {
              Lisp_Object item;
-             item = XVECTOR (menu_items)->contents[j];
+             item = AREF (menu_items, j);
              if (EQ (item, Qt))
                break;
              if (NILP (item))
              if (EQ (item, Qt))
                break;
              if (NILP (item))
@@ -2356,7 +2396,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
        }
       /* Ignore a nil in the item list.
         It's meaningful only for dialog boxes.  */
        }
       /* 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
        {
        i += 1;
       else
        {
@@ -2365,18 +2405,18 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
          char *item_data;
          char const *help_string;
 
          char *item_data;
          char const *help_string;
 
-         item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
-         enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
+         item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+         enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
          descrip
          descrip
-           = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
-         help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
+           = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+         help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
          help_string = STRINGP (help) ? SSDATA (help) : NULL;
 
          if (!NILP (descrip))
            {
              /* if alloca is fast, use that to make the space,
                 to reduce gc needs.  */
          help_string = STRINGP (help) ? SSDATA (help) : NULL;
 
          if (!NILP (descrip))
            {
              /* if alloca is fast, use that to make the space,
                 to reduce gc needs.  */
-             item_data = (char *) alloca (maxwidth + SBYTES (descrip) + 1);
+             item_data = alloca (maxwidth + SBYTES (descrip) + 1);
              memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
              for (j = SCHARS (item_name); j < maxwidth; j++)
                item_data[j] = ' ';
              memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
              for (j = SCHARS (item_name); j < maxwidth; j++)
                item_data[j] = ' ';
@@ -2483,11 +2523,11 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
       i = 0;
       while (i < menu_items_used)
        {
       i = 0;
       while (i < menu_items_used)
        {
-         if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+         if (EQ (AREF (menu_items, i), Qt))
            {
              if (pane == 0)
                pane_prefix
            {
              if (pane == 0)
                pane_prefix
-                 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+                 = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
              pane--;
              i += MENU_ITEMS_PANE_LENGTH;
            }
              pane--;
              i += MENU_ITEMS_PANE_LENGTH;
            }
@@ -2498,7 +2538,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
                  if (selidx == 0)
                    {
                      entry
                  if (selidx == 0)
                    {
                      entry
-                       = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
+                       = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
                      if (keymaps != 0)
                        {
                          entry = Fcons (entry, Qnil);
                      if (keymaps != 0)
                        {
                          entry = Fcons (entry, Qnil);