emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/xmenu.c [lexbind]


From: Miles Bader
Subject: [Emacs-diffs] Changes to emacs/src/xmenu.c [lexbind]
Date: Wed, 08 Dec 2004 19:38:25 -0500

Index: emacs/src/xmenu.c
diff -c emacs/src/xmenu.c:1.230.4.9 emacs/src/xmenu.c:1.230.4.10
*** emacs/src/xmenu.c:1.230.4.9 Fri Nov 12 04:21:15 2004
--- emacs/src/xmenu.c   Wed Dec  8 23:31:37 2004
***************
*** 48,53 ****
--- 48,54 ----
  #include "buffer.h"
  #include "charset.h"
  #include "coding.h"
+ #include "sysselect.h"
  
  #ifdef MSDOS
  #include "msdos.h"
***************
*** 157,164 ****
  static void list_of_panes P_ ((Lisp_Object));
  static void list_of_items P_ ((Lisp_Object));
  
- extern EMACS_TIME timer_check P_ ((int));
- 
  
  /* This holds a Lisp vector that holds the results of decoding
     the keymaps or alist-of-alists that specify a menu.
--- 158,163 ----
***************
*** 289,295 ****
  
  static Lisp_Object
  unuse_menu_items (dummy)
!      int dummy;
  {
    return menu_items_inuse = Qnil;
  }
--- 288,294 ----
  
  static Lisp_Object
  unuse_menu_items (dummy)
!      Lisp_Object dummy;
  {
    return menu_items_inuse = Qnil;
  }
***************
*** 525,531 ****
      return;                   /* Not a menu item.  */
  
    map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
!   
    if (skp->notreal)
      {
        /* We don't want to make a menu, just traverse the keymaps to
--- 524,530 ----
      return;                   /* Not a menu item.  */
  
    map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
! 
    if (skp->notreal)
      {
        /* We don't want to make a menu, just traverse the keymaps to
***************
*** 1099,1105 ****
           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.  */
--- 1098,1104 ----
           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.  */
***************
*** 1115,1123 ****
--- 1114,1188 ----
    }
  #endif
  }
+ 
+ 
+ #ifndef MSDOS
+ 
+ /* Set menu_items_inuse so no other popup menu or dialog is created.  */
+ 
+ void
+ x_menu_set_in_use (in_use)
+      int in_use;
+ {
+   menu_items_inuse = in_use ? Qt : Qnil;
+   popup_activated_flag = in_use;
+ }
+ 
+ /* Wait for an X event to arrive or for a timer to expire.  */
+ 
+ void
+ x_menu_wait_for_event (void *data)
+ {
+   extern EMACS_TIME timer_check P_ ((int));
+ 
+   /* Another way to do this is to register a timer callback, that can be
+      done in GTK and Xt.  But we have to do it like this when using only X
+      anyway, and with callbacks we would have three variants for timer 
handling
+      instead of the small ifdefs below.  */
+ 
+   while (
+ #ifdef USE_X_TOOLKIT
+          ! XtAppPending (Xt_app_con)
+ #elif defined USE_GTK
+          ! gtk_events_pending ()
+ #else
+          ! XPending ((Display*) data)
+ #endif
+          )
+     {
+       EMACS_TIME next_time = timer_check (1);
+       long secs = EMACS_SECS (next_time);
+       long usecs = EMACS_USECS (next_time);
+       SELECT_TYPE read_fds;
+       struct x_display_info *dpyinfo;
+       int n = 0;
+ 
+       FD_ZERO (&read_fds);
+       for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
+         {
+           int fd = ConnectionNumber (dpyinfo->display);
+           FD_SET (fd, &read_fds);
+           if (fd > n) n = fd;
+         }
+ 
+       if (secs < 0 || (secs == 0 && usecs == 0))
+         {
+           /* Sometimes timer_check returns -1 (no timers) even if there are
+              timers.  So do a timeout anyway.  */
+           EMACS_SET_SECS (next_time, 1);
+           EMACS_SET_USECS (next_time, 0);
+         }
+ 
+       select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, 
&next_time);
+     }
+ }
+ #endif /* ! MSDOS */
+ 
  
  #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
  
+ #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
     and x-popup-dialog; it is not used for the menu bar.
***************
*** 1127,1133 ****
     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, down_on_keypress)
       XEvent *initial_event;
--- 1192,1197 ----
***************
*** 1140,1156 ****
  
    while (popup_activated_flag)
      {
-        /* If we have no events to run, consider timers.  */    
-        if (do_timers && !XtAppPending (Xt_app_con))    
-          timer_check (1);      
- 
         if (initial_event)
          {
            event = *initial_event;
            initial_event = 0;
          }
        else
!         XtAppNextEvent (Xt_app_con, &event);
  
        /* Make sure we don't consider buttons grabbed after menu goes.
           And make sure to deactivate for any ButtonRelease,
--- 1204,1219 ----
  
    while (popup_activated_flag)
      {
         if (initial_event)
          {
            event = *initial_event;
            initial_event = 0;
          }
        else
!         {
!           if (do_timers) x_menu_wait_for_event (0);
!           XtAppNextEvent (Xt_app_con, &event);
!         }
  
        /* Make sure we don't consider buttons grabbed after menu goes.
           And make sure to deactivate for any ButtonRelease,
***************
*** 1195,1208 ****
  #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 ();
      }
  }
--- 1258,1275 ----
  #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 (do_timers, widget)
!      int do_timers;
!      GtkWidget *widget;
  {
    ++popup_activated_flag;
  
    /* Process events in the Gtk event loop until done.  */
    while (popup_activated_flag)
      {
+       if (do_timers) x_menu_wait_for_event (0);
        gtk_main_iteration ();
      }
  }
***************
*** 2329,2335 ****
    GtkRequisition req;
    int disp_width = FRAME_X_DISPLAY_INFO (data->f)->width;
    int disp_height = FRAME_X_DISPLAY_INFO (data->f)->height;
!   
    *x = data->x;
    *y = data->y;
  
--- 2396,2402 ----
    GtkRequisition req;
    int disp_width = FRAME_X_DISPLAY_INFO (data->f)->width;
    int disp_height = FRAME_X_DISPLAY_INFO (data->f)->height;
! 
    *x = data->x;
    *y = data->y;
  
***************
*** 2353,2358 ****
--- 2420,2438 ----
    if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
  }
  
+ static Lisp_Object
+ pop_down_menu (arg)
+      Lisp_Object arg;
+ {
+   struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+ 
+   popup_activated_flag = 0;
+   BLOCK_INPUT;
+   gtk_widget_destroy (GTK_WIDGET (p->pointer));
+   UNBLOCK_INPUT;
+   return Qnil;
+ }
+ 
  /* 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.  */
***************
*** 2368,2373 ****
--- 2448,2454 ----
    GtkWidget *menu;
    GtkMenuPositionFunc pos_func = 0;  /* Pop up at pointer.  */
    struct next_popup_x_y popup_x_y;
+   int specpdl_count = SPECPDL_INDEX ();
  
    xg_crazy_callback_abort = 1;
    menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
***************
*** 2398,2410 ****
    gtk_widget_show_all (menu);
    gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 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 ();
  
!   gtk_widget_destroy (menu);
  
    /* Must reset this manually because the button release event is not passed
       to Emacs event loop. */
--- 2479,2493 ----
    gtk_widget_show_all (menu);
    gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0);
  
+   record_unwind_protect (pop_down_menu, make_save_value (menu, 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 (1, menu);
  
!   unbind_to (specpdl_count, Qnil);
  
    /* Must reset this manually because the button release event is not passed
       to Emacs event loop. */
***************
*** 2432,2437 ****
--- 2515,2538 ----
    menu_item_selection = (Lisp_Object *) client_data;
  }
  
+ /* ARG is the LWLIB ID of the dialog box, represented
+    as a Lisp object as (HIGHPART . LOWPART).  */
+ 
+ static Lisp_Object
+ pop_down_menu (arg)
+      Lisp_Object arg;
+ {
+   LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
+                  | XINT (XCDR (arg)));
+ 
+   BLOCK_INPUT;
+   lw_destroy_all_widgets (id);
+   UNBLOCK_INPUT;
+   popup_activated_flag = 0;
+ 
+   return Qnil;
+ }
+ 
  /* 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.  */
***************
*** 2488,2502 ****
    /* 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, 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 */
--- 2589,2607 ----
    /* Display the menu.  */
    lw_popup_menu (menu, (XEvent *) &dummy);
    popup_activated_flag = 1;
+   
+   {
+     int fact = 4 * sizeof (LWLIB_ID);
+     int specpdl_count = SPECPDL_INDEX ();
+     record_unwind_protect (pop_down_menu,
+                            Fcons (make_number (menu_id >> (fact)),
+                                   make_number (menu_id & ~(-1 << (fact)))));
  
!     /* Process events that apply to the menu.  */
!     popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 
0);
  
!     unbind_to (specpdl_count, Qnil);
!   }
  }
  
  #endif /* not USE_GTK */
***************
*** 2807,2819 ****
  
    if (menu)
      {
        /* Display the menu.  */
        gtk_widget_show_all (menu);
  
        /* Process events that apply to the menu.  */
!       popup_widget_loop ();
  
!       gtk_widget_destroy (menu);
      }
  }
  
--- 2912,2927 ----
  
    if (menu)
      {
+       int specpdl_count = SPECPDL_INDEX ();
+       record_unwind_protect (pop_down_menu, make_save_value (menu, 0));
+ 
        /* Display the menu.  */
        gtk_widget_show_all (menu);
  
        /* Process events that apply to the menu.  */
!       popup_widget_loop (1, menu);
  
!       unbind_to (specpdl_count, Qnil);
      }
  }
  
***************
*** 2836,2858 ****
  }
  
  
- /* ARG is the LWLIB ID of the dialog box, represented
-    as a Lisp object as (HIGHPART . LOWPART).  */
- 
- Lisp_Object
- xdialog_show_unwind (arg)
-      Lisp_Object arg;
- {
-   LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
-                | XINT (XCDR (arg)));
-   BLOCK_INPUT;
-   lw_destroy_all_widgets (id);
-   UNBLOCK_INPUT;
-   popup_activated_flag = 0;
-   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.  */
--- 2944,2949 ----
***************
*** 2880,2886 ****
      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)))));
  
--- 2971,2977 ----
      int fact = 4 * sizeof (LWLIB_ID);
  
      /* xdialog_show_unwind is responsible for popping the dialog box down.  */
!     record_unwind_protect (pop_down_menu,
                             Fcons (make_number (dialog_id >> (fact)),
                                    make_number (dialog_id & ~(-1 << (fact)))));
  
***************
*** 3113,3118 ****
--- 3204,3244 ----
                  Qnil, menu_object, make_number (item), 1);
  }
  
+ static Lisp_Object
+ pop_down_menu (arg)
+      Lisp_Object arg;
+ {
+   struct Lisp_Save_Value *p1 = XSAVE_VALUE (Fcar (arg));
+   struct Lisp_Save_Value *p2 = XSAVE_VALUE (Fcdr (arg));
+   
+   FRAME_PTR f = p1->pointer;
+   XMenu *menu = p2->pointer;
+ 
+   BLOCK_INPUT;
+ #ifndef MSDOS
+   XUngrabPointer (FRAME_X_DISPLAY (f), CurrentTime);
+   XUngrabKeyboard (FRAME_X_DISPLAY (f), CurrentTime);
+ #endif
+   XMenuDestroy (FRAME_X_DISPLAY (f), menu);
+ 
+ #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));
+ 
+   /* 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;
+ 
+ #endif /* HAVE_X_WINDOWS */
+ 
+   UNBLOCK_INPUT;
+ 
+   return Qnil;
+ }
+ 
  
  static Lisp_Object
  xmenu_show (f, x, y, for_click, keymaps, title, error)
***************
*** 3134,3139 ****
--- 3260,3266 ----
    int maxwidth;
    int dummy_int;
    unsigned int dummy_uint;
+   int specpdl_count = SPECPDL_INDEX ();
  
    *error = 0;
    if (menu_items_n_panes == 0)
***************
*** 3323,3341 ****
    XMenuSetFreeze (menu, TRUE);
    pane = selidx = 0;
  
    /* Help display under X won't work because XMenuActivate contains
       a loop that doesn't give Emacs a chance to process it.  */
    menu_help_frame = f;
    status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx,
!                         x, y, ButtonReleaseMask, &datap,
!                         menu_help_callback);
! 
! 
! #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));
! #endif
  
    switch (status)
      {
--- 3450,3469 ----
    XMenuSetFreeze (menu, TRUE);
    pane = selidx = 0;
  
+ #ifndef MSDOS
+   XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
+ #endif
+   
+   record_unwind_protect (pop_down_menu,
+                          Fcons (make_save_value (f, 0),
+                                 make_save_value (menu, 0)));
+ 
    /* Help display under X won't work because XMenuActivate contains
       a loop that doesn't give Emacs a chance to process it.  */
    menu_help_frame = f;
    status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx,
!                           x, y, ButtonReleaseMask, &datap,
!                           menu_help_callback);
  
    switch (status)
      {
***************
*** 3386,3400 ****
        entry = Qnil;
        break;
      }
-   XMenuDestroy (FRAME_X_DISPLAY (f), menu);
  
! #ifdef HAVE_X_WINDOWS
!   /* 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;
! #endif
  
    return entry;
  }
--- 3514,3521 ----
        entry = Qnil;
        break;
      }
  
!   unbind_to (specpdl_count, Qnil);
  
    return entry;
  }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]