hi st users,
here is a patch to support xclipboard st.
the code was extracted and adapted from x11.c of qemacs.
please try and if there is something to change, Iet me know.
pd: Aurélien, thanks for accepting my previous patch.
pd2: sorry my bad english.
saludos
-f
# HG changeset patch
# User fl
# Date 1286656688 10800
# Node ID 3be141f80d5ac30dd786dafc3769964c62d2e887
# Parent 96c41df08c947e720ad46ca4adadd5f4e59a0108
xclipboard support
diff -r 96c41df08c94 -r 3be141f80d5a st.c
--- a/st.c Tue Sep 21 16:04:13 2010 +0200
+++ b/st.c Sat Oct 09 17:38:08 2010 -0300
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
+#include <X11/Xatom.h>
#include <X11/Xutil.h>
#if defined(__linux)
@@ -199,6 +200,8 @@
static void brelease(XEvent *);
static void bpress(XEvent *);
static void bmotion(XEvent *);
+static void selsend(XEvent *);
+static void selclear(XEvent *);
static void (*handler[LASTEvent])(XEvent *) = {
@@ -212,6 +215,8 @@
[MotionNotify] = bmotion,
[ButtonPress] = bpress,
[ButtonRelease] = brelease,
+ [SelectionRequest] = selsend,
+ [SelectionClear] = selclear,
};
/* Globals */
@@ -277,15 +282,119 @@
return str;
}
-/* TODO: use X11 clipboard */
+/* use X11 clipboard */
static void selcopy(char *str) {
+ static Atom xa_clipboard = None;
+
free(sel.clip);
sel.clip = str;
+
+ /* own selection from now */
+ XSetSelectionOwner(xw.dis, XA_PRIMARY, xw.win, CurrentTime);
+
+ /* Ctrl-V request support */
+ if (xa_clipboard == None) /* avoid Xmu */
+ xa_clipboard = XInternAtom(xw.dis, "CLIPBOARD", False);
+ XSetSelectionOwner(xw.dis, xa_clipboard, xw.win, CurrentTime);
+}
+
+static Bool seltest(Display *dpy, XEvent *ev, char *arg) {
+ return (ev->type == SelectionNotify);
}
static void selpaste() {
- if(sel.clip)
+ Window w;
+ Atom prop;
+ unsigned long nread, bytes_after, nitems;
+ unsigned char *data;
+ Atom actual_type;
+ int actual_fmt;
+ XEvent xev;
+
+ w = XGetSelectionOwner(xw.dis, XA_PRIMARY);
+ if (w == None)
+ return;
+ /* st is the owner, directly write sel.clip */
+ if (w == xw.win && sel.clip) {
ttywrite(sel.clip, strlen(sel.clip));
+ return;
+ }
+
+ /* use X11 selection (Will be pasted when receiving
+ SelectionNotify event) */
+ prop = XInternAtom(xw.dis, "VT_SELECTION", False);
+ XConvertSelection(xw.dis, XA_PRIMARY, XA_STRING,
+ prop, xw.win, CurrentTime);
+
+ /* XXX: add timeout too if the target application
+ is not well educated */
+ XIfEvent(xw.dis, &xev, seltest, NULL);
+
+ w = xev.xselection.requestor;
+ prop = xev.xselection.property;
+
+ nread = 0;
+ for(;;) {
+ if ((XGetWindowProperty(xw.dis, w, prop, nread/4, 4096,
+ True, AnyPropertyType, &actual_type, &actual_fmt,
+ &nitems, &bytes_after, &data) != Success)
+ || (actual_type != XA_STRING)) {
+ XFree (data);
+ break;
+ }
+
+ ttywrite((char*) data, nitems);
+
+ nread += nitems;
+ XFree (data);
+ }
+}
+
+/* send selection to requestor */
+static void selsend(XEvent *xev)
+{
+ static Atom xa_targets = None;
+ XSelectionRequestEvent *rq = (XSelectionRequestEvent *) xev;
+ XEvent ev;
+
+ if (xa_targets == None)
+ xa_targets = XInternAtom (xw.dis, "TARGETS", False);
+
+ ev.xselection.type = SelectionNotify;
+ ev.xselection.property = None;
+ ev.xselection.display = rq->display;
+ ev.xselection.requestor = rq->requestor;
+ ev.xselection.selection = rq->selection;
+ ev.xselection.target = rq->target;
+ ev.xselection.time = rq->time;
+
+ if (rq->target == xa_targets) {
+ unsigned int target_list[2];
+
+ /* indicate which are supported types */
+ target_list[0] = xa_targets;
+ target_list[1] = XA_STRING;
+
+ XChangeProperty (xw.dis, rq->requestor, rq->property,
+ xa_targets, 8 * sizeof(target_list[0]), PropModeReplace,
+ (unsigned char *) target_list,
+ sizeof(target_list) / sizeof(target_list[0]));
+ } else if (rq->target == XA_STRING) {
+ /* get selection buffer */
+
+ if (!sel.clip)
+ return;
+
+ XChangeProperty (xw.dis, rq->requestor, rq->property,
+ XA_STRING, 8, PropModeReplace,
+ (unsigned char *)sel.clip, strlen(sel.clip));
+ }
+ ev.xselection.property = rq->property;
+ XSendEvent (xw.dis, rq->requestor, False, 0, &ev);
+}
+
+static void selclear(XEvent *e) {
+ /* TODO */
}
/* TODO: doubleclick to select word */