Cleanup of the timeout and Fl::wait() code. This one calls the clock
function less than half as much, which resulted in a noticable improvement in a flip book program I was working on. The code looks nicer, too, and I am reasonably certain it works the same. Fl::wait(time) with a time greater than the system can handle (24.855 days on NT, the same on some Unix systems) will now act as though the time is infinity. Before it would do unpredictable things. "USE_POLL" now compiles and works, although it is disabled by default. poll() is an alternative to the Unix select() call which is available on Linux and Irix, but I don't know if it is faster, you can try it by editing config.h. I tried making the NT USE_ASYNC_SELECT code do translate/dispatch of the select events on the assumption (based on experience) that not doing this to every event gives NT fits. This appears to work but I'm not sure if it fixes anything. X version does not crash if Fl::wait() is called when the display is closed (it will not return unless you have a timeout or fd callback set up, though). Fixed up the documentation for all of this, including getting rid of some completely misleading documentation. Now I need to get this stuff into 2.0... git-svn-id: file:///fltk/svn/fltk/branches/branch-1.0@1215 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
4dd096e7b5
commit
be106a0977
10
configh.in
10
configh.in
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* "$Id: configh.in,v 1.11.2.4 2000/06/07 12:11:52 mike Exp $"
|
* "$Id: configh.in,v 1.11.2.5 2000/06/18 00:38:37 bill Exp $"
|
||||||
*
|
*
|
||||||
* Configuration file for the Fast Light Tool Kit (FLTK).
|
* Configuration file for the Fast Light Tool Kit (FLTK).
|
||||||
* @configure_input@
|
* @configure_input@
|
||||||
@ -145,13 +145,13 @@
|
|||||||
#define HAVE_SYS_SELECT_H 0
|
#define HAVE_SYS_SELECT_H 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HAVE_POLL:
|
* USE_POLL:
|
||||||
*
|
*
|
||||||
* Use poll() if we don't have select().
|
* Use the poll() call provided on Linux and Irix instead of select()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HAVE_POLL 0
|
#define USE_POLL 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of "$Id: configh.in,v 1.11.2.4 2000/06/07 12:11:52 mike Exp $".
|
* End of "$Id: configh.in,v 1.11.2.5 2000/06/18 00:38:37 bill Exp $".
|
||||||
*/
|
*/
|
||||||
|
File diff suppressed because it is too large
Load Diff
294
src/Fl.cxx
294
src/Fl.cxx
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// "$Id: Fl.cxx,v 1.24.2.26 2000/06/16 07:28:02 bill Exp $"
|
// "$Id: Fl.cxx,v 1.24.2.27 2000/06/18 00:38:39 bill Exp $"
|
||||||
//
|
//
|
||||||
// Main event handling code for the Fast Light Tool Kit (FLTK).
|
// Main event handling code for the Fast Light Tool Kit (FLTK).
|
||||||
//
|
//
|
||||||
@ -50,8 +50,6 @@ int Fl::damage_,
|
|||||||
char *Fl::e_text = "";
|
char *Fl::e_text = "";
|
||||||
int Fl::e_length;
|
int Fl::e_length;
|
||||||
|
|
||||||
static double fl_elapsed();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'Fl:event_inside()' - Return whether or not the mouse event is inside
|
// 'Fl:event_inside()' - Return whether or not the mouse event is inside
|
||||||
// the given rectangle.
|
// the given rectangle.
|
||||||
@ -67,6 +65,11 @@ int Fl::event_inside(const Fl_Widget *o) /*const*/ {
|
|||||||
return event_inside(o->x(),o->y(),o->w(),o->h());
|
return event_inside(o->x(),o->y(),o->w(),o->h());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// Timeouts and Fl::wait()
|
||||||
|
|
||||||
|
void (*Fl::idle)();
|
||||||
|
|
||||||
// Timeouts are insert-sorted into order. This works good if there
|
// Timeouts are insert-sorted into order. This works good if there
|
||||||
// are only a small number:
|
// are only a small number:
|
||||||
|
|
||||||
@ -78,9 +81,131 @@ static struct Timeout {
|
|||||||
static int numtimeouts;
|
static int numtimeouts;
|
||||||
static int timeout_array_size;
|
static int timeout_array_size;
|
||||||
|
|
||||||
|
extern int fl_wait(double time); // warning: assummes time >= 0.0
|
||||||
|
extern int fl_ready();
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// I avoid the overhead of getting the current time when we have no
|
||||||
|
// timeouts by setting this flag instead of getting the time.
|
||||||
|
// In this case calling elapse_timeouts() does nothing, but records
|
||||||
|
// the current time, and the next call will actualy elapse time.
|
||||||
|
static char reset_clock = 1;
|
||||||
|
|
||||||
|
static void elapse_timeouts() {
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
unsigned long newclock = GetTickCount();
|
||||||
|
static unsigned long prevclock;
|
||||||
|
if (reset_clock) {
|
||||||
|
prevclock = newclock;
|
||||||
|
reset_clock = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (newclock <= prevclock) return;
|
||||||
|
double elapsed = (newclock-prevclock)/1000.0;
|
||||||
|
prevclock = newclock;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static struct timeval prevclock;
|
||||||
|
struct timeval newclock;
|
||||||
|
gettimeofday(&newclock, NULL);
|
||||||
|
if (reset_clock) {
|
||||||
|
prevclock.tv_sec = newclock.tv_sec;
|
||||||
|
prevclock.tv_usec = newclock.tv_usec;
|
||||||
|
reset_clock = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
double elapsed = newclock.tv_sec - prevclock.tv_sec +
|
||||||
|
(newclock.tv_usec - prevclock.tv_usec)/1000000.0;
|
||||||
|
prevclock.tv_sec = newclock.tv_sec;
|
||||||
|
prevclock.tv_usec = newclock.tv_usec;
|
||||||
|
if (elapsed <= 0) return;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i=0; i<numtimeouts; i++) timeout[i].time -= elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char in_idle;
|
||||||
|
static char in_timeout;
|
||||||
|
|
||||||
|
double Fl::wait(double time_to_wait) {
|
||||||
|
if (numtimeouts) {
|
||||||
|
elapse_timeouts();
|
||||||
|
if (timeout[0].time <= time_to_wait) time_to_wait = timeout[0].time;
|
||||||
|
while (numtimeouts) {
|
||||||
|
if (timeout[0].time > 0) break;
|
||||||
|
// The first timeout in the array has expired.
|
||||||
|
// We must remove timeout from array before doing the callback:
|
||||||
|
void (*cb)(void*) = timeout[0].cb;
|
||||||
|
void *arg = timeout[0].arg;
|
||||||
|
numtimeouts--;
|
||||||
|
if (numtimeouts)
|
||||||
|
memmove(timeout, timeout+1, numtimeouts*sizeof(Timeout));
|
||||||
|
// Now it is safe for the callback to do add_timeout:
|
||||||
|
in_timeout = 1;
|
||||||
|
cb(arg);
|
||||||
|
in_timeout = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reset_clock = 1; // we are not going to check the clock
|
||||||
|
}
|
||||||
|
if (idle) {
|
||||||
|
if (!in_idle) {in_idle = 1; idle(); in_idle = 0;}
|
||||||
|
// the idle function may turn off idle, we can then wait:
|
||||||
|
if (idle) time_to_wait = 0.0;
|
||||||
|
}
|
||||||
|
if (time_to_wait <= 0.0) {
|
||||||
|
// do flush second so that the results of events are visible:
|
||||||
|
int ret = fl_wait(0.0);
|
||||||
|
flush();
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
// do flush first so that user sees the display:
|
||||||
|
flush();
|
||||||
|
return fl_wait(time_to_wait);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOREVER 1e20
|
||||||
|
|
||||||
|
int Fl::run() {
|
||||||
|
while (Fl_X::first) wait(FOREVER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Fl::wait() {
|
||||||
|
wait(FOREVER);
|
||||||
|
return Fl_X::first != 0; // return true if there is a window
|
||||||
|
}
|
||||||
|
|
||||||
|
int Fl::check() {
|
||||||
|
wait(0.0);
|
||||||
|
return Fl_X::first != 0; // return true if there is a window
|
||||||
|
}
|
||||||
|
|
||||||
|
int Fl::ready() {
|
||||||
|
if (numtimeouts) {
|
||||||
|
elapse_timeouts();
|
||||||
|
if (timeout[0].time <= 0) return 1;
|
||||||
|
} else {
|
||||||
|
reset_clock = 1;
|
||||||
|
}
|
||||||
|
return fl_ready();
|
||||||
|
}
|
||||||
|
|
||||||
void Fl::add_timeout(double t, Fl_Timeout_Handler cb, void *v) {
|
void Fl::add_timeout(double t, Fl_Timeout_Handler cb, void *v) {
|
||||||
|
|
||||||
fl_elapsed();
|
// This little test gets rid of about half the calls to get the time
|
||||||
|
// and has the added advantage of making timeouts that think they
|
||||||
|
// are happening at regular intervals actually happen at regular
|
||||||
|
// intervals:
|
||||||
|
if (!in_timeout) elapse_timeouts();
|
||||||
|
|
||||||
if (numtimeouts >= timeout_array_size) {
|
if (numtimeouts >= timeout_array_size) {
|
||||||
timeout_array_size = 2*timeout_array_size+1;
|
timeout_array_size = 2*timeout_array_size+1;
|
||||||
@ -117,145 +242,6 @@ void Fl::remove_timeout(Fl_Timeout_Handler cb, void *v) {
|
|||||||
numtimeouts = j;
|
numtimeouts = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int call_timeouts() {
|
|
||||||
int expired = 0;
|
|
||||||
while (numtimeouts) {
|
|
||||||
if (timeout[0].time > 0) break;
|
|
||||||
// we must remove timeout from array before doing the callback:
|
|
||||||
void (*cb)(void*) = timeout[0].cb;
|
|
||||||
void *arg = timeout[0].arg;
|
|
||||||
numtimeouts--; expired++;
|
|
||||||
if (numtimeouts) memmove(timeout, timeout+1, numtimeouts*sizeof(Timeout));
|
|
||||||
// now it is safe for the callback to do add_timeout:
|
|
||||||
cb(arg);
|
|
||||||
}
|
|
||||||
return expired;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Fl::flush() {
|
|
||||||
if (damage()) {
|
|
||||||
damage_ = 0;
|
|
||||||
for (Fl_X* x = Fl_X::first; x; x = x->next) {
|
|
||||||
if (x->w->damage() && x->w->visible_r()) {
|
|
||||||
if (x->wait_for_expose) {
|
|
||||||
// leave Fl::damage() set so programs can tell damage still exists
|
|
||||||
damage_ = 1;
|
|
||||||
} else {
|
|
||||||
x->flush();
|
|
||||||
x->w->clear_damage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef WIN32
|
|
||||||
if (fl_display) XFlush(fl_display);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern double fl_wait(int timeout_flag, double timeout);
|
|
||||||
extern int fl_ready();
|
|
||||||
|
|
||||||
static int initclock; // if false we didn't call fl_elapsed() last time
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// fl_elapsed must return the amount of time since the last time it was
|
|
||||||
// called. To reduce the number of system calls to get the
|
|
||||||
// current time, the "initclock" symbol is turned on by an indefinite
|
|
||||||
// wait. This should then reset the measured-from time and return zero
|
|
||||||
static double fl_elapsed() {
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
|
|
||||||
unsigned long newclock = GetTickCount();
|
|
||||||
const int TICKS_PER_SECOND = 1000; // divisor of the value to get seconds
|
|
||||||
static unsigned long prevclock;
|
|
||||||
if (!initclock) {prevclock = newclock; initclock = 1; return 0.0;}
|
|
||||||
else if (newclock < prevclock) return 0.0;
|
|
||||||
|
|
||||||
double t = double(newclock-prevclock)/TICKS_PER_SECOND;
|
|
||||||
prevclock = newclock;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static struct timeval prevclock;
|
|
||||||
struct timeval newclock;
|
|
||||||
gettimeofday(&newclock, NULL);
|
|
||||||
if (!initclock) {
|
|
||||||
prevclock.tv_sec = newclock.tv_sec;
|
|
||||||
prevclock.tv_usec = newclock.tv_usec;
|
|
||||||
initclock = 1;
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
double t = newclock.tv_sec - prevclock.tv_sec +
|
|
||||||
(newclock.tv_usec - prevclock.tv_usec)/1000000.0;
|
|
||||||
prevclock.tv_sec = newclock.tv_sec;
|
|
||||||
prevclock.tv_usec = newclock.tv_usec;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// expire any timeouts:
|
|
||||||
if (t > 0.0) for (int i=0; i<numtimeouts; i++) timeout[i].time -= t;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void (*Fl::idle)();
|
|
||||||
static char in_idle;
|
|
||||||
static void callidle() {
|
|
||||||
if (!Fl::idle || in_idle) return;
|
|
||||||
in_idle = 1;
|
|
||||||
Fl::idle();
|
|
||||||
in_idle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Fl::wait() {
|
|
||||||
callidle();
|
|
||||||
int expired = 0;
|
|
||||||
if (numtimeouts) {fl_elapsed(); expired = call_timeouts();}
|
|
||||||
flush();
|
|
||||||
if ((idle && !in_idle) || expired) {
|
|
||||||
fl_wait(1,0.0);
|
|
||||||
} else if (numtimeouts) {
|
|
||||||
fl_wait(1, timeout[0].time);
|
|
||||||
} else {
|
|
||||||
initclock = 0;
|
|
||||||
fl_wait(0,0);
|
|
||||||
}
|
|
||||||
return Fl_X::first != 0; // return true if there is a window
|
|
||||||
}
|
|
||||||
|
|
||||||
double Fl::wait(double time) {
|
|
||||||
callidle();
|
|
||||||
int expired = 0;
|
|
||||||
if (numtimeouts) {time -= fl_elapsed(); expired = call_timeouts();}
|
|
||||||
flush();
|
|
||||||
double wait_time = (idle && !in_idle) || expired ? 0.0 : time;
|
|
||||||
if (numtimeouts && timeout[0].time < wait_time) wait_time = timeout[0].time;
|
|
||||||
fl_wait(1, wait_time);
|
|
||||||
return time - fl_elapsed();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Fl::check() {
|
|
||||||
callidle();
|
|
||||||
if (numtimeouts) {fl_elapsed(); call_timeouts();}
|
|
||||||
fl_wait(1, 0.0);
|
|
||||||
flush();
|
|
||||||
return Fl_X::first != 0; // return true if there is a window
|
|
||||||
}
|
|
||||||
|
|
||||||
int Fl::ready() {
|
|
||||||
// if (idle && !in_idle) return 1; // should it do this?
|
|
||||||
if (numtimeouts) {fl_elapsed(); if (timeout[0].time <= 0) return 1;}
|
|
||||||
return fl_ready();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Fl::run() {
|
|
||||||
while (wait());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Window list management:
|
// Window list management:
|
||||||
|
|
||||||
@ -296,6 +282,26 @@ void Fl::redraw() {
|
|||||||
for (Fl_X* x = Fl_X::first; x; x = x->next) x->w->redraw();
|
for (Fl_X* x = Fl_X::first; x; x = x->next) x->w->redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Fl::flush() {
|
||||||
|
if (damage()) {
|
||||||
|
damage_ = 0;
|
||||||
|
for (Fl_X* x = Fl_X::first; x; x = x->next) {
|
||||||
|
if (x->w->damage() && x->w->visible_r()) {
|
||||||
|
if (x->wait_for_expose) {
|
||||||
|
// leave Fl::damage() set so programs can tell damage still exists
|
||||||
|
damage_ = 1;
|
||||||
|
} else {
|
||||||
|
x->flush();
|
||||||
|
x->w->clear_damage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifndef WIN32
|
||||||
|
if (fl_display) XFlush(fl_display);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Event handlers:
|
// Event handlers:
|
||||||
|
|
||||||
@ -727,5 +733,5 @@ void Fl_Window::flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// End of "$Id: Fl.cxx,v 1.24.2.26 2000/06/16 07:28:02 bill Exp $".
|
// End of "$Id: Fl.cxx,v 1.24.2.27 2000/06/18 00:38:39 bill Exp $".
|
||||||
//
|
//
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// "$Id: Fl_win32.cxx,v 1.33.2.26 2000/06/05 21:21:02 mike Exp $"
|
// "$Id: Fl_win32.cxx,v 1.33.2.27 2000/06/18 00:38:40 bill Exp $"
|
||||||
//
|
//
|
||||||
// WIN32-specific code for the Fast Light Tool Kit (FLTK).
|
// WIN32-specific code for the Fast Light Tool Kit (FLTK).
|
||||||
//
|
//
|
||||||
@ -151,24 +151,14 @@ void Fl::remove_fd(int n) {
|
|||||||
|
|
||||||
MSG fl_msg;
|
MSG fl_msg;
|
||||||
|
|
||||||
int fl_ready() {
|
#define FOREVER 1e20
|
||||||
if (PeekMessage(&fl_msg, NULL, 0, 0, PM_NOREMOVE)) return 1;
|
|
||||||
|
|
||||||
#ifdef USE_ASYNC_SELECT
|
// This is never called with time_to_wait < 0.0.
|
||||||
return (0);
|
// It *should* return negative on error, 0 if nothing happens before
|
||||||
#else
|
// timeout, and >0 if any callbacks were done. This version only
|
||||||
timeval t;
|
// returns zero if nothing happens during a 0.0 timeout, otherwise
|
||||||
t.tv_sec = 0;
|
// it returns 1.
|
||||||
t.tv_usec = 0;
|
int fl_wait(double time_to_wait) {
|
||||||
fd_set fdt[3];
|
|
||||||
fdt[0] = fdsets[0];
|
|
||||||
fdt[1] = fdsets[1];
|
|
||||||
fdt[2] = fdsets[2];
|
|
||||||
return ::select(0,&fdt[0],&fdt[1],&fdt[2],&t);
|
|
||||||
#endif // USE_ASYNC_SELECT
|
|
||||||
}
|
|
||||||
|
|
||||||
double fl_wait(int timeout_flag, double time) {
|
|
||||||
int have_message = 0;
|
int have_message = 0;
|
||||||
int timerid;
|
int timerid;
|
||||||
|
|
||||||
@ -195,46 +185,29 @@ double fl_wait(int timeout_flag, double time) {
|
|||||||
if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
|
if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
|
||||||
if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
|
if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
|
||||||
}
|
}
|
||||||
|
time_to_wait = 0.0; // just peek for any messages
|
||||||
|
} else {
|
||||||
|
// we need to check them periodically, so set a short timeout:
|
||||||
|
if (time_to_wait > .001) time_to_wait = .001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_ASYNC_SELECT
|
#endif // USE_ASYNC_SELECT
|
||||||
|
|
||||||
// get the first message by waiting the correct amount of time:
|
if (time_to_wait < 2147483.648) {
|
||||||
if (!timeout_flag) {
|
|
||||||
#ifdef USE_ASYNC_SELECT
|
|
||||||
// Wait for a message...
|
|
||||||
have_message = GetMessage(&fl_msg, NULL, 0, 0);
|
|
||||||
#else
|
|
||||||
// If we are monitoring sockets we need to check them periodically,
|
|
||||||
// so set a timer in this case...
|
|
||||||
if (nfds) {
|
|
||||||
// First see if there is a message waiting...
|
|
||||||
have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
|
|
||||||
if (!have_message) {
|
|
||||||
// If not then set a 1ms timer...
|
|
||||||
timerid = SetTimer(NULL, 0, 1, NULL);
|
|
||||||
GetMessage(&fl_msg, NULL, 0, 0);
|
|
||||||
KillTimer(NULL, timerid);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Wait for a message...
|
|
||||||
GetMessage(&fl_msg, NULL, 0, 0);
|
|
||||||
}
|
|
||||||
have_message = 1;
|
|
||||||
#endif // USE_ASYNC_SELECT
|
|
||||||
} else {
|
|
||||||
// Perform the requested timeout...
|
// Perform the requested timeout...
|
||||||
have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
|
have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
|
||||||
if (!have_message && time > 0.0) {
|
if (!have_message) {
|
||||||
int t = (int)(time * 1000.0);
|
int t = (int)(time_to_wait * 1000.0 + .5);
|
||||||
if (t <= 0) t = 1;
|
if (t <= 0) return 0; // too short to measure
|
||||||
timerid = SetTimer(NULL, 0, t, NULL);
|
timerid = SetTimer(NULL, 0, t, NULL);
|
||||||
have_message = GetMessage(&fl_msg, NULL, 0, 0);
|
have_message = GetMessage(&fl_msg, NULL, 0, 0);
|
||||||
KillTimer(NULL, timerid);
|
KillTimer(NULL, timerid);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
have_message = GetMessage(&fl_msg, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute it, them execute any other messages that become ready during it:
|
// Execute the message we got, and all other pending messages:
|
||||||
while (have_message) {
|
while (have_message) {
|
||||||
#ifdef USE_ASYNC_SELECT
|
#ifdef USE_ASYNC_SELECT
|
||||||
if (fl_msg.message == WM_FLSELECT) {
|
if (fl_msg.message == WM_FLSELECT) {
|
||||||
@ -244,20 +217,33 @@ double fl_wait(int timeout_flag, double time) {
|
|||||||
(fd[i].cb)(fd[i].fd, fd[i].arg);
|
(fd[i].cb)(fd[i].fd, fd[i].arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
// looks like it is best to do the dispatch-message anyway:
|
||||||
// Some other message...
|
|
||||||
TranslateMessage(&fl_msg);
|
|
||||||
DispatchMessage(&fl_msg);
|
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
TranslateMessage(&fl_msg);
|
TranslateMessage(&fl_msg);
|
||||||
DispatchMessage(&fl_msg);
|
DispatchMessage(&fl_msg);
|
||||||
#endif // USE_ASYNC_SELECT
|
|
||||||
|
|
||||||
have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
|
have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return time;
|
// This should return 0 if only timer events were handled:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fl_ready() is just like fl_wait(0.0) except no callbacks are done:
|
||||||
|
int fl_ready() {
|
||||||
|
if (PeekMessage(&fl_msg, NULL, 0, 0, PM_NOREMOVE)) return 1;
|
||||||
|
#ifdef USE_ASYNC_SELECT
|
||||||
|
return (0);
|
||||||
|
#else
|
||||||
|
timeval t;
|
||||||
|
t.tv_sec = 0;
|
||||||
|
t.tv_usec = 0;
|
||||||
|
fd_set fdt[3];
|
||||||
|
fdt[0] = fdsets[0];
|
||||||
|
fdt[1] = fdsets[1];
|
||||||
|
fdt[2] = fdsets[2];
|
||||||
|
return ::select(0,&fdt[0],&fdt[1],&fdt[2],&t);
|
||||||
|
#endif // USE_ASYNC_SELECT
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
@ -967,5 +953,5 @@ void Fl_Window::make_current() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// End of "$Id: Fl_win32.cxx,v 1.33.2.26 2000/06/05 21:21:02 mike Exp $".
|
// End of "$Id: Fl_win32.cxx,v 1.33.2.27 2000/06/18 00:38:40 bill Exp $".
|
||||||
//
|
//
|
||||||
|
116
src/Fl_x.cxx
116
src/Fl_x.cxx
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// "$Id: Fl_x.cxx,v 1.24.2.17 2000/06/05 21:21:03 mike Exp $"
|
// "$Id: Fl_x.cxx,v 1.24.2.18 2000/06/18 00:38:41 bill Exp $"
|
||||||
//
|
//
|
||||||
// X specific code for the Fast Light Tool Kit (FLTK).
|
// X specific code for the Fast Light Tool Kit (FLTK).
|
||||||
//
|
//
|
||||||
@ -45,7 +45,7 @@
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// interface to poll/select call:
|
// interface to poll/select call:
|
||||||
|
|
||||||
#if HAVE_POLL
|
#if USE_POLL
|
||||||
|
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
static pollfd *pollfds = 0;
|
static pollfd *pollfds = 0;
|
||||||
@ -65,13 +65,15 @@ static int maxfd;
|
|||||||
#define POLLOUT 4
|
#define POLLOUT 4
|
||||||
#define POLLERR 8
|
#define POLLERR 8
|
||||||
|
|
||||||
#endif /* HAVE_POLL */
|
#endif /* USE_POLL */
|
||||||
|
|
||||||
static int nfds = 0;
|
static int nfds = 0;
|
||||||
static int fd_array_size = 0;
|
static int fd_array_size = 0;
|
||||||
static struct FD {
|
static struct FD {
|
||||||
|
#if !USE_POLL
|
||||||
int fd;
|
int fd;
|
||||||
short events;
|
short events;
|
||||||
|
#endif
|
||||||
void (*cb)(int, void*);
|
void (*cb)(int, void*);
|
||||||
void* arg;
|
void* arg;
|
||||||
} *fd = 0;
|
} *fd = 0;
|
||||||
@ -82,18 +84,18 @@ void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
|
|||||||
if (i >= fd_array_size) {
|
if (i >= fd_array_size) {
|
||||||
fd_array_size = 2*fd_array_size+1;
|
fd_array_size = 2*fd_array_size+1;
|
||||||
fd = (FD*)realloc(fd, fd_array_size*sizeof(FD));
|
fd = (FD*)realloc(fd, fd_array_size*sizeof(FD));
|
||||||
#if HAVE_POLL
|
#if USE_POLL
|
||||||
pollfds = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd));
|
pollfds = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
fd[i].fd = n;
|
|
||||||
fd[i].events = events;
|
|
||||||
fd[i].cb = cb;
|
fd[i].cb = cb;
|
||||||
fd[i].arg = v;
|
fd[i].arg = v;
|
||||||
#if HAVE_POLL
|
#if USE_POLL
|
||||||
fds[i].fd = n;
|
pollfds[i].fd = n;
|
||||||
fds[i].events = events;
|
pollfds[i].events = events;
|
||||||
#else
|
#else
|
||||||
|
fd[i].fd = n;
|
||||||
|
fd[i].events = events;
|
||||||
if (events & POLLIN) FD_SET(n, &fdsets[0]);
|
if (events & POLLIN) FD_SET(n, &fdsets[0]);
|
||||||
if (events & POLLOUT) FD_SET(n, &fdsets[1]);
|
if (events & POLLOUT) FD_SET(n, &fdsets[1]);
|
||||||
if (events & POLLERR) FD_SET(n, &fdsets[2]);
|
if (events & POLLERR) FD_SET(n, &fdsets[2]);
|
||||||
@ -108,25 +110,30 @@ void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) {
|
|||||||
void Fl::remove_fd(int n, int events) {
|
void Fl::remove_fd(int n, int events) {
|
||||||
int i,j;
|
int i,j;
|
||||||
for (i=j=0; i<nfds; i++) {
|
for (i=j=0; i<nfds; i++) {
|
||||||
|
#if USE_POLL
|
||||||
|
if (pollfds[i].fd == n) {
|
||||||
|
int e = pollfds[i].events & ~events;
|
||||||
|
if (!e) continue; // if no events left, delete this fd
|
||||||
|
pollfds[j].events = e;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (fd[i].fd == n) {
|
if (fd[i].fd == n) {
|
||||||
int e = fd[i].events & ~events;
|
int e = fd[i].events & ~events;
|
||||||
if (!e) continue; // if no events left, delete this fd
|
if (!e) continue; // if no events left, delete this fd
|
||||||
fd[i].events = e;
|
fd[i].events = e;
|
||||||
#if HAVE_POLL
|
|
||||||
fds[j].events = e;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// move it down in the array if necessary:
|
// move it down in the array if necessary:
|
||||||
if (j<i) {
|
if (j<i) {
|
||||||
fd[j]=fd[i];
|
fd[j] = fd[i];
|
||||||
#if HAVE_POLL
|
#if USE_POLL
|
||||||
fds[j]=fds[i];
|
pollfds[j] = pollfds[i];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
nfds = j;
|
nfds = j;
|
||||||
#if !HAVE_POLL
|
#if !USE_POLL
|
||||||
if (events & POLLIN) FD_CLR(n, &fdsets[0]);
|
if (events & POLLIN) FD_CLR(n, &fdsets[0]);
|
||||||
if (events & POLLOUT) FD_CLR(n, &fdsets[1]);
|
if (events & POLLOUT) FD_CLR(n, &fdsets[1]);
|
||||||
if (events & POLLERR) FD_CLR(n, &fdsets[2]);
|
if (events & POLLERR) FD_CLR(n, &fdsets[2]);
|
||||||
@ -138,22 +145,6 @@ void Fl::remove_fd(int n) {
|
|||||||
remove_fd(n, -1);
|
remove_fd(n, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fl_ready() {
|
|
||||||
if (XQLength(fl_display)) return 1;
|
|
||||||
#if HAVE_POLL
|
|
||||||
return ::poll(fds, nfds, 0);
|
|
||||||
#else
|
|
||||||
timeval t;
|
|
||||||
t.tv_sec = 0;
|
|
||||||
t.tv_usec = 0;
|
|
||||||
fd_set fdt[3];
|
|
||||||
fdt[0] = fdsets[0];
|
|
||||||
fdt[1] = fdsets[1];
|
|
||||||
fdt[2] = fdsets[2];
|
|
||||||
return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONSOLIDATE_MOTION
|
#if CONSOLIDATE_MOTION
|
||||||
static Fl_Window* send_motion;
|
static Fl_Window* send_motion;
|
||||||
extern Fl_Window* fl_xmousewin;
|
extern Fl_Window* fl_xmousewin;
|
||||||
@ -172,14 +163,17 @@ static void do_queued_events() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
double fl_wait(int timeout_flag, double time) {
|
// This is never called with time_to_wait < 0.0:
|
||||||
|
// It should return negative on error, 0 if nothing happens before
|
||||||
|
// timeout, and >0 if any callbacks were done.
|
||||||
|
int fl_wait(double time_to_wait) {
|
||||||
|
|
||||||
// OpenGL and other broken libraries call XEventsQueued
|
// OpenGL and other broken libraries call XEventsQueued
|
||||||
// unnecessarily and thus cause the file descriptor to not be ready,
|
// unnecessarily and thus cause the file descriptor to not be ready,
|
||||||
// so we must check for already-read events:
|
// so we must check for already-read events:
|
||||||
if (XQLength(fl_display)) {do_queued_events(); return time;}
|
if (fl_display && XQLength(fl_display)) {do_queued_events(); return 1;}
|
||||||
|
|
||||||
#if !HAVE_POLL
|
#if !USE_POLL
|
||||||
fd_set fdt[3];
|
fd_set fdt[3];
|
||||||
fdt[0] = fdsets[0];
|
fdt[0] = fdsets[0];
|
||||||
fdt[1] = fdsets[1];
|
fdt[1] = fdsets[1];
|
||||||
@ -187,31 +181,26 @@ double fl_wait(int timeout_flag, double time) {
|
|||||||
#endif
|
#endif
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (!timeout_flag) {
|
if (time_to_wait < 2147483.648) {
|
||||||
#if HAVE_POLL
|
#if USE_POLL
|
||||||
n = ::poll(fds, nfds, -1);
|
n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5));
|
||||||
#else
|
|
||||||
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#if HAVE_POLL
|
|
||||||
int n = ::poll(fds, nfds, time > 0.0 ? int(time*1000) : 0);
|
|
||||||
#else
|
#else
|
||||||
timeval t;
|
timeval t;
|
||||||
if (time <= 0.0) {
|
t.tv_sec = int(time_to_wait);
|
||||||
t.tv_sec = 0;
|
t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec));
|
||||||
t.tv_usec = 0;
|
|
||||||
} else {
|
|
||||||
t.tv_sec = int(time);
|
|
||||||
t.tv_usec = int(1000000 * (time-t.tv_sec));
|
|
||||||
}
|
|
||||||
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
|
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#if USE_POLL
|
||||||
|
n = ::poll(pollfds, nfds, -1);
|
||||||
|
#else
|
||||||
|
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
for (int i=0; i<nfds; i++) {
|
for (int i=0; i<nfds; i++) {
|
||||||
#if HAVE_POLL
|
#if USE_POLL
|
||||||
if (fds[i].revents) fd[i].cb(fd[i].fd, fd[i].arg);
|
if (pollfds[i].revents) fd[i].cb(pollfds[i].fd, fd[i].arg);
|
||||||
#else
|
#else
|
||||||
int f = fd[i].fd;
|
int f = fd[i].fd;
|
||||||
short revents = 0;
|
short revents = 0;
|
||||||
@ -222,7 +211,24 @@ double fl_wait(int timeout_flag, double time) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return time;
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fl_ready() is just like fl_wait(0.0) except no callbacks are done:
|
||||||
|
int fl_ready() {
|
||||||
|
if (XQLength(fl_display)) return 1;
|
||||||
|
#if USE_POLL
|
||||||
|
return ::poll(pollfds, nfds, 0);
|
||||||
|
#else
|
||||||
|
timeval t;
|
||||||
|
t.tv_sec = 0;
|
||||||
|
t.tv_usec = 0;
|
||||||
|
fd_set fdt[3];
|
||||||
|
fdt[0] = fdsets[0];
|
||||||
|
fdt[1] = fdsets[1];
|
||||||
|
fdt[2] = fdsets[2];
|
||||||
|
return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
@ -890,5 +896,5 @@ void Fl_Window::make_current() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// End of "$Id: Fl_x.cxx,v 1.24.2.17 2000/06/05 21:21:03 mike Exp $".
|
// End of "$Id: Fl_x.cxx,v 1.24.2.18 2000/06/18 00:38:41 bill Exp $".
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user