diff options
-rw-r--r-- | src/cmd/snarfer.c | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/src/cmd/snarfer.c b/src/cmd/snarfer.c deleted file mode 100644 index 16f9b2ba..00000000 --- a/src/cmd/snarfer.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * This program is only intended for OS X, but the - * ifdef __APPLE__ below lets us build it on all systems. - * On non-OS X systems, you can use it to hold the snarf - * buffer around after a program exits. - */ - -#include <u.h> -#define Colormap XColormap -#define Cursor XCursor -#define Display XDisplay -#define Drawable XDrawable -#define Font XFont -#define GC XGC -#define Point XPoint -#define Rectangle XRectangle -#define Screen XScreen -#define Visual XVisual -#define Window XWindow -#include <X11/Xlib.h> -#include <X11/Xatom.h> -#include <X11/Xutil.h> -#include <X11/keysym.h> -#include <X11/IntrinsicP.h> -#include <X11/StringDefs.h> -#undef Colormap -#undef Cursor -#undef Display -#undef Drawable -#undef Font -#undef GC -#undef Point -#undef Rectangle -#undef Screen -#undef Visual -#undef Window -#ifdef __APPLE__ -#define APPLESNARF -#define Boolean AppleBoolean -#define Rect AppleRect -#define EventMask AppleEventMask -#define Point ApplePoint -#define Cursor AppleCursor -#include <Carbon/Carbon.h> -AUTOFRAMEWORK(Carbon) -#undef Boolean -#undef Rect -#undef EventMask -#undef Point -#undef Cursor -#endif -#include <libc.h> -#undef time -AUTOLIB(draw) /* to cause link of X11 */ - -enum { - SnarfSize = 65536, -}; -char snarf[3*SnarfSize+1]; -Rune rsnarf[SnarfSize+1]; -XDisplay *xdisplay; -XWindow drawable; -Atom xclipboard; -Atom xutf8string; -Atom xtargets; -Atom xtext; -Atom xcompoundtext; - -void xselectionrequest(XEvent*); -char *xgetsnarf(void); -void appleputsnarf(void); -void xputsnarf(void); - -int verbose; - -#ifdef __APPLE__ -PasteboardRef appleclip; -#endif - -void -usage(void) -{ - fprint(2, "usage: snarfer [-v]\n"); - exits("usage"); -} - -void -main(int argc, char **argv) -{ - XEvent xevent; - - ARGBEGIN{ - default: - usage(); - case 'v': - verbose = 1; - break; - }ARGEND - - if((xdisplay = XOpenDisplay(nil)) == nil) - sysfatal("XOpenDisplay: %r"); - drawable = XCreateWindow(xdisplay, DefaultRootWindow(xdisplay), - 0, 0, 1, 1, 0, 0, - InputOutput, DefaultVisual(xdisplay, DefaultScreen(xdisplay)), - 0, 0); - if(drawable == None) - sysfatal("XCreateWindow: %r"); - XFlush(xdisplay); - - xclipboard = XInternAtom(xdisplay, "CLIPBOARD", False); - xutf8string = XInternAtom(xdisplay, "UTF8_STRING", False); - xtargets = XInternAtom(xdisplay, "TARGETS", False); - xtext = XInternAtom(xdisplay, "TEXT", False); - xcompoundtext = XInternAtom(xdisplay, "COMPOUND_TEXT", False); - -#ifdef __APPLE__ - if(PasteboardCreate(kPasteboardClipboard, &appleclip) != noErr) - sysfatal("pasteboard create failed"); -#endif - - xgetsnarf(); - appleputsnarf(); - xputsnarf(); - - for(;;){ - XNextEvent(xdisplay, &xevent); - switch(xevent.type){ - case DestroyNotify: - exits(0); - case SelectionClear: - xgetsnarf(); - appleputsnarf(); - xputsnarf(); - if(verbose) - print("snarf{%s}\n", snarf); - break; - case SelectionRequest: - xselectionrequest(&xevent); - break; - } - } -} - -void -xselectionrequest(XEvent *e) -{ - char *name; - Atom a[4]; - XEvent r; - XSelectionRequestEvent *xe; - XDisplay *xd; - - xd = xdisplay; - - memset(&r, 0, sizeof r); - xe = (XSelectionRequestEvent*)e; -if(0) fprint(2, "xselect target=%d requestor=%d property=%d selection=%d\n", - xe->target, xe->requestor, xe->property, xe->selection); - r.xselection.property = xe->property; - if(xe->target == xtargets){ - a[0] = XA_STRING; - a[1] = xutf8string; - a[2] = xtext; - a[3] = xcompoundtext; - - XChangeProperty(xd, xe->requestor, xe->property, xe->target, - 8, PropModeReplace, (uchar*)a, sizeof a); - }else if(xe->target == XA_STRING || xe->target == xutf8string || xe->target == xtext || xe->target == xcompoundtext){ - /* if the target is STRING we're supposed to reply with Latin1 XXX */ - XChangeProperty(xd, xe->requestor, xe->property, xe->target, - 8, PropModeReplace, (uchar*)snarf, strlen(snarf)); - }else{ - name = XGetAtomName(xd, xe->target); - if(strcmp(name, "TIMESTAMP") != 0) - fprint(2, "%s: cannot handle selection request for '%s' (%d)\n", argv0, name, (int)xe->target); - r.xselection.property = None; - } - - r.xselection.display = xe->display; - /* r.xselection.property filled above */ - r.xselection.target = xe->target; - r.xselection.type = SelectionNotify; - r.xselection.requestor = xe->requestor; - r.xselection.time = xe->time; - r.xselection.send_event = True; - r.xselection.selection = xe->selection; - XSendEvent(xd, xe->requestor, False, 0, &r); - XFlush(xd); -} - -char* -xgetsnarf(void) -{ - uchar *data, *xdata; - Atom clipboard, type, prop; - ulong len, lastlen, dummy; - int fmt, i; - XWindow w; - XDisplay *xd; - - xd = xdisplay; - - /* - * Is there a primary selection (highlighted text in an xterm)? - */ - clipboard = XA_PRIMARY; - w = XGetSelectionOwner(xd, XA_PRIMARY); - if(w == drawable) - return snarf; - - /* - * If not, is there a clipboard selection? - */ - if(w == None && xclipboard != None){ - clipboard = xclipboard; - w = XGetSelectionOwner(xd, xclipboard); - if(w == drawable) - return snarf; - } - - /* - * If not, give up. - */ - if(w == None) - return nil; - - /* - * We should be waiting for SelectionNotify here, but it might never - * come, and we have no way to time out. Instead, we will clear - * local property #1, request our buddy to fill it in for us, and poll - * until he's done or we get tired of waiting. - * - * We should try to go for _x.utf8string instead of XA_STRING, - * but that would add to the polling. - */ - prop = 1; - XChangeProperty(xd, drawable, prop, XA_STRING, 8, PropModeReplace, (uchar*)"", 0); - XConvertSelection(xd, clipboard, XA_STRING, prop, drawable, CurrentTime); - XFlush(xd); - lastlen = 0; - for(i=0; i<10 || (lastlen!=0 && i<30); i++){ - sleep(100); - XGetWindowProperty(xd, drawable, prop, 0, 0, 0, AnyPropertyType, - &type, &fmt, &dummy, &len, &data); - if(lastlen == len && len > 0) - break; - lastlen = len; - } - if(i == 10) - return nil; - /* get the property */ - data = nil; - XGetWindowProperty(xd, drawable, prop, 0, SnarfSize/sizeof(ulong), 0, - AnyPropertyType, &type, &fmt, &len, &dummy, &xdata); - if(xdata == nil || (type != XA_STRING && type != xutf8string) || len == 0){ - if(xdata) - XFree(xdata); - return nil; - } - if(strlen((char*)xdata) >= SnarfSize){ - XFree(xdata); - return nil; - } - strcpy(snarf, (char*)xdata); - return snarf; -} - -void -xputsnarf(void) -{ - XSetSelectionOwner(xdisplay, XA_PRIMARY, drawable, CurrentTime); - if(xclipboard != None) - XSetSelectionOwner(xdisplay, xclipboard, drawable, CurrentTime); - XFlush(xdisplay); -} - -void -appleputsnarf(void) -{ -#ifdef __APPLE__ - CFDataRef cfdata; - PasteboardSyncFlags flags; - - runesnprint(rsnarf, nelem(rsnarf), "%s", snarf); - if(PasteboardClear(appleclip) != noErr){ - fprint(2, "apple pasteboard clear failed\n"); - return; - } - flags = PasteboardSynchronize(appleclip); - if((flags&kPasteboardModified) || !(flags&kPasteboardClientIsOwner)){ - fprint(2, "apple pasteboard cannot assert ownership\n"); - return; - } - cfdata = CFDataCreate(kCFAllocatorDefault, - (uchar*)rsnarf, runestrlen(rsnarf)*2); - if(cfdata == nil){ - fprint(2, "apple pasteboard cfdatacreate failed\n"); - return; - } - if(PasteboardPutItemFlavor(appleclip, (PasteboardItemID)1, - CFSTR("public.utf16-plain-text"), cfdata, 0) != noErr){ - fprint(2, "apple pasteboard putitem failed\n"); - CFRelease(cfdata); - return; - } - CFRelease(cfdata); -#endif -} - - |