[client] x11: fix bidirectional clipboard functionallity

This commit is contained in:
Geoffrey McRae 2019-02-24 15:35:31 +11:00
parent 03628505ed
commit c7666b314b
2 changed files with 44 additions and 27 deletions

View File

@ -110,8 +110,8 @@ static bool x11_cb_init(
return false; return false;
} }
XFixesSelectSelectionInput(this->display,DefaultRootWindow(this->display), XA_PRIMARY , XFixesSetSelectionOwnerNotifyMask); XFixesSelectSelectionInput(this->display, this->window, XA_PRIMARY , XFixesSetSelectionOwnerNotifyMask);
XFixesSelectSelectionInput(this->display,DefaultRootWindow(this->display), this->aSelection, XFixesSetSelectionOwnerNotifyMask); XFixesSelectSelectionInput(this->display, this->window, this->aSelection, XFixesSetSelectionOwnerNotifyMask);
return true; return true;
} }
@ -217,20 +217,22 @@ static void x11_cb_wmevent(SDL_SysWMmsg * msg)
} }
// if someone selected data // if someone selected data
if ( if (e.type == this->eventBase + XFixesSelectionNotify)
e.type == this->eventBase + XFixesSelectionNotify &&
((XFixesSelectionNotifyEvent *)&e)->owner != this->window &&
(
((XFixesSelectionNotifyEvent *)&e)->selection == XA_PRIMARY ||
((XFixesSelectionNotifyEvent *)&e)->selection == this->aSelection)
)
{ {
// ask for the data type
XFixesSelectionNotifyEvent * sne = (XFixesSelectionNotifyEvent *)&e; XFixesSelectionNotifyEvent * sne = (XFixesSelectionNotifyEvent *)&e;
// check if the selection is valid and it isn't ourself
if (
(sne->selection != XA_PRIMARY && sne->selection != this->aSelection) ||
sne->owner == this->window ||
sne->owner == 0
)
{
return;
}
// remember which selection we are working with // remember which selection we are working with
this->aCurSelection = sne->selection; this->aCurSelection = sne->selection;
XConvertSelection( XConvertSelection(
this->display, this->display,
sne->selection, sne->selection,
@ -300,20 +302,19 @@ static void x11_cb_wmevent(SDL_SysWMmsg * msg)
if (format == this->aIncr) if (format == this->aIncr)
{ {
DEBUG_WARN("fixme: large paste buffers are not yet supported"); DEBUG_WARN("fixme: large paste buffers are not yet supported");
} XFree(data);
else return;
{
for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i)
if (this->aTypes[i] == type)
{
this->dataFn(i, data, itemCount);
XFree(data);
return;
}
DEBUG_WARN("clipboard data (%s) not in a supported format", XGetAtomName(this->display, type));
} }
for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i)
if (this->aTypes[i] == type)
{
this->dataFn(i, data, itemCount);
XFree(data);
return;
}
DEBUG_WARN("clipboard data (%s) not in a supported format", XGetAtomName(this->display, type));
XFree(data); XFree(data);
return; return;
} }

View File

@ -525,8 +525,6 @@ static SpiceDataType clipboard_type_to_spice_type(const LG_ClipboardData type)
void clipboardRelease() void clipboardRelease()
{ {
spice_clipboard_release(); spice_clipboard_release();
// another application just took the clipboard ownership
} }
void clipboardNotify(const LG_ClipboardData type) void clipboardNotify(const LG_ClipboardData type)
@ -542,7 +540,26 @@ void clipboardNotify(const LG_ClipboardData type)
void clipboardData(const LG_ClipboardData type, uint8_t * data, size_t size) void clipboardData(const LG_ClipboardData type, uint8_t * data, size_t size)
{ {
spice_clipboard_data(clipboard_type_to_spice_type(type), data, (uint32_t)size); uint8_t * buffer = data;
// unix2dos
if (type == LG_CLIPBOARD_DATA_TEXT)
{
// TODO: make this more memory efficent
buffer = malloc(size * 2);
uint8_t * p = buffer;
for(uint32_t i = 0; i < size; ++i)
{
uint8_t c = data[i];
if (c == '\n')
*p++ = '\r';
*p++ = c;
}
}
spice_clipboard_data(clipboard_type_to_spice_type(type), buffer, (uint32_t)size);
if (buffer != data)
free(buffer);
} }
void clipboardRequest(const LG_ClipboardReplyFn replyFn, void * opaque) void clipboardRequest(const LG_ClipboardReplyFn replyFn, void * opaque)
@ -574,7 +591,6 @@ void spiceClipboardData(const SpiceDataType type, uint8_t * buffer, uint32_t siz
if (c != '\r') if (c != '\r')
*p++ = c; *p++ = c;
} }
*p = '\0';
} }
state.cbReplyFn(state.cbReplyData, type, buffer, size); state.cbReplyFn(state.cbReplyData, type, buffer, size);