merge trunk
[bpt/emacs.git] / src / xmenu.c
index 054a52e..c101d9f 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
@@ -192,149 +192,6 @@ mouse_position_for_popup (struct frame *f, int *x, int *y)
 
 #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
@@ -653,9 +510,7 @@ static void
 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
 
@@ -941,7 +796,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
 #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)
@@ -990,7 +845,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
 
       /* Save the frame's previous menu bar contents data.  */
       if (previous_menu_items_used)
-       memcpy (previous_items, XVECTOR (f->menu_bar_vector)->u.contents,
+       memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
                previous_menu_items_used * word_size);
 
       /* Fill in menu_items with the current menu bar contents.
@@ -1311,7 +1166,7 @@ free_frame_menubar (struct frame *f)
          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 ();
     }
@@ -1405,8 +1260,8 @@ pop_down_menu (void *arg)
    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;
@@ -1451,13 +1306,15 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, int x, int
       for (i = 0; i < 5; 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);
 
@@ -1515,7 +1372,7 @@ pop_down_menu (Lisp_Object arg)
    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];
@@ -1594,7 +1451,7 @@ cleanup_widget_value_tree (void *arg)
 
 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;
@@ -1792,7 +1649,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
 #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;
@@ -1807,7 +1664,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
   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);
 
@@ -2170,6 +2027,41 @@ xdialog_show (struct frame *f,
   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.
@@ -2194,7 +2086,7 @@ menu_help_callback (char const *help_string, int pane, int item)
   Lisp_Object pane_name;
   Lisp_Object menu_object;
 
-  first_item = XVECTOR (menu_items)->u.contents;
+  first_item = XVECTOR (menu_items)->contents;
   if (EQ (first_item[0], Qt))
     pane_name = first_item[MENU_ITEMS_PANE_NAME];
   else if (EQ (first_item[0], Qquote))
@@ -2241,7 +2133,7 @@ pop_down_menu (Lisp_Object arg)
 
 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;
@@ -2531,8 +2423,6 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
 
 #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.  */
@@ -2550,11 +2440,7 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
        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
@@ -2574,8 +2460,4 @@ syms_of_xmenu (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
 }