#ifdef HAVE_X_WINDOWS
#undef HAVE_MULTILINGUAL_MENU
#ifdef USE_X_TOOLKIT
+#include "widget.h"
#include <X11/Xlib.h>
#include <X11/IntrinsicP.h>
#include <X11/CoreP.h>
static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object));
-static Lisp_Object xmenu_show ();
-static void keymap_panes ();
-static void single_keymap_panes ();
-static void single_menu_item ();
-static void list_of_panes ();
-static void list_of_items ();
+static int update_frame_menubar P_ ((struct frame *));
+static Lisp_Object xmenu_show P_ ((struct frame *, int, int, int, int,
+ Lisp_Object, char **));
+static void keymap_panes P_ ((Lisp_Object *, int, int));
+static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
+ int, int));
+static void single_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object *,
+ int, int, int *));
+static void list_of_panes P_ ((Lisp_Object));
+static void list_of_items P_ ((Lisp_Object));
\f
/* This holds a Lisp vector that holds the results of decoding
the keymaps or alist-of-alists that specify a menu.
/* Create a new pane. */
Lisp_Object pane_name, prefix;
char *pane_string;
+
pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+
#ifndef HAVE_MULTILINGUAL_MENU
if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
- pane_name = string_make_unibyte (pane_name);
+ {
+ pane_name = string_make_unibyte (pane_name);
+ AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
+ }
#endif
pane_string = (NILP (pane_name)
? "" : (char *) XSTRING (pane_name)->data);
Lisp_Object item_name, enable, descrip, def, type, selected;
Lisp_Object help;
- item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
- enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
- descrip
- = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
- def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION];
- type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE];
- selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED];
- help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
+ item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+ enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
+ descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+ def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
+ type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
+ selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
+ help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
#ifndef HAVE_MULTILINGUAL_MENU
if (STRING_MULTIBYTE (item_name))
- item_name = string_make_unibyte (item_name);
+ {
+ item_name = string_make_unibyte (item_name);
+ AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
+ }
+
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
- descrip = string_make_unibyte (descrip);
-#endif
+ {
+ descrip = string_make_unibyte (descrip);
+ AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
+ }
+#endif /* not HAVE_MULTILINGUAL_MENU */
wv = xmalloc_widget_value ();
if (prev_wv)
return first_wv;
}
-\f
-extern void EmacsFrameSetCharSize ();
-/* Recompute all the widgets of frame F, when the menu bar
- has been changed. */
-static void
+\f
+/* Recompute all the widgets of frame F, when the menu bar has been
+ changed. Value is non-zero if widgets were updated. */
+
+static int
update_frame_menubar (f)
FRAME_PTR f;
{
struct x_output *x = f->output_data.x;
int columns, rows;
- int menubar_changed;
- /* We assume the menubar contents has changed if the global flag is set,
- or if the current buffer has changed, or if the menubar has never
- been updated before.
- */
- menubar_changed = (x->menubar_widget
- && !XtIsManaged (x->menubar_widget));
-
- if (! (menubar_changed))
- return;
+ if (!x->menubar_widget || XtIsManaged (x->menubar_widget))
+ return 0;
BLOCK_INPUT;
- /* Save the size of the frame because the pane widget doesn't accept to
- resize itself. So force it. */
+ /* Save the size of the frame because the pane widget doesn't accept
+ to resize itself. So force it. */
columns = f->width;
rows = f->height;
- /* Do the voodoo which means "I'm changing lots of things, don't try to
- refigure sizes until I'm done." */
+ /* Do the voodoo which means "I'm changing lots of things, don't try
+ to refigure sizes until I'm done." */
lw_refigure_widget (x->column_widget, False);
- /* the order in which children are managed is the top to
- bottom order in which they are displayed in the paned window.
- First, remove the text-area widget.
- */
+ /* The order in which children are managed is the top to bottom
+ order in which they are displayed in the paned window. First,
+ remove the text-area widget. */
XtUnmanageChild (x->edit_widget);
- /* remove the menubar that is there now, and put up the menubar that
- should be there.
- */
- if (menubar_changed)
- {
- XtManageChild (x->menubar_widget);
- XtMapWidget (x->menubar_widget);
- XtVaSetValues (x->menubar_widget, XtNmappedWhenManaged, 1, NULL);
- }
+ /* Remove the menubar that is there now, and put up the menubar that
+ should be there. */
+ XtManageChild (x->menubar_widget);
+ XtMapWidget (x->menubar_widget);
+ XtVaSetValues (x->menubar_widget, XtNmappedWhenManaged, 1, NULL);
/* Re-manage the text-area widget, and then thrash the sizes. */
XtManageChild (x->edit_widget);
- x_set_menu_resources_from_menu_face (f, x->menubar_widget);
lw_refigure_widget (x->column_widget, True);
/* Force the pane widget to resize itself with the right values. */
EmacsFrameSetCharSize (x->edit_widget, columns, rows);
UNBLOCK_INPUT;
+ return 1;
}
/* Set the contents of the menubar widgets of frame F.
set_frame_menubar (f, 1, 1);
}
+
/* Get rid of the menu bar of frame F, and free its storage.
This is used when deleting a frame, and when turning off the menu bar. */
if (menubar_widget)
{
+#ifdef USE_MOTIF
+ /* Removing the menu bar magically changes the shell widget's x
+ and y position of (0, 0) which, when the menu bar is turned
+ on again, leads to pull-down menuss appearing in strange
+ positions near the upper-left corner of the display. This
+ happens only with some window managers like twm and ctwm,
+ but not with other like Motif's mwm or kwm, because the
+ latter generate ConfigureNotify events when the menu bar
+ is switched off, which fixes the shell position. */
+ Position x0, y0, x1, y1;
+#endif
+
BLOCK_INPUT;
+
+#ifdef USE_MOTIF
+ if (f->output_data.x->widget)
+ XtVaGetValues (f->output_data.x->widget, XtNx, &x0, XtNy, &y0, NULL);
+#endif
+
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)
+ {
+ 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
+
UNBLOCK_INPUT;
}
}
/* Create a new pane. */
Lisp_Object pane_name, prefix;
char *pane_string;
- pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
- prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+
+ pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
+ prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
+
#ifndef HAVE_MULTILINGUAL_MENU
- if (!NILP (pane_name) && STRING_MULTIBYTE (pane_name))
- pane_name = string_make_unibyte (pane_name);
+ if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
+ {
+ pane_name = string_make_unibyte (pane_name);
+ AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
+ }
#endif
pane_string = (NILP (pane_name)
? "" : (char *) XSTRING (pane_name)->data);
{
/* Create a new item within current pane. */
Lisp_Object item_name, enable, descrip, def, type, selected, help;
- item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
- enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
- descrip
- = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
- def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION];
- type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE];
- selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED];
- help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
+ item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+ enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
+ descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+ def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
+ type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
+ selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
+ help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
#ifndef HAVE_MULTILINGUAL_MENU
if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
- item_name = string_make_unibyte (item_name);
+ {
+ item_name = string_make_unibyte (item_name);
+ AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name;
+ }
+
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
- item_name = string_make_unibyte (descrip);
-#endif
+ {
+ descrip = string_make_unibyte (descrip);
+ AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
+ }
+#endif /* not HAVE_MULTILINGUAL_MENU */
wv = xmalloc_widget_value ();
if (prev_wv)
if (STRING_MULTIBYTE (title))
title = string_make_unibyte (title);
#endif
+
wv_title->name = (char *) XSTRING (title)->data;
wv_title->enabled = True;
wv_title->button_type = BUTTON_TYPE_NONE;
/* Free the widget_value objects we used to specify the contents. */
free_menubar_widget_value_tree (first_wv);
- /* Override any default settings with ones from the `menu' face. */
- x_set_menu_resources_from_menu_face (f, menu);
-
/* No selection has been chosen yet. */
menu_item_selection = 0;
/* All set and ready to fly. */
XMenuRecompute (FRAME_X_DISPLAY (f), menu);
- dispwidth = DisplayWidth (FRAME_X_DISPLAY (f),
- XScreenNumberOfScreen (FRAME_X_SCREEN (f)));
- dispheight = DisplayHeight (FRAME_X_DISPLAY (f),
- XScreenNumberOfScreen (FRAME_X_SCREEN (f)));
+ dispwidth = DisplayWidth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f));
+ dispheight = DisplayHeight (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f));
x = min (x, dispwidth);
y = min (y, dispheight);
x = max (x, 1);