Blob Blame History Raw
diff -rupN xen-3.1.2-src.orig/Config.mk xen-3.1.2-src.new/Config.mk
--- xen-3.1.2-src.orig/Config.mk	2007-11-14 18:35:27.000000000 -0500
+++ xen-3.1.2-src.new/Config.mk	2007-12-01 14:53:57.000000000 -0500
@@ -96,7 +96,6 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_
 XENSTAT_XENTOP     ?= y
 VTPM_TOOLS         ?= n
 LIBXENAPI_BINDINGS ?= n
-XENFB_TOOLS        ?= n
 PYTHON_TOOLS       ?= y
 
 -include $(XEN_ROOT)/.config
diff -rupN xen-3.1.2-src.orig/tools/check/check_libvncserver xen-3.1.2-src.new/tools/check/check_libvncserver
--- xen-3.1.2-src.orig/tools/check/check_libvncserver	2007-11-14 18:35:27.000000000 -0500
+++ xen-3.1.2-src.new/tools/check/check_libvncserver	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-#!/bin/sh
-# CHECK-BUILD CHECK-INSTALL
-
-if [ ! "$XENFB_TOOLS" = "y" ]
-then
-    echo -n "unused, "
-    exit 0
-fi
-
-RC=0
-
-LIBVNCSERVER_CONFIG="$(which libvncserver-config)"
-
-if test -z ${LIBVNCSERVER_CONFIG}; then 
-    RC=1
-else
-    ${LIBVNCSERVER_CONFIG} --libs 2>&1 > /dev/null
-    RC=$?
-fi
-
-if test $RC -ne 0; then
-    echo "FAILED"
-	echo " *** libvncserver-config is missing. "
-    echo " *** Please install libvncserver."
-fi
-
-exit $RC
diff -rupN xen-3.1.2-src.orig/tools/check/check_sdl xen-3.1.2-src.new/tools/check/check_sdl
--- xen-3.1.2-src.orig/tools/check/check_sdl	2007-11-14 18:35:27.000000000 -0500
+++ xen-3.1.2-src.new/tools/check/check_sdl	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-#!/bin/sh
-# CHECK-BUILD CHECK-INSTALL
-
-if [ ! "$XENFB_TOOLS" = "y" ]
-then
-    echo -n "unused, "
-    exit 0
-fi
-
-RC=0
-
-SDL_CONFIG="$(which sdl-config)"
-
-if test -z ${SDL_CONFIG}; then 
-    RC=1
-else
-    ${SDL_CONFIG} --libs 2>&1 > /dev/null
-    RC=$?
-fi
-
-if test $RC -ne 0; then
-    echo "FAILED"
-	echo " *** sdl-config is missing. "
-    echo " *** Please install libsdl-dev or sdl."
-fi
-
-exit $RC
diff -rupN xen-3.1.2-src.orig/tools/check/Makefile xen-3.1.2-src.new/tools/check/Makefile
--- xen-3.1.2-src.orig/tools/check/Makefile	2007-11-14 18:35:27.000000000 -0500
+++ xen-3.1.2-src.new/tools/check/Makefile	2007-12-01 14:53:57.000000000 -0500
@@ -7,7 +7,7 @@ all: build
 # Check this machine is OK for building on.
 .PHONY: build
 build:
-	XENFB_TOOLS=$(XENFB_TOOLS) ./chk build
+	./chk build
 
 # Check this machine is OK for installing on.
 # DO NOT use this check from 'make install' in the parent
@@ -15,7 +15,7 @@ build:
 # copy rather than actually installing.
 .PHONY: install
 install:
-	XENFB_TOOLS=$(XENFB_TOOLS) ./chk install
+	./chk install
 
 .PHONY: clean
 clean:
diff -rupN xen-3.1.2-src.orig/tools/ioemu/hw/xenfb.c xen-3.1.2-src.new/tools/ioemu/hw/xenfb.c
--- xen-3.1.2-src.orig/tools/ioemu/hw/xenfb.c	1969-12-31 19:00:00.000000000 -0500
+++ xen-3.1.2-src.new/tools/ioemu/hw/xenfb.c	2007-12-01 14:53:57.000000000 -0500
@@ -0,0 +1,825 @@
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <xenctrl.h>
+#include <xen/io/xenbus.h>
+#include <xen/io/fbif.h>
+#include <xen/io/kbdif.h>
+#include <xen/io/protocols.h>
+#include <sys/select.h>
+#include <stdbool.h>
+#include <xen/event_channel.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <xs.h>
+
+#include "xenfb.h"
+
+// FIXME defend against malicious frontend?
+
+struct xenfb_device {
+	const char *devicetype;
+	char nodename[64];	/* backend xenstore dir */
+	char otherend[64];	/* frontend xenstore dir */
+	int otherend_id;	/* frontend domid */
+	enum xenbus_state state; /* backend state */
+	void *page;		/* shared page */
+	evtchn_port_t port;
+	struct xenfb_private *xenfb;
+};
+
+struct xenfb_private {
+	struct xenfb pub;
+	int evt_xch;		/* event channel driver handle */
+	int xc;			/* hypervisor interface handle */
+	struct xs_handle *xsh;	/* xs daemon handle */
+	struct xenfb_device fb, kbd;
+	size_t fb_len;		/* size of framebuffer */
+	char protocol[64];	/* frontend protocol */
+};
+
+static void xenfb_detach_dom(struct xenfb_private *);
+
+static char *xenfb_path_in_dom(struct xs_handle *xsh,
+			       char *buf, size_t size,
+			       unsigned domid, const char *fmt, ...)
+{
+	va_list ap;
+	char *domp = xs_get_domain_path(xsh, domid);
+	int n;
+
+        if (domp == NULL)
+		return NULL;
+
+	n = snprintf(buf, size, "%s/", domp);
+	free(domp);
+	if (n >= size)
+		return NULL;
+
+	va_start(ap, fmt);
+	n += vsnprintf(buf + n, size - n, fmt, ap);
+	va_end(ap);
+	if (n >= size)
+		return NULL;
+
+	return buf;
+}
+
+static int xenfb_xs_scanf1(struct xs_handle *xsh,
+			   const char *dir, const char *node,
+			   const char *fmt, void *dest)
+{
+	char buf[1024];
+	char *p;
+	int ret;
+
+	if (snprintf(buf, sizeof(buf), "%s/%s", dir, node) >= sizeof(buf)) {
+		errno = ENOENT;
+		return -1;
+        }
+	p = xs_read(xsh, XBT_NULL, buf, NULL);
+	if (!p) {
+		errno = ENOENT;
+		return -1;
+        }
+	ret = sscanf(p, fmt, dest);
+	free(p);
+	if (ret != 1) {
+		errno = EDOM;
+		return -1;
+        }
+	return ret;
+}
+
+static int xenfb_xs_printf(struct xs_handle *xsh,
+			   const char *dir, const char *node, char *fmt, ...)
+{
+	va_list ap;
+	char key[1024];
+	char val[1024];
+	int n;
+
+	if (snprintf(key, sizeof(key), "%s/%s", dir, node) >= sizeof(key)) {
+		errno = ENOENT;
+		return -1;
+        }
+
+	va_start(ap, fmt);
+	n = vsnprintf(val, sizeof(val), fmt, ap);
+	va_end(ap);
+	if (n >= sizeof(val)) {
+		errno = ENOSPC; /* close enough */
+		return -1;
+	}
+
+	if (!xs_write(xsh, XBT_NULL, key, val, n))
+		return -1;
+	return 0;
+}
+
+static void xenfb_device_init(struct xenfb_device *dev,
+			      const char *type,
+			      struct xenfb_private *xenfb)
+{
+	dev->devicetype = type;
+	dev->otherend_id = -1;
+	dev->port = -1;
+	dev->xenfb = xenfb;
+}
+
+int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
+{
+	struct xenfb_private *xenfb = dev->xenfb;
+
+	dev->otherend_id = domid;
+
+	if (!xenfb_path_in_dom(xenfb->xsh,
+			       dev->otherend, sizeof(dev->otherend),
+			       domid, "device/%s/0", dev->devicetype)) {
+		errno = ENOENT;
+		return -1;
+	}
+	if (!xenfb_path_in_dom(xenfb->xsh,
+			       dev->nodename, sizeof(dev->nodename),
+			       0, "backend/%s/%d/0", dev->devicetype, domid)) {
+		errno = ENOENT;
+		return -1;
+	}
+
+	return 0;
+}
+
+struct xenfb *xenfb_new(void)
+{
+	struct xenfb_private *xenfb = malloc(sizeof(*xenfb));
+	int serrno;
+
+	if (xenfb == NULL)
+		return NULL;
+
+	memset(xenfb, 0, sizeof(*xenfb));
+	xenfb->evt_xch = xenfb->xc = -1;
+	xenfb_device_init(&xenfb->fb, "vfb", xenfb);
+	xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
+
+	xenfb->evt_xch = xc_evtchn_open();
+	if (xenfb->evt_xch == -1)
+		goto fail;
+
+	xenfb->xc = xc_interface_open();
+	if (xenfb->xc == -1)
+		goto fail;
+
+	xenfb->xsh = xs_daemon_open();
+	if (!xenfb->xsh)
+		goto fail;
+
+	return &xenfb->pub;
+
+ fail:
+	serrno = errno;
+	xenfb_delete(&xenfb->pub);
+	errno = serrno;
+	return NULL;
+}
+
+/* Remove the backend area in xenbus since the framebuffer really is
+   going away. */
+void xenfb_teardown(struct xenfb *xenfb_pub)
+{
+       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+
+       xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
+       xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
+}
+
+
+void xenfb_delete(struct xenfb *xenfb_pub)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+
+	xenfb_detach_dom(xenfb);
+	if (xenfb->xc >= 0)
+		xc_interface_close(xenfb->xc);
+	if (xenfb->evt_xch >= 0)
+		xc_evtchn_close(xenfb->evt_xch);
+	if (xenfb->xsh)
+		xs_daemon_close(xenfb->xsh);
+	free(xenfb);
+}
+
+static enum xenbus_state xenfb_read_state(struct xs_handle *xsh,
+					  const char *dir)
+{
+	int ret, state;
+
+	ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state);
+	if (ret < 0)
+		return XenbusStateUnknown;
+
+	if ((unsigned)state > XenbusStateClosed)
+		state = XenbusStateUnknown;
+	return state;
+}
+
+static int xenfb_switch_state(struct xenfb_device *dev,
+			      enum xenbus_state state)
+{
+	struct xs_handle *xsh = dev->xenfb->xsh;
+
+	if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0)
+		return -1;
+	dev->state = state;
+	return 0;
+}
+
+static int xenfb_wait_for_state(struct xs_handle *xsh, const char *dir,
+				unsigned awaited)
+{
+	unsigned state, dummy;
+	char **vec;
+
+	awaited |= 1 << XenbusStateUnknown;
+
+	for (;;) {
+		state = xenfb_read_state(xsh, dir);
+		if ((1 << state) & awaited)
+			return state;
+
+		vec = xs_read_watch(xsh, &dummy);
+		if (!vec)
+			return -1;
+		free(vec);
+	}
+}
+
+static int xenfb_wait_for_backend_creation(struct xenfb_device *dev)
+{
+	struct xs_handle *xsh = dev->xenfb->xsh;
+	int state;
+
+	if (!xs_watch(xsh, dev->nodename, ""))
+		return -1;
+	state = xenfb_wait_for_state(xsh, dev->nodename,
+			(1 << XenbusStateInitialising)
+			| (1 << XenbusStateClosed)
+#if 1 /* TODO fudging state to permit restarting; to be removed */
+			| (1 << XenbusStateInitWait)
+			| (1 << XenbusStateConnected)
+			| (1 << XenbusStateClosing)
+#endif
+			);
+	xs_unwatch(xsh, dev->nodename, "");
+
+	switch (state) {
+#if 1
+	case XenbusStateInitWait:
+	case XenbusStateConnected:
+		printf("Fudging state to %d\n", XenbusStateInitialising); /* FIXME */
+#endif
+	case XenbusStateInitialising:
+	case XenbusStateClosing:
+	case XenbusStateClosed:
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static int xenfb_hotplug(struct xenfb_device *dev)
+{
+	if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename,
+			    "hotplug-status", "connected"))
+		return -1;
+	return 0;
+}
+
+static int xenfb_wait_for_frontend_initialised(struct xenfb_device *dev)
+{
+	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
+#if 1 /* TODO fudging state to permit restarting; to be removed */
+			(1 << XenbusStateInitialised)
+			| (1 << XenbusStateConnected)
+#else
+			1 << XenbusStateInitialised,
+#endif
+			)) {
+#if 1
+	case XenbusStateConnected:
+		printf("Fudging state to %d\n", XenbusStateInitialised); /* FIXME */
+#endif
+	case XenbusStateInitialised:
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
+{
+	uint32_t *src32 = src;
+	uint64_t *src64 = src;
+	int i;
+
+	for (i = 0; i < count; i++)
+		dst[i] = (mode == 32) ? src32[i] : src64[i];
+}
+
+static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
+{
+	struct xenfb_page *page = xenfb->fb.page;
+	int n_fbmfns;
+	int n_fbdirs;
+	unsigned long *pgmfns = NULL;
+	unsigned long *fbmfns = NULL;
+	void *map, *pd;
+	int mode, ret = -1;
+
+	/* default to native */
+	pd = page->pd;
+	mode = sizeof(unsigned long) * 8;
+
+	if (0 == strlen(xenfb->protocol)) {
+		/*
+		 * Undefined protocol, some guesswork needed.
+		 *
+		 * Old frontends which don't set the protocol use
+		 * one page directory only, thus pd[1] must be zero.
+		 * pd[1] of the 32bit struct layout and the lower
+		 * 32 bits of pd[0] of the 64bit struct layout have
+		 * the same location, so we can check that ...
+		 */
+		uint32_t *ptr32 = NULL;
+		uint32_t *ptr64 = NULL;
+#if defined(__i386__)
+		ptr32 = (void*)page->pd;
+		ptr64 = ((void*)page->pd) + 4;
+#elif defined(__x86_64__)
+		ptr32 = ((void*)page->pd) - 4;
+		ptr64 = (void*)page->pd;
+#endif
+		if (ptr32) {
+			if (0 == ptr32[1]) {
+				mode = 32;
+				pd   = ptr32;
+			} else {
+				mode = 64;
+				pd   = ptr64;
+			}
+		}
+#if defined(__x86_64__)
+	} else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) {
+		/* 64bit dom0, 32bit domU */
+		mode = 32;
+		pd   = ((void*)page->pd) - 4;
+#elif defined(__i386__)
+	} else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) {
+		/* 32bit dom0, 64bit domU */
+		mode = 64;
+		pd   = ((void*)page->pd) + 4;
+#endif
+	}
+
+	n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
+	n_fbdirs = n_fbmfns * mode / 8;
+	n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
+
+	pgmfns = malloc(sizeof(unsigned long) * n_fbdirs);
+	fbmfns = malloc(sizeof(unsigned long) * n_fbmfns);
+	if (!pgmfns || !fbmfns)
+		goto out;
+
+	/*
+	 * Bug alert: xc_map_foreign_batch() can fail partly and
+	 * return a non-null value.  This is a design flaw.  When it
+	 * happens, we happily continue here, and later crash on
+	 * access.
+	 */
+	xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
+	map = xc_map_foreign_batch(xenfb->xc, domid,
+				   PROT_READ, pgmfns, n_fbdirs);
+	if (map == NULL)
+		goto out;
+	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
+	munmap(map, n_fbdirs * XC_PAGE_SIZE);
+
+	xenfb->pub.pixels = xc_map_foreign_batch(xenfb->xc, domid,
+				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
+	if (xenfb->pub.pixels == NULL)
+		goto out;
+
+	ret = 0; /* all is fine */
+
+ out:
+	if (pgmfns)
+		free(pgmfns);
+	if (fbmfns)
+		free(fbmfns);
+	return ret;
+}
+
+static int xenfb_bind(struct xenfb_device *dev)
+{
+	struct xenfb_private *xenfb = dev->xenfb;
+	unsigned long mfn;
+	evtchn_port_t evtchn;
+
+	if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu",
+			    &mfn) < 0)
+		return -1;
+	if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u",
+			    &evtchn) < 0)
+		return -1;
+
+	dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch,
+					       dev->otherend_id, evtchn);
+	if (dev->port == -1)
+		return -1;
+
+	dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id,
+			XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
+	if (dev->page == NULL)
+		return -1;
+
+	return 0;
+}
+
+static void xenfb_unbind(struct xenfb_device *dev)
+{
+	if (dev->page) {
+		munmap(dev->page, XC_PAGE_SIZE);
+		dev->page = NULL;
+	}
+        if (dev->port >= 0) {
+		xc_evtchn_unbind(dev->xenfb->evt_xch, dev->port);
+		dev->port = -1;
+	}
+}
+
+static int xenfb_wait_for_frontend_connected(struct xenfb_device *dev)
+{
+	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
+				     1 << XenbusStateConnected)) {
+	case XenbusStateConnected:
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static void xenfb_dev_fatal(struct xenfb_device *dev, int err,
+			    const char *fmt, ...)
+{
+	struct xs_handle *xsh = dev->xenfb->xsh;
+	va_list ap;
+	char errdir[80];
+	char buf[1024];
+	int n;
+
+	fprintf(stderr, "%s ", dev->nodename); /* somewhat crude */
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	if (err)
+		fprintf(stderr, " (%s)", strerror(err));
+	putc('\n', stderr);
+
+	if (!xenfb_path_in_dom(xsh, errdir, sizeof(errdir), 0,
+			       "error/%s", dev->nodename))
+		goto out;	/* FIXME complain */
+
+	va_start(ap, fmt);
+	n = snprintf(buf, sizeof(buf), "%d ", err);
+	snprintf(buf + n, sizeof(buf) - n, fmt, ap);
+	va_end(ap);
+
+	if (xenfb_xs_printf(xsh, buf, "error", "%s", buf) < 0)
+		goto out;	/* FIXME complain */
+
+ out:
+	xenfb_switch_state(dev, XenbusStateClosing);
+}
+
+int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	struct xs_handle *xsh = xenfb->xsh;
+	int val, serrno;
+	struct xenfb_page *fb_page;
+
+	xenfb_detach_dom(xenfb);
+
+	xenfb_device_set_domain(&xenfb->fb, domid);
+	xenfb_device_set_domain(&xenfb->kbd, domid);
+
+	if (xenfb_wait_for_backend_creation(&xenfb->fb) < 0)
+		goto error;
+	if (xenfb_wait_for_backend_creation(&xenfb->kbd) < 0)
+		goto error;
+
+	if (xenfb_xs_printf(xsh, xenfb->kbd.nodename, "feature-abs-pointer", "1"))
+		goto error;
+	if (xenfb_switch_state(&xenfb->fb, XenbusStateInitWait))
+		goto error;
+	if (xenfb_switch_state(&xenfb->kbd, XenbusStateInitWait))
+		goto error;
+
+	if (xenfb_hotplug(&xenfb->fb) < 0)
+		goto error;
+	if (xenfb_hotplug(&xenfb->kbd) < 0)
+		goto error;
+
+	if (!xs_watch(xsh, xenfb->fb.otherend, ""))
+		goto error;
+	if (!xs_watch(xsh, xenfb->kbd.otherend, ""))
+		goto error;
+
+	if (xenfb_wait_for_frontend_initialised(&xenfb->fb) < 0)
+		goto error;
+	if (xenfb_wait_for_frontend_initialised(&xenfb->kbd) < 0)
+		goto error;
+
+	if (xenfb_bind(&xenfb->fb) < 0)
+		goto error;
+	if (xenfb_bind(&xenfb->kbd) < 0)
+		goto error;
+
+	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "feature-update",
+			    "%d", &val) < 0)
+		val = 0;
+	if (!val) {
+		errno = ENOTSUP;
+		goto error;
+	}
+	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
+			    xenfb->protocol) < 0)
+		xenfb->protocol[0] = '\0';
+	xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
+
+	/* TODO check for permitted ranges */
+	fb_page = xenfb->fb.page;
+	xenfb->pub.depth = fb_page->depth;
+	xenfb->pub.width = fb_page->width;
+	xenfb->pub.height = fb_page->height;
+	/* TODO check for consistency with the above */
+	xenfb->fb_len = fb_page->mem_length;
+	xenfb->pub.row_stride = fb_page->line_length;
+
+	if (xenfb_map_fb(xenfb, domid) < 0)
+		goto error;
+
+	if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
+		goto error;
+	if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
+		goto error;
+
+	if (xenfb_wait_for_frontend_connected(&xenfb->kbd) < 0)
+		goto error;
+	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
+			    "%d", &val) < 0)
+		val = 0;
+	xenfb->pub.abs_pointer_wanted = val;
+
+	return 0;
+
+ error:
+	serrno = errno;
+	xenfb_detach_dom(xenfb);
+	xenfb_dev_fatal(&xenfb->fb, serrno, "on fire");
+	xenfb_dev_fatal(&xenfb->kbd, serrno, "on fire");
+        errno = serrno;
+        return -1;
+}
+
+static void xenfb_detach_dom(struct xenfb_private *xenfb)
+{
+	xenfb_unbind(&xenfb->fb);
+	xenfb_unbind(&xenfb->kbd);
+	if (xenfb->pub.pixels) {
+		munmap(xenfb->pub.pixels, xenfb->fb_len);
+		xenfb->pub.pixels = NULL;
+	}
+}
+
+static void xenfb_on_fb_event(struct xenfb_private *xenfb)
+{
+	uint32_t prod, cons;
+	struct xenfb_page *page = xenfb->fb.page;
+
+	prod = page->out_prod;
+	if (prod == page->out_cons)
+		return;
+	rmb();			/* ensure we see ring contents up to prod */
+	for (cons = page->out_cons; cons != prod; cons++) {
+		union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
+
+		switch (event->type) {
+		case XENFB_TYPE_UPDATE:
+                    if (xenfb->pub.update)
+			xenfb->pub.update(&xenfb->pub,
+					  event->update.x, event->update.y,
+					  event->update.width, event->update.height);
+                    break;
+		}
+	}
+	mb();			/* ensure we're done with ring contents */
+	page->out_cons = cons;
+	xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
+}
+
+static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
+{
+	struct xenkbd_page *page = xenfb->kbd.page;
+
+	/* We don't understand any keyboard events, so just ignore them. */
+	if (page->out_prod == page->out_cons)
+		return;
+	page->out_cons = page->out_prod;
+	xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
+}
+
+static int xenfb_on_state_change(struct xenfb_device *dev)
+{
+	enum xenbus_state state;
+
+	state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
+
+	switch (state) {
+	case XenbusStateUnknown:
+		/* There was an error reading the frontend state.  The
+		   domain has probably gone away; in any case, there's
+		   not much point in us continuing. */
+		return -1;
+	case XenbusStateInitialising:
+	case XenbusStateInitWait:
+	case XenbusStateInitialised:
+	case XenbusStateConnected:
+		break;
+	case XenbusStateClosing:
+		xenfb_unbind(dev);
+		xenfb_switch_state(dev, state);
+		break;
+	case XenbusStateClosed:
+		xenfb_switch_state(dev, state);
+	}
+	return 0;
+}
+
+int xenfb_dispatch_channel(struct xenfb *xenfb_pub)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	evtchn_port_t port;
+	port = xc_evtchn_pending(xenfb->evt_xch);
+	if (port == -1)
+		return -1;
+
+	if (port == xenfb->fb.port)
+		xenfb_on_fb_event(xenfb);
+	else if (port == xenfb->kbd.port)
+		xenfb_on_kbd_event(xenfb);
+
+	if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
+		return -1;
+
+	return 0;
+}
+
+int xenfb_dispatch_store(struct xenfb *xenfb_pub)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	unsigned dummy;
+	char **vec;
+	int r;
+
+	vec = xs_read_watch(xenfb->xsh, &dummy);
+	free(vec);
+	r = xenfb_on_state_change(&xenfb->fb);
+	if (r == 0)
+		r = xenfb_on_state_change(&xenfb->kbd);
+	if (r == -1)
+		return -2;
+
+	return 0;
+}
+
+
+/* Returns 0 normally, -1 on error, or -2 if the domain went away. */
+int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	int ret;
+
+	if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
+		if ((ret = xenfb_dispatch_channel(xenfb_pub)) < 0)
+			return ret;
+	}
+
+	if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) {
+		if ((ret = xenfb_dispatch_store(xenfb_pub)) < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+int xenfb_select_fds(struct xenfb *xenfb_pub, fd_set *readfds)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	int fd1 = xc_evtchn_fd(xenfb->evt_xch);
+	int fd2 = xs_fileno(xenfb->xsh);
+
+	FD_SET(fd1, readfds);
+	FD_SET(fd2, readfds);
+	return fd1 > fd2 ? fd1 + 1 : fd2 + 1;
+}
+
+int xenfb_get_store_fd(struct xenfb *xenfb_pub)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	return xs_fileno(xenfb->xsh);
+}
+
+int xenfb_get_channel_fd(struct xenfb *xenfb_pub)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	return xc_evtchn_fd(xenfb->evt_xch);
+}
+
+static int xenfb_kbd_event(struct xenfb_private *xenfb,
+			   union xenkbd_in_event *event)
+{
+	uint32_t prod;
+	struct xenkbd_page *page = xenfb->kbd.page;
+
+	if (xenfb->kbd.state != XenbusStateConnected)
+		return 0;
+
+	prod = page->in_prod;
+	if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
+		errno = EAGAIN;
+		return -1;
+	}
+
+	mb();			/* ensure ring space available */
+	XENKBD_IN_RING_REF(page, prod) = *event;
+	wmb();			/* ensure ring contents visible */
+	page->in_prod = prod + 1;
+	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
+}
+
+int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	union xenkbd_in_event event;
+
+	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+	event.type = XENKBD_TYPE_KEY;
+	event.key.pressed = down ? 1 : 0;
+	event.key.keycode = keycode;
+
+	return xenfb_kbd_event(xenfb, &event);
+}
+
+int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	union xenkbd_in_event event;
+
+	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+	event.type = XENKBD_TYPE_MOTION;
+	event.motion.rel_x = rel_x;
+	event.motion.rel_y = rel_y;
+
+	return xenfb_kbd_event(xenfb, &event);
+}
+
+int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
+{
+	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
+	union xenkbd_in_event event;
+
+	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+	event.type = XENKBD_TYPE_POS;
+	event.pos.abs_x = abs_x;
+	event.pos.abs_y = abs_y;
+
+	return xenfb_kbd_event(xenfb, &event);
+}
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -rupN xen-3.1.2-src.orig/tools/ioemu/hw/xenfb.h xen-3.1.2-src.new/tools/ioemu/hw/xenfb.h
--- xen-3.1.2-src.orig/tools/ioemu/hw/xenfb.h	1969-12-31 19:00:00.000000000 -0500
+++ xen-3.1.2-src.new/tools/ioemu/hw/xenfb.h	2007-12-01 14:53:57.000000000 -0500
@@ -0,0 +1,39 @@
+#ifndef _XENFB_H_
+#define _XENFB_H_
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+struct xenfb
+{
+	void *pixels;
+
+	int row_stride;
+	int depth;
+	int width;
+	int height;
+	int abs_pointer_wanted;
+
+	void *user_data;
+
+	void (*update)(struct xenfb *xenfb, int x, int y, int width, int height);
+};
+
+struct xenfb *xenfb_new(void);
+void xenfb_delete(struct xenfb *xenfb);
+void xenfb_teardown(struct xenfb *xenfb);
+
+int xenfb_attach_dom(struct xenfb *xenfb, int domid);
+
+int xenfb_dispatch_store(struct xenfb *xenfb_pub);
+int xenfb_dispatch_channel(struct xenfb *xenfb_pub);
+int xenfb_select_fds(struct xenfb *xenfb, fd_set *readfds);
+int xenfb_poll(struct xenfb *xenfb, fd_set *readfds);
+int xenfb_get_store_fd(struct xenfb *xenfb_pub);
+int xenfb_get_channel_fd(struct xenfb *xenfb_pub);
+
+int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode);
+int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y);
+int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);
+
+#endif
diff -rupN xen-3.1.2-src.orig/tools/ioemu/hw/xen_machine_pv.c xen-3.1.2-src.new/tools/ioemu/hw/xen_machine_pv.c
--- xen-3.1.2-src.orig/tools/ioemu/hw/xen_machine_pv.c	2007-12-01 14:53:45.000000000 -0500
+++ xen-3.1.2-src.new/tools/ioemu/hw/xen_machine_pv.c	2007-12-01 14:53:57.000000000 -0500
@@ -23,7 +23,7 @@
  */
 
 #include "vl.h"
-#include "../../xenfb/xenfb.h"
+#include "xenfb.h"
 #include <linux/input.h>
 
 /* A convenient function for munging pixels between different depths */
diff -rupN xen-3.1.2-src.orig/tools/ioemu/Makefile.target xen-3.1.2-src.new/tools/ioemu/Makefile.target
--- xen-3.1.2-src.orig/tools/ioemu/Makefile.target	2007-12-01 14:53:45.000000000 -0500
+++ xen-3.1.2-src.new/tools/ioemu/Makefile.target	2007-12-01 14:53:57.000000000 -0500
@@ -371,7 +371,7 @@ VL_OBJS+= xenstore.o
 VL_OBJS+= xen_platform.o
 VL_OBJS+= xen_machine_fv.o
 VL_OBJS+= xen_machine_pv.o
-VL_OBJS+= ../../xenfb/xenfb.o
+VL_OBJS+= xenfb.o
 VL_OBJS+= tpm_tis.o
 DEFINES += -DHAS_AUDIO
 endif
diff -rupN xen-3.1.2-src.orig/tools/Makefile xen-3.1.2-src.new/tools/Makefile
--- xen-3.1.2-src.orig/tools/Makefile	2007-12-01 14:47:23.000000000 -0500
+++ xen-3.1.2-src.new/tools/Makefile	2007-12-01 14:53:57.000000000 -0500
@@ -19,7 +19,6 @@ SUBDIRS-y += xenstat
 SUBDIRS-y += libaio
 SUBDIRS-y += blktap
 SUBDIRS-y += libfsimage
-SUBDIRS-$(XENFB_TOOLS) += xenfb
 SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
 
 # These don't cross-compile
diff -rupN xen-3.1.2-src.orig/tools/xenfb/Makefile xen-3.1.2-src.new/tools/xenfb/Makefile
--- xen-3.1.2-src.orig/tools/xenfb/Makefile	2007-11-14 18:35:27.000000000 -0500
+++ xen-3.1.2-src.new/tools/xenfb/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-XEN_ROOT=../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-CFLAGS  += -I$(XEN_LIBXC) -I$(XEN_XENSTORE)
-CFLAGS  += -I$(XEN_ROOT)/linux-2.6-xen-sparse/include -I$(XEN_ROOT)/tools/ioemu
-LDFLAGS += -L$(XEN_LIBXC) -L$(XEN_XENSTORE)
-
-.PHONY: all
-all: build
-
-.PHONY: build
-build:
-	$(MAKE) vncfb sdlfb
-
-install: all
-	$(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
-	$(INSTALL_PROG) vncfb $(DESTDIR)/usr/$(LIBDIR)/xen/bin/xen-vncfb
-	$(INSTALL_PROG) sdlfb $(DESTDIR)/usr/$(LIBDIR)/xen/bin/xen-sdlfb
-
-sdlfb: sdlfb.o xenfb.o
-
-sdlfb.o: CFLAGS += $(shell sdl-config --cflags)
-sdlfb: LDLIBS += $(shell sdl-config --libs) -lxenctrl -lxenstore
-
-clean:
-	$(RM) *.o *~ vncfb sdlfb
-
-vncfb: vncfb.o xenfb.o
-vncfb.o: CFLAGS += $(shell libvncserver-config --cflags)
-vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl -lxenstore
-
-sdlfb.o xenfb.o vncfb.o: xenfb.h
diff -rupN xen-3.1.2-src.orig/tools/xenfb/sdlfb.c xen-3.1.2-src.new/tools/xenfb/sdlfb.c
--- xen-3.1.2-src.orig/tools/xenfb/sdlfb.c	2007-11-14 18:35:27.000000000 -0500
+++ xen-3.1.2-src.new/tools/xenfb/sdlfb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,342 +0,0 @@
-#include <SDL.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <stdlib.h>
-#include <linux/input.h>
-#include <getopt.h>
-#include <string.h>
-#include "xenfb.h"
-
-struct SDLFBData
-{
-	SDL_Surface *dst;
-	SDL_Surface *src;
-};
-
-/*
- * Map from scancode to Linux input layer keycode.  Scancodes are
- * hardware-specific.  This map assumes a standard AT or PS/2
- * keyboard.
- *
- * Why use scancodes?  We can't use key symbols, because they don't
- * identify keys --- they're what keys are mapped to.  The standard
- * German keymap, for instance, maps both KEY_COMMA and KEY_102ND to
- * SDLK_LESS.
- */
-static int keymap[256] = {
-	[9] = KEY_ESC,
-	[10] = KEY_1,
-	[11] = KEY_2,
-	[12] = KEY_3,
-	[13] = KEY_4,
-	[14] = KEY_5,
-	[15] = KEY_6,
-	[16] = KEY_7,
-	[17] = KEY_8,
-	[18] = KEY_9,
-	[19] = KEY_0,
-	[20] = KEY_MINUS,
-	[21] = KEY_EQUAL,
-	[22] = KEY_BACKSPACE,
-	[23] = KEY_TAB,
-	[24] = KEY_Q,
-	[25] = KEY_W,
-	[26] = KEY_E,
-	[27] = KEY_R,
-	[28] = KEY_T,
-	[29] = KEY_Y,
-	[30] = KEY_U,
-	[31] = KEY_I,
-	[32] = KEY_O,
-	[33] = KEY_P,
-	[34] = KEY_LEFTBRACE,
-	[35] = KEY_RIGHTBRACE,
-	[36] = KEY_ENTER,
-	[37] = KEY_LEFTCTRL,
-	[38] = KEY_A,
-	[39] = KEY_S,
-	[40] = KEY_D,
-	[41] = KEY_F,
-	[42] = KEY_G,
-	[43] = KEY_H,
-	[44] = KEY_J,
-	[45] = KEY_K,
-	[46] = KEY_L,
-	[47] = KEY_SEMICOLON,
-	[48] = KEY_APOSTROPHE,
-	[49] = KEY_GRAVE,
-	[50] = KEY_LEFTSHIFT,
-	[51] = KEY_BACKSLASH,
-	[52] = KEY_Z,
-	[53] = KEY_X,
-	[54] = KEY_C,
-	[55] = KEY_V,
-	[56] = KEY_B,
-	[57] = KEY_N,
-	[58] = KEY_M,
-	[59] = KEY_COMMA,
-	[60] = KEY_DOT,
-	[61] = KEY_SLASH,
-	[62] = KEY_RIGHTSHIFT,
-	[63] = KEY_KPASTERISK,
-	[64] = KEY_LEFTALT,
-	[65] = KEY_SPACE,
-	[66] = KEY_CAPSLOCK,
-	[67] = KEY_F1,
-	[68] = KEY_F2,
-	[69] = KEY_F3,
-	[70] = KEY_F4,
-	[71] = KEY_F5,
-	[72] = KEY_F6,
-	[73] = KEY_F7,
-	[74] = KEY_F8,
-	[75] = KEY_F9,
-	[76] = KEY_F10,
-	[77] = KEY_NUMLOCK,
-	[78] = KEY_SCROLLLOCK,
-	[79] = KEY_KP7,
-	[80] = KEY_KP8,
-	[81] = KEY_KP9,
-	[82] = KEY_KPMINUS,
-	[83] = KEY_KP4,
-	[84] = KEY_KP5,
-	[85] = KEY_KP6,
-	[86] = KEY_KPPLUS,
-	[87] = KEY_KP1,
-	[88] = KEY_KP2,
-	[89] = KEY_KP3,
-	[90] = KEY_KP0,
-	[91] = KEY_KPDOT,
-	[94] = KEY_102ND,	/* FIXME is this correct? */
-	[95] = KEY_F11,
-	[96] = KEY_F12,
-	[108] = KEY_KPENTER,
-	[109] = KEY_RIGHTCTRL,
-	[112] = KEY_KPSLASH,
-	[111] = KEY_SYSRQ,
-	[113] = KEY_RIGHTALT,
-	[97] = KEY_HOME,
-	[98] = KEY_UP,
-	[99] = KEY_PAGEUP,
-	[100] = KEY_LEFT,
-	[102] = KEY_RIGHT,
-	[103] = KEY_END,
-	[104] = KEY_DOWN,
-	[105] = KEY_PAGEDOWN,
-	[106] = KEY_INSERT,
-	[107] = KEY_DELETE,
-	[110] = KEY_PAUSE,
-	[115] = KEY_LEFTMETA,
-	[116] = KEY_RIGHTMETA,
-	[117] = KEY_MENU,
-};
-
-static int btnmap[] = {
-	[SDL_BUTTON_LEFT] = BTN_LEFT,
-	[SDL_BUTTON_MIDDLE] = BTN_MIDDLE,
-	[SDL_BUTTON_RIGHT] = BTN_RIGHT,
-	/* FIXME not 100% sure about these: */
-	[SDL_BUTTON_WHEELUP] = BTN_FORWARD,
-	[SDL_BUTTON_WHEELDOWN] BTN_BACK
-};
-
-static void sdl_update(struct xenfb *xenfb, int x, int y, int width, int height)
-{
-	struct SDLFBData *data = xenfb->user_data;
-	SDL_Rect r = { x, y, width, height };
-	SDL_BlitSurface(data->src, &r, data->dst, &r);
-	SDL_UpdateRect(data->dst, x, y, width, height);
-}
-
-static int sdl_on_event(struct xenfb *xenfb, SDL_Event *event)
-{
-	int x, y, ret;
-
-	switch (event->type) {
-	case SDL_KEYDOWN:
-	case SDL_KEYUP:
-		if (keymap[event->key.keysym.scancode] == 0)
-			break;
-		ret = xenfb_send_key(xenfb,
-				     event->type == SDL_KEYDOWN,
-				     keymap[event->key.keysym.scancode]);
-		if (ret < 0)
-			fprintf(stderr, "Key %d %s lost (%s)\n",
-				keymap[event->key.keysym.scancode],
-				event->type == SDL_KEYDOWN ? "down" : "up",
-				strerror(errno));
-		break;
-	case SDL_MOUSEMOTION:
-		if (xenfb->abs_pointer_wanted) {
-			SDL_GetMouseState(&x, &y);
-			ret = xenfb_send_position(xenfb, x, y);
-		} else {
-			SDL_GetRelativeMouseState(&x, &y);
-			ret = xenfb_send_motion(xenfb, x, y);
-		}
-		if (ret < 0)
-			fprintf(stderr, "Pointer to %d,%d lost (%s)\n",
-				x, y, strerror(errno));
-		break;
-	case SDL_MOUSEBUTTONDOWN:
-	case SDL_MOUSEBUTTONUP:
-		if (event->button.button >= sizeof(btnmap) / sizeof(*btnmap))
-			break;
-		if (btnmap[event->button.button] == 0)
-			break;
-		ret = xenfb_send_key(xenfb,
-				     event->type == SDL_MOUSEBUTTONDOWN,
-				     btnmap[event->button.button]);
-		if (ret < 0)
-			fprintf(stderr, "Button %d %s lost (%s)\n",
-				btnmap[event->button.button] - BTN_MOUSE,
-				event->type == SDL_MOUSEBUTTONDOWN ? "down" : "up",
-				strerror(errno));
-		break;
-	case SDL_QUIT:
-		return 0;
-	}
-
-	return 1;
-}
-
-static struct option options[] = {
-	{ "domid", 1, NULL, 'd' },
-	{ "title", 1, NULL, 't' },
-	{ NULL }
-};
-
-int main(int argc, char **argv)
-{
-	struct xenfb *xenfb;
-	int domid = -1;
-        char * title = NULL;
-	fd_set readfds;
-	int nfds;
-	struct SDLFBData data;
-	SDL_Rect r;
-	struct timeval tv;
-	SDL_Event event;
-	int do_quit = 0;
-	int opt;
-	char *endp;
-	int retval;
-
-	while ((opt = getopt_long(argc, argv, "d:t:", options,
-				  NULL)) != -1) {
-		switch (opt) {
-                case 'd':
-			domid = strtol(optarg, &endp, 10);
-			if (endp == optarg || *endp) {
-				fprintf(stderr, "Invalid domain id specified\n");
-				exit(1);
-			}
-			break;
-                case 't':
-			title = strdup(optarg);
-			break;
-		case '?':
-			exit(1);
-                }
-        }
-        if (optind != argc) {
-		fprintf(stderr, "Invalid options!\n");
-		exit(1);
-        }
-        if (domid <= 0) {
-		fprintf(stderr, "Domain ID must be specified!\n");
-		exit(1);
-        }
-
-	xenfb = xenfb_new();
-	if (xenfb == NULL) {
-		fprintf(stderr, "Could not create framebuffer (%s)\n",
-			strerror(errno));
-		exit(1);
-        }
-
-	if (xenfb_attach_dom(xenfb, domid) < 0) {
-		fprintf(stderr, "Could not connect to domain (%s)\n",
-			strerror(errno));
-		exit(1);
-        }
-
-	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
-		fprintf(stderr, "Could not initialize SDL\n");
-		exit(1);
-	}
-
-	data.dst = SDL_SetVideoMode(xenfb->width, xenfb->height, xenfb->depth,
-				    SDL_SWSURFACE);
-	if (!data.dst) {
-		fprintf(stderr, "SDL_SetVideoMode failed\n");
-		exit(1);
-	}
-
-	data.src = SDL_CreateRGBSurfaceFrom(xenfb->pixels,
-					    xenfb->width, xenfb->height,
-					    xenfb->depth, xenfb->row_stride,
-					    0xFF0000, 0xFF00, 0xFF, 0);
-
-	if (!data.src) {
-		fprintf(stderr, "SDL_CreateRGBSurfaceFrom failed\n");
-		exit(1);
-	}
-
-        if (title == NULL)
-		title = strdup("xen-sdlfb");
-        SDL_WM_SetCaption(title, title);
-
-	r.x = r.y = 0;
-	r.w = xenfb->width;
-	r.h = xenfb->height;
-	SDL_BlitSurface(data.src, &r, data.dst, &r);
-	SDL_UpdateRect(data.dst, 0, 0, xenfb->width, xenfb->height);
-
-	xenfb->update = sdl_update;
-	xenfb->user_data = &data;
-
-	SDL_ShowCursor(0);
-
-	/*
-	 * We need to wait for fds becoming ready or SDL events to
-	 * arrive.  We time out the select after 10ms to poll for SDL
-	 * events.  Clunky, but works.  Could avoid the clunkiness
-	 * with a separate thread.
-	 */
-	for (;;) {
-		FD_ZERO(&readfds);
-		nfds = xenfb_select_fds(xenfb, &readfds);
-		tv = (struct timeval){0, 10000};
-
-		if (select(nfds, &readfds, NULL, NULL, &tv) < 0) {
-			if (errno == EINTR)
-				continue;
-			fprintf(stderr,
-				"Can't select() on event channel (%s)\n",
-				strerror(errno));
-			break;
-		}
-
-		while (SDL_PollEvent(&event)) {
-			if (!sdl_on_event(xenfb, &event))
-				do_quit = 1;
-		}
-
-                if (do_quit)
-			break;
-
-		retval = xenfb_poll(xenfb, &readfds);
-		if (retval == -2)
-		    xenfb_teardown(xenfb);
-		if (retval < 0)
-		    break;
-	}
-
-	xenfb_delete(xenfb);
-
-	SDL_Quit();
-
-	return 0;
-}
diff -rupN xen-3.1.2-src.orig/tools/xenfb/vncfb.c xen-3.1.2-src.new/tools/xenfb/vncfb.c
--- xen-3.1.2-src.orig/tools/xenfb/vncfb.c	2007-11-14 18:35:27.000000000 -0500
+++ xen-3.1.2-src.new/tools/xenfb/vncfb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,422 +0,0 @@
-#define _GNU_SOURCE
-#include <errno.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <rfb/rfb.h>
-#include <rfb/keysym.h>
-#include <linux/input.h>
-#include <xs.h>
-#include "xenfb.h"
-
-/* Grab key translation support routines from qemu directory. */
-#define qemu_mallocz(size) calloc(1, (size))
-static const char *bios_dir = "/usr/share/xen/qemu";
-#include "vnc_keysym.h"
-#include "keymaps.c"
-
-static unsigned char atkbd_set2_keycode[512] = {
-
-	  0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
-	  0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
-	  0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
-	  0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
-	  0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
-	  0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
-	  0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
-	 82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
-
-	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
-	173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
-	159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
-	157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
-	226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
-	  0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
-	110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
-
-};
-
-static unsigned char atkbd_unxlate_table[128] = {
-
-	  0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
-	 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
-	 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
-	 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
-	 11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
-	114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
-	 71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
-	 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
-
-};
-
-unsigned char keycode_table[512];
-
-static void *kbd_layout;
-
-static int btnmap[] = {
-	BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE,
-	BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK
-};
-
-static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
-{
-	/*
-	 * We need to map to the key's Linux input layer keycode.
-	 * Unfortunately, we don't get the key here, only the
-	 * rfbKeySym, which is what the key is mapped to.  Mapping
-	 * back to the key is impossible in general, even when you
-	 * know the keymap.  For instance, the standard German keymap
-	 * maps both KEY_COMMA and KEY_102ND to XK_less.  We simply
-	 * assume standard US layout.  This sucks.
-	 */
-	rfbScreenInfoPtr server = cl->screen;
-	struct xenfb *xenfb = server->screenData;
-	int scancode;
-
-	if (keycode >= 'A' && keycode <= 'Z')
-		keycode += 'a' - 'A';
-
-	scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
-	if (scancode == 0)
-		return;
-	if (xenfb_send_key(xenfb, down, scancode) < 0)
-		fprintf(stderr, "Key %d %s lost (%s)\n",
-			scancode, down ? "down" : "up",
-			strerror(errno));
-}
-
-static void on_ptr_event(int buttonMask, int x, int y, rfbClientPtr cl)
-{
-	/* initial pointer state: at (0,0), buttons up */
-	static int last_x, last_y, last_button;
-	rfbScreenInfoPtr server = cl->screen;
-	struct xenfb *xenfb = server->screenData;
-	int i, last_down, down, ret;
-
-	for (i = 0; i < 8; i++) {
-		last_down = last_button & (1 << i);
-		down = buttonMask & (1 << i);
-		if (down == last_down)
-			continue;
-		if (i >= sizeof(btnmap) / sizeof(*btnmap))
-			break;
-		if (btnmap[i] == 0)
-			break;
-		if (xenfb_send_key(xenfb, down != 0, btnmap[i]) < 0)
-			fprintf(stderr, "Button %d %s lost (%s)\n",
-				i, down ? "down" : "up", strerror(errno));
-	}
-
-	if (x != last_x || y != last_y) {
-		if (xenfb->abs_pointer_wanted) 
-			ret = xenfb_send_position(xenfb, x, y);
-		else
-			ret = xenfb_send_motion(xenfb, x - last_x, y - last_y);
-		if (ret < 0)
-			fprintf(stderr, "Pointer to %d,%d lost (%s)\n",
-				x, y, strerror(errno));
-	}
-
-	last_button = buttonMask;
-	last_x = x;
-	last_y = y;
-}
-
-static void xenstore_write_vncport(struct xs_handle *xsh, int port, int domid)
-{
-	char *buf, *path;
-	char portstr[10];
-
-	path = xs_get_domain_path(xsh, domid);
-	if (path == NULL) {
-		fprintf(stderr, "Can't get domain path (%s)\n",
-			strerror(errno));
-		goto out;
-	}
-
-	if (asprintf(&buf, "%s/console/vnc-port", path) == -1) {
-		fprintf(stderr, "Can't make vncport path\n");
-		goto out;
-	}
-
-	if (snprintf(portstr, sizeof(portstr), "%d", port) == -1) {
-		fprintf(stderr, "Can't make vncport value\n");
-		goto out;
-	}
-
-	if (!xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)))
-		fprintf(stderr, "Can't set vncport (%s)\n",
-			strerror(errno));
-
- out:
-	free(buf);
-}
-
-
-static int xenstore_read_vncpasswd(struct xs_handle *xsh, int domid, char *pwbuf, int pwbuflen)
-{
-	char buf[256], *path, *uuid = NULL, *passwd = NULL;
-	unsigned int len, rc = 0;
-
-	if (xsh == NULL) {
-		return -1;
-	}
-
-	path = xs_get_domain_path(xsh, domid);
-	if (path == NULL) {
-		fprintf(stderr, "xs_get_domain_path() error\n");
-		return -1;
-	}
-
-	snprintf(buf, 256, "%s/vm", path);
-	uuid = xs_read(xsh, XBT_NULL, buf, &len);
-	if (uuid == NULL) {
-		fprintf(stderr, "xs_read(): uuid get error\n");
-		free(path);
-		return -1;
-	}
-
-	snprintf(buf, 256, "%s/vncpasswd", uuid);
-	passwd = xs_read(xsh, XBT_NULL, buf, &len);
-	if (passwd == NULL) {
-		free(uuid);
-		free(path);
-		return rc;
-	}
-
-	strncpy(pwbuf, passwd, pwbuflen-1);
-	pwbuf[pwbuflen-1] = '\0';
-
-	fprintf(stderr, "Got a VNC password read from XenStore\n");
-
-	passwd[0] = '\0';
-	snprintf(buf, 256, "%s/vncpasswd", uuid);
-	if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
-		fprintf(stderr, "xs_write() vncpasswd failed\n");
-		rc = -1;
-	}
-
-	free(passwd);
-	free(uuid);
-	free(path);
-
-	return rc;
-}
-
-static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h)
-{
-	rfbScreenInfoPtr server = xenfb->user_data;
-	rfbMarkRectAsModified(server, x, y, x + w, y + h);
-}
-
-static struct option options[] = {
-	{ "domid", 1, NULL, 'd' },
-	{ "vncport", 1, NULL, 'p' },
-	{ "title", 1, NULL, 't' },
-	{ "unused", 0, NULL, 'u' },
-	{ "listen", 1, NULL, 'l' },
-	{ "keymap", 1, NULL, 'k' },
-	{ NULL }
-};
-
-int main(int argc, char **argv)
-{
-	rfbScreenInfoPtr server;
-	char *fake_argv[7] = { "vncfb", "-rfbport", "5901", 
-                               "-desktop", "xen-vncfb", 
-                               "-listen", "127.0.0.1" };
-	int fake_argc = sizeof(fake_argv) / sizeof(fake_argv[0]);
-	int domid = -1, port = -1;
-	char *title = NULL;
-	char *listen = NULL;
-	char *keymap = NULL;
-	bool unused = false;
-	int opt;
-	struct xenfb *xenfb;
-	fd_set readfds;
-	int nfds;
-	char portstr[10];
-	char *endp;
-	int r;
-	struct xs_handle *xsh;
-	char vncpasswd[1024];
-	int i;
-
-	vncpasswd[0] = '\0';
-
-	while ((opt = getopt_long(argc, argv, "d:p:t:uk:", options,
-				  NULL)) != -1) {
-		switch (opt) {
-                case 'd':
-			errno = 0;
-			domid = strtol(optarg, &endp, 10);
-			if (endp == optarg || *endp || errno) {
-				fprintf(stderr, "Invalid domain id specified\n");
-				exit(1);
-			}
-			break;
-                case 'p':
-			errno = 0;
-			port = strtol(optarg, &endp, 10);
-			if (endp == optarg || *endp || errno) {
-				fprintf(stderr, "Invalid port specified\n");
-				exit(1);
-			}
-			break;
-                case 't':
-			title = strdup(optarg);
-			break;
-                case 'u':
-			unused = true;
-			break;
-                case 'l':
-			listen = strdup(optarg);
-			break;
-                case 'k':
-			keymap = strdup(optarg);
-			break;
-		case '?':
-			exit(1);
-                }
-        }
-        if (optind != argc) {
-		fprintf(stderr, "Invalid options!\n");
-		exit(1);
-        }
-        if (domid <= 0) {
-		fprintf(stderr, "Domain ID must be specified!\n");
-		exit(1);
-        }
-            
-        if (port <= 0)
-		port = 5900 + domid;
-	if (snprintf(portstr, sizeof(portstr), "%d", port) == -1) {
-		fprintf(stderr, "Invalid port specified\n");
-		exit(1);
-        }
-
-	if (keymap == NULL){
-		keymap = "en-us";
-	}
-
-	kbd_layout = init_keyboard_layout(keymap);
-	if( !kbd_layout ){
-		fprintf(stderr, "Invalid keyboard_layout\n");
-		exit(1);
-        }
-
-	for (i = 0; i < 128; i++) {
-		keycode_table[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
-		keycode_table[i | 0x80] = 
-			atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
-	}
-
-	fake_argv[2] = portstr;
-
-        if (title != NULL)
-		fake_argv[4] = title;
-
-        if (listen != NULL)
-		fake_argv[6] = listen;
-
-	signal(SIGPIPE, SIG_IGN);
-
-	xenfb = xenfb_new();
-	if (xenfb == NULL) {
-		fprintf(stderr, "Could not create framebuffer (%s)\n",
-			strerror(errno));
-		exit(1);
-	}
-
-	if (xenfb_attach_dom(xenfb, domid) < 0) {
-		fprintf(stderr, "Could not connect to domain (%s)\n",
-			strerror(errno));
-		exit(1);
-	}
-
-	xsh = xs_daemon_open();
-	if (xsh == NULL) {
-	        fprintf(stderr, "cannot open connection to xenstore\n");
-		exit(1);
-	}
-
-
-	if (xenstore_read_vncpasswd(xsh, domid, vncpasswd,
-				    sizeof(vncpasswd)/sizeof(char)) < 0) {
-		fprintf(stderr, "cannot read VNC password from xenstore\n");
-		exit(1);
-	}
-	  
-
-	server = rfbGetScreen(&fake_argc, fake_argv, 
-			      xenfb->width, xenfb->height,
-			      8, 3, xenfb->depth / 8);
-	if (server == NULL) {
-		fprintf(stderr, "Could not create VNC server\n");
-		exit(1);
-	}
-
-	xenfb->user_data = server;
-	xenfb->update = vnc_update;
-
-        if (unused)
-		server->autoPort = true;
-
-	if (vncpasswd[0]) {
-		char **passwds = malloc(sizeof(char**)*2);
-		if (!passwds) {
-			fprintf(stderr, "cannot allocate memory (%s)\n",
-				strerror(errno));
-			exit(1);
-		}
-		fprintf(stderr, "Registered password\n");
-		passwds[0] = vncpasswd;
-		passwds[1] = NULL;
-
-		server->authPasswdData = passwds;
-		server->passwordCheck = rfbCheckPasswordByList;
-	} else {
-		fprintf(stderr, "Running with no password\n");
-	}
-	server->serverFormat.redShift = 16;
-	server->serverFormat.greenShift = 8;
-	server->serverFormat.blueShift = 0;
-	server->kbdAddEvent = on_kbd_event;
-	server->ptrAddEvent = on_ptr_event;
-	server->frameBuffer = xenfb->pixels;
-	server->screenData = xenfb;
-	server->cursor = NULL;
-	rfbInitServer(server);
-
-	rfbRunEventLoop(server, -1, true);
-
-        xenstore_write_vncport(xsh, server->port, domid);
-
-	for (;;) {
-		FD_ZERO(&readfds);
-		nfds = xenfb_select_fds(xenfb, &readfds);
-
-		if (select(nfds, &readfds, NULL, NULL, NULL) < 0) {
-			if (errno == EINTR)
-				continue;
-			fprintf(stderr,
-				"Can't select() on event channel (%s)\n",
-				strerror(errno));
-			break;
-		}
-
-		r = xenfb_poll(xenfb, &readfds);
-		if (r == -2)
-		    xenfb_teardown(xenfb);
-		if (r < 0)
-		    break;
-	}
-
-	rfbScreenCleanup(server);
-	xenfb_delete(xenfb);
-
-	return 0;
-}
diff -rupN xen-3.1.2-src.orig/tools/xenfb/xenfb.c xen-3.1.2-src.new/tools/xenfb/xenfb.c
--- xen-3.1.2-src.orig/tools/xenfb/xenfb.c	2007-12-01 14:53:45.000000000 -0500
+++ xen-3.1.2-src.new/tools/xenfb/xenfb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,826 +0,0 @@
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <xenctrl.h>
-#include <xen/io/xenbus.h>
-#include <xen/io/fbif.h>
-#include <xen/io/kbdif.h>
-#include <xen/io/protocols.h>
-#include <sys/select.h>
-#include <stdbool.h>
-#include <xen/linux/evtchn.h>
-#include <xen/event_channel.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <xs.h>
-
-#include "xenfb.h"
-
-// FIXME defend against malicious frontend?
-
-struct xenfb_device {
-	const char *devicetype;
-	char nodename[64];	/* backend xenstore dir */
-	char otherend[64];	/* frontend xenstore dir */
-	int otherend_id;	/* frontend domid */
-	enum xenbus_state state; /* backend state */
-	void *page;		/* shared page */
-	evtchn_port_t port;
-	struct xenfb_private *xenfb;
-};
-
-struct xenfb_private {
-	struct xenfb pub;
-	int evt_xch;		/* event channel driver handle */
-	int xc;			/* hypervisor interface handle */
-	struct xs_handle *xsh;	/* xs daemon handle */
-	struct xenfb_device fb, kbd;
-	size_t fb_len;		/* size of framebuffer */
-	char protocol[64];	/* frontend protocol */
-};
-
-static void xenfb_detach_dom(struct xenfb_private *);
-
-static char *xenfb_path_in_dom(struct xs_handle *xsh,
-			       char *buf, size_t size,
-			       unsigned domid, const char *fmt, ...)
-{
-	va_list ap;
-	char *domp = xs_get_domain_path(xsh, domid);
-	int n;
-
-        if (domp == NULL)
-		return NULL;
-
-	n = snprintf(buf, size, "%s/", domp);
-	free(domp);
-	if (n >= size)
-		return NULL;
-
-	va_start(ap, fmt);
-	n += vsnprintf(buf + n, size - n, fmt, ap);
-	va_end(ap);
-	if (n >= size)
-		return NULL;
-
-	return buf;
-}
-
-static int xenfb_xs_scanf1(struct xs_handle *xsh,
-			   const char *dir, const char *node,
-			   const char *fmt, void *dest)
-{
-	char buf[1024];
-	char *p;
-	int ret;
-
-	if (snprintf(buf, sizeof(buf), "%s/%s", dir, node) >= sizeof(buf)) {
-		errno = ENOENT;
-		return -1;
-        }
-	p = xs_read(xsh, XBT_NULL, buf, NULL);
-	if (!p) {
-		errno = ENOENT;
-		return -1;
-        }
-	ret = sscanf(p, fmt, dest);
-	free(p);
-	if (ret != 1) {
-		errno = EDOM;
-		return -1;
-        }
-	return ret;
-}
-
-static int xenfb_xs_printf(struct xs_handle *xsh,
-			   const char *dir, const char *node, char *fmt, ...)
-{
-	va_list ap;
-	char key[1024];
-	char val[1024];
-	int n;
-
-	if (snprintf(key, sizeof(key), "%s/%s", dir, node) >= sizeof(key)) {
-		errno = ENOENT;
-		return -1;
-        }
-
-	va_start(ap, fmt);
-	n = vsnprintf(val, sizeof(val), fmt, ap);
-	va_end(ap);
-	if (n >= sizeof(val)) {
-		errno = ENOSPC; /* close enough */
-		return -1;
-	}
-
-	if (!xs_write(xsh, XBT_NULL, key, val, n))
-		return -1;
-	return 0;
-}
-
-static void xenfb_device_init(struct xenfb_device *dev,
-			      const char *type,
-			      struct xenfb_private *xenfb)
-{
-	dev->devicetype = type;
-	dev->otherend_id = -1;
-	dev->port = -1;
-	dev->xenfb = xenfb;
-}
-
-int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
-{
-	struct xenfb_private *xenfb = dev->xenfb;
-
-	dev->otherend_id = domid;
-
-	if (!xenfb_path_in_dom(xenfb->xsh,
-			       dev->otherend, sizeof(dev->otherend),
-			       domid, "device/%s/0", dev->devicetype)) {
-		errno = ENOENT;
-		return -1;
-	}
-	if (!xenfb_path_in_dom(xenfb->xsh,
-			       dev->nodename, sizeof(dev->nodename),
-			       0, "backend/%s/%d/0", dev->devicetype, domid)) {
-		errno = ENOENT;
-		return -1;
-	}
-
-	return 0;
-}
-
-struct xenfb *xenfb_new(void)
-{
-	struct xenfb_private *xenfb = malloc(sizeof(*xenfb));
-	int serrno;
-
-	if (xenfb == NULL)
-		return NULL;
-
-	memset(xenfb, 0, sizeof(*xenfb));
-	xenfb->evt_xch = xenfb->xc = -1;
-	xenfb_device_init(&xenfb->fb, "vfb", xenfb);
-	xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
-
-	xenfb->evt_xch = xc_evtchn_open();
-	if (xenfb->evt_xch == -1)
-		goto fail;
-
-	xenfb->xc = xc_interface_open();
-	if (xenfb->xc == -1)
-		goto fail;
-
-	xenfb->xsh = xs_daemon_open();
-	if (!xenfb->xsh)
-		goto fail;
-
-	return &xenfb->pub;
-
- fail:
-	serrno = errno;
-	xenfb_delete(&xenfb->pub);
-	errno = serrno;
-	return NULL;
-}
-
-/* Remove the backend area in xenbus since the framebuffer really is
-   going away. */
-void xenfb_teardown(struct xenfb *xenfb_pub)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-
-       xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
-       xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
-}
-
-
-void xenfb_delete(struct xenfb *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-
-	xenfb_detach_dom(xenfb);
-	if (xenfb->xc >= 0)
-		xc_interface_close(xenfb->xc);
-	if (xenfb->evt_xch >= 0)
-		xc_evtchn_close(xenfb->evt_xch);
-	if (xenfb->xsh)
-		xs_daemon_close(xenfb->xsh);
-	free(xenfb);
-}
-
-static enum xenbus_state xenfb_read_state(struct xs_handle *xsh,
-					  const char *dir)
-{
-	int ret, state;
-
-	ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state);
-	if (ret < 0)
-		return XenbusStateUnknown;
-
-	if ((unsigned)state > XenbusStateClosed)
-		state = XenbusStateUnknown;
-	return state;
-}
-
-static int xenfb_switch_state(struct xenfb_device *dev,
-			      enum xenbus_state state)
-{
-	struct xs_handle *xsh = dev->xenfb->xsh;
-
-	if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0)
-		return -1;
-	dev->state = state;
-	return 0;
-}
-
-static int xenfb_wait_for_state(struct xs_handle *xsh, const char *dir,
-				unsigned awaited)
-{
-	unsigned state, dummy;
-	char **vec;
-
-	awaited |= 1 << XenbusStateUnknown;
-
-	for (;;) {
-		state = xenfb_read_state(xsh, dir);
-		if ((1 << state) & awaited)
-			return state;
-
-		vec = xs_read_watch(xsh, &dummy);
-		if (!vec)
-			return -1;
-		free(vec);
-	}
-}
-
-static int xenfb_wait_for_backend_creation(struct xenfb_device *dev)
-{
-	struct xs_handle *xsh = dev->xenfb->xsh;
-	int state;
-
-	if (!xs_watch(xsh, dev->nodename, ""))
-		return -1;
-	state = xenfb_wait_for_state(xsh, dev->nodename,
-			(1 << XenbusStateInitialising)
-			| (1 << XenbusStateClosed)
-#if 1 /* TODO fudging state to permit restarting; to be removed */
-			| (1 << XenbusStateInitWait)
-			| (1 << XenbusStateConnected)
-			| (1 << XenbusStateClosing)
-#endif
-			);
-	xs_unwatch(xsh, dev->nodename, "");
-
-	switch (state) {
-#if 1
-	case XenbusStateInitWait:
-	case XenbusStateConnected:
-		printf("Fudging state to %d\n", XenbusStateInitialising); /* FIXME */
-#endif
-	case XenbusStateInitialising:
-	case XenbusStateClosing:
-	case XenbusStateClosed:
-		break;
-	default:
-		return -1;
-	}
-
-	return 0;
-}
-
-static int xenfb_hotplug(struct xenfb_device *dev)
-{
-	if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename,
-			    "hotplug-status", "connected"))
-		return -1;
-	return 0;
-}
-
-static int xenfb_wait_for_frontend_initialised(struct xenfb_device *dev)
-{
-	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
-#if 1 /* TODO fudging state to permit restarting; to be removed */
-			(1 << XenbusStateInitialised)
-			| (1 << XenbusStateConnected)
-#else
-			1 << XenbusStateInitialised,
-#endif
-			)) {
-#if 1
-	case XenbusStateConnected:
-		printf("Fudging state to %d\n", XenbusStateInitialised); /* FIXME */
-#endif
-	case XenbusStateInitialised:
-		break;
-	default:
-		return -1;
-	}
-
-	return 0;
-}
-
-static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
-{
-	uint32_t *src32 = src;
-	uint64_t *src64 = src;
-	int i;
-
-	for (i = 0; i < count; i++)
-		dst[i] = (mode == 32) ? src32[i] : src64[i];
-}
-
-static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
-{
-	struct xenfb_page *page = xenfb->fb.page;
-	int n_fbmfns;
-	int n_fbdirs;
-	unsigned long *pgmfns = NULL;
-	unsigned long *fbmfns = NULL;
-	void *map, *pd;
-	int mode, ret = -1;
-
-	/* default to native */
-	pd = page->pd;
-	mode = sizeof(unsigned long) * 8;
-
-	if (0 == strlen(xenfb->protocol)) {
-		/*
-		 * Undefined protocol, some guesswork needed.
-		 *
-		 * Old frontends which don't set the protocol use
-		 * one page directory only, thus pd[1] must be zero.
-		 * pd[1] of the 32bit struct layout and the lower
-		 * 32 bits of pd[0] of the 64bit struct layout have
-		 * the same location, so we can check that ...
-		 */
-		uint32_t *ptr32 = NULL;
-		uint32_t *ptr64 = NULL;
-#if defined(__i386__)
-		ptr32 = (void*)page->pd;
-		ptr64 = ((void*)page->pd) + 4;
-#elif defined(__x86_64__)
-		ptr32 = ((void*)page->pd) - 4;
-		ptr64 = (void*)page->pd;
-#endif
-		if (ptr32) {
-			if (0 == ptr32[1]) {
-				mode = 32;
-				pd   = ptr32;
-			} else {
-				mode = 64;
-				pd   = ptr64;
-			}
-		}
-#if defined(__x86_64__)
-	} else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) {
-		/* 64bit dom0, 32bit domU */
-		mode = 32;
-		pd   = ((void*)page->pd) - 4;
-#elif defined(__i386__)
-	} else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) {
-		/* 32bit dom0, 64bit domU */
-		mode = 64;
-		pd   = ((void*)page->pd) + 4;
-#endif
-	}
-
-	n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
-	n_fbdirs = n_fbmfns * mode / 8;
-	n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
-
-	pgmfns = malloc(sizeof(unsigned long) * n_fbdirs);
-	fbmfns = malloc(sizeof(unsigned long) * n_fbmfns);
-	if (!pgmfns || !fbmfns)
-		goto out;
-
-	/*
-	 * Bug alert: xc_map_foreign_batch() can fail partly and
-	 * return a non-null value.  This is a design flaw.  When it
-	 * happens, we happily continue here, and later crash on
-	 * access.
-	 */
-	xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
-	map = xc_map_foreign_batch(xenfb->xc, domid,
-				   PROT_READ, pgmfns, n_fbdirs);
-	if (map == NULL)
-		goto out;
-	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
-	munmap(map, n_fbdirs * XC_PAGE_SIZE);
-
-	xenfb->pub.pixels = xc_map_foreign_batch(xenfb->xc, domid,
-				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
-	if (xenfb->pub.pixels == NULL)
-		goto out;
-
-	ret = 0; /* all is fine */
-
- out:
-	if (pgmfns)
-		free(pgmfns);
-	if (fbmfns)
-		free(fbmfns);
-	return ret;
-}
-
-static int xenfb_bind(struct xenfb_device *dev)
-{
-	struct xenfb_private *xenfb = dev->xenfb;
-	unsigned long mfn;
-	evtchn_port_t evtchn;
-
-	if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu",
-			    &mfn) < 0)
-		return -1;
-	if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u",
-			    &evtchn) < 0)
-		return -1;
-
-	dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch,
-					       dev->otherend_id, evtchn);
-	if (dev->port == -1)
-		return -1;
-
-	dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id,
-			XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
-	if (dev->page == NULL)
-		return -1;
-
-	return 0;
-}
-
-static void xenfb_unbind(struct xenfb_device *dev)
-{
-	if (dev->page) {
-		munmap(dev->page, XC_PAGE_SIZE);
-		dev->page = NULL;
-	}
-        if (dev->port >= 0) {
-		xc_evtchn_unbind(dev->xenfb->evt_xch, dev->port);
-		dev->port = -1;
-	}
-}
-
-static int xenfb_wait_for_frontend_connected(struct xenfb_device *dev)
-{
-	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
-				     1 << XenbusStateConnected)) {
-	case XenbusStateConnected:
-		break;
-	default:
-		return -1;
-	}
-
-	return 0;
-}
-
-static void xenfb_dev_fatal(struct xenfb_device *dev, int err,
-			    const char *fmt, ...)
-{
-	struct xs_handle *xsh = dev->xenfb->xsh;
-	va_list ap;
-	char errdir[80];
-	char buf[1024];
-	int n;
-
-	fprintf(stderr, "%s ", dev->nodename); /* somewhat crude */
-	va_start(ap, fmt);
-	vfprintf(stderr, fmt, ap);
-	va_end(ap);
-	if (err)
-		fprintf(stderr, " (%s)", strerror(err));
-	putc('\n', stderr);
-
-	if (!xenfb_path_in_dom(xsh, errdir, sizeof(errdir), 0,
-			       "error/%s", dev->nodename))
-		goto out;	/* FIXME complain */
-
-	va_start(ap, fmt);
-	n = snprintf(buf, sizeof(buf), "%d ", err);
-	snprintf(buf + n, sizeof(buf) - n, fmt, ap);
-	va_end(ap);
-
-	if (xenfb_xs_printf(xsh, buf, "error", "%s", buf) < 0)
-		goto out;	/* FIXME complain */
-
- out:
-	xenfb_switch_state(dev, XenbusStateClosing);
-}
-
-int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	struct xs_handle *xsh = xenfb->xsh;
-	int val, serrno;
-	struct xenfb_page *fb_page;
-
-	xenfb_detach_dom(xenfb);
-
-	xenfb_device_set_domain(&xenfb->fb, domid);
-	xenfb_device_set_domain(&xenfb->kbd, domid);
-
-	if (xenfb_wait_for_backend_creation(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_wait_for_backend_creation(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_xs_printf(xsh, xenfb->kbd.nodename, "feature-abs-pointer", "1"))
-		goto error;
-	if (xenfb_switch_state(&xenfb->fb, XenbusStateInitWait))
-		goto error;
-	if (xenfb_switch_state(&xenfb->kbd, XenbusStateInitWait))
-		goto error;
-
-	if (xenfb_hotplug(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_hotplug(&xenfb->kbd) < 0)
-		goto error;
-
-	if (!xs_watch(xsh, xenfb->fb.otherend, ""))
-		goto error;
-	if (!xs_watch(xsh, xenfb->kbd.otherend, ""))
-		goto error;
-
-	if (xenfb_wait_for_frontend_initialised(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_wait_for_frontend_initialised(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_bind(&xenfb->fb) < 0)
-		goto error;
-	if (xenfb_bind(&xenfb->kbd) < 0)
-		goto error;
-
-	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "feature-update",
-			    "%d", &val) < 0)
-		val = 0;
-	if (!val) {
-		errno = ENOTSUP;
-		goto error;
-	}
-	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
-			    xenfb->protocol) < 0)
-		xenfb->protocol[0] = '\0';
-	xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
-
-	/* TODO check for permitted ranges */
-	fb_page = xenfb->fb.page;
-	xenfb->pub.depth = fb_page->depth;
-	xenfb->pub.width = fb_page->width;
-	xenfb->pub.height = fb_page->height;
-	/* TODO check for consistency with the above */
-	xenfb->fb_len = fb_page->mem_length;
-	xenfb->pub.row_stride = fb_page->line_length;
-
-	if (xenfb_map_fb(xenfb, domid) < 0)
-		goto error;
-
-	if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
-		goto error;
-	if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
-		goto error;
-
-	if (xenfb_wait_for_frontend_connected(&xenfb->kbd) < 0)
-		goto error;
-	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
-			    "%d", &val) < 0)
-		val = 0;
-	xenfb->pub.abs_pointer_wanted = val;
-
-	return 0;
-
- error:
-	serrno = errno;
-	xenfb_detach_dom(xenfb);
-	xenfb_dev_fatal(&xenfb->fb, serrno, "on fire");
-	xenfb_dev_fatal(&xenfb->kbd, serrno, "on fire");
-        errno = serrno;
-        return -1;
-}
-
-static void xenfb_detach_dom(struct xenfb_private *xenfb)
-{
-	xenfb_unbind(&xenfb->fb);
-	xenfb_unbind(&xenfb->kbd);
-	if (xenfb->pub.pixels) {
-		munmap(xenfb->pub.pixels, xenfb->fb_len);
-		xenfb->pub.pixels = NULL;
-	}
-}
-
-static void xenfb_on_fb_event(struct xenfb_private *xenfb)
-{
-	uint32_t prod, cons;
-	struct xenfb_page *page = xenfb->fb.page;
-
-	prod = page->out_prod;
-	if (prod == page->out_cons)
-		return;
-	rmb();			/* ensure we see ring contents up to prod */
-	for (cons = page->out_cons; cons != prod; cons++) {
-		union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
-
-		switch (event->type) {
-		case XENFB_TYPE_UPDATE:
-                    if (xenfb->pub.update)
-			xenfb->pub.update(&xenfb->pub,
-					  event->update.x, event->update.y,
-					  event->update.width, event->update.height);
-                    break;
-		}
-	}
-	mb();			/* ensure we're done with ring contents */
-	page->out_cons = cons;
-	xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
-}
-
-static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
-{
-	struct xenkbd_page *page = xenfb->kbd.page;
-
-	/* We don't understand any keyboard events, so just ignore them. */
-	if (page->out_prod == page->out_cons)
-		return;
-	page->out_cons = page->out_prod;
-	xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
-}
-
-static int xenfb_on_state_change(struct xenfb_device *dev)
-{
-	enum xenbus_state state;
-
-	state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
-
-	switch (state) {
-	case XenbusStateUnknown:
-		/* There was an error reading the frontend state.  The
-		   domain has probably gone away; in any case, there's
-		   not much point in us continuing. */
-		return -1;
-	case XenbusStateInitialising:
-	case XenbusStateInitWait:
-	case XenbusStateInitialised:
-	case XenbusStateConnected:
-		break;
-	case XenbusStateClosing:
-		xenfb_unbind(dev);
-		xenfb_switch_state(dev, state);
-		break;
-	case XenbusStateClosed:
-		xenfb_switch_state(dev, state);
-	}
-	return 0;
-}
-
-int xenfb_dispatch_channel(struct xenfb *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	evtchn_port_t port;
-	port = xc_evtchn_pending(xenfb->evt_xch);
-	if (port == -1)
-		return -1;
-
-	if (port == xenfb->fb.port)
-		xenfb_on_fb_event(xenfb);
-	else if (port == xenfb->kbd.port)
-		xenfb_on_kbd_event(xenfb);
-
-	if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
-		return -1;
-
-	return 0;
-}
-
-int xenfb_dispatch_store(struct xenfb *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	unsigned dummy;
-	char **vec;
-	int r;
-
-	vec = xs_read_watch(xenfb->xsh, &dummy);
-	free(vec);
-	r = xenfb_on_state_change(&xenfb->fb);
-	if (r == 0)
-		r = xenfb_on_state_change(&xenfb->kbd);
-	if (r == -1)
-		return -2;
-
-	return 0;
-}
-
-
-/* Returns 0 normally, -1 on error, or -2 if the domain went away. */
-int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	int ret;
-
-	if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
-		if ((ret = xenfb_dispatch_channel(xenfb_pub)) < 0)
-			return ret;
-	}
-
-	if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) {
-		if ((ret = xenfb_dispatch_store(xenfb_pub)) < 0)
-			return ret;
-	}
-
-	return 0;
-}
-
-int xenfb_select_fds(struct xenfb *xenfb_pub, fd_set *readfds)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	int fd1 = xc_evtchn_fd(xenfb->evt_xch);
-	int fd2 = xs_fileno(xenfb->xsh);
-
-	FD_SET(fd1, readfds);
-	FD_SET(fd2, readfds);
-	return fd1 > fd2 ? fd1 + 1 : fd2 + 1;
-}
-
-int xenfb_get_store_fd(struct xenfb *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	return xs_fileno(xenfb->xsh);
-}
-
-int xenfb_get_channel_fd(struct xenfb *xenfb_pub)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	return xc_evtchn_fd(xenfb->evt_xch);
-}
-
-static int xenfb_kbd_event(struct xenfb_private *xenfb,
-			   union xenkbd_in_event *event)
-{
-	uint32_t prod;
-	struct xenkbd_page *page = xenfb->kbd.page;
-
-	if (xenfb->kbd.state != XenbusStateConnected)
-		return 0;
-
-	prod = page->in_prod;
-	if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
-		errno = EAGAIN;
-		return -1;
-	}
-
-	mb();			/* ensure ring space available */
-	XENKBD_IN_RING_REF(page, prod) = *event;
-	wmb();			/* ensure ring contents visible */
-	page->in_prod = prod + 1;
-	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
-}
-
-int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	union xenkbd_in_event event;
-
-	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-	event.type = XENKBD_TYPE_KEY;
-	event.key.pressed = down ? 1 : 0;
-	event.key.keycode = keycode;
-
-	return xenfb_kbd_event(xenfb, &event);
-}
-
-int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	union xenkbd_in_event event;
-
-	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-	event.type = XENKBD_TYPE_MOTION;
-	event.motion.rel_x = rel_x;
-	event.motion.rel_y = rel_y;
-
-	return xenfb_kbd_event(xenfb, &event);
-}
-
-int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
-{
-	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-	union xenkbd_in_event event;
-
-	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-	event.type = XENKBD_TYPE_POS;
-	event.pos.abs_x = abs_x;
-	event.pos.abs_y = abs_y;
-
-	return xenfb_kbd_event(xenfb, &event);
-}
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff -rupN xen-3.1.2-src.orig/tools/xenfb/xenfb.h xen-3.1.2-src.new/tools/xenfb/xenfb.h
--- xen-3.1.2-src.orig/tools/xenfb/xenfb.h	2007-12-01 14:53:45.000000000 -0500
+++ xen-3.1.2-src.new/tools/xenfb/xenfb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-#ifndef _XENFB_H_
-#define _XENFB_H_
-
-#include <stdbool.h>
-#include <sys/types.h>
-
-struct xenfb
-{
-	void *pixels;
-
-	int row_stride;
-	int depth;
-	int width;
-	int height;
-	int abs_pointer_wanted;
-
-	void *user_data;
-
-	void (*update)(struct xenfb *xenfb, int x, int y, int width, int height);
-};
-
-struct xenfb *xenfb_new(void);
-void xenfb_delete(struct xenfb *xenfb);
-void xenfb_teardown(struct xenfb *xenfb);
-
-int xenfb_attach_dom(struct xenfb *xenfb, int domid);
-
-int xenfb_dispatch_store(struct xenfb *xenfb_pub);
-int xenfb_dispatch_channel(struct xenfb *xenfb_pub);
-int xenfb_select_fds(struct xenfb *xenfb, fd_set *readfds);
-int xenfb_poll(struct xenfb *xenfb, fd_set *readfds);
-int xenfb_get_store_fd(struct xenfb *xenfb_pub);
-int xenfb_get_channel_fd(struct xenfb *xenfb_pub);
-
-int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode);
-int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y);
-int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);
-
-#endif