diff --git a/src/if_xcmdsrv.c b/src/if_xcmdsrv.c
new file mode 100644
index 0000000..a82139e
--- /dev/null
+++ b/src/if_xcmdsrv.c
@@ -0,0 +1,1441 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ * X command server 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.
+ *
+ * if_xcmdsrv.c: Functions for passing commands through an X11 display.
+ *
+ */
+
+#include "vim.h"
+#include "version.h"
+
+#if defined(FEAT_CLIENTSERVER) || defined(PROTO)
+
+# ifdef FEAT_X11
+#  include <X11/Intrinsic.h>
+#  include <X11/Xatom.h>
+# endif
+
+# if defined(HAVE_SYS_SELECT_H) && \
+	(!defined(HAVE_SYS_TIME_H) || defined(SYS_SELECT_WITH_SYS_TIME))
+#  include <sys/select.h>
+# endif
+
+# ifndef HAVE_SELECT
+#  ifdef HAVE_SYS_POLL_H
+#   include <sys/poll.h>
+#  else
+#   ifdef HAVE_POLL_H
+#    include <poll.h>
+#   endif
+#  endif
+# endif
+
+/*
+ * This file provides procedures that implement the command server functionality
+ * of Vim when in contact with an X11 server.
+ *
+ * Adapted from TCL/TK's send command  in tkSend.c of the tk 3.6 distribution.
+ * Adapted for use in Vim by Flemming Madsen. Protocol changed to that of tk 4
+ */
+
+/*
+ * Copyright (c) 1989-1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+
+/*
+ * When a result is being awaited from a sent command, one of
+ * the following structures is present on a list of all outstanding
+ * sent commands.  The information in the structure is used to
+ * process the result when it arrives.  You're probably wondering
+ * how there could ever be multiple outstanding sent commands.
+ * This could happen if Vim instances invoke each other recursively.
+ * It's unlikely, but possible.
+ */
+
+typedef struct PendingCommand
+{
+    int	    serial;	/* Serial number expected in result. */
+    int	    code;	/* Result Code. 0 is OK */
+    char_u  *result;	/* String result for command (malloc'ed).
+			 * NULL means command still pending. */
+    struct PendingCommand *nextPtr;
+			/* Next in list of all outstanding commands.
+			 * NULL means end of list. */
+} PendingCommand;
+
+static PendingCommand *pendingCommands = NULL;
+				/* List of all commands currently
+				 * being waited for. */
+
+/*
+ * The information below is used for communication between processes
+ * during "send" commands.  Each process keeps a private window, never
+ * even mapped, with one property, "Comm".  When a command is sent to
+ * an interpreter, the command is appended to the comm property of the
+ * communication window associated with the interp's process.  Similarly,
+ * when a result is returned from a sent command, it is also appended
+ * to the comm property.
+ *
+ * Each command and each result takes the form of ASCII text.  For a
+ * command, the text consists of a nul character followed by several
+ * nul-terminated ASCII strings.  The first string consists of the
+ * single letter "c" for an expression, or "k" for keystrokes.  Subsequent
+ * strings have the form "option value" where the following options are
+ * supported:
+ *
+ * -r commWindow serial
+ *
+ *	This option means that a response should be sent to the window
+ *	whose X identifier is "commWindow" (in hex), and the response should
+ *	be identified with the serial number given by "serial" (in decimal).
+ *	If this option isn't specified then the send is asynchronous and
+ *	no response is sent.
+ *
+ * -n name
+ *	"Name" gives the name of the application for which the command is
+ *	intended.  This option must be present.
+ *
+ * -s script
+ *	"Script" is the script to be executed.  This option must be
+ *	present.  Taken as a series of keystrokes in a "k" command where
+ *	<Key>'s are expanded
+ *
+ * The options may appear in any order.  The -n and -s options must be
+ * present, but -r may be omitted for asynchronous RPCs.  For compatibility
+ * with future releases that may add new features, there may be additional
+ * options present;  as long as they start with a "-" character, they will
+ * be ignored.
+ *
+ * A result also consists of a zero character followed by several null-
+ * terminated ASCII strings.  The first string consists of the single
+ * letter "r".  Subsequent strings have the form "option value" where
+ * the following options are supported:
+ *
+ * -s serial
+ *	Identifies the command for which this is the result.  It is the
+ *	same as the "serial" field from the -s option in the command.  This
+ *	option must be present.
+ *
+ * -r result
+ *	"Result" is the result string for the script, which may be either
+ *	a result or an error message.  If this field is omitted then it
+ *	defaults to an empty string.
+ *
+ * -c code
+ *	0: for OK. This is the default.
+ *	1: for error: Result is the last error
+ *
+ * -i errorInfo
+ * -e errorCode
+ *	Not applicable for Vim
+ *
+ * Options may appear in any order, and only the -s option must be
+ * present.  As with commands, there may be additional options besides
+ * these;  unknown options are ignored.
+ */
+
+/*
+ * Maximum size property that can be read at one time by
+ * this module:
+ */
+
+#define MAX_PROP_WORDS 100000
+
+struct ServerReply
+{
+    Window  id;
+    garray_T strings;
+};
+static garray_T serverReply = { 0, 0, 0, 0, 0 };
+enum ServerReplyOp { SROP_Find, SROP_Add, SROP_Delete };
+
+typedef int (*EndCond) __ARGS((void *));
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static Window	LookupName __ARGS((Display *dpy, char_u *name, int delete, char_u **loose));
+static int	SendInit __ARGS((Display *dpy));
+static int	DoRegisterName __ARGS((Display *dpy, char_u *name));
+static void	DeleteAnyLingerer __ARGS((Display *dpy, Window w));
+static int	GetRegProp __ARGS((Display *dpy, char_u **regPropp, long_u *numItemsp, int domsg));
+static int	WaitForPend __ARGS((void *p));
+static int	WaitForReply __ARGS((void *p));
+static int	WindowValid __ARGS((Display *dpy, Window w));
+static void	ServerWait __ARGS((Display *dpy, Window w, EndCond endCond, void *endData, int localLoop, int seconds));
+static struct ServerReply *ServerReplyFind __ARGS((Window w, enum ServerReplyOp op));
+static int	AppendPropCarefully __ARGS((Display *display, Window window, Atom property, char_u *value, int length));
+static int	x_error_check __ARGS((Display *dpy, XErrorEvent *error_event));
+static int	IsSerialName __ARGS((char_u *name));
+
+/* Private variables for the "server" functionality */
+static Atom	registryProperty = None;
+static Atom	vimProperty = None;
+static int	got_x_error = FALSE;
+
+static char_u	*empty_prop = (char_u *)"";	/* empty GetRegProp() result */
+
+/*
+ * Associate an ASCII name with Vim.  Try real hard to get a unique one.
+ * Returns FAIL or OK.
+ */
+    int
+serverRegisterName(dpy, name)
+    Display	*dpy;		/* display to register with */
+    char_u	*name;		/* the name that will be used as a base */
+{
+    int		i;
+    int		res;
+    char_u	*p = NULL;
+
+    res = DoRegisterName(dpy, name);
+    if (res < 0)
+    {
+	i = 1;
+	do
+	{
+	    if (res < -1 || i >= 1000)
+	    {
+		MSG_ATTR(_("Unable to register a command server name"),
+							      hl_attr(HLF_W));
+		return FAIL;
+	    }
+	    if (p == NULL)
+		p = alloc(STRLEN(name) + 10);
+	    if (p == NULL)
+	    {
+		res = -10;
+		continue;
+	    }
+	    sprintf((char *)p, "%s%d", name, i++);
+	    res = DoRegisterName(dpy, p);
+	}
+	while (res < 0)
+	    ;
+	vim_free(p);
+    }
+    return OK;
+}
+
+    static int
+DoRegisterName(dpy, name)
+    Display	*dpy;
+    char_u	*name;
+{
+    Window	w;
+    XErrorHandler old_handler;
+#define MAX_NAME_LENGTH 100
+    char_u	propInfo[MAX_NAME_LENGTH + 20];
+
+    if (commProperty == None)
+    {
+	if (SendInit(dpy) < 0)
+	    return -2;
+    }
+
+    /*
+     * Make sure the name is unique, and append info about it to
+     * the registry property.  It's important to lock the server
+     * here to prevent conflicting changes to the registry property.
+     * WARNING: Do not step through this while debugging, it will hangup the X
+     * server!
+     */
+    XGrabServer(dpy);
+    w = LookupName(dpy, name, FALSE, NULL);
+    if (w != (Window)0)
+    {
+	Status		status;
+	int		dummyInt;
+	unsigned int	dummyUns;
+	Window		dummyWin;
+
+	/*
+	 * The name is currently registered.  See if the commWindow
+	 * associated with the name exists.  If not, or if the commWindow
+	 * is *our* commWindow, then just unregister the old name (this
+	 * could happen if an application dies without cleaning up the
+	 * registry).
+	 */
+	old_handler = XSetErrorHandler(x_error_check);
+	status = XGetGeometry(dpy, w, &dummyWin, &dummyInt, &dummyInt,
+				  &dummyUns, &dummyUns, &dummyUns, &dummyUns);
+	(void)XSetErrorHandler(old_handler);
+	if (status != Success && w != commWindow)
+	{
+	    XUngrabServer(dpy);
+	    XFlush(dpy);
+	    return -1;
+	}
+	(void)LookupName(dpy, name, /*delete=*/TRUE, NULL);
+    }
+    sprintf((char *)propInfo, "%x %.*s", (int_u)commWindow,
+						       MAX_NAME_LENGTH, name);
+    old_handler = XSetErrorHandler(x_error_check);
+    got_x_error = FALSE;
+    XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING, 8,
+		    PropModeAppend, propInfo, STRLEN(propInfo) + 1);
+    XUngrabServer(dpy);
+    XSync(dpy, False);
+    (void)XSetErrorHandler(old_handler);
+
+    if (!got_x_error)
+    {
+#ifdef FEAT_EVAL
+	set_vim_var_string(VV_SEND_SERVER, name, -1);
+#endif
+	serverName = vim_strsave(name);
+#ifdef FEAT_TITLE
+	need_maketitle = TRUE;
+#endif
+	return 0;
+    }
+    return -2;
+}
+
+#if defined(FEAT_GUI) || defined(PROTO)
+/*
+ * Clean out new ID from registry and set it as comm win.
+ * Change any registered window ID.
+ */
+    void
+serverChangeRegisteredWindow(dpy, newwin)
+    Display	*dpy;		/* Display to register with */
+    Window	newwin;		/* Re-register to this ID */
+{
+    char_u	propInfo[MAX_NAME_LENGTH + 20];
+
+    commWindow = newwin;
+
+    /* Always call SendInit() here, to make sure commWindow is marked as a Vim
+     * window. */
+    if (SendInit(dpy) < 0)
+	return;
+
+    /* WARNING: Do not step through this while debugging, it will hangup the X
+     * server! */
+    XGrabServer(dpy);
+    DeleteAnyLingerer(dpy, newwin);
+    if (serverName != NULL)
+    {
+	/* Reinsert name if we was already registered */
+	(void)LookupName(dpy, serverName, /*delete=*/TRUE, NULL);
+	sprintf((char *)propInfo, "%x %.*s",
+		(int_u)newwin, MAX_NAME_LENGTH, serverName);
+	XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING, 8,
+			PropModeAppend, (char_u *)propInfo,
+			STRLEN(propInfo) + 1);
+    }
+    XUngrabServer(dpy);
+}
+#endif
+
+/*
+ * Send to an instance of Vim via the X display.
+ * Returns 0 for OK, negative for an error.
+ */
+    int
+serverSendToVim(dpy, name, cmd,  result, server, asExpr, localLoop, silent)
+    Display	*dpy;			/* Where to send. */
+    char_u	*name;			/* Where to send. */
+    char_u	*cmd;			/* What to send. */
+    char_u	**result;		/* Result of eval'ed expression */
+    Window	*server;		/* Actual ID of receiving app */
+    Bool	asExpr;			/* Interpret as keystrokes or expr ? */
+    Bool	localLoop;		/* Throw away everything but result */
+    int		silent;			/* don't complain about no server */
+{
+    Window	    w;
+    char_u	    *property;
+    int		    length;
+    int		    res;
+    static int	    serial = 0;	/* Running count of sent commands.
+				 * Used to give each command a
+				 * different serial number. */
+    PendingCommand  pending;
+    char_u	    *loosename = NULL;
+
+    if (result != NULL)
+	*result = NULL;
+    if (name == NULL || *name == NUL)
+	name = (char_u *)"GVIM";    /* use a default name */
+
+    if (commProperty == None && dpy != NULL)
+    {
+	if (SendInit(dpy) < 0)
+	    return -1;
+    }
+
+    /* Execute locally if no display or target is ourselves */
+    if (dpy == NULL || (serverName != NULL && STRICMP(name, serverName) == 0))
+    {
+	if (asExpr)
+	{
+	    char_u *ret;
+
+	    ret = eval_client_expr_to_string(cmd);
+	    if (result != NULL)
+	    {
+		if (ret == NULL)
+		    *result = vim_strsave((char_u *)_(e_invexprmsg));
+		else
+		    *result = ret;
+	    }
+	    else
+		vim_free(ret);
+	    return ret == NULL ? -1 : 0;
+	}
+	else
+	    server_to_input_buf(cmd);
+	return 0;
+    }
+
+    /*
+     * 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.
+     */
+    while (TRUE)
+    {
+	w = LookupName(dpy, name, FALSE, &loosename);
+	/* Check that the window is hot */
+	if (w != None)
+	{
+	    if (!WindowValid(dpy, w))
+	    {
+		LookupName(dpy, loosename ? loosename : name,
+			   /*DELETE=*/TRUE, NULL);
+		continue;
+	    }
+	}
+	break;
+    }
+    if (w == None)
+    {
+	if (!silent)
+	    EMSG2(_(e_noserver), name);
+	return -1;
+    }
+    else if (loosename != NULL)
+	name = loosename;
+    if (server != NULL)
+	*server = w;
+
+    /*
+     * Send the command to target interpreter by appending it to the
+     * comm window in the communication window.
+     */
+    length = STRLEN(name) + STRLEN(cmd) + 10;
+    property = (char_u *)alloc((unsigned) length + 30);
+
+    sprintf((char *)property, "%c%c%c-n %s%c-s %s",
+		      0, asExpr ? 'c' : 'k', 0, name, 0, cmd);
+    if (name == loosename)
+	vim_free(loosename);
+    /* Add a back reference to our comm window */
+    serial++;
+    sprintf((char *)property + length, "%c-r %x %d",
+						0, (int_u)commWindow, serial);
+    length += STRLEN(property + length + 1) + 1;
+
+    res = AppendPropCarefully(dpy, w, commProperty, property, length + 1);
+    vim_free(property);
+    if (res < 0)
+    {
+	EMSG(_("E248: Failed to send command to the destination program"));
+	return -1;
+    }
+
+    if (!asExpr) /* There is no answer for this - Keys are sent async */
+	return 0;
+
+    /*
+     * Register the fact that we're waiting for a command to
+     * complete (this is needed by SendEventProc and by
+     * AppendErrorProc to pass back the command's results).
+     */
+    pending.serial = serial;
+    pending.code = 0;
+    pending.result = NULL;
+    pending.nextPtr = pendingCommands;
+    pendingCommands = &pending;
+
+    ServerWait(dpy, w, WaitForPend, &pending, localLoop, 600);
+
+    /*
+     * Unregister the information about the pending command
+     * and return the result.
+     */
+    if (pendingCommands == &pending)
+	pendingCommands = pending.nextPtr;
+    else
+    {
+	PendingCommand *pcPtr;
+
+	for (pcPtr = pendingCommands; pcPtr != NULL; pcPtr = pcPtr->nextPtr)
+	    if (pcPtr->nextPtr == &pending)
+	    {
+		pcPtr->nextPtr = pending.nextPtr;
+		break;
+	    }
+    }
+    if (result != NULL)
+	*result = pending.result;
+    else
+	vim_free(pending.result);
+
+    return pending.code == 0 ? 0 : -1;
+}
+
+    static int
+WaitForPend(p)
+    void    *p;
+{
+    PendingCommand *pending = (PendingCommand *) p;
+    return pending->result != NULL;
+}
+
+/*
+ * Return TRUE if window "w" exists and has a "Vim" property on it.
+ */
+    static int
+WindowValid(dpy, w)
+    Display     *dpy;
+    Window	w;
+{
+    XErrorHandler   old_handler;
+    Atom	    *plist;
+    int		    numProp;
+    int		    i;
+
+    old_handler = XSetErrorHandler(x_error_check);
+    got_x_error = 0;
+    plist = XListProperties(dpy, w, &numProp);
+    XSync(dpy, False);
+    XSetErrorHandler(old_handler);
+    if (plist == NULL || got_x_error)
+	return FALSE;
+
+    for (i = 0; i < numProp; i++)
+	if (plist[i] == vimProperty)
+	{
+	    XFree(plist);
+	    return TRUE;
+	}
+    XFree(plist);
+    return FALSE;
+}
+
+/*
+ * Enter a loop processing X events & polling chars until we see a result
+ */
+    static void
+ServerWait(dpy, w, endCond, endData, localLoop, seconds)
+    Display	*dpy;
+    Window	w;
+    EndCond	endCond;
+    void	*endData;
+    int		localLoop;
+    int		seconds;
+{
+    time_t	    start;
+    time_t	    now;
+    time_t	    lastChk = 0;
+    XEvent	    event;
+    XPropertyEvent *e = (XPropertyEvent *)&event;
+#   define SEND_MSEC_POLL 50
+
+    time(&start);
+    while (endCond(endData) == 0)
+    {
+	time(&now);
+	if (seconds >= 0 && (now - start) >= seconds)
+	    break;
+	if (now != lastChk)
+	{
+	    lastChk = now;
+	    if (!WindowValid(dpy, w))
+		break;
+	    /*
+	     * Sometimes the PropertyChange event doesn't come.
+	     * This can be seen in eg: vim -c 'echo remote_expr("gvim", "3+2")'
+	     */
+	    serverEventProc(dpy, NULL);
+	}
+	if (localLoop)
+	{
+	    /* Just look out for the answer without calling back into Vim */
+#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)
+		    serverEventProc(dpy, &event);
+	    }
+	}
+	else
+	{
+	    if (got_int)
+		break;
+	    ui_delay((long)SEND_MSEC_POLL, TRUE);
+	    ui_breakcheck();
+	}
+    }
+}
+
+
+/*
+ * Fetch a list of all the Vim instance names currently registered for the
+ * display.
+ *
+ * Returns a newline separated list in allocated memory or NULL.
+ */
+    char_u *
+serverGetVimNames(dpy)
+    Display	*dpy;
+{
+    char_u	*regProp;
+    char_u	*entry;
+    char_u	*p;
+    long_u	numItems;
+    int_u	w;
+    garray_T	ga;
+
+    if (registryProperty == None)
+    {
+	if (SendInit(dpy) < 0)
+	    return NULL;
+    }
+    ga_init2(&ga, 1, 100);
+
+    /*
+     * Read the registry property.
+     */
+    if (GetRegProp(dpy, &regProp, &numItems, TRUE) == FAIL)
+	return NULL;
+
+    /*
+     * Scan all of the names out of the property.
+     */
+    ga_init2(&ga, 1, 100);
+    for (p = regProp; (p - regProp) < numItems; p++)
+    {
+	entry = p;
+	while (*p != 0 && !isspace(*p))
+	    p++;
+	if (*p != 0)
+	{
+	    w = None;
+	    sscanf((char *)entry, "%x", &w);
+	    if (WindowValid(dpy, (Window)w))
+	    {
+		ga_concat(&ga, p + 1);
+		ga_concat(&ga, (char_u *)"\n");
+	    }
+	    while (*p != 0)
+		p++;
+	}
+    }
+    if (regProp != empty_prop)
+	XFree(regProp);
+    return ga.ga_data;
+}
+
+/* ----------------------------------------------------------
+ * Reply stuff
+ */
+
+    static struct ServerReply *
+ServerReplyFind(w, op)
+    Window  w;
+    enum ServerReplyOp op;
+{
+    struct ServerReply *p;
+    struct ServerReply e;
+    int		i;
+
+    p = (struct ServerReply *) serverReply.ga_data;
+    for (i = 0; i < serverReply.ga_len; i++, p++)
+	if (p->id == w)
+	    break;
+    if (i >= serverReply.ga_len)
+	p = NULL;
+
+    if (p == NULL && op == SROP_Add)
+    {
+	if (serverReply.ga_growsize == 0)
+	    ga_init2(&serverReply, sizeof(struct ServerReply), 1);
+	if (ga_grow(&serverReply, 1) == OK)
+	{
+	    p = ((struct ServerReply *) serverReply.ga_data)
+		+ serverReply.ga_len;
+	    e.id = w;
+	    ga_init2(&e.strings, 1, 100);
+	    memcpy(p, &e, sizeof(e));
+	    serverReply.ga_len++;
+	    serverReply.ga_room--;
+	}
+    }
+    else if (p != NULL && op == SROP_Delete)
+    {
+	ga_clear(&p->strings);
+	mch_memmove(p, p + 1, (serverReply.ga_len - i - 1) * sizeof(*p));
+	serverReply.ga_len--;
+	serverReply.ga_room++;
+    }
+
+    return p;
+}
+
+/*
+ * Convert string to windowid.
+ * Issue an error if the id is invalid.
+ */
+    Window
+serverStrToWin(str)
+    char_u  *str;
+{
+    unsigned  id = None;
+
+    sscanf((char *)str, "0x%x", &id);
+    if (id == None)
+	EMSG2(_("E573: Invalid server id used: %s"), str);
+
+    return (Window)id;
+}
+
+/*
+ * Send a reply string to client with id "name".
+ * Return -1 if the window is invalid.
+ */
+    int
+serverSendReply(name, str)
+    char_u	*name;
+    char_u	*str;
+{
+    char_u	*property;
+    int		length;
+    int		res;
+    Display	*dpy = X_DISPLAY;
+    Window	win = serverStrToWin(name);
+
+    if (commProperty == None)
+    {
+	if (SendInit(dpy) < 0)
+	    return -2;
+    }
+    if (!WindowValid(dpy, win))
+	return -1;
+
+    length = STRLEN(str) + 7;
+    if ((property = (char_u *)alloc((unsigned) length + 30)) != NULL)
+    {
+	sprintf((char *)property, "%c%c%c-n %s%c-w %x",
+			  0, 'n', 0, str, 0, (unsigned int)commWindow);
+	length += STRLEN(property + length);
+	res = AppendPropCarefully(dpy, win, commProperty, property, length + 1);
+	vim_free(property);
+	return res;
+    }
+    return -1;
+}
+
+    static int
+WaitForReply(p)
+    void    *p;
+{
+    Window  *w = (Window *) p;
+    return ServerReplyFind(*w, SROP_Find) != NULL;
+}
+
+/*
+ * Wait for replies from id (win)
+ * Return 0 and the malloc'ed string when a reply is available.
+ * Return -1 if the window becomes invalid while waiting.
+ */
+    int
+serverReadReply(dpy, win, str, localLoop)
+    Display	*dpy;
+    Window	win;
+    char_u	**str;
+    int		localLoop;
+{
+    int		len;
+    char_u	*s;
+    struct	ServerReply *p;
+
+    ServerWait(dpy, win, WaitForReply, &win, localLoop, -1);
+
+    if ((p = ServerReplyFind(win, SROP_Find)) != NULL && p->strings.ga_len > 0)
+    {
+	*str = vim_strsave(p->strings.ga_data);
+	len = STRLEN(*str) + 1;
+	if (len < p->strings.ga_len)
+	{
+	    s = (char_u *) p->strings.ga_data;
+	    mch_memmove(s, s + len, p->strings.ga_len - len);
+	    p->strings.ga_room += len;
+	    p->strings.ga_len -= len;
+	}
+	else
+	{
+	    /* Last string read.  Remove from list */
+	    ga_clear(&p->strings);
+	    ServerReplyFind(win, SROP_Delete);
+	}
+	return 0;
+    }
+    return -1;
+}
+
+/*
+ * Check for replies from id (win).
+ * Return TRUE and a non-malloc'ed string if there is.  Else return FALSE.
+ */
+    int
+serverPeekReply(dpy, win, str)
+    Display *dpy;
+    Window win;
+    char_u **str;
+{
+    struct ServerReply *p;
+
+    if ((p = ServerReplyFind(win, SROP_Find)) != NULL && p->strings.ga_len > 0)
+    {
+	if (str != NULL)
+	    *str = p->strings.ga_data;
+	return 1;
+    }
+    if (!WindowValid(dpy, win))
+	return -1;
+    return 0;
+}
+
+
+/*
+ * Initialize the communication channels for sending commands and receiving
+ * results.
+ */
+    static int
+SendInit(dpy)
+    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;
+
+    if (commProperty == None)
+	commProperty = XInternAtom(dpy, "Comm", False);
+    if (vimProperty == None)
+	vimProperty = XInternAtom(dpy, "Vim", False);
+    if (registryProperty == None)
+	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);
+	/* WARNING: Do not step through this while debugging, it will hangup
+	 * the X server! */
+	XGrabServer(dpy);
+	DeleteAnyLingerer(dpy, commWindow);
+	XUngrabServer(dpy);
+    }
+
+    /* Make window recognizable as a vim window */
+    XChangeProperty(dpy, commWindow, vimProperty, XA_STRING,
+		    8, PropModeReplace, (char_u *)VIM_VERSION_SHORT,
+			(int)STRLEN(VIM_VERSION_SHORT) + 1);
+
+    XSync(dpy, False);
+    (void)XSetErrorHandler(old_handler);
+
+    return got_x_error ? -1 : 0;
+}
+
+/*
+ * Given a server name, see if the name exists in the registry for a
+ * particular display.
+ *
+ * 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.
+ *
+ * Side effects:
+ *	If the registry property is improperly formed, then it is deleted.
+ *	If "delete" is non-zero, then if the named server is found it is
+ *	removed from the registry property.
+ */
+    static Window
+LookupName(dpy, name, delete, loose)
+    Display	*dpy;	    /* Display whose registry to check. */
+    char_u	*name;	    /* Name of a server. */
+    int		delete;	    /* If non-zero, delete info about name. */
+    char_u	**loose;    /* Do another search matching -999 if not found
+			       Return result here if a match is found */
+{
+    char_u	*regProp, *entry;
+    char_u	*p;
+    long_u	numItems;
+    int_u	returnValue;
+
+    /*
+     * Read the registry property.
+     */
+    if (GetRegProp(dpy, &regProp, &numItems, FALSE) == FAIL)
+	return 0;
+
+    /*
+     * Scan the property for the desired name.
+     */
+    returnValue = (int_u)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 && STRICMP(name, p + 1) == 0)
+	{
+	    sscanf((char *)entry, "%x", &returnValue);
+	    break;
+	}
+	while (*p != 0)
+	    p++;
+	p++;
+    }
+
+    if (loose != NULL && returnValue == (int_u)None && !IsSerialName(name))
+    {
+	for (p = regProp; (p - regProp) < numItems; )
+	{
+	    entry = p;
+	    while (*p != 0 && !isspace(*p))
+		p++;
+	    if (*p != 0 && IsSerialName(p + 1)
+		    && STRNICMP(name, p + 1, STRLEN(name)) == 0)
+	    {
+		sscanf((char *)entry, "%x", &returnValue);
+		*loose = vim_strsave(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 != (int_u)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);
+    }
+
+    if (regProp != empty_prop)
+	XFree(regProp);
+    return (Window)returnValue;
+}
+
+/*
+ * Delete any lingering occurences of window id.  We promise that any
+ * occurences is not ours since it is not yet put into the registry (by us)
+ *
+ * This is necessary in the following scenario:
+ * 1. There is an old windowid for an exit'ed vim in the registry
+ * 2. We get that id for our commWindow but only want to send, not register.
+ * 3. The window will mistakenly be regarded valid because of own commWindow
+ */
+    static void
+DeleteAnyLingerer(dpy, win)
+    Display	*dpy;	/* Display whose registry to check. */
+    Window	win;	/* Window to remove */
+{
+    char_u	*regProp, *entry = NULL;
+    char_u	*p;
+    long_u	numItems;
+    Window	wwin;
+
+    /*
+     * Read the registry property.
+     */
+    if (GetRegProp(dpy, &regProp, &numItems, FALSE) == FAIL)
+	return;
+
+    /* Scan the property for the window id.  */
+    for (p = regProp; (p - regProp) < numItems; )
+    {
+	if (*p != 0)
+	{
+	    sscanf((char *)p, "%x", (int_u *)&wwin);
+	    if (wwin == win)
+	    {
+		int lastHalf;
+
+		/* Copy down the remainder to delete entry */
+		entry = p;
+		while (*p != 0)
+		    p++;
+		p++;
+		lastHalf = numItems - (p - regProp);
+		if (lastHalf > 0)
+		    memcpy(entry, p, lastHalf);
+		numItems = (entry - regProp) + lastHalf;
+		p = entry;
+		continue;
+	    }
+	}
+	while (*p != 0)
+	    p++;
+	p++;
+    }
+
+    if (entry != NULL)
+    {
+	XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty,
+			XA_STRING, 8, PropModeReplace, regProp,
+			(int)(p - regProp));
+	XSync(dpy, False);
+    }
+
+    if (regProp != empty_prop)
+	XFree(regProp);
+}
+
+/*
+ * Read the registry property.  Delete it when it's formatted wrong.
+ * Return the property in "regPropp".  "empty_prop" is used when it doesn't
+ * exist yet.
+ * Return OK when successful.
+ */
+    static int
+GetRegProp(dpy, regPropp, numItemsp, domsg)
+    Display	*dpy;
+    char_u	**regPropp;
+    long_u	*numItemsp;
+    int		domsg;		/* When TRUE give error message. */
+{
+    int		result, actualFormat;
+    long_u	bytesAfter;
+    Atom	actualType;
+
+    *regPropp = NULL;
+    result = XGetWindowProperty(dpy, RootWindow(dpy, 0), registryProperty, 0L,
+				(long)MAX_PROP_WORDS, False,
+				XA_STRING, &actualType,
+				&actualFormat, numItemsp, &bytesAfter,
+				regPropp);
+
+    if (actualType == None)
+    {
+	/* No prop yet. Logically equal to the empty list */
+	*numItemsp = 0;
+	*regPropp = empty_prop;
+	return OK;
+    }
+
+    /* If the property is improperly formed, then delete it. */
+    if (result != Success || actualFormat != 8 || actualType != XA_STRING)
+    {
+	if (*regPropp != NULL)
+	    XFree(*regPropp);
+	XDeleteProperty(dpy, RootWindow(dpy, 0), registryProperty);
+	if (domsg)
+	    EMSG(_("E251: VIM instance registry property is badly formed.  Deleted!"));
+	return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * This procedure is invoked by the varous X event loops throughout Vims when
+ * a property changes on the communication window.  This procedure reads the
+ * property and handles command requests and responses.
+ */
+    void
+serverEventProc(dpy, eventPtr)
+    Display	*dpy;
+    XEvent	*eventPtr;		/* Information about event. */
+{
+    char_u	*propInfo;
+    char_u	*p;
+    int		result, actualFormat, code;
+    long_u	numItems, bytesAfter;
+    Atom	actualType;
+
+    if (eventPtr != NULL)
+    {
+	if (eventPtr->xproperty.atom != commProperty
+		|| eventPtr->xproperty.state != PropertyNewValue)
+	    return;
+    }
+
+    /*
+     * Read the comm property and delete it.
+     */
+    propInfo = NULL;
+    result = XGetWindowProperty(dpy, commWindow, commProperty, 0L,
+				(long)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 == 'c' || *p == 'k') && (p[1] == 0))
+	{
+	    Window	resWindow;
+	    char_u	*name, *script, *serial, *end, *res;
+	    Bool	asKeys = *p == 'k';
+	    garray_T	reply;
+
+	    /*
+	     * This is an incoming command from some other application.
+	     * 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;
+	    name = NULL;
+	    resWindow = None;
+	    serial = (char_u *)"";
+	    script = NULL;
+	    while (p - propInfo < numItems && *p == '-')
+	    {
+		switch (p[1])
+		{
+		    case 'r':
+			end = skipwhite(p + 2);
+			resWindow = 0;
+			while (vim_isxdigit(*end))
+			{
+			    resWindow = 16 * resWindow + (long_u)hex2nr(*end);
+			    ++end;
+			}
+			if (end == p + 2 || *end != ' ')
+			    resWindow = None;
+			else
+			{
+			    p = serial = end + 1;
+			    clientWindow = resWindow; /* Remember in global */
+			}
+			break;
+		    case 'n':
+			if (p[2] == ' ')
+			    name = p + 3;
+			break;
+		    case 's':
+			if (p[2] == ' ')
+			    script = p + 3;
+			break;
+		}
+		while (*p != 0)
+		    p++;
+		p++;
+	    }
+
+	    if (script == NULL || name == NULL)
+		continue;
+
+	    /*
+	     * Initialize the result property, so that we're ready at any
+	     * time if we need to return an error.
+	     */
+	    if (resWindow != None)
+	    {
+		ga_init2(&reply, 1, 100);
+		ga_grow(&reply, 50);
+		sprintf(reply.ga_data, "%cr%c-s %s%c-r ", 0, 0, serial, 0);
+		reply.ga_len = 10 + STRLEN(serial);
+		reply.ga_room -= reply.ga_len;
+	    }
+	    res = NULL;
+	    if (serverName != NULL && STRICMP(name, serverName) == 0)
+	    {
+		if (asKeys)
+		    server_to_input_buf(script);
+		else
+		    res = eval_client_expr_to_string(script);
+	    }
+	    if (resWindow != None)
+	    {
+		if (res != NULL)
+		    ga_concat(&reply, res);
+		else if (asKeys == 0)
+		{
+		    ga_concat(&reply, (char_u *)_(e_invexprmsg));
+		    ga_append(&reply, 0);
+		    ga_concat(&reply, (char_u *)"-c 1");
+		}
+		ga_append(&reply, 0);
+		(void)AppendPropCarefully(dpy, resWindow, commProperty,
+					   reply.ga_data, reply.ga_len);
+	    }
+	    vim_free(res);
+	}
+	else if (*p == 'r' && p[1] == 0)
+	{
+	    int	    serial, gotSerial;
+	    char_u  *res;
+	    PendingCommand *pcPtr;
+
+	    /*
+	     * 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 = (char_u *)"";
+	    code = 0;
+	    while ((p-propInfo) < numItems && *p == '-')
+	    {
+		switch (p[1])
+		{
+		    case 'r':
+			if (p[2] == ' ')
+			    res = p + 3;
+			break;
+		    case 's':
+			if (sscanf((char *)p + 2, " %d", &serial) == 1)
+			    gotSerial = 1;
+			break;
+		    case 'c':
+			if (sscanf((char *)p + 2, " %d", &code) != 1)
+			    code = 0;
+			break;
+		}
+		while (*p != 0)
+		    p++;
+		p++;
+	    }
+
+	    if (!gotSerial)
+		continue;
+
+	    /*
+	     * Give the result information to anyone who's
+	     * waiting for it.
+	     */
+	    for (pcPtr = pendingCommands; pcPtr != NULL; pcPtr = pcPtr->nextPtr)
+	    {
+		if (serial != pcPtr->serial || pcPtr->result != NULL)
+		    continue;
+
+		pcPtr->code = code;
+		if (res != NULL)
+		    pcPtr->result = vim_strsave(res);
+		else
+		    pcPtr->result = vim_strsave((char_u *)"");
+		break;
+	    }
+	}
+	else if (*p == 'n' && p[1] == 0)
+	{
+	    Window	win = 0;
+	    unsigned int u;
+	    int		gotWindow;
+	    char_u	*str;
+	    char_u	winstr[30];
+	    struct	ServerReply *r;
+
+	    /*
+	     * This is a (n)otification.  Sent with serverreply_send in VimL.
+	     * Execute any autocommand and save it for later retrieval
+	     */
+	    p += 2;
+	    gotWindow = 0;
+	    str = (char_u *)"";
+	    while ((p-propInfo) < numItems && *p == '-')
+	    {
+		switch (p[1])
+		{
+		    case 'n':
+			if (p[2] == ' ')
+			    str = p + 3;
+			break;
+		    case 'w':
+			if (sscanf((char *)p + 2, " %x", &u) == 1)
+			{
+			    win = u;
+			    gotWindow = 1;
+			}
+			break;
+		}
+		while (*p != 0)
+		    p++;
+		p++;
+	    }
+
+	    if (!gotWindow)
+		continue;
+	    if ((r = ServerReplyFind(win, SROP_Add)) != NULL)
+	    {
+		ga_concat(&(r->strings), str);
+		ga_append(&(r->strings), 0);
+	    }
+#ifdef FEAT_AUTOCMD
+	    sprintf((char *)winstr, "0x%x", (unsigned int)win);
+	    apply_autocmds(EVENT_REMOTEREPLY, winstr, str, TRUE, curbuf);
+#endif
+
+	}
+	else
+	{
+	    /*
+	     * Didn't recognize this thing.  Just skip through the next
+	     * null character and try again.
+	     * Even if we get an 'r'(eply) we will throw it away as we
+	     * never specify (and thus expect) one
+	     */
+	    while (*p != 0)
+		p++;
+	    p++;
+	}
+    }
+    XFree(propInfo);
+}
+
+/*
+ * 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 for OK, -1 for error
+ */
+    static int
+AppendPropCarefully(dpy, window, property, value, length)
+    Display	*dpy;		/* Display on which to operate. */
+    Window	window;		/* Window whose property is to be modified. */
+    Atom	property;	/* Name of property. */
+    char_u	*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(dpy, error_event)
+    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(str)
+    char_u	*str;
+{
+    int len = STRLEN(str);
+
+    return (len > 1 && vim_isdigit(str[len - 1]));
+}
+#endif	/* FEAT_CLIENTSERVER */
