diff options
author | Martin Herkt <lachs0r@srsfckn.biz> | 2016-01-18 07:27:03 +0100 |
---|---|---|
committer | Martin Herkt <lachs0r@srsfckn.biz> | 2016-01-18 07:27:03 +0100 |
commit | ba9b2f1e49732d597009ba514b0132a50562cd10 (patch) | |
tree | fa05f5feb181823ac9d3b5682a835ff825de6914 /input | |
parent | e1993d5ad2bdf3dd4c26474aaa2370cbc9c1cd1b (diff) | |
parent | 7b4ccb3e9f58a0745b58e473ee6e60b381242813 (diff) | |
download | mpv-ba9b2f1e49732d597009ba514b0132a50562cd10.tar.bz2 mpv-ba9b2f1e49732d597009ba514b0132a50562cd10.tar.xz |
Merge branch 'master' into release/current
Diffstat (limited to 'input')
-rw-r--r-- | input/cmd_parse.c | 1 | ||||
-rw-r--r-- | input/input.c | 19 | ||||
-rw-r--r-- | input/input.h | 1 | ||||
-rw-r--r-- | input/keycodes.c | 2 | ||||
-rw-r--r-- | input/keycodes.h | 3 | ||||
-rw-r--r-- | input/pipe-win32.c | 121 |
6 files changed, 79 insertions, 68 deletions
diff --git a/input/cmd_parse.c b/input/cmd_parse.c index ba35cd5e1c..c2c3270e97 100644 --- a/input/cmd_parse.c +++ b/input/cmd_parse.c @@ -417,6 +417,7 @@ mp_cmd_t *mp_cmd_clone(mp_cmd_t *cmd) m_option_copy(ret->args[i].type, &ret->args[i].v, &cmd->args[i].v); } ret->original = bstrdup(ret, cmd->original); + ret->key_name = talloc_strdup(ret, ret->key_name); if (cmd->id == MP_CMD_COMMAND_LIST) { struct mp_cmd *prev = NULL; diff --git a/input/input.c b/input/input.c index 5b3370736a..d1c69a9587 100644 --- a/input/input.c +++ b/input/input.c @@ -48,7 +48,7 @@ #include "options/m_config.h" #include "options/m_option.h" #include "options/path.h" -#include "talloc.h" +#include "mpv_talloc.h" #include "options/options.h" #include "misc/bstr.h" #include "stream/stream.h" @@ -446,7 +446,9 @@ static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, char *force_section, return handle_test(ictx, code); struct cmd_bind *cmd = find_any_bind_for_key(ictx, force_section, code); - if (cmd == NULL) { + if (!cmd) + cmd = find_any_bind_for_key(ictx, force_section, MP_KEY_UNMAPPED); + if (!cmd) { if (code == MP_KEY_CLOSE_WIN) return mp_input_parse_cmd_strv(ictx->log, (const char*[]){"quit", 0}); int msgl = MSGL_WARN; @@ -460,12 +462,9 @@ static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, char *force_section, mp_cmd_t *ret = mp_input_parse_cmd(ictx, bstr0(cmd->cmd), cmd->location); if (ret) { ret->input_section = cmd->owner->section; - if (mp_msg_test(ictx->log, MSGL_DEBUG)) { - char *keyname = mp_input_get_key_combo_name(&code, 1); - MP_DBG(ictx, "key '%s' -> '%s' in '%s'\n", - keyname, cmd->cmd, ret->input_section); - talloc_free(keyname); - } + ret->key_name = talloc_steal(ret, mp_input_get_key_combo_name(&code, 1)); + MP_DBG(ictx, "key '%s' -> '%s' in '%s'\n", + ret->key_name, cmd->cmd, ret->input_section); ret->is_mouse_button = code & MP_KEY_EMIT_ON_UP; } else { char *key_buf = mp_input_get_key_combo_name(&code, 1); @@ -1265,11 +1264,7 @@ void mp_input_load(struct input_ctx *ictx) #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 } diff --git a/input/input.h b/input/input.h index 2b2299d5cc..6462555326 100644 --- a/input/input.h +++ b/input/input.h @@ -86,6 +86,7 @@ typedef struct mp_cmd { double scale; // for scaling numeric arguments const struct mp_cmd_def *def; char *sender; // name of the client API user which sent this + char *key_name; // string representation of the key binding } mp_cmd_t; struct mp_input_src { diff --git a/input/keycodes.c b/input/keycodes.c index 21a3c10e64..d6c07288c2 100644 --- a/input/keycodes.c +++ b/input/keycodes.c @@ -171,6 +171,8 @@ static const struct key_name key_names[] = { { MP_KEY_MOUSE_LEAVE, "MOUSE_LEAVE" }, { MP_KEY_MOUSE_ENTER, "MOUSE_ENTER" }, + { MP_KEY_UNMAPPED, "UNMAPPED" }, + { 0, NULL } }; diff --git a/input/keycodes.h b/input/keycodes.h index d95edb1f45..da88d52c37 100644 --- a/input/keycodes.h +++ b/input/keycodes.h @@ -200,6 +200,9 @@ #define MP_KEY_IS_MOUSE(code) \ (MP_KEY_IS_MOUSE_CLICK(code) || MP_KEY_IS_MOUSE_MOVE(code)) +// No input source should generate this. +#define MP_KEY_UNMAPPED (MP_KEY_INTERN+4) + // Emit a command even on key-up (normally key-up is ignored). This means by // default they binding will be triggered on key-up instead of key-down. // This is a fixed part of the keycode, not a modifier than can change. diff --git a/input/pipe-win32.c b/input/pipe-win32.c index 4077ea84ee..3d47fb66c1 100644 --- a/input/pipe-win32.c +++ b/input/pipe-win32.c @@ -1,98 +1,107 @@ -#include <pthread.h> -#include <stdio.h> +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + #include <windows.h> #include <io.h> -#include <stdint.h> -#include <waio/waio.h> - #include "common/msg.h" +#include "osdep/atomics.h" #include "osdep/io.h" #include "input.h" +struct priv { + atomic_bool cancel_requested; + int fd; + bool close_fd; + HANDLE file; + HANDLE thread; +}; + static void request_cancel(struct mp_input_src *src) { - HANDLE terminate = src->priv; + struct priv *p = src->priv; MP_VERBOSE(src, "Exiting...\n"); - SetEvent(terminate); + atomic_store(&p->cancel_requested, true); + + // The thread might not be peforming I/O at the exact moment when + // CancelIoEx is called, so call it in a loop until it succeeds or the + // thread exits + do { + if (CancelIoEx(p->file, NULL)) + break; + } while (WaitForSingleObject(p->thread, 1) != WAIT_OBJECT_0); } static void uninit(struct mp_input_src *src) { - HANDLE terminate = src->priv; + struct priv *p = src->priv; + + CloseHandle(p->thread); + if (p->close_fd) + close(p->fd); - CloseHandle(terminate); MP_VERBOSE(src, "Exited.\n"); } static void read_pipe_thread(struct mp_input_src *src, void *param) { char *filename = talloc_strdup(src, param); + struct priv *p = talloc_zero(src, struct priv); - struct waio_cx_interface *waio = NULL; - int mode = O_RDONLY; - int fd = -1; - bool close_fd = true; + p->fd = -1; + p->close_fd = true; if (strcmp(filename, "/dev/stdin") == 0) { // for symmetry with unix - fd = STDIN_FILENO; - close_fd = false; + p->fd = STDIN_FILENO; + p->close_fd = false; } - if (fd < 0) - fd = open(filename, mode); - if (fd < 0) { + if (p->fd < 0) + p->fd = open(filename, O_RDONLY); + if (p->fd < 0) { MP_ERR(src, "Can't open %s.\n", filename); - goto done; + return; } - // If we're reading from stdin, unset it. All I/O on synchronous handles is - // serialized, so stupid DLLs that call GetFileType on stdin can hang the - // process if they do it while we're reading from it. At least, the - // VirtualBox OpenGL ICD is affected by this, but only on Windows XP. - // GetFileType works differently in later versions of Windows. See: - // https://support.microsoft.com/kb/2009703 - // http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx - if ((void*)_get_osfhandle(fd) == GetStdHandle(STD_INPUT_HANDLE)) - SetStdHandle(STD_INPUT_HANDLE, NULL); - - waio = waio_alloc((void *)_get_osfhandle(fd), 0, NULL, NULL); - if (!waio) { - MP_ERR(src, "Can't initialize win32 file reader.\n"); - goto done; + p->file = (HANDLE)_get_osfhandle(p->fd); + if (!p->file || p->file == INVALID_HANDLE_VALUE) { + MP_ERR(src, "Can't open %s.\n", filename); + return; } - HANDLE terminate = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!terminate) - goto done; + atomic_store(&p->cancel_requested, false); + if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), + GetCurrentProcess(), &p->thread, SYNCHRONIZE, FALSE, 0)) + return; - src->priv = terminate; + src->priv = p; src->cancel = request_cancel; src->uninit = uninit; mp_input_src_init_done(src); - char buffer[128]; - struct waio_aiocb cb = { - .aio_buf = buffer, - .aio_nbytes = sizeof(buffer), - .hsignal = terminate, - }; - while (1) { - if (waio_read(waio, &cb)) { - MP_ERR(src, "Read operation failed.\n"); + char buffer[4096]; + while (!atomic_load(&p->cancel_requested)) { + DWORD r; + if (!ReadFile(p->file, buffer, 4096, &r, NULL)) { + if (GetLastError() != ERROR_OPERATION_ABORTED) + MP_ERR(src, "Read operation failed.\n"); break; } - if (waio_suspend(waio, (const struct waio_aiocb *[]){&cb}, 1, NULL)) - break; - ssize_t r = waio_return(waio, &cb); - if (r <= 0) - break; // EOF or error mp_input_src_feed_cmd_text(src, buffer, r); } - -done: - waio_free(waio); - if (close_fd) - close(fd); } void mp_input_pipe_add(struct input_ctx *ictx, const char *filename) |