diff options
Diffstat (limited to 'input')
-rw-r--r-- | input/cmd.c | 22 | ||||
-rw-r--r-- | input/cmd.h | 3 | ||||
-rw-r--r-- | input/event.c | 15 | ||||
-rw-r--r-- | input/event.h | 5 | ||||
-rw-r--r-- | input/input.c | 171 | ||||
-rw-r--r-- | input/input.h | 7 | ||||
-rw-r--r-- | input/ipc-unix.c | 30 | ||||
-rw-r--r-- | input/ipc-win.c | 32 | ||||
-rw-r--r-- | input/ipc.c | 4 | ||||
-rw-r--r-- | input/keycodes.c | 25 | ||||
-rw-r--r-- | input/keycodes.h | 13 | ||||
-rw-r--r-- | input/meson.build | 20 | ||||
-rw-r--r-- | input/sdl_gamepad.c | 14 |
13 files changed, 232 insertions, 129 deletions
diff --git a/input/cmd.c b/input/cmd.c index 3d3b7c6587..64232143f7 100644 --- a/input/cmd.c +++ b/input/cmd.c @@ -336,13 +336,23 @@ static int pctx_read_token(struct parse_ctx *ctx, bstr *out) return -1; } if (!bstr_eatstart0(&ctx->str, "\"")) { - MP_ERR(ctx, "Unterminated quotes: ...>%.*s<.\n", BSTR_P(start)); + MP_ERR(ctx, "Unterminated double quote: ...>%.*s<.\n", BSTR_P(start)); return -1; } return 1; } - if (ctx->start.len > 1 && bstr_eatstart0(&ctx->str, "!")) { - char endquote[2] = {ctx->str.start[0], '!'}; + if (bstr_eatstart0(&ctx->str, "'")) { + int next = bstrchr(ctx->str, '\''); + if (next < 0) { + MP_ERR(ctx, "Unterminated single quote: ...>%.*s<.\n", BSTR_P(start)); + return -1; + } + *out = bstr_splice(ctx->str, 0, next); + ctx->str = bstr_cut(ctx->str, next+1); + return 1; + } + if (ctx->start.len > 1 && bstr_eatstart0(&ctx->str, "`")) { + char endquote[2] = {ctx->str.start[0], '`'}; ctx->str = bstr_cut(ctx->str, 1); int next = bstr_find(ctx->str, (bstr){endquote, 2}); if (next < 0) { @@ -598,8 +608,10 @@ void mp_cmd_dump(struct mp_log *log, int msgl, char *header, struct mp_cmd *cmd) bool mp_input_is_repeatable_cmd(struct mp_cmd *cmd) { - return (cmd->def->allow_auto_repeat) || cmd->def == &mp_cmd_list || - (cmd->flags & MP_ALLOW_REPEAT); + if (cmd->def == &mp_cmd_list && cmd->args[0].v.p) + cmd = cmd->args[0].v.p; // list - only 1st cmd is considered + + return (cmd->def->allow_auto_repeat) || (cmd->flags & MP_ALLOW_REPEAT); } bool mp_input_is_scalable_cmd(struct mp_cmd *cmd) diff --git a/input/cmd.h b/input/cmd.h index 3ed07e8028..3d4b15fcc3 100644 --- a/input/cmd.h +++ b/input/cmd.h @@ -23,7 +23,7 @@ #include "misc/bstr.h" #include "options/m_option.h" -#define MP_CMD_DEF_MAX_ARGS 9 +#define MP_CMD_DEF_MAX_ARGS 11 #define MP_CMD_OPT_ARG M_OPT_OPTIONAL_PARAM struct mp_log; @@ -85,6 +85,7 @@ enum mp_cmd_flags { struct mp_cmd_arg { const struct m_option *type; union { + bool b; int i; int64_t i64; float f; diff --git a/input/event.c b/input/event.c index 266e0294e2..6c1e00409a 100644 --- a/input/event.c +++ b/input/event.c @@ -37,6 +37,21 @@ void mp_event_drop_files(struct input_ctx *ictx, int num_files, char **files, }; mp_input_run_cmd(ictx, cmd); } + } else if (action == DND_INSERT_NEXT) { + /* To insert the entries in the correct order, we iterate over them + backwards */ + for (int i = num_files - 1; i >= 0; i--) { + const char *cmd[] = { + "osd-auto", + "loadfile", + files[i], + /* Since we're inserting in reverse, wait til the final item + is added to start playing */ + (i > 0) ? "insert-next" : "insert-next-play", + NULL + }; + mp_input_run_cmd(ictx, cmd); + } } else { for (int i = 0; i < num_files; i++) { const char *cmd[] = { diff --git a/input/event.h b/input/event.h index 1e2149bb89..5f48bee00e 100644 --- a/input/event.h +++ b/input/event.h @@ -24,16 +24,17 @@ struct input_ctx; enum mp_dnd_action { DND_REPLACE, DND_APPEND, + DND_INSERT_NEXT, }; // Enqueue files for playback after drag and drop void mp_event_drop_files(struct input_ctx *ictx, int num_files, char **files, - enum mp_dnd_action append); + enum mp_dnd_action action); // Drop data in a specific format (identified by the mimetype). // Returns <0 on error, ==0 if data was ok but empty, >0 on success. int mp_event_drop_mime_data(struct input_ctx *ictx, const char *mime_type, - bstr data, enum mp_dnd_action append); + bstr data, enum mp_dnd_action action); // Many drag & drop APIs support multiple mime types, and this function returns // whether a type is preferred (higher integer score), or supported (scores diff --git a/input/input.c b/input/input.c index 40abd7d0fa..9fd2a16f0c 100644 --- a/input/input.c +++ b/input/input.c @@ -28,7 +28,6 @@ #include <sys/stat.h> #include <sys/time.h> #include <fcntl.h> -#include <pthread.h> #include <assert.h> #include "osdep/io.h" @@ -51,13 +50,13 @@ #include "common/common.h" #if HAVE_COCOA -#include "osdep/macosx_events.h" +#include "osdep/mac/app_bridge.h" #endif -#define input_lock(ictx) pthread_mutex_lock(&ictx->mutex) -#define input_unlock(ictx) pthread_mutex_unlock(&ictx->mutex) +#define input_lock(ictx) mp_mutex_lock(&ictx->mutex) +#define input_unlock(ictx) mp_mutex_unlock(&ictx->mutex) -#define MP_MAX_KEY_DOWN 4 +#define MP_MAX_KEY_DOWN 16 struct cmd_bind { int keys[MP_MAX_KEY_DOWN]; @@ -80,8 +79,6 @@ struct cmd_bind_section { #define MP_MAX_SOURCES 10 -#define MAX_ACTIVE_SECTIONS 50 - struct active_section { char *name; int flags; @@ -97,7 +94,7 @@ struct wheel_state { }; struct input_ctx { - pthread_mutex_t mutex; + mp_mutex mutex; struct mp_log *log; struct mpv_global *global; struct m_config_cache *opts_cache; @@ -143,7 +140,7 @@ struct input_ctx { int num_sections; // List currently active command sections - struct active_section active_sections[MAX_ACTIVE_SECTIONS]; + struct active_section *active_sections; int num_active_sections; unsigned int mouse_event_counter; @@ -171,15 +168,16 @@ struct input_opts { // Autorepeat config (be aware of mp_input_set_repeat_info()) int ar_delay; int ar_rate; - int use_alt_gr; - int use_appleremote; - int use_gamepad; - int use_media_keys; - int default_bindings; - int enable_mouse_movements; - int vo_key_input; - int test; - int allow_win_drag; + bool use_alt_gr; + bool use_gamepad; + bool use_media_keys; + bool default_bindings; + bool builtin_bindings; + bool enable_mouse_movements; + bool vo_key_input; + bool test; + bool allow_win_drag; + bool preprocess_wheel; }; const struct m_sub_options input_config = { @@ -189,23 +187,21 @@ const struct m_sub_options input_config = { {"input-ar-rate", OPT_INT(ar_rate)}, {"input-keylist", OPT_PRINT(mp_print_key_list)}, {"input-cmdlist", OPT_PRINT(mp_print_cmd_list)}, - {"input-default-bindings", OPT_FLAG(default_bindings)}, - {"input-test", OPT_FLAG(test)}, + {"input-default-bindings", OPT_BOOL(default_bindings)}, + {"input-builtin-bindings", OPT_BOOL(builtin_bindings)}, + {"input-test", OPT_BOOL(test)}, {"input-doubleclick-time", OPT_INT(doubleclick_time), M_RANGE(0, 1000)}, - {"input-right-alt-gr", OPT_FLAG(use_alt_gr)}, + {"input-right-alt-gr", OPT_BOOL(use_alt_gr)}, {"input-key-fifo-size", OPT_INT(key_fifo_size), M_RANGE(2, 65000)}, - {"input-cursor", OPT_FLAG(enable_mouse_movements)}, - {"input-vo-keyboard", OPT_FLAG(vo_key_input)}, - {"input-media-keys", OPT_FLAG(use_media_keys)}, + {"input-cursor", OPT_BOOL(enable_mouse_movements)}, + {"input-vo-keyboard", OPT_BOOL(vo_key_input)}, + {"input-media-keys", OPT_BOOL(use_media_keys)}, + {"input-preprocess-wheel", OPT_BOOL(preprocess_wheel)}, #if HAVE_SDL2_GAMEPAD - {"input-gamepad", OPT_FLAG(use_gamepad)}, -#endif - {"window-dragging", OPT_FLAG(allow_win_drag)}, - {"input-x11-keyboard", OPT_REPLACED("input-vo-keyboard")}, -#if HAVE_COCOA - {"input-appleremote", OPT_REMOVED("replaced by MediaPlayer support")}, + {"input-gamepad", OPT_BOOL(use_gamepad)}, #endif + {"window-dragging", OPT_BOOL(allow_win_drag)}, {0} }, .size = sizeof(struct input_opts), @@ -214,18 +210,20 @@ const struct m_sub_options input_config = { .doubleclick_time = 300, .ar_delay = 200, .ar_rate = 40, - .use_alt_gr = 1, - .enable_mouse_movements = 1, - .use_media_keys = 1, - .default_bindings = 1, - .vo_key_input = 1, - .allow_win_drag = 1, + .use_alt_gr = true, + .enable_mouse_movements = true, + .use_media_keys = true, + .default_bindings = true, + .builtin_bindings = true, + .vo_key_input = true, + .allow_win_drag = true, + .preprocess_wheel = true, }, .change_flags = UPDATE_INPUT, }; static const char builtin_input_conf[] = -#include "generated/etc/input.conf.inc" +#include "etc/input.conf.inc" ; static bool test_rect(struct mp_rect *rc, int x, int y) @@ -592,7 +590,7 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale, ictx->current_down_cmd = mp_cmd_clone(cmd); } ictx->last_key_down = code; - ictx->last_key_down_time = mp_time_us(); + ictx->last_key_down_time = mp_time_ns(); ictx->ar_state = 0; mp_input_wakeup(ictx); // possibly start timer for autorepeat } else if (state == MP_KEY_STATE_UP) { @@ -734,18 +732,23 @@ static void mp_input_feed_key(struct input_ctx *ictx, int code, double scale, if (!force_mouse && opts->doubleclick_time && MP_KEY_IS_MOUSE_BTN_DBL(unmod)) return; int units = 1; - if (MP_KEY_IS_WHEEL(unmod) && !process_wheel(ictx, unmod, &scale, &units)) + if (MP_KEY_IS_WHEEL(unmod) && opts->preprocess_wheel && !process_wheel(ictx, unmod, &scale, &units)) return; interpret_key(ictx, code, scale, units); if (code & MP_KEY_STATE_DOWN) { code &= ~MP_KEY_STATE_DOWN; if (ictx->last_doubleclick_key_down == code && - now - ictx->last_doubleclick_time < opts->doubleclick_time / 1000.0) + now - ictx->last_doubleclick_time < opts->doubleclick_time / 1000.0 && + code >= MP_MBTN_LEFT && code <= MP_MBTN_RIGHT) { - if (code >= MP_MBTN_LEFT && code <= MP_MBTN_RIGHT) { - interpret_key(ictx, code - MP_MBTN_BASE + MP_MBTN_DBL_BASE, - 1, 1); - } + now = 0; + interpret_key(ictx, code - MP_MBTN_BASE + MP_MBTN_DBL_BASE, + 1, 1); + } else if (code == MP_MBTN_LEFT) { + // This is a mouse left botton down event which isn't part of a doubleclick. + // Initialize vo dragging in this case. + mp_cmd_t *cmd = mp_input_parse_cmd(ictx, bstr0("begin-vo-dragging"), "<internal>"); + mp_input_queue_cmd(ictx, cmd); } ictx->last_doubleclick_key_down = code; ictx->last_doubleclick_time = now; @@ -759,10 +762,12 @@ void mp_input_put_key(struct input_ctx *ictx, int code) input_unlock(ictx); } -void mp_input_put_key_artificial(struct input_ctx *ictx, int code) +void mp_input_put_key_artificial(struct input_ctx *ictx, int code, double value) { + if (value == 0.0) + return; input_lock(ictx); - mp_input_feed_key(ictx, code, 1, true); + mp_input_feed_key(ictx, code, value, true); input_unlock(ictx); } @@ -917,19 +922,19 @@ static mp_cmd_t *check_autorepeat(struct input_ctx *ictx) ictx->ar_state = -1; // disable if (ictx->ar_state >= 0) { - int64_t t = mp_time_us(); - if (ictx->last_ar + 2000000 < t) + int64_t t = mp_time_ns(); + if (ictx->last_ar + MP_TIME_S_TO_NS(2) < t) ictx->last_ar = t; // First time : wait delay if (ictx->ar_state == 0 - && (t - ictx->last_key_down_time) >= opts->ar_delay * 1000) + && (t - ictx->last_key_down_time) >= MP_TIME_MS_TO_NS(opts->ar_delay)) { ictx->ar_state = 1; - ictx->last_ar = ictx->last_key_down_time + opts->ar_delay * 1000; + ictx->last_ar = ictx->last_key_down_time + MP_TIME_MS_TO_NS(opts->ar_delay); // Then send rate / sec event } else if (ictx->ar_state == 1 - && (t - ictx->last_ar) >= 1000000 / opts->ar_rate) { - ictx->last_ar += 1000000 / opts->ar_rate; + && (t - ictx->last_ar) >= 1e9 / opts->ar_rate) { + ictx->last_ar += 1e9 / opts->ar_rate; } else { return NULL; } @@ -1010,20 +1015,16 @@ void mp_input_enable_section(struct input_ctx *ictx, char *name, int flags) MP_TRACE(ictx, "enable section '%s'\n", name); - if (ictx->num_active_sections < MAX_ACTIVE_SECTIONS) { - int top = ictx->num_active_sections; - if (!(flags & MP_INPUT_ON_TOP)) { - // insert before the first top entry - for (top = 0; top < ictx->num_active_sections; top++) { - if (ictx->active_sections[top].flags & MP_INPUT_ON_TOP) - break; - } - for (int n = ictx->num_active_sections; n > top; n--) - ictx->active_sections[n] = ictx->active_sections[n - 1]; + int top = ictx->num_active_sections; + if (!(flags & MP_INPUT_ON_TOP)) { + // insert before the first top entry + for (top = 0; top < ictx->num_active_sections; top++) { + if (ictx->active_sections[top].flags & MP_INPUT_ON_TOP) + break; } - ictx->active_sections[top] = (struct active_section){name, flags}; - ictx->num_active_sections++; } + MP_TARRAY_INSERT_AT(ictx, ictx->active_sections, ictx->num_active_sections, + top, (struct active_section){name, flags}); MP_TRACE(ictx, "active section stack:\n"); for (int n = 0; n < ictx->num_active_sections; n++) { @@ -1276,9 +1277,9 @@ static int parse_config(struct input_ctx *ictx, bool builtin, bstr data, return n_binds; } -static int parse_config_file(struct input_ctx *ictx, char *file, bool warn) +static bool parse_config_file(struct input_ctx *ictx, char *file) { - int r = 0; + bool r = false; void *tmp = talloc_new(NULL); stream_t *s = NULL; @@ -1295,7 +1296,7 @@ static int parse_config_file(struct input_ctx *ictx, char *file, bool warn) MP_VERBOSE(ictx, "Parsing input config file %s\n", file); int num = parse_config(ictx, false, data, file, NULL); MP_VERBOSE(ictx, "Input config file %s parsed: %d binds\n", file, num); - r = 1; + r = true; } else { MP_ERR(ictx, "Error reading input config file %s\n", file); } @@ -1320,11 +1321,12 @@ struct input_ctx *mp_input_init(struct mpv_global *global, .opts_cache = m_config_cache_alloc(ictx, global, &input_config), .wakeup_cb = wakeup_cb, .wakeup_ctx = wakeup_ctx, + .active_sections = talloc_array(ictx, struct active_section, 0), }; ictx->opts = ictx->opts_cache->opts; - mpthread_mutex_init_recursive(&ictx->mutex); + mp_mutex_init_type(&ictx->mutex, MP_MUTEX_RECURSIVE); // Setup default section, so that it does nothing. mp_input_enable_section(ictx, NULL, MP_INPUT_ALLOW_VO_DRAGGING | @@ -1367,7 +1369,7 @@ void mp_input_load_config(struct input_ctx *ictx) // "Uncomment" the default key bindings in etc/input.conf and add them. // All lines that do not start with '# ' are parsed. bstr builtin = bstr0(builtin_input_conf); - while (builtin.len) { + while (ictx->opts->builtin_bindings && builtin.len) { bstr line = bstr_getline(builtin, &builtin); bstr_eatstart0(&line, "#"); if (!bstr_startswith0(line, " ")) @@ -1376,13 +1378,13 @@ void mp_input_load_config(struct input_ctx *ictx) bool config_ok = false; if (ictx->opts->config_file && ictx->opts->config_file[0]) - config_ok = parse_config_file(ictx, ictx->opts->config_file, true); + config_ok = parse_config_file(ictx, ictx->opts->config_file); if (!config_ok) { // Try global conf dir void *tmp = talloc_new(NULL); char **files = mp_find_all_config_files(tmp, ictx->global, "input.conf"); for (int n = 0; files && files[n]; n++) - parse_config_file(ictx, files[n], false); + parse_config_file(ictx, files[n]); talloc_free(tmp); } @@ -1395,6 +1397,14 @@ void mp_input_load_config(struct input_ctx *ictx) input_unlock(ictx); } +bool mp_input_load_config_file(struct input_ctx *ictx, char *file) +{ + input_lock(ictx); + bool result = parse_config_file(ictx, file); + input_unlock(ictx); + return result; +} + static void clear_queue(struct cmd_queue *queue) { while (queue->first) { @@ -1416,7 +1426,7 @@ void mp_input_uninit(struct input_ctx *ictx) close_input_sources(ictx); clear_queue(&ictx->cmd_queue); talloc_free(ictx->current_down_cmd); - pthread_mutex_destroy(&ictx->mutex); + mp_mutex_destroy(&ictx->mutex); talloc_free(ictx); } @@ -1536,7 +1546,7 @@ struct mpv_node mp_input_get_bindings(struct input_ctx *ictx) } struct mp_input_src_internal { - pthread_t thread; + mp_thread thread; bool thread_running; bool init_done; @@ -1598,33 +1608,33 @@ static void mp_input_src_kill(struct mp_input_src *src) if (src->cancel) src->cancel(src); if (src->in->thread_running) - pthread_join(src->in->thread, NULL); + mp_thread_join(src->in->thread); if (src->uninit) src->uninit(src); talloc_free(src); return; } } - abort(); + MP_ASSERT_UNREACHABLE(); } void mp_input_src_init_done(struct mp_input_src *src) { assert(!src->in->init_done); assert(src->in->thread_running); - assert(pthread_equal(src->in->thread, pthread_self())); + assert(mp_thread_id_equal(mp_thread_get_id(src->in->thread), mp_thread_current_id())); src->in->init_done = true; mp_rendezvous(&src->in->init_done, 0); } -static void *input_src_thread(void *ptr) +static MP_THREAD_VOID input_src_thread(void *ptr) { void **args = ptr; struct mp_input_src *src = args[0]; void (*loop_fn)(struct mp_input_src *src, void *ctx) = args[1]; void *ctx = args[2]; - mpthread_set_name("input source"); + mp_thread_set_name("input"); src->in->thread_running = true; @@ -1633,7 +1643,7 @@ static void *input_src_thread(void *ptr) if (!src->in->init_done) mp_rendezvous(&src->in->init_done, -1); - return NULL; + MP_THREAD_RETURN(); } int mp_input_add_thread_src(struct input_ctx *ictx, void *ctx, @@ -1644,7 +1654,7 @@ int mp_input_add_thread_src(struct input_ctx *ictx, void *ctx, return -1; void *args[] = {src, loop_fn, ctx}; - if (pthread_create(&src->in->thread, NULL, input_src_thread, args)) { + if (mp_thread_create(&src->in->thread, input_src_thread, args)) { mp_input_src_kill(src); return -1; } @@ -1696,4 +1706,3 @@ void mp_input_set_repeat_info(struct input_ctx *ictx, int rate, int delay) ictx->opts->ar_delay = delay; input_unlock(ictx); } - diff --git a/input/input.h b/input/input.h index 5b5e7a99ce..7f6707eeca 100644 --- a/input/input.h +++ b/input/input.h @@ -83,7 +83,8 @@ void mp_input_src_feed_cmd_text(struct mp_input_src *src, char *buf, size_t len) void mp_input_put_key(struct input_ctx *ictx, int code); // Like mp_input_put_key(), but ignore mouse disable option for mouse buttons. -void mp_input_put_key_artificial(struct input_ctx *ictx, int code); +// value can be used like with mp_input_put_wheel(), use 1 if not applicable. +void mp_input_put_key_artificial(struct input_ctx *ictx, int code, double value); // Like mp_input_put_key(), but process all UTF-8 characters in the given // string as key events. @@ -177,8 +178,12 @@ struct input_ctx *mp_input_init(struct mpv_global *global, void (*wakeup_cb)(void *ctx), void *wakeup_ctx); +// Load the configured input.conf files. void mp_input_load_config(struct input_ctx *ictx); +// Load a specific input.conf file. +bool mp_input_load_config_file(struct input_ctx *ictx, char *file); + void mp_input_update_opts(struct input_ctx *ictx); void mp_input_uninit(struct input_ctx *ictx); diff --git a/input/ipc-unix.c b/input/ipc-unix.c index cd788e0061..a416b54e1e 100644 --- a/input/ipc-unix.c +++ b/input/ipc-unix.c @@ -15,7 +15,6 @@ * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ -#include <pthread.h> #include <errno.h> #include <unistd.h> #include <limits.h> @@ -26,8 +25,6 @@ #include <sys/stat.h> #include <sys/un.h> -#include "config.h" - #include "osdep/io.h" #include "osdep/threads.h" @@ -50,7 +47,7 @@ struct mp_ipc_ctx { struct mp_client_api *client_api; const char *path; - pthread_t thread; + mp_thread thread; int death_pipe[2]; }; @@ -93,10 +90,8 @@ static int ipc_write_str(struct client_arg *client, const char *buf) return 0; } -static void *client_thread(void *p) +static MP_THREAD_VOID client_thread(void *p) { - pthread_detach(pthread_self()); - // We don't use MSG_NOSIGNAL because the moldy fruit OS doesn't support it. struct sigaction sa = { .sa_handler = SIG_IGN, .sa_flags = SA_RESTART }; sigfillset(&sa.sa_mask); @@ -107,7 +102,9 @@ static void *client_thread(void *p) struct client_arg *arg = p; bstr client_msg = { talloc_strdup(NULL, ""), 0 }; - mpthread_set_name(arg->client_name); + char *tname = talloc_asprintf(NULL, "ipc/%s", arg->client_name); + mp_thread_set_name(tname); + talloc_free(tname); int pipe_fd = mpv_get_wakeup_pipe(arg->client); if (pipe_fd < 0) { @@ -219,7 +216,7 @@ done: } else { mpv_destroy(h); } - return NULL; + MP_THREAD_RETURN(); } static bool ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client, @@ -232,9 +229,10 @@ static bool ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client, client->log = mp_client_get_log(client->client); - pthread_t client_thr; - if (pthread_create(&client_thr, NULL, client_thread, client)) + mp_thread client_thr; + if (mp_thread_create(&client_thr, client_thread, client)) goto err; + mp_thread_detach(client_thr); return true; @@ -295,7 +293,7 @@ bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h, return true; } -static void *ipc_thread(void *p) +static MP_THREAD_VOID ipc_thread(void *p) { int rc; @@ -304,7 +302,7 @@ static void *ipc_thread(void *p) struct mp_ipc_ctx *arg = p; - mpthread_set_name("ipc socket listener"); + mp_thread_set_name("ipc/socket"); MP_VERBOSE(arg, "Starting IPC master\n"); @@ -379,7 +377,7 @@ done: if (ipc_fd >= 0) close(ipc_fd); - return NULL; + MP_THREAD_RETURN(); } struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api, @@ -418,7 +416,7 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api, if (mp_make_wakeup_pipe(arg->death_pipe) < 0) goto out; - if (pthread_create(&arg->thread, NULL, ipc_thread, arg)) + if (mp_thread_create(&arg->thread, ipc_thread, arg)) goto out; return arg; @@ -438,7 +436,7 @@ void mp_uninit_ipc(struct mp_ipc_ctx *arg) return; (void)write(arg->death_pipe[1], &(char){0}, 1); - pthread_join(arg->thread, NULL); + mp_thread_join(arg->thread); close(arg->death_pipe[0]); close(arg->death_pipe[1]); diff --git a/input/ipc-win.c b/input/ipc-win.c index 9672ec85fe..b0200eafc3 100644 --- a/input/ipc-win.c +++ b/input/ipc-win.c @@ -18,8 +18,6 @@ #include <windows.h> #include <sddl.h> -#include "config.h" - #include "osdep/io.h" #include "osdep/threads.h" #include "osdep/windows_utils.h" @@ -38,7 +36,7 @@ struct mp_ipc_ctx { struct mp_client_api *client_api; const wchar_t *path; - pthread_t thread; + mp_thread thread; HANDLE death_event; }; @@ -200,10 +198,8 @@ static void report_read_error(struct client_arg *arg, DWORD error) } } -static void *client_thread(void *p) +static MP_THREAD_VOID client_thread(void *p) { - pthread_detach(pthread_self()); - struct client_arg *arg = p; char buf[4096]; HANDLE wakeup_event = CreateEventW(NULL, TRUE, FALSE, NULL); @@ -212,7 +208,9 @@ static void *client_thread(void *p) DWORD ioerr = 0; DWORD r; - mpthread_set_name(arg->client_name); + char *tname = talloc_asprintf(NULL, "ipc/%s", arg->client_name); + mp_thread_set_name(tname); + talloc_free(tname); arg->write_ol.hEvent = CreateEventW(NULL, TRUE, TRUE, NULL); if (!wakeup_event || !ol.hEvent || !arg->write_ol.hEvent) { @@ -307,7 +305,7 @@ done: CloseHandle(arg->client_h); mpv_destroy(arg->client); talloc_free(arg); - return NULL; + MP_THREAD_RETURN(); } static void ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client) @@ -315,12 +313,13 @@ static void ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client) client->client = mp_new_client(ctx->client_api, client->client_name), client->log = mp_client_get_log(client->client); - pthread_t client_thr; - if (pthread_create(&client_thr, NULL, client_thread, client)) { + mp_thread client_thr; + if (mp_thread_create(&client_thr, client_thread, client)) { mpv_destroy(client->client); CloseHandle(client->client_h); talloc_free(client); } + mp_thread_detach(client_thr); } static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, HANDLE h) @@ -341,7 +340,7 @@ bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h, return false; } -static void *ipc_thread(void *p) +static MP_THREAD_VOID ipc_thread(void *p) { // Use PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE so message framing is // maintained for message-mode clients, but byte-mode clients can still @@ -358,9 +357,10 @@ static void *ipc_thread(void *p) HANDLE client = INVALID_HANDLE_VALUE; int client_num = 0; - mpthread_set_name("ipc named pipe listener"); + mp_thread_set_name("ipc/named-pipe"); MP_VERBOSE(arg, "Starting IPC master\n"); + OVERLAPPED ol = {0}; SECURITY_ATTRIBUTES sa = { .nLength = sizeof sa, .lpSecurityDescriptor = create_restricted_sd(), @@ -370,7 +370,7 @@ static void *ipc_thread(void *p) goto done; } - OVERLAPPED ol = { .hEvent = CreateEventW(NULL, TRUE, TRUE, NULL) }; + ol = (OVERLAPPED){ .hEvent = CreateEventW(NULL, TRUE, TRUE, NULL) }; if (!ol.hEvent) { MP_ERR(arg, "Couldn't create event"); goto done; @@ -450,7 +450,7 @@ done: CloseHandle(server); if (ol.hEvent) CloseHandle(ol.hEvent); - return NULL; + MP_THREAD_RETURN(); } struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api, @@ -482,7 +482,7 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api, if (!(arg->death_event = CreateEventW(NULL, TRUE, FALSE, NULL))) goto out; - if (pthread_create(&arg->thread, NULL, ipc_thread, arg)) + if (mp_thread_create(&arg->thread, ipc_thread, arg)) goto out; talloc_free(opts); @@ -502,7 +502,7 @@ void mp_uninit_ipc(struct mp_ipc_ctx *arg) return; SetEvent(arg->death_event); - pthread_join(arg->thread, NULL); + mp_thread_join(arg->thread); CloseHandle(arg->death_event); talloc_free(arg); diff --git a/input/ipc.c b/input/ipc.c index 34a10bbb00..ea69fb7c24 100644 --- a/input/ipc.c +++ b/input/ipc.c @@ -15,8 +15,6 @@ * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ -#include "config.h" - #include "common/msg.h" #include "input/input.h" #include "misc/json.h" @@ -128,7 +126,7 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent, bool async = false; bool send_reply = true; - rc = json_parse(ta_parent, &msg_node, &src, 50); + rc = json_parse(ta_parent, &msg_node, &src, MAX_JSON_DEPTH); if (rc < 0) { mp_err(log, "malformed JSON received: '%s'\n", src); rc = MPV_ERROR_INVALID_PARAMETER; diff --git a/input/keycodes.c b/input/keycodes.c index 312ffc4893..c412191573 100644 --- a/input/keycodes.c +++ b/input/keycodes.c @@ -64,6 +64,18 @@ static const struct key_name key_names[] = { { MP_KEY_F+10, "F10" }, { MP_KEY_F+11, "F11" }, { MP_KEY_F+12, "F12" }, + { MP_KEY_F+13, "F13" }, + { MP_KEY_F+14, "F14" }, + { MP_KEY_F+15, "F15" }, + { MP_KEY_F+16, "F16" }, + { MP_KEY_F+17, "F17" }, + { MP_KEY_F+18, "F18" }, + { MP_KEY_F+19, "F19" }, + { MP_KEY_F+20, "F20" }, + { MP_KEY_F+21, "F21" }, + { MP_KEY_F+22, "F22" }, + { MP_KEY_F+23, "F23" }, + { MP_KEY_F+24, "F24" }, { MP_KEY_KP0, "KP0" }, { MP_KEY_KP1, "KP1" }, { MP_KEY_KP2, "KP2" }, @@ -77,6 +89,14 @@ static const struct key_name key_names[] = { { MP_KEY_KPDEL, "KP_DEL" }, { MP_KEY_KPDEC, "KP_DEC" }, { MP_KEY_KPINS, "KP_INS" }, + { MP_KEY_KPHOME, "KP_HOME" }, + { MP_KEY_KPEND, "KP_END" }, + { MP_KEY_KPPGUP, "KP_PGUP" }, + { MP_KEY_KPPGDOWN, "KP_PGDWN" }, + { MP_KEY_KPRIGHT, "KP_RIGHT" }, + { MP_KEY_KPLEFT, "KP_LEFT" }, + { MP_KEY_KPDOWN, "KP_DOWN" }, + { MP_KEY_KPUP, "KP_UP" }, { MP_KEY_KPENTER, "KP_ENTER" }, { MP_MBTN_LEFT, "MBTN_LEFT" }, { MP_MBTN_MID, "MBTN_MID" }, @@ -153,6 +173,11 @@ static const struct key_name key_names[] = { { MP_KEY_CHANNEL_DOWN,"CHANNEL_DOWN" }, { MP_KEY_PLAYONLY, "PLAYONLY" }, { MP_KEY_PAUSEONLY, "PAUSEONLY" }, + { MP_KEY_GO_BACK, "GO_BACK" }, + { MP_KEY_GO_FORWARD, "GO_FORWARD" }, + { MP_KEY_TOOLS, "TOOLS" }, + { MP_KEY_ZOOMIN, "ZOOMIN" }, + { MP_KEY_ZOOMOUT, "ZOOMOUT" }, // These are kept for backward compatibility { MP_KEY_PAUSE, "XF86_PAUSE" }, diff --git a/input/keycodes.h b/input/keycodes.h index 6373a6e21a..1a21a3c89f 100644 --- a/input/keycodes.h +++ b/input/keycodes.h @@ -82,6 +82,11 @@ #define MP_KEY_CHANNEL_DOWN (MP_KEY_MM_BASE+22) #define MP_KEY_PLAYONLY (MP_KEY_MM_BASE+23) #define MP_KEY_PAUSEONLY (MP_KEY_MM_BASE+24) +#define MP_KEY_GO_BACK (MP_KEY_MM_BASE+25) +#define MP_KEY_GO_FORWARD (MP_KEY_MM_BASE+26) +#define MP_KEY_TOOLS (MP_KEY_MM_BASE+27) +#define MP_KEY_ZOOMIN (MP_KEY_MM_BASE+28) +#define MP_KEY_ZOOMOUT (MP_KEY_MM_BASE+29) /* Function keys */ #define MP_KEY_F (MP_KEY_BASE+0x40) @@ -102,6 +107,14 @@ #define MP_KEY_KPINS (MP_KEY_KEYPAD+11) #define MP_KEY_KPDEL (MP_KEY_KEYPAD+12) #define MP_KEY_KPENTER (MP_KEY_KEYPAD+13) +#define MP_KEY_KPHOME (MP_KEY_KEYPAD+14) +#define MP_KEY_KPEND (MP_KEY_KEYPAD+15) +#define MP_KEY_KPPGUP (MP_KEY_KEYPAD+16) +#define MP_KEY_KPPGDOWN (MP_KEY_KEYPAD+17) +#define MP_KEY_KPRIGHT (MP_KEY_KEYPAD+18) +#define MP_KEY_KPLEFT (MP_KEY_KEYPAD+19) +#define MP_KEY_KPDOWN (MP_KEY_KEYPAD+20) +#define MP_KEY_KPUP (MP_KEY_KEYPAD+21) // Mouse events from VOs #define MP_MBTN_BASE ((MP_KEY_BASE+0xA0)|MP_NO_REPEAT_KEY|MP_KEY_EMIT_ON_UP) diff --git a/input/meson.build b/input/meson.build new file mode 100644 index 0000000000..12fe732b43 --- /dev/null +++ b/input/meson.build @@ -0,0 +1,20 @@ +icons = ['16', '32', '64', '128'] +foreach size: icons + name = 'mpv-icon-8bit-'+size+'x'+size+'.png' + icon = custom_target(name, + input: join_paths(source_root, 'etc', name), + output: name + '.inc', + command: [file2string, '@INPUT@', '@OUTPUT@'], + ) + sources += icon +endforeach + +etc_files = ['input.conf', 'builtin.conf'] |