xref: /qemu/ui/clipboard.c (revision d0fb9657)
1 #include "qemu/osdep.h"
2 #include "ui/clipboard.h"
3 
4 static NotifierList clipboard_notifiers =
5     NOTIFIER_LIST_INITIALIZER(clipboard_notifiers);
6 
7 void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
8 {
9     notifier_list_add(&clipboard_notifiers, &peer->update);
10 }
11 
12 void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
13 {
14     notifier_remove(&peer->update);
15 }
16 
17 void qemu_clipboard_update(QemuClipboardInfo *info)
18 {
19     notifier_list_notify(&clipboard_notifiers, info);
20 }
21 
22 QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner,
23                                            QemuClipboardSelection selection)
24 {
25     QemuClipboardInfo *info = g_new0(QemuClipboardInfo, 1);
26 
27     info->owner = owner;
28     info->selection = selection;
29     info->refcount = 1;
30 
31     return info;
32 }
33 
34 QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info)
35 {
36     info->refcount++;
37     return info;
38 }
39 
40 void qemu_clipboard_info_unref(QemuClipboardInfo *info)
41 {
42     uint32_t type;
43 
44     if (!info) {
45         return;
46     }
47 
48     info->refcount--;
49     if (info->refcount > 0) {
50         return;
51     }
52 
53     for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
54         g_free(info->types[type].data);
55     }
56     g_free(info);
57 }
58 
59 void qemu_clipboard_request(QemuClipboardInfo *info,
60                             QemuClipboardType type)
61 {
62     if (info->types[type].data ||
63         info->types[type].requested ||
64         !info->types[type].available ||
65         !info->owner)
66         return;
67 
68     info->types[type].requested = true;
69     info->owner->request(info, type);
70 }
71 
72 void qemu_clipboard_set_data(QemuClipboardPeer *peer,
73                              QemuClipboardInfo *info,
74                              QemuClipboardType type,
75                              uint32_t size,
76                              void *data,
77                              bool update)
78 {
79     if (!info ||
80         info->owner != peer) {
81         return;
82     }
83 
84     g_free(info->types[type].data);
85     info->types[type].data = g_memdup(data, size);
86     info->types[type].size = size;
87     info->types[type].available = true;
88 
89     if (update) {
90         qemu_clipboard_update(info);
91     }
92 }
93