emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] emacs/src ChangeLog gtkutil.c keyboard.c keyboa...


From: Jan Djärv
Subject: [Emacs-diffs] emacs/src ChangeLog gtkutil.c keyboard.c keyboa...
Date: Tue, 10 Nov 2009 19:06:42 +0000

CVSROOT:        /cvsroot/emacs
Module name:    emacs
Changes by:     Jan Djärv <jhd> 09/11/10 19:06:42

Modified files:
        src            : ChangeLog gtkutil.c keyboard.c keyboard.h 
                         process.c xmenu.c 

Log message:
        Bug #4574.  Common code for file/font dialog. Handle timers with 
glib-timers.
        
        * keyboard.h: Declare timer_check.
        
        * keyboard.c (timer_check_2): New function that does what the old
        timer_check did.
        (timer_check): Call timer_check_2 until -1 or a non-zero time is
        returned, i.e. don't return -1 with timers pending.
        
        * process.c: Remove extern declaration of timer_check.
        
        * xmenu.c (x_menu_wait_for_event): Remove code that did a timeout
        even if timer_check returned -1.
        
        * gtkutil.c (xg_dialog_response_cb): data is now a struct xg_dialog_data
        (pop_down_dialog): Destroy widget (if any), cancel timer and unref
        the event loop.
        (xg_maybe_add_timer, xg_dialog_run): New functions (bug #4574).
        (xg_get_file_name, xg_get_font_name): Call xg_dialog_run (bug #4574).
        Destroy the dialog after xg_dialog_run.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/emacs/src/ChangeLog?cvsroot=emacs&r1=1.7853&r2=1.7854
http://cvs.savannah.gnu.org/viewcvs/emacs/src/gtkutil.c?cvsroot=emacs&r1=1.162&r2=1.163
http://cvs.savannah.gnu.org/viewcvs/emacs/src/keyboard.c?cvsroot=emacs&r1=1.1020&r2=1.1021
http://cvs.savannah.gnu.org/viewcvs/emacs/src/keyboard.h?cvsroot=emacs&r1=1.94&r2=1.95
http://cvs.savannah.gnu.org/viewcvs/emacs/src/process.c?cvsroot=emacs&r1=1.601&r2=1.602
http://cvs.savannah.gnu.org/viewcvs/emacs/src/xmenu.c?cvsroot=emacs&r1=1.348&r2=1.349

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/emacs/emacs/src/ChangeLog,v
retrieving revision 1.7853
retrieving revision 1.7854
diff -u -b -r1.7853 -r1.7854
--- ChangeLog   10 Nov 2009 18:07:09 -0000      1.7853
+++ ChangeLog   10 Nov 2009 19:06:40 -0000      1.7854
@@ -1,3 +1,24 @@
+2009-11-10  Jan Djärv  <address@hidden>
+
+       * keyboard.h: Declare timer_check.
+
+       * keyboard.c (timer_check_2): New function that does what the old
+       timer_check did.
+       (timer_check): Call timer_check_2 until -1 or a non-zero time is
+       returned, i.e. don't return -1 with timers pending.
+
+       * process.c: Remove extern declaration of timer_check.
+
+       * xmenu.c (x_menu_wait_for_event): Remove code that did a timeout
+       even if timer_check returned -1.
+
+       * gtkutil.c (xg_dialog_response_cb): data is now a struct xg_dialog_data
+       (pop_down_dialog): Destroy widget (if any), cancel timer and unref
+       the event loop.
+       (xg_maybe_add_timer, xg_dialog_run): New functions (bug #4574).
+       (xg_get_file_name, xg_get_font_name): Call xg_dialog_run (bug #4574).
+       Destroy the dialog after xg_dialog_run.
+
 2009-11-10  Stefan Monnier  <address@hidden>
 
        * menu.c (Fx_popup_menu) [HAVE_NS]: Remove unused vars.

Index: gtkutil.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/gtkutil.c,v
retrieving revision 1.162
retrieving revision 1.163
diff -u -b -r1.162 -r1.163
--- gtkutil.c   6 Nov 2009 08:30:45 -0000       1.162
+++ gtkutil.c   10 Nov 2009 19:06:41 -0000      1.163
@@ -1224,35 +1224,17 @@
   return wdialog;
 }
 
-
-
-/***********************************************************************
-                      File dialog functions
- ***********************************************************************/
-/* Return non-zero if the old file selection dialog is being used.
-   Return zero if not.  */
-
-int
-xg_uses_old_file_dialog ()
+struct xg_dialog_data
 {
-#ifdef HAVE_GTK_FILE_BOTH
-  extern int x_gtk_use_old_file_dialog;
-  return x_gtk_use_old_file_dialog;
-#else /* ! HAVE_GTK_FILE_BOTH */
-
-#ifdef HAVE_GTK_FILE_SELECTION_NEW
-  return 1;
-#else
-  return 0;
-#endif
-
-#endif /* ! HAVE_GTK_FILE_BOTH */
-}
-
+  GMainLoop *loop;
+  int response;
+  GtkWidget *w;
+  guint timerid;
+};
 
 /* Function that is called when the file or font dialogs pop down.
    W is the dialog widget, RESPONSE is the response code.
-   USER_DATA is what we passed in to g_signal_connect (pointer to int).  */
+   USER_DATA is what we passed in to g_signal_connect.  */
 
 static void
 xg_dialog_response_cb (w,
@@ -1262,8 +1244,9 @@
      gint response;
      gpointer user_data;
 {
-  int *ptr = (int *) user_data;
-  *ptr = response;
+  struct xg_dialog_data *dd = (struct xg_dialog_data *)user_data;
+  dd->response = response;
+  g_main_loop_quit (dd->loop);
 }
 
 
@@ -1274,12 +1257,112 @@
      Lisp_Object arg;
 {
   struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+  struct xg_dialog_data *dd = (struct xg_dialog_data *) p->pointer;
+
   BLOCK_INPUT;
-  gtk_widget_destroy (GTK_WIDGET (p->pointer));
+  if (dd->w) gtk_widget_destroy (dd->w);
+  if (dd->timerid != 0) g_source_remove (dd->timerid);
+
+  g_main_loop_quit (dd->loop);
+  g_main_loop_unref (dd->loop);
+  
   UNBLOCK_INPUT;
+
   return Qnil;
 }
 
+/* If there are any emacs timers pending, add a timeout to main loop in DATA.
+    We pass in DATA as gpointer* so we can use this as a callback.  */
+
+static gboolean
+xg_maybe_add_timer (data)
+     gpointer data;
+{
+  struct xg_dialog_data *dd = (struct xg_dialog_data *) data;
+  EMACS_TIME next_time = timer_check (1);
+  long secs = EMACS_SECS (next_time);
+  long usecs = EMACS_USECS (next_time);
+
+  dd->timerid = 0;
+
+  if (secs >= 0 && usecs >= 0 && secs < ((guint)-1)/1000)
+    {
+      dd->timerid = g_timeout_add (secs * 1000 + usecs/1000,
+                                   xg_maybe_add_timer,
+                                   dd);
+    }
+  return FALSE;
+}
+
+     
+/* Pops up a modal dialog W and waits for response.
+   We don't use gtk_dialog_run because we want to process emacs timers.
+   The dialog W is not destroyed when this function returns.  */
+
+static int
+xg_dialog_run (f, w)
+     FRAME_PTR f;
+     GtkWidget *w;
+
+{
+  int count = SPECPDL_INDEX ();
+  struct xg_dialog_data dd;
+
+  xg_set_screen (w, f);
+  gtk_window_set_transient_for (GTK_WINDOW (w),
+                                GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+  gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE);
+  gtk_window_set_modal (GTK_WINDOW (w), TRUE);
+
+  dd.loop = g_main_loop_new (NULL, FALSE);
+  dd.response = GTK_RESPONSE_CANCEL;
+  dd.w = w;
+  dd.timerid = 0;
+
+  g_signal_connect (G_OBJECT (w),
+                    "response",
+                    G_CALLBACK (xg_dialog_response_cb),
+                    &dd);
+  /* Don't destroy the widget if closed by the window manager close button.  */
+  g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL);
+  gtk_widget_show (w);
+
+  record_unwind_protect (pop_down_dialog, make_save_value (&dd, 0));
+
+  (void) xg_maybe_add_timer (&dd);
+  g_main_loop_run (dd.loop);
+  
+  dd.w = 0;
+  unbind_to (count, Qnil);
+
+  return dd.response;
+}
+
+
+/***********************************************************************
+                      File dialog functions
+ ***********************************************************************/
+/* Return non-zero if the old file selection dialog is being used.
+   Return zero if not.  */
+
+int
+xg_uses_old_file_dialog ()
+{
+#ifdef HAVE_GTK_FILE_BOTH
+  extern int x_gtk_use_old_file_dialog;
+  return x_gtk_use_old_file_dialog;
+#else /* ! HAVE_GTK_FILE_BOTH */
+
+#ifdef HAVE_GTK_FILE_SELECTION_NEW
+  return 1;
+#else
+  return 0;
+#endif
+
+#endif /* ! HAVE_GTK_FILE_BOTH */
+}
+
+
 typedef char * (*xg_get_file_func) P_ ((GtkWidget *));
 
 #ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW
@@ -1537,7 +1620,6 @@
      int mustmatch_p, only_dir_p;
 {
   GtkWidget *w = 0;
-  int count = SPECPDL_INDEX ();
   char *fn = 0;
   int filesel_done = 0;
   xg_get_file_func func;
@@ -1571,29 +1653,9 @@
 
 #endif /* HAVE_GTK_FILE_BOTH */
 
-  xg_set_screen (w, f);
   gtk_widget_set_name (w, "emacs-filedialog");
-  gtk_window_set_transient_for (GTK_WINDOW (w),
-                                GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
-  gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE);
-  gtk_window_set_modal (GTK_WINDOW (w), TRUE);
 
-  g_signal_connect (G_OBJECT (w),
-                    "response",
-                    G_CALLBACK (xg_dialog_response_cb),
-                    &filesel_done);
-
-  /* Don't destroy the widget if closed by the window manager close button.  */
-  g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL);
-
-  gtk_widget_show (w);
-
-  record_unwind_protect (pop_down_dialog, make_save_value (w, 0));
-  while (! filesel_done)
-    {
-      x_menu_wait_for_event (0);
-      gtk_main_iteration ();
-    }
+  filesel_done = xg_dialog_run (f, w);
 
 #if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN)
   sigunblock (sigmask (__SIGRTMIN));
@@ -1602,8 +1664,7 @@
   if (filesel_done == GTK_RESPONSE_OK)
     fn = (*func) (w);
 
-  unbind_to (count, Qnil);
-
+  gtk_widget_destroy (w);
   return fn;
 }
 
@@ -1622,8 +1683,7 @@
      FRAME_PTR f;
      char *default_name;
 {
-  GtkWidget *w = 0;
-  int count = SPECPDL_INDEX ();
+  GtkWidget *w;
   char *fontname = NULL;
   int done = 0;
 
@@ -1637,27 +1697,9 @@
   gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (w),
                                            default_name);
 
-  xg_set_screen (w, f);
   gtk_widget_set_name (w, "emacs-fontdialog");
-  gtk_window_set_transient_for (GTK_WINDOW (w),
-                                GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
-  gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE);
-  gtk_window_set_modal (GTK_WINDOW (w), TRUE);
-
-  g_signal_connect (G_OBJECT (w), "response",
-                   G_CALLBACK (xg_dialog_response_cb), &done);
-
-  /* Don't destroy the widget if closed by the window manager close button.  */
-  g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL);
-
-  gtk_widget_show (w);
 
-  record_unwind_protect (pop_down_dialog, make_save_value (w, 0));
-  while (!done)
-    {
-      x_menu_wait_for_event (0);
-      gtk_main_iteration ();
-    }
+  done = xg_dialog_run (f, w);
 
 #if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN)
   sigunblock (sigmask (__SIGRTMIN));
@@ -1665,10 +1707,9 @@
 
   if (done == GTK_RESPONSE_OK)
     fontname = gtk_font_selection_dialog_get_font_name
-      ((GtkFontSelectionDialog *) w);
-
-  unbind_to (count, Qnil);
+      (GTK_FONT_SELECTION_DIALOG (w));
 
+  gtk_widget_destroy (w);
   return fontname;
 }
 #endif /* HAVE_FREETYPE */

Index: keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.1020
retrieving revision 1.1021
diff -u -b -r1.1020 -r1.1021
--- keyboard.c  9 Nov 2009 06:21:04 -0000       1.1020
+++ keyboard.c  10 Nov 2009 19:06:41 -0000      1.1021
@@ -4509,19 +4509,16 @@
    disregard elements that are not proper timers.  Do not make a circular
    timer list for the time being.
 
-   Returns the number of seconds to wait until the next timer fires.  If a
-   timer is triggering now, return zero seconds.
-   If no timer is active, return -1 seconds.
+   Returns the time to wait until the next timer fires.  If a
+   timer is triggering now, return zero.
+   If no timer is active, return -1.
 
    If a timer is ripe, we run it, with quitting turned off.
+   In that case we return 0 to indicate that a new timer_check_2 call
+   should be done.  */
 
-   DO_IT_NOW is now ignored.  It used to mean that we should
-   run the timer directly instead of queueing a timer-event.
-   Now we always run timers directly.  */
-
-EMACS_TIME
-timer_check (do_it_now)
-     int do_it_now;
+static EMACS_TIME
+timer_check_2 ()
 {
   EMACS_TIME nexttime;
   EMACS_TIME now, idleness_now;
@@ -4685,7 +4682,12 @@
 
              /* Since we have handled the event,
                 we don't need to tell the caller to wake up and do it.  */
+              /* But the caller must still wait for the next timer, so
+                 return 0 to indicate that.  */
            }
+
+          EMACS_SET_SECS (nexttime, 0);
+          EMACS_SET_USECS (nexttime, 0);
        }
       else
        /* When we encounter a timer that is still waiting,
@@ -4702,6 +4704,35 @@
   return nexttime;
 }
 
+
+/* Check whether a timer has fired.  To prevent larger problems we simply
+   disregard elements that are not proper timers.  Do not make a circular
+   timer list for the time being.
+
+   Returns the time to wait until the next timer fires.
+   If no timer is active, return -1.
+
+   As long as any timer is ripe, we run it.
+
+   DO_IT_NOW is now ignored.  It used to mean that we should
+   run the timer directly instead of queueing a timer-event.
+   Now we always run timers directly.  */
+
+EMACS_TIME
+timer_check (do_it_now)
+     int do_it_now;
+{
+  EMACS_TIME nexttime;
+
+  do 
+    {
+      nexttime = timer_check_2 ();
+    }
+  while (EMACS_SECS (nexttime) == 0 && EMACS_USECS (nexttime) == 0);
+
+  return nexttime;
+}
+
 DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
        doc: /* Return the current length of Emacs idleness, or nil.
 The value when Emacs is idle is a list of three integers.  The first has

Index: keyboard.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.h,v
retrieving revision 1.94
retrieving revision 1.95
diff -u -b -r1.94 -r1.95
--- keyboard.h  9 Nov 2009 06:21:03 -0000       1.94
+++ keyboard.h  10 Nov 2009 19:06:41 -0000      1.95
@@ -488,6 +488,7 @@
 
 extern int tty_read_avail_input P_ ((struct terminal *, int,
                                      struct input_event *));
+extern EMACS_TIME timer_check P_ ((int));
 
 /* arch-tag: 769cbade-1ba9-4950-b886-db265b061aa3
    (do not change this comment) */

Index: process.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/process.c,v
retrieving revision 1.601
retrieving revision 1.602
diff -u -b -r1.601 -r1.602
--- process.c   6 Nov 2009 06:50:58 -0000       1.601
+++ process.c   10 Nov 2009 19:06:41 -0000      1.602
@@ -296,7 +296,6 @@
 static Lisp_Object get_process ();
 static void exec_sentinel ();
 
-extern EMACS_TIME timer_check ();
 extern int timers_run;
 
 /* Mask of bits indicating the descriptors that we wait for input on.  */

Index: xmenu.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xmenu.c,v
retrieving revision 1.348
retrieving revision 1.349
diff -u -b -r1.348 -r1.349
--- xmenu.c     10 Nov 2009 07:58:59 -0000      1.348
+++ xmenu.c     10 Nov 2009 19:06:42 -0000      1.349
@@ -405,8 +405,6 @@
 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
@@ -422,7 +420,7 @@
 #endif
          )
     {
-      EMACS_TIME next_time = timer_check (1);
+      EMACS_TIME next_time = timer_check (1), *ntp;
       long secs = EMACS_SECS (next_time);
       long usecs = EMACS_USECS (next_time);
       SELECT_TYPE read_fds;
@@ -437,15 +435,12 @@
           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);
-        }
+      if (secs < 0 && usecs < 0)
+        ntp = 0;
+      else
+        ntp = &next_time;
 
-      select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, 
&next_time);
+      select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, ntp);
     }
 }
 #endif /* ! MSDOS */




reply via email to

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