[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/src/xmenu.c
From: |
Kenichi Handa |
Subject: |
[Emacs-diffs] Changes to emacs/src/xmenu.c |
Date: |
Tue, 21 Jan 2003 21:33:56 -0500 |
Index: emacs/src/xmenu.c
diff -c emacs/src/xmenu.c:1.241 emacs/src/xmenu.c:1.242
*** emacs/src/xmenu.c:1.241 Sat Jan 18 04:55:37 2003
--- emacs/src/xmenu.c Sun Jan 19 16:50:02 2003
***************
*** 81,87 ****
--- 81,89 ----
#endif /* USE_LUCID */
#include "../lwlib/lwlib.h"
#else /* not USE_X_TOOLKIT */
+ #ifndef USE_GTK
#include "../oldXMenu/XMenu.h"
+ #endif
#endif /* not USE_X_TOOLKIT */
#endif /* HAVE_X_WINDOWS */
***************
*** 116,121 ****
--- 118,130 ----
/* Define HAVE_BOXES if menus can handle radio and toggle buttons. */
#define HAVE_BOXES 1
+ #endif /* USE_X_TOOLKIT */
+
+ #ifdef USE_GTK
+ #include "gtkutil.h"
+ #define HAVE_BOXES 1
+ extern void set_frame_menubar ();
+ static Lisp_Object xdialog_show ();
#endif
static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
***************
*** 194,200 ****
/* Flag which when set indicates a dialog or menu has been posted by
Xt on behalf of one of the widget sets. */
! int popup_activated_flag;
static int next_menubar_widget_id;
--- 203,209 ----
/* Flag which when set indicates a dialog or menu has been posted by
Xt on behalf of one of the widget sets. */
! static int popup_activated_flag;
static int next_menubar_widget_id;
***************
*** 593,599 ****
}
#endif /* not HAVE_BOXES */
! #ifndef USE_X_TOOLKIT
if (!NILP(map))
/* Indicate visually that this is a submenu. */
item_string = concat2 (item_string, build_string (" >"));
--- 602,608 ----
}
#endif /* not HAVE_BOXES */
! #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
if (!NILP(map))
/* Indicate visually that this is a submenu. */
item_string = concat2 (item_string, build_string (" >"));
***************
*** 606,612 ****
XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
! #ifdef USE_X_TOOLKIT
/* Display a submenu using the toolkit. */
if (! (NILP (map) || NILP (enabled)))
{
--- 615,621 ----
XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
! #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Display a submenu using the toolkit. */
if (! (NILP (map) || NILP (enabled)))
{
***************
*** 771,776 ****
--- 780,786 ----
#ifdef HAVE_MENUS
if (! NILP (position))
{
+ int get_current_pos_p = 0;
check_x ();
/* Decode the first argument: find the window and the coordinates. */
***************
*** 778,783 ****
--- 788,825 ----
|| (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
|| EQ (XCAR (position), Qtool_bar))))
{
+ get_current_pos_p = 1;
+ }
+ else
+ {
+ tem = Fcar (position);
+ if (CONSP (tem))
+ {
+ window = Fcar (Fcdr (position));
+ x = Fcar (tem);
+ y = Fcar (Fcdr (tem));
+ }
+ else
+ {
+ for_click = 1;
+ tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
+ window = Fcar (tem); /* POSN_WINDOW (tem) */
+ tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
+ x = Fcar (tem);
+ y = Fcdr (tem);
+ }
+
+ /* If a click happens in an external tool bar or a detached
+ tool bar, x and y is NIL. In that case, use the current
+ mouse position. This happens for the help button in the
+ tool bar. Ideally popup-menu should pass NIL to
+ this function, but it doesn't. */
+ if (NILP (x) && NILP (y))
+ get_current_pos_p = 1;
+ }
+
+ if (get_current_pos_p)
+ {
/* Use the mouse's current position. */
FRAME_PTR new_f = SELECTED_FRAME ();
#ifdef HAVE_X_WINDOWS
***************
*** 813,837 ****
XSETFASTINT (y, 0);
}
}
- else
- {
- tem = Fcar (position);
- if (CONSP (tem))
- {
- window = Fcar (Fcdr (position));
- x = Fcar (tem);
- y = Fcar (Fcdr (tem));
- }
- else
- {
- for_click = 1;
- tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
- window = Fcar (tem); /* POSN_WINDOW (tem) */
- tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
- x = Fcar (tem);
- y = Fcdr (tem);
- }
- }
CHECK_NUMBER (x);
CHECK_NUMBER (y);
--- 855,860 ----
***************
*** 1040,1046 ****
but I don't want to make one now. */
CHECK_WINDOW (window);
! #ifndef USE_X_TOOLKIT
/* Display a menu with these alternatives
in the middle of frame F. */
{
--- 1063,1069 ----
but I don't want to make one now. */
CHECK_WINDOW (window);
! #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Display a menu with these alternatives
in the middle of frame F. */
{
***************
*** 1081,1087 ****
#endif
}
! #ifdef USE_X_TOOLKIT
/* Loop in Xt until the menu pulldown or dialog popup has been
popped down (deactivated). This is used for x-popup-menu
--- 1104,1110 ----
#endif
}
! #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Loop in Xt until the menu pulldown or dialog popup has been
popped down (deactivated). This is used for x-popup-menu
***************
*** 1092,1097 ****
--- 1115,1121 ----
NOTE: All calls to popup_get_selection should be protected
with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */
+ #ifdef USE_X_TOOLKIT
static void
popup_get_selection (initial_event, dpyinfo, id, do_timers)
XEvent *initial_event;
***************
*** 1148,1153 ****
--- 1172,1195 ----
}
}
+ #endif /* USE_X_TOOLKIT */
+
+ #ifdef USE_GTK
+ /* Loop util popup_activated_flag is set to zero in a callback.
+ Used for popup menus and dialogs. */
+ static void
+ popup_widget_loop ()
+ {
+ ++popup_activated_flag;
+
+ /* Process events in the Gtk event loop until done. */
+ while (popup_activated_flag)
+ {
+ gtk_main_iteration ();
+ }
+ }
+ #endif
+
/* Activate the menu bar of frame F.
This is called from keyboard.c when it gets the
MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
***************
*** 1169,1177 ****
--- 1211,1230 ----
if (!f->output_data.x->saved_menu_event->type)
return;
+ #ifdef USE_GTK
+ if (! xg_win_to_widget (f->output_data.x->saved_menu_event->xany.window))
+ return;
+ #endif
+
set_frame_menubar (f, 0, 1);
BLOCK_INPUT;
+ #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)
***************
*** 1193,1198 ****
--- 1246,1252 ----
/* This callback is invoked when the user selects a menubar cascade
pushbutton, but before the pulldown menu is posted. */
+ #ifndef USE_GTK
static void
popup_activate_callback (widget, id, client_data)
Widget widget;
***************
*** 1201,1210 ****
--- 1255,1274 ----
{
popup_activated_flag = 1;
}
+ #endif
/* This callback is invoked when a dialog or menu is finished being
used and has been unposted. */
+ #ifdef USE_GTK
+ static void
+ popup_deactivate_callback (widget, client_data)
+ GtkWidget *widget;
+ gpointer client_data;
+ {
+ popup_activated_flag = 0;
+ }
+ #else
static void
popup_deactivate_callback (widget, id, client_data)
Widget widget;
***************
*** 1213,1239 ****
{
popup_activated_flag = 0;
}
- /* Lwlib callback called when menu items are highlighted/unhighlighted
- while moving the mouse over them. WIDGET is the menu bar or menu
- popup widget. ID is its LWLIB_ID. CALL_DATA contains a pointer to
- the widget_value structure for the menu item, or null in case of
- unhighlighting. */
! void
! menu_highlight_callback (widget, id, call_data)
! Widget widget;
! LWLIB_ID id;
! void *call_data;
{
! widget_value *wv = (widget_value *) call_data;
! struct frame *f;
! Lisp_Object frame, help;
- help = wv ? wv->help : Qnil;
-
- /* Determine the frame for the help event. */
- f = menubar_id_to_frame (id);
if (f)
{
XSETFRAME (frame, f);
--- 1277,1296 ----
{
popup_activated_flag = 0;
}
+ #endif
! /* Function that finds the frame for WIDGET and shows the HELP text
! for that widget.
! F is the frame if known, or NULL if not known. */
! static void
! show_help_event (f, widget, help)
! FRAME_PTR f;
! xt_or_gtk_widget widget;
! Lisp_Object help;
{
! Lisp_Object frame;
if (f)
{
XSETFRAME (frame, f);
***************
*** 1243,1249 ****
{
/* WIDGET is the popup menu. It's parent is the frame's
widget. See which frame that is. */
! Widget frame_widget = XtParent (widget);
Lisp_Object tail;
for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
--- 1300,1306 ----
{
/* WIDGET is the popup menu. It's parent is the frame's
widget. See which frame that is. */
! xt_or_gtk_widget frame_widget = XtParent (widget);
Lisp_Object tail;
for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
***************
*** 1259,1290 ****
}
}
! /* This callback is called from the menu bar pulldown menu
! when the user makes a selection.
! 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;
{
Lisp_Object prefix, entry;
- FRAME_PTR f = menubar_id_to_frame (id);
- Lisp_Object vector;
Lisp_Object *subprefix_stack;
int submenu_depth = 0;
int i;
- 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;
i = 0;
! while (i < f->menu_bar_items_used)
{
if (EQ (XVECTOR (vector)->contents[i], Qnil))
{
--- 1316,1392 ----
}
}
! /* Callback called when menu items are highlighted/unhighlighted
! while moving the mouse over them. WIDGET is the menu bar or menu
! popup widget. ID is its LWLIB_ID. CALL_DATA contains a pointer to
! the data structure for the menu item, or null in case of
! unhighlighting. */
! #ifdef USE_GTK
! void
! menu_highlight_callback (widget, call_data)
! GtkWidget *widget;
! gpointer call_data;
! {
! xg_menu_item_cb_data *cb_data;
! Lisp_Object help;
!
! cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (widget),
! XG_ITEM_DATA);
! if (! cb_data) return;
!
! help = call_data ? cb_data->help : Qnil;
!
! /* If popup_activated_flag is greater than 1 we are in a popup menu.
! Don't show help for them, they won't appear before the
! popup is popped down. */
! if (popup_activated_flag <= 1)
! show_help_event (cb_data->cl_data->f, widget, help);
! }
! #else
! void
! menu_highlight_callback (widget, id, call_data)
Widget widget;
LWLIB_ID id;
! void *call_data;
! {
! struct frame *f;
! Lisp_Object help;
!
! widget_value *wv = (widget_value *) call_data;
!
! help = wv ? wv->help : Qnil;
!
! /* Determine the frame for the help event. */
! f = menubar_id_to_frame (id);
!
! show_help_event (f, widget, help);
! }
! #endif
!
! /* Find the menu selection and store it in the keyboard buffer.
! F is the frame the menu is on.
! MENU_BAR_ITEMS_USED is the length of VECTOR.
! VECTOR is an array of menu events for the whole menu.
! */
! void
! find_and_call_menu_selection (f, menu_bar_items_used, vector, client_data)
! FRAME_PTR f;
! int menu_bar_items_used;
! Lisp_Object vector;
! void *client_data;
{
Lisp_Object prefix, entry;
Lisp_Object *subprefix_stack;
int submenu_depth = 0;
int i;
entry = Qnil;
! subprefix_stack = (Lisp_Object *) alloca (menu_bar_items_used * sizeof
(Lisp_Object));
prefix = Qnil;
i = 0;
!
! while (i < menu_bar_items_used)
{
if (EQ (XVECTOR (vector)->contents[i], Qnil))
{
***************
*** 1348,1353 ****
--- 1450,1508 ----
}
}
+
+ #ifdef USE_GTK
+ /* Gtk calls callbacks just because we tell it what item should be
+ selected in a radio group. If this variable is set to a non-zero
+ value, we are creating menus and don't want callbacks right now.
+ */
+ static int xg_crazy_callback_abort;
+
+ /* This callback is called from the menu bar pulldown menu
+ when the user makes a selection.
+ Figure out what the user chose
+ and put the appropriate events into the keyboard buffer. */
+ static void
+ menubar_selection_callback (widget, client_data)
+ GtkWidget *widget;
+ gpointer client_data;
+ {
+ xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data;
+
+ if (xg_crazy_callback_abort)
+ return;
+
+ if (! cb_data || ! cb_data->cl_data || ! cb_data->cl_data->f)
+ return;
+
+ find_and_call_menu_selection (cb_data->cl_data->f,
+ cb_data->cl_data->menu_bar_items_used,
+ cb_data->cl_data->menu_bar_vector,
+ cb_data->call_data);
+ }
+
+ #else /* not USE_GTK */
+
+ /* This callback is called from the menu bar pulldown menu
+ when the user makes a selection.
+ 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;
+ {
+ FRAME_PTR f;
+
+ f = menubar_id_to_frame (id);
+ if (!f)
+ return;
+ find_and_call_menu_selection (f, f->menu_bar_items_used,
+ f->menu_bar_vector, client_data);
+ }
+ #endif /* not USE_GTK */
+
/* Allocate a widget_value, blocking input. */
widget_value *
***************
*** 1623,1631 ****
update_frame_menubar (f)
FRAME_PTR f;
{
struct x_output *x = f->output_data.x;
int columns, rows;
!
if (!x->menubar_widget || XtIsManaged (x->menubar_widget))
return 0;
--- 1778,1789 ----
update_frame_menubar (f)
FRAME_PTR f;
{
+ #ifdef USE_GTK
+ return xg_update_frame_menubar (f);
+ #else
struct x_output *x = f->output_data.x;
int columns, rows;
!
if (!x->menubar_widget || XtIsManaged (x->menubar_widget))
return 0;
***************
*** 1657,1662 ****
--- 1815,1821 ----
/* Force the pane widget to resize itself with the right values. */
EmacsFrameSetCharSize (x->edit_widget, columns, rows);
UNBLOCK_INPUT;
+ #endif
return 1;
}
***************
*** 1670,1690 ****
int first_time;
int deep_p;
{
! Widget menubar_widget = f->output_data.x->menubar_widget;
Lisp_Object items;
widget_value *wv, *first_wv, *prev_wv = 0;
int i, last_i;
int *submenu_start, *submenu_end;
int *submenu_top_level_items, *submenu_n_panes;
- LWLIB_ID id;
XSETFRAME (Vmenu_updating_frame, f);
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;
else if (pending_menu_activation && !deep_p)
--- 1829,1853 ----
int first_time;
int deep_p;
{
! xt_or_gtk_widget menubar_widget = f->output_data.x->menubar_widget;
! #ifdef USE_X_TOOLKIT
! LWLIB_ID id;
! #endif
Lisp_Object items;
widget_value *wv, *first_wv, *prev_wv = 0;
int i, last_i;
int *submenu_start, *submenu_end;
int *submenu_top_level_items, *submenu_n_panes;
XSETFRAME (Vmenu_updating_frame, f);
+ #ifdef USE_X_TOOLKIT
if (f->output_data.x->id == 0)
f->output_data.x->id = next_menubar_widget_id++;
id = f->output_data.x->id;
! #endif
!
if (! menubar_widget)
deep_p = 1;
else if (pending_menu_activation && !deep_p)
***************
*** 1893,1898 ****
--- 2056,2090 ----
BLOCK_INPUT;
+ #ifdef USE_GTK
+ xg_crazy_callback_abort = 1;
+ if (menubar_widget)
+ {
+ /* The third arg is DEEP_P, which says to consider the entire
+ menu trees we supply, rather than just the menu bar item names. */
+ xg_modify_menubar_widgets (menubar_widget,
+ f,
+ first_wv,
+ deep_p,
+ G_CALLBACK (menubar_selection_callback),
+ G_CALLBACK (popup_deactivate_callback),
+ G_CALLBACK (menu_highlight_callback));
+ }
+ else
+ {
+ GtkWidget *wvbox = f->output_data.x->vbox_widget;
+
+ menubar_widget
+ = xg_create_widget ("menubar", "menubar", f, first_wv,
+ G_CALLBACK (menubar_selection_callback),
+ G_CALLBACK (popup_deactivate_callback),
+ G_CALLBACK (menu_highlight_callback));
+
+ f->output_data.x->menubar_widget = menubar_widget;
+ }
+
+
+ #else /* not USE_GTK */
if (menubar_widget)
{
/* Disable resizing (done for Motif!) */
***************
*** 1939,1948 ****
--- 2131,2145 ----
f->output_data.x->menubar_height = menubar_size;
}
+ #endif /* not USE_GTK */
free_menubar_widget_value_tree (first_wv);
update_frame_menubar (f);
+ #ifdef USE_GTK
+ xg_crazy_callback_abort = 0;
+ #endif
+
UNBLOCK_INPUT;
}
***************
*** 1963,1970 ****
/* 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. */
void
free_frame_menubar (f)
FRAME_PTR f;
--- 2160,2169 ----
/* 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.
! For GTK this function is in gtkutil.c. */
+ #ifndef USE_GTK
void
free_frame_menubar (f)
FRAME_PTR f;
***************
*** 2011,2018 ****
UNBLOCK_INPUT;
}
}
! #endif /* USE_X_TOOLKIT */
/* xmenu_show actually displays a menu using the panes and items in menu_items
and returns the value selected from it.
--- 2210,2218 ----
UNBLOCK_INPUT;
}
}
+ #endif /* not USE_GTK */
! #endif /* USE_X_TOOLKIT || USE_GTK */
/* xmenu_show actually displays a menu using the panes and items in menu_items
and returns the value selected from it.
***************
*** 2030,2036 ****
ERROR is a place to store an error message string in case of failure.
(We return nil on failure, but the value doesn't actually matter.) */
! #ifdef USE_X_TOOLKIT
/* We need a unique id for each widget handled by the Lucid Widget
library.
--- 2230,2345 ----
ERROR is a place to store an error message string in case of failure.
(We return nil on failure, but the value doesn't actually matter.) */
! #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
!
! /* The item selected in the popup menu. */
! static Lisp_Object *volatile menu_item_selection;
!
! #ifdef USE_GTK
!
! /* Used when position a popup menu. See menu_position_func and
! create_and_show_popup_menu below. */
! struct next_popup_x_y
! {
! int x;
! int y;
! };
!
! /* The menu position function to use if we are not putting a popup
! menu where the pointer is.
! MENU is the menu to pop up.
! X and Y shall on exit contain x/y where the menu shall pop up.
! PUSH_IN is not documented in the GTK manual.
! USER_DATA is any data passed in when calling gtk_menu_popup.
! Here it points to a struct next_popup_x_y where the coordinates
! to store in *X and *Y are.
!
! Here only X and Y are used. */
! static void
! menu_position_func (menu, x, y, push_in, user_data)
! GtkMenu *menu;
! gint *x;
! gint *y;
! gboolean *push_in;
! gpointer user_data;
! {
! *x = ((struct next_popup_x_y*)user_data)->x;
! *y = ((struct next_popup_x_y*)user_data)->y;
! }
!
! static void
! popup_selection_callback (widget, client_data)
! GtkWidget *widget;
! gpointer client_data;
! {
! xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data;
!
! if (xg_crazy_callback_abort) return;
! if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
! }
!
! /* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
! 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)
! FRAME_PTR f;
! widget_value *first_wv;
! int x;
! int y;
! int for_click;
! {
! int i;
! GtkWidget *menu;
! GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */
! struct next_popup_x_y popup_x_y;
!
! xg_crazy_callback_abort = 1;
! menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
! G_CALLBACK (popup_selection_callback),
! G_CALLBACK (popup_deactivate_callback),
! G_CALLBACK (menu_highlight_callback));
! xg_crazy_callback_abort = 0;
!
! for (i = 0; i < 5; i++)
! if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
! break;
!
! if (! for_click)
! {
! /* Not invoked by a click. pop up at x/y. */
! pos_func = menu_position_func;
!
! /* Adjust coordinates to be root-window-relative. */
! x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
! y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
!
! popup_x_y.x = x;
! popup_x_y.y = y;
! }
!
! /* Display the menu. */
! gtk_widget_show_all (menu);
! gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0);
!
! xg_did_tearoff = 0;
! /* Set this to one. popup_widget_loop increases it by one, so it becomes
! two. show_help_echo uses this to detect popup menus. */
! popup_activated_flag = 1;
! /* Process events that apply to the menu. */
! popup_widget_loop ();
!
! if (xg_did_tearoff)
! xg_keep_popup (menu, xg_did_tearoff);
! else
! gtk_widget_destroy (menu);
!
! /* Must reset this manually because the button release event is not passed
! to Emacs event loop. */
! FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
! }
!
! #else /* not USE_GTK */
/* We need a unique id for each widget handled by the Lucid Widget
library.
***************
*** 2042,2049 ****
next_menubar_widget_id. */
LWLIB_ID widget_id_tick;
- static Lisp_Object *volatile menu_item_selection;
-
static void
popup_selection_callback (widget, id, client_data)
Widget widget;
--- 2351,2356 ----
***************
*** 2053,2058 ****
--- 2360,2435 ----
menu_item_selection = (Lisp_Object *) client_data;
}
+ /* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
+ 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)
+ FRAME_PTR f;
+ widget_value *first_wv;
+ int x;
+ int y;
+ int for_click;
+ {
+ int i;
+ Arg av[2];
+ int ac = 0;
+ XButtonPressedEvent dummy;
+ LWLIB_ID menu_id;
+ Widget menu;
+ Window child;
+
+ menu_id = widget_id_tick++;
+ menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
+ f->output_data.x->widget, 1, 0,
+ popup_selection_callback,
+ popup_deactivate_callback,
+ menu_highlight_callback);
+
+ 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;
+
+ /* Adjust coordinates to be root-window-relative. */
+ x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+
+ dummy.x_root = x;
+ dummy.y_root = y;
+
+ dummy.state = 0;
+ dummy.button = 0;
+ for (i = 0; i < 5; i++)
+ if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
+ dummy.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);
+ popup_activated_flag = 1;
+
+ /* Process events that apply to the menu. */
+ popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0);
+
+ /* 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
+ we need to delete the widgets or multiple ones will pile up. */
+ lw_destroy_all_widgets (menu_id);
+ }
+
+ #endif /* not USE_GTK */
+
static Lisp_Object
xmenu_show (f, x, y, for_click, keymaps, title, error)
FRAME_PTR f;
***************
*** 2064,2080 ****
char **error;
{
int i;
- LWLIB_ID menu_id;
- Widget menu;
- Arg av[2];
- int ac = 0;
widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
widget_value **submenu_stack
= (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
Lisp_Object *subprefix_stack
= (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
int submenu_depth = 0;
- XButtonPressedEvent dummy;
int first_pane;
--- 2441,2452 ----
***************
*** 2266,2335 ****
first_wv->contents = wv_title;
}
- /* Actually create the menu. */
- menu_id = widget_id_tick++;
- menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
- f->output_data.x->widget, 1, 0,
- popup_selection_callback,
- popup_deactivate_callback,
- menu_highlight_callback);
-
- /* See if whe positions are up to date. Temporary code to be removed
- when we are sure positions are always up to date. */
- {
- int real_x, real_y;
- x_real_positions (f, &real_x, &real_y);
-
- if (real_x != f->output_data.x->left_pos ||
- real_y != f->output_data.x->top_pos)
- abort ();
- }
-
- 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;
-
- /* Adjust coordinates to be root-window-relative. */
- x += f->output_data.x->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- y += f->output_data.x->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-
- dummy.x_root = x;
- dummy.y_root = y;
- dummy.state = 0;
- dummy.button = 0;
- for (i = 0; i < 5; i++)
- if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
- dummy.button = i;
-
- /* Don't allow any geometry request from the user. */
- XtSetArg (av[ac], XtNgeometry, 0); ac++;
- XtSetValues (menu, av, ac);
-
- /* Free the widget_value objects we used to specify the contents. */
- free_menubar_widget_value_tree (first_wv);
-
/* No selection has been chosen yet. */
menu_item_selection = 0;
! /* Display the menu. */
! lw_popup_menu (menu, (XEvent *) &dummy);
! popup_activated_flag = 1;
! /* Process events that apply to the menu. */
! popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0);
!
! /* 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
! we need to delete the widgets or multiple ones will pile up. */
! lw_destroy_all_widgets (menu_id);
/* Find the selected item, and its pane, to return
the proper value. */
--- 2638,2651 ----
first_wv->contents = wv_title;
}
/* No selection has been chosen yet. */
menu_item_selection = 0;
! /* Actually create and show the menu until popped down. */
! create_and_show_popup_menu (f, first_wv, x, y, for_click);
! /* Free the widget_value objects we used to specify the contents. */
! free_menubar_widget_value_tree (first_wv);
/* Find the selected item, and its pane, to return
the proper value. */
***************
*** 2389,2394 ****
--- 2705,2752 ----
return Qnil;
}
+ #ifdef USE_GTK
+ static void
+ dialog_selection_callback (widget, client_data)
+ GtkWidget *widget;
+ gpointer client_data;
+ {
+ /* The EMACS_INT cast avoids a warning. There's no problem
+ as long as pointers have enough bits to hold small integers. */
+ if ((int) (EMACS_INT) client_data != -1)
+ menu_item_selection = (Lisp_Object *) client_data;
+
+ popup_activated_flag = 0;
+ }
+
+ /* Pop up the dialog for frame F defined by FIRST_WV and loop until the
+ 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;
+ {
+ GtkWidget *menu;
+
+ menu = xg_create_widget ("dialog", first_wv->name, f, first_wv,
+ G_CALLBACK (dialog_selection_callback),
+ G_CALLBACK (popup_deactivate_callback),
+ 0);
+
+ if (menu)
+ {
+ /* Display the menu. */
+ gtk_widget_show_all (menu);
+
+ /* Process events that apply to the menu. */
+ popup_widget_loop ();
+
+ gtk_widget_destroy (menu);
+ }
+ }
+
+ #else /* not USE_GTK */
static void
dialog_selection_callback (widget, id, client_data)
Widget widget;
***************
*** 2399,2410 ****
--- 2757,2770 ----
as long as pointers have enough bits to hold small integers. */
if ((int) (EMACS_INT) client_data != -1)
menu_item_selection = (Lisp_Object *) client_data;
+
BLOCK_INPUT;
lw_destroy_all_widgets (id);
UNBLOCK_INPUT;
popup_activated_flag = 0;
}
+
/* ARG is the LWLIB ID of the dialog box, represented
as a Lisp object as (HIGHPART . LOWPART). */
***************
*** 2421,2426 ****
--- 2781,2826 ----
return Qnil;
}
+
+ /* Pop up the dialog for frame F defined by FIRST_WV and loop until the
+ 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;
+ {
+ LWLIB_ID dialog_id;
+
+ dialog_id = widget_id_tick++;
+ lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
+ f->output_data.x->widget, 1, 0,
+ dialog_selection_callback, 0, 0);
+ lw_modify_all_widgets (dialog_id, first_wv->contents, True);
+
+ /* Display the dialog box. */
+ lw_pop_up_all_widgets (dialog_id);
+ popup_activated_flag = 1;
+
+ /* Process events that apply to the dialog box.
+ Also handle timers. */
+ {
+ int count = SPECPDL_INDEX ();
+ int fact = 4 * sizeof (LWLIB_ID);
+
+ /* xdialog_show_unwind is responsible for popping the dialog box down. */
+ record_unwind_protect (xdialog_show_unwind,
+ Fcons (make_number (dialog_id >> (fact)),
+ make_number (dialog_id & ~(-1 << (fact)))));
+
+ popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id,
1);
+
+ unbind_to (count, Qnil);
+ }
+ }
+
+ #endif /* not USE_GTK */
+
static char * button_names [] = {
"button1", "button2", "button3", "button4", "button5",
"button6", "button7", "button8", "button9", "button10" };
***************
*** 2433,2439 ****
char **error;
{
int i, nb_buttons=0;
- LWLIB_ID dialog_id;
char dialog_name[6];
widget_value *wv, *first_wv = 0, *prev_wv = 0;
--- 2833,2838 ----
***************
*** 2543,2580 ****
first_wv = wv;
}
- /* Actually create the dialog. */
- dialog_id = widget_id_tick++;
- lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
- f->output_data.x->widget, 1, 0,
- dialog_selection_callback, 0, 0);
- lw_modify_all_widgets (dialog_id, first_wv->contents, True);
- /* Free the widget_value objects we used to specify the contents. */
- free_menubar_widget_value_tree (first_wv);
-
/* No selection has been chosen yet. */
menu_item_selection = 0;
! /* Display the dialog box. */
! lw_pop_up_all_widgets (dialog_id);
! popup_activated_flag = 1;
!
! /* Process events that apply to the dialog box.
! Also handle timers. */
! {
! int count = SPECPDL_INDEX ();
!
! /* xdialog_show_unwind is responsible for popping the dialog box down. */
! record_unwind_protect (xdialog_show_unwind,
! Fcons (make_number (dialog_id >> (4 * sizeof
(LWLIB_ID))),
! make_number (dialog_id & ~(-1 << (4 * sizeof
(LWLIB_ID))))));
! popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id,
1);
!
! unbind_to (count, Qnil);
! }
!
! /* Find the selected item and pane, and return the corresponding value. */
if (menu_item_selection != 0)
{
Lisp_Object prefix;
--- 2942,2958 ----
first_wv = wv;
}
/* No selection has been chosen yet. */
menu_item_selection = 0;
! /* Actually create and show the dialog. */
! create_and_show_dialog (f, first_wv);
! /* Free the widget_value objects we used to specify the contents. */
! free_menubar_widget_value_tree (first_wv);
!
! /* Find the selected item, and its pane, to return
! the proper value. */
if (menu_item_selection != 0)
{
Lisp_Object prefix;
***************
*** 2619,2625 ****
return Qnil;
}
! #else /* not USE_X_TOOLKIT */
/* The frame of the last activated non-toolkit menu bar.
Used to generate menu help events. */
--- 2997,3003 ----
return Qnil;
}
! #else /* not USE_X_TOOLKIT && not USE_GTK */
/* The frame of the last activated non-toolkit menu bar.
Used to generate menu help events. */
- [Emacs-diffs] Changes to emacs/src/xmenu.c,
Kenichi Handa <=