/* X Communication module for terminals which understand the X protocol.
-Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2013 Free Software
+Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2014 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
#endif /* HAVE_X_WINDOWS */
-#ifdef HAVE_MENUS
-
-DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
- 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 (DIALOG 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.)
-
-If HEADER is non-nil, the frame title for the box is "Information",
-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. */)
- (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
-{
- struct frame *f = NULL;
- Lisp_Object window;
-
- /* Decode the first argument: find the window or frame to use. */
- if (EQ (position, Qt)
- || (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. */
- struct frame *new_f = SELECTED_FRAME ();
- Lisp_Object bar_window;
- enum scroll_bar_part part;
- Time time;
- Lisp_Object x, y;
-
- (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time);
-
- if (new_f != 0)
- XSETFRAME (window, new_f);
- else
- window = selected_window;
-#endif
- window = selected_window;
- }
- else if (CONSP (position))
- {
- Lisp_Object tem = XCAR (position);
- if (CONSP (tem))
- window = Fcar (XCDR (position));
- else
- {
- tem = Fcar (XCDR (position)); /* EVENT_START (position) */
- window = Fcar (tem); /* POSN_WINDOW (tem) */
- }
- }
- else if (WINDOWP (position) || FRAMEP (position))
- window = position;
- else
- window = Qnil;
-
- /* Decode where to put the menu. */
-
- if (FRAMEP (window))
- f = XFRAME (window);
- else if (WINDOWP (window))
- {
- 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);
-
- check_window_system (f);
-
- /* Force a redisplay before showing the dialog. If a frame is created
- just before showing the dialog, its contents may not have been fully
- drawn, as this depends on timing of events from the X server. Redisplay
- is not done when a dialog is shown. If redisplay could be done in the
- X event loop (i.e. the X event loop does not run in a signal handler)
- this would not be needed.
-
- Do this before creating the widget value that points to Lisp
- string contents, because Fredisplay may GC and relocate them. */
- Fredisplay (Qt);
-
-#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
- /* Display a menu with these alternatives
- in the middle of frame F. */
- {
- Lisp_Object x, y, frame, newpos;
- XSETFRAME (frame, f);
- XSETINT (x, FRAME_PIXEL_WIDTH (f) / 2);
- XSETINT (y, FRAME_PIXEL_HEIGHT (f) / 2);
- newpos = list2 (list2 (x, y), frame);
-
- return Fx_popup_menu (newpos,
- list2 (Fcar (contents), contents));
- }
-#else
- {
- Lisp_Object title;
- const char *error_name;
- Lisp_Object selection;
- ptrdiff_t specpdl_count = SPECPDL_INDEX ();
-
- /* Decode the dialog items from what was specified. */
- title = Fcar (contents);
- CHECK_STRING (title);
- record_unwind_protect_void (unuse_menu_items);
-
- if (NILP (Fcar (Fcdr (contents))))
- /* No buttons specified, add an "Ok" button so users can pop down
- the dialog. Also, the lesstif/motif version crashes if there are
- no buttons. */
- contents = list2 (title, Fcons (build_string ("Ok"), Qt));
-
- list_of_panes (list1 (contents));
-
- /* Display them in a dialog box. */
- block_input ();
- selection = xdialog_show (f, 0, title, header, &error_name);
- unblock_input ();
-
- unbind_to (specpdl_count, Qnil);
- discard_menu_items ();
-
- if (error_name) error ("%s", error_name);
- return selection;
- }
-#endif
-}
-
-
#ifndef MSDOS
#if defined USE_GTK || defined USE_MOTIF
memset (&ev, 0, sizeof ev);
ev.xbutton.display = FRAME_X_DISPLAY (f);
ev.xbutton.window = XtWindow (menubar);
- ev.xbutton.root = FRAME_X_DISPLAY_INFO (f)->root_window;
+ ev.xbutton.root = FRAME_DISPLAY_INFO (f)->root_window;
ev.xbutton.time = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
ev.xbutton.button = Button1;
ev.xbutton.x = ev.xbutton.y = FRAME_MENUBAR_HEIGHT (f) / 2;
popup_activate_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
{
popup_activated_flag = 1;
-#ifdef USE_X_TOOLKIT
x_activate_timeout_atimer ();
-#endif
}
#endif
#ifdef USE_GTK
/* If we have detached menus, we must update deep so detached menus
also gets updated. */
- deep_p = deep_p || xg_have_tear_offs ();
+ deep_p = deep_p || xg_have_tear_offs (f);
#endif
if (deep_p)
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));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
}
unblock_input ();
}
{
struct next_popup_x_y *data = user_data;
GtkRequisition req;
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (data->f);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (data->f);
int disp_width = x_display_pixel_width (dpyinfo);
int disp_height = x_display_pixel_height (dpyinfo);
menu pops down.
menu_item_selection will be set to the selection. */
static void
-create_and_show_popup_menu (struct frame *f, widget_value *first_wv, int x, int y,
- bool for_click, Time timestamp)
+create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
+ int x, int y, bool for_click)
{
int i;
GtkWidget *menu;
if (for_click)
{
for (i = 0; i < 5; i++)
- if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
+ if (FRAME_DISPLAY_INFO (f)->grabbed & (1 << i))
break;
+ // If keys aren't grabbed (i.e. a mouse up event), use 0.
+ if (i == 5) i = 0;
}
/* Display the menu. */
gtk_widget_show_all (menu);
gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i,
- timestamp ? timestamp : gtk_get_current_event_time ());
+ FRAME_DISPLAY_INFO (f)->last_user_time);
record_unwind_protect_ptr (pop_down_menu, menu);
/* Must reset this manually because the button release event is not passed
to Emacs event loop. */
- FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
+ FRAME_DISPLAY_INFO (f)->grabbed = 0;
}
#else /* not USE_GTK */
menu_item_selection will be set to the selection. */
static void
create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
- int x, int y, bool for_click, Time timestamp)
+ int x, int y, bool for_click)
{
int i;
Arg av[2];
event->send_event = 0;
event->display = FRAME_X_DISPLAY (f);
event->time = CurrentTime;
- event->root = FRAME_X_DISPLAY_INFO (f)->root_window;
+ event->root = FRAME_DISPLAY_INFO (f)->root_window;
event->window = event->subwindow = event->root;
event->x = x;
event->y = y;
event->state = 0;
event->button = 0;
for (i = 0; i < 5; i++)
- if (FRAME_X_DISPLAY_INFO (f)->grabbed & (1 << i))
+ if (FRAME_DISPLAY_INFO (f)->grabbed & (1 << i))
event->button = i;
/* Don't allow any geometry request from the user. */
make_number (menu_id & ~(-1 << (fact)))));
/* Process events that apply to the menu. */
- popup_get_selection (0, FRAME_X_DISPLAY_INFO (f), menu_id, 1);
+ popup_get_selection (0, FRAME_DISPLAY_INFO (f), menu_id, 1);
unbind_to (specpdl_count, Qnil);
}
Lisp_Object
xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
- Lisp_Object title, const char **error_name, Time timestamp)
+ Lisp_Object title, const char **error_name)
{
int i;
widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
return Qnil;
}
+ block_input ();
+
/* Create a tree of widget_value objects
representing the panes and their items. */
wv = xmalloc_widget_value ();
#endif
wv_title->name = SSDATA (title);
- wv_title->enabled = TRUE;
+ wv_title->enabled = true;
wv_title->button_type = BUTTON_TYPE_NONE;
wv_title->help = Qnil;
wv_title->next = wv_sep1;
record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
/* Actually create and show the menu until popped down. */
- create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp);
+ create_and_show_popup_menu (f, first_wv, x, y, for_click);
unbind_to (specpdl_count, Qnil);
if (!NILP (subprefix_stack[j]))
entry = Fcons (subprefix_stack[j], entry);
}
+ unblock_input ();
return entry;
}
i += MENU_ITEMS_ITEM_LENGTH;
}
}
else if (!for_click)
- /* Make "Cancel" equivalent to C-g. */
- Fsignal (Qquit, Qnil);
+ {
+ unblock_input ();
+ /* Make "Cancel" equivalent to C-g. */
+ Fsignal (Qquit, Qnil);
+ }
+ unblock_input ();
return Qnil;
}
\f
Fcons (make_number (dialog_id >> (fact)),
make_number (dialog_id & ~(-1 << (fact)))));
- popup_get_selection (0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1);
+ popup_get_selection (0, FRAME_DISPLAY_INFO (f), dialog_id, 1);
unbind_to (count, Qnil);
}
return Qnil;
}
+Lisp_Object
+xw_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
+{
+ Lisp_Object title;
+ const char *error_name;
+ Lisp_Object selection;
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+
+ check_window_system (f);
+
+ /* Decode the dialog items from what was specified. */
+ title = Fcar (contents);
+ CHECK_STRING (title);
+ record_unwind_protect_void (unuse_menu_items);
+
+ if (NILP (Fcar (Fcdr (contents))))
+ /* No buttons specified, add an "Ok" button so users can pop down
+ the dialog. Also, the lesstif/motif version crashes if there are
+ no buttons. */
+ contents = list2 (title, Fcons (build_string ("Ok"), Qt));
+
+ list_of_panes (list1 (contents));
+
+ /* Display them in a dialog box. */
+ block_input ();
+ selection = xdialog_show (f, 0, title, header, &error_name);
+ unblock_input ();
+
+ unbind_to (specpdl_count, Qnil);
+ discard_menu_items ();
+
+ if (error_name) error ("%s", error_name);
+ return selection;
+}
+
#else /* not USE_X_TOOLKIT && not USE_GTK */
/* The frame of the last activated non-toolkit menu bar.
#ifdef HAVE_X_WINDOWS
/* Assume the mouse has moved out of the X window.
If it has actually moved in, we will get an EnterNotify. */
- x_mouse_leave (FRAME_X_DISPLAY_INFO (f));
+ x_mouse_leave (FRAME_DISPLAY_INFO (f));
/* State that no mouse buttons are now held.
(The oldXMenu code doesn't track this info for us.)
That is not necessarily true, but the fiction leads to reasonable
results, and it is a pain to ask which are actually held now. */
- FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
+ FRAME_DISPLAY_INFO (f)->grabbed = 0;
#endif /* HAVE_X_WINDOWS */
Lisp_Object
xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
- Lisp_Object title, const char **error_name, Time timestamp)
+ Lisp_Object title, const char **error_name)
{
Window root;
XMenu *menu;
return Qnil;
}
+ block_input ();
+
/* Figure out which root window F is on. */
XGetGeometry (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &root,
&dummy_int, &dummy_int, &dummy_uint, &dummy_uint,
if (menu == NULL)
{
*error_name = "Can't create menu";
+ unblock_input ();
return Qnil;
}
{
XMenuDestroy (FRAME_X_DISPLAY (f), menu);
*error_name = "Can't create pane";
+ unblock_input ();
return Qnil;
}
i += MENU_ITEMS_PANE_LENGTH;
{
XMenuDestroy (FRAME_X_DISPLAY (f), menu);
*error_name = "Can't add selection to menu";
+ unblock_input ();
return Qnil;
}
i += MENU_ITEMS_ITEM_LENGTH;
/* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
the menu was invoked with a mouse event as POSITION). */
if (! for_click)
- Fsignal (Qquit, Qnil);
+ {
+ unblock_input ();
+ Fsignal (Qquit, Qnil);
+ }
break;
}
+ unblock_input ();
unbind_to (specpdl_count, Qnil);
return entry;
#endif /* not USE_X_TOOLKIT */
-#endif /* HAVE_MENUS */
-
#ifndef MSDOS
/* Detect if a dialog or menu has been posted. MSDOS has its own
implementation on msdos.c. */
doc: /* Return t if a menu or popup dialog is active. */)
(void)
{
-#ifdef HAVE_MENUS
return (popup_activated ()) ? Qt : Qnil;
-#else
- return Qnil;
-#endif /* HAVE_MENUS */
}
\f
void
Ffset (intern_c_string ("accelerate-menu"),
intern_c_string (Sx_menu_bar_open_internal.symbol_name));
#endif
-
-#ifdef HAVE_MENUS
- defsubr (&Sx_popup_dialog);
-#endif
}