]> code.delx.au - gnu-emacs/blobdiff - src/xmenu.c
Merge from emacs--devo--0
[gnu-emacs] / src / xmenu.c
index 397e8a59e817c4b9eb9f586bc8a6aa772685891c..bf9a9101ef043d0a0dd85bc2cfc21f43ed25fc5c 100644 (file)
@@ -1,12 +1,12 @@
 /* X Communication module for terminals which understand the X protocol.
    Copyright (C) 1986, 1988, 1993, 1994, 1996, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -41,10 +41,10 @@ Boston, MA 02110-1301, USA.  */
 #include <stdio.h>
 
 #include "lisp.h"
-#include "termhooks.h"
 #include "keyboard.h"
 #include "keymap.h"
 #include "frame.h"
+#include "termhooks.h"
 #include "window.h"
 #include "blockinput.h"
 #include "buffer.h"
@@ -82,7 +82,11 @@ Boston, MA 02110-1301, USA.  */
 #include <X11/StringDefs.h>
 #include <X11/Shell.h>
 #ifdef USE_LUCID
+#ifdef HAVE_XAW3D
+#include <X11/Xaw3d/Paned.h>
+#else /* !HAVE_XAW3D */
 #include <X11/Xaw/Paned.h>
+#endif /* HAVE_XAW3D */
 #endif /* USE_LUCID */
 #include "../lwlib/lwlib.h"
 #else /* not USE_X_TOOLKIT */
@@ -325,7 +329,7 @@ restore_menu_items (saved)
   menu_items_used = XINT (XCAR (saved));
   saved = XCDR (saved);
   menu_items_n_panes = XINT (XCAR (saved));
-  saved = XCDR (saved);  
+  saved = XCDR (saved);
   menu_items_submenu_depth = XINT (XCAR (saved));
   return Qnil;
 }
@@ -741,6 +745,9 @@ mouse_position_for_popup (f, x, y)
   Window root, dummy_window;
   int dummy;
 
+  if (! FRAME_X_P (f))
+    abort ();
+
   BLOCK_INPUT;
 
   XQueryPointer (FRAME_X_DISPLAY (f),
@@ -822,7 +829,7 @@ no quit occurs and `x-popup-menu' returns nil.  */)
   int xpos = 0, ypos = 0;
   Lisp_Object title;
   char *error_name = NULL;
-  Lisp_Object selection;
+  Lisp_Object selection = Qnil;
   FRAME_PTR f = NULL;
   Lisp_Object x, y, window;
   int keymaps = 0;
@@ -936,6 +943,9 @@ no quit occurs and `x-popup-menu' returns nil.  */)
       xpos += XINT (x);
       ypos += XINT (y);
 
+      if (! FRAME_X_P (f))
+        error ("Can not put X menu on non-X terminal");
+
       XSETFRAME (Vmenu_updating_frame, f);
     }
   else
@@ -1124,6 +1134,9 @@ for instance using the window manager, then this produces a quit and
        but I don't want to make one now.  */
     CHECK_WINDOW (window);
 
+  if (! FRAME_X_P (f))
+    error ("Can not put X dialog on non-X terminal");
+
 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
   /* Display a menu with these alternatives
      in the middle of frame F.  */
@@ -1305,7 +1318,7 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers)
     }
 }
 
-DEFUN ("menu-bar-open", Fmenu_bar_open, Smenu_bar_open, 0, 1, "i",
+DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_internal, 0, 1, "i",
        doc: /* Start key navigation of the menu bar in FRAME.
 This initially opens the first menu bar item and you can then navigate with the
 arrow keys, select a menu entry with the return key or cancel with the
@@ -1384,7 +1397,7 @@ If FRAME is nil or not given, use the selected frame.  */)
 
 
 #ifdef USE_GTK
-DEFUN ("menu-bar-open", Fmenu_bar_open, Smenu_bar_open, 0, 1, "i",
+DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_internal, 0, 1, "i",
        doc: /* Start key navigation of the menu bar in FRAME.
 This initially opens the first menu bar item and you can then navigate with the
 arrow keys, select a menu entry with the return key or cancel with the
@@ -1414,7 +1427,7 @@ If FRAME is nil or not given, use the selected frame.  */)
 
       gtk_menu_shell_select_item (GTK_MENU_SHELL (menubar),
                                   GTK_WIDGET (children->data));
-      
+
       popup_activated_flag = 1;
       g_list_free (children);
     }
@@ -1460,6 +1473,9 @@ void
 x_activate_menubar (f)
      FRAME_PTR f;
 {
+  if (! FRAME_X_P (f))
+    abort ();
+
   if (!f->output_data.x->saved_menu_event->type)
     return;
 
@@ -1488,23 +1504,6 @@ x_activate_menubar (f)
   f->output_data.x->saved_menu_event->type = 0;
 }
 
-/* Detect if a dialog or menu has been posted.  */
-
-int
-popup_activated ()
-{
-  return popup_activated_flag;
-}
-
-/* The following is used by delayed window autoselection.  */
-
-DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
-       doc: /* Return t if a menu or popup dialog is active.  */)
-     ()
-{
-  return (popup_activated ()) ? Qt : Qnil;
-}
-
 /* This callback is invoked when the user selects a menubar cascade
    pushbutton, but before the pulldown menu is posted.  */
 
@@ -2111,9 +2110,14 @@ update_frame_menubar (f)
 #ifdef USE_GTK
   return xg_update_frame_menubar (f);
 #else
-  struct x_output *x = f->output_data.x;
+  struct x_output *x;
   int columns, rows;
 
+  if (! FRAME_X_P (f))
+    abort ();
+
+  x = f->output_data.x;
+
   if (!x->menubar_widget || XtIsManaged (x->menubar_widget))
     return 0;
 
@@ -2159,7 +2163,7 @@ set_frame_menubar (f, first_time, deep_p)
      int first_time;
      int deep_p;
 {
-  xt_or_gtk_widget menubar_widget = f->output_data.x->menubar_widget;
+  xt_or_gtk_widget menubar_widget;
 #ifdef USE_X_TOOLKIT
   LWLIB_ID id;
 #endif
@@ -2169,6 +2173,10 @@ set_frame_menubar (f, first_time, deep_p)
   int *submenu_start, *submenu_end;
   int *submenu_top_level_items, *submenu_n_panes;
 
+  if (! FRAME_X_P (f))
+    abort ();
+
+  menubar_widget = f->output_data.x->menubar_widget;
 
   XSETFRAME (Vmenu_updating_frame, f);
 
@@ -2521,6 +2529,9 @@ free_frame_menubar (f)
 {
   Widget menubar_widget;
 
+  if (! FRAME_X_P (f))
+    abort ();
+
   menubar_widget = f->output_data.x->menubar_widget;
 
   f->output_data.x->menubar_height = 0;
@@ -2673,6 +2684,9 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
   struct next_popup_x_y popup_x_y;
   int specpdl_count = SPECPDL_INDEX ();
 
+  if (! FRAME_X_P (f))
+    abort ();
+
   xg_crazy_callback_abort = 1;
   menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
                            G_CALLBACK (popup_selection_callback),
@@ -2781,6 +2795,9 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
   LWLIB_ID menu_id;
   Widget menu;
 
+  if (! FRAME_X_P (f))
+    abort ();
+
   menu_id = widget_id_tick++;
   menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
                            f->output_data.x->widget, 1, 0,
@@ -2857,6 +2874,9 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
 
   int first_pane;
 
+  if (! FRAME_X_P (f))
+    abort ();
+
   *error = NULL;
 
   if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
@@ -3139,6 +3159,9 @@ create_and_show_dialog (f, first_wv)
 {
   GtkWidget *menu;
 
+  if (! FRAME_X_P (f))
+    abort ();
+
   menu = xg_create_widget ("dialog", first_wv->name, f, first_wv,
                            G_CALLBACK (dialog_selection_callback),
                            G_CALLBACK (popup_deactivate_callback),
@@ -3188,6 +3211,9 @@ create_and_show_dialog (f, first_wv)
 {
   LWLIB_ID dialog_id;
 
+  if (!FRAME_X_P (f))
+    abort();
+
   dialog_id = widget_id_tick++;
   lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
                     f->output_data.x->widget, 1, 0,
@@ -3240,6 +3266,9 @@ xdialog_show (f, keymaps, title, header, error_name)
   /* 1 means we've seen the boundary between left-hand elts and right-hand.  */
   int boundary_seen = 0;
 
+  if (! FRAME_X_P (f))
+    abort ();
+
   *error_name = NULL;
 
   if (menu_items_n_panes > 1)
@@ -3350,6 +3379,14 @@ xdialog_show (f, keymaps, title, header, error_name)
   /* No selection has been chosen yet.  */
   menu_item_selection = 0;
 
+  /* 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
+     is not done when a dialog is shown.  If redisplay could be done in the
+     X event loop (i.e. the X event loop does not run in a signal handler)
+     this would not be needed.  */
+  Fredisplay (Qt);
+
   /* Actually create and show the dialog.  */
   create_and_show_dialog (f, first_wv);
 
@@ -3437,7 +3474,7 @@ menu_help_callback (help_string, pane, item)
     pane_name = first_item[MENU_ITEMS_PANE_NAME];
   else if (EQ (first_item[0], Qquote))
     /* This shouldn't happen, see xmenu_show.  */
-    pane_name = empty_string;
+    pane_name = empty_unibyte_string;
   else
     pane_name = first_item[MENU_ITEMS_ITEM_NAME];
 
@@ -3507,6 +3544,9 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
   unsigned int dummy_uint;
   int specpdl_count = SPECPDL_INDEX ();
 
+  if (! FRAME_X_P (f))
+    abort ();
+
   *error = 0;
   if (menu_items_n_panes == 0)
     return Qnil;
@@ -3770,6 +3810,27 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
 #endif /* not USE_X_TOOLKIT */
 
 #endif /* HAVE_MENUS */
+
+/* Detect if a dialog or menu has been posted.  */
+
+int
+popup_activated ()
+{
+  return popup_activated_flag;
+}
+
+/* The following is used by delayed window autoselection.  */
+
+DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
+       doc: /* Return t if a menu or popup dialog is active.  */)
+     ()
+{
+#ifdef HAVE_MENUS
+  return (popup_activated ()) ? Qt : Qnil;
+#else
+  return Qnil;
+#endif /* HAVE_MENUS */
+}
 \f
 void
 syms_of_xmenu ()
@@ -3790,8 +3851,9 @@ syms_of_xmenu ()
   defsubr (&Smenu_or_popup_active_p);
 
 #if defined (USE_GTK) || defined (USE_X_TOOLKIT)
-  defsubr (&Smenu_bar_open);
-  Ffset (intern ("accelerate-menu"), intern (Smenu_bar_open.symbol_name));
+  defsubr (&Sx_menu_bar_open_internal);
+  Ffset (intern ("accelerate-menu"),
+        intern (Sx_menu_bar_open_internal.symbol_name));
 #endif
 
 #ifdef HAVE_MENUS