/* X Communication module for terminals which understand the X protocol.
- Copyright (C) 1986, 88, 93, 94, 96, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1986, 88, 93, 94, 96, 99, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* X pop-up deck-of-cards menu facility for gnuemacs.
+/* X pop-up deck-of-cards menu facility for GNU Emacs.
*
* Written by Jon Arnold and Roman Budzianowski
* Mods and rewrite by Robert Krawitz
#include <signal.h>
#include <stdio.h>
+
#include "lisp.h"
#include "termhooks.h"
+#include "keyboard.h"
+#include "keymap.h"
#include "frame.h"
#include "window.h"
-#include "keyboard.h"
#include "blockinput.h"
#include "buffer.h"
+#include "charset.h"
+#include "coding.h"
#ifdef MSDOS
#include "msdos.h"
#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>
#endif /* not USE_X_TOOLKIT */
#endif /* HAVE_X_WINDOWS */
-#ifdef USE_MOTIF
-#include <Xm/Xm.h> /* for LESSTIF_VERSION */
-#endif
-
-#define min(x,y) (((x) < (y)) ? (x) : (y))
-#define max(x,y) (((x) > (y)) ? (x) : (y))
-
#ifndef TRUE
#define TRUE 1
#define FALSE 0
static Lisp_Object xdialog_show ();
void popup_get_selection ();
-#endif
-#ifdef USE_X_TOOLKIT
-
-/* Define HAVE_BOXES if meus can handle radio and toggle buttons. */
+/* Define HAVE_BOXES if menus can handle radio and toggle buttons. */
#define HAVE_BOXES 1
#endif
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.
menu_items_submenu_depth = 0;
}
-/* Call at the end of generating the data in menu_items.
- This fills in the number of items in the last pane. */
+/* Call at the end of generating the data in menu_items. */
static void
finish_menu_items ()
XVECTOR (menu_items)->contents[menu_items_used++] = Qquote;
}
-/* Start a new menu pane in menu_items..
+/* Start a new menu pane in menu_items.
NAME is the pane name. PREFIX_VEC is a prefix key for this pane. */
static void
P is the number of panes we have made so far. */
for (mapno = 0; mapno < nmaps; mapno++)
single_keymap_panes (keymaps[mapno],
- map_prompt (keymaps[mapno]), Qnil, notreal, 10);
+ Fkeymap_prompt (keymaps[mapno]), Qnil, notreal, 10);
finish_menu_items ();
}
Lisp_Object elt, pane_name, pane_data;
elt = Fcar (tail);
pane_name = Fcar (elt);
- CHECK_STRING (pane_name, 0);
+ CHECK_STRING (pane_name);
push_menu_pane (pane_name, Qnil);
pane_data = Fcdr (elt);
- CHECK_CONS (pane_data, 0);
+ CHECK_CONS (pane_data);
list_of_items (pane_data);
}
push_left_right_boundary ();
else
{
- CHECK_CONS (item, 0);
+ CHECK_CONS (item);
item1 = Fcar (item);
- CHECK_STRING (item1, 1);
+ CHECK_STRING (item1);
push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil, Qnil);
}
}
}
\f
DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
- "Pop up a deck-of-cards menu and return user's selection.\n\
-POSITION is a position specification. This is either a mouse button event\n\
-or a list ((XOFFSET YOFFSET) WINDOW)\n\
-where XOFFSET and YOFFSET are positions in pixels from the top left\n\
-corner of WINDOW's frame. (WINDOW may be a frame object instead of a window.)\n\
-This controls the position of the center of the first line\n\
-in the first pane of the menu, not the top left of the menu as a whole.\n\
-If POSITION is t, it means to use the current mouse position.\n\
-\n\
-MENU is a specifier for a menu. For the simplest case, MENU is a keymap.\n\
-The menu items come from key bindings that have a menu string as well as\n\
-a definition; actually, the \"definition\" in such a key binding looks like\n\
-\(STRING . REAL-DEFINITION). To give the menu a title, put a string into\n\
-the keymap as a top-level element.\n\n\
-If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.\n\
-Otherwise, REAL-DEFINITION should be a valid key binding definition.\n\
-\n\
-You can also use a list of keymaps as MENU.\n\
- Then each keymap makes a separate pane.\n\
-When MENU is a keymap or a list of keymaps, the return value\n\
-is a list of events.\n\n\
-\n\
-Alternatively, you can specify a menu of multiple panes\n\
- with a list of the form (TITLE PANE1 PANE2...),\n\
-where each pane is a list of form (TITLE ITEM1 ITEM2...).\n\
-Each ITEM is normally a cons cell (STRING . VALUE);\n\
-but a string can appear as an item--that makes a nonselectable line\n\
-in the menu.\n\
-With this form of menu, the return value is VALUE from the chosen item.\n\
-\n\
-If POSITION is nil, don't display the menu at all, just precalculate the\n\
-cached information about equivalent key sequences.")
- (position, menu)
+ doc: /* Pop up a deck-of-cards menu and return user's selection.
+POSITION is a position specification. This is either a mouse button event
+or a list ((XOFFSET YOFFSET) WINDOW)
+where XOFFSET and YOFFSET are positions in pixels from the top left
+corner of WINDOW's frame. (WINDOW may be a frame object instead of a window.)
+This controls the position of the center of the first line
+in the first pane of the menu, not the top left of the menu as a whole.
+If POSITION is t, it means to use the current mouse position.
+
+MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
+The menu items come from key bindings that have a menu string as well as
+a definition; actually, the "definition" in such a key binding looks like
+\(STRING . REAL-DEFINITION). To give the menu a title, put a string into
+the keymap as a top-level element.
+
+If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
+Otherwise, REAL-DEFINITION should be a valid key binding definition.
+
+You can also use a list of keymaps as MENU.
+ Then each keymap makes a separate pane.
+When MENU is a keymap or a list of keymaps, the return value
+is a list of events.
+
+Alternatively, you can specify a menu of multiple panes
+ with a list of the form (TITLE PANE1 PANE2...),
+where each pane is a list of form (TITLE ITEM1 ITEM2...).
+Each ITEM is normally a cons cell (STRING . VALUE);
+but a string can appear as an item--that makes a nonselectable line
+in the menu.
+With this form of menu, the return value is VALUE from the chosen item.
+
+If POSITION is nil, don't display the menu at all, just precalculate the
+cached information about equivalent key sequences. */)
+ (position, menu)
Lisp_Object position, menu;
{
Lisp_Object keymap, tem;
- int xpos, ypos;
+ int xpos = 0, ypos = 0;
Lisp_Object title;
char *error_name;
Lisp_Object selection;
- FRAME_PTR f;
+ FRAME_PTR f = NULL;
Lisp_Object x, y, window;
int keymaps = 0;
int for_click = 0;
/* Decode the first argument: find the window and the coordinates. */
if (EQ (position, Qt)
- || (CONSP (position) && EQ (XCAR (position), Qmenu_bar)))
+ || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
+ || EQ (XCAR (position), Qtool_bar))))
{
/* Use the mouse's current position. */
FRAME_PTR new_f = SELECTED_FRAME ();
}
}
- CHECK_NUMBER (x, 0);
- CHECK_NUMBER (y, 0);
+ CHECK_NUMBER (x);
+ CHECK_NUMBER (y);
/* Decode where to put the menu. */
}
else if (WINDOWP (window))
{
- CHECK_LIVE_WINDOW (window, 0);
+ CHECK_LIVE_WINDOW (window);
f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
- xpos = (FONT_WIDTH (f->output_data.x->font)
+ xpos = (FONT_WIDTH (FRAME_FONT (f))
* XFASTINT (XWINDOW (window)->left));
- ypos = (f->output_data.x->line_height
+ ypos = (FRAME_LINE_HEIGHT (f)
* XFASTINT (XWINDOW (window)->top));
}
else
/* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
but I don't want to make one now. */
- CHECK_WINDOW (window, 0);
+ CHECK_WINDOW (window);
xpos += XINT (x);
ypos += XINT (y);
/* Decode the menu items from what was specified. */
- keymap = Fkeymapp (menu);
- tem = Qnil;
- if (CONSP (menu))
- tem = Fkeymapp (Fcar (menu));
- if (!NILP (keymap))
+ keymap = get_keymap (menu, 0, 0);
+ if (CONSP (keymap))
{
/* We were given a keymap. Extract menu info from the keymap. */
Lisp_Object prompt;
- keymap = get_keymap (menu);
/* Extract the detailed info to make one pane. */
keymap_panes (&menu, 1, NILP (position));
/* Search for a string appearing directly as an element of the keymap.
That string is the title of the menu. */
- prompt = map_prompt (keymap);
+ prompt = Fkeymap_prompt (keymap);
if (NILP (title) && !NILP (prompt))
title = prompt;
keymaps = 1;
}
- else if (!NILP (tem))
+ else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
{
/* We were given a list of keymaps. */
int nmaps = XFASTINT (Flength (menu));
{
Lisp_Object prompt;
- maps[i++] = keymap = get_keymap (Fcar (tem));
+ maps[i++] = keymap = get_keymap (Fcar (tem), 1, 0);
- prompt = map_prompt (keymap);
+ prompt = Fkeymap_prompt (keymap);
if (NILP (title) && !NILP (prompt))
title = prompt;
}
{
/* We were given an old-fashioned menu. */
title = Fcar (menu);
- CHECK_STRING (title, 1);
+ CHECK_STRING (title);
list_of_panes (Fcdr (menu));
#ifdef HAVE_MENUS
DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 2, 0,
- "Pop up a dialog box and return user's selection.\n\
-POSITION specifies which frame to use.\n\
-This is normally a mouse button event or a window or frame.\n\
-If POSITION is t, it means to use the frame the mouse is on.\n\
-The dialog box appears in the middle of the specified frame.\n\
-\n\
-CONTENTS specifies the alternatives to display in the dialog box.\n\
-It is a list of the form (TITLE ITEM1 ITEM2...).\n\
-Each ITEM is a cons cell (STRING . VALUE).\n\
-The return value is VALUE from the chosen item.\n\n\
-An ITEM may also be just a string--that makes a nonselectable item.\n\
-An ITEM may also be nil--that means to put all preceding items\n\
-on the left of the dialog box and all following items on the right.\n\
-\(By default, approximately half appear on each side.)")
- (position, contents)
+ doc: /* Pop up a dialog box and return user's selection.
+POSITION specifies which frame to use.
+This is normally a mouse button event or a window or frame.
+If POSITION is t, it means to use the frame the mouse is on.
+The dialog box appears in the middle of the specified frame.
+
+CONTENTS specifies the alternatives to display in the dialog box.
+It is a list of the form (TITLE ITEM1 ITEM2...).
+Each ITEM is a cons cell (STRING . VALUE).
+The return value is VALUE from the chosen item.
+
+An ITEM may also be just a string--that makes a nonselectable item.
+An ITEM may also be nil--that means to put all preceding items
+on the left of the dialog box and all following items on the right.
+\(By default, approximately half appear on each side.) */)
+ (position, contents)
Lisp_Object position, contents;
{
- FRAME_PTR f;
+ FRAME_PTR f = NULL;
Lisp_Object window;
check_x ();
/* Decode the first argument: find the window or frame to use. */
if (EQ (position, Qt)
- || (CONSP (position) && EQ (XCAR (position), Qmenu_bar)))
+ || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
+ || EQ (XCAR (position), Qtool_bar))))
{
#if 0 /* Using the frame the mouse is on may not be right. */
/* Use the mouse's current position. */
FRAME_PTR new_f = SELECTED_FRAME ();
Lisp_Object bar_window;
- int part;
+ enum scroll_bar_part part;
unsigned long time;
Lisp_Object x, y;
f = XFRAME (window);
else if (WINDOWP (window))
{
- CHECK_LIVE_WINDOW (window, 0);
+ CHECK_LIVE_WINDOW (window);
f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
}
else
/* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
but I don't want to make one now. */
- CHECK_WINDOW (window, 0);
+ CHECK_WINDOW (window);
#ifndef USE_X_TOOLKIT
/* Display a menu with these alternatives
/* Decode the dialog items from what was specified. */
title = Fcar (contents);
- CHECK_STRING (title, 1);
+ CHECK_STRING (title);
list_of_panes (Fcons (contents, Qnil));
&& (event.xany.display != dpyinfo->display
|| x_non_menubar_window_to_frame (dpyinfo, event.xany.window)))
{
- queue_tmp = (struct event_queue *) malloc (sizeof (struct event_queue));
-
- if (queue_tmp != NULL)
- {
- queue_tmp->event = event;
- queue_tmp->next = queue;
- queue = queue_tmp;
- }
+ queue_tmp = (struct event_queue *) xmalloc (sizeof *queue_tmp);
+ queue_tmp->event = event;
+ queue_tmp->next = queue;
+ queue = queue_tmp;
}
else
XtDispatchEvent (&event);
LWLIB_ID id;
XtPointer client_data;
{
-#ifdef USE_MOTIF
- ++popup_activated_flag;
-#else
popup_activated_flag = 1;
-#endif
}
/* This callback is invoked when a dialog or menu is finished being
LWLIB_ID id;
XtPointer client_data;
{
-#ifdef USE_MOTIF
- --popup_activated_flag;
-#else
popup_activated_flag = 0;
-#endif
}
/* Lwlib callback called when menu items are highlighted/unhighlighted
struct frame *f;
Lisp_Object frame, help;
- help = wv && wv->help ? build_string (wv->help) : Qnil;
+ help = wv ? wv->help : Qnil;
/* Determine the frame for the help event. */
f = menubar_id_to_frame (id);
if (!f)
return;
+ entry = Qnil;
subprefix_stack = (Lisp_Object *) alloca (f->menu_bar_items_used * sizeof (Lisp_Object));
vector = f->menu_bar_vector;
prefix = Qnil;
for (i = 0; i < len; i++)
{
if (SYMBOLP (mapvec[i])
- || (CONSP (mapvec[i])
- && NILP (Fkeymapp (mapvec[i]))))
+ || (CONSP (mapvec[i]) && !KEYMAPP (mapvec[i])))
{
/* Here we have a command at top level in the menu bar
as opposed to a submenu. */
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
+ wv->help = Qnil;
first_wv = wv;
save_wv = 0;
prev_wv = 0;
/* 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 = ENCODE_SYSTEM (pane_name);
+ AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
+ }
#endif
pane_string = (NILP (pane_name)
? "" : (char *) XSTRING (pane_name)->data);
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
+ wv->help = Qnil;
}
save_wv = wv;
prev_wv = 0;
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 = ENCODE_SYSTEM (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 = ENCODE_SYSTEM (descrip);
+ AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
+ }
+#endif /* not HAVE_MULTILINGUAL_MENU */
wv = xmalloc_widget_value ();
if (prev_wv)
abort ();
wv->selected = !NILP (selected);
- if (STRINGP (help))
- wv->help = XSTRING (help)->data;
-
+ if (! STRINGP (help))
+ help = Qnil;
+
+ wv->help = help;
+
prev_wv = wv;
i += MENU_ITEMS_ITEM_LENGTH;
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.
Lisp_Object items;
widget_value *wv, *first_wv, *prev_wv = 0;
int i;
+
LWLIB_ID id;
XSETFRAME (Vmenu_updating_frame, f);
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
+ wv->help = Qnil;
first_wv = wv;
if (deep_p)
set_buffer_internal_1 (XBUFFER (buffer));
/* Run the Lucid hook. */
- call1 (Vrun_hooks, Qactivate_menubar_hook);
+ safe_run_hooks (Qactivate_menubar_hook);
+
/* If it has changed current-menubar from previous value,
really recompute the menubar from the value. */
if (! NILP (Vlucid_menu_bar_dirty_flag))
inhibit_garbage_collection ();
/* Save the frame's previous menu bar contents data. */
- bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
- previous_menu_items_used * sizeof (Lisp_Object));
+ if (previous_menu_items_used)
+ bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
+ previous_menu_items_used * sizeof (Lisp_Object));
/* Fill in the current menu bar contents. */
menu_items = f->menu_bar_vector;
- menu_items_allocated = XVECTOR (menu_items)->size;
+ menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
init_menu_items ();
for (i = 0; i < XVECTOR (items)->size; i += 4)
{
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
+ wv->help = Qnil;
/* This prevents lwlib from assuming this
menu item is really supposed to be empty. */
/* The EMACS_INT cast avoids a warning.
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;
}
}
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
+ wv->help =Qnil;
first_wv = wv;
first_pane = 1;
/* 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 = ENCODE_SYSTEM (pane_name);
+ AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name;
+ }
#endif
pane_string = (NILP (pane_name)
? "" : (char *) XSTRING (pane_name)->data);
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
+ wv->help = Qnil;
save_wv = wv;
prev_wv = 0;
}
{
/* 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 = ENCODE_SYSTEM (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 = ENCODE_SYSTEM (descrip);
+ AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip;
+ }
+#endif /* not HAVE_MULTILINGUAL_MENU */
wv = xmalloc_widget_value ();
if (prev_wv)
abort ();
wv->selected = !NILP (selected);
- if (STRINGP (help))
- wv->help = XSTRING (help)->data;
-
+
+ if (! STRINGP (help))
+ help = Qnil;
+
+ wv->help = help;
+
prev_wv = wv;
i += MENU_ITEMS_ITEM_LENGTH;
wv_sep2->name = "--";
wv_sep2->next = first_wv->contents;
+ wv_sep2->help = Qnil;
wv_sep1->name = "--";
wv_sep1->next = wv_sep2;
+ wv_sep1->help = Qnil;
#ifndef HAVE_MULTILINGUAL_MENU
if (STRING_MULTIBYTE (title))
- title = string_make_unibyte (title);
+ title = ENCODE_SYSTEM (title);
#endif
+
wv_title->name = (char *) XSTRING (title)->data;
- wv_title->enabled = True;
+ wv_title->enabled = TRUE;
wv_title->button_type = BUTTON_TYPE_NONE;
wv_title->next = wv_sep1;
+ wv_title->help = Qnil;
first_wv->contents = wv_title;
}
/* 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;
/* Process events that apply to the menu. */
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id);
-#ifdef LESSTIF_VERSION
- /* Nov 1998: For an unknown reason a button grab remains active
- after the popup menu has gone. */
- XUngrabButton (XtDisplay (f->output_data.x->widget),
- AnyButton, AnyModifier,
- XtWindow (f->output_data.x->widget));
- XUngrabButton (XtDisplay (f->output_data.x->edit_widget),
- AnyButton, AnyModifier,
- XtWindow (f->output_data.x->edit_widget));
-#endif /* LESSTIF_VERSION */
-
/* fp turned off the following statement and wrote a comment
that it is unnecessary--that the menu has already disappeared.
Nowadays the menu disappears ok, all right, but
{
Lisp_Object prefix, entry;
- prefix = Qnil;
+ prefix = entry = Qnil;
i = 0;
while (i < menu_items_used)
{
prev_wv->name++;
prev_wv->enabled = 1;
prev_wv->name = "message";
+ prev_wv->help = Qnil;
first_wv = prev_wv;
/* Loop over all panes and items, filling in the tree. */
wv->value = (char *) XSTRING (item_name)->data;
wv->call_data = (void *) &XVECTOR (menu_items)->contents[i];
wv->enabled = !NILP (enable);
+ wv->help = Qnil;
prev_wv = wv;
if (! boundary_seen)
wv = xmalloc_widget_value ();
wv->name = dialog_name;
-
+ wv->help = Qnil;
/* Dialog boxes use a really stupid name encoding
which specifies how many buttons to use
and how many buttons are on the right.
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
i += MENU_ITEMS_PANE_LENGTH;
}
+ else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+ {
+ /* This is the boundary between left-side elts and
+ right-side elts. */
+ ++i;
+ }
else
{
entry
pane_name = first_item[MENU_ITEMS_PANE_NAME];
else if (EQ (first_item[0], Qquote))
/* This shouldn't happen, see xmenu_show. */
- pane_name = build_string ("");
+ pane_name = empty_string;
else
pane_name = first_item[MENU_ITEMS_ITEM_NAME];
/* 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);
staticpro (&Qdebug_on_next_call);
DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
- "Frame for which we are updating a menu.\n\
-The enable predicate for a menu command should check this variable.");
+ doc: /* Frame for which we are updating a menu.
+The enable predicate for a menu command should check this variable. */);
Vmenu_updating_frame = Qnil;
#ifdef USE_X_TOOLKIT