[client] clipboard: refactor for readabillity

This commit is contained in:
Geoffrey McRae 2020-12-03 00:42:11 +11:00
parent 301ba45f0f
commit aaf449442a

View File

@ -141,107 +141,93 @@ 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;
if (e.type == SelectionRequest)
{
XEvent * s = (XEvent *)malloc(sizeof(XEvent)); XEvent * s = (XEvent *)malloc(sizeof(XEvent));
s->xselection.type = SelectionNotify; s->xselection.type = SelectionNotify;
s->xselection.requestor = e.xselectionrequest.requestor; s->xselection.requestor = e.requestor;
s->xselection.selection = e.xselectionrequest.selection; s->xselection.selection = e.selection;
s->xselection.target = e.xselectionrequest.target; s->xselection.target = e.target;
s->xselection.property = e.xselectionrequest.property; s->xselection.property = e.property;
s->xselection.time = e.xselectionrequest.time; s->xselection.time = e.time;
if (!this->requestFn) if (!this->requestFn)
{ goto nodata;
s->xselection.property = None;
XSendEvent(this->display, e.xselectionrequest.requestor, 0, 0, s);
XFlush(this->display);
free(s);
return;
}
// target list requested // target list requested
if (e.xselectionrequest.target == this->aTargets) if (e.target == this->aTargets)
{ {
Atom targets[2]; Atom targets[2];
targets[0] = this->aTargets; targets[0] = this->aTargets;
targets[1] = this->aTypes[this->type]; targets[1] = this->aTypes[this->type];
XChangeProperty( XChangeProperty(
e.xselectionrequest.display, e.display,
e.xselectionrequest.requestor, e.requestor,
e.xselectionrequest.property, e.property,
XA_ATOM, XA_ATOM,
32, 32,
PropModeReplace, PropModeReplace,
(unsigned char*)targets, (unsigned char*)targets,
sizeof(targets) / sizeof(Atom)); sizeof(targets) / sizeof(Atom));
XSendEvent(this->display, e.xselectionrequest.requestor, 0, 0, s); goto send;
XFlush(this->display);
free(s);
return;
} }
// look to see if we can satisfy the data type // look to see if we can satisfy the data type
for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i) for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i)
if (this->aTypes[i] == e.xselectionrequest.target && this->type == i) if (this->aTypes[i] == e.target && this->type == i)
{ {
// request the data // request the data
this->requestFn(x11_cb_reply_fn, s); this->requestFn(x11_cb_reply_fn, s);
return; return;
} }
nodata:
// report no data // report no data
s->xselection.property = None; s->xselection.property = None;
XSendEvent(this->display, e.xselectionrequest.requestor, 0, 0, s);
XFlush(this->display);
}
if (e.type == SelectionClear && ( send:
e.xselectionclear.selection == XA_PRIMARY || XSendEvent(this->display, e.requestor, 0, 0, s);
e.xselectionclear.selection == this->aSelection) 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->aCurSelection = BadValue;
this->releaseFn(); this->releaseFn();
return; return;
} }
// if someone selected data
if (e.type == this->eventBase + XFixesSelectionNotify)
{
XFixesSelectionNotifyEvent * sne = (XFixesSelectionNotifyEvent *)&e;
static void x11_cb_xfixes_selection_notify(const XFixesSelectionNotifyEvent e)
{
// check if the selection is valid and it isn't ourself // check if the selection is valid and it isn't ourself
if ( if ((e.selection != XA_PRIMARY && e.selection != this->aSelection) ||
(sne->selection != XA_PRIMARY && sne->selection != this->aSelection) || e.owner == this->window || e.owner == 0)
sne->owner == this->window ||
sne->owner == 0
)
{ {
return; return;
} }
// remember which selection we are working with // remember which selection we are working with
this->aCurSelection = sne->selection; this->aCurSelection = e.selection;
XConvertSelection( XConvertSelection(
this->display, this->display,
sne->selection, e.selection,
this->aTargets, this->aTargets,
this->aTargets, this->aTargets,
this->window, this->window,
CurrentTime); CurrentTime);
return;
}
if (e.type == SelectionNotify) return;
{ }
if (e.xselection.property == None)
static void x11_cb_selection_notify(const XSelectionEvent e)
{
if (e.property == None)
return; return;
Atom type; Atom type;
@ -252,7 +238,7 @@ static void x11_cb_wmevent(SDL_SysWMmsg * msg)
XGetWindowProperty( XGetWindowProperty(
this->display, this->display,
this->window, this->window,
e.xselection.property, e.property,
0, ~0L, // start and length 0, ~0L, // start and length
True , // delete the property True , // delete the property
AnyPropertyType, AnyPropertyType,
@ -262,18 +248,20 @@ static void x11_cb_wmevent(SDL_SysWMmsg * msg)
&after, &after,
&data); &data);
if (format == this->aIncr)
{
DEBUG_WARN("fixme: large paste buffers are not yet supported");
goto out;
}
// the target list // the target list
if (e.xselection.property == this->aTargets) if (e.property == this->aTargets)
{ {
// the format is 32-bit and we must have data // the format is 32-bit and we must have data
// this is technically incorrect however as it's // this is technically incorrect however as it's
// an array of padded 64-bit values // an array of padded 64-bit values
if (!data || format != 32) if (!data || format != 32)
{ goto out;
if (data)
XFree(data);
return;
}
// see if we support any of the targets listed // see if we support any of the targets listed
const uint64_t * targets = (const uint64_t *)data; const uint64_t * targets = (const uint64_t *)data;
@ -282,37 +270,61 @@ static void x11_cb_wmevent(SDL_SysWMmsg * msg)
for(int n = 0; n < LG_CLIPBOARD_DATA_NONE; ++n) for(int n = 0; n < LG_CLIPBOARD_DATA_NONE; ++n)
if (this->aTypes[n] == targets[i]) if (this->aTypes[n] == targets[i])
{ {
DEBUG_INFO("%s", atomTypes[n]);
// we have a match, so send the notification // we have a match, so send the notification
this->notifyFn(n); this->notifyFn(n);
XFree(data); goto out;
return;
} }
} }
// no matches // no matches
this->notifyFn(LG_CLIPBOARD_DATA_NONE); this->notifyFn(LG_CLIPBOARD_DATA_NONE);
XFree(data); goto out;
return;
} }
if (format == this->aIncr) if (e.property == this->aSelData)
{ {
DEBUG_WARN("fixme: large paste buffers are not yet supported");
XFree(data);
return;
}
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;
} }
} }