ui: generalize clipboard notifier
Use a QemuClipboardNotify union type for extendable clipboard events. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
5912745288
commit
1b17f1e9f9
@ -20,8 +20,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum QemuClipboardType QemuClipboardType;
|
typedef enum QemuClipboardType QemuClipboardType;
|
||||||
|
typedef enum QemuClipboardNotifyType QemuClipboardNotifyType;
|
||||||
typedef enum QemuClipboardSelection QemuClipboardSelection;
|
typedef enum QemuClipboardSelection QemuClipboardSelection;
|
||||||
typedef struct QemuClipboardPeer QemuClipboardPeer;
|
typedef struct QemuClipboardPeer QemuClipboardPeer;
|
||||||
|
typedef struct QemuClipboardNotify QemuClipboardNotify;
|
||||||
typedef struct QemuClipboardInfo QemuClipboardInfo;
|
typedef struct QemuClipboardInfo QemuClipboardInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,18 +57,44 @@ enum QemuClipboardSelection {
|
|||||||
* struct QemuClipboardPeer
|
* struct QemuClipboardPeer
|
||||||
*
|
*
|
||||||
* @name: peer name.
|
* @name: peer name.
|
||||||
* @update: notifier for clipboard updates.
|
* @notifier: notifier for clipboard updates.
|
||||||
* @request: callback for clipboard data requests.
|
* @request: callback for clipboard data requests.
|
||||||
*
|
*
|
||||||
* Clipboard peer description.
|
* Clipboard peer description.
|
||||||
*/
|
*/
|
||||||
struct QemuClipboardPeer {
|
struct QemuClipboardPeer {
|
||||||
const char *name;
|
const char *name;
|
||||||
Notifier update;
|
Notifier notifier;
|
||||||
void (*request)(QemuClipboardInfo *info,
|
void (*request)(QemuClipboardInfo *info,
|
||||||
QemuClipboardType type);
|
QemuClipboardType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum QemuClipboardNotifyType
|
||||||
|
*
|
||||||
|
* @QEMU_CLIPBOARD_UPDATE_INFO: clipboard info update
|
||||||
|
*
|
||||||
|
* Clipboard notify type.
|
||||||
|
*/
|
||||||
|
enum QemuClipboardNotifyType {
|
||||||
|
QEMU_CLIPBOARD_UPDATE_INFO,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct QemuClipboardNotify
|
||||||
|
*
|
||||||
|
* @type: the type of event.
|
||||||
|
* @info: a QemuClipboardInfo event.
|
||||||
|
*
|
||||||
|
* Clipboard notify data.
|
||||||
|
*/
|
||||||
|
struct QemuClipboardNotify {
|
||||||
|
QemuClipboardNotifyType type;
|
||||||
|
union {
|
||||||
|
QemuClipboardInfo *info;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct QemuClipboardInfo
|
* struct QemuClipboardInfo
|
||||||
*
|
*
|
||||||
|
@ -8,7 +8,7 @@ static QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__COUNT];
|
|||||||
|
|
||||||
void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
|
void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
|
||||||
{
|
{
|
||||||
notifier_list_add(&clipboard_notifiers, &peer->update);
|
notifier_list_add(&clipboard_notifiers, &peer->notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
|
void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
|
||||||
@ -18,8 +18,7 @@ void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
|
|||||||
for (i = 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) {
|
for (i = 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) {
|
||||||
qemu_clipboard_peer_release(peer, i);
|
qemu_clipboard_peer_release(peer, i);
|
||||||
}
|
}
|
||||||
|
notifier_remove(&peer->notifier);
|
||||||
notifier_remove(&peer->update);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qemu_clipboard_peer_owns(QemuClipboardPeer *peer,
|
bool qemu_clipboard_peer_owns(QemuClipboardPeer *peer,
|
||||||
@ -44,10 +43,15 @@ void qemu_clipboard_peer_release(QemuClipboardPeer *peer,
|
|||||||
|
|
||||||
void qemu_clipboard_update(QemuClipboardInfo *info)
|
void qemu_clipboard_update(QemuClipboardInfo *info)
|
||||||
{
|
{
|
||||||
|
QemuClipboardNotify notify = {
|
||||||
|
.type = QEMU_CLIPBOARD_UPDATE_INFO,
|
||||||
|
.info = info,
|
||||||
|
};
|
||||||
g_autoptr(QemuClipboardInfo) old = NULL;
|
g_autoptr(QemuClipboardInfo) old = NULL;
|
||||||
|
|
||||||
assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT);
|
assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT);
|
||||||
|
|
||||||
notifier_list_notify(&clipboard_notifiers, info);
|
notifier_list_notify(&clipboard_notifiers, ¬ify);
|
||||||
|
|
||||||
old = cbinfo[info->selection];
|
old = cbinfo[info->selection];
|
||||||
cbinfo[info->selection] = qemu_clipboard_info_ref(info);
|
cbinfo[info->selection] = qemu_clipboard_info_ref(info);
|
||||||
|
17
ui/cocoa.m
17
ui/cocoa.m
@ -1808,14 +1808,12 @@ static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
|||||||
|
|
||||||
static QemuClipboardPeer cbpeer = {
|
static QemuClipboardPeer cbpeer = {
|
||||||
.name = "cocoa",
|
.name = "cocoa",
|
||||||
.update = { .notify = cocoa_clipboard_notify },
|
.notifier = { .notify = cocoa_clipboard_notify },
|
||||||
.request = cocoa_clipboard_request
|
.request = cocoa_clipboard_request
|
||||||
};
|
};
|
||||||
|
|
||||||
static void cocoa_clipboard_notify(Notifier *notifier, void *data)
|
static void cocoa_clipboard_update_info(QemuClipboardInfo *info)
|
||||||
{
|
{
|
||||||
QemuClipboardInfo *info = data;
|
|
||||||
|
|
||||||
if (info->owner == &cbpeer || info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
|
if (info->owner == &cbpeer || info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1831,6 +1829,17 @@ static void cocoa_clipboard_notify(Notifier *notifier, void *data)
|
|||||||
qemu_event_set(&cbevent);
|
qemu_event_set(&cbevent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cocoa_clipboard_notify(Notifier *notifier, void *data)
|
||||||
|
{
|
||||||
|
QemuClipboardNotify *notify = data;
|
||||||
|
|
||||||
|
switch (notify->type) {
|
||||||
|
case QEMU_CLIPBOARD_UPDATE_INFO:
|
||||||
|
cocoa_clipboard_update_info(notify->info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
||||||
QemuClipboardType type)
|
QemuClipboardType type)
|
||||||
{
|
{
|
||||||
|
@ -74,10 +74,9 @@ static void gd_clipboard_clear(GtkClipboard *clipboard,
|
|||||||
gd->cbowner[s] = false;
|
gd->cbowner[s] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gd_clipboard_notify(Notifier *notifier, void *data)
|
static void gd_clipboard_update_info(GtkDisplayState *gd,
|
||||||
|
QemuClipboardInfo *info)
|
||||||
{
|
{
|
||||||
GtkDisplayState *gd = container_of(notifier, GtkDisplayState, cbpeer.update);
|
|
||||||
QemuClipboardInfo *info = data;
|
|
||||||
QemuClipboardSelection s = info->selection;
|
QemuClipboardSelection s = info->selection;
|
||||||
bool self_update = info->owner == &gd->cbpeer;
|
bool self_update = info->owner == &gd->cbpeer;
|
||||||
|
|
||||||
@ -118,6 +117,19 @@ static void gd_clipboard_notify(Notifier *notifier, void *data)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gd_clipboard_notify(Notifier *notifier, void *data)
|
||||||
|
{
|
||||||
|
GtkDisplayState *gd =
|
||||||
|
container_of(notifier, GtkDisplayState, cbpeer.notifier);
|
||||||
|
QemuClipboardNotify *notify = data;
|
||||||
|
|
||||||
|
switch (notify->type) {
|
||||||
|
case QEMU_CLIPBOARD_UPDATE_INFO:
|
||||||
|
gd_clipboard_update_info(gd, notify->info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void gd_clipboard_request(QemuClipboardInfo *info,
|
static void gd_clipboard_request(QemuClipboardInfo *info,
|
||||||
QemuClipboardType type)
|
QemuClipboardType type)
|
||||||
{
|
{
|
||||||
@ -172,7 +184,7 @@ static void gd_owner_change(GtkClipboard *clipboard,
|
|||||||
void gd_clipboard_init(GtkDisplayState *gd)
|
void gd_clipboard_init(GtkDisplayState *gd)
|
||||||
{
|
{
|
||||||
gd->cbpeer.name = "gtk";
|
gd->cbpeer.name = "gtk";
|
||||||
gd->cbpeer.update.notify = gd_clipboard_notify;
|
gd->cbpeer.notifier.notify = gd_clipboard_notify;
|
||||||
gd->cbpeer.request = gd_clipboard_request;
|
gd->cbpeer.request = gd_clipboard_request;
|
||||||
qemu_clipboard_peer_register(&gd->cbpeer);
|
qemu_clipboard_peer_register(&gd->cbpeer);
|
||||||
|
|
||||||
|
27
ui/vdagent.c
27
ui/vdagent.c
@ -417,10 +417,9 @@ static void vdagent_send_empty_clipboard_data(VDAgentChardev *vd,
|
|||||||
vdagent_send_clipboard_data(vd, info, type);
|
vdagent_send_clipboard_data(vd, info, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vdagent_clipboard_notify(Notifier *notifier, void *data)
|
static void vdagent_clipboard_update_info(VDAgentChardev *vd,
|
||||||
|
QemuClipboardInfo *info)
|
||||||
{
|
{
|
||||||
VDAgentChardev *vd = container_of(notifier, VDAgentChardev, cbpeer.update);
|
|
||||||
QemuClipboardInfo *info = data;
|
|
||||||
QemuClipboardSelection s = info->selection;
|
QemuClipboardSelection s = info->selection;
|
||||||
QemuClipboardType type;
|
QemuClipboardType type;
|
||||||
bool self_update = info->owner == &vd->cbpeer;
|
bool self_update = info->owner == &vd->cbpeer;
|
||||||
@ -449,6 +448,19 @@ static void vdagent_clipboard_notify(Notifier *notifier, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vdagent_clipboard_notify(Notifier *notifier, void *data)
|
||||||
|
{
|
||||||
|
VDAgentChardev *vd =
|
||||||
|
container_of(notifier, VDAgentChardev, cbpeer.notifier);
|
||||||
|
QemuClipboardNotify *notify = data;
|
||||||
|
|
||||||
|
switch (notify->type) {
|
||||||
|
case QEMU_CLIPBOARD_UPDATE_INFO:
|
||||||
|
vdagent_clipboard_update_info(vd, notify->info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void vdagent_clipboard_request(QemuClipboardInfo *info,
|
static void vdagent_clipboard_request(QemuClipboardInfo *info,
|
||||||
QemuClipboardType qtype)
|
QemuClipboardType qtype)
|
||||||
{
|
{
|
||||||
@ -658,9 +670,9 @@ static void vdagent_chr_recv_caps(VDAgentChardev *vd, VDAgentMessage *msg)
|
|||||||
if (have_mouse(vd) && vd->mouse_hs) {
|
if (have_mouse(vd) && vd->mouse_hs) {
|
||||||
qemu_input_handler_activate(vd->mouse_hs);
|
qemu_input_handler_activate(vd->mouse_hs);
|
||||||
}
|
}
|
||||||
if (have_clipboard(vd) && vd->cbpeer.update.notify == NULL) {
|
if (have_clipboard(vd) && vd->cbpeer.notifier.notify == NULL) {
|
||||||
vd->cbpeer.name = "vdagent";
|
vd->cbpeer.name = "vdagent";
|
||||||
vd->cbpeer.update.notify = vdagent_clipboard_notify;
|
vd->cbpeer.notifier.notify = vdagent_clipboard_notify;
|
||||||
vd->cbpeer.request = vdagent_clipboard_request;
|
vd->cbpeer.request = vdagent_clipboard_request;
|
||||||
qemu_clipboard_peer_register(&vd->cbpeer);
|
qemu_clipboard_peer_register(&vd->cbpeer);
|
||||||
}
|
}
|
||||||
@ -799,7 +811,7 @@ static void vdagent_disconnect(VDAgentChardev *vd)
|
|||||||
if (vd->mouse_hs) {
|
if (vd->mouse_hs) {
|
||||||
qemu_input_handler_deactivate(vd->mouse_hs);
|
qemu_input_handler_deactivate(vd->mouse_hs);
|
||||||
}
|
}
|
||||||
if (vd->cbpeer.update.notify) {
|
if (vd->cbpeer.notifier.notify) {
|
||||||
qemu_clipboard_peer_unregister(&vd->cbpeer);
|
qemu_clipboard_peer_unregister(&vd->cbpeer);
|
||||||
memset(&vd->cbpeer, 0, sizeof(vd->cbpeer));
|
memset(&vd->cbpeer, 0, sizeof(vd->cbpeer));
|
||||||
}
|
}
|
||||||
@ -807,11 +819,8 @@ static void vdagent_disconnect(VDAgentChardev *vd)
|
|||||||
|
|
||||||
static void vdagent_chr_set_fe_open(struct Chardev *chr, int fe_open)
|
static void vdagent_chr_set_fe_open(struct Chardev *chr, int fe_open)
|
||||||
{
|
{
|
||||||
VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr);
|
|
||||||
|
|
||||||
if (!fe_open) {
|
if (!fe_open) {
|
||||||
trace_vdagent_close();
|
trace_vdagent_close();
|
||||||
vdagent_disconnect(vd);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,10 +189,8 @@ static void vnc_clipboard_provide(VncState *vs,
|
|||||||
vnc_flush(vs);
|
vnc_flush(vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnc_clipboard_notify(Notifier *notifier, void *data)
|
static void vnc_clipboard_update_info(VncState *vs, QemuClipboardInfo *info)
|
||||||
{
|
{
|
||||||
VncState *vs = container_of(notifier, VncState, cbpeer.update);
|
|
||||||
QemuClipboardInfo *info = data;
|
|
||||||
QemuClipboardType type;
|
QemuClipboardType type;
|
||||||
bool self_update = info->owner == &vs->cbpeer;
|
bool self_update = info->owner == &vs->cbpeer;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
@ -223,6 +221,18 @@ static void vnc_clipboard_notify(Notifier *notifier, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vnc_clipboard_notify(Notifier *notifier, void *data)
|
||||||
|
{
|
||||||
|
VncState *vs = container_of(notifier, VncState, cbpeer.notifier);
|
||||||
|
QemuClipboardNotify *notify = data;
|
||||||
|
|
||||||
|
switch (notify->type) {
|
||||||
|
case QEMU_CLIPBOARD_UPDATE_INFO:
|
||||||
|
vnc_clipboard_update_info(vs, notify->info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void vnc_clipboard_request(QemuClipboardInfo *info,
|
static void vnc_clipboard_request(QemuClipboardInfo *info,
|
||||||
QemuClipboardType type)
|
QemuClipboardType type)
|
||||||
{
|
{
|
||||||
@ -316,9 +326,9 @@ void vnc_server_cut_text_caps(VncState *vs)
|
|||||||
caps[1] = 0;
|
caps[1] = 0;
|
||||||
vnc_clipboard_send(vs, 2, caps);
|
vnc_clipboard_send(vs, 2, caps);
|
||||||
|
|
||||||
if (!vs->cbpeer.update.notify) {
|
if (!vs->cbpeer.notifier.notify) {
|
||||||
vs->cbpeer.name = "vnc";
|
vs->cbpeer.name = "vnc";
|
||||||
vs->cbpeer.update.notify = vnc_clipboard_notify;
|
vs->cbpeer.notifier.notify = vnc_clipboard_notify;
|
||||||
vs->cbpeer.request = vnc_clipboard_request;
|
vs->cbpeer.request = vnc_clipboard_request;
|
||||||
qemu_clipboard_peer_register(&vs->cbpeer);
|
qemu_clipboard_peer_register(&vs->cbpeer);
|
||||||
}
|
}
|
||||||
|
2
ui/vnc.c
2
ui/vnc.c
@ -1354,7 +1354,7 @@ void vnc_disconnect_finish(VncState *vs)
|
|||||||
/* last client gone */
|
/* last client gone */
|
||||||
vnc_update_server_surface(vs->vd);
|
vnc_update_server_surface(vs->vd);
|
||||||
}
|
}
|
||||||
if (vs->cbpeer.update.notify) {
|
if (vs->cbpeer.notifier.notify) {
|
||||||
qemu_clipboard_peer_unregister(&vs->cbpeer);
|
qemu_clipboard_peer_unregister(&vs->cbpeer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user