[hackers] [st] Implement INCR transfers in the clipboard. || Christoph Lohmann

From: <git_AT_suckless.org>
Date: Fri, 10 Jul 2015 14:32:07 +0200 (CEST)

commit f8c6e7d0419d10c1425cb2c7123c5798ffb3b942
Author: Christoph Lohmann <20h_AT_r-36.net>
AuthorDate: Fri Jul 10 14:10:17 2015 +0200
Commit: Christoph Lohmann <20h_AT_r-36.net>
CommitDate: Fri Jul 10 14:10:17 2015 +0200

    Implement INCR transfers in the clipboard.

diff --git a/st.c b/st.c
index 274ac5d..17e0a65 100644
--- a/st.c
+++ b/st.c
_AT_@ -452,6 +452,7 @@ static void focus(XEvent *);
 static void brelease(XEvent *);
 static void bpress(XEvent *);
 static void bmotion(XEvent *);
+static void propnotify(XEvent *);
 static void selnotify(XEvent *);
 static void selclear(XEvent *);
 static void selrequest(XEvent *);
_AT_@ -500,6 +501,11 @@ static void (*handler[LASTEvent])(XEvent *) = {
  */
 /* [SelectionClear] = selclear, */
         [SelectionNotify] = selnotify,
+/*
+ * PropertyNotify is only turned on when there is some INCR transfer happening
+ * for the selection retrieval.
+ */
+ [PropertyNotify] = propnotify,
         [SelectionRequest] = selrequest,
 };
 
_AT_@ -1029,20 +1035,40 @@ selcopy(Time t)
 }
 
 void
+propnotify(XEvent *e)
+{
+ XPropertyEvent *xpev;
+ Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+
+ xpev = &e->xproperty;
+ if (xpev->state == PropertyNewValue &&
+ (xpev->atom == XA_PRIMARY ||
+ xpev->atom == clipboard)) {
+ slenotify(e);
+ }
+}
+
+void
 selnotify(XEvent *e)
 {
         ulong nitems, ofs, rem;
         int format;
         uchar *data, *last, *repl;
- Atom type;
- XSelectionEvent *xsev;
+ Atom type, incratom, property;
 
         ofs = 0;
- xsev = &e->xselection;
- if (xsev->property == None)
- return;
+ if (e->type == SelectionNotify) {
+ property = e->xselection.property;
+ } else if(e->type == PropertyNotify) {
+ property = e->xproperty.atom;
+ } else {
+ return;
+ }
+ if (property == None)
+ return;
+
         do {
- if (XGetWindowProperty(xw.dpy, xw.win, xsev->property, ofs,
+ if (XGetWindowProperty(xw.dpy, xw.win, property, ofs,
                                         BUFSIZ/4, False, AnyPropertyType,
                                         &type, &format, &nitems, &rem,
                                         &data)) {
_AT_@ -1050,6 +1076,35 @@ selnotify(XEvent *e)
                         return;
                 }
 
+ if (e->type == PropertyNotify && nitems == 0 && rem == 0) {
+ /*
+ * If there is some PropertyNotify with no data, then
+ * this is the signal of the selection owner that all
+ * data has been transferred. We won't need to receive
+ * PropertyNotify events anymore.
+ */
+ MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask);
+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
+ &xw.attrs);
+ }
+
+ if (type == incratom) {
+ /*
+ * Activate the PropertyNotify events so we receive
+ * when the selection owner does send us the next
+ * chunk of data.
+ */
+ MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
+ &xw.attrs);
+
+ /*
+ * Deleting the property is the transfer start signal.
+ */
+ XDeleteProperty(xw.dpy, xw.win, (int)property);
+ continue;
+ }
+
                 /*
                  * As seen in getsel:
                  * Line endings are inconsistent in the terminal and GUI world
_AT_@ -1072,6 +1127,13 @@ selnotify(XEvent *e)
                 /* number of 32-bit chunks returned */
                 ofs += nitems * format / 32;
         } while (rem > 0);
+
+ /*
+ * Deleting the property again tells the selection owner to send the
+ * next data chunk in the property.
+ */
+ if (e->type == PropertyNotify)
+ XDeleteProperty(xw.dpy, xw.win, (int)property);
 }
 
 void
Received on Fri Jul 10 2015 - 14:32:07 CEST

This archive was generated by hypermail 2.3.0 : Fri Jul 10 2015 - 14:36:13 CEST