/*
 * 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
}


