Introduction
Introduction Statistics Contact Development Disclaimer Help
tmove snarfer to use X includes - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
commit bb3b0aeb9c29e8dc21d8e48390ae4ce410563e3c
parent 5db07ba9422804c9de1e8fbda5486722cb731e03
Author: rsc <devnull@localhost>
Date: Fri, 3 Mar 2006 01:42:25 +0000
move snarfer to use X includes
Diffstat:
A src/cmd/snarfer/mkfile | 9 +++++++++
A src/cmd/snarfer/snarfer.c | 310 +++++++++++++++++++++++++++++…
2 files changed, 319 insertions(+), 0 deletions(-)
---
diff --git a/src/cmd/snarfer/mkfile b/src/cmd/snarfer/mkfile
t@@ -0,0 +1,9 @@
+<$PLAN9/src/mkhdr
+
+TARG=snarfer
+OFILES=
+HFILES=
+
+<|sh ../../libdraw/mkwsysrules.sh
+<$PLAN9/src/mkmany
+
diff --git a/src/cmd/snarfer/snarfer.c b/src/cmd/snarfer/snarfer.c
t@@ -0,0 +1,310 @@
+/*
+ * 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->t…
+ /* if the target is STRING we're supposed to reply with Latin1…
+ 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…
+ 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, (uc…
+ XConvertSelection(xd, clipboard, XA_STRING, prop, drawable, CurrentTim…
+ XFlush(xd);
+ lastlen = 0;
+ for(i=0; i<10 || (lastlen!=0 && i<30); i++){
+ sleep(100);
+ XGetWindowProperty(xd, drawable, prop, 0, 0, 0, AnyPropertyTyp…
+ &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 =…
+ 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
+}
+
+
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.