use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / xmenu.c
index 2d41350..92f293b 100644 (file)
@@ -139,53 +139,6 @@ menubar_id_to_frame (LWLIB_ID id)
 }
 
 #endif
-\f
-#ifdef HAVE_X_WINDOWS
-/* Return the mouse position in *X and *Y.  The coordinates are window
-   relative for the edit window in frame F.
-   This is for Fx_popup_menu.  The mouse_position_hook can not
-   be used for X, as it returns window relative coordinates
-   for the window where the mouse is in.  This could be the menu bar,
-   the scroll bar or the edit window.  Fx_popup_menu needs to be
-   sure it is the edit window.  */
-void
-mouse_position_for_popup (struct frame *f, int *x, int *y)
-{
-  Window root, dummy_window;
-  int dummy;
-
-  eassert (FRAME_X_P (f));
-
-  block_input ();
-
-  XQueryPointer (FRAME_X_DISPLAY (f),
-                 DefaultRootWindow (FRAME_X_DISPLAY (f)),
-
-                 /* The root window which contains the pointer.  */
-                 &root,
-
-                 /* Window pointer is on, not used  */
-                 &dummy_window,
-
-                 /* The position on that root window.  */
-                 x, y,
-
-                 /* x/y in dummy_window coordinates, not used.  */
-                 &dummy, &dummy,
-
-                 /* Modifier keys and pointer buttons, about which
-                    we don't care.  */
-                 (unsigned int *) &dummy);
-
-  unblock_input ();
-
-  /* x_menu_show expects window coordinates, not root window
-     coordinates.  Translate.  */
-  *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
-  *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-}
-
-#endif /* HAVE_X_WINDOWS */
 
 #ifndef MSDOS
 
@@ -797,7 +750,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
 
       struct buffer *prev = current_buffer;
       Lisp_Object buffer;
-      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+      dynwind_begin ();
       int previous_menu_items_used = f->menu_bar_items_used;
       Lisp_Object *previous_items
        = alloca (previous_menu_items_used * sizeof *previous_items);
@@ -914,7 +867,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
             the menus in any form, since it would be a no-op.  */
          free_menubar_widget_value_tree (first_wv);
          discard_menu_items ();
-         unbind_to (specpdl_count, Qnil);
+         dynwind_end ();
          return;
        }
 
@@ -923,7 +876,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
       f->menu_bar_items_used = menu_items_used;
 
       /* This undoes save_menu_items.  */
-      unbind_to (specpdl_count, Qnil);
+      dynwind_end ();
 
       /* Now GC cannot happen during the lifetime of the widget_value,
         so it's safe to store data from a Lisp_String.  */
@@ -1248,7 +1201,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
   GtkWidget *menu;
   GtkMenuPositionFunc pos_func = 0;  /* Pop up at pointer.  */
   struct next_popup_x_y popup_x_y;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  dynwind_begin ();
   bool use_pos_func = ! for_click;
 
 #ifdef HAVE_GTK3
@@ -1308,7 +1261,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
       popup_widget_loop (1, menu);
     }
 
-  unbind_to (specpdl_count, Qnil);
+  dynwind_end ();
 
   /* Must reset this manually because the button release event is not passed
      to Emacs event loop. */
@@ -1410,7 +1363,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
 
   {
     int fact = 4 * sizeof (LWLIB_ID);
-    ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+    dynwind_begin ();
     record_unwind_protect (pop_down_menu,
                            Fcons (make_number (menu_id >> (fact)),
                                   make_number (menu_id & ~(-1 << (fact)))));
@@ -1418,7 +1371,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
     /* Process events that apply to the menu.  */
     popup_get_selection (0, FRAME_DISPLAY_INFO (f), menu_id, 1);
 
-    unbind_to (specpdl_count, Qnil);
+    dynwind_end ();
   }
 }
 
@@ -1444,7 +1397,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
 
   int first_pane;
 
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   eassert (FRAME_X_P (f));
 
@@ -1453,6 +1406,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
   if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
     {
       *error_name = "Empty menu";
+      dynwind_end ();
       return Qnil;
     }
 
@@ -1626,7 +1580,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
   create_and_show_popup_menu (f, first_wv, x, y,
                              menuflags & MENU_FOR_CLICK);
 
-  unbind_to (specpdl_count, Qnil);
+  dynwind_end ();
 
   /* Find the selected item, and its pane, to return
      the proper value.  */
@@ -1723,7 +1677,7 @@ create_and_show_dialog (struct frame *f, widget_value *first_wv)
 
   if (menu)
     {
-      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+      dynwind_begin ();
       record_unwind_protect_ptr (pop_down_menu, menu);
 
       /* Display the menu.  */
@@ -1732,7 +1686,7 @@ create_and_show_dialog (struct frame *f, widget_value *first_wv)
       /* Process events that apply to the menu.  */
       popup_widget_loop (1, menu);
 
-      unbind_to (specpdl_count, Qnil);
+      dynwind_end ();
     }
 }
 
@@ -1778,7 +1732,7 @@ create_and_show_dialog (struct frame *f, widget_value *first_wv)
   /* Process events that apply to the dialog box.
      Also handle timers.  */
   {
-    ptrdiff_t count = SPECPDL_INDEX ();
+    dynwind_begin ();
     int fact = 4 * sizeof (LWLIB_ID);
 
     /* xdialog_show_unwind is responsible for popping the dialog box down.  */
@@ -1788,7 +1742,7 @@ create_and_show_dialog (struct frame *f, widget_value *first_wv)
 
     popup_get_selection (0, FRAME_DISPLAY_INFO (f), dialog_id, 1);
 
-    unbind_to (count, Qnil);
+    dynwind_end ();
   }
 }
 
@@ -1812,7 +1766,7 @@ x_dialog_show (struct frame *f, Lisp_Object title,
   /* 1 means we've seen the boundary between left-hand elts and right-hand.  */
   int boundary_seen = 0;
 
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   eassert (FRAME_X_P (f));
 
@@ -1821,6 +1775,7 @@ x_dialog_show (struct frame *f, Lisp_Object title,
   if (menu_items_n_panes > 1)
     {
       *error_name = "Multiple panes in dialog box";
+      dynwind_end ();
       return Qnil;
     }
 
@@ -1851,6 +1806,7 @@ x_dialog_show (struct frame *f, Lisp_Object title,
          {
            free_menubar_widget_value_tree (first_wv);
            *error_name = "Submenu in dialog items";
+           dynwind_end ();
            return Qnil;
          }
        if (EQ (item_name, Qquote))
@@ -1865,6 +1821,7 @@ x_dialog_show (struct frame *f, Lisp_Object title,
          {
            free_menubar_widget_value_tree (first_wv);
            *error_name = "Too many dialog items";
+           dynwind_end ();
            return Qnil;
          }
 
@@ -1922,7 +1879,7 @@ x_dialog_show (struct frame *f, Lisp_Object title,
   /* Actually create and show the dialog.  */
   create_and_show_dialog (f, first_wv);
 
-  unbind_to (specpdl_count, Qnil);
+  dynwind_end ();
 
   /* Find the selected item, and its pane, to return
      the proper value.  */
@@ -2077,17 +2034,20 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
   int maxwidth;
   int dummy_int;
   unsigned int dummy_uint;
-  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   eassert (FRAME_X_P (f) || FRAME_MSDOS_P (f));
 
   *error_name = 0;
-  if (menu_items_n_panes == 0)
+  if (menu_items_n_panes == 0) {
+    dynwind_end ();
     return Qnil;
+  }
 
   if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
     {
       *error_name = "Empty menu";
+      dynwind_end ();
       return Qnil;
     }
 
@@ -2104,14 +2064,10 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
     {
       *error_name = "Can't create menu";
       unblock_input ();
+      dynwind_end ();
       return Qnil;
     }
 
-  /* Don't GC while we prepare and show the menu,
-     because we give the oldxmenu library pointers to the
-     contents of strings.  */
-  inhibit_garbage_collection ();
-
 #ifdef HAVE_X_WINDOWS
   /* Adjust coordinates to relative to the outer (window manager) window.  */
   x += FRAME_OUTER_TO_INNER_DIFF_X (f);
@@ -2148,6 +2104,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
              XMenuDestroy (FRAME_X_DISPLAY (f), menu);
              *error_name = "Can't create pane";
              unblock_input ();
+             dynwind_end ();
              return Qnil;
            }
          i += MENU_ITEMS_PANE_LENGTH;
@@ -2213,6 +2170,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
              XMenuDestroy (FRAME_X_DISPLAY (f), menu);
              *error_name = "Can't add selection to menu";
              unblock_input ();
+             dynwind_end ();
              return Qnil;
            }
          i += MENU_ITEMS_ITEM_LENGTH;
@@ -2347,7 +2305,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
     }
 
   unblock_input ();
-  unbind_to (specpdl_count, Qnil);
+  dynwind_end ();
 
   return entry;
 }
@@ -2377,6 +2335,8 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
 void
 syms_of_xmenu (void)
 {
+#include "xmenu.x"
+
   DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
 
 #ifdef USE_X_TOOLKIT
@@ -2384,10 +2344,7 @@ syms_of_xmenu (void)
   next_menubar_widget_id = 1;
 #endif
 
-  defsubr (&Smenu_or_popup_active_p);
-
 #if defined (USE_GTK) || defined (USE_X_TOOLKIT)
-  defsubr (&Sx_menu_bar_open_internal);
   Ffset (intern_c_string ("accelerate-menu"),
         intern_c_string (Sx_menu_bar_open_internal.symbol_name));
 #endif