1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
//
// 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
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
}
|