]> code.delx.au - gnu-emacs/blobdiff - src/menu.c
Bump version to 24.5 for the release-candidate
[gnu-emacs] / src / menu.c
index e33c647d020eb8c14e666a02fc58c8ea3024e1c7..3e0a89dc0761b487fce945fc685a1a6762bb6aae 100644 (file)
@@ -1,6 +1,6 @@
 /* Platform-independent code for terminal communications.
 
-Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2013 Free Software
+Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2015 Free Software
 Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -415,7 +415,8 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
        item_string = concat2 (prefix, item_string);
   }
 
-  if (FRAME_TERMCAP_P (XFRAME (Vmenu_updating_frame))
+  if ((FRAME_TERMCAP_P (XFRAME (Vmenu_updating_frame))
+       || FRAME_MSDOS_P (XFRAME (Vmenu_updating_frame)))
       && !NILP (map))
     /* Indicate visually that this is a submenu.  */
     item_string = concat2 (item_string, build_string (" >"));
@@ -1237,35 +1238,39 @@ no quit occurs and `x-popup-menu' returns nil.  */)
        /* Use the mouse's current position.  */
        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,
-          we need coordinates relative to the edit widget always.  */
-       if (new_f != 0)
+       if (FRAME_X_P (new_f))
          {
-           int cur_x, cur_y;
-
-           mouse_position_for_popup (new_f, &cur_x, &cur_y);
-           /* cur_x/y may be negative, so use make_number.  */
-           x = make_number (cur_x);
-           y = make_number (cur_y);
+           /* Can't use mouse_position_hook for X since it returns
+              coordinates relative to the window the mouse is in,
+              we need coordinates relative to the edit widget always.  */
+           if (new_f != 0)
+             {
+               int cur_x, cur_y;
+
+               mouse_position_for_popup (new_f, &cur_x, &cur_y);
+               /* cur_x/y may be negative, so use make_number.  */
+               x = make_number (cur_x);
+               y = make_number (cur_y);
+             }
+         }
+       else
+#endif /* HAVE_X_WINDOWS */
+         {
+           Lisp_Object bar_window;
+           enum scroll_bar_part part;
+           Time time;
+           void (*mouse_position_hook) (struct frame **, int,
+                                        Lisp_Object *,
+                                        enum scroll_bar_part *,
+                                        Lisp_Object *,
+                                        Lisp_Object *,
+                                        Time *) =
+             FRAME_TERMINAL (new_f)->mouse_position_hook;
+
+           if (mouse_position_hook)
+             (*mouse_position_hook) (&new_f, 1, &bar_window,
+                                     &part, &x, &y, &time);
          }
-
-#else /* not HAVE_X_WINDOWS */
-       Lisp_Object bar_window;
-       enum scroll_bar_part part;
-       Time time;
-        void (*mouse_position_hook) (struct frame **, int,
-                                     Lisp_Object *,
-                                     enum scroll_bar_part *,
-                                     Lisp_Object *,
-                                     Lisp_Object *,
-                                     Time *) =
-         FRAME_TERMINAL (new_f)->mouse_position_hook;
-
-       if (mouse_position_hook)
-         (*mouse_position_hook) (&new_f, 1, &bar_window,
-                                 &part, &x, &y, &time);
-#endif /* not HAVE_X_WINDOWS */
 
        if (new_f != 0)
          XSETFRAME (window, new_f);
@@ -1442,9 +1447,19 @@ no quit occurs and `x-popup-menu' returns nil.  */)
                            keymaps, title, &error_name);
   else
 #endif
+#ifndef MSDOS
   if (FRAME_TERMCAP_P (f))
-    selection = tty_menu_show (f, xpos, ypos, for_click, keymaps, title,
-                              kbd_menu_navigation, &error_name);
+    {
+      ptrdiff_t count1 = SPECPDL_INDEX ();
+
+      /* Avoid crashes if, e.g., another client will connect while we
+        are in a menu.  */
+      temporarily_switch_to_single_kboard (f);
+      selection = tty_menu_show (f, xpos, ypos, for_click, keymaps, title,
+                                kbd_menu_navigation, &error_name);
+      unbind_to (count1, Qnil);
+    }
+#endif
 
 #ifdef HAVE_NS
   unbind_to (specpdl_count, Qnil);
@@ -1543,6 +1558,11 @@ for instance using the window manager, then this produces a quit and
        but I don't want to make one now.  */
     CHECK_WINDOW (window);
 
+  /* Note that xw_popup_dialog can call menu code, so
+     Vmenu_updating_frame should be set (Bug#17891).  */
+  eassert (f && FRAME_LIVE_P (f));
+  XSETFRAME (Vmenu_updating_frame, f);
+
   /* Force a redisplay before showing the dialog.  If a frame is created
      just before showing the dialog, its contents may not have been fully
      drawn, as this depends on timing of events from the X server.  Redisplay
@@ -1553,20 +1573,23 @@ for instance using the window manager, then this produces a quit and
      Do this before creating the widget value that points to Lisp
      string contents, because Fredisplay may GC and relocate them.  */
   Fredisplay (Qt);
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+
+#if defined USE_X_TOOLKIT || defined USE_GTK
   if (FRAME_WINDOW_P (f))
     return xw_popup_dialog (f, header, contents);
-  else
 #endif
-#if defined (HAVE_NTGUI) && defined (HAVE_DIALOGS)
+#ifdef HAVE_NTGUI
   if (FRAME_W32_P (f))
-    return w32_popup_dialog (f, header, contents);
-  else
+    {
+      Lisp_Object selection = w32_popup_dialog (f, header, contents);
+
+      if (!EQ (selection, Qunsupported__w32_dialog))
+       return selection;
+    }
 #endif
 #ifdef HAVE_NS
   if (FRAME_NS_P (f))
     return ns_popup_dialog (position, header, contents);
-  else
 #endif
   /* Display a menu with these alternatives
      in the middle of frame F.  */