]> git.eshelyaron.com Git - emacs.git/commitdiff
*** empty log message ***
authorGerd Moellmann <gerd@gnu.org>
Tue, 25 Jan 2000 15:59:42 +0000 (15:59 +0000)
committerGerd Moellmann <gerd@gnu.org>
Tue, 25 Jan 2000 15:59:42 +0000 (15:59 +0000)
lisp/ChangeLog
lwlib/ChangeLog
src/ChangeLog
src/atimer.c [new file with mode: 0644]
src/atimer.h [new file with mode: 0644]

index 73972d8f2666701d0b56f1e5cafe7ca1e24360dd..3bee200456653ae0f93205fceb319c7c5211d09a 100644 (file)
@@ -1,3 +1,8 @@
+2000-01-25  Gerd Moellmann  <gerd@gnu.org>
+
+       * scroll-bar.el (scroll-bar-timer): Variable removed.
+       (scroll-bar-toolkit-scroll): Don't use a timer.
+
 2000-01-25  Kenichi Handa  <handa@etl.go.jp>
 
        * language/thai-util.el (thai-composition-function): Delete
index 9563a8f5b924e5444847382aa7bc82fb98e908fd..25dda71e443035d4cd9092233dc85520e0f08c64 100644 (file)
@@ -1,3 +1,11 @@
+2000-01-25  Gerd Moellmann  <gerd@gnu.org>
+
+       * lwlib-Xm.c (make_menu_in_widget): Don't add XmNpopdownCallback,
+       add XmNunmapCallback.
+       (xm_unmap_callback): New function.
+       (xm_pull_down_callback): Call pre-activate callback only if
+       parent is the menu bar.
+
 2000-01-17  Gerd Moellmann  <gerd@gnu.org>
 
        * lwlib-Xm.c (xm_arm_callback): New function.
index 1195c6f20b21c42ef9a877fbbabead096643ed61..adcfb0089f942d099ae6cd1d801c064b38365a71 100644 (file)
@@ -1,3 +1,52 @@
+2000-01-25  Gerd Moellmann  <gerd@gnu.org>
+
+       * sysdep.c (sys_select): Turn atimers off and on instead of
+       recording and restoring old alarm handler
+
+       * process.c (toplevel): Include atimer.h.
+       (create_process_1): Rewritten.
+       (create_process): Use atimers instead of alarm.
+       (wait_reading_process_input) [hpux]: Turn atimers off instead
+       of turning off SIGALRM.
+       (wait_reading_process_input): Turn off atimers instead off
+       calling stop_polling.
+
+       * emacs.c (main): Call init_atimer.
+
+       * keyboard.c (toplevel): Include systime.h and atimer.h.
+       (polling_for_input): Removed because unused.
+       (input_poll_signal) [POLL_FOR_INPUT]: Removed.
+       (poll_timer): New variable.
+       (poll_for_input, poll_for_input_1): New functions.
+       (start_polling, stop_polling): Rewritten.
+
+       * keyboard.h (polling_for_input): Removed.
+       
+       * atimer.h, atimer.c: New files.
+
+       * Makefile.in (obj): Add atimer.o.
+       (atimer.o): New target.
+
+       * blockinput.h (pending_atimers): Add extern declaration.
+       (UNBLOCK_INPUT): Rewritten.  Handle pending atimers.
+
+       * lisp.h (popup_activated_flag): Add extern declaration.
+
+       * xmenu.c (popup_activated_flag): Make externally visible.
+       (popup_activate_callback) [USE_MOTIF]: Increment
+       popup_activated_flag.
+       (popup_deactivate_callback) [USE_MOTIF]: Decrement it.
+
+       * xterm.c (toplevel): Include atimer.h.
+       (toolkit_scroll_bar_interaction): New variable.
+       (Fxt_process_timeouts): Removed.
+       (x_process_timeouts): New function.
+       (xt_action_hook): Clear toolkit_scroll_bar_interaction.
+       (x_send_scroll_bar_event): Set toolkit_scroll_bar_interaction.
+       (x_make_frame_visible): Call poll_for_input_1 instead of
+       input_poll_signal.  Don't call alarm.
+       (x_initialize): Install timer calling x_process_timeouts.
+       
 2000-01-24  Dave Love  <fx@gnu.org>
 
        * irix5-0.h: Don't set LD_SWITCH_SYSTEM -- we use unexelf now.
diff --git a/src/atimer.c b/src/atimer.c
new file mode 100644 (file)
index 0000000..92f5076
--- /dev/null
@@ -0,0 +1,336 @@
+/* Asynchronous timers.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include <config.h>
+#include <lisp.h>
+#include <signal.h>
+#include <syssignal.h>
+#include <systime.h>
+#include <blockinput.h>
+#include <atimer.h>
+#include <stdio.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+/* The ubiquitous min/max macros.  */
+
+#define max(X, Y) ((X) > (Y) ? (X) : (Y))
+#define min(X, Y) ((X) < (Y) ? (X) : (Y))
+
+/* Free-list of atimer structures.  */
+
+static struct atimer *free_atimers;
+
+/* List of active atimers, sorted by expiration time.  The timer that
+   will become ripe next is always at the front of this list.  */
+
+static struct atimer *atimers;
+
+/* Non-zero means alarm_signal_handler has found ripe timers but
+   interrupt_input_blocked was non-zero.  In this case, timer
+   functions are not called until the next UNBLOCK_INPUT because timer
+   functions are expected to call X, and X cannot be assumed to be
+   reentrant.  */
+
+int pending_atimers;
+
+/* Block/unblock SIGALRM.. */
+
+#define BLOCK_ATIMERS   sigblock (sigmask (SIGALRM))
+#define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM))
+
+/* Function prototypes.  */
+
+static void set_alarm P_ ((void));
+static void schedule_atimer P_ ((struct atimer *));
+
+
+/* Start a new atimer of type TYPE.  TIME specifies when the timer is
+   ripe.  FN is the function to call when the timer fires.
+   CLIENT_DATA is stored in the client_data member of the atimer
+   structure returned and so made available to FN when it is called.
+
+   If TYPE is ATIMER_ABSOLUTE, TIME is the absolute time at which the
+   timer fires.
+
+   If TYPE is ATIMER_RELATIVE, the timer is ripe TIME s/us in the
+   future.
+
+   In both cases, the timer is automatically freed after it has fired.
+
+   If TYPE is ATIMER_CONTINUOUS, the timer fires every TIME s/us.
+
+   Value is a pointer to the atimer started.  It can be used in calls
+   to cancel_atimer; don't free it yourself.  */
+
+struct atimer *
+start_atimer (type, time, fn, client_data)
+     enum atimer_type type;
+     EMACS_TIME time;
+     atimer_callback fn;
+     void *client_data;
+{
+  struct atimer *t;
+
+  /* Round TIME up to the next full second if we don't have
+     itimers.  */
+#ifndef HAVE_SETITIMER
+  if (EMACS_USECS (time) != 0)
+    {
+      EMACS_USECS (time) = 0;
+      ++EMACS_SECS (time);
+    }
+#endif /* not HAVE_SETITIMER */
+
+  /* Get an atimer structure from the free-list, or allocate
+     a new one.  */
+  if (free_atimers)
+    {
+      t = free_atimers;
+      free_atimers = t->next;
+    }
+  else
+    t = (struct atimer *) xmalloc (sizeof *t);
+
+  /* Fill the atimer structure.  */
+  bzero (t, sizeof *t);
+  t->type = type;
+  t->fn = fn;
+  t->client_data = client_data;
+
+  BLOCK_ATIMERS;
+
+  /* Compute the timer's expiration time.  */
+  switch (type)
+    {
+    case ATIMER_ABSOLUTE:
+      t->expiration = time;
+      break;
+      
+    case ATIMER_RELATIVE:
+      EMACS_GET_TIME (t->expiration);
+      EMACS_ADD_TIME (t->expiration, t->expiration, time);
+      break;
+      
+    case ATIMER_CONTINUOUS:
+      EMACS_GET_TIME (t->expiration);
+      EMACS_ADD_TIME (t->expiration, t->expiration, time);
+      t->interval = time;
+      break;
+    }
+
+  /* Insert the timer in the list of active atimers.  */
+  schedule_atimer (t);
+  UNBLOCK_ATIMERS;
+
+  /* Arrange for a SIGALRM at the time the next atimer is ripe.  */
+  set_alarm ();
+  
+  return t;
+}
+
+
+/* Cancel and free atimer TIMER.  */
+
+void
+cancel_atimer (timer)
+     struct atimer *timer;
+{
+  struct atimer *t, *prev;
+
+  BLOCK_ATIMERS;
+
+  /* See if TIMER is active.  */
+  for (t = atimers, prev = 0; t && t != timer; t = t->next)
+    ;
+
+  /* If it is, take it off the list of active timers, put in on the
+     free-list.  We don't bother to arrange for setting a different
+     alarm time, since a too early one doesn't hurt.  */
+  if (t)
+    {
+      if (prev)
+       prev->next = t->next;
+      else
+       atimers = t->next;
+
+      t->next = free_atimers;
+      free_atimers = t;
+    }
+
+  UNBLOCK_ATIMERS;
+}
+
+
+/* Arrange for a SIGALRM to arrive when the next timer is ripe.  */
+
+static void
+set_alarm ()
+{
+  
+#if defined (USG) && !defined (POSIX_SIGNALS)
+  /* USG systems forget handlers when they are used;
+     must reestablish each time.  */
+  signal (SIGALRM, alarm_signal_handler);
+#endif /* USG */
+  
+  if (atimers)
+    {
+      EMACS_TIME now, time;
+#ifdef HAVE_SETITIMER
+      struct itimerval it;
+#endif
+
+      /* Determine s/us till the next timer is ripe.  */
+      EMACS_GET_TIME (now);
+      EMACS_SUB_TIME (time, atimers->expiration, now);
+
+#ifdef HAVE_SETITIMER
+      /* Don't set the interval to 0; this disables the timer.  */
+      if (EMACS_TIME_LE (atimers->expiration, now))
+       {
+         EMACS_SET_SECS (time, 0);
+         EMACS_SET_USECS (time, 1000);
+       }
+      
+      bzero (&it, sizeof it);
+      it.it_value = time;
+      setitimer (ITIMER_REAL, &it, 0);
+#else /* not HAVE_SETITIMER */
+      alarm (max (EMACS_SECS (time), 1));
+#endif /* not HAVE_SETITIMER */
+    }
+}
+
+
+/* Insert timer T into the list of active atimers `atimers', keeping
+   the list sorted by expiration time.  T must not be in this list
+   already.  */
+
+static void
+schedule_atimer (t)
+     struct atimer *t;
+{
+  struct atimer *a = atimers, *prev = NULL;
+
+  /* Look for the first atimer that is ripe after T.  */
+  while (a && EMACS_TIME_GT (t->expiration, a->expiration))
+    prev = a, a = a->next;
+
+  /* Insert T in front of the atimer found, if any.  */
+  if (prev)
+    prev->next = t;
+  else
+    atimers = t;
+  
+  t->next = a;
+}
+
+
+/* Signal handler for SIGALRM.  SIGNO is the signal number, i.e.
+   SIGALRM.  */
+
+SIGTYPE
+alarm_signal_handler (signo)
+     int signo;
+{
+  EMACS_TIME now;
+  
+  EMACS_GET_TIME (now);
+  pending_atimers = 0;
+  
+  while (atimers
+        && (pending_atimers = interrupt_input_blocked) == 0
+        && EMACS_TIME_LE (atimers->expiration, now))
+    {
+      struct atimer *t;
+      
+      t = atimers;
+      atimers = atimers->next;
+      t->fn (t);
+      
+      if (t->type == ATIMER_CONTINUOUS)
+       {
+         EMACS_ADD_TIME (t->expiration, now, t->interval);
+         schedule_atimer (t);
+       }
+      else
+       {
+         t->next = free_atimers;
+         free_atimers = t;
+       }
+      
+      EMACS_GET_TIME (now);
+    }
+  
+#if defined (USG) && !defined (POSIX_SIGNALS)
+  /* USG systems forget handlers when they are used;
+     must reestablish each time.  */
+  signal (SIGALRM, alarm_signal_handler);
+#endif /* USG */
+  
+  set_alarm ();
+}
+
+
+/* Call alarm_signal_handler for pending timers.  */
+
+void
+do_pending_atimers ()
+{
+  if (pending_atimers)
+    {
+      BLOCK_ATIMERS;
+      alarm_signal_handler (SIGALRM);
+      UNBLOCK_ATIMERS;
+    }
+}
+
+
+/* Turn alarms on/off.  This seems to be temporarily necessary on
+   some systems like HPUX (see process.c).  */
+
+void
+turn_on_atimers (on)
+     int on;
+{
+  if (on)
+    {
+      signal (SIGALRM, alarm_signal_handler);
+      set_alarm ();
+    }
+  else
+    alarm (0);
+}
+
+
+void
+init_atimer ()
+{
+  free_atimers = atimers = NULL;
+  pending_atimers = 0;
+  signal (SIGALRM, alarm_signal_handler);
+}
diff --git a/src/atimer.h b/src/atimer.h
new file mode 100644 (file)
index 0000000..9a5b7ef
--- /dev/null
@@ -0,0 +1,75 @@
+/* Asynchronous timers.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Forward declaration.  */
+
+struct atimer;
+
+/* Types of timers.  */
+
+enum atimer_type
+{
+  /* Timer is ripe at some absolute time.  */
+  ATIMER_ABSOLUTE,
+
+  /* Timer is ripe at now plus an offset.  */
+  ATIMER_RELATIVE,
+
+  /* Timer runs continously.  */
+  ATIMER_CONTINUOUS
+};
+
+/* Type of timer callback functions.  */
+
+typedef void (* atimer_callback) P_ ((struct atimer *timer));
+
+/* Structure describing an asynchronous timer.  */
+
+struct atimer
+{
+  /* The type of this timer.  */
+  enum atimer_type type;
+  
+  /* Time when this timer is ripe.  */
+  EMACS_TIME expiration;
+
+  /* Interval of this timer.  */
+  EMACS_TIME interval;
+
+  /* Function to call when timer is ripe.  Interupt input is
+     garanteed to not be blocked when this function is called.  */
+  atimer_callback fn;
+
+  /* Additional user-specified data to pass to FN.  */
+  void *client_data;
+
+  /* Next in list of active or free atimers.  */
+  struct atimer *next;
+};
+
+/* Function prototypes.  */
+
+struct atimer *start_atimer P_ ((enum atimer_type, EMACS_TIME,
+                                atimer_callback, void *));
+void cancel_atimer P_ ((struct atimer *));
+void do_pending_atimers P_ ((void));
+void init_atimer P_ ((void));
+void turn_on_atimers P_ ((int));
+