summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBill Spitzak <spitzak@gmail.com>1999-04-17 01:02:30 +0000
committerBill Spitzak <spitzak@gmail.com>1999-04-17 01:02:30 +0000
commit0e29799dda01961603e5dbd790681b0e0303f485 (patch)
tree39a464e73d39a660f5b7a93ee85340115dbd8b93 /src
parent677604187378f4d3a85433963f97c4de34eea659 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/Fl.cxx53
-rw-r--r--src/Fl_win32.cxx106
-rw-r--r--src/Fl_x.cxx102
3 files changed, 152 insertions, 109 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx
index 9b03897d1..df51ed702 100644
--- a/src/Fl.cxx
+++ b/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 $".
//
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index 8f424b701..a687cd448 100644
--- a/src/Fl_win32.cxx
+++ b/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) {
+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;
+ }
+ // move it down in the array if necessary:
+ if (j<i) {
+ fd[j]=fd[i];
+ }
+ j++;
}
nfds = j;
- 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--;
+}
+
+void Fl::remove_fd(int n) {
+ 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];
-
-
- // 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 (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];
+
+ 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 $".
//
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index 96f264646..02b0a458a 100644
--- a/src/Fl_x.cxx
+++ b/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;};
-#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!
-//
+#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))
-#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 {
+#define POLLIN 1
+#define POLLOUT 4
+#define POLLERR 8
+
+#endif /* HAVE_POLL */
+
+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 $".
//