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