/* vi:set ts=8 sts=4 sw=4:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 * X-Windows communication by Flemming Madsen
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 *
 * Client for sending commands to an '+xcmdsrv' enabled vim.
 * This is mostly a de-Vimified version of if_xcmdsrv.c in vim.
 * See that file for a protocol specification.
 *
 * You can make a test program with a Makefile like:
 *  xcmdsrv_client: xcmdsrv_client.c
 *	cc -o $@ -g -DMAIN -I/usr/X11R6/include -L/usr/X11R6/lib $< -lX11
 *
 */

#include <stdio.h>
#include <string.h>
#ifdef HAVE_SELECT
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#else
#include <sys/poll.h>
#endif
#include <X11/Intrinsic.h>
#include <X11/Xatom.h>

/* Client API */
char * sendToVim(Display *dpy, char *name, char *cmd, int asKeys, int *code);

#ifdef MAIN
/* A sample program */
main(int argc, char **argv)
{
    char    *res;
    int	    code;

    if (argc == 4)
    {
	if ((res = sendToVim(XOpenDisplay(NULL), argv[2], argv[3],
			     argv[1][0] != 'e', &code)) != NULL)
	{
	    if (code)
		printf("Error code returned: %d\n", code);
	    puts(res);
	}
	exit(0);
    }
    else
	fprintf(stderr, "Usage: %s {k|e} <server> <command>", argv[0]);

    exit(1);
}
#endif

/*
 * Maximum size property that can be read at one time by
 * this module:
 */

#define MAX_PROP_WORDS 100000

/*
 * Forward declarations for procedures defined later in this file:
 */

static int	x_error_check(Display *dpy, XErrorEvent *error_event);
static int	AppendPropCarefully(Display *display,
		    Window window, Atom property, char *value, int length);
static Window	LookupName(Display *dpy, char *name,
		    int delete, char **loose);
static int	SendInit(Display *dpy);
static char	*SendEventProc(Display *dpy, XEvent *eventPtr,
				      int expect, int *code);
static int	IsSerialName(char *name);

/* Private variables */
static Atom	registryProperty = None;
static Atom	commProperty = None;
static Window	commWindow = None;
static int	got_x_error = FALSE;


/*
 * sendToVim --
 *	Send to an instance of Vim via the X display.
 *
 * Results:
 *	A string with the result or NULL. Caller must free if non-NULL
 */

    char *
sendToVim(
    Display	*dpy,			/* Where to send. */
    char	*name,			/* Where to send. */
    char	*cmd,			/* What to send. */
    int		asKeys,			/* Interpret as keystrokes or expr ? */
    int		*code)			/* Return code. 0 => OK */
{
    Window	    w;
    Atom	    *plist;
    XErrorHandler   old_handler;
#define STATIC_SPACE 500
    char	    *property, staticSpace[STATIC_SPACE];
    int		    length;
    int		    res;
    static int	    serial = 0;	/* Running count of sent commands.
				 * Used to give each command a
				 * different serial number. */
    XEvent	    event;
    XPropertyEvent  *e = (XPropertyEvent *)&event;
    time_t	    start;
    char	    *result;
    char	    *loosename = NULL;

    if (commProperty == None && dpy != NULL)
    {
	if (SendInit(dpy) < 0)
	    return NULL;
    }

    /*
     * Bind the server name to a communication window.
     *
     * Find any survivor with a serialno attached to the name if the
     * original registrant of the wanted name is no longer present.
     *
     * Delete any lingering names from dead editors.
     */

    old_handler = XSetErrorHandler(x_error_check);
    while (TRUE)
    {
	got_x_error = FALSE;
	w = LookupName(dpy, name, 0, &loosename);
	/* Check that the window is hot */
	if (w != None)
	{
	    plist = XListProperties(dpy, w, &res);
	    XSync(dpy, False);
	    if (plist != NULL)
		XFree(plist);
	    if (got_x_error)
	    {
		LookupName(dpy, loosename ? loosename : name,
			   /*DELETE=*/TRUE, NULL);
		continue;
	    }
	}
	break;
    }
    if (w == None)
    {
	fprintf(stderr, "no registered server named %s\n", name);
	return NULL;
    }
    else if (loosename != NULL)
	name = loosename;

    /*
     * Send the command to target interpreter by appending it to the
     * comm window in the communication window.
     */

    length = strlen(name) + strlen(cmd) + 10;
    if (length <= STATIC_SPACE)
	property = staticSpace;
    else
	property = (char *) malloc((unsigned) length);

    serial++;
    sprintf(property, "%c%c%c-n %s%c-s %s",
		      0, asKeys ? 'k' : 'c', 0, name, 0, cmd);
    if (name == loosename)
	free(loosename);
    if (!asKeys)
    {
	/* Add a back reference to our comm window */
	sprintf(property + length, "%c-r %x %d", 0, (uint) commWindow, serial);
	length += strlen(property + length + 1) + 1;
    }

    res = AppendPropCarefully(dpy, w, commProperty, property, length + 1);
    if (length > STATIC_SPACE)
	free(property);
    if (res < 0)
    {
	fprintf(stderr, "Failed to send command to the destination program\n");
	return NULL;
    }

    if (asKeys) /* There is no answer for this - Keys are sent async */
	return NULL;


    /*
     * Enter a loop processing X events & pooling chars until we see the result
     */

#define SEND_MSEC_POLL 50

    time(&start);
    while ((time((time_t *) 0) - start) < 60)
    {
	/* Look out for the answer */
#ifndef HAVE_SELECT
	struct pollfd   fds;

	fds.fd = ConnectionNumber(dpy);
	fds.events = POLLIN;
	if (poll(&fds, 1, SEND_MSEC_POLL) < 0)
	    break;
#else
	fd_set	    fds;
	struct timeval  tv;

	tv.tv_sec = 0;
	tv.tv_usec =  SEND_MSEC_POLL * 1000;
	FD_ZERO(&fds);
	FD_SET(ConnectionNumber(dpy), &fds);
	if (select(ConnectionNumber(dpy) + 1, &fds, NULL, NULL, &tv) < 0)
	    break;
#endif
	while (XEventsQueued(dpy, QueuedAfterReading) > 0)
	{
	    XNextEvent(dpy, &event);
	    if (event.type == PropertyNotify && e->window == commWindow)
		if ((result = SendEventProc(dpy, &event, serial, code)) != NULL)
		    return result;
	}
    }
    return NULL;
}


/*
 * SendInit --
 *	This procedure is called to initialize the
 *	communication channels for sending commands and
 *	receiving results.
 */

    static int
SendInit(Display *dpy)
{
    XErrorHandler old_handler;

    /*
     * Create the window used for communication, and set up an
     * event handler for it.
     */
    old_handler = XSetErrorHandler(x_error_check);
    got_x_error = FALSE;

    commProperty = XInternAtom(dpy, "Comm", False);
    /* Change this back to "InterpRegistry" to talk to tk processes */
    registryProperty = XInternAtom(dpy, "VimRegistry", False);

    if (commWindow == None)
    {
	commWindow =
	    XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy),
				getpid(), 0, 10, 10, 0,
				WhitePixel(dpy, DefaultScreen(dpy)),
				WhitePixel(dpy, DefaultScreen(dpy)));
	XSelectInput(dpy, commWindow, PropertyChangeMask);
    }

    XSync(dpy, False);
    (void) XSetErrorHandler(old_handler);

    return got_x_error ? -1 : 0;
}

/*
 * LookupName --
 *	Given an interpreter name, see if the name exists in
 *	the interpreter registry for a particular display.
 *
 * Results:
 *	If the given name is registered, return the ID of
 *	the window associated with the name.  If the name
 *	isn't registered, then return 0.
 */

    static Window
LookupName(
    Display *dpy,	/* Display whose registry to check. */
    char *name,		/* Name of an interpreter. */
    int delete,		/* If non-zero, delete info about name. */
    char **loose)	/* Do another search matching -999 if not found
			   Return result here if a match is found */
{
    unsigned char   *regProp, *entry;
    unsigned char   *p;
    int		    result, actualFormat;
    unsigned long   numItems, bytesAfter;
    Atom	    actualType;
    Window	    returnValue;

    /*
     * Read the registry property.
     */

    regProp = NULL;
    result = XGetWindowProperty(dpy, RootWindow(dpy, 0), registryProperty, 0,
				MAX_PROP_WORDS, False, XA_STRING, &actualType,
				&actualFormat, &numItems, &bytesAfter,
				&regProp);

    if (actualType == None)
	return 0;

    /*
     * If the property is improperly formed, then delete it.
     */

    if ((result != Success) || (actualFormat != 8) || (actualType != XA_STRING))
    {
	if (regProp != NULL)
	    XFree(regProp);
	XDeleteProperty(dpy, RootWindow(dpy, 0), registryProperty);
	return 0;
    }

    /*
     * Scan the property for the desired name.
     */

    returnValue = None;
    entry = NULL;	/* Not needed, but eliminates compiler warning. */
    for (p = regProp; (p - regProp) < numItems; )
    {
	entry = p;
	while ((*p != 0) && (!isspace(*p)))
	    p++;
	if ((*p != 0) && (strcasecmp(name, p + 1) == 0))
	{
	    sscanf(entry, "%x", (uint*) &returnValue);
	    break;
	}
	while (*p != 0)
	    p++;
	p++;
    }

    if (loose != NULL && returnValue == None && !IsSerialName(name))
    {
	for (p = regProp; (p - regProp) < numItems; )
	{
	    entry = p;
	    while ((*p != 0) && (!isspace(*p)))
		p++;
	    if ((*p != 0) && IsSerialName(p + 1)
		    && (strncmp(name, p + 1, strlen(name)) == 0))
	    {
		sscanf(entry, "%x", (uint*) &returnValue);
		*loose = strdup(p + 1);
		break;
	    }
	    while (*p != 0)
		p++;
	    p++;
	}
    }

    /*
     * Delete the property, if that is desired (copy down the
     * remainder of the registry property to overlay the deleted
     * info, then rewrite the property).
     */

    if ((delete) && (returnValue != None))
    {
	int count;

	while (*p != 0)
	    p++;
	p++;
	count = numItems - (p-regProp);
	if (count > 0)
	    memcpy(entry, p, count);
	XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING,
			8, PropModeReplace, regProp,
			(int) (numItems - (p-entry)));
	XSync(dpy, False);
    }

    XFree(regProp);
    return returnValue;
}

    static char *
SendEventProc(
    Display	   *dpy,
    XEvent	    *eventPtr,		/* Information about event. */
    int		    expected,		/* The one were waiting for */
    int		    *code)		/* Return code. 0 => OK */
{
    unsigned char   *propInfo;
    unsigned char   *p;
    int		    result, actualFormat;
    int		    retCode;
    unsigned long   numItems, bytesAfter;
    Atom	    actualType;

    if ((eventPtr->xproperty.atom != commProperty)
	    || (eventPtr->xproperty.state != PropertyNewValue))
    {
	return;
    }

    /*
     * Read the comm property and delete it.
     */

    propInfo = NULL;
    result = XGetWindowProperty(dpy, commWindow, commProperty, 0,
				MAX_PROP_WORDS, True, XA_STRING, &actualType,
				&actualFormat, &numItems, &bytesAfter,
				&propInfo);

    /*
     * If the property doesn't exist or is improperly formed
     * then ignore it.
     */

    if ((result != Success) || (actualType != XA_STRING)
	    || (actualFormat != 8))
    {
	if (propInfo != NULL)
	{
	    XFree(propInfo);
	}
	return;
    }

    /*
     * Several commands and results could arrive in the property at
     * one time;  each iteration through the outer loop handles a
     * single command or result.
     */

    for (p = propInfo; (p - propInfo) < numItems; )
    {
	/*
	 * Ignore leading NULs; each command or result starts with a
	 * NUL so that no matter how badly formed a preceding command
	 * is, we'll be able to tell that a new command/result is
	 * starting.
	 */

	if (*p == 0)
	{
	    p++;
	    continue;
	}

	if ((*p == 'r') && (p[1] == 0))
	{
	    int	    serial, gotSerial;
	    char  *res;

	    /*
	     * This is a reply to some command that we sent out.  Iterate
	     * over all of its options.  Stop when we reach the end of the
	     * property or something that doesn't look like an option.
	     */

	    p += 2;
	    gotSerial = 0;
	    res = "";
	    retCode = 0;
	    while (((p-propInfo) < numItems) && (*p == '-'))
	    {
		switch (p[1])
		{
		    case 'r':
			if (p[2] == ' ')
			    res = p + 3;
			break;
		    case 's':
			if (sscanf(p + 2, " %d", &serial) == 1)
			    gotSerial = 1;
			break;
		    case 'c':
			if (sscanf(p + 2, " %d", &retCode) != 1)
			    retCode = 0;
			break;
		}
		while (*p != 0)
		    p++;
		p++;
	    }

	    if (!gotSerial)
		continue;

	    if (code != NULL)
		*code = retCode;
	    return serial == expected ? strdup(res) : NULL;
	}
	else
	{
	    /*
	     * Didn't recognize this thing.  Just skip through the next
	     * null character and try again.
	     * Also, throw away commands that we cant process anyway.
	     */

	    while (*p != 0)
		p++;
	    p++;
	}
    }
    XFree(propInfo);
}

/*
 * AppendPropCarefully --
 *
 *	Append a given property to a given window, but set up
 *	an X error handler so that if the append fails this
 *	procedure can return an error code rather than having
 *	Xlib panic.
 *
 *  Return:
 *	0 on OK - -1 on error
 *--------------------------------------------------------------
 */

    static int
AppendPropCarefully(
    Display *dpy,		/* Display on which to operate. */
    Window window,		/* Window whose property is to
				 * be modified. */
    Atom property,		/* Name of property. */
    char *value,		/* Characters  to append to property. */
    int  length)		/* How much to append */
{
    XErrorHandler old_handler;

    old_handler = XSetErrorHandler(x_error_check);
    got_x_error = FALSE;
    XChangeProperty(dpy, window, property, XA_STRING, 8,
		    PropModeAppend, value, length);
    XSync(dpy, False);
    (void) XSetErrorHandler(old_handler);
    return got_x_error ? -1 : 0;
}


/*
 * Another X Error handler, just used to check for errors.
 */
/* ARGSUSED */
    static int
x_error_check(Display *dpy, XErrorEvent *error_event)
{
    got_x_error = TRUE;
    return 0;
}

/*
 * Check if "str" looks like it had a serial number appended.
 * Actually just checks if the name ends in a digit.
 */
    static int
IsSerialName(char *str)
{
    int len = strlen(str);

    return (len > 1 && isdigit(str[len - 1]));
}
