From b2cbcbfc16cde88a7c0af5d03c162aa55201046b Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 7 Jul 2013 16:53:35 +0200 Subject: input: use only one array for input sources Removes some code duplication. Also restructure the input waiting code a bit: split the select() loop into a input_wait_read() function. On systems which do not have POSIX select(), this function has an alternate implementation, which waits unconditionally. --- core/input/input.c | 270 +++++++++++++++++++++++++---------------------------- core/input/input.h | 3 - 2 files changed, 128 insertions(+), 145 deletions(-) diff --git a/core/input/input.c b/core/input/input.c index 36543f3e5f..889f5fd1c7 100644 --- a/core/input/input.c +++ b/core/input/input.c @@ -462,20 +462,12 @@ struct key_name modifier_names[] = { { 0 } }; -#ifndef MP_MAX_KEY_FD -#define MP_MAX_KEY_FD 10 -#endif - -#ifndef MP_MAX_CMD_FD -#define MP_MAX_CMD_FD 10 -#endif +#define MP_MAX_FDS 10 struct input_fd { int fd; - union { - int (*key)(void *ctx, int fd); - int (*cmd)(int fd, char *dest, int size); - } read_func; + int (*read_key)(void *ctx, int fd); + int (*read_cmd)(int fd, char *dest, int size); int (*close_func)(int fd); void *ctx; unsigned eof : 1; @@ -553,11 +545,8 @@ struct input_ctx { unsigned int mouse_event_counter; - struct input_fd key_fds[MP_MAX_KEY_FD]; - unsigned int num_key_fd; - - struct input_fd cmd_fds[MP_MAX_CMD_FD]; - unsigned int num_cmd_fd; + struct input_fd fds[MP_MAX_FDS]; + unsigned int num_fds; struct cmd_queue key_cmd_queue; struct cmd_queue control_cmd_queue; @@ -700,98 +689,90 @@ static void queue_add(struct cmd_queue *queue, struct mp_cmd *cmd, } } -int mp_input_add_cmd_fd(struct input_ctx *ictx, int fd, int select, +static struct input_fd *mp_input_add_fd(struct input_ctx *ictx) +{ + if (ictx->num_fds == MP_MAX_FDS) { + mp_tmsg(MSGT_INPUT, MSGL_ERR, "Too many file descriptors.\n"); + return NULL; + } + + struct input_fd *fd = &ictx->fds[ictx->num_fds]; + *fd = (struct input_fd){ + .fd = -1, + .no_select = 1, + }; + ictx->num_fds++; + + return fd; +} + +int mp_input_add_cmd_fd(struct input_ctx *ictx, int unix_fd, int select, int read_func(int fd, char *dest, int size), int close_func(int fd)) { - if (ictx->num_cmd_fd == MP_MAX_CMD_FD) { - mp_tmsg(MSGT_INPUT, MSGL_ERR, "Too many command file descriptors, " - "cannot register file descriptor %d.\n", fd); - return 0; - } - if (select && fd < 0) { + if (select && unix_fd < 0) { mp_msg(MSGT_INPUT, MSGL_ERR, - "Invalid fd %d in mp_input_add_cmd_fd", fd); + "Invalid fd %d in mp_input_add_cmd_fd", unix_fd); return 0; } - ictx->cmd_fds[ictx->num_cmd_fd] = (struct input_fd){ - .fd = fd, - .read_func.cmd = read_func ? read_func : default_cmd_func, - .close_func = close_func, - .no_select = !select - }; - ictx->num_cmd_fd++; - + struct input_fd *fd = mp_input_add_fd(ictx); + if (!fd) + return 0; + fd->fd = unix_fd; + fd->no_select = !select; + fd->read_cmd = read_func ? read_func : default_cmd_func; + fd->close_func = close_func; return 1; } -void mp_input_rm_cmd_fd(struct input_ctx *ictx, int fd) +int mp_input_add_key_fd(struct input_ctx *ictx, int unix_fd, int select, + int read_func(void *ctx, int fd), + int close_func(int fd), void *ctx) { - struct input_fd *cmd_fds = ictx->cmd_fds; - unsigned int i; - - for (i = 0; i < ictx->num_cmd_fd; i++) { - if (cmd_fds[i].fd == fd) - break; + if (select && unix_fd < 0) { + mp_msg(MSGT_INPUT, MSGL_ERR, + "Invalid fd %d in mp_input_add_key_fd", unix_fd); + return 0; } - if (i == ictx->num_cmd_fd) - return; - if (cmd_fds[i].close_func) - cmd_fds[i].close_func(cmd_fds[i].fd); - talloc_free(cmd_fds[i].buffer); + assert(read_func); - if (i + 1 < ictx->num_cmd_fd) - memmove(&cmd_fds[i], &cmd_fds[i + 1], - (ictx->num_cmd_fd - i - 1) * sizeof(struct input_fd)); - ictx->num_cmd_fd--; + struct input_fd *fd = mp_input_add_fd(ictx); + if (!fd) + return 0; + fd->fd = unix_fd; + fd->no_select = !select; + fd->read_key = read_func; + fd->close_func = close_func; + fd->ctx = ctx; + return 1; } -void mp_input_rm_key_fd(struct input_ctx *ictx, int fd) + +static void mp_input_rm_fd(struct input_ctx *ictx, int fd) { - struct input_fd *key_fds = ictx->key_fds; + struct input_fd *fds = ictx->fds; unsigned int i; - for (i = 0; i < ictx->num_key_fd; i++) { - if (key_fds[i].fd == fd) + for (i = 0; i < ictx->num_fds; i++) { + if (fds[i].fd == fd) break; } - if (i == ictx->num_key_fd) + if (i == ictx->num_fds) return; - if (key_fds[i].close_func) - key_fds[i].close_func(key_fds[i].fd); + if (fds[i].close_func) + fds[i].close_func(fds[i].fd); + talloc_free(fds[i].buffer); - if (i + 1 < ictx->num_key_fd) - memmove(&key_fds[i], &key_fds[i + 1], - (ictx->num_key_fd - i - 1) * sizeof(struct input_fd)); - ictx->num_key_fd--; + if (i + 1 < ictx->num_fds) + memmove(&fds[i], &fds[i + 1], + (ictx->num_fds - i - 1) * sizeof(struct input_fd)); + ictx->num_fds--; } -int mp_input_add_key_fd(struct input_ctx *ictx, int fd, int select, - int read_func(void *ctx, int fd), - int close_func(int fd), void *ctx) +void mp_input_rm_key_fd(struct input_ctx *ictx, int fd) { - if (ictx->num_key_fd == MP_MAX_KEY_FD) { - mp_tmsg(MSGT_INPUT, MSGL_ERR, "Too many key file descriptors, " - "cannot register file descriptor %d.\n", fd); - return 0; - } - if (select && fd < 0) { - mp_msg(MSGT_INPUT, MSGL_ERR, - "Invalid fd %d in mp_input_add_key_fd", fd); - return 0; - } - - ictx->key_fds[ictx->num_key_fd] = (struct input_fd){ - .fd = fd, - .read_func.key = read_func, - .close_func = close_func, - .no_select = !select, - .ctx = ctx, - }; - ictx->num_key_fd++; - - return 1; + mp_input_rm_fd(ictx, fd); } static int parse_cycle_dir(const struct m_option *opt, struct bstr name, @@ -1068,8 +1049,8 @@ static int read_cmd(struct input_fd *mp_fd, char **ret) // Get some data if needed/possible while (!mp_fd->got_cmd && !mp_fd->eof && (mp_fd->size - mp_fd->pos > 1)) { - int r = mp_fd->read_func.cmd(mp_fd->fd, mp_fd->buffer + mp_fd->pos, - mp_fd->size - 1 - mp_fd->pos); + int r = mp_fd->read_cmd(mp_fd->fd, mp_fd->buffer + mp_fd->pos, + mp_fd->size - 1 - mp_fd->pos); // Error ? if (r < 0) { switch (r) { @@ -1595,7 +1576,7 @@ static void read_cmd_fd(struct input_ctx *ictx, struct input_fd *cmd_fd) static void read_key_fd(struct input_ctx *ictx, struct input_fd *key_fd) { - int code = key_fd->read_func.key(key_fd->ctx, key_fd->fd); + int code = key_fd->read_key(key_fd->ctx, key_fd->fd); if (code >= 0 || code == MP_INPUT_RELEASE_ALL) { mp_input_feed_key(ictx, code); return; @@ -1611,50 +1592,38 @@ static void read_key_fd(struct input_ctx *ictx, struct input_fd *key_fd) } } -/** - * \param time time to wait at most for an event in milliseconds - */ -static void read_events(struct input_ctx *ictx, int time) +static void read_fd(struct input_ctx *ictx, struct input_fd *fd) { - if (ictx->num_key_down) { - time = FFMIN(time, 1000 / ictx->ar_rate); - time = FFMIN(time, ictx->ar_delay); + if (fd->read_cmd) { + read_cmd_fd(ictx, fd); + } else { + read_key_fd(ictx, fd); } - time = FFMAX(time, 0); - ictx->got_new_events = false; - struct input_fd *key_fds = ictx->key_fds; - struct input_fd *cmd_fds = ictx->cmd_fds; - for (int i = 0; i < ictx->num_key_fd; i++) - if (key_fds[i].dead) { - mp_input_rm_key_fd(ictx, key_fds[i].fd); - i--; - } else if (time && key_fds[i].no_select) - read_key_fd(ictx, &key_fds[i]); - for (int i = 0; i < ictx->num_cmd_fd; i++) - if (cmd_fds[i].dead || cmd_fds[i].eof) { - mp_input_rm_cmd_fd(ictx, cmd_fds[i].fd); +} + +static void remove_dead_fds(struct input_ctx *ictx) +{ + for (int i = 0; i < ictx->num_fds; i++) { + if (ictx->fds[i].dead) { + mp_input_rm_fd(ictx, ictx->fds[i].fd); i--; - } else if (time && cmd_fds[i].no_select) - read_cmd_fd(ictx, &cmd_fds[i]); - if (ictx->got_new_events) - time = 0; + } + } +} + #ifdef HAVE_POSIX_SELECT + +static void input_wait_read(struct input_ctx *ictx, int time) +{ fd_set fds; FD_ZERO(&fds); int max_fd = 0; - for (int i = 0; i < ictx->num_key_fd; i++) { - if (key_fds[i].no_select) + for (int i = 0; i < ictx->num_fds; i++) { + if (ictx->fds[i].no_select) continue; - if (key_fds[i].fd > max_fd) - max_fd = key_fds[i].fd; - FD_SET(key_fds[i].fd, &fds); - } - for (int i = 0; i < ictx->num_cmd_fd; i++) { - if (cmd_fds[i].no_select) - continue; - if (cmd_fds[i].fd > max_fd) - max_fd = cmd_fds[i].fd; - FD_SET(cmd_fds[i].fd, &fds); + if (ictx->fds[i].fd > max_fd) + max_fd = ictx->fds[i].fd; + FD_SET(ictx->fds[i].fd, &fds); } struct timeval tv, *time_val; tv.tv_sec = time / 1000; @@ -1666,27 +1635,48 @@ static void read_events(struct input_ctx *ictx, int time) strerror(errno)); FD_ZERO(&fds); } + for (int i = 0; i < ictx->num_fds; i++) { + if (!ictx->fds[i].no_select && !FD_ISSET(ictx->fds[i].fd, &fds)) + continue; + read_fd(ictx, &ictx->fds[i]); + } +} + #else + +static void input_wait_read(struct input_ctx *ictx, int time) +{ if (time > 0) mp_sleep_us(time * 1000); -#endif + for (int i = 0; i < ictx->num_fds; i++) + read_fd(ictx, &ictx->fds[i]); +} - for (int i = 0; i < ictx->num_key_fd; i++) { -#ifdef HAVE_POSIX_SELECT - if (!key_fds[i].no_select && !FD_ISSET(key_fds[i].fd, &fds)) - continue; #endif - read_key_fd(ictx, &key_fds[i]); - } - for (int i = 0; i < ictx->num_cmd_fd; i++) { -#ifdef HAVE_POSIX_SELECT - if (!cmd_fds[i].no_select && !FD_ISSET(cmd_fds[i].fd, &fds)) - continue; -#endif - read_cmd_fd(ictx, &cmd_fds[i]); +/** + * \param time time to wait at most for an event in milliseconds + */ +static void read_events(struct input_ctx *ictx, int time) +{ + if (ictx->num_key_down) { + time = FFMIN(time, 1000 / ictx->ar_rate); + time = FFMIN(time, ictx->ar_delay); } + time = FFMAX(time, 0); + ictx->got_new_events = false; + remove_dead_fds(ictx); + if (time) { + for (int i = 0; i < ictx->num_fds; i++) { + if (ictx->fds[i].no_select) + read_fd(ictx, &ictx->fds[i]); + } + } + if (ictx->got_new_events) + time = 0; + + input_wait_read(ictx, time); } /* To support blocking file descriptors we don't loop the read over @@ -2211,13 +2201,9 @@ void mp_input_uninit(struct input_ctx *ictx, struct input_conf *input_conf) } #endif - for (int i = 0; i < ictx->num_key_fd; i++) { - if (ictx->key_fds[i].close_func) - ictx->key_fds[i].close_func(ictx->key_fds[i].fd); - } - for (int i = 0; i < ictx->num_cmd_fd; i++) { - if (ictx->cmd_fds[i].close_func) - ictx->cmd_fds[i].close_func(ictx->cmd_fds[i].fd); + for (int i = 0; i < ictx->num_fds; i++) { + if (ictx->fds[i].close_func) + ictx->fds[i].close_func(ictx->fds[i].fd); } for (int i = 0; i < 2; i++) { if (ictx->wakeup_pipe[i] != -1) diff --git a/core/input/input.h b/core/input/input.h index da92efd373..1a0f2529ce 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -170,9 +170,6 @@ int mp_input_add_cmd_fd(struct input_ctx *ictx, int fd, int select, int read_func(int fd, char *dest, int size), int close_func(int fd)); -// This removes a cmd driver, you usually don't need to use it. -void mp_input_rm_cmd_fd(struct input_ctx *ictx, int fd); - /* The args are similar to the cmd version above, except you must give * a read_func, and it should return key codes (ASCII plus keycodes.h). */ -- cgit v1.2.3