]> git.proxmox.com Git - mirror_qemu.git/blob - ui/clipboard.c
update seabios to master branch snapshot
[mirror_qemu.git] / ui / clipboard.c
1 #include "qemu/osdep.h"
2 #include "ui/clipboard.h"
3
4 static NotifierList clipboard_notifiers =
5 NOTIFIER_LIST_INITIALIZER(clipboard_notifiers);
6
7 static QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__COUNT];
8
9 void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
10 {
11 notifier_list_add(&clipboard_notifiers, &peer->update);
12 }
13
14 void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
15 {
16 int i;
17
18 for (i = 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) {
19 qemu_clipboard_peer_release(peer, i);
20 }
21
22 notifier_remove(&peer->update);
23 }
24
25 bool qemu_clipboard_peer_owns(QemuClipboardPeer *peer,
26 QemuClipboardSelection selection)
27 {
28 QemuClipboardInfo *info = qemu_clipboard_info(selection);
29
30 return info && info->owner == peer;
31 }
32
33 void qemu_clipboard_peer_release(QemuClipboardPeer *peer,
34 QemuClipboardSelection selection)
35 {
36 g_autoptr(QemuClipboardInfo) info = NULL;
37
38 if (qemu_clipboard_peer_owns(peer, selection)) {
39 /* set empty clipboard info */
40 info = qemu_clipboard_info_new(NULL, selection);
41 qemu_clipboard_update(info);
42 }
43 }
44
45 void qemu_clipboard_update(QemuClipboardInfo *info)
46 {
47 g_autoptr(QemuClipboardInfo) old = NULL;
48 assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT);
49
50 notifier_list_notify(&clipboard_notifiers, info);
51
52 old = cbinfo[info->selection];
53 cbinfo[info->selection] = qemu_clipboard_info_ref(info);
54 }
55
56 QemuClipboardInfo *qemu_clipboard_info(QemuClipboardSelection selection)
57 {
58 assert(selection < QEMU_CLIPBOARD_SELECTION__COUNT);
59
60 return cbinfo[selection];
61 }
62
63 QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner,
64 QemuClipboardSelection selection)
65 {
66 QemuClipboardInfo *info = g_new0(QemuClipboardInfo, 1);
67
68 info->owner = owner;
69 info->selection = selection;
70 info->refcount = 1;
71
72 return info;
73 }
74
75 QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info)
76 {
77 info->refcount++;
78 return info;
79 }
80
81 void qemu_clipboard_info_unref(QemuClipboardInfo *info)
82 {
83 uint32_t type;
84
85 if (!info) {
86 return;
87 }
88
89 info->refcount--;
90 if (info->refcount > 0) {
91 return;
92 }
93
94 for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
95 g_free(info->types[type].data);
96 }
97 g_free(info);
98 }
99
100 void qemu_clipboard_request(QemuClipboardInfo *info,
101 QemuClipboardType type)
102 {
103 if (info->types[type].data ||
104 info->types[type].requested ||
105 !info->types[type].available ||
106 !info->owner)
107 return;
108
109 info->types[type].requested = true;
110 info->owner->request(info, type);
111 }
112
113 void qemu_clipboard_set_data(QemuClipboardPeer *peer,
114 QemuClipboardInfo *info,
115 QemuClipboardType type,
116 uint32_t size,
117 const void *data,
118 bool update)
119 {
120 if (!info ||
121 info->owner != peer) {
122 return;
123 }
124
125 g_free(info->types[type].data);
126 info->types[type].data = g_memdup(data, size);
127 info->types[type].size = size;
128 info->types[type].available = true;
129
130 if (update) {
131 qemu_clipboard_update(info);
132 }
133 }