mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-13 01:38:20 +00:00
[client] clipboard: refactor for readabillity
This commit is contained in:
parent
301ba45f0f
commit
aaf449442a
@ -141,178 +141,190 @@ static void x11_cb_reply_fn(void * opaque, LG_ClipboardData type, uint8_t * data
|
|||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x11_cb_wmevent(SDL_SysWMmsg * msg)
|
static void x11_cb_selection_request(const XSelectionRequestEvent e)
|
||||||
{
|
{
|
||||||
XEvent e = msg->msg.x11.event;
|
XEvent * s = (XEvent *)malloc(sizeof(XEvent));
|
||||||
|
s->xselection.type = SelectionNotify;
|
||||||
|
s->xselection.requestor = e.requestor;
|
||||||
|
s->xselection.selection = e.selection;
|
||||||
|
s->xselection.target = e.target;
|
||||||
|
s->xselection.property = e.property;
|
||||||
|
s->xselection.time = e.time;
|
||||||
|
|
||||||
if (e.type == SelectionRequest)
|
if (!this->requestFn)
|
||||||
|
goto nodata;
|
||||||
|
|
||||||
|
// target list requested
|
||||||
|
if (e.target == this->aTargets)
|
||||||
{
|
{
|
||||||
XEvent * s = (XEvent *)malloc(sizeof(XEvent));
|
Atom targets[2];
|
||||||
s->xselection.type = SelectionNotify;
|
targets[0] = this->aTargets;
|
||||||
s->xselection.requestor = e.xselectionrequest.requestor;
|
targets[1] = this->aTypes[this->type];
|
||||||
s->xselection.selection = e.xselectionrequest.selection;
|
|
||||||
s->xselection.target = e.xselectionrequest.target;
|
|
||||||
s->xselection.property = e.xselectionrequest.property;
|
|
||||||
s->xselection.time = e.xselectionrequest.time;
|
|
||||||
|
|
||||||
if (!this->requestFn)
|
XChangeProperty(
|
||||||
{
|
e.display,
|
||||||
s->xselection.property = None;
|
e.requestor,
|
||||||
XSendEvent(this->display, e.xselectionrequest.requestor, 0, 0, s);
|
e.property,
|
||||||
XFlush(this->display);
|
XA_ATOM,
|
||||||
free(s);
|
32,
|
||||||
return;
|
PropModeReplace,
|
||||||
}
|
(unsigned char*)targets,
|
||||||
|
sizeof(targets) / sizeof(Atom));
|
||||||
|
|
||||||
// target list requested
|
goto send;
|
||||||
if (e.xselectionrequest.target == this->aTargets)
|
|
||||||
{
|
|
||||||
Atom targets[2];
|
|
||||||
targets[0] = this->aTargets;
|
|
||||||
targets[1] = this->aTypes[this->type];
|
|
||||||
|
|
||||||
XChangeProperty(
|
|
||||||
e.xselectionrequest.display,
|
|
||||||
e.xselectionrequest.requestor,
|
|
||||||
e.xselectionrequest.property,
|
|
||||||
XA_ATOM,
|
|
||||||
32,
|
|
||||||
PropModeReplace,
|
|
||||||
(unsigned char*)targets,
|
|
||||||
sizeof(targets) / sizeof(Atom));
|
|
||||||
|
|
||||||
XSendEvent(this->display, e.xselectionrequest.requestor, 0, 0, s);
|
|
||||||
XFlush(this->display);
|
|
||||||
free(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// look to see if we can satisfy the data type
|
|
||||||
for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i)
|
|
||||||
if (this->aTypes[i] == e.xselectionrequest.target && this->type == i)
|
|
||||||
{
|
|
||||||
// request the data
|
|
||||||
this->requestFn(x11_cb_reply_fn, s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// report no data
|
|
||||||
s->xselection.property = None;
|
|
||||||
XSendEvent(this->display, e.xselectionrequest.requestor, 0, 0, s);
|
|
||||||
XFlush(this->display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.type == SelectionClear && (
|
// look to see if we can satisfy the data type
|
||||||
e.xselectionclear.selection == XA_PRIMARY ||
|
for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i)
|
||||||
e.xselectionclear.selection == this->aSelection)
|
if (this->aTypes[i] == e.target && this->type == i)
|
||||||
)
|
{
|
||||||
|
// request the data
|
||||||
|
this->requestFn(x11_cb_reply_fn, s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodata:
|
||||||
|
// report no data
|
||||||
|
s->xselection.property = None;
|
||||||
|
|
||||||
|
send:
|
||||||
|
XSendEvent(this->display, e.requestor, 0, 0, s);
|
||||||
|
XFlush(this->display);
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void x11_cb_selection_clear(const XSelectionClearEvent e)
|
||||||
|
{
|
||||||
|
if (e.selection != XA_PRIMARY && e.selection != this->aSelection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->aCurSelection = BadValue;
|
||||||
|
this->releaseFn();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void x11_cb_xfixes_selection_notify(const XFixesSelectionNotifyEvent e)
|
||||||
|
{
|
||||||
|
// check if the selection is valid and it isn't ourself
|
||||||
|
if ((e.selection != XA_PRIMARY && e.selection != this->aSelection) ||
|
||||||
|
e.owner == this->window || e.owner == 0)
|
||||||
{
|
{
|
||||||
this->aCurSelection = BadValue;
|
|
||||||
this->releaseFn();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if someone selected data
|
// remember which selection we are working with
|
||||||
if (e.type == this->eventBase + XFixesSelectionNotify)
|
this->aCurSelection = e.selection;
|
||||||
{
|
XConvertSelection(
|
||||||
XFixesSelectionNotifyEvent * sne = (XFixesSelectionNotifyEvent *)&e;
|
this->display,
|
||||||
|
e.selection,
|
||||||
|
this->aTargets,
|
||||||
|
this->aTargets,
|
||||||
|
this->window,
|
||||||
|
CurrentTime);
|
||||||
|
|
||||||
// check if the selection is valid and it isn't ourself
|
return;
|
||||||
if (
|
}
|
||||||
(sne->selection != XA_PRIMARY && sne->selection != this->aSelection) ||
|
|
||||||
sne->owner == this->window ||
|
|
||||||
sne->owner == 0
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember which selection we are working with
|
static void x11_cb_selection_notify(const XSelectionEvent e)
|
||||||
this->aCurSelection = sne->selection;
|
{
|
||||||
XConvertSelection(
|
if (e.property == None)
|
||||||
this->display,
|
|
||||||
sne->selection,
|
|
||||||
this->aTargets,
|
|
||||||
this->aTargets,
|
|
||||||
this->window,
|
|
||||||
CurrentTime);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Atom type;
|
||||||
|
int format;
|
||||||
|
unsigned long itemCount, after;
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
XGetWindowProperty(
|
||||||
|
this->display,
|
||||||
|
this->window,
|
||||||
|
e.property,
|
||||||
|
0, ~0L, // start and length
|
||||||
|
True , // delete the property
|
||||||
|
AnyPropertyType,
|
||||||
|
&type,
|
||||||
|
&format,
|
||||||
|
&itemCount,
|
||||||
|
&after,
|
||||||
|
&data);
|
||||||
|
|
||||||
|
if (format == this->aIncr)
|
||||||
|
{
|
||||||
|
DEBUG_WARN("fixme: large paste buffers are not yet supported");
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.type == SelectionNotify)
|
// the target list
|
||||||
|
if (e.property == this->aTargets)
|
||||||
{
|
{
|
||||||
if (e.xselection.property == None)
|
// the format is 32-bit and we must have data
|
||||||
return;
|
// this is technically incorrect however as it's
|
||||||
|
// an array of padded 64-bit values
|
||||||
|
if (!data || format != 32)
|
||||||
|
goto out;
|
||||||
|
|
||||||
Atom type;
|
// see if we support any of the targets listed
|
||||||
int format;
|
const uint64_t * targets = (const uint64_t *)data;
|
||||||
unsigned long itemCount, after;
|
for(unsigned long i = 0; i < itemCount; ++i)
|
||||||
unsigned char *data;
|
|
||||||
|
|
||||||
XGetWindowProperty(
|
|
||||||
this->display,
|
|
||||||
this->window,
|
|
||||||
e.xselection.property,
|
|
||||||
0, ~0L, // start and length
|
|
||||||
True , // delete the property
|
|
||||||
AnyPropertyType,
|
|
||||||
&type,
|
|
||||||
&format,
|
|
||||||
&itemCount,
|
|
||||||
&after,
|
|
||||||
&data);
|
|
||||||
|
|
||||||
// the target list
|
|
||||||
if (e.xselection.property == this->aTargets)
|
|
||||||
{
|
{
|
||||||
// the format is 32-bit and we must have data
|
for(int n = 0; n < LG_CLIPBOARD_DATA_NONE; ++n)
|
||||||
// this is technically incorrect however as it's
|
if (this->aTypes[n] == targets[i])
|
||||||
// an array of padded 64-bit values
|
{
|
||||||
if (!data || format != 32)
|
DEBUG_INFO("%s", atomTypes[n]);
|
||||||
{
|
// we have a match, so send the notification
|
||||||
if (data)
|
this->notifyFn(n);
|
||||||
XFree(data);
|
goto out;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// see if we support any of the targets listed
|
|
||||||
const uint64_t * targets = (const uint64_t *)data;
|
|
||||||
for(unsigned long i = 0; i < itemCount; ++i)
|
|
||||||
{
|
|
||||||
for(int n = 0; n < LG_CLIPBOARD_DATA_NONE; ++n)
|
|
||||||
if (this->aTypes[n] == targets[i])
|
|
||||||
{
|
|
||||||
// we have a match, so send the notification
|
|
||||||
this->notifyFn(n);
|
|
||||||
XFree(data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no matches
|
|
||||||
this->notifyFn(LG_CLIPBOARD_DATA_NONE);
|
|
||||||
XFree(data);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == this->aIncr)
|
// no matches
|
||||||
{
|
this->notifyFn(LG_CLIPBOARD_DATA_NONE);
|
||||||
DEBUG_WARN("fixme: large paste buffers are not yet supported");
|
goto out;
|
||||||
XFree(data);
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (e.property == this->aSelData)
|
||||||
|
{
|
||||||
for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i)
|
for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i)
|
||||||
if (this->aTypes[i] == type)
|
if (this->aTypes[i] == type)
|
||||||
{
|
{
|
||||||
this->dataFn(i, data, itemCount);
|
this->dataFn(i, data, itemCount);
|
||||||
XFree(data);
|
goto out;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_WARN("clipboard data (%s) not in a supported format", XGetAtomName(this->display, type));
|
DEBUG_WARN("clipboard data (%s) not in a supported format", XGetAtomName(this->display, type));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (data)
|
||||||
XFree(data);
|
XFree(data);
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
static void x11_cb_wmevent(SDL_SysWMmsg * msg)
|
||||||
|
{
|
||||||
|
XEvent e = msg->msg.x11.event;
|
||||||
|
|
||||||
|
switch(e.type)
|
||||||
|
{
|
||||||
|
case SelectionRequest:
|
||||||
|
x11_cb_selection_request(e.xselectionrequest);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SelectionClear:
|
||||||
|
x11_cb_selection_clear(e.xselectionclear);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SelectionNotify:
|
||||||
|
x11_cb_selection_notify(e.xselection);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (e.type == this->eventBase + XFixesSelectionNotify)
|
||||||
|
{
|
||||||
|
XFixesSelectionNotifyEvent * sne = (XFixesSelectionNotifyEvent *)&e;
|
||||||
|
x11_cb_xfixes_selection_notify(*sne);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,4 +368,4 @@ const LG_Clipboard LGC_X11 =
|
|||||||
.notice = x11_cb_notice,
|
.notice = x11_cb_notice,
|
||||||
.release = x11_cb_release,
|
.release = x11_cb_release,
|
||||||
.request = x11_cb_request
|
.request = x11_cb_request
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user