mirror of https://github.com/fltk/fltk
Fl::add_fd() structures are dynamically allocated so you can listen to
as many connections as you want (up to the maximum number handled by select()). Fl::remove_fd(fd, when) added. This allows you to remove the read, write, and error callbacks individually. Fl::remove_fd(fd) does Fl::remove_fd(fd,-1). Fl::add_fd() calls Fl::remove_fd(), so it can be used safely to replace callbacks with new ones for the same file descriptor. Fl::add_timeout() also dynamically allocates it's array so there is no limit on the number of pending timeouts. I cut/pasted the changes into the Windoze version but this is UNTESTED! Somebody please do a test compile. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.0@544 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
6776041873
commit
0e29799dda
7
FL/Fl.H
7
FL/Fl.H
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// "$Id: Fl.H,v 1.8 1999/02/23 22:12:38 mike Exp $"
|
||||
// "$Id: Fl.H,v 1.8.2.1 1999/04/17 01:02:27 bill Exp $"
|
||||
//
|
||||
// Main header file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
|
@ -89,8 +89,9 @@ public:
|
|||
static FL_EXPORT Fl_Widget* readqueue();
|
||||
static FL_EXPORT void add_timeout(double t,void (*cb)(void*),void* = 0);
|
||||
static FL_EXPORT void remove_timeout(void (*cb)(void*), void* = 0);
|
||||
static FL_EXPORT void add_fd(int fd, int when, void (*cb)(int, void*), void* = 0);
|
||||
static FL_EXPORT void add_fd(int fd, int when, void (*cb)(int,void*),void* =0);
|
||||
static FL_EXPORT void add_fd(int fd, void (*cb)(int, void*), void* = 0);
|
||||
static FL_EXPORT void remove_fd(int, int when);
|
||||
static FL_EXPORT void remove_fd(int);
|
||||
static FL_EXPORT void add_idle(void (*cb)(void*), void* = 0);
|
||||
static FL_EXPORT void remove_idle(void (*cb)(void*), void* = 0);
|
||||
|
@ -204,5 +205,5 @@ public:
|
|||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id: Fl.H,v 1.8 1999/02/23 22:12:38 mike Exp $".
|
||||
// End of "$Id: Fl.H,v 1.8.2.1 1999/04/17 01:02:27 bill Exp $".
|
||||
//
|
||||
|
|
53
src/Fl.cxx
53
src/Fl.cxx
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// "$Id: Fl.cxx,v 1.24.2.3 1999/04/10 08:09:38 bill Exp $"
|
||||
// "$Id: Fl.cxx,v 1.24.2.4 1999/04/17 01:02:28 bill Exp $"
|
||||
//
|
||||
// Main event handling code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
|
@ -27,6 +27,8 @@
|
|||
#include <FL/Fl_Window.H>
|
||||
#include <FL/x.H>
|
||||
#include <ctype.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
//
|
||||
// Globals...
|
||||
|
@ -68,31 +70,36 @@ int Fl::event_inside(const Fl_Widget *o) /*const*/ {
|
|||
// Timeouts are insert-sorted into order. This works good if there
|
||||
// are only a small number:
|
||||
|
||||
#define MAXTIMEOUT 8
|
||||
|
||||
static struct {
|
||||
static struct Timeout {
|
||||
double time;
|
||||
void (*cb)(void*);
|
||||
void* arg;
|
||||
} timeout[MAXTIMEOUT+1];
|
||||
} * timeout;
|
||||
static int numtimeouts;
|
||||
static int timeout_array_size;
|
||||
|
||||
void Fl::add_timeout(double t, void (*cb)(void *), void *v) {
|
||||
int i;
|
||||
|
||||
fl_elapsed();
|
||||
|
||||
if (numtimeouts<MAXTIMEOUT) numtimeouts++;
|
||||
for (i=0; i<(numtimeouts-1); i++) {
|
||||
if (numtimeouts >= timeout_array_size) {
|
||||
timeout_array_size = 2*timeout_array_size+1;
|
||||
timeout = (Timeout*)realloc(timeout, timeout_array_size*sizeof(Timeout));
|
||||
}
|
||||
|
||||
// insert-sort the new timeout:
|
||||
int i;
|
||||
for (i=0; i<numtimeouts; i++) {
|
||||
if (timeout[i].time > t) {
|
||||
for (int j=numtimeouts-1; j>i; j--) timeout[j] = timeout[j-1];
|
||||
for (int j=numtimeouts; j>i; j--) timeout[j] = timeout[j-1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timeout[i].time = t;
|
||||
timeout[i].cb = cb;
|
||||
timeout[i].arg = v;
|
||||
|
||||
numtimeouts++;
|
||||
}
|
||||
|
||||
void Fl::remove_timeout(void (*cb)(void *), void *v) {
|
||||
|
@ -105,22 +112,16 @@ void Fl::remove_timeout(void (*cb)(void *), void *v) {
|
|||
}
|
||||
|
||||
static void call_timeouts() {
|
||||
if (timeout[0].time > 0) return;
|
||||
struct {
|
||||
void (*cb)(void *);
|
||||
void *arg;
|
||||
} temp[MAXTIMEOUT];
|
||||
int i,j,k;
|
||||
// copy all expired timeouts to temp array:
|
||||
for (i=j=0; j<numtimeouts && timeout[j].time <= 0; i++,j++) {
|
||||
temp[i].cb = timeout[j].cb;
|
||||
temp[i].arg= timeout[j].arg;
|
||||
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--;
|
||||
if (numtimeouts) memmove(timeout, timeout+1, numtimeouts*sizeof(Timeout));
|
||||
// now it is safe for the callback to do add_timeout:
|
||||
cb(arg);
|
||||
}
|
||||
// remove them from source array:
|
||||
for (k=0; j<numtimeouts;) timeout[k++] = timeout[j++];
|
||||
numtimeouts = k;
|
||||
// and then call them:
|
||||
for (k=0; k<i; k++) temp[k].cb(temp[k].arg);
|
||||
}
|
||||
|
||||
void Fl::flush() {
|
||||
|
@ -695,5 +696,5 @@ int fl_old_shortcut(const char* s) {
|
|||
}
|
||||
|
||||
//
|
||||
// End of "$Id: Fl.cxx,v 1.24.2.3 1999/04/10 08:09:38 bill Exp $".
|
||||
// End of "$Id: Fl.cxx,v 1.24.2.4 1999/04/17 01:02:28 bill Exp $".
|
||||
//
|
||||
|
|
108
src/Fl_win32.cxx
108
src/Fl_win32.cxx
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// "$Id: Fl_win32.cxx,v 1.33.2.5 1999/04/10 08:09:38 bill Exp $"
|
||||
// "$Id: Fl_win32.cxx,v 1.33.2.6 1999/04/17 01:02:29 bill Exp $"
|
||||
//
|
||||
// WIN32-specific code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
|
@ -56,43 +56,60 @@
|
|||
#define POLLIN 1
|
||||
#define POLLOUT 4
|
||||
#define POLLERR 8
|
||||
struct pollfd {int fd; short events; short revents;};
|
||||
|
||||
#define MAXFD 8
|
||||
static fd_set fdsets[3];
|
||||
static int nfds;
|
||||
static struct pollfd fds[MAXFD];
|
||||
static struct {
|
||||
static int nfds = 0;
|
||||
static int fd_array_size = 0;
|
||||
static struct FD {
|
||||
int fd;
|
||||
short events;
|
||||
void (*cb)(int, void*);
|
||||
void* arg;
|
||||
} fd[MAXFD];
|
||||
} *fd = 0;
|
||||
|
||||
void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
|
||||
int i;
|
||||
if (nfds < MAXFD) {i = nfds; nfds++;} else {i = MAXFD-1;}
|
||||
fds[i].fd = n;
|
||||
fds[i].events = events;
|
||||
remove_fd(n,events);
|
||||
int i = nfds++;
|
||||
if (i >= fd_array_size) {
|
||||
fd_array_size = 2*fd_array_size+1;
|
||||
fd = (FD*)realloc(fd, fd_array_size*sizeof(FD));
|
||||
}
|
||||
fd[i].fd = n;
|
||||
fd[i].events = events;
|
||||
fd[i].cb = cb;
|
||||
fd[i].arg = v;
|
||||
if (events & POLLIN) FD_SET(n, &fdsets[0]);
|
||||
if (events & POLLOUT) FD_SET(n, &fdsets[1]);
|
||||
if (events & POLLERR) FD_SET(n, &fdsets[2]);
|
||||
fd[i].cb = cb;
|
||||
fd[i].arg = v;
|
||||
if (n > maxfd) maxfd = n;
|
||||
}
|
||||
|
||||
void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) {
|
||||
Fl::add_fd(fd,POLLIN,cb,v);
|
||||
Fl::add_fd(fd, POLLIN, cb, v);
|
||||
}
|
||||
|
||||
void Fl::remove_fd(int n, int events) {
|
||||
int i,j;
|
||||
for (i=j=0; i<nfds; i++) {
|
||||
if (fd[i].fd == n) {
|
||||
int e = fd[i].events & ~events;
|
||||
if (!e) continue; // if no events left, delete this fd
|
||||
fd[i].events = e;
|
||||
}
|
||||
// move it down in the array if necessary:
|
||||
if (j<i) {
|
||||
fd[j]=fd[i];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
nfds = j;
|
||||
if (events & POLLIN) FD_CLR(n, &fdsets[0]);
|
||||
if (events & POLLOUT) FD_CLR(n, &fdsets[1]);
|
||||
if (events & POLLERR) FD_CLR(n, &fdsets[2]);
|
||||
if (n == maxfd) maxfd--;
|
||||
}
|
||||
|
||||
void Fl::remove_fd(int n) {
|
||||
int i,j;
|
||||
for (i=j=0; i<nfds; i++) {
|
||||
if (fds[i].fd == n);
|
||||
else {if (j<i) {fd[j]=fd[i]; fds[j]=fds[i];} j++;}
|
||||
}
|
||||
nfds = j;
|
||||
FD_CLR(n, &fdsets[0]);
|
||||
FD_CLR(n, &fdsets[1]);
|
||||
FD_CLR(n, &fdsets[2]);
|
||||
remove_fd(n, -1);
|
||||
}
|
||||
|
||||
MSG fl_msg;
|
||||
|
@ -112,29 +129,28 @@ int fl_ready() {
|
|||
|
||||
double fl_wait(int timeout_flag, double time) {
|
||||
int have_message;
|
||||
timeval t;
|
||||
fd_set fdt[3];
|
||||
if (nfds) {
|
||||
// For WIN32 we need to poll for socket input FIRST, since
|
||||
// the event queue is not something we can select() on...
|
||||
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];
|
||||
|
||||
// For WIN32 we need to poll for socket input FIRST, since
|
||||
// the event queue is not something we can select() on...
|
||||
|
||||
t.tv_sec = 0;
|
||||
t.tv_usec = 0;
|
||||
|
||||
fdt[0] = fdsets[0];
|
||||
fdt[1] = fdsets[1];
|
||||
fdt[2] = fdsets[2];
|
||||
|
||||
if (::select(0,&fdt[0],&fdt[1],&fdt[2],&t)) {
|
||||
// We got something - do the callback!
|
||||
for (int i = 0; i < nfds; i ++) {
|
||||
int f = fds[i].fd;
|
||||
short revents = 0;
|
||||
if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
|
||||
if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
|
||||
if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
|
||||
if (fds[i].events & revents) fd[i].cb(f, fd[i].arg);
|
||||
if (::select(0,&fdt[0],&fdt[1],&fdt[2],&t)) {
|
||||
// We got something - do the callback!
|
||||
for (int i = 0; i < nfds; i ++) {
|
||||
int f = fd[i].fd;
|
||||
short revents = 0;
|
||||
if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
|
||||
if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
|
||||
if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
|
||||
if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -905,5 +921,5 @@ void Fl_Window::make_current() {
|
|||
}
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_win32.cxx,v 1.33.2.5 1999/04/10 08:09:38 bill Exp $".
|
||||
// End of "$Id: Fl_win32.cxx,v 1.33.2.6 1999/04/17 01:02:29 bill Exp $".
|
||||
//
|
||||
|
|
104
src/Fl_x.cxx
104
src/Fl_x.cxx
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// "$Id: Fl_x.cxx,v 1.24.2.2 1999/04/10 08:09:39 bill Exp $"
|
||||
// "$Id: Fl_x.cxx,v 1.24.2.3 1999/04/17 01:02:29 bill Exp $"
|
||||
//
|
||||
// X specific code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
|
@ -41,77 +41,103 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#if HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif /* HAVE_SYS_SELECT_H */
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// interface to poll/select call:
|
||||
|
||||
#if HAVE_POLL
|
||||
|
||||
#include <poll.h>
|
||||
static pollfd *pollfds = 0;
|
||||
|
||||
#else
|
||||
struct pollfd {int fd; short events; short revents;};
|
||||
|
||||
#if HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif /* HAVE_SYS_SELECT_H */
|
||||
|
||||
// The following #define is only needed for HP-UX 9.x and earlier:
|
||||
//#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e))
|
||||
|
||||
static fd_set fdsets[3];
|
||||
static int maxfd;
|
||||
#define POLLIN 1
|
||||
#define POLLOUT 4
|
||||
#define POLLERR 8
|
||||
|
||||
//
|
||||
// The following #define is only needed for HP-UX 9.x and earlier. 10.x
|
||||
// and beyond have the right stuff, and any good GCC distribution fixes
|
||||
// this, too!
|
||||
//
|
||||
#endif /* HAVE_POLL */
|
||||
|
||||
//#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e))
|
||||
|
||||
#endif
|
||||
|
||||
#define MAXFD 8
|
||||
#if !HAVE_POLL
|
||||
static fd_set fdsets[3];
|
||||
static int maxfd;
|
||||
#endif
|
||||
static int nfds;
|
||||
static struct pollfd fds[MAXFD];
|
||||
static struct {
|
||||
static int nfds = 0;
|
||||
static int fd_array_size = 0;
|
||||
static struct FD {
|
||||
int fd;
|
||||
short events;
|
||||
void (*cb)(int, void*);
|
||||
void* arg;
|
||||
} fd[MAXFD];
|
||||
} *fd = 0;
|
||||
|
||||
void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
|
||||
int i;
|
||||
if (nfds < MAXFD) {i = nfds; nfds++;} else {i = MAXFD-1;}
|
||||
remove_fd(n,events);
|
||||
int i = nfds++;
|
||||
if (i >= fd_array_size) {
|
||||
fd_array_size = 2*fd_array_size+1;
|
||||
fd = (FD*)realloc(fd, fd_array_size*sizeof(FD));
|
||||
#if HAVE_POLL
|
||||
pollfds = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd));
|
||||
#endif
|
||||
}
|
||||
fd[i].fd = n;
|
||||
fd[i].events = events;
|
||||
fd[i].cb = cb;
|
||||
fd[i].arg = v;
|
||||
#if HAVE_POLL
|
||||
fds[i].fd = n;
|
||||
fds[i].events = events;
|
||||
#if !HAVE_POLL
|
||||
#else
|
||||
if (events & POLLIN) FD_SET(n, &fdsets[0]);
|
||||
if (events & POLLOUT) FD_SET(n, &fdsets[1]);
|
||||
if (events & POLLERR) FD_SET(n, &fdsets[2]);
|
||||
if (n > maxfd) maxfd = n;
|
||||
#endif
|
||||
fd[i].cb = cb;
|
||||
fd[i].arg = v;
|
||||
}
|
||||
|
||||
void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) {
|
||||
Fl::add_fd(fd,POLLIN,cb,v);
|
||||
Fl::add_fd(fd, POLLIN, cb, v);
|
||||
}
|
||||
|
||||
void Fl::remove_fd(int n) {
|
||||
void Fl::remove_fd(int n, int events) {
|
||||
int i,j;
|
||||
for (i=j=0; i<nfds; i++) {
|
||||
if (fds[i].fd == n);
|
||||
else {if (j<i) {fd[j]=fd[i]; fds[j]=fds[i];} j++;}
|
||||
if (fd[i].fd == n) {
|
||||
int e = fd[i].events & ~events;
|
||||
if (!e) continue; // if no events left, delete this fd
|
||||
fd[i].events = e;
|
||||
#if HAVE_POLL
|
||||
fds[j].events = e;
|
||||
#endif
|
||||
}
|
||||
// move it down in the array if necessary:
|
||||
if (j<i) {
|
||||
fd[j]=fd[i];
|
||||
#if HAVE_POLL
|
||||
fds[j]=fds[i];
|
||||
#endif
|
||||
}
|
||||
j++;
|
||||
}
|
||||
nfds = j;
|
||||
#if !HAVE_POLL
|
||||
FD_CLR(n, &fdsets[0]);
|
||||
FD_CLR(n, &fdsets[1]);
|
||||
FD_CLR(n, &fdsets[2]);
|
||||
if (events & POLLIN) FD_CLR(n, &fdsets[0]);
|
||||
if (events & POLLOUT) FD_CLR(n, &fdsets[1]);
|
||||
if (events & POLLERR) FD_CLR(n, &fdsets[2]);
|
||||
if (n == maxfd) maxfd--;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fl::remove_fd(int n) {
|
||||
remove_fd(n, -1);
|
||||
}
|
||||
|
||||
int fl_ready() {
|
||||
if (XQLength(fl_display)) return 1;
|
||||
#if HAVE_POLL
|
||||
|
@ -185,14 +211,14 @@ double fl_wait(int timeout_flag, double time) {
|
|||
if (n > 0) {
|
||||
for (int i=0; i<nfds; i++) {
|
||||
#if HAVE_POLL
|
||||
if (fds[i].revents) fd[i].cb(fds[i].fd, fd[i].arg);
|
||||
if (fds[i].revents) fd[i].cb(fd[i].fd, fd[i].arg);
|
||||
#else
|
||||
int f = fds[i].fd;
|
||||
int f = fd[i].fd;
|
||||
short revents = 0;
|
||||
if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
|
||||
if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
|
||||
if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
|
||||
if (fds[i].events & revents) fd[i].cb(f, fd[i].arg);
|
||||
if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -823,5 +849,5 @@ void Fl_Window::make_current() {
|
|||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_x.cxx,v 1.24.2.2 1999/04/10 08:09:39 bill Exp $".
|
||||
// End of "$Id: Fl_x.cxx,v 1.24.2.3 1999/04/17 01:02:29 bill Exp $".
|
||||
//
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// "$Id: button.cxx,v 1.4 1999/01/07 19:17:50 mike Exp $"
|
||||
// "$Id: button.cxx,v 1.4.2.1 1999/04/17 01:02:30 bill Exp $"
|
||||
//
|
||||
// Button/callback test program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
|
@ -37,6 +37,15 @@ void exitcb(Fl_Widget *, void *) {
|
|||
exit(0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// test Fl::add_fd()...
|
||||
void stdin_cb(int, void*) {
|
||||
char buf[1000];
|
||||
gets(buf);
|
||||
printf("stdin callback\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
Fl_Window *window = new Fl_Window(320,65);
|
||||
Fl_Button *b1 = new Fl_Button(20, 20, 80, 25, "&Beep");
|
||||
|
@ -46,9 +55,12 @@ int main(int argc, char ** argv) {
|
|||
b3->callback(exitcb,0);
|
||||
window->end();
|
||||
window->show(argc,argv);
|
||||
#if 0
|
||||
Fl::add_fd(0, stdin_cb);
|
||||
#endif
|
||||
return Fl::run();
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id: button.cxx,v 1.4 1999/01/07 19:17:50 mike Exp $".
|
||||
// End of "$Id: button.cxx,v 1.4.2.1 1999/04/17 01:02:30 bill Exp $".
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue