|
@@ -65,12 +65,24 @@ bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client)
|
|
|
|
|
|
void qemu_clipboard_update(QemuClipboardInfo *info)
|
|
|
{
|
|
|
+ uint32_t type;
|
|
|
QemuClipboardNotify notify = {
|
|
|
.type = QEMU_CLIPBOARD_UPDATE_INFO,
|
|
|
.info = info,
|
|
|
};
|
|
|
assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT);
|
|
|
|
|
|
+ for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
|
|
|
+ /*
|
|
|
+ * If data is missing, the clipboard owner's 'request' callback needs to
|
|
|
+ * be set. Otherwise, there is no way to get the clipboard data and
|
|
|
+ * qemu_clipboard_request() cannot be called.
|
|
|
+ */
|
|
|
+ if (info->types[type].available && !info->types[type].data) {
|
|
|
+ assert(info->owner && info->owner->request);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
notifier_list_notify(&clipboard_notifiers, ¬ify);
|
|
|
|
|
|
if (cbinfo[info->selection] != info) {
|
|
@@ -132,6 +144,8 @@ void qemu_clipboard_request(QemuClipboardInfo *info,
|
|
|
!info->owner)
|
|
|
return;
|
|
|
|
|
|
+ assert(info->owner->request);
|
|
|
+
|
|
|
info->types[type].requested = true;
|
|
|
info->owner->request(info, type);
|
|
|
}
|
|
@@ -163,9 +177,15 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
|
|
|
}
|
|
|
|
|
|
g_free(info->types[type].data);
|
|
|
- info->types[type].data = g_memdup(data, size);
|
|
|
- info->types[type].size = size;
|
|
|
- info->types[type].available = true;
|
|
|
+ if (size) {
|
|
|
+ info->types[type].data = g_memdup2(data, size);
|
|
|
+ info->types[type].size = size;
|
|
|
+ info->types[type].available = true;
|
|
|
+ } else {
|
|
|
+ info->types[type].data = NULL;
|
|
|
+ info->types[type].size = 0;
|
|
|
+ info->types[type].available = false;
|
|
|
+ }
|
|
|
|
|
|
if (update) {
|
|
|
qemu_clipboard_update(info);
|