#include <ctype.h>
#include <stdio.h>
#include <string.h>			/* for strcmp() */
#ifdef __STDC__
#include <stdlib.h>			/* for exit()... */
#endif
#ifndef VMS
#include <unistd.h>			/* for read(), write() */
#endif
#include <X11/Xatom.h>			/* for pre-defined atom names */
#include <X11/StringDefs.h>		/* for XtNforeground et.al.*/
/* #include <X11/Intrinsic.h> */
#include <X11/IntrinsicP.h>		/* needed for CorePart et.al.*/




#define	_printf		(void) printf
#define	_fprintf	(void) fprintf
#define	_sprintf	(void) sprintf

#define	eq(a,b)		(strcmp((a),(b)) == 0)
#define	min(a,b)	((a) < (b)? (a): (b))
#define	max(a,b)	((a) > (b)? (a): (b))

#define	XtNbufferCount	"bufferCount"		/* Application resources */
#define	XtCBufferCount	"BufferCount"
#define	XtNlayout	"layout"
#define	XtCLayout	"Layout"

#define	PGM_NAME	"printpuffer"
#define	PGM_CLASS	"Printpuffer"
#define	BUFINC		2048

static Display		*dpy;
static Window		root;
static XtAppContext	app;
static Widget		top, box, *wdg;
static Atom		delwin;
static Atom		*atom;
static int		natoms, nbuffs;
static Window		seln;



/*
 * Fetch the contents of cut buffer n from the root window.
 */
static char *
fetch_buffer(a, nb)
Atom	a;
int	*nb;
{
	Atom		actl_type;
	int		actl_format;
	unsigned long	nitems, after;
	char		*data;

	*nb = 0;
	if (XGetWindowProperty(dpy, root, a,
			0L, 10000000L, False, XA_STRING,
			&actl_type, &actl_format, &nitems,
			&after, (unsigned char **) &data) != Success)
		return NULL;

	if (actl_type == XA_STRING && actl_format != 32) {
		*nb = nitems;
		return data;
	}
	if (data != NULL)
		XFree(data);
	return NULL;
}


/*
 * Print the contents of a cut buffer on stdout.
 */
static void
doprint(n, ptr, nb)
int	n;
char	*ptr;
int	nb;
{
	char	tmp[32];

	if (!atom[0]) {
		_sprintf(tmp, "CUT_BUFFER%d", 0);
		atom[0] = XInternAtom(dpy, tmp, (Bool) True);
       }
	if (atom[0]) {
		ptr = fetch_buffer(atom[0], &nb);
		if (write(1, ptr, nb) != nb) {
			_fprintf(stderr, "Write error\n");
			exit(1);
		}
		XFree(ptr);
	}
}



static void
timeout(arg, id)
char	*arg;
XtIntervalId *id;
{
	exit(2);
}

/*
 * Copy the PRIMARY selection into a cut buffer.
 */
static void
dogetseln(n, ptr, nb)
int	n;
char	*ptr;
int	nb;
{
	char	*data;
	int	nbytes;
	XEvent	event;
	char	tmp[32];


	if (!atom[0]) {
		_sprintf(tmp, "CUT_BUFFER%d", 0);
		atom[0] = XInternAtom(dpy, tmp, (Bool) False);
	}

	if (XGetSelectionOwner(dpy, XA_PRIMARY) == None) {
		return;
	}

	XSelectInput(dpy, root, PropertyChangeMask);
	XConvertSelection(dpy, XA_PRIMARY, XA_STRING, atom[0], root, CurrentTime);
	XtAppAddTimeOut(app, 3000, timeout, (char *)0);

	for (;;) {
		XtAppNextEvent(app, &event);
		if (event.type == PropertyNotify
			&& event.xproperty.window == root
			&& event.xproperty.atom == atom[0]
			&& event.xproperty.state == PropertyNewValue) {
			return;
		}
		XtDispatchEvent(&event);	/* This cannot happen. !!?? */
	}
}


typedef struct {
	int	nbuffs;
	char	*layout;
} ares_t, *ares_ptr;

static ares_t	ares;

static XtResource	res[] = {
#define offset(field)		XtOffset(ares_ptr, field)
	{ XtNbufferCount, XtCBufferCount, XtRInt, sizeof(int), 
		offset(nbuffs), XtRImmediate, (XtPointer) 8 },
	{ XtNlayout, XtCLayout, XtRString, sizeof(char *),
		offset(layout), XtRImmediate, "horiz" },
#undef offset
};



static char		*def[] = {		/* default resource values */
	".bufferCount:		8",
	".layout:		horizontal",
	"*font:			fixed",
	"*Buffer.width:		60",
	"*Buffer.height:	60",
	0,
};

static XrmOptionDescRec opt[] = {
	{ "-n",	".bufferCount",	XrmoptionSepArg, (caddr_t) 8 },
	{ "-l",	".layout",	XrmoptionSepArg, (caddr_t) "horiz" },
};



main(argc, argv)
int	argc;
char	**argv;
{
	int	i, n;
	char	**p;
	char	name[16];
	Arg	args[3];

	/*
	 * Set up the atoms that we already know about.
	 */
	natoms = 1;
	atom = (Atom *) XtMalloc(natoms * sizeof(Atom));
	atom[0] = XA_CUT_BUFFER0;

	/*
	 * Initialize the toolkit, parse the command line,
	 * initialize the resources database, and find out
	 * how many buffers to deal with.
	 */
	top = XtAppInitialize(&app, PGM_CLASS, opt, 2, &argc, argv, def, 0, 0);
	dpy = XtDisplay(top);
	root = RootWindow(dpy, DefaultScreen(dpy));

	XtGetApplicationResources(top, &ares, res, XtNumber(res), 0, 0);
	nbuffs = max(ares.nbuffs, 1);


       /**********************************************************/
       
       dogetseln(0, (char *)0, 0); 
       doprint(0, (char *)0, 0);


/*        exit(0); */
	return 0;
}



