summaryrefslogtreecommitdiffstats
path: root/input
diff options
context:
space:
mode:
authorMartin Herkt <lachs0r@srsfckn.biz>2016-01-18 07:27:03 +0100
committerMartin Herkt <lachs0r@srsfckn.biz>2016-01-18 07:27:03 +0100
commitba9b2f1e49732d597009ba514b0132a50562cd10 (patch)
treefa05f5feb181823ac9d3b5682a835ff825de6914 /input
parente1993d5ad2bdf3dd4c26474aaa2370cbc9c1cd1b (diff)
parent7b4ccb3e9f58a0745b58e473ee6e60b381242813 (diff)
downloadmpv-ba9b2f1e49732d597009ba514b0132a50562cd10.tar.bz2
mpv-ba9b2f1e49732d597009ba514b0132a50562cd10.tar.xz
Merge branch 'master' into release/current
Diffstat (limited to 'input')
-rw-r--r--input/cmd_parse.c1
-rw-r--r--input/input.c19
-rw-r--r--input/input.h1
-rw-r--r--input/keycodes.c2
-rw-r--r--input/keycodes.h3
-rw-r--r--input/pipe-win32.c121
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)