Fixes: debbugs:17865
[bpt/emacs.git] / src / menu.c
index d87d495..468f281 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-2014 Free Software
 Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -55,7 +55,7 @@ extern HMENU current_popup_menu;
 static bool
 have_boxes (void)
 {
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI) || defined(HAVE_NS)
   if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame)))
     return 1;
 #endif
@@ -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 (" >"));
@@ -1178,7 +1179,6 @@ no quit occurs and `x-popup-menu' returns nil.  */)
        keybinding equivalents, but we don't do that any more anyway.  */
     return Qnil;
 
-#ifdef HAVE_MENUS
   {
     bool get_current_pos_p = 0;
 
@@ -1315,7 +1315,6 @@ no quit occurs and `x-popup-menu' returns nil.  */)
 
     XSETFRAME (Vmenu_updating_frame, f);
   }
-#endif /* HAVE_MENUS */
 
   /* Now parse the lisp menus.  */
   record_unwind_protect_void (unuse_menu_items);
@@ -1398,7 +1397,6 @@ no quit occurs and `x-popup-menu' returns nil.  */)
 
   unbind_to (specpdl_count, Qnil);
 
-#ifdef HAVE_MENUS
 #ifdef HAVE_WINDOW_SYSTEM
   /* Hide a previous tip, if any.  */
   if (!FRAME_TERMCAP_P (f))
@@ -1445,9 +1443,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);
@@ -1460,16 +1468,12 @@ no quit occurs and `x-popup-menu' returns nil.  */)
     FRAME_DISPLAY_INFO (f)->grabbed = 0;
 #endif
 
-#endif /* HAVE_MENUS */
-
   UNGCPRO;
 
   if (error_name) error ("%s", error_name);
   return selection;
 }
 
-#ifdef HAVE_MENUS
-
 DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
        doc: /* Pop up a dialog box and return user's selection.
 POSITION specifies which frame to use.
@@ -1560,20 +1564,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.  */
@@ -1605,8 +1612,6 @@ for instance using the window manager, then this produces a quit and
   }
 }
 
-#endif /* HAVE_MENUS */
-
 void
 syms_of_menu (void)
 {
@@ -1615,9 +1620,6 @@ syms_of_menu (void)
   menu_items_inuse = Qnil;
 
   defsubr (&Sx_popup_menu);
-
-#ifdef HAVE_MENUS
   defsubr (&Sx_popup_dialog);
-#endif
   defsubr (&Smenu_bar_menu_at_x_y);
 }