]>
Commit | Line | Data |
---|---|---|
660e8d0f GH |
1 | #include "qemu/osdep.h" |
2 | #include "ui/clipboard.h" | |
3 | ||
4 | static NotifierList clipboard_notifiers = | |
5 | NOTIFIER_LIST_INITIALIZER(clipboard_notifiers); | |
6 | ||
684e64d3 MAL |
7 | static QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__COUNT]; |
8 | ||
660e8d0f GH |
9 | void qemu_clipboard_peer_register(QemuClipboardPeer *peer) |
10 | { | |
1b17f1e9 | 11 | notifier_list_add(&clipboard_notifiers, &peer->notifier); |
660e8d0f GH |
12 | } |
13 | ||
14 | void 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 | } | |
1b17f1e9 | 21 | notifier_remove(&peer->notifier); |
660e8d0f GH |
22 | } |
23 | ||
482bbaf4 MAL |
24 | bool qemu_clipboard_peer_owns(QemuClipboardPeer *peer, |
25 | QemuClipboardSelection selection) | |
26 | { | |
27 | QemuClipboardInfo *info = qemu_clipboard_info(selection); | |
28 | ||
29 | return info && info->owner == peer; | |
30 | } | |
31 | ||
1387865e MAL |
32 | void qemu_clipboard_peer_release(QemuClipboardPeer *peer, |
33 | QemuClipboardSelection selection) | |
34 | { | |
35 | g_autoptr(QemuClipboardInfo) info = NULL; | |
36 | ||
37 | if (qemu_clipboard_peer_owns(peer, selection)) { | |
38 | /* set empty clipboard info */ | |
39 | info = qemu_clipboard_info_new(NULL, selection); | |
40 | qemu_clipboard_update(info); | |
41 | } | |
42 | } | |
43 | ||
349504e5 MAL |
44 | bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client) |
45 | { | |
46 | if (!info->has_serial || | |
47 | !cbinfo[info->selection] || | |
48 | !cbinfo[info->selection]->has_serial) { | |
49 | return true; | |
50 | } | |
51 | ||
52 | if (client) { | |
53 | return cbinfo[info->selection]->serial >= info->serial; | |
54 | } else { | |
55 | return cbinfo[info->selection]->serial > info->serial; | |
56 | } | |
57 | } | |
58 | ||
660e8d0f GH |
59 | void qemu_clipboard_update(QemuClipboardInfo *info) |
60 | { | |
1b17f1e9 MAL |
61 | QemuClipboardNotify notify = { |
62 | .type = QEMU_CLIPBOARD_UPDATE_INFO, | |
63 | .info = info, | |
64 | }; | |
684e64d3 MAL |
65 | assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT); |
66 | ||
1b17f1e9 | 67 | notifier_list_notify(&clipboard_notifiers, ¬ify); |
684e64d3 | 68 | |
70a54b01 | 69 | qemu_clipboard_info_unref(cbinfo[info->selection]); |
684e64d3 MAL |
70 | cbinfo[info->selection] = qemu_clipboard_info_ref(info); |
71 | } | |
72 | ||
73 | QemuClipboardInfo *qemu_clipboard_info(QemuClipboardSelection selection) | |
74 | { | |
75 | assert(selection < QEMU_CLIPBOARD_SELECTION__COUNT); | |
76 | ||
77 | return cbinfo[selection]; | |
660e8d0f GH |
78 | } |
79 | ||
80 | QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner, | |
81 | QemuClipboardSelection selection) | |
82 | { | |
83 | QemuClipboardInfo *info = g_new0(QemuClipboardInfo, 1); | |
84 | ||
85 | info->owner = owner; | |
86 | info->selection = selection; | |
87 | info->refcount = 1; | |
88 | ||
89 | return info; | |
90 | } | |
91 | ||
92 | QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info) | |
93 | { | |
94 | info->refcount++; | |
95 | return info; | |
96 | } | |
97 | ||
98 | void qemu_clipboard_info_unref(QemuClipboardInfo *info) | |
99 | { | |
100 | uint32_t type; | |
101 | ||
102 | if (!info) { | |
103 | return; | |
104 | } | |
105 | ||
106 | info->refcount--; | |
107 | if (info->refcount > 0) { | |
108 | return; | |
109 | } | |
110 | ||
111 | for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) { | |
112 | g_free(info->types[type].data); | |
113 | } | |
114 | g_free(info); | |
115 | } | |
116 | ||
117 | void qemu_clipboard_request(QemuClipboardInfo *info, | |
118 | QemuClipboardType type) | |
119 | { | |
120 | if (info->types[type].data || | |
121 | info->types[type].requested || | |
122 | !info->types[type].available || | |
123 | !info->owner) | |
124 | return; | |
125 | ||
126 | info->types[type].requested = true; | |
127 | info->owner->request(info, type); | |
128 | } | |
129 | ||
505dbf9b MAL |
130 | void qemu_clipboard_reset_serial(void) |
131 | { | |
132 | QemuClipboardNotify notify = { .type = QEMU_CLIPBOARD_RESET_SERIAL }; | |
133 | ||
134 | notifier_list_notify(&clipboard_notifiers, ¬ify); | |
135 | } | |
136 | ||
660e8d0f GH |
137 | void qemu_clipboard_set_data(QemuClipboardPeer *peer, |
138 | QemuClipboardInfo *info, | |
139 | QemuClipboardType type, | |
140 | uint32_t size, | |
7e3e20d8 | 141 | const void *data, |
660e8d0f GH |
142 | bool update) |
143 | { | |
144 | if (!info || | |
145 | info->owner != peer) { | |
146 | return; | |
147 | } | |
148 | ||
149 | g_free(info->types[type].data); | |
150 | info->types[type].data = g_memdup(data, size); | |
151 | info->types[type].size = size; | |
152 | info->types[type].available = true; | |
153 | ||
154 | if (update) { | |
155 | qemu_clipboard_update(info); | |
156 | } | |
157 | } |