*** empty log message ***
This commit is contained in:
parent
ffdcc91d6d
commit
e12489f9ab
5 changed files with 473 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
336
src/atimer.c
Normal file
336
src/atimer.c
Normal file
|
@ -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);
|
||||
}
|
75
src/atimer.h
Normal file
75
src/atimer.h
Normal file
|
@ -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));
|
||||
|
Loading…
Add table
Reference in a new issue