Skip to content

Commit

Permalink
player/command: add clipboard property
Browse files Browse the repository at this point in the history
  • Loading branch information
rcombs committed Apr 8, 2024
1 parent 5786236 commit 99e1f27
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 1 deletion.
12 changes: 12 additions & 0 deletions DOCS/man/input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3447,6 +3447,18 @@ Property list
``current-ao``
Current audio output driver (name as used with ``--ao``).

``clipboard`` (RW)
Access to the system clipboard as a key/value map of types and data.

Sub-paths can be accessed directly; e.g. ``clipboard/text`` can be read or written.

The top-level object itself can be written directly as a shortcut.

Converting this property to a string will give a JSON representation of all types.
Unset types will be null.

Currently, only the ``text`` type is available.

``user-data`` (RW)
This is a recursive key/value map of arbitrary nodes shared between clients for
general use (i.e. scripts, IPC clients, host applications, etc).
Expand Down
119 changes: 118 additions & 1 deletion player/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ static const struct m_option mdata_type = {
.type = CONF_TYPE_NODE
};

static const struct m_option clipboard_type = {
.type = CONF_TYPE_NODE
};

struct overlay {
struct mp_image *source;
int x, y;
Expand Down Expand Up @@ -3933,6 +3937,117 @@ static int mp_property_udata(void *ctx, struct m_property *prop,
return ret;
}

static int do_get_clipboard(mpv_node *out, enum m_clipboard_type type)
{
struct m_clipboard_item item = {
.type = type,
};

switch (type) {
case CLIPBOARD_UNKNOWN:
return M_PROPERTY_UNKNOWN;
case CLIPBOARD_TEXT:
break;
default:
return M_PROPERTY_NOT_IMPLEMENTED;
}

int ret = m_clipboard_get(&item);
if (ret < 0)
return M_PROPERTY_ERROR;
else if (ret == CLIPBOARD_NONE)
return M_PROPERTY_UNAVAILABLE;

m_option_free(&clipboard_type, out);

switch (type) {
case CLIPBOARD_TEXT:
out->format = MPV_FORMAT_STRING;
out->u.string = item.text;
return M_PROPERTY_OK;
default:
m_clipboard_item_free(&item);
return M_PROPERTY_NOT_IMPLEMENTED;
}
}

static int do_set_clipboard(mpv_node *node, enum m_clipboard_type type)
{
struct m_clipboard_item item = {};

switch (type) {
case CLIPBOARD_UNKNOWN:
break;
case CLIPBOARD_TEXT:
if (node->format != MPV_FORMAT_STRING)
return M_PROPERTY_INVALID_FORMAT;
break;
default:
return M_PROPERTY_NOT_IMPLEMENTED;
}

switch (node->format) {
case MPV_FORMAT_STRING:
item.type = CLIPBOARD_TEXT;
item.text = node->u.string;
break;
default:
return M_PROPERTY_NOT_IMPLEMENTED;
}

return (m_clipboard_set(&item) == CLIPBOARD_OK) ? M_PROPERTY_OK : M_PROPERTY_ERROR;
}

static int mp_property_clipboard(void *ctx, struct m_property *prop,
int action, void *arg)
{
switch (action) {
case M_PROPERTY_GET_TYPE:
*(struct m_option *)arg = clipboard_type;
return M_PROPERTY_OK;
case M_PROPERTY_GET:
case M_PROPERTY_GET_NODE: {
mpv_node *node = arg;
m_option_free(&clipboard_type, node);
node_init(node, MPV_FORMAT_NODE_MAP, NULL);
struct mpv_node *text = node_map_add(node, "text", MPV_FORMAT_NONE);
do_get_clipboard(text, CLIPBOARD_TEXT);
return M_PROPERTY_OK;
}
case M_PROPERTY_SET:
case M_PROPERTY_SET_NODE:
return do_set_clipboard(arg, CLIPBOARD_UNKNOWN);
case M_PROPERTY_KEY_ACTION: {
struct m_property_action_arg *act = arg;
const char *key = act->key;

enum m_clipboard_type type = CLIPBOARD_UNKNOWN;
if (!strcmp(key, "text")) {
type = CLIPBOARD_TEXT;
}

if (type == CLIPBOARD_UNKNOWN)
return M_PROPERTY_UNKNOWN;

switch (act->action) {
case M_PROPERTY_GET_TYPE:
*(struct m_option *)act->arg = clipboard_type;
return M_PROPERTY_OK;
case M_PROPERTY_GET:
case M_PROPERTY_GET_NODE:
return do_get_clipboard(act->arg, type);
case M_PROPERTY_SET:
case M_PROPERTY_SET_NODE:
return do_set_clipboard(act->arg, type);
default:
return M_PROPERTY_NOT_IMPLEMENTED;
}
}
default:
return M_PROPERTY_NOT_IMPLEMENTED;
}
}

// Redirect a property name to another
#define M_PROPERTY_ALIAS(name, real_property) \
{(name), mp_property_alias, .priv = (real_property)}
Expand Down Expand Up @@ -4149,6 +4264,8 @@ static const struct m_property mp_properties_base[] = {
{"user-data", mp_property_udata},
{"term-size", mp_property_term_size},

{"clipboard", mp_property_clipboard},

M_PROPERTY_ALIAS("video", "vid"),
M_PROPERTY_ALIAS("audio", "aid"),
M_PROPERTY_ALIAS("sub", "sid"),
Expand Down Expand Up @@ -6609,7 +6726,7 @@ static void cmd_context_menu(void *p)
struct mp_cmd_ctx *cmd = p;
struct MPContext *mpctx = cmd->mpctx;
struct vo *vo = mpctx->video_out;

if (vo)
vo_control(vo, VOCTRL_SHOW_MENU, NULL);
}
Expand Down

0 comments on commit 99e1f27

Please sign in to comment.