summaryrefslogtreecommitdiffstats
path: root/input
diff options
context:
space:
mode:
Diffstat (limited to 'input')
-rw-r--r--input/cmd.h3
-rw-r--r--input/event.c15
-rw-r--r--input/event.h5
-rw-r--r--input/input.c172
-rw-r--r--input/input.h7
-rw-r--r--input/ipc-unix.c30
-rw-r--r--input/ipc-win.c32
-rw-r--r--input/ipc.c4
-rw-r--r--input/keycodes.c13
-rw-r--r--input/keycodes.h13
-rw-r--r--input/meson.build20
-rw-r--r--input/sdl_gamepad.c14
12 files changed, 202 insertions, 126 deletions
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 f69517f748..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,16 +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 builtin_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 = {
@@ -190,24 +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-builtin-bindings", OPT_FLAG(builtin_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),
@@ -216,19 +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,
- .builtin_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)
@@ -595,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) {
@@ -737,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;
@@ -762,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);
}
@@ -920,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;
}
@@ -1013,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++) {
@@ -1279,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;
@@ -1298,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);
}
@@ -1323,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 |
@@ -1379,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);
}
@@ -1398,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) {
@@ -1419,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);
}
@@ -1539,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;
@@ -1601,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;
@@ -1636,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,
@@ -1647,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;
}
@@ -1699,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 3f97b4a9ad..c412191573 100644
--- a/input/keycodes.c
+++ b/input/keycodes.c
@@ -89,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" },
@@ -165,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']
+foreach file: etc_files
+ etc_file = custom_target(file,
+ input: join_paths(source_root, 'etc', file),
+ output: file + '.inc',
+ command: [file2string, '@INPUT@', '@OUTPUT@'],
+ )
+ sources += etc_file
+endforeach
diff --git a/input/sdl_gamepad.c b/input/sdl_gamepad.c
index 7045239fda..b61f7c9543 100644
--- a/input/sdl_gamepad.c
+++ b/input/sdl_gamepad.c
@@ -15,13 +15,15 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <SDL.h>
#include <stdbool.h>
-#include <pthread.h>
+
+#include <SDL.h>
+
#include "common/common.h"
#include "common/msg.h"
#include "input.h"
#include "input/keycodes.h"
+#include "osdep/threads.h"
struct gamepad_priv {
SDL_GameController *controller;
@@ -34,7 +36,7 @@ static void initialize_events(void)
gamepad_cancel_wakeup = SDL_RegisterEvents(1);
}
-static pthread_once_t events_initialized = PTHREAD_ONCE_INIT;
+static mp_once events_initialized = MP_STATIC_ONCE_INITIALIZER;
#define INVALID_KEY -1
@@ -198,6 +200,10 @@ static void remove_gamepad(struct mp_input_src *src, int id)
static void read_gamepad_thread(struct mp_input_src *src, void *param)
{
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1");
+#endif
+
if (SDL_WasInit(SDL_INIT_EVENTS)) {
MP_ERR(src, "Another component is using SDL already.\n");
mp_input_src_init_done(src);
@@ -210,7 +216,7 @@ static void read_gamepad_thread(struct mp_input_src *src, void *param)
return;
}
- pthread_once(&events_initialized, initialize_events);
+ mp_exec_once(&events_initialized, initialize_events);
if (gamepad_cancel_wakeup == (Uint32)-1) {
MP_ERR(src, "Can't register SDL custom events\n");