summaryrefslogtreecommitdiffstats
path: root/input/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'input/input.c')
-rw-r--r--input/input.c193
1 files changed, 110 insertions, 83 deletions
diff --git a/input/input.c b/input/input.c
index dd9486f12a..9525dbcbb1 100644
--- a/input/input.c
+++ b/input/input.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
+#include <math.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -34,7 +35,6 @@
#include <libavutil/common.h>
#include "osdep/io.h"
-#include "osdep/semaphore.h"
#include "misc/rendezvous.h"
#include "input.h"
@@ -73,6 +73,7 @@ struct cmd_bind {
};
struct cmd_bind_section {
+ char *owner;
struct cmd_bind *binds;
int num_binds;
char *section;
@@ -96,15 +97,13 @@ struct cmd_queue {
struct input_ctx {
pthread_mutex_t mutex;
- sem_t wakeup;
struct mp_log *log;
struct mpv_global *global;
+ struct m_config_cache *opts_cache;
struct input_opts *opts;
- bool using_alt_gr;
bool using_ar;
bool using_cocoa_media_keys;
- bool win_drag;
// Autorepeat stuff
short ar_state;
@@ -146,6 +145,9 @@ struct input_ctx {
struct cmd_queue cmd_queue;
struct mp_cancel *cancel;
+
+ void (*wakeup_cb)(void *ctx);
+ void *wakeup_ctx;
};
static int parse_config(struct input_ctx *ictx, bool builtin, bstr data,
@@ -170,28 +172,30 @@ struct input_opts {
int enable_mouse_movements;
int vo_key_input;
int test;
+ int allow_win_drag;
};
const struct m_sub_options input_config = {
.opts = (const m_option_t[]) {
- OPT_STRING("conf", config_file, CONF_GLOBAL | M_OPT_FILE),
- OPT_INT("ar-delay", ar_delay, CONF_GLOBAL),
- OPT_INT("ar-rate", ar_rate, CONF_GLOBAL),
- OPT_PRINT("keylist", mp_print_key_list),
- OPT_PRINT("cmdlist", mp_print_cmd_list),
- OPT_FLAG("default-bindings", default_bindings, CONF_GLOBAL),
- OPT_FLAG("test", test, CONF_GLOBAL),
- OPT_INTRANGE("doubleclick-time", doubleclick_time, 0, 0, 1000),
- OPT_FLAG("right-alt-gr", use_alt_gr, CONF_GLOBAL),
- OPT_INTRANGE("key-fifo-size", key_fifo_size, CONF_GLOBAL, 2, 65000),
- OPT_FLAG("cursor", enable_mouse_movements, CONF_GLOBAL),
- OPT_FLAG("vo-keyboard", vo_key_input, CONF_GLOBAL),
- OPT_FLAG("x11-keyboard", vo_key_input, CONF_GLOBAL), // old alias
+ OPT_STRING("input-conf", config_file, M_OPT_FIXED | M_OPT_FILE),
+ OPT_INT("input-ar-delay", ar_delay, 0),
+ OPT_INT("input-ar-rate", ar_rate, 0),
+ OPT_PRINT("input-keylist", mp_print_key_list),
+ OPT_PRINT("input-cmdlist", mp_print_cmd_list),
+ OPT_FLAG("input-default-bindings", default_bindings, 0),
+ OPT_FLAG("input-test", test, 0),
+ OPT_INTRANGE("input-doubleclick-time", doubleclick_time, 0, 0, 1000),
+ OPT_FLAG("input-right-alt-gr", use_alt_gr, 0),
+ OPT_INTRANGE("input-key-fifo-size", key_fifo_size, 0, 2, 65000),
+ OPT_FLAG("input-cursor", enable_mouse_movements, 0),
+ OPT_FLAG("input-vo-keyboard", vo_key_input, 0),
#if HAVE_COCOA
- OPT_FLAG("appleremote", use_appleremote, CONF_GLOBAL),
- OPT_FLAG("media-keys", use_media_keys, CONF_GLOBAL),
- OPT_FLAG("app-events", use_app_events, CONF_GLOBAL),
+ OPT_FLAG("input-appleremote", use_appleremote, 0),
+ OPT_FLAG("input-media-keys", use_media_keys, 0),
+ OPT_FLAG("input-app-events", use_app_events, M_OPT_FIXED),
#endif
+ OPT_FLAG("window-dragging", allow_win_drag, 0),
+ OPT_REPLACED("input-x11-keyboard", "input-vo-keyboard"),
{0}
},
.size = sizeof(struct input_opts),
@@ -209,7 +213,9 @@ const struct m_sub_options input_config = {
#endif
.default_bindings = 1,
.vo_key_input = 1,
+ .allow_win_drag = 1,
},
+ .change_flags = UPDATE_INPUT,
};
static const char builtin_input_conf[] =
@@ -845,33 +851,18 @@ static mp_cmd_t *check_autorepeat(struct input_ctx *ictx)
return NULL;
}
-void mp_input_wait(struct input_ctx *ictx, double seconds)
+double mp_input_get_delay(struct input_ctx *ictx)
{
input_lock(ictx);
+ double seconds = INFINITY;
adjust_max_wait_time(ictx, &seconds);
input_unlock(ictx);
- while (sem_trywait(&ictx->wakeup) == 0)
- seconds = -1;
- if (seconds > 0) {
- MP_STATS(ictx, "start sleep");
- struct timespec ts =
- mp_time_us_to_timespec(mp_add_timeout(mp_time_us(), seconds));
- sem_timedwait(&ictx->wakeup, &ts);
- MP_STATS(ictx, "end sleep");
- }
-}
-
-void mp_input_wakeup_nolock(struct input_ctx *ictx)
-{
- // Some audio APIs discourage use of locking in their audio callback,
- // and these audio callbacks happen to call mp_input_wakeup_nolock()
- // when new data is needed. This is why we use semaphores here.
- sem_post(&ictx->wakeup);
+ return seconds;
}
void mp_input_wakeup(struct input_ctx *ictx)
{
- mp_input_wakeup_nolock(ictx);
+ ictx->wakeup_cb(ictx->wakeup_ctx);
}
mp_cmd_t *mp_input_read_cmd(struct input_ctx *ictx)
@@ -996,7 +987,8 @@ bool mp_input_test_mouse_active(struct input_ctx *ictx, int x, int y)
bool mp_input_test_dragging(struct input_ctx *ictx, int x, int y)
{
input_lock(ictx);
- bool r = !ictx->win_drag || test_mouse(ictx, x, y, MP_INPUT_ALLOW_VO_DRAGGING);
+ bool r = !ictx->opts->allow_win_drag ||
+ test_mouse(ictx, x, y, MP_INPUT_ALLOW_VO_DRAGGING);
input_unlock(ictx);
return r;
}
@@ -1021,13 +1013,19 @@ static void remove_binds(struct cmd_bind_section *bs, bool builtin)
}
void mp_input_define_section(struct input_ctx *ictx, char *name, char *location,
- char *contents, bool builtin)
+ char *contents, bool builtin, char *owner)
{
if (!name || !name[0])
return; // parse_config() changes semantics with restrict_section==empty
input_lock(ictx);
// Delete:
struct cmd_bind_section *bs = get_bind_section(ictx, bstr0(name));
+ if ((!bs->owner || (owner && strcmp(bs->owner, owner) != 0)) &&
+ strcmp(bs->section, "default") != 0)
+ {
+ talloc_free(bs->owner);
+ bs->owner = talloc_strdup(bs, owner);
+ }
remove_binds(bs, builtin);
if (contents && contents[0]) {
// Redefine:
@@ -1039,6 +1037,21 @@ void mp_input_define_section(struct input_ctx *ictx, char *name, char *location,
input_unlock(ictx);
}
+void mp_input_remove_sections_by_owner(struct input_ctx *ictx, char *owner)
+{
+ input_lock(ictx);
+ struct cmd_bind_section *bs = ictx->cmd_bind_sections;
+ while (bs) {
+ if (bs->owner && owner && strcmp(bs->owner, owner) == 0) {
+ mp_input_disable_section(ictx, bs->section);
+ remove_binds(bs, false);
+ remove_binds(bs, true);
+ }
+ bs = bs->next;
+ }
+ input_unlock(ictx);
+}
+
static bool bind_matches_key(struct cmd_bind *bind, int num_keys, const int *keys)
{
if (bind->num_keys != num_keys)
@@ -1195,22 +1208,23 @@ done:
return r;
}
-struct input_ctx *mp_input_init(struct mpv_global *global)
+struct input_ctx *mp_input_init(struct mpv_global *global,
+ void (*wakeup_cb)(void *ctx),
+ void *wakeup_ctx)
{
struct input_ctx *ictx = talloc_ptrtype(NULL, ictx);
*ictx = (struct input_ctx){
.global = global,
- .opts = talloc_zero(ictx, struct input_opts), // replaced later
.ar_state = -1,
.log = mp_log_new(ictx, global->log, "input"),
.mouse_section = "default",
+ .opts_cache = m_config_cache_alloc(ictx, global, &input_config),
+ .wakeup_cb = wakeup_cb,
+ .wakeup_ctx = wakeup_ctx,
};
- if (sem_init(&ictx->wakeup, 0, 0)) {
- MP_FATAL(ictx, "mpv doesn't work on systems without POSIX semaphores.\n");
- abort();
- }
+ ictx->opts = ictx->opts_cache->opts;
mpthread_mutex_init_recursive(&ictx->mutex);
@@ -1221,13 +1235,45 @@ struct input_ctx *mp_input_init(struct mpv_global *global)
return ictx;
}
-void mp_input_load(struct input_ctx *ictx)
+static void reload_opts(struct input_ctx *ictx, bool shutdown)
+{
+ m_config_cache_update(ictx->opts_cache);
+
+#if HAVE_COCOA
+ struct input_opts *opts = ictx->opts;
+
+ if (ictx->using_ar != (opts->use_appleremote && !shutdown)) {
+ ictx->using_ar = !ictx->using_ar;
+ if (ictx->using_ar) {
+ cocoa_init_apple_remote();
+ } else {
+ cocoa_uninit_apple_remote();
+ }
+ }
+
+ if (ictx->using_cocoa_media_keys != (opts->use_media_keys && !shutdown)) {
+ ictx->using_cocoa_media_keys = !ictx->using_cocoa_media_keys;
+ if (ictx->using_cocoa_media_keys) {
+ cocoa_init_media_keys();
+ } else {
+ cocoa_uninit_media_keys();
+ }
+ }
+#endif
+}
+
+void mp_input_update_opts(struct input_ctx *ictx)
+{
+ input_lock(ictx);
+ reload_opts(ictx, false);
+ input_unlock(ictx);
+}
+
+void mp_input_load_config(struct input_ctx *ictx)
{
- struct input_opts *input_conf =
- m_sub_options_copy(ictx, &input_config, ictx->global->opts->input_opts);
+ input_lock(ictx);
- talloc_free(ictx->opts);
- ictx->opts = input_conf;
+ reload_opts(ictx, false);
// "Uncomment" the default key bindings in etc/input.conf and add them.
// All lines that do not start with '# ' are parsed.
@@ -1240,8 +1286,8 @@ void mp_input_load(struct input_ctx *ictx)
}
bool config_ok = false;
- if (input_conf->config_file)
- config_ok = parse_config_file(ictx, input_conf->config_file, true);
+ if (ictx->opts->config_file && ictx->opts->config_file[0])
+ config_ok = parse_config_file(ictx, ictx->opts->config_file, true);
if (!config_ok) {
// Try global conf dir
void *tmp = talloc_new(NULL);
@@ -1251,32 +1297,17 @@ void mp_input_load(struct input_ctx *ictx)
talloc_free(tmp);
}
- if (input_conf->use_alt_gr) {
- ictx->using_alt_gr = true;
- }
-
#if HAVE_COCOA
- if (input_conf->use_app_events) {
+ if (ictx->opts->use_app_events)
cocoa_start_event_monitor();
- }
-
- if (input_conf->use_appleremote) {
- cocoa_init_apple_remote();
- ictx->using_ar = true;
- }
-
- if (input_conf->use_media_keys) {
- cocoa_init_media_keys();
- ictx->using_cocoa_media_keys = true;
- }
#endif
- ictx->win_drag = ictx->global->opts->allow_win_drag;
-
#if defined(__MINGW32__)
if (ictx->global->opts->input_file && *ictx->global->opts->input_file)
mp_input_pipe_add(ictx, ictx->global->opts->input_file);
#endif
+
+ input_unlock(ictx);
}
static void clear_queue(struct cmd_queue *queue)
@@ -1293,21 +1324,14 @@ void mp_input_uninit(struct input_ctx *ictx)
if (!ictx)
return;
-#if HAVE_COCOA
- if (ictx->using_ar) {
- cocoa_uninit_apple_remote();
- }
-
- if (ictx->using_cocoa_media_keys) {
- cocoa_uninit_media_keys();
- }
-#endif
+ input_lock(ictx);
+ reload_opts(ictx, true);
+ input_unlock(ictx);
close_input_sources(ictx);
clear_queue(&ictx->cmd_queue);
talloc_free(ictx->current_down_cmd);
pthread_mutex_destroy(&ictx->mutex);
- sem_destroy(&ictx->wakeup);
talloc_free(ictx);
}
@@ -1320,7 +1344,10 @@ void mp_input_set_cancel(struct input_ctx *ictx, struct mp_cancel *cancel)
bool mp_input_use_alt_gr(struct input_ctx *ictx)
{
- return ictx->using_alt_gr;
+ input_lock(ictx);
+ bool r = ictx->opts->use_alt_gr;
+ input_unlock(ictx);
+ return r;
}
struct mp_cmd *mp_input_parse_cmd(struct input_ctx *ictx, bstr str,