ui/vdagent: split clipboard recv message handling
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20210805135715.857938-12-marcandre.lureau@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
5fb2e8d99b
commit
3b99bb4c3a
157
ui/vdagent.c
157
ui/vdagent.c
|
@ -433,13 +433,94 @@ static void vdagent_clipboard_request(QemuClipboardInfo *info,
|
||||||
vdagent_send_msg(vd, msg);
|
vdagent_send_msg(vd, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vdagent_clipboard_recv_grab(VDAgentChardev *vd, uint8_t s, uint32_t size, void *data)
|
||||||
|
{
|
||||||
|
g_autoptr(QemuClipboardInfo) info = NULL;
|
||||||
|
|
||||||
|
trace_vdagent_cb_grab_selection(GET_NAME(sel_name, s));
|
||||||
|
info = qemu_clipboard_info_new(&vd->cbpeer, s);
|
||||||
|
if (size > sizeof(uint32_t) * 10) {
|
||||||
|
/*
|
||||||
|
* spice has 6 types as of 2021. Limiting to 10 entries
|
||||||
|
* so we we have some wiggle room.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (size >= sizeof(uint32_t)) {
|
||||||
|
trace_vdagent_cb_grab_type(GET_NAME(type_name, *(uint32_t *)data));
|
||||||
|
switch (*(uint32_t *)data) {
|
||||||
|
case VD_AGENT_CLIPBOARD_UTF8_TEXT:
|
||||||
|
info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data += sizeof(uint32_t);
|
||||||
|
size -= sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
qemu_clipboard_update(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vdagent_clipboard_recv_request(VDAgentChardev *vd, uint8_t s, uint32_t size, void *data)
|
||||||
|
{
|
||||||
|
QemuClipboardType type;
|
||||||
|
|
||||||
|
if (size < sizeof(uint32_t)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (*(uint32_t *)data) {
|
||||||
|
case VD_AGENT_CLIPBOARD_UTF8_TEXT:
|
||||||
|
type = QEMU_CLIPBOARD_TYPE_TEXT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (vd->cbinfo[s] && vd->cbinfo[s]->types[type].available &&
|
||||||
|
vd->cbinfo[s]->owner != &vd->cbpeer) {
|
||||||
|
if (vd->cbinfo[s]->types[type].data) {
|
||||||
|
vdagent_send_clipboard_data(vd, vd->cbinfo[s], type);
|
||||||
|
} else {
|
||||||
|
vd->cbpending[s] |= (1 << type);
|
||||||
|
qemu_clipboard_request(vd->cbinfo[s], type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vdagent_clipboard_recv_data(VDAgentChardev *vd, uint8_t s, uint32_t size, void *data)
|
||||||
|
{
|
||||||
|
QemuClipboardType type;
|
||||||
|
|
||||||
|
if (size < sizeof(uint32_t)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (*(uint32_t *)data) {
|
||||||
|
case VD_AGENT_CLIPBOARD_UTF8_TEXT:
|
||||||
|
type = QEMU_CLIPBOARD_TYPE_TEXT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data += 4;
|
||||||
|
size -= 4;
|
||||||
|
qemu_clipboard_set_data(&vd->cbpeer, vd->cbinfo[s], type, size, data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vdagent_clipboard_recv_release(VDAgentChardev *vd, uint8_t s)
|
||||||
|
{
|
||||||
|
g_autoptr(QemuClipboardInfo) info = NULL;
|
||||||
|
|
||||||
|
if (vd->cbinfo[s] && vd->cbinfo[s]->owner == &vd->cbpeer) {
|
||||||
|
/* set empty clipboard info */
|
||||||
|
info = qemu_clipboard_info_new(NULL, s);
|
||||||
|
qemu_clipboard_update(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void vdagent_chr_recv_clipboard(VDAgentChardev *vd, VDAgentMessage *msg)
|
static void vdagent_chr_recv_clipboard(VDAgentChardev *vd, VDAgentMessage *msg)
|
||||||
{
|
{
|
||||||
uint8_t s = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
|
uint8_t s = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
|
||||||
uint32_t size = msg->size;
|
uint32_t size = msg->size;
|
||||||
void *data = msg->data;
|
void *data = msg->data;
|
||||||
g_autoptr(QemuClipboardInfo) info = NULL;
|
|
||||||
QemuClipboardType type;
|
|
||||||
|
|
||||||
if (have_selection(vd)) {
|
if (have_selection(vd)) {
|
||||||
if (size < 4) {
|
if (size < 4) {
|
||||||
|
@ -455,75 +536,15 @@ static void vdagent_chr_recv_clipboard(VDAgentChardev *vd, VDAgentMessage *msg)
|
||||||
|
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
case VD_AGENT_CLIPBOARD_GRAB:
|
case VD_AGENT_CLIPBOARD_GRAB:
|
||||||
trace_vdagent_cb_grab_selection(GET_NAME(sel_name, s));
|
return vdagent_clipboard_recv_grab(vd, s, size, data);
|
||||||
info = qemu_clipboard_info_new(&vd->cbpeer, s);
|
|
||||||
if (size > sizeof(uint32_t) * 10) {
|
|
||||||
/*
|
|
||||||
* spice has 6 types as of 2021. Limiting to 10 entries
|
|
||||||
* so we we have some wiggle room.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (size >= sizeof(uint32_t)) {
|
|
||||||
trace_vdagent_cb_grab_type(GET_NAME(type_name, *(uint32_t *)data));
|
|
||||||
switch (*(uint32_t *)data) {
|
|
||||||
case VD_AGENT_CLIPBOARD_UTF8_TEXT:
|
|
||||||
info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
data += sizeof(uint32_t);
|
|
||||||
size -= sizeof(uint32_t);
|
|
||||||
}
|
|
||||||
qemu_clipboard_update(info);
|
|
||||||
break;
|
|
||||||
case VD_AGENT_CLIPBOARD_REQUEST:
|
case VD_AGENT_CLIPBOARD_REQUEST:
|
||||||
if (size < sizeof(uint32_t)) {
|
return vdagent_clipboard_recv_request(vd, s, size, data);
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (*(uint32_t *)data) {
|
|
||||||
case VD_AGENT_CLIPBOARD_UTF8_TEXT:
|
|
||||||
type = QEMU_CLIPBOARD_TYPE_TEXT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (vd->cbinfo[s] &&
|
|
||||||
vd->cbinfo[s]->types[type].available &&
|
|
||||||
vd->cbinfo[s]->owner != &vd->cbpeer) {
|
|
||||||
if (vd->cbinfo[s]->types[type].data) {
|
|
||||||
vdagent_send_clipboard_data(vd, vd->cbinfo[s], type);
|
|
||||||
} else {
|
|
||||||
vd->cbpending[s] |= (1 << type);
|
|
||||||
qemu_clipboard_request(vd->cbinfo[s], type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VD_AGENT_CLIPBOARD: /* data */
|
case VD_AGENT_CLIPBOARD: /* data */
|
||||||
if (size < sizeof(uint32_t)) {
|
return vdagent_clipboard_recv_data(vd, s, size, data);
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (*(uint32_t *)data) {
|
|
||||||
case VD_AGENT_CLIPBOARD_UTF8_TEXT:
|
|
||||||
type = QEMU_CLIPBOARD_TYPE_TEXT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data += 4;
|
|
||||||
size -= 4;
|
|
||||||
qemu_clipboard_set_data(&vd->cbpeer, vd->cbinfo[s], type,
|
|
||||||
size, data, true);
|
|
||||||
break;
|
|
||||||
case VD_AGENT_CLIPBOARD_RELEASE:
|
case VD_AGENT_CLIPBOARD_RELEASE:
|
||||||
if (vd->cbinfo[s] &&
|
return vdagent_clipboard_recv_release(vd, s);
|
||||||
vd->cbinfo[s]->owner == &vd->cbpeer) {
|
default:
|
||||||
/* set empty clipboard info */
|
g_assert_not_reached();
|
||||||
info = qemu_clipboard_info_new(NULL, s);
|
|
||||||
qemu_clipboard_update(info);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue