/src/mpv/player/clipboard/clipboard.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * This file is part of mpv. |
3 | | * |
4 | | * mpv is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU Lesser General Public |
6 | | * License as published by the Free Software Foundation; either |
7 | | * version 2.1 of the License, or (at your option) any later version. |
8 | | * |
9 | | * mpv is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | * GNU Lesser General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Lesser General Public |
15 | | * License along with mpv. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | |
18 | | #include "clipboard.h" |
19 | | |
20 | | #include "common/common.h" |
21 | | #include "common/global.h" |
22 | | #include "options/m_config.h" |
23 | | #include "player/core.h" |
24 | | |
25 | | struct clipboard_opts { |
26 | | bool monitor; |
27 | | struct m_obj_settings *backends; |
28 | | }; |
29 | | |
30 | | // backend list |
31 | | extern const struct clipboard_backend clipboard_backend_win32; |
32 | | extern const struct clipboard_backend clipboard_backend_mac; |
33 | | extern const struct clipboard_backend clipboard_backend_wayland; |
34 | | extern const struct clipboard_backend clipboard_backend_vo; |
35 | | |
36 | | static const struct clipboard_backend *const clipboard_backend_list[] = { |
37 | | #if HAVE_WIN32_DESKTOP |
38 | | &clipboard_backend_win32, |
39 | | #endif |
40 | | #if HAVE_COCOA |
41 | | &clipboard_backend_mac, |
42 | | #endif |
43 | | #if HAVE_WAYLAND_PROTOCOLS_1_39 |
44 | | &clipboard_backend_wayland, |
45 | | #endif |
46 | | &clipboard_backend_vo, |
47 | | }; |
48 | | |
49 | | static bool get_desc(struct m_obj_desc *dst, int index) |
50 | 356k | { |
51 | 356k | if (index >= MP_ARRAY_SIZE(clipboard_backend_list)) |
52 | 178k | return false; |
53 | 178k | const struct clipboard_backend *backend = clipboard_backend_list[index]; |
54 | 178k | *dst = (struct m_obj_desc) { |
55 | 178k | .name = backend->name, |
56 | 178k | .description = backend->desc, |
57 | 178k | }; |
58 | 178k | return true; |
59 | 356k | } |
60 | | |
61 | | static const struct m_obj_list backend_obj_list = { |
62 | | .get_desc = get_desc, |
63 | | .description = "clipboard backends", |
64 | | .allow_trailer = true, |
65 | | .disallow_positional_parameters = true, |
66 | | .use_global_options = true, |
67 | | }; |
68 | | |
69 | | #define OPT_BASE_STRUCT struct clipboard_opts |
70 | | const struct m_sub_options clipboard_conf = { |
71 | | .opts = (const struct m_option[]) { |
72 | | {"monitor", OPT_BOOL(monitor), .flags = UPDATE_CLIPBOARD}, |
73 | | {"backends", OPT_SETTINGSLIST(backends, &backend_obj_list), |
74 | | .flags = UPDATE_CLIPBOARD}, |
75 | | {0} |
76 | | }, |
77 | | .defaults = &(const struct clipboard_opts) { |
78 | | .backends = (struct m_obj_settings[]) { |
79 | | {.name = "win32", .enabled = true}, |
80 | | {.name = "mac", .enabled = true}, |
81 | | {.name = "wayland", .enabled = true}, |
82 | | {.name = "vo", .enabled = true}, |
83 | | {0} |
84 | | } |
85 | | }, |
86 | | .size = sizeof(struct clipboard_opts) |
87 | | }; |
88 | | |
89 | | struct clipboard_ctx *mp_clipboard_create(struct clipboard_init_params *params, |
90 | | struct mpv_global *global) |
91 | 160k | { |
92 | 160k | struct clipboard_ctx *cl = talloc_ptrtype(NULL, cl); |
93 | 160k | *cl = (struct clipboard_ctx) { |
94 | 160k | .log = mp_log_new(cl, global->log, "clipboard"), |
95 | 160k | .monitor = params->flags & CLIPBOARD_INIT_ENABLE_MONITORING, |
96 | 160k | }; |
97 | | |
98 | 642k | for (int n = 0; params->backends && params->backends[n].name; n++) { |
99 | 642k | if (!params->backends[n].enabled) |
100 | 0 | continue; |
101 | 1.12M | for (int i = 0; i < MP_ARRAY_SIZE(clipboard_backend_list); i++) { |
102 | 642k | const struct clipboard_backend *backend = clipboard_backend_list[i]; |
103 | 642k | if (strcmp(params->backends[n].name, backend->name)) |
104 | 481k | continue; |
105 | 160k | if (backend->init(cl, params) != CLIPBOARD_SUCCESS) |
106 | 0 | break; |
107 | 160k | cl->backend = backend; |
108 | 160k | goto success; |
109 | 160k | } |
110 | 642k | } |
111 | | |
112 | 0 | MP_WARN(cl, "Failed to initialize any clipboard backend.\n"); |
113 | 0 | talloc_free(cl); |
114 | 0 | return NULL; |
115 | 160k | success: |
116 | 160k | MP_VERBOSE(cl, "Initialized %s clipboard backend.\n", cl->backend->name); |
117 | 160k | return cl; |
118 | 160k | } |
119 | | |
120 | | void mp_clipboard_destroy(struct clipboard_ctx *cl) |
121 | 338k | { |
122 | 338k | if (cl && cl->backend->uninit) |
123 | 0 | cl->backend->uninit(cl); |
124 | 338k | talloc_free(cl); |
125 | 338k | } |
126 | | |
127 | | bool mp_clipboard_data_changed(struct clipboard_ctx *cl) |
128 | 8.91M | { |
129 | 8.91M | if (cl && cl->backend->data_changed && cl->monitor) |
130 | 0 | return cl->backend->data_changed(cl); |
131 | 8.91M | return false; |
132 | 8.91M | } |
133 | | |
134 | | int mp_clipboard_get_data(struct clipboard_ctx *cl, struct clipboard_access_params *params, |
135 | | struct clipboard_data *out, void *talloc_ctx) |
136 | 161 | { |
137 | 161 | if (cl && cl->backend->get_data) |
138 | 0 | return cl->backend->get_data(cl, params, out, talloc_ctx); |
139 | 161 | return CLIPBOARD_UNAVAILABLE; |
140 | 161 | } |
141 | | |
142 | | int mp_clipboard_set_data(struct clipboard_ctx *cl, struct clipboard_access_params *params, |
143 | | struct clipboard_data *data) |
144 | 0 | { |
145 | 0 | if (cl && cl->backend->set_data) |
146 | 0 | return cl->backend->set_data(cl, params, data); |
147 | 0 | return CLIPBOARD_UNAVAILABLE; |
148 | 0 | } |
149 | | |
150 | | const char *mp_clipboard_get_backend_name(struct clipboard_ctx *cl) |
151 | 24 | { |
152 | 24 | return cl ? cl->backend->name : NULL; |
153 | 24 | } |
154 | | |
155 | | void reinit_clipboard(struct MPContext *mpctx) |
156 | 160k | { |
157 | 160k | mp_clipboard_destroy(mpctx->clipboard); |
158 | 160k | mpctx->clipboard = NULL; |
159 | | |
160 | 160k | struct clipboard_opts *opts = mp_get_config_group(NULL, mpctx->global, &clipboard_conf); |
161 | 160k | if (opts->backends && opts->backends[0].name) { |
162 | 160k | struct clipboard_init_params params = { |
163 | 160k | .mpctx = mpctx, |
164 | 160k | .flags = opts->monitor ? CLIPBOARD_INIT_ENABLE_MONITORING : 0, |
165 | 160k | .backends = opts->backends, |
166 | 160k | }; |
167 | 160k | mpctx->clipboard = mp_clipboard_create(¶ms, mpctx->global); |
168 | 160k | } |
169 | 160k | talloc_free(opts); |
170 | 160k | } |