102 lines
2.5 KiB
C++
102 lines
2.5 KiB
C++
//
|
|
// Definition of the part of the Screen interface shared by X11/Wayland
|
|
//
|
|
// Copyright 2022-2024 by Bill Spitzak and others.
|
|
//
|
|
// This library is free software. Distribution and use rights are outlined in
|
|
// the file "COPYING" which should have been included with this file. If this
|
|
// file is missing or damaged, see the license at:
|
|
//
|
|
// https://www.fltk.org/COPYING.php
|
|
//
|
|
// Please see the following page on how to report bugs and issues:
|
|
//
|
|
// https://www.fltk.org/bugs.php
|
|
//
|
|
|
|
#include <config.h>
|
|
#include <sys/time.h>
|
|
#include "Fl_Unix_Screen_Driver.H"
|
|
|
|
#if USE_POLL
|
|
pollfd *Fl_Unix_Screen_Driver::pollfds = NULL;
|
|
#else
|
|
fd_set Fl_Unix_Screen_Driver::fdsets[3];
|
|
#endif
|
|
int Fl_Unix_Screen_Driver::maxfd = 0;
|
|
int Fl_Unix_Screen_Driver::nfds = 0;
|
|
Fl_Unix_Screen_Driver::FD *Fl_Unix_Screen_Driver::fd = NULL;
|
|
|
|
// these pointers are set by the Fl::lock() function:
|
|
static void nothing() {}
|
|
void (*fl_lock_function)() = nothing;
|
|
void (*fl_unlock_function)() = nothing;
|
|
|
|
|
|
// 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_Unix_Screen_Driver::poll_or_select_with_delay(double time_to_wait) {
|
|
# if !USE_POLL
|
|
fd_set fdt[3];
|
|
fdt[0] = fdsets[0];
|
|
fdt[1] = fdsets[1];
|
|
fdt[2] = fdsets[2];
|
|
# endif
|
|
int n;
|
|
|
|
fl_unlock_function();
|
|
|
|
if (time_to_wait < 2147483.648) {
|
|
# if USE_POLL
|
|
n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5));
|
|
# else
|
|
timeval t;
|
|
t.tv_sec = int(time_to_wait);
|
|
t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec));
|
|
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
|
|
}
|
|
|
|
fl_lock_function();
|
|
|
|
if (n > 0) {
|
|
for (int i=0; i<nfds; i++) {
|
|
# if USE_POLL
|
|
if (pollfds[i].revents) fd[i].cb(pollfds[i].fd, fd[i].arg);
|
|
# else
|
|
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);
|
|
# endif
|
|
}
|
|
}
|
|
return n;
|
|
}
|
|
|
|
|
|
int Fl_Unix_Screen_Driver::poll_or_select() {
|
|
if (!nfds) return 0; // nothing to select or poll
|
|
# 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
|
|
}
|