+ str = NULL;
+ else {
+ sz = (term.col+1) * (sel.e.y-sel.b.y+1) * UTF_SIZ;
+ ptr = str = malloc(sz);
+ for(y = 0; y < term.row; y++) {
+ for(x = 0; x < term.col; x++)
+ if(term.line[y][x].state & GLYPH_SET && (ls = selected(x, y))) {
+ sl = utf8size(term.line[y][x].c);
+ memcpy(ptr, term.line[y][x].c, sl);
+ ptr += sl;
+ }
+ if(ls && y < sel.e.y)
+ *ptr++ = '\n';
+ }
+ *ptr = 0;
+ }
+ xsetsel(str);
+}
+
+void
+selnotify(XEvent *e) {
+ unsigned long nitems;
+ unsigned long ofs, rem;
+ int format;
+ unsigned char *data;
+ Atom type;
+
+ ofs = 0;
+ do {
+ if(XGetWindowProperty(xw.dpy, xw.win, XA_PRIMARY, ofs, BUFSIZ/4,
+ False, AnyPropertyType, &type, &format,
+ &nitems, &rem, &data)) {
+ fprintf(stderr, "Clipboard allocation failed\n");
+ return;
+ }
+ ttywrite((const char *) data, nitems * format / 8);
+ XFree(data);
+ /* number of 32-bit chunks returned */
+ ofs += nitems * format / 32;
+ } while(rem > 0);
+}
+
+void
+selpaste() {
+ XConvertSelection(xw.dpy, XA_PRIMARY, XA_STRING, XA_PRIMARY, xw.win, CurrentTime);
+}
+
+void
+selrequest(XEvent *e) {
+ XSelectionRequestEvent *xsre;
+ XSelectionEvent xev;
+ Atom xa_targets;
+
+ xsre = (XSelectionRequestEvent *) e;
+ xev.type = SelectionNotify;
+ xev.requestor = xsre->requestor;
+ xev.selection = xsre->selection;
+ xev.target = xsre->target;
+ xev.time = xsre->time;
+ /* reject */
+ xev.property = None;
+
+ xa_targets = XInternAtom(xw.dpy, "TARGETS", 0);
+ if(xsre->target == xa_targets) {
+ /* respond with the supported type */
+ Atom string = XA_STRING;
+ XChangeProperty(xsre->display, xsre->requestor, xsre->property,
+ XA_ATOM, 32, PropModeReplace,
+ (unsigned char *) &string, 1);
+ xev.property = xsre->property;
+ } else if(xsre->target == XA_STRING) {
+ XChangeProperty(xsre->display, xsre->requestor, xsre->property,
+ xsre->target, 8, PropModeReplace,
+ (unsigned char *) sel.clip, strlen(sel.clip));
+ xev.property = xsre->property;