Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-clipboard"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <gio/gio.h>
9 : : #include <libpeas.h>
10 : : #include <libvalent-core.h>
11 : :
12 : : #include "valent-clipboard.h"
13 : : #include "valent-clipboard-adapter.h"
14 : :
15 : :
16 : : /**
17 : : * ValentClipboard:
18 : : *
19 : : * A class for reading and writing the desktop clipboard.
20 : : *
21 : : * `ValentClipboard` is an abstraction of clipboard selections, intended for use
22 : : * by [class@Valent.DevicePlugin] implementations.
23 : : *
24 : : * Plugins can implement [class@Valent.ClipboardAdapter] to provide an interface
25 : : * to access a clipboard selection.
26 : : *
27 : : * Since: 1.0
28 : : */
29 : :
30 : : struct _ValentClipboard
31 : : {
32 : : ValentComponent parent_instance;
33 : :
34 : : ValentClipboardAdapter *default_adapter;
35 : : };
36 : :
37 [ + + + - ]: 235 : G_DEFINE_FINAL_TYPE (ValentClipboard, valent_clipboard, VALENT_TYPE_COMPONENT)
38 : :
39 : : enum {
40 : : CHANGED,
41 : : N_SIGNALS
42 : : };
43 : :
44 : : static guint signals[N_SIGNALS] = { 0, };
45 : :
46 : : static ValentClipboard *default_clipboard = NULL;
47 : :
48 : : static const char * const text_mimetypes[] = {
49 : : "text/plain;charset=utf-8",
50 : : "text/plain",
51 : : "UTF8_STRING",
52 : : "STRING",
53 : : "TEXT",
54 : : "COMPOUND_TEXT",
55 : : };
56 : :
57 : :
58 : : static void
59 : 2 : valent_clipboard_adapter_read_bytes_cb (ValentClipboardAdapter *adapter,
60 : : GAsyncResult *result,
61 : : gpointer user_data)
62 : : {
63 : 2 : g_autoptr (GTask) task = G_TASK (user_data);
64 [ - - + - ]: 2 : g_autoptr (GBytes) bytes = NULL;
65 [ - - + - ]: 2 : g_autoptr (GError) error = NULL;
66 : :
67 [ + - ]: 2 : g_assert (VALENT_IS_CLIPBOARD_ADAPTER (adapter));
68 [ - + ]: 2 : g_assert (g_task_is_valid (result, adapter));
69 : :
70 : 2 : bytes = valent_clipboard_adapter_read_bytes_finish (adapter, result, &error);
71 : :
72 [ - + ]: 2 : if (bytes == NULL)
73 [ # # ]: 0 : return g_task_return_error (task, g_steal_pointer (&error));
74 : :
75 [ - + ]: 2 : g_task_return_pointer (task,
76 : : g_steal_pointer (&bytes),
77 : : (GDestroyNotify)g_bytes_unref);
78 : : }
79 : :
80 : : static void
81 : 10 : valent_clipboard_adapter_write_bytes_cb (ValentClipboardAdapter *adapter,
82 : : GAsyncResult *result,
83 : : gpointer user_data)
84 : : {
85 : 10 : g_autoptr (GTask) task = G_TASK (user_data);
86 [ - - + - ]: 10 : g_autoptr (GError) error = NULL;
87 : :
88 [ + - ]: 10 : g_assert (VALENT_IS_CLIPBOARD_ADAPTER (adapter));
89 [ - + ]: 10 : g_assert (g_task_is_valid (result, adapter));
90 : :
91 [ - + ]: 10 : if (!valent_clipboard_adapter_write_bytes_finish (adapter, result, &error))
92 [ # # ]: 0 : return g_task_return_error (task, g_steal_pointer (&error));
93 : :
94 [ - + ]: 10 : g_task_return_boolean (task, TRUE);
95 : : }
96 : :
97 : : static void
98 : 15 : valent_clipboard_adapter_read_text_cb (ValentClipboardAdapter *adapter,
99 : : GAsyncResult *result,
100 : : gpointer user_data)
101 : : {
102 : 15 : g_autoptr (GTask) task = G_TASK (user_data);
103 [ - - + - ]: 15 : g_autoptr (GError) error = NULL;
104 [ - - - + ]: 15 : g_autoptr (GBytes) bytes = NULL;
105 : 15 : const char *data = NULL;
106 : 15 : size_t size;
107 : :
108 [ + - ]: 15 : g_assert (VALENT_IS_CLIPBOARD_ADAPTER (adapter));
109 [ - + ]: 15 : g_assert (g_task_is_valid (result, adapter));
110 : :
111 : 15 : bytes = valent_clipboard_adapter_read_bytes_finish (adapter, result, &error);
112 : :
113 [ - + ]: 15 : if (bytes == NULL)
114 [ # # ]: 0 : return g_task_return_error (task, g_steal_pointer (&error));
115 : :
116 : 15 : data = g_bytes_get_data (bytes, &size);
117 : :
118 [ + - + - ]: 15 : if (size > 0 && data[size - 1] == '\0')
119 [ - + ]: 30 : g_task_return_pointer (task, g_strdup (data), g_free);
120 : : else
121 : 0 : g_task_return_pointer (task, g_strndup (data, size), g_free);
122 : : }
123 : :
124 : : static void
125 : 14 : on_clipboard_adapter_changed (ValentClipboardAdapter *clipboard,
126 : : ValentClipboard *self)
127 : : {
128 : 14 : VALENT_ENTRY;
129 : :
130 [ + - ]: 14 : if (self->default_adapter == clipboard)
131 : 14 : g_signal_emit (G_OBJECT (self), signals [CHANGED], 0);
132 : :
133 : 14 : VALENT_EXIT;
134 : : }
135 : :
136 : : /*
137 : : * ValentComponent
138 : : */
139 : : static void
140 : 5 : valent_clipboard_bind_preferred (ValentComponent *component,
141 : : GObject *extension)
142 : : {
143 : 5 : ValentClipboard *self = VALENT_CLIPBOARD (component);
144 : 5 : ValentClipboardAdapter *adapter = VALENT_CLIPBOARD_ADAPTER (extension);
145 : :
146 : 5 : VALENT_ENTRY;
147 : :
148 [ + - ]: 5 : g_assert (VALENT_IS_CLIPBOARD (self));
149 [ + - - + ]: 5 : g_assert (adapter == NULL || VALENT_IS_CLIPBOARD_ADAPTER (adapter));
150 : :
151 [ - + ]: 5 : if (self->default_adapter != NULL)
152 : : {
153 : 0 : g_signal_handlers_disconnect_by_func (self->default_adapter,
154 : : self,
155 : : on_clipboard_adapter_changed);
156 : 0 : self->default_adapter = NULL;
157 : : }
158 : :
159 [ + - ]: 5 : if (adapter != NULL)
160 : : {
161 : 5 : self->default_adapter = adapter;
162 : 5 : g_signal_connect_object (self->default_adapter,
163 : : "changed",
164 : : G_CALLBACK (on_clipboard_adapter_changed),
165 : : self, 0);
166 : : }
167 : :
168 : 5 : VALENT_EXIT;
169 : : }
170 : :
171 : : /*
172 : : * GObject
173 : : */
174 : : static void
175 : 5 : valent_clipboard_class_init (ValentClipboardClass *klass)
176 : : {
177 : 5 : ValentComponentClass *component_class = VALENT_COMPONENT_CLASS (klass);
178 : :
179 : 5 : component_class->bind_preferred = valent_clipboard_bind_preferred;
180 : :
181 : : /**
182 : : * ValentClipboard::changed:
183 : : * @clipboard: a `ValentClipboard`
184 : : *
185 : : * Emitted when the content of the primary [class@Valent.ClipboardAdapter]
186 : : * changes.
187 : : *
188 : : * Since: 1.0
189 : : */
190 : 10 : signals [CHANGED] =
191 : 5 : g_signal_new ("changed",
192 : : G_TYPE_FROM_CLASS (klass),
193 : : G_SIGNAL_RUN_FIRST,
194 : : 0,
195 : : NULL, NULL, NULL,
196 : : G_TYPE_NONE, 0);
197 : 5 : }
198 : :
199 : : static void
200 : 5 : valent_clipboard_init (ValentClipboard *self)
201 : : {
202 : 5 : }
203 : :
204 : : /**
205 : : * valent_clipboard_get_default:
206 : : *
207 : : * Get the default [class@Valent.Clipboard].
208 : : *
209 : : * Returns: (transfer none) (not nullable): a `ValentClipboard`
210 : : *
211 : : * Since: 1.0
212 : : */
213 : : ValentClipboard *
214 : 19 : valent_clipboard_get_default (void)
215 : : {
216 [ + + ]: 19 : if (default_clipboard == NULL)
217 : : {
218 : 5 : default_clipboard = g_object_new (VALENT_TYPE_CLIPBOARD,
219 : : "plugin-domain", "clipboard",
220 : : "plugin-type", VALENT_TYPE_CLIPBOARD_ADAPTER,
221 : : NULL);
222 : :
223 : 5 : g_object_add_weak_pointer (G_OBJECT (default_clipboard),
224 : : (gpointer)&default_clipboard);
225 : : }
226 : :
227 : 19 : return default_clipboard;
228 : : }
229 : :
230 : : /**
231 : : * valent_clipboard_get_mimetypes:
232 : : * @clipboard: a `ValentClipboard`
233 : : *
234 : : * Get the mime-types of the primary clipboard content.
235 : : *
236 : : * Returns: (transfer full) (nullable) (array zero-terminated=1): a list of
237 : : * mime-types
238 : : *
239 : : * Since: 1.0
240 : : */
241 : : GStrv
242 : 4 : valent_clipboard_get_mimetypes (ValentClipboard *clipboard)
243 : : {
244 : 4 : GStrv ret = NULL;
245 : :
246 : 4 : VALENT_ENTRY;
247 : :
248 [ + - ]: 4 : g_return_val_if_fail (VALENT_IS_CLIPBOARD (clipboard), NULL);
249 : :
250 [ - + ]: 4 : if G_LIKELY (clipboard->default_adapter != NULL)
251 : 4 : ret = valent_clipboard_adapter_get_mimetypes (clipboard->default_adapter);
252 : :
253 : 4 : VALENT_RETURN (g_steal_pointer (&ret));
254 : : }
255 : :
256 : : /**
257 : : * valent_clipboard_get_timestamp:
258 : : * @clipboard: a `ValentClipboard`
259 : : *
260 : : * Get the timestamp of the current clipboard content, in milliseconds since the
261 : : * UNIX epoch.
262 : : *
263 : : * Returns: a UNIX epoch timestamp (ms)
264 : : *
265 : : * Since: 1.0
266 : : */
267 : : int64_t
268 : 15 : valent_clipboard_get_timestamp (ValentClipboard *clipboard)
269 : : {
270 : 15 : int64_t ret = 0;
271 : :
272 : 15 : VALENT_ENTRY;
273 : :
274 [ + - ]: 15 : g_return_val_if_fail (VALENT_IS_CLIPBOARD (clipboard), 0);
275 : :
276 [ - + ]: 15 : if G_LIKELY (clipboard->default_adapter != NULL)
277 : 15 : ret = valent_clipboard_adapter_get_timestamp (clipboard->default_adapter);
278 : :
279 : 15 : VALENT_RETURN (ret);
280 : : }
281 : :
282 : : /**
283 : : * valent_clipboard_read_bytes:
284 : : * @clipboard: a `ValentClipboard`
285 : : * @mimetype: a mime-type
286 : : * @cancellable: (nullable): a `GCancellable`
287 : : * @callback: (scope async): a `GAsyncReadyCallback`
288 : : * @user_data: user supplied data
289 : : *
290 : : * Get the content of the primary clipboard adapter.
291 : : *
292 : : * Call [method@Valent.Clipboard.read_bytes_finish] to get the result.
293 : : *
294 : : * Since: 1.0
295 : : */
296 : : void
297 : 2 : valent_clipboard_read_bytes (ValentClipboard *clipboard,
298 : : const char *mimetype,
299 : : GCancellable *cancellable,
300 : : GAsyncReadyCallback callback,
301 : : gpointer user_data)
302 : : {
303 : 4 : g_autoptr (GTask) task = NULL;
304 : :
305 : 2 : VALENT_ENTRY;
306 : :
307 [ + - ]: 2 : g_return_if_fail (VALENT_IS_CLIPBOARD (clipboard));
308 [ + - - + ]: 2 : g_return_if_fail (mimetype != NULL && *mimetype != '\0');
309 [ - + - - : 2 : g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- - - - ]
310 : :
311 [ + - ]: 2 : if G_UNLIKELY (clipboard->default_adapter == NULL)
312 : : {
313 : 0 : g_task_report_new_error (clipboard, callback, user_data,
314 : : valent_clipboard_read_bytes,
315 : : G_IO_ERROR,
316 : : G_IO_ERROR_NOT_SUPPORTED,
317 : : "No clipboard adapter available");
318 : 0 : return;
319 : : }
320 : :
321 : 2 : task = g_task_new (clipboard, cancellable, callback, user_data);
322 [ + - ]: 2 : g_task_set_source_tag (task, valent_clipboard_read_bytes);
323 : 2 : valent_clipboard_adapter_read_bytes (clipboard->default_adapter,
324 : : mimetype,
325 : : cancellable,
326 : : (GAsyncReadyCallback)valent_clipboard_adapter_read_bytes_cb,
327 : : g_steal_pointer (&task));
328 : :
329 : 2 : VALENT_EXIT;
330 : : }
331 : :
332 : : /**
333 : : * valent_clipboard_read_bytes_finish:
334 : : * @clipboard: a `ValentClipboard`
335 : : * @result: a `GAsyncResult`
336 : : * @error: (nullable): a `GError`
337 : : *
338 : : * Finish an operation started by [method@Valent.Clipboard.read_bytes].
339 : : *
340 : : * Returns: (transfer full) (nullable): the content
341 : : *
342 : : * Since: 1.0
343 : : */
344 : : GBytes *
345 : 2 : valent_clipboard_read_bytes_finish (ValentClipboard *clipboard,
346 : : GAsyncResult *result,
347 : : GError **error)
348 : : {
349 : 2 : GBytes *ret;
350 : :
351 : 2 : VALENT_ENTRY;
352 : :
353 [ + - ]: 2 : g_return_val_if_fail (VALENT_IS_CLIPBOARD (clipboard), NULL);
354 [ - + ]: 2 : g_return_val_if_fail (g_task_is_valid (result, clipboard), NULL);
355 [ + - - + ]: 2 : g_return_val_if_fail (error == NULL || *error == NULL, NULL);
356 : :
357 : 2 : ret = g_task_propagate_pointer (G_TASK (result), error);
358 : :
359 : 2 : VALENT_RETURN (g_steal_pointer (&ret));
360 : : }
361 : :
362 : : /**
363 : : * valent_clipboard_write_bytes:
364 : : * @clipboard: a `ValentClipboard`
365 : : * @mimetype: (nullable): a mime-type, or %NULL if @bytes is %NULL
366 : : * @bytes: (nullable): a `GBytes`, or %NULL if @mimetype is %NULL
367 : : * @cancellable: (nullable): a `GCancellable`
368 : : * @callback: (scope async): a `GAsyncReadyCallback`
369 : : * @user_data: user supplied data
370 : : *
371 : : * Set the content of the primary clipboard adapter.
372 : : *
373 : : * Call [method@Valent.Clipboard.write_bytes_finish] to get the result.
374 : : *
375 : : * Since: 1.0
376 : : */
377 : : void
378 : 2 : valent_clipboard_write_bytes (ValentClipboard *clipboard,
379 : : const char *mimetype,
380 : : GBytes *bytes,
381 : : GCancellable *cancellable,
382 : : GAsyncReadyCallback callback,
383 : : gpointer user_data)
384 : : {
385 : 4 : g_autoptr (GTask) task = NULL;
386 : :
387 : 2 : VALENT_ENTRY;
388 : :
389 [ + - ]: 2 : g_return_if_fail (VALENT_IS_CLIPBOARD (clipboard));
390 [ + - + - : 2 : g_return_if_fail (bytes == NULL || (mimetype != NULL && *mimetype != '\0'));
- + ]
391 [ - + - - : 2 : g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- - - - ]
392 : :
393 [ + - ]: 2 : if G_UNLIKELY (clipboard->default_adapter == NULL)
394 : : {
395 : 0 : g_task_report_new_error (clipboard, callback, user_data,
396 : : valent_clipboard_write_bytes,
397 : : G_IO_ERROR,
398 : : G_IO_ERROR_NOT_SUPPORTED,
399 : : "No clipboard adapter available");
400 : 0 : return;
401 : : }
402 : :
403 : 2 : task = g_task_new (clipboard, cancellable, callback, user_data);
404 [ + - ]: 2 : g_task_set_source_tag (task, valent_clipboard_write_bytes);
405 : 2 : valent_clipboard_adapter_write_bytes (clipboard->default_adapter,
406 : : mimetype,
407 : : bytes,
408 : : cancellable,
409 : : (GAsyncReadyCallback)valent_clipboard_adapter_write_bytes_cb,
410 : : g_steal_pointer (&task));
411 : :
412 : 2 : VALENT_EXIT;
413 : : }
414 : :
415 : : /**
416 : : * valent_clipboard_write_bytes_finish:
417 : : * @clipboard: a `ValentClipboard`
418 : : * @result: a `GAsyncResult`
419 : : * @error: (nullable): a `GError`
420 : : *
421 : : * Finish an operation started by [method@Valent.Clipboard.write_bytes].
422 : : *
423 : : * Returns: %TRUE if successful, or %FALSE with @error set
424 : : *
425 : : * Since: 1.0
426 : : */
427 : : gboolean
428 : 2 : valent_clipboard_write_bytes_finish (ValentClipboard *clipboard,
429 : : GAsyncResult *result,
430 : : GError **error)
431 : : {
432 : 2 : gboolean ret;
433 : :
434 : 2 : VALENT_ENTRY;
435 : :
436 [ + - ]: 2 : g_return_val_if_fail (VALENT_IS_CLIPBOARD (clipboard), FALSE);
437 [ - + ]: 2 : g_return_val_if_fail (g_task_is_valid (result, clipboard), FALSE);
438 [ + - - + ]: 2 : g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
439 : :
440 : 2 : ret = g_task_propagate_boolean (G_TASK (result), error);
441 : :
442 : 2 : VALENT_RETURN (ret);
443 : : }
444 : :
445 : : /**
446 : : * valent_clipboard_read_text:
447 : : * @clipboard: a `ValentClipboard`
448 : : * @cancellable: (nullable): a `GCancellable`
449 : : * @callback: (scope async): a `GAsyncReadyCallback`
450 : : * @user_data: user supplied data
451 : : *
452 : : * Get the text content of the primary clipboard adapter.
453 : : *
454 : : * Call [method@Valent.Clipboard.read_text_finish] to get the result.
455 : : *
456 : : * Since: 1.0
457 : : */
458 : : void
459 : 15 : valent_clipboard_read_text (ValentClipboard *clipboard,
460 : : GCancellable *cancellable,
461 : : GAsyncReadyCallback callback,
462 : : gpointer user_data)
463 : : {
464 : 30 : g_autoptr (GTask) task = NULL;
465 : 30 : g_auto (GStrv) mimetypes = NULL;
466 : 15 : const char *mimetype = NULL;
467 : :
468 : 15 : VALENT_ENTRY;
469 : :
470 [ + - ]: 15 : g_return_if_fail (VALENT_IS_CLIPBOARD (clipboard));
471 [ + + + - : 15 : g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- + - - ]
472 : :
473 [ + - ]: 15 : if G_UNLIKELY (clipboard->default_adapter == NULL)
474 : : {
475 : 0 : g_task_report_new_error (clipboard, callback, user_data,
476 : : valent_clipboard_read_text,
477 : : G_IO_ERROR,
478 : : G_IO_ERROR_NOT_SUPPORTED,
479 : : "No clipboard adapter available");
480 : 0 : return;
481 : : }
482 : :
483 : 15 : mimetypes = valent_clipboard_adapter_get_mimetypes (clipboard->default_adapter);
484 : :
485 [ + - ]: 15 : if (mimetypes != NULL)
486 : : {
487 [ + - ]: 15 : for (size_t i = 0; i < G_N_ELEMENTS (text_mimetypes); i++)
488 : : {
489 : 15 : const char *text_mimetype = text_mimetypes[i];
490 : :
491 [ - + ]: 15 : if (g_strv_contains ((const char * const *)mimetypes, text_mimetype))
492 : : {
493 : : mimetype = text_mimetypes[i];
494 : : break;
495 : : }
496 : : }
497 : : }
498 : :
499 [ - + ]: 15 : if (mimetype == NULL)
500 : 0 : return g_task_report_new_error (clipboard, callback, user_data,
501 : : valent_clipboard_read_text,
502 : : G_IO_ERROR,
503 : : G_IO_ERROR_NOT_SUPPORTED,
504 : : "text not available");
505 : :
506 : 15 : task = g_task_new (clipboard, cancellable, callback, user_data);
507 [ + - ]: 15 : g_task_set_source_tag (task, valent_clipboard_read_text);
508 : 15 : valent_clipboard_adapter_read_bytes (clipboard->default_adapter,
509 : : mimetype,
510 : : cancellable,
511 : : (GAsyncReadyCallback)valent_clipboard_adapter_read_text_cb,
512 : : g_steal_pointer (&task));
513 : :
514 [ + - ]: 30 : VALENT_EXIT;
515 : : }
516 : :
517 : : /**
518 : : * valent_clipboard_read_text_finish:
519 : : * @clipboard: a `ValentClipboard`
520 : : * @result: a `GAsyncResult`
521 : : * @error: (nullable): a `GError`
522 : : *
523 : : * Finish an operation started by [method@Valent.Clipboard.read_text].
524 : : *
525 : : * Returns: (transfer full) (nullable): the text content
526 : : *
527 : : * Since: 1.0
528 : : */
529 : : char *
530 : 15 : valent_clipboard_read_text_finish (ValentClipboard *clipboard,
531 : : GAsyncResult *result,
532 : : GError **error)
533 : : {
534 : 15 : char *ret;
535 : :
536 : 15 : VALENT_ENTRY;
537 : :
538 [ + - ]: 15 : g_return_val_if_fail (VALENT_IS_CLIPBOARD (clipboard), NULL);
539 [ - + ]: 15 : g_return_val_if_fail (g_task_is_valid (result, clipboard), NULL);
540 [ + - - + ]: 15 : g_return_val_if_fail (error == NULL || *error == NULL, NULL);
541 : :
542 : 15 : ret = g_task_propagate_pointer (G_TASK (result), error);
543 : :
544 : 15 : VALENT_RETURN (g_steal_pointer (&ret));
545 : : }
546 : :
547 : : /**
548 : : * valent_clipboard_write_text:
549 : : * @clipboard: a `ValentClipboard`
550 : : * @text: text content
551 : : * @cancellable: (nullable): a `GCancellable`
552 : : * @callback: (scope async): a `GAsyncReadyCallback`
553 : : * @user_data: user supplied data
554 : : *
555 : : * Set the text content of the primary clipboard adapter.
556 : : *
557 : : * Call [method@Valent.Clipboard.write_text_finish] to get the result.
558 : : *
559 : : * Since: 1.0
560 : : */
561 : : void
562 : 8 : valent_clipboard_write_text (ValentClipboard *clipboard,
563 : : const char *text,
564 : : GCancellable *cancellable,
565 : : GAsyncReadyCallback callback,
566 : : gpointer user_data)
567 : : {
568 : 16 : g_autoptr (GTask) task = NULL;
569 : 16 : g_autoptr (GBytes) bytes = NULL;
570 : :
571 : 8 : VALENT_ENTRY;
572 : :
573 [ + - ]: 8 : g_return_if_fail (VALENT_IS_CLIPBOARD (clipboard));
574 [ + + + - : 8 : g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- + - - ]
575 [ - + ]: 8 : g_return_if_fail (text != NULL);
576 : :
577 [ + - ]: 8 : if G_UNLIKELY (clipboard->default_adapter == NULL)
578 : : {
579 : 0 : g_task_report_new_error (clipboard, callback, user_data,
580 : : valent_clipboard_write_text,
581 : : G_IO_ERROR,
582 : : G_IO_ERROR_NOT_SUPPORTED,
583 : : "No clipboard adapter available");
584 : 0 : return;
585 : : }
586 : :
587 : 8 : task = g_task_new (clipboard, cancellable, callback, user_data);
588 [ + - ]: 8 : g_task_set_source_tag (task, valent_clipboard_write_text);
589 : :
590 : 8 : bytes = g_bytes_new (text, strlen (text) + 1);
591 : 8 : valent_clipboard_adapter_write_bytes (clipboard->default_adapter,
592 : : "text/plain;charset=utf-8",
593 : : bytes,
594 : : cancellable,
595 : : (GAsyncReadyCallback)valent_clipboard_adapter_write_bytes_cb,
596 : : g_steal_pointer (&task));
597 : :
598 [ + - ]: 8 : VALENT_EXIT;
599 : : }
600 : :
601 : : /**
602 : : * valent_clipboard_write_text_finish:
603 : : * @clipboard: a `ValentClipboard`
604 : : * @result: a `GAsyncResult`
605 : : * @error: (nullable): a `GError`
606 : : *
607 : : * Finish an operation started by [method@Valent.Clipboard.write_text].
608 : : *
609 : : * Returns: %TRUE if successful, or %FALSE with @error set
610 : : *
611 : : * Since: 1.0
612 : : */
613 : : gboolean
614 : 6 : valent_clipboard_write_text_finish (ValentClipboard *clipboard,
615 : : GAsyncResult *result,
616 : : GError **error)
617 : : {
618 : 6 : gboolean ret;
619 : :
620 : 6 : VALENT_ENTRY;
621 : :
622 [ + - ]: 6 : g_return_val_if_fail (VALENT_IS_CLIPBOARD (clipboard), FALSE);
623 [ - + ]: 6 : g_return_val_if_fail (g_task_is_valid (result, clipboard), FALSE);
624 [ + - - + ]: 6 : g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
625 : :
626 : 6 : ret = g_task_propagate_boolean (G_TASK (result), error);
627 : :
628 : 6 : VALENT_RETURN (ret);
629 : : }
630 : :
|