aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorChristoph Lohmann <20h@r-36.net>2015-07-10 14:10:17 +0200
committerChristoph Lohmann <20h@r-36.net>2015-07-10 14:10:17 +0200
commitf8c6e7d0419d10c1425cb2c7123c5798ffb3b942 (patch)
tree659acb41481f2c8f7e7575ecbfd174312b3efbcb /st.c
parent539afe3af1b0d8b56b9ebfaa3bb7fc4e40f68c71 (diff)
downloadst-f8c6e7d0419d10c1425cb2c7123c5798ffb3b942.tar.gz
st-f8c6e7d0419d10c1425cb2c7123c5798ffb3b942.zip
Implement INCR transfers in the clipboard.
Diffstat (limited to 'st.c')
-rw-r--r--st.c74
1 files changed, 68 insertions, 6 deletions
diff --git a/st.c b/st.c
index 274ac5d..17e0a65 100644
--- a/st.c
+++ b/st.c
@@ -452,6 +452,7 @@ static void focus(XEvent *);
452static void brelease(XEvent *); 452static void brelease(XEvent *);
453static void bpress(XEvent *); 453static void bpress(XEvent *);
454static void bmotion(XEvent *); 454static void bmotion(XEvent *);
455static void propnotify(XEvent *);
455static void selnotify(XEvent *); 456static void selnotify(XEvent *);
456static void selclear(XEvent *); 457static void selclear(XEvent *);
457static void selrequest(XEvent *); 458static void selrequest(XEvent *);
@@ -500,6 +501,11 @@ static void (*handler[LASTEvent])(XEvent *) = {
500 */ 501 */
501/* [SelectionClear] = selclear, */ 502/* [SelectionClear] = selclear, */
502 [SelectionNotify] = selnotify, 503 [SelectionNotify] = selnotify,
504/*
505 * PropertyNotify is only turned on when there is some INCR transfer happening
506 * for the selection retrieval.
507 */
508 [PropertyNotify] = propnotify,
503 [SelectionRequest] = selrequest, 509 [SelectionRequest] = selrequest,
504}; 510};
505 511
@@ -1029,20 +1035,40 @@ selcopy(Time t)
1029} 1035}
1030 1036
1031void 1037void
1038propnotify(XEvent *e)
1039{
1040 XPropertyEvent *xpev;
1041 Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
1042
1043 xpev = &e->xproperty;
1044 if (xpev->state == PropertyNewValue &&
1045 (xpev->atom == XA_PRIMARY ||
1046 xpev->atom == clipboard)) {
1047 slenotify(e);
1048 }
1049}
1050
1051void
1032selnotify(XEvent *e) 1052selnotify(XEvent *e)
1033{ 1053{
1034 ulong nitems, ofs, rem; 1054 ulong nitems, ofs, rem;
1035 int format; 1055 int format;
1036 uchar *data, *last, *repl; 1056 uchar *data, *last, *repl;
1037 Atom type; 1057 Atom type, incratom, property;
1038 XSelectionEvent *xsev;
1039 1058
1040 ofs = 0; 1059 ofs = 0;
1041 xsev = &e->xselection; 1060 if (e->type == SelectionNotify) {
1042 if (xsev->property == None) 1061 property = e->xselection.property;
1043 return; 1062 } else if(e->type == PropertyNotify) {
1063 property = e->xproperty.atom;
1064 } else {
1065 return;
1066 }
1067 if (property == None)
1068 return;
1069
1044 do { 1070 do {
1045 if (XGetWindowProperty(xw.dpy, xw.win, xsev->property, ofs, 1071 if (XGetWindowProperty(xw.dpy, xw.win, property, ofs,
1046 BUFSIZ/4, False, AnyPropertyType, 1072 BUFSIZ/4, False, AnyPropertyType,
1047 &type, &format, &nitems, &rem, 1073 &type, &format, &nitems, &rem,
1048 &data)) { 1074 &data)) {
@@ -1050,6 +1076,35 @@ selnotify(XEvent *e)
1050 return; 1076 return;
1051 } 1077 }
1052 1078
1079 if (e->type == PropertyNotify && nitems == 0 && rem == 0) {
1080 /*
1081 * If there is some PropertyNotify with no data, then
1082 * this is the signal of the selection owner that all
1083 * data has been transferred. We won't need to receive
1084 * PropertyNotify events anymore.
1085 */
1086 MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask);
1087 XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
1088 &xw.attrs);
1089 }
1090
1091 if (type == incratom) {
1092 /*
1093 * Activate the PropertyNotify events so we receive
1094 * when the selection owner does send us the next
1095 * chunk of data.
1096 */
1097 MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
1098 XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
1099 &xw.attrs);
1100
1101 /*
1102 * Deleting the property is the transfer start signal.
1103 */
1104 XDeleteProperty(xw.dpy, xw.win, (int)property);
1105 continue;
1106 }
1107
1053 /* 1108 /*
1054 * As seen in getsel: 1109 * As seen in getsel:
1055 * Line endings are inconsistent in the terminal and GUI world 1110 * Line endings are inconsistent in the terminal and GUI world
@@ -1072,6 +1127,13 @@ selnotify(XEvent *e)
1072 /* number of 32-bit chunks returned */ 1127 /* number of 32-bit chunks returned */
1073 ofs += nitems * format / 32; 1128 ofs += nitems * format / 32;
1074 } while (rem > 0); 1129 } while (rem > 0);
1130
1131 /*
1132 * Deleting the property again tells the selection owner to send the
1133 * next data chunk in the property.
1134 */
1135 if (e->type == PropertyNotify)
1136 XDeleteProperty(xw.dpy, xw.win, (int)property);
1075} 1137}
1076 1138
1077void 1139void