aboutsummaryrefslogtreecommitdiffstats
path: root/pugl/detail
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-03-15 14:33:08 +0100
committerDavid Robillard <d@drobilla.net>2020-03-15 14:33:08 +0100
commite6a38b049573bb3ab3bdc90ddce678945ba555c9 (patch)
treead61cd6c9ad6e3d506d2bd085ab9cddb2a06c8bc /pugl/detail
parent6c250b3cfd04218c7335af61e440c3a909b6d87f (diff)
downloadpugl-e6a38b049573bb3ab3bdc90ddce678945ba555c9.tar.gz
pugl-e6a38b049573bb3ab3bdc90ddce678945ba555c9.tar.bz2
pugl-e6a38b049573bb3ab3bdc90ddce678945ba555c9.zip
X11: Factor out selection event handling
Diffstat (limited to 'pugl/detail')
-rw-r--r--pugl/detail/x11.c109
1 files changed, 69 insertions, 40 deletions
diff --git a/pugl/detail/x11.c b/pugl/detail/x11.c
index 05746d7..fa23bf0 100644
--- a/pugl/detail/x11.c
+++ b/pugl/detail/x11.c
@@ -1,5 +1,5 @@
/*
- Copyright 2012-2019 David Robillard <http://drobilla.net>
+ Copyright 2012-2020 David Robillard <http://drobilla.net>
Copyright 2013 Robin Gareus <robin@gareus.org>
Copyright 2011-2012 Ben Loftis, Harrison Consoles
@@ -673,6 +673,72 @@ mergeExposeEvents(PuglEvent* dst, const PuglEvent* src)
}
}
+static void
+handleSelectionNotify(const PuglWorld* world, PuglView* view)
+{
+ uint8_t* str = NULL;
+ Atom type = 0;
+ int fmt = 0;
+ unsigned long len = 0;
+ unsigned long left = 0;
+
+ XGetWindowProperty(world->impl->display,
+ view->impl->win,
+ XA_PRIMARY,
+ 0,
+ 0x1FFFFFFF,
+ False,
+ AnyPropertyType,
+ &type,
+ &fmt,
+ &len,
+ &left,
+ &str);
+
+ if (str && fmt == 8 && type == world->impl->atoms.UTF8_STRING &&
+ left == 0) {
+ puglSetBlob(&view->clipboard, str, len);
+ }
+
+ XFree(str);
+}
+
+static void
+handleSelectionRequest(const PuglWorld* world,
+ PuglView* view,
+ const XSelectionRequestEvent* request)
+{
+ XSelectionEvent note = {SelectionNotify,
+ request->serial,
+ False,
+ world->impl->display,
+ request->requestor,
+ request->selection,
+ request->target,
+ None,
+ request->time};
+
+ const char* type = NULL;
+ size_t len = 0;
+ const void* data = puglGetInternalClipboard(view, &type, &len);
+ if (data && request->selection == world->impl->atoms.CLIPBOARD &&
+ request->target == world->impl->atoms.UTF8_STRING) {
+ note.property = request->property;
+ XChangeProperty(world->impl->display,
+ note.requestor,
+ note.property,
+ note.target,
+ 8,
+ PropModeReplace,
+ (const uint8_t*)data,
+ (int)len);
+ } else {
+ note.property = None;
+ }
+
+ XSendEvent(world->impl->display, note.requestor, True, 0, (XEvent*)&note);
+}
+
PUGL_API PuglStatus
puglDispatchEvents(PuglWorld* world)
{
@@ -715,47 +781,10 @@ puglDispatchEvents(PuglWorld* world)
xevent.xselection.selection == atoms->CLIPBOARD &&
xevent.xselection.target == atoms->UTF8_STRING &&
xevent.xselection.property == XA_PRIMARY) {
-
- uint8_t* str = NULL;
- Atom type = 0;
- int fmt = 0;
- unsigned long len = 0;
- unsigned long left = 0;
- XGetWindowProperty(impl->display, impl->win, XA_PRIMARY,
- 0, 0x1FFFFFFF, False, AnyPropertyType,
- &type, &fmt, &len, &left, &str);
-
- if (str && fmt == 8 && type == atoms->UTF8_STRING && left == 0) {
- puglSetBlob(&view->clipboard, str, len);
- }
-
- XFree(str);
+ handleSelectionNotify(world, view);
continue;
} else if (xevent.type == SelectionRequest) {
- const XSelectionRequestEvent* request = &xevent.xselectionrequest;
-
- XSelectionEvent note = {0};
- note.type = SelectionNotify;
- note.requestor = request->requestor;
- note.selection = request->selection;
- note.target = request->target;
- note.time = request->time;
-
- const char* type = NULL;
- size_t len = 0;
- const void* data = puglGetInternalClipboard(view, &type, &len);
- if (data &&
- request->selection == atoms->CLIPBOARD &&
- request->target == atoms->UTF8_STRING) {
- note.property = request->property;
- XChangeProperty(impl->display, note.requestor,
- note.property, note.target, 8, PropModeReplace,
- (const uint8_t*)data, (int)len);
- } else {
- note.property = None;
- }
-
- XSendEvent(impl->display, note.requestor, True, 0, (XEvent*)&note);
+ handleSelectionRequest(world, view, &xevent.xselectionrequest);
continue;
}