[util] Wrap fd_set

While select itself is reasonably portable, it turns out that including
the declaration for fd_set makes a bit of a mess for QF's clean headers.
This commit is contained in:
Bill Currie 2021-09-28 10:53:51 +09:00
parent 29f8ed388e
commit cacf0be7f6
8 changed files with 135 additions and 29 deletions

View file

@ -46,21 +46,21 @@ typedef struct in_buttoninfo_s {
#ifndef __QFCC__
#include <sys/select.h>
typedef struct {
vec3_t angles;
vec3_t position;
} viewdelta_t;
struct qf_fd_set;
typedef struct in_driver_s {
void (*init) (void *data);
void (*shutdown) (void *data);
// The driver must provide either both or none of add_select and
// chec_select.
void (*add_select) (fd_set *fdset, int *maxfd, void *data);
void (*check_select) (fd_set *fdset, void *data);
void (*add_select) (struct qf_fd_set *fdset, int *maxfd, void *data);
void (*check_select) (struct qf_fd_set *fdset, void *data);
// Generally musually exclusive with add_select/check_select
void (*process_events) (void *data);
@ -95,8 +95,8 @@ int IN_AddDevice (int driver, void *device, const char *name, const char *id);
void IN_RemoveDevice (int devid);
void IN_SendConnectedDevices (void);
const char *IN_GetDeviceName (int devid);
const char *IN_GetDeviceId (int devid);
const char *IN_GetDeviceName (int devid) __attribute__((pure));
const char *IN_GetDeviceId (int devid) __attribute__((pure));
int IN_AxisInfo (int devid, in_axisinfo_t *axes, int *numaxes);
int IN_ButtonInfo (int devid, in_buttoninfo_t *button, int *numbuttons);

View file

@ -37,7 +37,6 @@
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <sys/select.h>
extern struct cvar_s *sys_nostdout;
extern struct cvar_s *sys_extrasleep;
@ -101,7 +100,8 @@ enum {
#include "QF/sys_developer.h"
};
int Sys_Select (int maxfd, fd_set *fdset, int64_t usec);
struct qf_fd_set;
int Sys_Select (int maxfd, struct qf_fd_set *fdset, int64_t usec);
int Sys_CheckInput (int idle, int net_socket);
const char *Sys_ConsoleInput (void);

98
include/qfselect.h Normal file
View file

@ -0,0 +1,98 @@
/*
qfselect.h
select fd_set wrapper
Copyright (C) 2021 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2021/09/28
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __qfselect_h
#define __qfselect_h
#include "config.h"
#ifdef HAVE_WINDOWS_H
# define mouse_event __hide_mouse_event
# include "winquake.h"
# undef mouse_event
#endif
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
typedef struct qf_fd_set {
fd_set fdset;
} qf_fd_set;
GNU89INLINE inline void QF_FD_CLR (int fd, qf_fd_set *set);
GNU89INLINE inline int QF_FD_ISSET (int fd, qf_fd_set *set);
GNU89INLINE inline void QF_FD_SET (int fd, qf_fd_set *set);
GNU89INLINE inline void QF_FD_ZERO (qf_fd_set *set);
#ifndef IMPLEMENT_QFSELECT_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
void
QF_FD_CLR (int fd, qf_fd_set *set)
{
FD_CLR (fd, &set->fdset);
}
#ifndef IMPLEMENT_QFSELECT_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
int
QF_FD_ISSET(int fd, qf_fd_set *set)
{
return FD_ISSET(fd, &set->fdset);
}
#ifndef IMPLEMENT_QFSELECT_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
void
QF_FD_SET(int fd, qf_fd_set *set)
{
FD_SET(fd, &set->fdset);
}
#ifndef IMPLEMENT_QFSELECT_Funcs
GNU89INLINE inline
#else
VISIBLE
#endif
void
QF_FD_ZERO(qf_fd_set *set)
{
FD_ZERO(&set->fdset);
}
#endif//__qfselect_h

View file

@ -58,6 +58,8 @@
#include "QF/sys.h"
#include "QF/vid.h"
#include "qfselect.h"
typedef struct {
in_driver_t driver;
void *data;
@ -266,11 +268,11 @@ IN_UpdateGrab (cvar_t *var) // called from context_*.c
void
IN_ProcessEvents (void)
{
fd_set fdset;
qf_fd_set fdset;
int maxfd = -1;
int64_t timeout = in_timeout;
FD_ZERO (&fdset);
QF_FD_ZERO (&fdset);
for (size_t i = 0; i < in_drivers.size; i++) {
in_regdriver_t *rd = &in_drivers.a[i];
if (rd->driver.add_select) {

View file

@ -43,6 +43,7 @@
#include "QF/sys.h"
#include "compat.h"
#include "qfselect.h"
#include "evdev/inputlib.h"
typedef struct devmap_s {
@ -62,15 +63,15 @@ in_evdev_keydest_callback (keydest_t key_dest, void *data)
}
static void
in_evdev_add_select (fd_set *fdset, int *maxfd, void *data)
in_evdev_add_select (qf_fd_set *fdset, int *maxfd, void *data)
{
inputlib_add_select (fdset, maxfd);
inputlib_add_select (&fdset->fdset, maxfd);
}
static void
in_evdev_check_select (fd_set *fdset, void *data)
in_evdev_check_select (qf_fd_set *fdset, void *data)
{
inputlib_check_select (fdset);
inputlib_check_select (&fdset->fdset);
}
static void

View file

@ -89,6 +89,8 @@
#include "QF/va.h"
#include "compat.h"
#define IMPLEMENT_QFSELECT_Funcs
#include "qfselect.h"
static void Sys_StdPrintf (const char *fmt, va_list args) __attribute__((format(PRINTF, 1, 0)));
static void Sys_ErrPrintf (const char *fmt, va_list args) __attribute__((format(PRINTF, 1, 0)));
@ -721,7 +723,7 @@ Sys_DebugLog (const char *file, const char *fmt, ...)
}
VISIBLE int
Sys_Select (int maxfd, fd_set *fdset, int64_t usec)
Sys_Select (int maxfd, qf_fd_set *fdset, int64_t usec)
{
struct timeval _timeout;
struct timeval *timeout = 0;
@ -737,13 +739,13 @@ Sys_Select (int maxfd, fd_set *fdset, int64_t usec)
}
}
return select (maxfd + 1, fdset, NULL, NULL, timeout);
return select (maxfd + 1, &fdset->fdset, NULL, NULL, timeout);
}
VISIBLE int
Sys_CheckInput (int idle, int net_socket)
{
fd_set fdset;
qf_fd_set fdset;
int res;
int64_t usec;
@ -766,13 +768,13 @@ Sys_CheckInput (int idle, int net_socket)
// the only reason we have a timeout at all is so that if the last
// connected client times out, the message would not otherwise
// be printed until the next event.
FD_ZERO (&fdset);
QF_FD_ZERO (&fdset);
#ifndef _WIN32
if (do_stdin)
FD_SET (0, &fdset);
QF_FD_SET (0, &fdset);
#endif
if (net_socket >= 0)
FD_SET (((unsigned) net_socket), &fdset); // cast needed for windows
QF_FD_SET (((unsigned) net_socket), &fdset);// cast needed for windows
if (idle && sys_dead_sleep->int_val)
usec = -1;
@ -781,7 +783,7 @@ Sys_CheckInput (int idle, int net_socket)
if (res == 0 || res == -1)
return 0;
#ifndef _WIN32
stdin_ready = FD_ISSET (0, &fdset);
stdin_ready = QF_FD_ISSET (0, &fdset);
#endif
return 1;
}

View file

@ -76,6 +76,7 @@
#include "compat.h"
#include "context_x11.h"
#include "dga_check.h"
#include "qfselect.h"
#include "vid_internal.h"
cvar_t *in_snd_block;
@ -782,18 +783,18 @@ in_x11_grab_input (void *data, int grab)
}
static void
in_x11_add_select (fd_set *fdset, int *maxfd, void *data)
in_x11_add_select (qf_fd_set *fdset, int *maxfd, void *data)
{
FD_SET (x11_fd, fdset);
QF_FD_SET (x11_fd, fdset);
if (*maxfd < x11_fd) {
*maxfd = x11_fd;
}
}
static void
in_x11_check_select (fd_set *fdset, void *data)
in_x11_check_select (qf_fd_set *fdset, void *data)
{
if (FD_ISSET (x11_fd, fdset)) {
if (QF_FD_ISSET (x11_fd, fdset)) {
X11_ProcessEvents (); // Get events from X server.
}
}

View file

@ -51,6 +51,8 @@
#include "QF/keys.h"
#include "QF/sys.h"
#include "qfselect.h"
#include "ruamoko/qwaq/qwaq.h"
#include "ruamoko/qwaq/qwaq-input.h"
#include "ruamoko/qwaq/ui/event.h"
@ -466,16 +468,16 @@ term_shutdown (void *_res)
#define FD 0
static void
term_add_select (fd_set *fdset, int *maxfd, void *_res)
term_add_select (qf_fd_set *fdset, int *maxfd, void *_res)
{
FD_SET (FD, fdset);
QF_FD_SET (FD, fdset);
if (*maxfd < FD) {
*maxfd = FD;
}
}
static void
term_check_select (fd_set *fdset, void *_res)
term_check_select (qf_fd_set *fdset, void *_res)
{
qwaq_input_resources_t *res = _res;
char buf[256];
@ -492,7 +494,7 @@ term_check_select (fd_set *fdset, void *_res)
resize_event (res);
}
#endif
if (FD_ISSET (FD, fdset)) {
if (QF_FD_ISSET (FD, fdset)) {
len = read(0, buf, sizeof (buf));
for (int i = 0; i < len; i++) {
process_char (res, buf[i]);