iImplement INCR transfers in the clipboard. - st - Simple Terminal Err gopher.r-36.net 70 i Err gopher.r-36.net 70 1Log /scm/st//log.gph gopher.r-36.net 70 1Files /scm/st//files.gph gopher.r-36.net 70 1Refs /scm/st//refs.gph gopher.r-36.net 70 1README /scm/st//file/README.gph gopher.r-36.net 70 1LICENSE /scm/st//file/LICENSE.gph gopher.r-36.net 70 i--- Err gopher.r-36.net 70 1commit f8c6e7d0419d10c1425cb2c7123c5798ffb3b942 /scm/st//commit/f8c6e7d0419d10c1425cb2c7123c5798ffb3b942.gph gopher.r-36.net 70 1parent 539afe3af1b0d8b56b9ebfaa3bb7fc4e40f68c71 /scm/st//commit/539afe3af1b0d8b56b9ebfaa3bb7fc4e40f68c71.gph gopher.r-36.net 70 hAuthor: Christoph Lohmann <20h@r-36.net> URL:mailto:20h@r-36.net gopher.r-36.net 70 iDate: Fri, 10 Jul 2015 14:10:17 +0200 Err gopher.r-36.net 70 i Err gopher.r-36.net 70 iImplement INCR transfers in the clipboard. Err gopher.r-36.net 70 i Err gopher.r-36.net 70 iDiffstat: Err gopher.r-36.net 70 i st.c | 74 ++++++++++++++++++++++++++++--- Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i1 file changed, 68 insertions(+), 6 deletions(-) Err gopher.r-36.net 70 i--- Err gopher.r-36.net 70 1diff --git a/st.c b/st.c /scm/st//file/st.c.gph gopher.r-36.net 70 i@@ -452,6 +452,7 @@ static void focus(XEvent *); Err gopher.r-36.net 70 i static void brelease(XEvent *); Err gopher.r-36.net 70 i static void bpress(XEvent *); Err gopher.r-36.net 70 i static void bmotion(XEvent *); Err gopher.r-36.net 70 i+static void propnotify(XEvent *); Err gopher.r-36.net 70 i static void selnotify(XEvent *); Err gopher.r-36.net 70 i static void selclear(XEvent *); Err gopher.r-36.net 70 i static void selrequest(XEvent *); Err gopher.r-36.net 70 i@@ -500,6 +501,11 @@ static void (*handler[LASTEvent])(XEvent *) = { Err gopher.r-36.net 70 i */ Err gopher.r-36.net 70 i /* [SelectionClear] = selclear, */ Err gopher.r-36.net 70 i [SelectionNotify] = selnotify, Err gopher.r-36.net 70 i+/* Err gopher.r-36.net 70 i+ * PropertyNotify is only turned on when there is some INCR transfer happening Err gopher.r-36.net 70 i+ * for the selection retrieval. Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ [PropertyNotify] = propnotify, Err gopher.r-36.net 70 i [SelectionRequest] = selrequest, Err gopher.r-36.net 70 i }; Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i@@ -1029,20 +1035,40 @@ selcopy(Time t) Err gopher.r-36.net 70 i } Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i void Err gopher.r-36.net 70 i+propnotify(XEvent *e) Err gopher.r-36.net 70 i+{ Err gopher.r-36.net 70 i+ XPropertyEvent *xpev; Err gopher.r-36.net 70 i+ Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ xpev = &e->xproperty; Err gopher.r-36.net 70 i+ if (xpev->state == PropertyNewValue && Err gopher.r-36.net 70 i+ (xpev->atom == XA_PRIMARY || Err gopher.r-36.net 70 i+ xpev->atom == clipboard)) { Err gopher.r-36.net 70 i+ slenotify(e); Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+} Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+void Err gopher.r-36.net 70 i selnotify(XEvent *e) Err gopher.r-36.net 70 i { Err gopher.r-36.net 70 i ulong nitems, ofs, rem; Err gopher.r-36.net 70 i int format; Err gopher.r-36.net 70 i uchar *data, *last, *repl; Err gopher.r-36.net 70 i- Atom type; Err gopher.r-36.net 70 i- XSelectionEvent *xsev; Err gopher.r-36.net 70 i+ Atom type, incratom, property; Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i ofs = 0; Err gopher.r-36.net 70 i- xsev = &e->xselection; Err gopher.r-36.net 70 i- if (xsev->property == None) Err gopher.r-36.net 70 i- return; Err gopher.r-36.net 70 i+ if (e->type == SelectionNotify) { Err gopher.r-36.net 70 i+ property = e->xselection.property; Err gopher.r-36.net 70 i+ } else if(e->type == PropertyNotify) { Err gopher.r-36.net 70 i+ property = e->xproperty.atom; Err gopher.r-36.net 70 i+ } else { Err gopher.r-36.net 70 i+ return; Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ if (property == None) Err gopher.r-36.net 70 i+ return; Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i do { Err gopher.r-36.net 70 i- if (XGetWindowProperty(xw.dpy, xw.win, xsev->property, ofs, Err gopher.r-36.net 70 i+ if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, Err gopher.r-36.net 70 i BUFSIZ/4, False, AnyPropertyType, Err gopher.r-36.net 70 i &type, &format, &nitems, &rem, Err gopher.r-36.net 70 i &data)) { Err gopher.r-36.net 70 i@@ -1050,6 +1076,35 @@ selnotify(XEvent *e) Err gopher.r-36.net 70 i return; Err gopher.r-36.net 70 i } Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i+ if (e->type == PropertyNotify && nitems == 0 && rem == 0) { Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * If there is some PropertyNotify with no data, then Err gopher.r-36.net 70 i+ * this is the signal of the selection owner that all Err gopher.r-36.net 70 i+ * data has been transferred. We won't need to receive Err gopher.r-36.net 70 i+ * PropertyNotify events anymore. Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask); Err gopher.r-36.net 70 i+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, Err gopher.r-36.net 70 i+ &xw.attrs); Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ if (type == incratom) { Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * Activate the PropertyNotify events so we receive Err gopher.r-36.net 70 i+ * when the selection owner does send us the next Err gopher.r-36.net 70 i+ * chunk of data. Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); Err gopher.r-36.net 70 i+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, Err gopher.r-36.net 70 i+ &xw.attrs); Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * Deleting the property is the transfer start signal. Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ XDeleteProperty(xw.dpy, xw.win, (int)property); Err gopher.r-36.net 70 i+ continue; Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i /* Err gopher.r-36.net 70 i * As seen in getsel: Err gopher.r-36.net 70 i * Line endings are inconsistent in the terminal and GUI world Err gopher.r-36.net 70 i@@ -1072,6 +1127,13 @@ selnotify(XEvent *e) Err gopher.r-36.net 70 i /* number of 32-bit chunks returned */ Err gopher.r-36.net 70 i ofs += nitems * format / 32; Err gopher.r-36.net 70 i } while (rem > 0); Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * Deleting the property again tells the selection owner to send the Err gopher.r-36.net 70 i+ * next data chunk in the property. Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ if (e->type == PropertyNotify) Err gopher.r-36.net 70 i+ XDeleteProperty(xw.dpy, xw.win, (int)property); Err gopher.r-36.net 70 i } Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i void Err gopher.r-36.net 70 .