summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst4
-rw-r--r--player/client.c10
-rw-r--r--player/client.h2
-rw-r--r--player/core.h10
-rw-r--r--player/javascript.c10
-rw-r--r--player/lua.c13
-rw-r--r--player/scripting.c86
7 files changed, 83 insertions, 52 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index f7c26f33f2..3e0347bc7f 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -24,6 +24,10 @@ Interface changes
::
+ --- mpv 0.33.0 ---
+ - directories in ~/.mpv/scripts/ (or equivalent) now have special semantics
+ (see mpv Lua scripting docs)
+ - names starting with "." in ~/.mpv/scripts/ (or equivalent) are now ignored
--- mpv 0.32.0 ---
- change behavior when using legacy option syntax with options that start
with two dashes (``--`` instead of a ``-``). Now, using the recommended
diff --git a/player/client.c b/player/client.c
index 0a3f5491a7..14ee8fd7ee 100644
--- a/player/client.c
+++ b/player/client.c
@@ -316,16 +316,6 @@ struct mpv_global *mp_client_get_global(struct mpv_handle *ctx)
return ctx->mpctx->global;
}
-struct MPContext *mp_client_get_core(struct mpv_handle *ctx)
-{
- return ctx->mpctx;
-}
-
-struct MPContext *mp_client_api_get_core(struct mp_client_api *api)
-{
- return api->mpctx;
-}
-
static void wakeup_client(struct mpv_handle *ctx)
{
pthread_mutex_lock(&ctx->wakeup_lock);
diff --git a/player/client.h b/player/client.h
index affefe8d71..a8eae2d0c1 100644
--- a/player/client.h
+++ b/player/client.h
@@ -36,8 +36,6 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name
void mp_client_set_weak(struct mpv_handle *ctx);
struct mp_log *mp_client_get_log(struct mpv_handle *ctx);
struct mpv_global *mp_client_get_global(struct mpv_handle *ctx);
-struct MPContext *mp_client_get_core(struct mpv_handle *ctx);
-struct MPContext *mp_client_api_get_core(struct mp_client_api *api);
void mp_client_broadcast_event_external(struct mp_client_api *api, int event,
void *data);
diff --git a/player/core.h b/player/core.h
index acb57ddbe2..70fc33448e 100644
--- a/player/core.h
+++ b/player/core.h
@@ -619,10 +619,18 @@ void update_screensaver_state(struct MPContext *mpctx);
void update_ab_loop_clip(struct MPContext *mpctx);
// scripting.c
+struct mp_script_args {
+ const struct mp_scripting *backend;
+ struct MPContext *mpctx;
+ struct mp_log *log;
+ struct mpv_handle *client;
+ const char *filename;
+ const char *path;
+};
struct mp_scripting {
const char *name; // e.g. "lua script"
const char *file_ext; // e.g. "lua"
- int (*load)(struct mpv_handle *client, const char *filename);
+ int (*load)(struct mp_script_args *args);
};
bool mp_load_scripts(struct MPContext *mpctx);
void mp_load_builtin_scripts(struct MPContext *mpctx);
diff --git a/player/javascript.c b/player/javascript.c
index 8d0e7715f1..6047add255 100644
--- a/player/javascript.c
+++ b/player/javascript.c
@@ -468,15 +468,15 @@ static int s_init_js(js_State *J, struct script_ctx *ctx)
//
// Note: init functions don't need autofree. They can use ctx as a talloc
// context and free normally. If they throw - ctx is freed right afterwards.
-static int s_load_javascript(struct mpv_handle *client, const char *fname)
+static int s_load_javascript(struct mp_script_args *args)
{
struct script_ctx *ctx = talloc_ptrtype(NULL, ctx);
*ctx = (struct script_ctx) {
- .client = client,
- .mpctx = mp_client_get_core(client),
- .log = mp_client_get_log(client),
+ .client = args->client,
+ .mpctx = args->mpctx,
+ .log = args->log,
.last_error_str = talloc_strdup(ctx, "Cannot initialize JavaScript"),
- .filename = fname,
+ .filename = args->filename,
};
int r = -1;
diff --git a/player/lua.c b/player/lua.c
index 6423861f16..3d23a307fb 100644
--- a/player/lua.c
+++ b/player/lua.c
@@ -337,18 +337,17 @@ static int run_lua(lua_State *L)
return 0;
}
-static int load_lua(struct mpv_handle *client, const char *fname)
+static int load_lua(struct mp_script_args *args)
{
- struct MPContext *mpctx = mp_client_get_core(client);
int r = -1;
struct script_ctx *ctx = talloc_ptrtype(NULL, ctx);
*ctx = (struct script_ctx) {
- .mpctx = mpctx,
- .client = client,
- .name = mpv_client_name(client),
- .log = mp_client_get_log(client),
- .filename = fname,
+ .mpctx = args->mpctx,
+ .client = args->client,
+ .name = mpv_client_name(args->client),
+ .log = args->log,
+ .filename = args->filename,
};
if (LUA_VERSION_NUM != 501 && LUA_VERSION_NUM != 502) {
diff --git a/player/scripting.c b/player/scripting.c
index 5f1ae5ce96..bab34d0d03 100644
--- a/player/scripting.c
+++ b/player/scripting.c
@@ -30,6 +30,8 @@
#include "common/common.h"
#include "common/msg.h"
+#include "options/m_config.h"
+#include "options/parse_configfile.h"
#include "options/path.h"
#include "misc/bstr.h"
#include "core.h"
@@ -74,26 +76,19 @@ static char *script_name_from_filename(void *talloc_ctx, const char *fname)
return talloc_asprintf(talloc_ctx, "%s", name);
}
-struct thread_arg {
- struct mp_log *log;
- const struct mp_scripting *backend;
- mpv_handle *client;
- const char *fname;
-};
-
static void *script_thread(void *p)
{
pthread_detach(pthread_self());
- struct thread_arg *arg = p;
+ struct mp_script_args *arg = p;
char name[90];
snprintf(name, sizeof(name), "%s (%s)", arg->backend->name,
mpv_client_name(arg->client));
mpthread_set_name(name);
- if (arg->backend->load(arg->client, arg->fname) < 0)
- MP_ERR(arg, "Could not load %s %s\n", arg->backend->name, arg->fname);
+ if (arg->backend->load(arg) < 0)
+ MP_ERR(arg, "Could not load %s %s\n", arg->backend->name, arg->filename);
mpv_destroy(arg->client);
talloc_free(arg);
@@ -106,34 +101,70 @@ static int mp_load_script(struct MPContext *mpctx, const char *fname)
if (ext && strcasecmp(ext, "disable") == 0)
return 0;
+ void *tmp = talloc_new(NULL);
+
+ const char *path = NULL;
const struct mp_scripting *backend = NULL;
- for (int n = 0; scripting_backends[n]; n++) {
- const struct mp_scripting *b = scripting_backends[n];
- if (ext && strcasecmp(ext, b->file_ext) == 0) {
- backend = b;
- break;
+
+ struct stat s;
+ if (!stat(fname, &s) && S_ISDIR(s.st_mode)) {
+ path = fname;
+ fname = NULL;
+
+ for (int n = 0; scripting_backends[n]; n++) {
+ const struct mp_scripting *b = scripting_backends[n];
+ char *filename = mp_tprintf(80, "main.%s", b->file_ext);
+ fname = mp_path_join(tmp, path, filename);
+ if (!stat(fname, &s) && S_ISREG(s.st_mode)) {
+ backend = b;
+ break;
+ }
+ talloc_free((void *)fname);
+ fname = NULL;
+ }
+
+ if (!fname) {
+ MP_ERR(mpctx, "Cannot find main.* for any supported scripting "
+ "backend in: %s\n", path);
+ talloc_free(tmp);
+ return -1;
+ }
+ } else {
+ for (int n = 0; scripting_backends[n]; n++) {
+ const struct mp_scripting *b = scripting_backends[n];
+ if (ext && strcasecmp(ext, b->file_ext) == 0) {
+ backend = b;
+ break;
+ }
}
}
if (!backend) {
MP_ERR(mpctx, "Can't load unknown script: %s\n", fname);
+ talloc_free(tmp);
return -1;
}
- struct thread_arg *arg = talloc_ptrtype(NULL, arg);
+ struct mp_script_args *arg = talloc_ptrtype(NULL, arg);
char *name = script_name_from_filename(arg, fname);
- *arg = (struct thread_arg){
- .fname = talloc_strdup(arg, fname),
+ *arg = (struct mp_script_args){
+ .mpctx = mpctx,
+ .filename = talloc_strdup(arg, fname),
+ .path = talloc_strdup(arg, path),
.backend = backend,
// Create the client before creating the thread; otherwise a race
// condition could happen, where MPContext is destroyed while the
// thread tries to create the client.
.client = mp_new_client(mpctx->clients, name),
};
+
+ talloc_free(tmp);
+
if (!arg->client) {
talloc_free(arg);
return -1;
}
+
mp_client_set_weak(arg->client);
arg->log = mp_client_get_log(arg->client);
@@ -173,10 +204,12 @@ static char **list_script_files(void *talloc_ctx, char *path)
return NULL;
struct dirent *ep;
while ((ep = readdir(dp))) {
- char *fname = mp_path_join(talloc_ctx, path, ep->d_name);
- struct stat s;
- if (!stat(fname, &s) && S_ISREG(s.st_mode))
- MP_TARRAY_APPEND(talloc_ctx, files, count, fname);
+ if (ep->d_name[0] != '.') {
+ char *fname = mp_path_join(talloc_ctx, path, ep->d_name);
+ struct stat s;
+ if (!stat(fname, &s) && (S_ISREG(s.st_mode) || S_ISDIR(s.st_mode)))
+ MP_TARRAY_APPEND(talloc_ctx, files, count, fname);
+ }
}
closedir(dp);
if (files)
@@ -247,10 +280,9 @@ bool mp_load_scripts(struct MPContext *mpctx)
#define MPV_DLOPEN_FN "mpv_open_cplugin"
typedef int (*mpv_open_cplugin)(mpv_handle *handle);
-static int load_cplugin(struct mpv_handle *client, const char *fname)
+static int load_cplugin(struct mp_script_args *args)
{
- MPContext *ctx = mp_client_get_core(client);
- void *lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL);
+ void *lib = dlopen(args->filename, RTLD_NOW | RTLD_LOCAL);
if (!lib)
goto error;
// Note: once loaded, we never unload, as unloading the libraries linked to
@@ -258,11 +290,11 @@ static int load_cplugin(struct mpv_handle *client, const char *fname)
mpv_open_cplugin sym = (mpv_open_cplugin)dlsym(lib, MPV_DLOPEN_FN);
if (!sym)
goto error;
- return sym(client) ? -1 : 0;
+ return sym(args->client) ? -1 : 0;
error: ;
char *err = dlerror();
if (err)
- MP_ERR(ctx, "C plugin error: '%s'\n", err);
+ MP_ERR(args, "C plugin error: '%s'\n", err);
return -1;
}