1 #include "qemu/osdep.h"
2 #include "ui/clipboard.h"
4 static NotifierList clipboard_notifiers
=
5 NOTIFIER_LIST_INITIALIZER(clipboard_notifiers
);
7 static QemuClipboardInfo
*cbinfo
[QEMU_CLIPBOARD_SELECTION__COUNT
];
9 void qemu_clipboard_peer_register(QemuClipboardPeer
*peer
)
11 notifier_list_add(&clipboard_notifiers
, &peer
->notifier
);
14 void qemu_clipboard_peer_unregister(QemuClipboardPeer
*peer
)
18 for (i
= 0; i
< QEMU_CLIPBOARD_SELECTION__COUNT
; i
++) {
19 qemu_clipboard_peer_release(peer
, i
);
21 notifier_remove(&peer
->notifier
);
24 bool qemu_clipboard_peer_owns(QemuClipboardPeer
*peer
,
25 QemuClipboardSelection selection
)
27 QemuClipboardInfo
*info
= qemu_clipboard_info(selection
);
29 return info
&& info
->owner
== peer
;
32 void qemu_clipboard_peer_release(QemuClipboardPeer
*peer
,
33 QemuClipboardSelection selection
)
35 g_autoptr(QemuClipboardInfo
) info
= NULL
;
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
);
44 bool qemu_clipboard_check_serial(QemuClipboardInfo
*info
, bool client
)
46 if (!info
->has_serial
||
47 !cbinfo
[info
->selection
] ||
48 !cbinfo
[info
->selection
]->has_serial
) {
53 return cbinfo
[info
->selection
]->serial
>= info
->serial
;
55 return cbinfo
[info
->selection
]->serial
> info
->serial
;
59 void qemu_clipboard_update(QemuClipboardInfo
*info
)
61 QemuClipboardNotify notify
= {
62 .type
= QEMU_CLIPBOARD_UPDATE_INFO
,
65 assert(info
->selection
< QEMU_CLIPBOARD_SELECTION__COUNT
);
67 notifier_list_notify(&clipboard_notifiers
, ¬ify
);
69 if (cbinfo
[info
->selection
] != info
) {
70 qemu_clipboard_info_unref(cbinfo
[info
->selection
]);
71 cbinfo
[info
->selection
] = qemu_clipboard_info_ref(info
);
75 QemuClipboardInfo
*qemu_clipboard_info(QemuClipboardSelection selection
)
77 assert(selection
< QEMU_CLIPBOARD_SELECTION__COUNT
);
79 return cbinfo
[selection
];
82 QemuClipboardInfo
*qemu_clipboard_info_new(QemuClipboardPeer
*owner
,
83 QemuClipboardSelection selection
)
85 QemuClipboardInfo
*info
= g_new0(QemuClipboardInfo
, 1);
88 info
->selection
= selection
;
94 QemuClipboardInfo
*qemu_clipboard_info_ref(QemuClipboardInfo
*info
)
100 void qemu_clipboard_info_unref(QemuClipboardInfo
*info
)
109 if (info
->refcount
> 0) {
113 for (type
= 0; type
< QEMU_CLIPBOARD_TYPE__COUNT
; type
++) {
114 g_free(info
->types
[type
].data
);
119 void qemu_clipboard_request(QemuClipboardInfo
*info
,
120 QemuClipboardType type
)
122 if (info
->types
[type
].data
||
123 info
->types
[type
].requested
||
124 !info
->types
[type
].available
||
128 info
->types
[type
].requested
= true;
129 info
->owner
->request(info
, type
);
132 void qemu_clipboard_reset_serial(void)
134 QemuClipboardNotify notify
= { .type
= QEMU_CLIPBOARD_RESET_SERIAL
};
136 notifier_list_notify(&clipboard_notifiers
, ¬ify
);
139 void qemu_clipboard_set_data(QemuClipboardPeer
*peer
,
140 QemuClipboardInfo
*info
,
141 QemuClipboardType type
,
147 info
->owner
!= peer
) {
151 g_free(info
->types
[type
].data
);
152 info
->types
[type
].data
= g_memdup(data
, size
);
153 info
->types
[type
].size
= size
;
154 info
->types
[type
].available
= true;
157 qemu_clipboard_update(info
);