Avoid calls to strlen in miscellaneous functions.
[bpt/emacs.git] / src / xmenu.c
index fc629b3..5a63904 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
@@ -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 "character.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 HAVE_GTK3
+#include "xgselect.h"
+#endif
 #endif
 
 #include "menu.h"
@@ -315,7 +319,7 @@ for instance using the window manager, then this produces a quit and
     Lisp_Object title;
     const char *error_name;
     Lisp_Object selection;
-    int specpdl_count = SPECPDL_INDEX ();
+    ptrdiff_t specpdl_count = SPECPDL_INDEX ();
 
     /* Decode the dialog items from what was specified.  */
     title = Fcar (contents);
@@ -388,8 +392,6 @@ x_menu_wait_for_event (void *data)
          )
     {
       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;
@@ -403,12 +405,19 @@ x_menu_wait_for_event (void *data)
           XFlush (dpyinfo->display);
         }
 
-      if (secs < 0 && usecs < 0)
+      if (! EMACS_TIME_VALID_P (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 */
@@ -740,10 +749,13 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data)
   help = call_data ? cb_data->help : Qnil;
 
   /* If popup_activated_flag is greater than 1 we are in a popup menu.
-     Don't show help for them, they won't appear before the
-     popup is popped down.  */
-  if (popup_activated_flag <= 1)
-    show_help_event (cb_data->cl_data->f, widget, help);
+     Don't pass the frame to show_help_event for those.
+     Passing frame creates an Emacs event.  As we are looping in
+     popup_widget_loop, it won't be handled.  Passing NULL shows the tip
+     directly without using an Emacs event.  This is what the Lucid code
+     does below.  */
+  show_help_event (popup_activated_flag <= 1 ? cb_data->cl_data->f : NULL,
+                   widget, help);
 }
 #else
 static void
@@ -949,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;
-      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;
     }
 
@@ -965,11 +977,10 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
 
       struct buffer *prev = current_buffer;
       Lisp_Object buffer;
-      int specpdl_count = SPECPDL_INDEX ();
+      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,
@@ -1016,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;
-      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;
 
-         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;
 
@@ -1078,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
-           || (!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)
        {
@@ -1103,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;
-         string = XVECTOR (items)->contents[i + 1];
+         string = AREF (items, i + 1);
          if (NILP (string))
             break;
           wv->name = SSDATA (string);
@@ -1130,7 +1142,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
        {
          Lisp_Object string;
 
-         string = XVECTOR (items)->contents[i + 1];
+         string = AREF (items, i + 1);
          if (NILP (string))
            break;
 
@@ -1301,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
-        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
@@ -1431,7 +1443,14 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y,
   GtkWidget *menu;
   GtkMenuPositionFunc pos_func = 0;  /* Pop up at pointer.  */
   struct next_popup_x_y popup_x_y;
-  int specpdl_count = SPECPDL_INDEX ();
+  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 ();
@@ -1443,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;
 
-  if (! for_click)
+  if (use_pos_func)
     {
       /* Not invoked by a click.  pop up at x/y.  */
       pos_func = menu_position_func;
@@ -1458,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.  */
     }
-  else
+
+  if (for_click)
     {
       for (i = 0; i < 5; i++)
         if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
@@ -1587,7 +1607,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
 
   {
     int fact = 4 * sizeof (LWLIB_ID);
-    int specpdl_count = SPECPDL_INDEX ();
+    ptrdiff_t specpdl_count = SPECPDL_INDEX ();
     record_unwind_protect (pop_down_menu,
                            Fcons (make_number (menu_id >> (fact)),
                                   make_number (menu_id & ~(-1 << (fact)))));
@@ -1601,6 +1621,17 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
 
 #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)
@@ -1608,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
-    = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
+    = alloca (menu_items_used * sizeof *submenu_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;
 
+  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
   if (! FRAME_X_P (f))
     abort ();
 
@@ -1641,7 +1674,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
   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;
@@ -1649,21 +1682,21 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
          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++;
        }
-      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, prefix;
@@ -1696,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;
-             wv->name = pane_string;
+             wv->name = (char *) pane_string;
              if (keymaps && !NILP (prefix))
                wv->name++;
              wv->value = 0;
@@ -1753,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
-           = (!NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0);
+           = (!NILP (def) ? (void *) &AREF (menu_items, i) : 0);
          wv->enabled = !NILP (enable);
 
          if (NILP (type))
@@ -1809,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;
 
+  /* 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);
 
-  /* 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.  */
@@ -1825,32 +1862,32 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
       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++;
            }
-         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 (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)
                    {
@@ -1906,7 +1943,7 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
 
   if (menu)
     {
-      int specpdl_count = SPECPDL_INDEX ();
+      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
       record_unwind_protect (pop_down_menu, make_save_value (menu, 0));
 
       /* Display the menu.  */
@@ -1944,7 +1981,7 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
   LWLIB_ID dialog_id;
 
   if (!FRAME_X_P (f))
-    abort();
+    abort ();
 
   dialog_id = widget_id_tick++;
 #ifdef USE_LUCID
@@ -1962,7 +1999,7 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
   /* Process events that apply to the dialog box.
      Also handle timers.  */
   {
-    int count = SPECPDL_INDEX ();
+    ptrdiff_t count = SPECPDL_INDEX ();
     int fact = 4 * sizeof (LWLIB_ID);
 
     /* xdialog_show_unwind is responsible for popping the dialog box down.  */
@@ -2000,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;
 
+  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
   if (! FRAME_X_P (f))
     abort ();
 
@@ -2016,12 +2055,12 @@ xdialog_show (FRAME_PTR f,
   {
     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 ();
-    prev_wv->value = pane_string;
+    prev_wv->value = (char *) pane_string;
     if (keymaps && !NILP (prefix))
       prev_wv->name++;
     prev_wv->enabled = 1;
@@ -2036,10 +2075,10 @@ xdialog_show (FRAME_PTR f,
 
        /* 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
-         = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
+         = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
 
        if (NILP (item_name))
          {
@@ -2068,7 +2107,7 @@ xdialog_show (FRAME_PTR f,
        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;
@@ -2092,7 +2131,7 @@ xdialog_show (FRAME_PTR f,
     /*  Frame title: 'Q' = Question, 'I' = Information.
         Can also have 'E' = Error if, one day, we want
         a popup for errors. */
-    if (NILP(header))
+    if (NILP (header))
       dialog_name[0] = 'Q';
     else
       dialog_name[0] = 'I';
@@ -2113,11 +2152,15 @@ xdialog_show (FRAME_PTR f,
   /* 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);
 
-  /* 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.  */
@@ -2131,13 +2174,13 @@ xdialog_show (FRAME_PTR f,
        {
          Lisp_Object entry;
 
-         if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+         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;
            }
-         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.  */
@@ -2146,8 +2189,8 @@ xdialog_show (FRAME_PTR f,
          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)
                    {
@@ -2259,7 +2302,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
   int maxwidth;
   int dummy_int;
   unsigned int dummy_uint;
-  int specpdl_count = SPECPDL_INDEX ();
+  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
 
   if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f))
     abort ();
@@ -2307,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)
     {
-      if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+      if (EQ (AREF (menu_items, i), Qt))
        {
          /* Create a new pane.  */
          Lisp_Object pane_name, prefix;
@@ -2315,8 +2358,8 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
 
           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))
@@ -2336,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;
-             item = XVECTOR (menu_items)->contents[j];
+             item = AREF (menu_items, j);
              if (EQ (item, Qt))
                break;
              if (NILP (item))
@@ -2353,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.  */
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+      else if (EQ (AREF (menu_items, i), Qquote))
        i += 1;
       else
        {
@@ -2362,18 +2405,18 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
          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
-           = 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.  */
-             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] = ' ';
@@ -2480,11 +2523,11 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
       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
-                 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+                 = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
              pane--;
              i += MENU_ITEMS_PANE_LENGTH;
            }
@@ -2495,7 +2538,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
                  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);