-\f
-#ifdef HAVE_X_WINDOWS
-/* Return the mouse position in *X and *Y. The coordinates are window
- relative for the edit window in frame F.
- This is for Fx_popup_menu. The mouse_position_hook can not
- be used for X, as it returns window relative coordinates
- for the window where the mouse is in. This could be the menu bar,
- the scroll bar or the edit window. Fx_popup_menu needs to be
- sure it is the edit window. */
-void
-mouse_position_for_popup (FRAME_PTR f, int *x, int *y)
-{
- Window root, dummy_window;
- int dummy;
-
- if (! FRAME_X_P (f))
- emacs_abort ();
-
- block_input ();
-
- XQueryPointer (FRAME_X_DISPLAY (f),
- DefaultRootWindow (FRAME_X_DISPLAY (f)),
-
- /* The root window which contains the pointer. */
- &root,
-
- /* Window pointer is on, not used */
- &dummy_window,
-
- /* The position on that root window. */
- x, y,
-
- /* x/y in dummy_window coordinates, not used. */
- &dummy, &dummy,
-
- /* Modifier keys and pointer buttons, about which
- we don't care. */
- (unsigned int *) &dummy);
-
- unblock_input ();
-
- /* xmenu_show expects window coordinates, not root window
- coordinates. Translate. */
- *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
- *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
-}
-
-#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)
-{
- FRAME_PTR 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. */
- FRAME_PTR 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, x_pixel_width (f) / 2);
- XSETINT (y, x_pixel_height (f) / 2);
- newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil));
-
- return Fx_popup_menu (newpos,
- Fcons (Fcar (contents), Fcons (contents, Qnil)));
- }
-#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 (unuse_menu_items, Qnil);
-
- 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 = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil));
-
- list_of_panes (Fcons (contents, Qnil));
-
- /* 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
-}
-