From 3deb6c3d4f49bd8933c2cab2e58752f6d0a33c6e Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Wed, 15 Oct 2014 17:48:47 +0200 Subject: input: implement --input-file on unix using the IPC support --- input/input.c | 11 +++++----- input/ipc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++---------- input/pipe-unix.c | 59 ------------------------------------------------- options/options.c | 1 + options/options.h | 1 + wscript_build.py | 1 - 6 files changed, 62 insertions(+), 77 deletions(-) delete mode 100644 input/pipe-unix.c diff --git a/input/input.c b/input/input.c index 613d1ec3b0..c9a5bbe99c 100644 --- a/input/input.c +++ b/input/input.c @@ -165,7 +165,6 @@ struct input_opts { int ar_delay; int ar_rate; char *js_dev; - char *in_file; int use_joystick; int use_lirc; char *lirc_configfile; @@ -188,7 +187,6 @@ const struct m_sub_options input_config = { OPT_PRINT("keylist", mp_print_key_list), OPT_PRINT("cmdlist", mp_print_cmd_list), OPT_STRING("js-dev", js_dev, CONF_GLOBAL), - OPT_STRING("file", in_file, CONF_GLOBAL), OPT_FLAG("default-bindings", default_bindings, CONF_GLOBAL), OPT_FLAG("test", test, CONF_GLOBAL), OPT_INTRANGE("doubleclick-time", doubleclick_time, 0, 0, 1000), @@ -1296,13 +1294,14 @@ void mp_input_load(struct input_ctx *ictx) ictx->win_drag = ictx->global->opts->allow_win_drag; - if (input_conf->in_file && input_conf->in_file[0]) { -#if !defined(__MINGW32__) || HAVE_WAIO - mp_input_pipe_add(ictx, input_conf->in_file); +#if defined(__MINGW32__) + if (ictx->global->opts->input_file && *ictx->global->opts->input_file) +#if HAVE_WAIO + mp_input_pipe_add(ictx, ictx->global->opts->input_file); #else MP_ERR(ictx, "Pipes not available.\n"); #endif - } +#endif } static void clear_queue(struct cmd_queue *queue) diff --git a/input/ipc.c b/input/ipc.c index 7ce8aa3424..e76a9af5e6 100644 --- a/input/ipc.c +++ b/input/ipc.c @@ -31,6 +31,7 @@ #include "osdep/io.h" #include "common/common.h" +#include "common/global.h" #include "common/msg.h" #include "input/input.h" #include "libmpv/client.h" @@ -53,6 +54,7 @@ struct client_arg { struct mp_log *log; struct mpv_handle *client; + char *client_name; int client_fd; char *(*encode_event)(mpv_event *event); @@ -432,6 +434,15 @@ error: return output; } +static char *text_execute_command(struct client_arg *arg, bstr msg) +{ + char *cmd_str = bstrdup0(NULL, msg); + mpv_command_string(arg->client, cmd_str); + talloc_free(cmd_str); + + return NULL; +} + static int ipc_write(int fd, const char *buf, size_t count) { while (count > 0) { @@ -576,26 +587,56 @@ done: return NULL; } -static void ipc_start_client(struct MPContext *mpctx, int id, int fd) +static void ipc_start_client(struct MPContext *mpctx, struct client_arg *client) +{ + client->client = mp_new_client(mpctx->clients, client->client_name), + client->log = mp_client_get_log(client->client); + + pthread_t client_thr; + if (pthread_create(&client_thr, NULL, client_thread, client)) { + mpv_detach_destroy(client->client); + close(client->client_fd); + talloc_free(client); + } +} + +static void ipc_start_client_json(struct MPContext *mpctx, int id, int fd) { struct client_arg *client = talloc_ptrtype(NULL, client); - char *client_name = talloc_asprintf(client, "ipc-%d", id); *client = (struct client_arg){ - .client = mp_new_client(mpctx->clients, client_name), - .client_fd = fd, + .client_name = talloc_asprintf(client, "ipc-%d", id), + .client_fd = fd, .encode_event = json_encode_event, .execute_command = json_execute_command, }; - client->log = mp_client_get_log(client->client); + ipc_start_client(mpctx, client); +} - pthread_t client_thr; - if (pthread_create(&client_thr, NULL, client_thread, client)) { - mpv_detach_destroy(client->client); - close(client->client_fd); - talloc_free(client); +static void ipc_start_client_text(struct MPContext *mpctx, const char *path) +{ + int mode = O_RDONLY; + // Use RDWR for FIFOs to ensure they stay open over multiple accesses. + struct stat st; + if (stat(path, &st) == 0 && S_ISFIFO(st.st_mode)) + mode = O_RDWR; + int client_fd = open(path, mode); + if (client_fd < 0) { + MP_ERR(mpctx, "Could not open pipe at '%s'\n", path); + return; } + + struct client_arg *client = talloc_ptrtype(NULL, client); + *client = (struct client_arg){ + .client_name = "input-file", + .client_fd = client_fd, + + .encode_event = NULL, + .execute_command = text_execute_command, + }; + + ipc_start_client(mpctx, client); } static void *ipc_thread(void *p) @@ -668,7 +709,7 @@ static void *ipc_thread(void *p) goto done; } - ipc_start_client(arg->mpctx, client_num++, client_fd); + ipc_start_client_json(arg->mpctx, client_num++, client_fd); } } @@ -688,6 +729,9 @@ done: void mp_init_ipc(struct MPContext *mpctx) { + if (mpctx->global->opts->input_file && *mpctx->global->opts->input_file) + ipc_start_client_text(mpctx, mpctx->global->opts->input_file); + if (!mpctx->opts->ipc_path || !*mpctx->opts->ipc_path) return; diff --git a/input/pipe-unix.c b/input/pipe-unix.c deleted file mode 100644 index 51eb315d6b..0000000000 --- a/input/pipe-unix.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "common/msg.h" -#include "osdep/io.h" -#include "input.h" -#include "cmd_parse.h" - -static void read_pipe_thread(struct mp_input_src *src, void *param) -{ - void *tmp = talloc_new(NULL); - char *filename = talloc_strdup(tmp, param); // param deallocates after init - int wakeup_fd = mp_input_src_get_wakeup_fd(src); - int fd = -1; - - struct mp_log *log = src->log; - - int mode = O_RDONLY; - // Use RDWR for FIFOs to ensure they stay open over multiple accesses. - struct stat st; - if (stat(filename, &st) == 0 && S_ISFIFO(st.st_mode)) - mode = O_RDWR; - fd = open(filename, mode); - if (fd < 0) { - mp_err(log, "Can't open %s.\n", filename); - goto done; - } - - mp_input_src_init_done(src); - - while (1) { - struct pollfd fds[2] = { - { .fd = fd, .events = POLLIN }, - { .fd = wakeup_fd, .events = POLLIN }, - }; - poll(fds, 2, -1); - if (!(fds[0].revents & POLLIN)) - break; - char buffer[128]; - int r = read(fd, buffer, sizeof(buffer)); - if (r <= 0) - break; - mp_input_src_feed_cmd_text(src, buffer, r); - } - -done: - close(fd); - talloc_free(tmp); -} - -void mp_input_pipe_add(struct input_ctx *ictx, const char *filename) -{ - mp_input_add_thread_src(ictx, (void *)filename, read_pipe_thread); -} diff --git a/options/options.c b/options/options.c index 333f35911f..4621df9b7e 100644 --- a/options/options.c +++ b/options/options.c @@ -528,6 +528,7 @@ const m_option_t mp_opts[] = { OPT_FLAG("idle", player_idle_mode, M_OPT_GLOBAL), OPT_FLAG("input-terminal", consolecontrols, CONF_GLOBAL), + OPT_STRING("input-file", input_file, M_OPT_FILE | M_OPT_GLOBAL), OPT_STRING("input-unix-socket", ipc_path, M_OPT_FILE), OPT_SUBSTRUCT("screenshot", screenshot_image_opts, image_writer_conf, 0), diff --git a/options/options.h b/options/options.h index a34f3d6042..adbb70e420 100644 --- a/options/options.h +++ b/options/options.h @@ -286,6 +286,7 @@ typedef struct MPOpts { struct encode_opts *encode_opts; char *ipc_path; + char *input_file; } MPOpts; extern const m_option_t mp_opts[]; diff --git a/wscript_build.py b/wscript_build.py index a7d7e0171f..bf47d00dfa 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -191,7 +191,6 @@ def build(ctx): ( "input/input.c" ), ( "input/ipc.c", "!mingw" ), ( "input/keycodes.c" ), - ( "input/pipe-unix.c", "!mingw" ), ( "input/pipe-win32.c", "waio" ), ( "input/joystick.c", "joystick" ), ( "input/lirc.c", "lirc" ), -- cgit v1.2.3