diff options
Diffstat (limited to 'input/input.c')
-rw-r--r-- | input/input.c | 358 |
1 files changed, 201 insertions, 157 deletions
diff --git a/input/input.c b/input/input.c index 40abd7d0fa..b24e82fe50 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) @@ -277,6 +275,14 @@ static struct mp_cmd *queue_peek_tail(struct cmd_queue *queue) return cur; } +static void queue_cmd(struct input_ctx *ictx, mp_cmd_t *cmd) +{ + if (!cmd) + return; + queue_add_tail(&ictx->cmd_queue, cmd); + mp_input_wakeup(ictx); +} + static void append_bind_info(struct input_ctx *ictx, char **pmsg, struct cmd_bind *bind) { @@ -510,7 +516,7 @@ static void update_mouse_section(struct input_ctx *ictx) if (strcmp(old, ictx->mouse_section) != 0) { MP_TRACE(ictx, "input: switch section %s -> %s\n", old, ictx->mouse_section); - mp_input_queue_cmd(ictx, get_cmd_from_keys(ictx, old, MP_KEY_MOUSE_LEAVE)); + queue_cmd(ictx, get_cmd_from_keys(ictx, old, MP_KEY_MOUSE_LEAVE)); } } @@ -528,7 +534,7 @@ static void release_down_cmd(struct input_ctx *ictx, bool drop_current) { memset(ictx->key_history, 0, sizeof(ictx->key_history)); ictx->current_down_cmd->is_up = true; - mp_input_queue_cmd(ictx, ictx->current_down_cmd); + queue_cmd(ictx, ictx->current_down_cmd); } else { talloc_free(ictx->current_down_cmd); } @@ -592,7 +598,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) { @@ -624,7 +630,7 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale, if (mp_input_is_scalable_cmd(cmd)) { cmd->scale = scale; cmd->scale_units = scale_units; - mp_input_queue_cmd(ictx, cmd); + queue_cmd(ictx, cmd); } else { // Non-scalable commands won't understand cmd->scale, so synthesize // multiple commands with cmd->scale = 1 @@ -633,9 +639,9 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale, // Avoid spamming the player with too many commands scale_units = MPMIN(scale_units, 20); for (int i = 0; i < scale_units - 1; i++) - mp_input_queue_cmd(ictx, mp_cmd_clone(cmd)); + queue_cmd(ictx, mp_cmd_clone(cmd)); if (scale_units) - mp_input_queue_cmd(ictx, cmd); + queue_cmd(ictx, cmd); } } @@ -705,7 +711,7 @@ static bool process_wheel(struct input_ctx *ictx, int code, double *scale, return true; } -static void mp_input_feed_key(struct input_ctx *ictx, int code, double scale, +static void feed_key(struct input_ctx *ictx, int code, double scale, bool force_mouse) { struct input_opts *opts = ictx->opts; @@ -726,7 +732,7 @@ static void mp_input_feed_key(struct input_ctx *ictx, int code, double scale, mp_cmd_t *cmd = get_cmd_from_keys(ictx, NULL, code); if (!cmd) // queue dummy cmd so that mouse-pos can notify observers cmd = mp_input_parse_cmd(ictx, bstr0("ignore"), "<internal>"); - mp_input_queue_cmd(ictx, cmd); + queue_cmd(ictx, cmd); return; } double now = mp_time_sec(); @@ -734,18 +740,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>"); + queue_cmd(ictx, cmd); } ictx->last_doubleclick_key_down = code; ictx->last_doubleclick_time = now; @@ -755,25 +766,31 @@ static void mp_input_feed_key(struct input_ctx *ictx, int code, double scale, void mp_input_put_key(struct input_ctx *ictx, int code) { input_lock(ictx); - mp_input_feed_key(ictx, code, 1, false); + feed_key(ictx, code, 1, false); 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); + feed_key(ictx, code, value, true); input_unlock(ictx); } void mp_input_put_key_utf8(struct input_ctx *ictx, int mods, struct bstr t) { + if (!t.len) + return; + input_lock(ictx); while (t.len) { int code = bstr_decode_utf8(t, &t); if (code < 0) break; - mp_input_put_key(ictx, code | mods); + feed_key(ictx, code | mods, 1, false); } + input_unlock(ictx); } void mp_input_put_wheel(struct input_ctx *ictx, int direction, double value) @@ -781,7 +798,7 @@ void mp_input_put_wheel(struct input_ctx *ictx, int direction, double value) if (value == 0.0) return; input_lock(ictx); - mp_input_feed_key(ictx, direction, value, false); + feed_key(ictx, direction, value, false); input_unlock(ictx); } @@ -815,21 +832,11 @@ bool mp_input_vo_keyboard_enabled(struct input_ctx *ictx) return r; } -void mp_input_set_mouse_pos(struct input_ctx *ictx, int x, int y) +static void set_mouse_pos(struct input_ctx *ictx, int x, int y) { - input_lock(ictx); - if (ictx->opts->enable_mouse_movements) - mp_input_set_mouse_pos_artificial(ictx, x, y); - input_unlock(ictx); -} - -void mp_input_set_mouse_pos_artificial(struct input_ctx *ictx, int x, int y) -{ - input_lock(ictx); MP_TRACE(ictx, "mouse move %d/%d\n", x, y); if (ictx->mouse_vo_x == x && ictx->mouse_vo_y == y) { - input_unlock(ictx); return; } @@ -867,10 +874,62 @@ void mp_input_set_mouse_pos_artificial(struct input_ctx *ictx, int x, int y) queue_remove(&ictx->cmd_queue, tail); talloc_free(tail); } - mp_input_queue_cmd(ictx, cmd); + queue_cmd(ictx, cmd); } } +} + +void mp_input_set_mouse_pos_artificial(struct input_ctx *ictx, int x, int y) +{ + input_lock(ictx); + set_mouse_pos(ictx, x, y); + input_unlock(ictx); +} + +void mp_input_set_mouse_pos(struct input_ctx *ictx, int x, int y) +{ + input_lock(ictx); + if (ictx->opts->enable_mouse_movements) + set_mouse_pos(ictx, x, y); + input_unlock(ictx); +} + +static bool test_mouse(struct input_ctx *ictx, int x, int y, int rej_flags) +{ + bool res = false; + for (int i = 0; i < ictx->num_active_sections; i++) { + struct active_section *as = &ictx->active_sections[i]; + if (as->flags & rej_flags) + continue; + struct cmd_bind_section *s = get_bind_section(ictx, bstr0(as->name)); + if (s->mouse_area_set && test_rect(&s->mouse_area, x, y)) { + res = true; + break; + } + } + return res; +} + +static bool test_mouse_active(struct input_ctx *ictx, int x, int y) +{ + return test_mouse(ictx, x, y, MP_INPUT_ALLOW_HIDE_CURSOR); +} + +bool mp_input_test_mouse_active(struct input_ctx *ictx, int x, int y) +{ + input_lock(ictx); + bool res = test_mouse_active(ictx, x, y); + input_unlock(ictx); + return res; +} + +bool mp_input_test_dragging(struct input_ctx *ictx, int x, int y) +{ + input_lock(ictx); + bool r = !ictx->opts->allow_win_drag || + test_mouse(ictx, x, y, MP_INPUT_ALLOW_VO_DRAGGING); input_unlock(ictx); + return r; } unsigned int mp_input_get_mouse_event_counter(struct input_ctx *ictx) @@ -878,7 +937,7 @@ unsigned int mp_input_get_mouse_event_counter(struct input_ctx *ictx) // Make the frontend always display the mouse cursor (as long as it's not // forced invisible) if mouse input is desired. input_lock(ictx); - if (mp_input_test_mouse_active(ictx, ictx->mouse_x, ictx->mouse_y)) + if (test_mouse_active(ictx, ictx->mouse_x, ictx->mouse_y)) ictx->mouse_event_counter++; int ret = ictx->mouse_event_counter; input_unlock(ictx); @@ -897,11 +956,10 @@ static void adjust_max_wait_time(struct input_ctx *ictx, double *time) int mp_input_queue_cmd(struct input_ctx *ictx, mp_cmd_t *cmd) { + if (!cmd) + return 0; input_lock(ictx); - if (cmd) { - queue_add_tail(&ictx->cmd_queue, cmd); - mp_input_wakeup(ictx); - } + queue_cmd(ictx, cmd); input_unlock(ictx); return 1; } @@ -917,19 +975,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; } @@ -985,9 +1043,8 @@ static char *normalize_section(struct input_ctx *ictx, char *name) return get_bind_section(ictx, bstr0(name))->section; } -void mp_input_disable_section(struct input_ctx *ictx, char *name) +static void disable_section(struct input_ctx *ictx, char *name) { - input_lock(ictx); name = normalize_section(ictx, name); // Remove old section, or make sure it's on top if re-enabled @@ -998,6 +1055,12 @@ void mp_input_disable_section(struct input_ctx *ictx, char *name) ictx->num_active_sections, i); } } +} + +void mp_input_disable_section(struct input_ctx *ictx, char *name) +{ + input_lock(ictx); + disable_section(ictx, name); input_unlock(ictx); } @@ -1006,24 +1069,20 @@ void mp_input_enable_section(struct input_ctx *ictx, char *name, int flags) input_lock(ictx); name = normalize_section(ictx, name); - mp_input_disable_section(ictx, name); + disable_section(ictx, name); 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++) { @@ -1051,38 +1110,6 @@ void mp_input_set_section_mouse_area(struct input_ctx *ictx, char *name, input_unlock(ictx); } -static bool test_mouse(struct input_ctx *ictx, int x, int y, int rej_flags) -{ - input_lock(ictx); - bool res = false; - for (int i = 0; i < ictx->num_active_sections; i++) { - struct active_section *as = &ictx->active_sections[i]; - if (as->flags & rej_flags) - continue; - struct cmd_bind_section *s = get_bind_section(ictx, bstr0(as->name)); - if (s->mouse_area_set && test_rect(&s->mouse_area, x, y)) { - res = true; - break; - } - } - input_unlock(ictx); - return res; -} - -bool mp_input_test_mouse_active(struct input_ctx *ictx, int x, int y) -{ - return test_mouse(ictx, x, y, MP_INPUT_ALLOW_HIDE_CURSOR); -} - -bool mp_input_test_dragging(struct input_ctx *ictx, int x, int y) -{ - input_lock(ictx); - bool r = !ictx->opts->allow_win_drag || - test_mouse(ictx, x, y, MP_INPUT_ALLOW_VO_DRAGGING); - input_unlock(ictx); - return r; -} - static void bind_dealloc(struct cmd_bind *bind) { talloc_free(bind->cmd); @@ -1123,7 +1150,7 @@ void mp_input_define_section(struct input_ctx *ictx, char *name, char *location, parse_config(ictx, builtin, bstr0(contents), location, name); } else { // Disable: - mp_input_disable_section(ictx, name); + disable_section(ictx, name); } input_unlock(ictx); } @@ -1134,7 +1161,7 @@ void mp_input_remove_sections_by_owner(struct input_ctx *ictx, char *owner) for (int n = 0; n < ictx->num_sections; n++) { struct cmd_bind_section *bs = ictx->sections[n]; if (bs->owner && owner && strcmp(bs->owner, owner) == 0) { - mp_input_disable_section(ictx, bs->section); + disable_section(ictx, bs->section); remove_binds(bs, false); remove_binds(bs, true); } @@ -1276,9 +1303,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 +1322,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 +1347,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(&ictx->mutex); // Setup default section, so that it does nothing. mp_input_enable_section(ictx, NULL, MP_INPUT_ALLOW_VO_DRAGGING | @@ -1367,7 +1395,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,23 +1404,33 @@ 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); } + bool use_gamepad = ictx->opts->use_gamepad; + input_unlock(ictx); + #if HAVE_SDL2_GAMEPAD - if (ictx->opts->use_gamepad) { + if (use_gamepad) mp_input_sdl_gamepad_add(ictx); - } +#else + (void)use_gamepad; #endif +} +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) @@ -1416,7 +1454,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); } @@ -1444,11 +1482,14 @@ struct mp_cmd *mp_input_parse_cmd(struct input_ctx *ictx, bstr str, void mp_input_run_cmd(struct input_ctx *ictx, const char **cmd) { - mp_input_queue_cmd(ictx, mp_input_parse_cmd_strv(ictx->log, cmd)); + input_lock(ictx); + queue_cmd(ictx, mp_input_parse_cmd_strv(ictx->log, cmd)); + input_unlock(ictx); } void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command) { + input_lock(ictx); struct cmd_bind_section *bs = get_bind_section(ictx, (bstr){0}); struct cmd_bind *bind = NULL; @@ -1483,6 +1524,7 @@ void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command) bind->cmd, bind->location); talloc_free(s); } + input_unlock(ictx); } struct mpv_node mp_input_get_bindings(struct input_ctx *ictx) @@ -1536,7 +1578,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; @@ -1545,7 +1587,7 @@ struct mp_input_src_internal { bool drop; }; -static struct mp_input_src *mp_input_add_src(struct input_ctx *ictx) +static struct mp_input_src *input_add_src(struct input_ctx *ictx) { input_lock(ictx); if (ictx->num_sources == MP_MAX_SOURCES) { @@ -1569,7 +1611,7 @@ static struct mp_input_src *mp_input_add_src(struct input_ctx *ictx) return src; } -static void mp_input_src_kill(struct mp_input_src *src); +static void input_src_kill(struct mp_input_src *src); static void close_input_sources(struct input_ctx *ictx) { @@ -1581,11 +1623,11 @@ static void close_input_sources(struct input_ctx *ictx) input_unlock(ictx); if (!src) break; - mp_input_src_kill(src); + input_src_kill(src); } } -static void mp_input_src_kill(struct mp_input_src *src) +static void input_src_kill(struct mp_input_src *src) { if (!src) return; @@ -1598,33 +1640,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,23 +1675,23 @@ 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, void (*loop_fn)(struct mp_input_src *src, void *ctx)) { - struct mp_input_src *src = mp_input_add_src(ictx); + struct mp_input_src *src = input_add_src(ictx); if (!src) return -1; void *args[] = {src, loop_fn, ctx}; - if (pthread_create(&src->in->thread, NULL, input_src_thread, args)) { - mp_input_src_kill(src); + if (mp_thread_create(&src->in->thread, input_src_thread, args)) { + input_src_kill(src); return -1; } if (mp_rendezvous(&src->in->init_done, 0) < 0) { - mp_input_src_kill(src); + input_src_kill(src); return -1; } return 0; @@ -1681,8 +1723,11 @@ void mp_input_src_feed_cmd_text(struct mp_input_src *src, char *buf, size_t len) bstr s = {in->cmd_buffer, in->cmd_buffer_size}; s = bstr_strip(s); struct mp_cmd *cmd = mp_input_parse_cmd_str(src->log, s, "<>"); - if (cmd) - mp_input_queue_cmd(src->input_ctx, cmd); + if (cmd) { + input_lock(src->input_ctx); + queue_cmd(src->input_ctx, cmd); + input_unlock(src->input_ctx); + } in->cmd_buffer_size = 0; } } @@ -1696,4 +1741,3 @@ void mp_input_set_repeat_info(struct input_ctx *ictx, int rate, int delay) ictx->opts->ar_delay = delay; input_unlock(ictx); } - |