#include <X11/CoreP.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
+#ifdef USE_LUCID
#include <X11/Xaw/Paned.h>
+#endif /* USE_LUCID */
#include "../lwlib/lwlib.h"
#else /* not USE_X_TOOLKIT */
#include "../oldXMenu/XMenu.h"
\f
#ifdef USE_X_TOOLKIT
-/* Return the frame whose ->display.x->id equals ID, or 0 if none. */
+/* Return the frame whose ->output_data.x->id equals ID, or 0 if none. */
static struct frame *
menubar_id_to_frame (id)
if (!GC_FRAMEP (frame))
continue;
f = XFRAME (frame);
- if (f->display.nothing == 1)
+ if (f->output_data.nothing == 1)
continue;
- if (f->display.x->id == id)
+ if (f->output_data.x->id == id)
return f;
}
return 0;
}
}
\f
-/* Push all the panes and items of a menu decsribed by the
+/* Push all the panes and items of a menu described by the
alist-of-alists MENU.
This handles old-fashioned calls to x-popup-menu. */
CHECK_LIVE_WINDOW (window, 0);
f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
- xpos = (FONT_WIDTH (f->display.x->font) * XWINDOW (window)->left);
- ypos = (f->display.x->line_height * XWINDOW (window)->top);
+ xpos = (FONT_WIDTH (f->output_data.x->font) * XWINDOW (window)->left);
+ ypos = (f->output_data.x->line_height * XWINDOW (window)->top);
}
else
/* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
#ifdef USE_X_TOOLKIT
/* Loop in Xt until the menu pulldown or dialog popup has been
- popped down (deactivated).
+ popped down (deactivated). This is used for x-popup-menu
+ and x-popup-dialog; it is not used for the menu bar any more.
NOTE: All calls to popup_get_selection should be protected
with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */
popup_activated_flag = 0;
break;
}
+ /* Button presses outside the menu also pop it down. */
+ else if (event.type == ButtonPress
+ && event.xany.display == dpyinfo->display
+ && x_any_window_to_frame (dpyinfo, event.xany.window))
+ {
+ popup_activated_flag = 0;
+ break;
+ }
/* Queue all events not for this popup,
except for Expose, which we've already handled.
x_activate_menubar (f)
FRAME_PTR f;
{
- if (f->display.x->saved_button_event->type != ButtonPress)
+ if (f->output_data.x->saved_button_event->type != ButtonPress)
return;
set_frame_menubar (f, 0, 1);
BLOCK_INPUT;
- XtDispatchEvent ((XEvent *) f->display.x->saved_button_event);
+ XtDispatchEvent ((XEvent *) f->output_data.x->saved_button_event);
UNBLOCK_INPUT;
/* Ignore this if we get it a second time. */
- f->display.x->saved_button_event->type = 0;
+ f->output_data.x->saved_button_event->type = 0;
}
/* Detect if a dialog or menu has been posted. */
else
first_wv->contents = wv;
wv->name = pane_string;
- if (!NILP (prefix))
+ /* Ignore the @ that means "separate pane".
+ This is a kludge, but this isn't worth more time. */
+ if (!NILP (prefix) && wv->name[0] == '@')
wv->name++;
wv->value = 0;
wv->enabled = 1;
update_frame_menubar (f)
FRAME_PTR f;
{
- struct x_display *x = f->display.x;
+ struct x_output *x = f->output_data.x;
int columns, rows;
int menubar_changed;
int first_time;
int deep_p;
{
- Widget menubar_widget = f->display.x->menubar_widget;
+ Widget menubar_widget = f->output_data.x->menubar_widget;
Lisp_Object tail, items, frame;
widget_value *wv, *first_wv, *prev_wv = 0;
int i;
LWLIB_ID id;
- if (f->display.x->id == 0)
- f->display.x->id = next_menubar_widget_id++;
- id = f->display.x->id;
+ if (f->output_data.x->id == 0)
+ f->output_data.x->id = next_menubar_widget_id++;
+ id = f->output_data.x->id;
if (! menubar_widget)
deep_p = 1;
if (menu_items_used == i
|| (previous_items[i] != XVECTOR (menu_items)->contents[i]))
break;
- if (i == menu_items_used && i == previous_menu_items_used)
+ if (i == menu_items_used && i == previous_menu_items_used && i != 0)
{
free_menubar_widget_value_tree (first_wv);
menu_items = Qnil;
first_wv->contents = wv;
prev_wv = wv;
}
+
+ /* Forget what we thought we knew about what is in the
+ detailed contents of the menu bar menus.
+ Changing the top level always destroys the contents. */
+ f->menu_bar_items_used = 0;
}
/* Create or update the menu bar widget. */
if (menubar_widget)
{
/* Disable resizing (done for Motif!) */
- lw_allow_resizing (f->display.x->widget, False);
+ lw_allow_resizing (f->output_data.x->widget, False);
/* The third arg is DEEP_P, which says to consider the entire
menu trees we supply, rather than just the menu bar item names. */
lw_modify_all_widgets (id, first_wv, deep_p);
/* Re-enable the edit widget to resize. */
- lw_allow_resizing (f->display.x->widget, True);
+ lw_allow_resizing (f->output_data.x->widget, True);
}
else
{
menubar_widget = lw_create_widget ("menubar", "menubar", id, first_wv,
- f->display.x->column_widget,
+ f->output_data.x->column_widget,
0,
popup_activate_callback,
menubar_selection_callback,
popup_deactivate_callback);
- f->display.x->menubar_widget = menubar_widget;
+ f->output_data.x->menubar_widget = menubar_widget;
}
{
int menubar_size
- = (f->display.x->menubar_widget
- ? (f->display.x->menubar_widget->core.height
- + f->display.x->menubar_widget->core.border_width)
+ = (f->output_data.x->menubar_widget
+ ? (f->output_data.x->menubar_widget->core.height
+ + f->output_data.x->menubar_widget->core.border_width)
: 0);
+#ifdef USE_LUCID
if (FRAME_EXTERNAL_MENU_BAR (f))
{
Dimension ibw = 0;
- XtVaGetValues (f->display.x->column_widget,
+ XtVaGetValues (f->output_data.x->column_widget,
XtNinternalBorderWidth, &ibw, NULL);
menubar_size += ibw;
}
+#endif /* USE_LUCID */
- f->display.x->menubar_height = menubar_size;
+ f->output_data.x->menubar_height = menubar_size;
}
free_menubar_widget_value_tree (first_wv);
UNBLOCK_INPUT;
}
-/* Called from Fx_create_frame to create the inital menubar of a frame
+/* Called from Fx_create_frame to create the initial menubar of a frame
before it is mapped, so that the window is mapped with the menubar already
there instead of us tacking it on later and thrashing the window after it
is visible. */
Widget menubar_widget;
int id;
- menubar_widget = f->display.x->menubar_widget;
+ menubar_widget = f->output_data.x->menubar_widget;
if (menubar_widget)
{
BLOCK_INPUT;
- lw_destroy_all_widgets ((LWLIB_ID) f->display.x->id);
+ lw_destroy_all_widgets ((LWLIB_ID) f->output_data.x->id);
UNBLOCK_INPUT;
}
}
int i;
LWLIB_ID menu_id;
Widget menu;
- Arg av [2];
+ Arg av[2];
int ac = 0;
widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
widget_value **submenu_stack
Lisp_Object *subprefix_stack
= (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
int submenu_depth = 0;
-
- Position root_x, root_y;
+ XButtonPressedEvent dummy;
int first_pane;
int next_release_must_exit = 0;
/* Actually create the menu. */
menu_id = widget_id_tick++;
menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
- f->display.x->widget, 1, 0,
+ f->output_data.x->widget, 1, 0,
popup_selection_callback,
popup_deactivate_callback);
+ /* Adjust coordinates to relative to the outer (window manager) window. */
+ {
+ Window child;
+ int win_x = 0, win_y = 0;
+
+ /* Find the position of the outside upper-left corner of
+ the inner window, with respect to the outer window. */
+ if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+ {
+ BLOCK_INPUT;
+ XTranslateCoordinates (FRAME_X_DISPLAY (f),
+
+ /* From-window, to-window. */
+ f->output_data.x->window_desc,
+ f->output_data.x->parent_desc,
+
+ /* From-position, to-position. */
+ 0, 0, &win_x, &win_y,
+
+ /* Child of window. */
+ &child);
+ UNBLOCK_INPUT;
+ x += win_x;
+ y += win_y;
+ }
+ }
+
+ /* Adjust coordinates to be root-window-relative. */
+ x += f->output_data.x->left_pos;
+ y += f->output_data.x->top_pos;
+
+ dummy.type = ButtonPress;
+ dummy.serial = 0;
+ dummy.send_event = 0;
+ dummy.display = FRAME_X_DISPLAY (f);
+ dummy.time = CurrentTime;
+ dummy.button = 0;
+ dummy.root = FRAME_X_DISPLAY_INFO (f)->root_window;
+ dummy.window = dummy.root;
+ dummy.subwindow = dummy.root;
+ dummy.x_root = x;
+ dummy.y_root = y;
+ dummy.x = x;
+ dummy.y = y;
+
/* Don't allow any geometry request from the user. */
XtSetArg (av[ac], XtNgeometry, 0); ac++;
XtSetValues (menu, av, ac);
menu_item_selection = 0;
/* Display the menu. */
- lw_popup_menu (menu);
+ lw_popup_menu (menu, &dummy);
popup_activated_flag = 1;
/* Process events that apply to the menu. */
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
i += MENU_ITEMS_PANE_LENGTH;
}
+ /* Ignore a nil in the item list.
+ It's meaningful only for dialog boxes. */
+ else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+ i += 1;
else
{
entry
/* Actually create the dialog. */
dialog_id = widget_id_tick++;
menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
- f->display.x->widget, 1, 0,
+ f->output_data.x->widget, 1, 0,
dialog_selection_callback, 0);
lw_modify_all_widgets (dialog_id, first_wv->contents, True);
/* Free the widget_value objects we used to specify the contents. */
/* Find the position of the outside upper-left corner of
the inner window, with respect to the outer window. */
- if (f->display.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+ if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
{
BLOCK_INPUT;
XTranslateCoordinates (FRAME_X_DISPLAY (f),
/* From-window, to-window. */
- f->display.x->window_desc,
- f->display.x->parent_desc,
+ f->output_data.x->window_desc,
+ f->output_data.x->parent_desc,
/* From-position, to-position. */
0, 0, &win_x, &win_y,
#endif /* HAVE_X_WINDOWS */
/* Adjust coordinates to be root-window-relative. */
- x += f->display.x->left_pos;
- y += f->display.x->top_pos;
+ x += f->output_data.x->left_pos;
+ y += f->output_data.x->top_pos;
/* Create all the necessary panes and their items. */
i = 0;