]> git.proxmox.com Git - mirror_qemu.git/blame - ui/clipboard.c
ui/console: replace kbd_timer with chr_accept_input callback
[mirror_qemu.git] / ui / clipboard.c
CommitLineData
660e8d0f
GH
1#include "qemu/osdep.h"
2#include "ui/clipboard.h"
3
4static NotifierList clipboard_notifiers =
5 NOTIFIER_LIST_INITIALIZER(clipboard_notifiers);
6
684e64d3
MAL
7static QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__COUNT];
8
660e8d0f
GH
9void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
10{
11 notifier_list_add(&clipboard_notifiers, &peer->update);
12}
13
14void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
15{
7424bfaa
MAL
16 int i;
17
18 for (i = 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) {
19 qemu_clipboard_peer_release(peer, i);
20 }
21
660e8d0f
GH
22 notifier_remove(&peer->update);
23}
24
482bbaf4
MAL
25bool 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
1387865e
MAL
33void 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
660e8d0f
GH
45void qemu_clipboard_update(QemuClipboardInfo *info)
46{
684e64d3
MAL
47 g_autoptr(QemuClipboardInfo) old = NULL;
48 assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT);
49
660e8d0f 50 notifier_list_notify(&clipboard_notifiers, info);
684e64d3
MAL
51
52 old = cbinfo[info->selection];
53 cbinfo[info->selection] = qemu_clipboard_info_ref(info);
54}
55
56QemuClipboardInfo *qemu_clipboard_info(QemuClipboardSelection selection)
57{
58 assert(selection < QEMU_CLIPBOARD_SELECTION__COUNT);
59
60 return cbinfo[selection];
660e8d0f
GH
61}
62
63QemuClipboardInfo *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
75QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info)
76{
77 info->refcount++;
78 return info;
79}
80
81void 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
100void 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
113void qemu_clipboard_set_data(QemuClipboardPeer *peer,
114 QemuClipboardInfo *info,
115 QemuClipboardType type,
116 uint32_t size,
7e3e20d8 117 const void *data,
660e8d0f
GH
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}