forked from my-unikernel/qemu
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add some infrastructure to manage the clipboard in qemu. Signed-off-by: Gerd Hoffmann <[email protected]> Reviewed-by: Marc-André Lureau <[email protected]> Message-id: [email protected] Message-Id: <[email protected]>
- Loading branch information
Showing
3 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#ifndef QEMU_CLIPBOARD_H | ||
#define QEMU_CLIPBOARD_H | ||
|
||
#include "qemu/notify.h" | ||
|
||
typedef enum QemuClipboardType QemuClipboardType; | ||
typedef enum QemuClipboardSelection QemuClipboardSelection; | ||
typedef struct QemuClipboardPeer QemuClipboardPeer; | ||
typedef struct QemuClipboardInfo QemuClipboardInfo; | ||
|
||
enum QemuClipboardType { | ||
QEMU_CLIPBOARD_TYPE_TEXT, /* text/plain; charset=utf-8 */ | ||
QEMU_CLIPBOARD_TYPE__COUNT, | ||
}; | ||
|
||
/* same as VD_AGENT_CLIPBOARD_SELECTION_* */ | ||
enum QemuClipboardSelection { | ||
QEMU_CLIPBOARD_SELECTION_CLIPBOARD, | ||
QEMU_CLIPBOARD_SELECTION_PRIMARY, | ||
QEMU_CLIPBOARD_SELECTION_SECONDARY, | ||
QEMU_CLIPBOARD_SELECTION__COUNT, | ||
}; | ||
|
||
struct QemuClipboardPeer { | ||
const char *name; | ||
Notifier update; | ||
void (*request)(QemuClipboardInfo *info, | ||
QemuClipboardType type); | ||
}; | ||
|
||
struct QemuClipboardInfo { | ||
uint32_t refcount; | ||
QemuClipboardPeer *owner; | ||
QemuClipboardSelection selection; | ||
struct { | ||
bool available; | ||
bool requested; | ||
size_t size; | ||
void *data; | ||
} types[QEMU_CLIPBOARD_TYPE__COUNT]; | ||
}; | ||
|
||
void qemu_clipboard_peer_register(QemuClipboardPeer *peer); | ||
void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer); | ||
|
||
QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner, | ||
QemuClipboardSelection selection); | ||
QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info); | ||
void qemu_clipboard_info_unref(QemuClipboardInfo *info); | ||
|
||
void qemu_clipboard_update(QemuClipboardInfo *info); | ||
void qemu_clipboard_request(QemuClipboardInfo *info, | ||
QemuClipboardType type); | ||
|
||
void qemu_clipboard_set_data(QemuClipboardPeer *peer, | ||
QemuClipboardInfo *info, | ||
QemuClipboardType type, | ||
uint32_t size, | ||
void *data, | ||
bool update); | ||
|
||
#endif /* QEMU_CLIPBOARD_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#include "qemu/osdep.h" | ||
#include "ui/clipboard.h" | ||
|
||
static NotifierList clipboard_notifiers = | ||
NOTIFIER_LIST_INITIALIZER(clipboard_notifiers); | ||
|
||
void qemu_clipboard_peer_register(QemuClipboardPeer *peer) | ||
{ | ||
notifier_list_add(&clipboard_notifiers, &peer->update); | ||
} | ||
|
||
void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer) | ||
{ | ||
notifier_remove(&peer->update); | ||
} | ||
|
||
void qemu_clipboard_update(QemuClipboardInfo *info) | ||
{ | ||
notifier_list_notify(&clipboard_notifiers, info); | ||
} | ||
|
||
QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner, | ||
QemuClipboardSelection selection) | ||
{ | ||
QemuClipboardInfo *info = g_new0(QemuClipboardInfo, 1); | ||
|
||
info->owner = owner; | ||
info->selection = selection; | ||
info->refcount = 1; | ||
|
||
return info; | ||
} | ||
|
||
QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info) | ||
{ | ||
info->refcount++; | ||
return info; | ||
} | ||
|
||
void qemu_clipboard_info_unref(QemuClipboardInfo *info) | ||
{ | ||
uint32_t type; | ||
|
||
if (!info) { | ||
return; | ||
} | ||
|
||
info->refcount--; | ||
if (info->refcount > 0) { | ||
return; | ||
} | ||
|
||
for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) { | ||
g_free(info->types[type].data); | ||
} | ||
g_free(info); | ||
} | ||
|
||
void qemu_clipboard_request(QemuClipboardInfo *info, | ||
QemuClipboardType type) | ||
{ | ||
if (info->types[type].data || | ||
info->types[type].requested || | ||
!info->types[type].available || | ||
!info->owner) | ||
return; | ||
|
||
info->types[type].requested = true; | ||
info->owner->request(info, type); | ||
} | ||
|
||
void qemu_clipboard_set_data(QemuClipboardPeer *peer, | ||
QemuClipboardInfo *info, | ||
QemuClipboardType type, | ||
uint32_t size, | ||
void *data, | ||
bool update) | ||
{ | ||
if (!info || | ||
info->owner != peer) { | ||
return; | ||
} | ||
|
||
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 (update) { | ||
qemu_clipboard_update(info); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters