From: Gerd Moellmann Date: Tue, 25 Jan 2000 15:59:42 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: emacs-pretest-21.0.90~5255 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e12489f9ab542b1c83f7ac9cca05fd21a37d4080;p=emacs.git *** empty log message *** --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 73972d8f266..3bee2004566 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2000-01-25 Gerd Moellmann + + * scroll-bar.el (scroll-bar-timer): Variable removed. + (scroll-bar-toolkit-scroll): Don't use a timer. + 2000-01-25 Kenichi Handa * language/thai-util.el (thai-composition-function): Delete diff --git a/lwlib/ChangeLog b/lwlib/ChangeLog index 9563a8f5b92..25dda71e443 100644 --- a/lwlib/ChangeLog +++ b/lwlib/ChangeLog @@ -1,3 +1,11 @@ +2000-01-25 Gerd Moellmann + + * 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 * lwlib-Xm.c (xm_arm_callback): New function. diff --git a/src/ChangeLog b/src/ChangeLog index 1195c6f20b2..adcfb0089f9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,52 @@ +2000-01-25 Gerd Moellmann + + * 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 * 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 index 00000000000..92f5076fcc7 --- /dev/null +++ b/src/atimer.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#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 index 00000000000..9a5b7ef3107 --- /dev/null +++ b/src/atimer.h @@ -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)); +