Promote SSDATA macro from gtkutil.c and xsmfns.c to lisp.h.
[bpt/emacs.git] / src / xmenu.c
index deb7c09..93fcf69 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
+                 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -89,7 +89,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"
@@ -110,31 +112,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 Lisp_Object Qdebug_on_next_call;
 
-extern Lisp_Object Qmenu_bar;
-
-extern Lisp_Object QCtoggle, QCradio;
-
-extern Lisp_Object Voverriding_local_map;
-extern Lisp_Object Voverriding_local_map_menu_flag;
-
-extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
-
-extern Lisp_Object Qmenu_bar_update_hook;
-
-#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 *);
@@ -145,28 +125,13 @@ 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
-
-/* This is set nonzero after the user activates the menu bar, and set
-   to zero again after the menu bars are redisplayed by prepare_menu_bar.
-   While it is nonzero, all calls to set_frame_menubar go deep.
-
-   I don't understand why this is needed, but it does seem to be
-   needed on Motif, according to Marcus Daniels <marcus@sysc.pdx.edu>.  */
-
-int pending_menu_activation;
 \f
 #ifdef USE_X_TOOLKIT
 
 /* Return the frame whose ->output_data.x->id equals ID, or 0 if none.  */
 
 static struct frame *
-menubar_id_to_frame (id)
-     LWLIB_ID id;
+menubar_id_to_frame (LWLIB_ID id)
 {
   Lisp_Object tail, frame;
   FRAME_PTR f;
@@ -260,8 +225,7 @@ otherwise it is "Question".
 If the user gets rid of the dialog box without making a valid choice,
 for instance using the window manager, then this produces a quit and
 `x-popup-dialog' does not return.  */)
-     (position, contents, header)
-     Lisp_Object position, contents, header;
+  (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
 {
   FRAME_PTR f = NULL;
   Lisp_Object window;
@@ -351,7 +315,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 ();
 
@@ -457,11 +421,7 @@ x_menu_wait_for_event (void *data)
    with BLOCK_INPUT, UNBLOCK_INPUT wrappers.  */
 
 static void
-popup_get_selection (initial_event, dpyinfo, id, do_timers)
-     XEvent *initial_event;
-     struct x_display_info *dpyinfo;
-     LWLIB_ID id;
-     int do_timers;
+popup_get_selection (XEvent *initial_event, struct x_display_info *dpyinfo, LWLIB_ID id, int do_timers)
 {
   XEvent event;
 
@@ -518,8 +478,7 @@ arrow keys, select a menu entry with the return key or cancel with the
 escape key.  If FRAME has no menu bar this function does nothing.
 
 If FRAME is nil or not given, use the selected frame.  */)
-     (frame)
-     Lisp_Object frame;
+  (Lisp_Object frame)
 {
   XEvent ev;
   FRAME_PTR f = check_x_frame (frame);
@@ -597,8 +556,7 @@ arrow keys, select a menu entry with the return key or cancel with the
 escape key.  If FRAME has no menu bar this function does nothing.
 
 If FRAME is nil or not given, use the selected frame.  */)
-     (frame)
-     Lisp_Object frame;
+  (Lisp_Object frame)
 {
   GtkWidget *menubar;
   FRAME_PTR f;
@@ -678,18 +636,14 @@ x_activate_menubar (FRAME_PTR f)
 
   set_frame_menubar (f, 0, 1);
   BLOCK_INPUT;
+  popup_activated_flag = 1;
 #ifdef USE_GTK
   XPutBackEvent (f->output_data.x->display_info->display,
                  f->output_data.x->saved_menu_event);
-  popup_activated_flag = 1;
 #else
   XtDispatchEvent (f->output_data.x->saved_menu_event);
 #endif
   UNBLOCK_INPUT;
-#ifdef USE_MOTIF
-  if (f->output_data.x->saved_menu_event->type == ButtonRelease)
-    pending_menu_activation = 1;
-#endif
 
   /* Ignore this if we get it a second time.  */
   f->output_data.x->saved_menu_event->type = 0;
@@ -700,10 +654,7 @@ x_activate_menubar (FRAME_PTR f)
 
 #ifndef USE_GTK
 static void
-popup_activate_callback (widget, id, client_data)
-     Widget widget;
-     LWLIB_ID id;
-     XtPointer client_data;
+popup_activate_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
 {
   popup_activated_flag = 1;
 #ifdef USE_X_TOOLKIT
@@ -723,10 +674,7 @@ popup_deactivate_callback (GtkWidget *widget, gpointer client_data)
 }
 #else
 static void
-popup_deactivate_callback (widget, id, client_data)
-     Widget widget;
-     LWLIB_ID id;
-     XtPointer client_data;
+popup_deactivate_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
 {
   popup_activated_flag = 0;
 }
@@ -794,10 +742,7 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data)
 }
 #else
 void
-menu_highlight_callback (widget, id, call_data)
-     Widget widget;
-     LWLIB_ID id;
-     void *call_data;
+menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data)
 {
   struct frame *f;
   Lisp_Object help;
@@ -868,10 +813,7 @@ menubar_selection_callback (GtkWidget *widget, gpointer client_data)
    Figure out what the user chose
    and put the appropriate events into the keyboard buffer.  */
 static void
-menubar_selection_callback (widget, id, client_data)
-     Widget widget;
-     LWLIB_ID id;
-     XtPointer client_data;
+menubar_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
 {
   FRAME_PTR f;
 
@@ -937,11 +879,10 @@ update_frame_menubar (FRAME_PTR f)
 
 #ifdef USE_LUCID
 static void
-apply_systemfont_to_dialog (w)
-     Widget w;
+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)
@@ -950,8 +891,7 @@ apply_systemfont_to_dialog (w)
 }
 
 static void
-apply_systemfont_to_menu (w)
-     Widget w;
+apply_systemfont_to_menu (Widget w)
 {
   const char *fn = xsettings_get_system_normal_font ();
   int defflt;
@@ -1005,8 +945,6 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
 
   if (! menubar_widget)
     deep_p = 1;
-  else if (pending_menu_activation && !deep_p)
-    deep_p = 1;
   /* Make the first call for any given frame always go deep.  */
   else if (!f->output_data.x->saved_menu_event && !deep_p)
     {
@@ -1067,8 +1005,8 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
 
       /* Save the frame's previous menu bar contents data.  */
       if (previous_menu_items_used)
-       bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
-              previous_menu_items_used * sizeof (Lisp_Object));
+       memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
+               previous_menu_items_used * sizeof (Lisp_Object));
 
       /* Fill in menu_items with the current menu bar contents.
         This can evaluate Lisp code.  */
@@ -1168,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;
        }
@@ -1197,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;
@@ -1282,11 +1220,17 @@ 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
     }
 
   {
-    int menubar_size
+    int menubar_size;
+    if (f->output_data.x->menubar_widget)
+      XtRealizeWidget (f->output_data.x->menubar_widget);
+
+    menubar_size
       = (f->output_data.x->menubar_widget
         ? (f->output_data.x->menubar_widget->core.height
            + f->output_data.x->menubar_widget->core.border_width)
@@ -1295,7 +1239,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
 #if 1 /* Experimentally, we now get the right results
         for -geometry -0-0 without this.  24 Aug 96, rms.
          Maybe so, but the menu bar size is missing the pixels so the
-         WM size hints are off by theses pixel.  Jan D, oct 2009.  */
+         WM size hints are off by these pixels.  Jan D, oct 2009.  */
 #ifdef USE_LUCID
     if (FRAME_EXTERNAL_MENU_BAR (f))
       {
@@ -1342,8 +1286,7 @@ initialize_frame_menubar (FRAME_PTR f)
 
 #ifndef USE_GTK
 void
-free_frame_menubar (f)
-     FRAME_PTR f;
+free_frame_menubar (FRAME_PTR f)
 {
   Widget menubar_widget;
 
@@ -1378,15 +1321,15 @@ free_frame_menubar (f)
       lw_destroy_all_widgets ((LWLIB_ID) f->output_data.x->id);
       f->output_data.x->menubar_widget = NULL;
 
-#ifdef USE_MOTIF
       if (f->output_data.x->widget)
        {
+#ifdef USE_MOTIF
          XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL);
          if (x1 == 0 && y1 == 0)
            XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL);
-       }
 #endif
-
+          x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+       }
       UNBLOCK_INPUT;
     }
 }
@@ -1559,10 +1502,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, i
 LWLIB_ID widget_id_tick;
 
 static void
-popup_selection_callback (widget, id, client_data)
-     Widget widget;
-     LWLIB_ID id;
-     XtPointer client_data;
+popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
 {
   menu_item_selection = (Lisp_Object *) client_data;
 }
@@ -1571,8 +1511,7 @@ popup_selection_callback (widget, id, client_data)
    as a Lisp object as (HIGHPART . LOWPART).  */
 
 static Lisp_Object
-pop_down_menu (arg)
-     Lisp_Object arg;
+pop_down_menu (Lisp_Object arg)
 {
   LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
                  | XINT (XCDR (arg)));
@@ -1589,13 +1528,8 @@ pop_down_menu (arg)
    menu pops down.
    menu_item_selection will be set to the selection.  */
 static void
-create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp)
-     FRAME_PTR f;
-     widget_value *first_wv;
-     int x;
-     int y;
-     int for_click;
-     EMACS_UINT timestamp;
+create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
+                           int x, int y, int for_click, EMACS_UINT timestamp)
 {
   int i;
   Arg av[2];
@@ -1614,7 +1548,9 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp)
                            popup_deactivate_callback,
                            menu_highlight_callback);
 
+#ifdef USE_LUCID
   apply_systemfont_to_menu (menu);
+#endif
 
   dummy.type = ButtonPress;
   dummy.serial = 0;
@@ -1667,7 +1603,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp)
 
 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)
 {
   int i;
   widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
@@ -1731,7 +1667,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);
@@ -1744,7 +1680,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)
@@ -1809,9 +1745,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
@@ -1862,7 +1798,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;
@@ -1985,10 +1921,7 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
 
 #else /* not USE_GTK */
 static void
-dialog_selection_callback (widget, id, client_data)
-     Widget widget;
-     LWLIB_ID id;
-     XtPointer client_data;
+dialog_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
 {
   /* The EMACS_INT cast avoids a warning.  There's no problem
      as long as pointers have enough bits to hold small integers.  */
@@ -2006,9 +1939,7 @@ dialog_selection_callback (widget, id, client_data)
    dialog pops down.
    menu_item_selection will be set to the selection.  */
 static void
-create_and_show_dialog (f, first_wv)
-     FRAME_PTR f;
-     widget_value *first_wv;
+create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
 {
   LWLIB_ID dialog_id;
 
@@ -2016,7 +1947,7 @@ create_and_show_dialog (f, first_wv)
     abort();
 
   dialog_id = widget_id_tick++;
-#ifdef HAVE_XFT
+#ifdef USE_LUCID
   apply_systemfont_to_dialog (f->output_data.x->widget);
 #endif
   lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
@@ -2048,12 +1979,16 @@ create_and_show_dialog (f, 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];
@@ -2080,11 +2015,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))
@@ -2131,8 +2066,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;
@@ -2251,11 +2186,8 @@ static struct frame *menu_help_frame;
    keyboard events.  */
 
 static void
-menu_help_callback (help_string, pane, item)
-     char *help_string;
-     int pane, item;
+menu_help_callback (char *help_string, int pane, int item)
 {
-  extern Lisp_Object Qmenu_item;
   Lisp_Object *first_item;
   Lisp_Object pane_name;
   Lisp_Object menu_object;
@@ -2278,8 +2210,7 @@ menu_help_callback (help_string, pane, item)
 }
 
 static Lisp_Object
-pop_down_menu (arg)
-     Lisp_Object arg;
+pop_down_menu (Lisp_Object arg)
 {
   struct Lisp_Save_Value *p1 = XSAVE_VALUE (Fcar (arg));
   struct Lisp_Save_Value *p2 = XSAVE_VALUE (Fcdr (arg));
@@ -2314,14 +2245,8 @@ pop_down_menu (arg)
 
 
 Lisp_Object
-xmenu_show (f, x, y, for_click, keymaps, title, error, timestamp)
-     FRAME_PTR f;
-     int x, y;
-     int for_click;
-     int keymaps;
-     Lisp_Object title;
-     char **error;
-     EMACS_UINT timestamp;
+xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
+           Lisp_Object title, const char **error, EMACS_UINT timestamp)
 {
   Window root;
   XMenu *menu;
@@ -2392,7 +2317,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error, timestamp)
          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++;
 
@@ -2452,12 +2377,10 @@ xmenu_show (f, x, y, for_click, keymaps, title, error, timestamp)
              item_data
                = (unsigned char *) alloca (maxwidth
                                            + SBYTES (descrip) + 1);
-             bcopy (SDATA (item_name), item_data,
-                    SBYTES (item_name));
+             memcpy (item_data, SDATA (item_name), SBYTES (item_name));
              for (j = SCHARS (item_name); j < maxwidth; j++)
                item_data[j] = ' ';
-             bcopy (SDATA (descrip), item_data + j,
-                    SBYTES (descrip));
+             memcpy (item_data + j, SDATA (descrip), SBYTES (descrip));
              item_data[j + SBYTES (descrip)] = 0;
            }
          else
@@ -2612,19 +2535,22 @@ xmenu_show (f, x, y, for_click, keymaps, title, error, timestamp)
 
 #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.  */
 
 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.  */)
-     ()
+  (void)
 {
 #ifdef HAVE_MENUS
   return (popup_activated ()) ? Qt : Qnil;
@@ -2656,6 +2582,3 @@ syms_of_xmenu (void)
   defsubr (&Sx_popup_dialog);
 #endif
 }
-
-/* arch-tag: 92ea573c-398e-496e-ac73-2436f7d63242
-   (do not change this comment) */