Undo the DEFUN->DEFUE change.
[bpt/emacs.git] / src / xmenu.c
index a04eb25..6e84b84 100644 (file)
@@ -1,6 +1,7 @@
 /* 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, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2011
+  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -89,6 +90,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <X11/Xaw/Paned.h>
 #endif /* HAVE_XAW3D */
 #endif /* USE_LUCID */
+#ifdef USE_MOTIF
+#include "../lwlib/lwlib.h"
+#endif
 #else /* not USE_X_TOOLKIT */
 #ifndef USE_GTK
 #include "../oldXMenu/XMenu.h"
@@ -107,30 +111,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define FALSE 0
 #endif /* no TRUE */
 
-Lisp_Object Qdebug_on_next_call;
-
-extern Lisp_Object Qmenu_bar;
-
-extern Lisp_Object QCtoggle, QCradio;
-
-extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
-
-extern Lisp_Object Qmenu_bar_update_hook;
+static Lisp_Object Qdebug_on_next_call;
 
-#ifdef USE_X_TOOLKIT
-extern void set_frame_menubar (FRAME_PTR, int, int);
-extern XtAppContext Xt_app_con;
-
-static Lisp_Object xdialog_show (FRAME_PTR, int, Lisp_Object, Lisp_Object,
-                                 char **);
-static void popup_get_selection (XEvent *, struct x_display_info *,
-                                 LWLIB_ID, int);
-#endif /* USE_X_TOOLKIT */
-
-#ifdef USE_GTK
-extern void set_frame_menubar (FRAME_PTR, int, int);
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 static Lisp_Object xdialog_show (FRAME_PTR, int, Lisp_Object, Lisp_Object,
-                                 char **);
+                                 const char **);
 #endif
 
 static int update_frame_menubar (struct frame *);
@@ -139,17 +124,11 @@ static int update_frame_menubar (struct frame *);
    Xt on behalf of one of the widget sets.  */
 static int popup_activated_flag;
 
-static int next_menubar_widget_id;
-
-/* For NS and NTGUI, these prototypes are defined in keyboard.h.  */
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
-extern widget_value *xmalloc_widget_value (void);
-extern widget_value *digest_single_submenu (int, int, int);
-#endif
-
 \f
 #ifdef USE_X_TOOLKIT
 
+static int next_menubar_widget_id;
+
 /* Return the frame whose ->output_data.x->id equals ID, or 0 if none.  */
 
 static struct frame *
@@ -337,7 +316,7 @@ for instance using the window manager, then this produces a quit and
 #else
   {
     Lisp_Object title;
-    char *error_name;
+    const char *error_name;
     Lisp_Object selection;
     int specpdl_count = SPECPDL_INDEX ();
 
@@ -362,7 +341,7 @@ for instance using the window manager, then this produces a quit and
     unbind_to (specpdl_count, Qnil);
     discard_menu_items ();
 
-    if (error_name) error (error_name);
+    if (error_name) error ("%s", error_name);
     return selection;
   }
 #endif
@@ -386,6 +365,9 @@ x_menu_set_in_use (int in_use)
 
 /* Wait for an X event to arrive or for a timer to expire.  */
 
+#ifndef USE_MOTIF
+static
+#endif
 void
 x_menu_wait_for_event (void *data)
 {
@@ -404,7 +386,7 @@ x_menu_wait_for_event (void *data)
 #endif
          )
     {
-      EMACS_TIME next_time = timer_check (1), *ntp;
+      EMACS_TIME next_time = timer_check (), *ntp;
       long secs = EMACS_SECS (next_time);
       long usecs = EMACS_USECS (next_time);
       SELECT_TYPE read_fds;
@@ -733,7 +715,7 @@ show_help_event (FRAME_PTR f, xt_or_gtk_widget widget, Lisp_Object help)
            break;
        }
 #endif
-      show_help_echo (help, Qnil, Qnil, Qnil, 1);
+      show_help_echo (help, Qnil, Qnil, Qnil);
     }
 }
 
@@ -744,7 +726,7 @@ show_help_event (FRAME_PTR f, xt_or_gtk_widget widget, Lisp_Object help)
    unhighlighting.  */
 
 #ifdef USE_GTK
-void
+static void
 menu_highlight_callback (GtkWidget *widget, gpointer call_data)
 {
   xg_menu_item_cb_data *cb_data;
@@ -763,7 +745,7 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data)
     show_help_event (cb_data->cl_data->f, widget, help);
 }
 #else
-void
+static void
 menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data)
 {
   struct frame *f;
@@ -904,35 +886,30 @@ static void
 apply_systemfont_to_dialog (Widget w)
 {
   const char *fn = xsettings_get_system_normal_font ();
-  if (fn) 
+  if (fn)
     {
       XrmDatabase db = XtDatabase (XtDisplay (w));
       if (db)
-        XrmPutStringResource (&db, "*dialog.faceName", fn);
+        XrmPutStringResource (&db, "*dialog.font", fn);
     }
 }
 
 static void
-apply_systemfont_to_menu (Widget w)
+apply_systemfont_to_menu (struct frame *f, Widget w)
 {
   const char *fn = xsettings_get_system_normal_font ();
-  int defflt;
 
-  if (!fn) return;
-
-  if (XtIsShell (w)) /* popup menu */
+  if (fn)
     {
-      Widget *childs = NULL;
-
-      XtVaGetValues (w, XtNchildren, &childs, NULL);
-      if (*childs) w = *childs;
+      XrmDatabase db = XtDatabase (XtDisplay (w));
+      if (db)
+        {
+          XrmPutStringResource (&db, "*menubar*font", fn);
+          XrmPutStringResource (&db, "*popup*font", fn);
+        }
     }
-
-  /* Only use system font if the default is used for the menu.  */
-  XtVaGetValues (w, XtNdefaultFace, &defflt, NULL);
-  if (defflt)
-    XtVaSetValues (w, XtNfaceName, fn, NULL);
 }
+
 #endif
 
 /* Set the contents of the menubar widgets of frame F.
@@ -948,7 +925,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
 #endif
   Lisp_Object items;
   widget_value *wv, *first_wv, *prev_wv = 0;
-  int i, last_i = 0;
+  EMACS_UINT i, last_i = 0;
   int *submenu_start, *submenu_end;
   int *submenu_top_level_items, *submenu_n_panes;
 
@@ -992,6 +969,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
       Lisp_Object *previous_items
        = (Lisp_Object *) alloca (previous_menu_items_used
                                  * sizeof (Lisp_Object));
+      EMACS_UINT subitems;
 
       /* If we are making a new widget, its contents are empty,
         do always reinitialize them.  */
@@ -1036,21 +1014,21 @@ 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;
-      submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
-      submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
-      submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
-      submenu_top_level_items
-       = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
+      subitems = XVECTOR (items)->size / 4;
+      submenu_start = (int *) alloca (subitems * 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 *));
       init_menu_items ();
-      for (i = 0; i < XVECTOR (items)->size; i += 4)
+      for (i = 0; i < subitems; i++)
        {
          Lisp_Object key, string, maps;
 
          last_i = i;
 
-         key = XVECTOR (items)->contents[i];
-         string = XVECTOR (items)->contents[i + 1];
-         maps = XVECTOR (items)->contents[i + 2];
+         key = XVECTOR (items)->contents[4 * i];
+         string = XVECTOR (items)->contents[4 * i + 1];
+         maps = XVECTOR (items)->contents[4 * i + 2];
          if (NILP (string))
            break;
 
@@ -1077,7 +1055,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
       wv->help = Qnil;
       first_wv = wv;
 
-      for (i = 0; i < last_i; i += 4)
+      for (i = 0; i < last_i; i++)
        {
          menu_items_n_panes = submenu_n_panes[i];
          wv = digest_single_submenu (submenu_start[i], submenu_end[i],
@@ -1128,7 +1106,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
          string = XVECTOR (items)->contents[i + 1];
          if (NILP (string))
             break;
-          wv->name = (char *) SDATA (string);
+          wv->name = SSDATA (string);
           update_submenu_strings (wv->contents);
           wv = wv->next;
        }
@@ -1157,7 +1135,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
            break;
 
          wv = xmalloc_widget_value ();
-         wv->name = (char *) SDATA (string);
+         wv->name = SSDATA (string);
          wv->value = 0;
          wv->enabled = 1;
          wv->button_type = BUTTON_TYPE_NONE;
@@ -1201,8 +1179,6 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
     }
   else
     {
-      GtkWidget *wvbox = f->output_data.x->vbox_widget;
-
       menubar_widget
         = xg_create_widget ("menubar", "menubar", f, first_wv,
                             G_CALLBACK (menubar_selection_callback),
@@ -1231,7 +1207,11 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
       char menuOverride[] = "Ctrl<KeyPress>g: MenuGadgetEscape()";
       XtTranslations  override = XtParseTranslationTable (menuOverride);
 
-      menubar_widget = lw_create_widget ("menubar", "menubar", id, first_wv,
+#ifdef USE_LUCID
+      apply_systemfont_to_menu (f, f->output_data.x->column_widget);
+#endif
+      menubar_widget = lw_create_widget ("menubar", "menubar", id,
+                                         first_wv,
                                         f->output_data.x->column_widget,
                                         0,
                                         popup_activate_callback,
@@ -1242,9 +1222,6 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
 
       /* Make menu pop down on C-g.  */
       XtOverrideTranslations (menubar_widget, override);
-#ifdef USE_LUCID
-      apply_systemfont_to_menu (menubar_widget);
-#endif
     }
 
   {
@@ -1415,7 +1392,7 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer
 
   /* Check if there is room for the menu.  If not, adjust x/y so that
      the menu is fully visible.  */
-  gtk_widget_size_request (GTK_WIDGET (menu), &req);
+  gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &req);
   if (data->x + req.width > disp_width)
     *x -= data->x + req.width - disp_width;
   if (data->y + req.height > disp_height)
@@ -1556,13 +1533,18 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
   int i;
   Arg av[2];
   int ac = 0;
-  XButtonPressedEvent dummy;
+  XEvent dummy;
+  XButtonPressedEvent *event = &(dummy.xbutton);
   LWLIB_ID menu_id;
   Widget menu;
 
   if (! FRAME_X_P (f))
     abort ();
 
+#ifdef USE_LUCID
+  apply_systemfont_to_menu (f, f->output_data.x->widget);
+#endif
+
   menu_id = widget_id_tick++;
   menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
                            f->output_data.x->widget, 1, 0,
@@ -1570,40 +1552,35 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
                            popup_deactivate_callback,
                            menu_highlight_callback);
 
-#ifdef USE_LUCID
-  apply_systemfont_to_menu (menu);
-#endif
-
-  dummy.type = ButtonPress;
-  dummy.serial = 0;
-  dummy.send_event = 0;
-  dummy.display = FRAME_X_DISPLAY (f);
-  dummy.time = CurrentTime;
-  dummy.root = FRAME_X_DISPLAY_INFO (f)->root_window;
-  dummy.window = dummy.root;
-  dummy.subwindow = dummy.root;
-  dummy.x = x;
-  dummy.y = y;
+  event->type = ButtonPress;
+  event->serial = 0;
+  event->send_event = 0;
+  event->display = FRAME_X_DISPLAY (f);
+  event->time = CurrentTime;
+  event->root = FRAME_X_DISPLAY_INFO (f)->root_window;
+  event->window = event->subwindow = event->root;
+  event->x = x;
+  event->y = y;
 
   /* Adjust coordinates to be root-window-relative.  */
   x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
   y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
 
-  dummy.x_root = x;
-  dummy.y_root = y;
+  event->x_root = x;
+  event->y_root = y;
 
-  dummy.state = 0;
-  dummy.button = 0;
+  event->state = 0;
+  event->button = 0;
   for (i = 0; i < 5; i++)
     if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
-      dummy.button = i;
+      event->button = i;
 
   /* Don't allow any geometry request from the user.  */
   XtSetArg (av[ac], XtNgeometry, 0); ac++;
   XtSetValues (menu, av, ac);
 
   /* Display the menu.  */
-  lw_popup_menu (menu, (XEvent *) &dummy);
+  lw_popup_menu (menu, &dummy);
   popup_activated_flag = 1;
   x_activate_timeout_atimer ();
 
@@ -1625,7 +1602,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
 
 Lisp_Object
 xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
-           Lisp_Object title, char **error, EMACS_UINT timestamp)
+           Lisp_Object title, const char **error_name, EMACS_UINT timestamp)
 {
   int i;
   widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
@@ -1640,11 +1617,11 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
   if (! FRAME_X_P (f))
     abort ();
 
-  *error = NULL;
+  *error_name = NULL;
 
   if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
     {
-      *error = "Empty menu";
+      *error_name = "Empty menu";
       return Qnil;
     }
 
@@ -1689,7 +1666,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
        {
          /* Create a new pane.  */
          Lisp_Object pane_name, prefix;
-         char *pane_string;
+         const char *pane_string;
 
          pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
          prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
@@ -1702,7 +1679,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
            }
 #endif
          pane_string = (NILP (pane_name)
-                        ? "" : (char *) SDATA (pane_name));
+                        ? "" : SSDATA (pane_name));
          /* If there is just one top-level pane, put all its items directly
             under the top-level menu.  */
          if (menu_items_n_panes == 1)
@@ -1767,9 +1744,9 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
            prev_wv->next = wv;
          else
            save_wv->contents = wv;
-         wv->name = (char *) SDATA (item_name);
+         wv->name = SSDATA (item_name);
          if (!NILP (descrip))
-           wv->key = (char *) SDATA (descrip);
+           wv->key = SSDATA (descrip);
          wv->value = 0;
          /* If this item has a null value,
             make the call_data null so that it won't display a box
@@ -1820,7 +1797,7 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
        title = ENCODE_MENU_STRING (title);
 #endif
 
-      wv_title->name = (char *) SDATA (title);
+      wv_title->name = SSDATA (title);
       wv_title->enabled = TRUE;
       wv_title->button_type = BUTTON_TYPE_NONE;
       wv_title->help = Qnil;
@@ -2001,12 +1978,16 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
 
 #endif /* not USE_GTK */
 
-static char * button_names [] = {
+static const char * button_names [] = {
   "button1", "button2", "button3", "button4", "button5",
   "button6", "button7", "button8", "button9", "button10" };
 
 static Lisp_Object
-xdialog_show (FRAME_PTR f, int keymaps, Lisp_Object title, Lisp_Object header, char **error_name)
+xdialog_show (FRAME_PTR f,
+              int keymaps,
+              Lisp_Object title,
+              Lisp_Object header,
+              const char **error_name)
 {
   int i, nb_buttons=0;
   char dialog_name[6];
@@ -2033,11 +2014,11 @@ xdialog_show (FRAME_PTR f, int keymaps, Lisp_Object title, Lisp_Object header, c
      representing the text label and buttons.  */
   {
     Lisp_Object pane_name, prefix;
-    char *pane_string;
+    const char *pane_string;
     pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME];
     prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX];
     pane_string = (NILP (pane_name)
-                  ? "" : (char *) SDATA (pane_name));
+                  ? "" : SSDATA (pane_name));
     prev_wv = xmalloc_widget_value ();
     prev_wv->value = pane_string;
     if (keymaps && !NILP (prefix))
@@ -2084,8 +2065,8 @@ xdialog_show (FRAME_PTR f, int keymaps, Lisp_Object title, Lisp_Object header, c
        prev_wv->next = wv;
        wv->name = (char *) button_names[nb_buttons];
        if (!NILP (descrip))
-         wv->key = (char *) SDATA (descrip);
-       wv->value = (char *) SDATA (item_name);
+         wv->key = SSDATA (descrip);
+       wv->value = SSDATA (item_name);
        wv->call_data = (void *) &XVECTOR (menu_items)->contents[i];
        wv->enabled = !NILP (enable);
        wv->help = Qnil;
@@ -2224,7 +2205,7 @@ menu_help_callback (char *help_string, int pane, int item)
                       Fcons (pane_name,
                              Fcons (make_number (pane), Qnil)));
   show_help_echo (help_string ? build_string (help_string) : Qnil,
-                 Qnil, menu_object, make_number (item), 1);
+                 Qnil, menu_object, make_number (item));
 }
 
 static Lisp_Object
@@ -2264,7 +2245,7 @@ pop_down_menu (Lisp_Object arg)
 
 Lisp_Object
 xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
-           Lisp_Object title, char **error, EMACS_UINT timestamp)
+           Lisp_Object title, const char **error, EMACS_UINT timestamp)
 {
   Window root;
   XMenu *menu;
@@ -2328,14 +2309,14 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
        {
          /* Create a new pane.  */
          Lisp_Object pane_name, prefix;
-         char *pane_string;
+         const char *pane_string;
 
           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_string = (NILP (pane_name)
-                        ? "" : (char *) SDATA (pane_name));
+                        ? "" : SSDATA (pane_name));
          if (keymaps && !NILP (prefix))
            pane_string++;
 
@@ -2553,13 +2534,16 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
 
 #endif /* HAVE_MENUS */
 
-/* Detect if a dialog or menu has been posted.  */
+#ifndef MSDOS
+/* Detect if a dialog or menu has been posted.  MSDOS has its own
+   implementation on msdos.c.  */
 
 int
 popup_activated (void)
 {
   return popup_activated_flag;
 }
+#endif /* not MSDOS */
 
 /* The following is used by delayed window autoselection.  */
 
@@ -2597,6 +2581,3 @@ syms_of_xmenu (void)
   defsubr (&Sx_popup_dialog);
 #endif
 }
-
-/* arch-tag: 92ea573c-398e-496e-ac73-2436f7d63242
-   (do not change this comment) */