ia64/xen-unstable

changeset 16230:1ed990bc8da9

pv-qemu: Remove standalone xenfb code

This patch removes all trace of the standalone paravirt framebuffer
daemon. With this there is no longer any requirement for
LibVNCServer. Everything is handled by the QEMU device model. The
xenfb.c and xenfb.h files are now moved (without code change) into
tools/ioemu/hw/ & the temporary Makefile hack from the previous patch
is removed.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
author Keir Fraser <keir@xensource.com>
date Thu Oct 25 14:37:23 2007 +0100 (2007-10-25)
parents 290b460838a8
children 93938fee0bf5
files Config.mk tools/Makefile tools/check/Makefile tools/check/check_libvncserver tools/check/check_sdl tools/ioemu/Makefile.target tools/ioemu/hw/xen_machine_pv.c tools/ioemu/hw/xenfb.c tools/ioemu/hw/xenfb.h tools/xenfb/Makefile tools/xenfb/sdlfb.c tools/xenfb/vncfb.c tools/xenfb/xenfb.c tools/xenfb/xenfb.h
line diff
     1.1 --- a/Config.mk	Thu Oct 25 14:35:04 2007 +0100
     1.2 +++ b/Config.mk	Thu Oct 25 14:37:23 2007 +0100
     1.3 @@ -89,7 +89,6 @@ ACM_SECURITY ?= n
     1.4  XENSTAT_XENTOP     ?= y
     1.5  VTPM_TOOLS         ?= n
     1.6  LIBXENAPI_BINDINGS ?= n
     1.7 -XENFB_TOOLS        ?= n
     1.8  PYTHON_TOOLS       ?= y
     1.9  
    1.10  -include $(XEN_ROOT)/.config
     2.1 --- a/tools/Makefile	Thu Oct 25 14:35:04 2007 +0100
     2.2 +++ b/tools/Makefile	Thu Oct 25 14:37:23 2007 +0100
     2.3 @@ -20,7 +20,6 @@ SUBDIRS-y += xenstat
     2.4  SUBDIRS-y += libaio
     2.5  SUBDIRS-y += blktap
     2.6  SUBDIRS-y += libfsimage
     2.7 -SUBDIRS-$(XENFB_TOOLS) += xenfb
     2.8  SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
     2.9  
    2.10  # These don't cross-compile
     3.1 --- a/tools/check/Makefile	Thu Oct 25 14:35:04 2007 +0100
     3.2 +++ b/tools/check/Makefile	Thu Oct 25 14:37:23 2007 +0100
     3.3 @@ -7,7 +7,7 @@ all: build
     3.4  # Check this machine is OK for building on.
     3.5  .PHONY: build
     3.6  build:
     3.7 -	XENFB_TOOLS=$(XENFB_TOOLS) LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) ./chk build
     3.8 +	LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) ./chk build
     3.9  
    3.10  # Check this machine is OK for installing on.
    3.11  # DO NOT use this check from 'make install' in the parent
    3.12 @@ -15,7 +15,7 @@ build:
    3.13  # copy rather than actually installing.
    3.14  .PHONY: install
    3.15  install:
    3.16 -	XENFB_TOOLS=$(XENFB_TOOLS) LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) ./chk install
    3.17 +	LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) ./chk install
    3.18  
    3.19  .PHONY: clean
    3.20  clean:
     4.1 --- a/tools/check/check_libvncserver	Thu Oct 25 14:35:04 2007 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,38 +0,0 @@
     4.4 -#!/bin/sh
     4.5 -# CHECK-BUILD CHECK-INSTALL
     4.6 -
     4.7 -if [ ! "$XENFB_TOOLS" = "y" ]
     4.8 -then
     4.9 -    echo -n "unused, "
    4.10 -    exit 0
    4.11 -fi
    4.12 -
    4.13 -RC=0
    4.14 -
    4.15 -LIBVNCSERVER_CONFIG="$(which libvncserver-config)"
    4.16 -tmpfile=$(mktemp)
    4.17 -
    4.18 -if test -z ${LIBVNCSERVER_CONFIG}; then 
    4.19 -    RC=1
    4.20 -else
    4.21 -    ${LIBVNCSERVER_CONFIG} --libs 2>&1 > /dev/null
    4.22 -    RC=$?
    4.23 -fi
    4.24 -
    4.25 -if test $RC -ne 0; then
    4.26 -    echo "FAILED"
    4.27 -	echo " *** libvncserver-config is missing. "
    4.28 -    echo " *** Please install libvncserver."
    4.29 -elif ! ld $($LIBVNCSERVER_CONFIG --libs) -o $tmpfile >/dev/null 2>&1; then
    4.30 -    echo "FAILED"
    4.31 -    echo " *** dependency libraries for libvncserver are missing: "
    4.32 -    RC=1
    4.33 -    for i in $(ld $($LIBVNCSERVER_CONFIG --libs) -o $tmpfile 2>&1 >/dev/null); do
    4.34 -        case $i in
    4.35 -        -l*) echo lib${i#-l}
    4.36 -        esac
    4.37 -    done
    4.38 -fi
    4.39 -rm -f $tmpfile
    4.40 -
    4.41 -exit $RC
     5.1 --- a/tools/check/check_sdl	Thu Oct 25 14:35:04 2007 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,27 +0,0 @@
     5.4 -#!/bin/sh
     5.5 -# CHECK-BUILD CHECK-INSTALL
     5.6 -
     5.7 -if [ ! "$XENFB_TOOLS" = "y" ]
     5.8 -then
     5.9 -    echo -n "unused, "
    5.10 -    exit 0
    5.11 -fi
    5.12 -
    5.13 -RC=0
    5.14 -
    5.15 -SDL_CONFIG="$(which sdl-config)"
    5.16 -
    5.17 -if test -z ${SDL_CONFIG}; then 
    5.18 -    RC=1
    5.19 -else
    5.20 -    ${SDL_CONFIG} --libs 2>&1 > /dev/null
    5.21 -    RC=$?
    5.22 -fi
    5.23 -
    5.24 -if test $RC -ne 0; then
    5.25 -    echo "FAILED"
    5.26 -	echo " *** sdl-config is missing. "
    5.27 -    echo " *** Please install libsdl-dev or sdl."
    5.28 -fi
    5.29 -
    5.30 -exit $RC
     6.1 --- a/tools/ioemu/Makefile.target	Thu Oct 25 14:35:04 2007 +0100
     6.2 +++ b/tools/ioemu/Makefile.target	Thu Oct 25 14:37:23 2007 +0100
     6.3 @@ -411,7 +411,7 @@ VL_OBJS+= xenstore.o
     6.4  VL_OBJS+= xen_platform.o
     6.5  VL_OBJS+= xen_machine_fv.o
     6.6  VL_OBJS+= xen_machine_pv.o
     6.7 -VL_OBJS+= ../../xenfb/xenfb.o
     6.8 +VL_OBJS+= xenfb.o
     6.9  VL_OBJS+= tpm_tis.o
    6.10  CPPFLAGS += -DHAS_AUDIO
    6.11  endif
     7.1 --- a/tools/ioemu/hw/xen_machine_pv.c	Thu Oct 25 14:35:04 2007 +0100
     7.2 +++ b/tools/ioemu/hw/xen_machine_pv.c	Thu Oct 25 14:37:23 2007 +0100
     7.3 @@ -23,7 +23,7 @@
     7.4   */
     7.5  
     7.6  #include "vl.h"
     7.7 -#include "../../xenfb/xenfb.h"
     7.8 +#include "xenfb.h"
     7.9  #include <linux/input.h>
    7.10  
    7.11  /*
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/ioemu/hw/xenfb.c	Thu Oct 25 14:37:23 2007 +0100
     8.3 @@ -0,0 +1,819 @@
     8.4 +#include <stdarg.h>
     8.5 +#include <stdlib.h>
     8.6 +#include <sys/types.h>
     8.7 +#include <fcntl.h>
     8.8 +#include <unistd.h>
     8.9 +#include <xenctrl.h>
    8.10 +#include <xen/io/xenbus.h>
    8.11 +#include <xen/io/fbif.h>
    8.12 +#include <xen/io/kbdif.h>
    8.13 +#include <xen/io/protocols.h>
    8.14 +#include <sys/select.h>
    8.15 +#include <stdbool.h>
    8.16 +#include <xen/event_channel.h>
    8.17 +#include <sys/mman.h>
    8.18 +#include <errno.h>
    8.19 +#include <stdio.h>
    8.20 +#include <string.h>
    8.21 +#include <time.h>
    8.22 +#include <xs.h>
    8.23 +
    8.24 +#include "xenfb.h"
    8.25 +
    8.26 +// FIXME defend against malicious frontend?
    8.27 +
    8.28 +struct xenfb_device {
    8.29 +	const char *devicetype;
    8.30 +	char nodename[64];	/* backend xenstore dir */
    8.31 +	char otherend[64];	/* frontend xenstore dir */
    8.32 +	int otherend_id;	/* frontend domid */
    8.33 +	enum xenbus_state state; /* backend state */
    8.34 +	void *page;		/* shared page */
    8.35 +	evtchn_port_t port;
    8.36 +	struct xenfb_private *xenfb;
    8.37 +};
    8.38 +
    8.39 +struct xenfb_private {
    8.40 +	struct xenfb pub;
    8.41 +	int evt_xch;		/* event channel driver handle */
    8.42 +	int xc;			/* hypervisor interface handle */
    8.43 +	struct xs_handle *xsh;	/* xs daemon handle */
    8.44 +	struct xenfb_device fb, kbd;
    8.45 +	size_t fb_len;		/* size of framebuffer */
    8.46 +	char protocol[64];	/* frontend protocol */
    8.47 +};
    8.48 +
    8.49 +static void xenfb_detach_dom(struct xenfb_private *);
    8.50 +
    8.51 +static char *xenfb_path_in_dom(struct xs_handle *xsh,
    8.52 +			       char *buf, size_t size,
    8.53 +			       unsigned domid, const char *fmt, ...)
    8.54 +{
    8.55 +	va_list ap;
    8.56 +	char *domp = xs_get_domain_path(xsh, domid);
    8.57 +	int n;
    8.58 +
    8.59 +        if (domp == NULL)
    8.60 +		return NULL;
    8.61 +
    8.62 +	n = snprintf(buf, size, "%s/", domp);
    8.63 +	free(domp);
    8.64 +	if (n >= size)
    8.65 +		return NULL;
    8.66 +
    8.67 +	va_start(ap, fmt);
    8.68 +	n += vsnprintf(buf + n, size - n, fmt, ap);
    8.69 +	va_end(ap);
    8.70 +	if (n >= size)
    8.71 +		return NULL;
    8.72 +
    8.73 +	return buf;
    8.74 +}
    8.75 +
    8.76 +static int xenfb_xs_scanf1(struct xs_handle *xsh,
    8.77 +			   const char *dir, const char *node,
    8.78 +			   const char *fmt, void *dest)
    8.79 +{
    8.80 +	char buf[1024];
    8.81 +	char *p;
    8.82 +	int ret;
    8.83 +
    8.84 +	if (snprintf(buf, sizeof(buf), "%s/%s", dir, node) >= sizeof(buf)) {
    8.85 +		errno = ENOENT;
    8.86 +		return -1;
    8.87 +        }
    8.88 +	p = xs_read(xsh, XBT_NULL, buf, NULL);
    8.89 +	if (!p) {
    8.90 +		errno = ENOENT;
    8.91 +		return -1;
    8.92 +        }
    8.93 +	ret = sscanf(p, fmt, dest);
    8.94 +	free(p);
    8.95 +	if (ret != 1) {
    8.96 +		errno = EDOM;
    8.97 +		return -1;
    8.98 +        }
    8.99 +	return ret;
   8.100 +}
   8.101 +
   8.102 +static int xenfb_xs_printf(struct xs_handle *xsh,
   8.103 +			   const char *dir, const char *node, char *fmt, ...)
   8.104 +{
   8.105 +	va_list ap;
   8.106 +	char key[1024];
   8.107 +	char val[1024];
   8.108 +	int n;
   8.109 +
   8.110 +	if (snprintf(key, sizeof(key), "%s/%s", dir, node) >= sizeof(key)) {
   8.111 +		errno = ENOENT;
   8.112 +		return -1;
   8.113 +        }
   8.114 +
   8.115 +	va_start(ap, fmt);
   8.116 +	n = vsnprintf(val, sizeof(val), fmt, ap);
   8.117 +	va_end(ap);
   8.118 +	if (n >= sizeof(val)) {
   8.119 +		errno = ENOSPC; /* close enough */
   8.120 +		return -1;
   8.121 +	}
   8.122 +
   8.123 +	if (!xs_write(xsh, XBT_NULL, key, val, n))
   8.124 +		return -1;
   8.125 +	return 0;
   8.126 +}
   8.127 +
   8.128 +static void xenfb_device_init(struct xenfb_device *dev,
   8.129 +			      const char *type,
   8.130 +			      struct xenfb_private *xenfb)
   8.131 +{
   8.132 +	dev->devicetype = type;
   8.133 +	dev->otherend_id = -1;
   8.134 +	dev->port = -1;
   8.135 +	dev->xenfb = xenfb;
   8.136 +}
   8.137 +
   8.138 +int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
   8.139 +{
   8.140 +	struct xenfb_private *xenfb = dev->xenfb;
   8.141 +
   8.142 +	dev->otherend_id = domid;
   8.143 +
   8.144 +	if (!xenfb_path_in_dom(xenfb->xsh,
   8.145 +			       dev->otherend, sizeof(dev->otherend),
   8.146 +			       domid, "device/%s/0", dev->devicetype)) {
   8.147 +		errno = ENOENT;
   8.148 +		return -1;
   8.149 +	}
   8.150 +	if (!xenfb_path_in_dom(xenfb->xsh,
   8.151 +			       dev->nodename, sizeof(dev->nodename),
   8.152 +			       0, "backend/%s/%d/0", dev->devicetype, domid)) {
   8.153 +		errno = ENOENT;
   8.154 +		return -1;
   8.155 +	}
   8.156 +
   8.157 +	return 0;
   8.158 +}
   8.159 +
   8.160 +struct xenfb *xenfb_new(void)
   8.161 +{
   8.162 +	struct xenfb_private *xenfb = malloc(sizeof(*xenfb));
   8.163 +	int serrno;
   8.164 +
   8.165 +	if (xenfb == NULL)
   8.166 +		return NULL;
   8.167 +
   8.168 +	memset(xenfb, 0, sizeof(*xenfb));
   8.169 +	xenfb->evt_xch = xenfb->xc = -1;
   8.170 +	xenfb_device_init(&xenfb->fb, "vfb", xenfb);
   8.171 +	xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
   8.172 +
   8.173 +	xenfb->evt_xch = xc_evtchn_open();
   8.174 +	if (xenfb->evt_xch == -1)
   8.175 +		goto fail;
   8.176 +
   8.177 +	xenfb->xc = xc_interface_open();
   8.178 +	if (xenfb->xc == -1)
   8.179 +		goto fail;
   8.180 +
   8.181 +	xenfb->xsh = xs_daemon_open();
   8.182 +	if (!xenfb->xsh)
   8.183 +		goto fail;
   8.184 +
   8.185 +	return &xenfb->pub;
   8.186 +
   8.187 + fail:
   8.188 +	serrno = errno;
   8.189 +	xenfb_delete(&xenfb->pub);
   8.190 +	errno = serrno;
   8.191 +	return NULL;
   8.192 +}
   8.193 +
   8.194 +/* Remove the backend area in xenbus since the framebuffer really is
   8.195 +   going away. */
   8.196 +void xenfb_teardown(struct xenfb *xenfb_pub)
   8.197 +{
   8.198 +       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.199 +
   8.200 +       xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
   8.201 +       xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
   8.202 +}
   8.203 +
   8.204 +
   8.205 +void xenfb_delete(struct xenfb *xenfb_pub)
   8.206 +{
   8.207 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.208 +
   8.209 +	xenfb_detach_dom(xenfb);
   8.210 +	if (xenfb->xc >= 0)
   8.211 +		xc_interface_close(xenfb->xc);
   8.212 +	if (xenfb->evt_xch >= 0)
   8.213 +		xc_evtchn_close(xenfb->evt_xch);
   8.214 +	if (xenfb->xsh)
   8.215 +		xs_daemon_close(xenfb->xsh);
   8.216 +	free(xenfb);
   8.217 +}
   8.218 +
   8.219 +static enum xenbus_state xenfb_read_state(struct xs_handle *xsh,
   8.220 +					  const char *dir)
   8.221 +{
   8.222 +	int ret, state;
   8.223 +
   8.224 +	ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state);
   8.225 +	if (ret < 0)
   8.226 +		return XenbusStateUnknown;
   8.227 +
   8.228 +	if ((unsigned)state > XenbusStateClosed)
   8.229 +		state = XenbusStateUnknown;
   8.230 +	return state;
   8.231 +}
   8.232 +
   8.233 +static int xenfb_switch_state(struct xenfb_device *dev,
   8.234 +			      enum xenbus_state state)
   8.235 +{
   8.236 +	struct xs_handle *xsh = dev->xenfb->xsh;
   8.237 +
   8.238 +	if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0)
   8.239 +		return -1;
   8.240 +	dev->state = state;
   8.241 +	return 0;
   8.242 +}
   8.243 +
   8.244 +static int xenfb_wait_for_state(struct xs_handle *xsh, const char *dir,
   8.245 +				unsigned awaited)
   8.246 +{
   8.247 +	unsigned state, dummy;
   8.248 +	char **vec;
   8.249 +
   8.250 +	awaited |= 1 << XenbusStateUnknown;
   8.251 +
   8.252 +	for (;;) {
   8.253 +		state = xenfb_read_state(xsh, dir);
   8.254 +		if ((1 << state) & awaited)
   8.255 +			return state;
   8.256 +
   8.257 +		vec = xs_read_watch(xsh, &dummy);
   8.258 +		if (!vec)
   8.259 +			return -1;
   8.260 +		free(vec);
   8.261 +	}
   8.262 +}
   8.263 +
   8.264 +static int xenfb_wait_for_backend_creation(struct xenfb_device *dev)
   8.265 +{
   8.266 +	struct xs_handle *xsh = dev->xenfb->xsh;
   8.267 +	int state;
   8.268 +
   8.269 +	if (!xs_watch(xsh, dev->nodename, ""))
   8.270 +		return -1;
   8.271 +	state = xenfb_wait_for_state(xsh, dev->nodename,
   8.272 +			(1 << XenbusStateInitialising)
   8.273 +			| (1 << XenbusStateClosed)
   8.274 +#if 1 /* TODO fudging state to permit restarting; to be removed */
   8.275 +			| (1 << XenbusStateInitWait)
   8.276 +			| (1 << XenbusStateConnected)
   8.277 +			| (1 << XenbusStateClosing)
   8.278 +#endif
   8.279 +			);
   8.280 +	xs_unwatch(xsh, dev->nodename, "");
   8.281 +
   8.282 +	switch (state) {
   8.283 +#if 1
   8.284 +	case XenbusStateInitWait:
   8.285 +	case XenbusStateConnected:
   8.286 +		printf("Fudging state to %d\n", XenbusStateInitialising); /* FIXME */
   8.287 +#endif
   8.288 +	case XenbusStateInitialising:
   8.289 +	case XenbusStateClosing:
   8.290 +	case XenbusStateClosed:
   8.291 +		break;
   8.292 +	default:
   8.293 +		return -1;
   8.294 +	}
   8.295 +
   8.296 +	return 0;
   8.297 +}
   8.298 +
   8.299 +static int xenfb_hotplug(struct xenfb_device *dev)
   8.300 +{
   8.301 +	if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename,
   8.302 +			    "hotplug-status", "connected"))
   8.303 +		return -1;
   8.304 +	return 0;
   8.305 +}
   8.306 +
   8.307 +static int xenfb_wait_for_frontend_initialised(struct xenfb_device *dev)
   8.308 +{
   8.309 +	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
   8.310 +#if 1 /* TODO fudging state to permit restarting; to be removed */
   8.311 +			(1 << XenbusStateInitialised)
   8.312 +			| (1 << XenbusStateConnected)
   8.313 +#else
   8.314 +			1 << XenbusStateInitialised,
   8.315 +#endif
   8.316 +			)) {
   8.317 +#if 1
   8.318 +	case XenbusStateConnected:
   8.319 +		printf("Fudging state to %d\n", XenbusStateInitialised); /* FIXME */
   8.320 +#endif
   8.321 +	case XenbusStateInitialised:
   8.322 +		break;
   8.323 +	default:
   8.324 +		return -1;
   8.325 +	}
   8.326 +
   8.327 +	return 0;
   8.328 +}
   8.329 +
   8.330 +static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
   8.331 +{
   8.332 +	uint32_t *src32 = src;
   8.333 +	uint64_t *src64 = src;
   8.334 +	int i;
   8.335 +
   8.336 +	for (i = 0; i < count; i++)
   8.337 +		dst[i] = (mode == 32) ? src32[i] : src64[i];
   8.338 +}
   8.339 +
   8.340 +static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
   8.341 +{
   8.342 +	struct xenfb_page *page = xenfb->fb.page;
   8.343 +	int n_fbmfns;
   8.344 +	int n_fbdirs;
   8.345 +	unsigned long *pgmfns = NULL;
   8.346 +	unsigned long *fbmfns = NULL;
   8.347 +	void *map, *pd;
   8.348 +	int mode, ret = -1;
   8.349 +
   8.350 +	/* default to native */
   8.351 +	pd = page->pd;
   8.352 +	mode = sizeof(unsigned long) * 8;
   8.353 +
   8.354 +	if (0 == strlen(xenfb->protocol)) {
   8.355 +		/*
   8.356 +		 * Undefined protocol, some guesswork needed.
   8.357 +		 *
   8.358 +		 * Old frontends which don't set the protocol use
   8.359 +		 * one page directory only, thus pd[1] must be zero.
   8.360 +		 * pd[1] of the 32bit struct layout and the lower
   8.361 +		 * 32 bits of pd[0] of the 64bit struct layout have
   8.362 +		 * the same location, so we can check that ...
   8.363 +		 */
   8.364 +		uint32_t *ptr32 = NULL;
   8.365 +		uint32_t *ptr64 = NULL;
   8.366 +#if defined(__i386__)
   8.367 +		ptr32 = (void*)page->pd;
   8.368 +		ptr64 = ((void*)page->pd) + 4;
   8.369 +#elif defined(__x86_64__)
   8.370 +		ptr32 = ((void*)page->pd) - 4;
   8.371 +		ptr64 = (void*)page->pd;
   8.372 +#endif
   8.373 +		if (ptr32) {
   8.374 +			if (0 == ptr32[1]) {
   8.375 +				mode = 32;
   8.376 +				pd   = ptr32;
   8.377 +			} else {
   8.378 +				mode = 64;
   8.379 +				pd   = ptr64;
   8.380 +			}
   8.381 +		}
   8.382 +#if defined(__x86_64__)
   8.383 +	} else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) {
   8.384 +		/* 64bit dom0, 32bit domU */
   8.385 +		mode = 32;
   8.386 +		pd   = ((void*)page->pd) - 4;
   8.387 +#elif defined(__i386__)
   8.388 +	} else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) {
   8.389 +		/* 32bit dom0, 64bit domU */
   8.390 +		mode = 64;
   8.391 +		pd   = ((void*)page->pd) + 4;
   8.392 +#endif
   8.393 +	}
   8.394 +
   8.395 +	n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
   8.396 +	n_fbdirs = n_fbmfns * mode / 8;
   8.397 +	n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
   8.398 +
   8.399 +	pgmfns = malloc(sizeof(unsigned long) * n_fbdirs);
   8.400 +	fbmfns = malloc(sizeof(unsigned long) * n_fbmfns);
   8.401 +	if (!pgmfns || !fbmfns)
   8.402 +		goto out;
   8.403 +
   8.404 +	xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
   8.405 +	map = xc_map_foreign_pages(xenfb->xc, domid,
   8.406 +				   PROT_READ, pgmfns, n_fbdirs);
   8.407 +	if (map == NULL)
   8.408 +		goto out;
   8.409 +	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
   8.410 +	munmap(map, n_fbdirs * XC_PAGE_SIZE);
   8.411 +
   8.412 +	xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
   8.413 +				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
   8.414 +	if (xenfb->pub.pixels == NULL)
   8.415 +		goto out;
   8.416 +
   8.417 +	ret = 0; /* all is fine */
   8.418 +
   8.419 + out:
   8.420 +	if (pgmfns)
   8.421 +		free(pgmfns);
   8.422 +	if (fbmfns)
   8.423 +		free(fbmfns);
   8.424 +	return ret;
   8.425 +}
   8.426 +
   8.427 +static int xenfb_bind(struct xenfb_device *dev)
   8.428 +{
   8.429 +	struct xenfb_private *xenfb = dev->xenfb;
   8.430 +	unsigned long mfn;
   8.431 +	evtchn_port_t evtchn;
   8.432 +
   8.433 +	if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu",
   8.434 +			    &mfn) < 0)
   8.435 +		return -1;
   8.436 +	if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u",
   8.437 +			    &evtchn) < 0)
   8.438 +		return -1;
   8.439 +
   8.440 +	dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch,
   8.441 +					       dev->otherend_id, evtchn);
   8.442 +	if (dev->port == -1)
   8.443 +		return -1;
   8.444 +
   8.445 +	dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id,
   8.446 +			XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
   8.447 +	if (dev->page == NULL)
   8.448 +		return -1;
   8.449 +
   8.450 +	return 0;
   8.451 +}
   8.452 +
   8.453 +static void xenfb_unbind(struct xenfb_device *dev)
   8.454 +{
   8.455 +	if (dev->page) {
   8.456 +		munmap(dev->page, XC_PAGE_SIZE);
   8.457 +		dev->page = NULL;
   8.458 +	}
   8.459 +        if (dev->port >= 0) {
   8.460 +		xc_evtchn_unbind(dev->xenfb->evt_xch, dev->port);
   8.461 +		dev->port = -1;
   8.462 +	}
   8.463 +}
   8.464 +
   8.465 +static int xenfb_wait_for_frontend_connected(struct xenfb_device *dev)
   8.466 +{
   8.467 +	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
   8.468 +				     1 << XenbusStateConnected)) {
   8.469 +	case XenbusStateConnected:
   8.470 +		break;
   8.471 +	default:
   8.472 +		return -1;
   8.473 +	}
   8.474 +
   8.475 +	return 0;
   8.476 +}
   8.477 +
   8.478 +static void xenfb_dev_fatal(struct xenfb_device *dev, int err,
   8.479 +			    const char *fmt, ...)
   8.480 +{
   8.481 +	struct xs_handle *xsh = dev->xenfb->xsh;
   8.482 +	va_list ap;
   8.483 +	char errdir[80];
   8.484 +	char buf[1024];
   8.485 +	int n;
   8.486 +
   8.487 +	fprintf(stderr, "%s ", dev->nodename); /* somewhat crude */
   8.488 +	va_start(ap, fmt);
   8.489 +	vfprintf(stderr, fmt, ap);
   8.490 +	va_end(ap);
   8.491 +	if (err)
   8.492 +		fprintf(stderr, " (%s)", strerror(err));
   8.493 +	putc('\n', stderr);
   8.494 +
   8.495 +	if (!xenfb_path_in_dom(xsh, errdir, sizeof(errdir), 0,
   8.496 +			       "error/%s", dev->nodename))
   8.497 +		goto out;	/* FIXME complain */
   8.498 +
   8.499 +	va_start(ap, fmt);
   8.500 +	n = snprintf(buf, sizeof(buf), "%d ", err);
   8.501 +	snprintf(buf + n, sizeof(buf) - n, fmt, ap);
   8.502 +	va_end(ap);
   8.503 +
   8.504 +	if (xenfb_xs_printf(xsh, buf, "error", "%s", buf) < 0)
   8.505 +		goto out;	/* FIXME complain */
   8.506 +
   8.507 + out:
   8.508 +	xenfb_switch_state(dev, XenbusStateClosing);
   8.509 +}
   8.510 +
   8.511 +int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
   8.512 +{
   8.513 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.514 +	struct xs_handle *xsh = xenfb->xsh;
   8.515 +	int val, serrno;
   8.516 +	struct xenfb_page *fb_page;
   8.517 +
   8.518 +	xenfb_detach_dom(xenfb);
   8.519 +
   8.520 +	xenfb_device_set_domain(&xenfb->fb, domid);
   8.521 +	xenfb_device_set_domain(&xenfb->kbd, domid);
   8.522 +
   8.523 +	if (xenfb_wait_for_backend_creation(&xenfb->fb) < 0)
   8.524 +		goto error;
   8.525 +	if (xenfb_wait_for_backend_creation(&xenfb->kbd) < 0)
   8.526 +		goto error;
   8.527 +
   8.528 +	if (xenfb_xs_printf(xsh, xenfb->kbd.nodename, "feature-abs-pointer", "1"))
   8.529 +		goto error;
   8.530 +	if (xenfb_switch_state(&xenfb->fb, XenbusStateInitWait))
   8.531 +		goto error;
   8.532 +	if (xenfb_switch_state(&xenfb->kbd, XenbusStateInitWait))
   8.533 +		goto error;
   8.534 +
   8.535 +	if (xenfb_hotplug(&xenfb->fb) < 0)
   8.536 +		goto error;
   8.537 +	if (xenfb_hotplug(&xenfb->kbd) < 0)
   8.538 +		goto error;
   8.539 +
   8.540 +	if (!xs_watch(xsh, xenfb->fb.otherend, ""))
   8.541 +		goto error;
   8.542 +	if (!xs_watch(xsh, xenfb->kbd.otherend, ""))
   8.543 +		goto error;
   8.544 +
   8.545 +	if (xenfb_wait_for_frontend_initialised(&xenfb->fb) < 0)
   8.546 +		goto error;
   8.547 +	if (xenfb_wait_for_frontend_initialised(&xenfb->kbd) < 0)
   8.548 +		goto error;
   8.549 +
   8.550 +	if (xenfb_bind(&xenfb->fb) < 0)
   8.551 +		goto error;
   8.552 +	if (xenfb_bind(&xenfb->kbd) < 0)
   8.553 +		goto error;
   8.554 +
   8.555 +	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "feature-update",
   8.556 +			    "%d", &val) < 0)
   8.557 +		val = 0;
   8.558 +	if (!val) {
   8.559 +		errno = ENOTSUP;
   8.560 +		goto error;
   8.561 +	}
   8.562 +	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
   8.563 +			    xenfb->protocol) < 0)
   8.564 +		xenfb->protocol[0] = '\0';
   8.565 +	xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
   8.566 +
   8.567 +	/* TODO check for permitted ranges */
   8.568 +	fb_page = xenfb->fb.page;
   8.569 +	xenfb->pub.depth = fb_page->depth;
   8.570 +	xenfb->pub.width = fb_page->width;
   8.571 +	xenfb->pub.height = fb_page->height;
   8.572 +	/* TODO check for consistency with the above */
   8.573 +	xenfb->fb_len = fb_page->mem_length;
   8.574 +	xenfb->pub.row_stride = fb_page->line_length;
   8.575 +
   8.576 +	if (xenfb_map_fb(xenfb, domid) < 0)
   8.577 +		goto error;
   8.578 +
   8.579 +	if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
   8.580 +		goto error;
   8.581 +	if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
   8.582 +		goto error;
   8.583 +
   8.584 +	if (xenfb_wait_for_frontend_connected(&xenfb->kbd) < 0)
   8.585 +		goto error;
   8.586 +	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
   8.587 +			    "%d", &val) < 0)
   8.588 +		val = 0;
   8.589 +	xenfb->pub.abs_pointer_wanted = val;
   8.590 +
   8.591 +	return 0;
   8.592 +
   8.593 + error:
   8.594 +	serrno = errno;
   8.595 +	xenfb_detach_dom(xenfb);
   8.596 +	xenfb_dev_fatal(&xenfb->fb, serrno, "on fire");
   8.597 +	xenfb_dev_fatal(&xenfb->kbd, serrno, "on fire");
   8.598 +        errno = serrno;
   8.599 +        return -1;
   8.600 +}
   8.601 +
   8.602 +static void xenfb_detach_dom(struct xenfb_private *xenfb)
   8.603 +{
   8.604 +	xenfb_unbind(&xenfb->fb);
   8.605 +	xenfb_unbind(&xenfb->kbd);
   8.606 +	if (xenfb->pub.pixels) {
   8.607 +		munmap(xenfb->pub.pixels, xenfb->fb_len);
   8.608 +		xenfb->pub.pixels = NULL;
   8.609 +	}
   8.610 +}
   8.611 +
   8.612 +static void xenfb_on_fb_event(struct xenfb_private *xenfb)
   8.613 +{
   8.614 +	uint32_t prod, cons;
   8.615 +	struct xenfb_page *page = xenfb->fb.page;
   8.616 +
   8.617 +	prod = page->out_prod;
   8.618 +	if (prod == page->out_cons)
   8.619 +		return;
   8.620 +	rmb();			/* ensure we see ring contents up to prod */
   8.621 +	for (cons = page->out_cons; cons != prod; cons++) {
   8.622 +		union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
   8.623 +
   8.624 +		switch (event->type) {
   8.625 +		case XENFB_TYPE_UPDATE:
   8.626 +                    if (xenfb->pub.update)
   8.627 +			xenfb->pub.update(&xenfb->pub,
   8.628 +					  event->update.x, event->update.y,
   8.629 +					  event->update.width, event->update.height);
   8.630 +                    break;
   8.631 +		}
   8.632 +	}
   8.633 +	mb();			/* ensure we're done with ring contents */
   8.634 +	page->out_cons = cons;
   8.635 +	xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
   8.636 +}
   8.637 +
   8.638 +static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
   8.639 +{
   8.640 +	struct xenkbd_page *page = xenfb->kbd.page;
   8.641 +
   8.642 +	/* We don't understand any keyboard events, so just ignore them. */
   8.643 +	if (page->out_prod == page->out_cons)
   8.644 +		return;
   8.645 +	page->out_cons = page->out_prod;
   8.646 +	xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
   8.647 +}
   8.648 +
   8.649 +static int xenfb_on_state_change(struct xenfb_device *dev)
   8.650 +{
   8.651 +	enum xenbus_state state;
   8.652 +
   8.653 +	state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
   8.654 +
   8.655 +	switch (state) {
   8.656 +	case XenbusStateUnknown:
   8.657 +		/* There was an error reading the frontend state.  The
   8.658 +		   domain has probably gone away; in any case, there's
   8.659 +		   not much point in us continuing. */
   8.660 +		return -1;
   8.661 +	case XenbusStateInitialising:
   8.662 +	case XenbusStateInitWait:
   8.663 +	case XenbusStateInitialised:
   8.664 +	case XenbusStateConnected:
   8.665 +		break;
   8.666 +	case XenbusStateClosing:
   8.667 +		xenfb_unbind(dev);
   8.668 +		xenfb_switch_state(dev, state);
   8.669 +		break;
   8.670 +	case XenbusStateClosed:
   8.671 +		xenfb_switch_state(dev, state);
   8.672 +	}
   8.673 +	return 0;
   8.674 +}
   8.675 +
   8.676 +int xenfb_dispatch_channel(struct xenfb *xenfb_pub)
   8.677 +{
   8.678 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.679 +	evtchn_port_t port;
   8.680 +	port = xc_evtchn_pending(xenfb->evt_xch);
   8.681 +	if (port == -1)
   8.682 +		return -1;
   8.683 +
   8.684 +	if (port == xenfb->fb.port)
   8.685 +		xenfb_on_fb_event(xenfb);
   8.686 +	else if (port == xenfb->kbd.port)
   8.687 +		xenfb_on_kbd_event(xenfb);
   8.688 +
   8.689 +	if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
   8.690 +		return -1;
   8.691 +
   8.692 +	return 0;
   8.693 +}
   8.694 +
   8.695 +int xenfb_dispatch_store(struct xenfb *xenfb_pub)
   8.696 +{
   8.697 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.698 +	unsigned dummy;
   8.699 +	char **vec;
   8.700 +	int r;
   8.701 +
   8.702 +	vec = xs_read_watch(xenfb->xsh, &dummy);
   8.703 +	free(vec);
   8.704 +	r = xenfb_on_state_change(&xenfb->fb);
   8.705 +	if (r == 0)
   8.706 +		r = xenfb_on_state_change(&xenfb->kbd);
   8.707 +	if (r == -1)
   8.708 +		return -2;
   8.709 +
   8.710 +	return 0;
   8.711 +}
   8.712 +
   8.713 +
   8.714 +/* Returns 0 normally, -1 on error, or -2 if the domain went away. */
   8.715 +int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
   8.716 +{
   8.717 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.718 +	int ret;
   8.719 +
   8.720 +	if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
   8.721 +		if ((ret = xenfb_dispatch_channel(xenfb_pub)) < 0)
   8.722 +			return ret;
   8.723 +	}
   8.724 +
   8.725 +	if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) {
   8.726 +		if ((ret = xenfb_dispatch_store(xenfb_pub)) < 0)
   8.727 +			return ret;
   8.728 +	}
   8.729 +
   8.730 +	return 0;
   8.731 +}
   8.732 +
   8.733 +int xenfb_select_fds(struct xenfb *xenfb_pub, fd_set *readfds)
   8.734 +{
   8.735 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.736 +	int fd1 = xc_evtchn_fd(xenfb->evt_xch);
   8.737 +	int fd2 = xs_fileno(xenfb->xsh);
   8.738 +
   8.739 +	FD_SET(fd1, readfds);
   8.740 +	FD_SET(fd2, readfds);
   8.741 +	return fd1 > fd2 ? fd1 + 1 : fd2 + 1;
   8.742 +}
   8.743 +
   8.744 +int xenfb_get_store_fd(struct xenfb *xenfb_pub)
   8.745 +{
   8.746 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.747 +	return xs_fileno(xenfb->xsh);
   8.748 +}
   8.749 +
   8.750 +int xenfb_get_channel_fd(struct xenfb *xenfb_pub)
   8.751 +{
   8.752 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.753 +	return xc_evtchn_fd(xenfb->evt_xch);
   8.754 +}
   8.755 +
   8.756 +static int xenfb_kbd_event(struct xenfb_private *xenfb,
   8.757 +			   union xenkbd_in_event *event)
   8.758 +{
   8.759 +	uint32_t prod;
   8.760 +	struct xenkbd_page *page = xenfb->kbd.page;
   8.761 +
   8.762 +	if (xenfb->kbd.state != XenbusStateConnected)
   8.763 +		return 0;
   8.764 +
   8.765 +	prod = page->in_prod;
   8.766 +	if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
   8.767 +		errno = EAGAIN;
   8.768 +		return -1;
   8.769 +	}
   8.770 +
   8.771 +	mb();			/* ensure ring space available */
   8.772 +	XENKBD_IN_RING_REF(page, prod) = *event;
   8.773 +	wmb();			/* ensure ring contents visible */
   8.774 +	page->in_prod = prod + 1;
   8.775 +	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
   8.776 +}
   8.777 +
   8.778 +int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
   8.779 +{
   8.780 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.781 +	union xenkbd_in_event event;
   8.782 +
   8.783 +	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
   8.784 +	event.type = XENKBD_TYPE_KEY;
   8.785 +	event.key.pressed = down ? 1 : 0;
   8.786 +	event.key.keycode = keycode;
   8.787 +
   8.788 +	return xenfb_kbd_event(xenfb, &event);
   8.789 +}
   8.790 +
   8.791 +int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
   8.792 +{
   8.793 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.794 +	union xenkbd_in_event event;
   8.795 +
   8.796 +	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
   8.797 +	event.type = XENKBD_TYPE_MOTION;
   8.798 +	event.motion.rel_x = rel_x;
   8.799 +	event.motion.rel_y = rel_y;
   8.800 +
   8.801 +	return xenfb_kbd_event(xenfb, &event);
   8.802 +}
   8.803 +
   8.804 +int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
   8.805 +{
   8.806 +	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   8.807 +	union xenkbd_in_event event;
   8.808 +
   8.809 +	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
   8.810 +	event.type = XENKBD_TYPE_POS;
   8.811 +	event.pos.abs_x = abs_x;
   8.812 +	event.pos.abs_y = abs_y;
   8.813 +
   8.814 +	return xenfb_kbd_event(xenfb, &event);
   8.815 +}
   8.816 +/*
   8.817 + * Local variables:
   8.818 + *  c-indent-level: 8
   8.819 + *  c-basic-offset: 8
   8.820 + *  tab-width: 8
   8.821 + * End:
   8.822 + */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/ioemu/hw/xenfb.h	Thu Oct 25 14:37:23 2007 +0100
     9.3 @@ -0,0 +1,39 @@
     9.4 +#ifndef _XENFB_H_
     9.5 +#define _XENFB_H_
     9.6 +
     9.7 +#include <stdbool.h>
     9.8 +#include <sys/types.h>
     9.9 +
    9.10 +struct xenfb
    9.11 +{
    9.12 +	void *pixels;
    9.13 +
    9.14 +	int row_stride;
    9.15 +	int depth;
    9.16 +	int width;
    9.17 +	int height;
    9.18 +	int abs_pointer_wanted;
    9.19 +
    9.20 +	void *user_data;
    9.21 +
    9.22 +	void (*update)(struct xenfb *xenfb, int x, int y, int width, int height);
    9.23 +};
    9.24 +
    9.25 +struct xenfb *xenfb_new(void);
    9.26 +void xenfb_delete(struct xenfb *xenfb);
    9.27 +void xenfb_teardown(struct xenfb *xenfb);
    9.28 +
    9.29 +int xenfb_attach_dom(struct xenfb *xenfb, int domid);
    9.30 +
    9.31 +int xenfb_dispatch_store(struct xenfb *xenfb_pub);
    9.32 +int xenfb_dispatch_channel(struct xenfb *xenfb_pub);
    9.33 +int xenfb_select_fds(struct xenfb *xenfb, fd_set *readfds);
    9.34 +int xenfb_poll(struct xenfb *xenfb, fd_set *readfds);
    9.35 +int xenfb_get_store_fd(struct xenfb *xenfb_pub);
    9.36 +int xenfb_get_channel_fd(struct xenfb *xenfb_pub);
    9.37 +
    9.38 +int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode);
    9.39 +int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y);
    9.40 +int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);
    9.41 +
    9.42 +#endif
    10.1 --- a/tools/xenfb/Makefile	Thu Oct 25 14:35:04 2007 +0100
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,32 +0,0 @@
    10.4 -XEN_ROOT=../..
    10.5 -include $(XEN_ROOT)/tools/Rules.mk
    10.6 -
    10.7 -CFLAGS  += -I$(XEN_LIBXC) -I$(XEN_XENSTORE)
    10.8 -CFLAGS  += -I$(XEN_ROOT)/tools/ioemu
    10.9 -LDFLAGS += -L$(XEN_LIBXC) -L$(XEN_XENSTORE)
   10.10 -
   10.11 -.PHONY: all
   10.12 -all: build
   10.13 -
   10.14 -.PHONY: build
   10.15 -build:
   10.16 -	$(MAKE) vncfb sdlfb
   10.17 -
   10.18 -install: all
   10.19 -	$(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
   10.20 -	$(INSTALL_PROG) vncfb $(DESTDIR)/usr/$(LIBDIR)/xen/bin/xen-vncfb
   10.21 -	$(INSTALL_PROG) sdlfb $(DESTDIR)/usr/$(LIBDIR)/xen/bin/xen-sdlfb
   10.22 -
   10.23 -sdlfb: sdlfb.o xenfb.o
   10.24 -
   10.25 -sdlfb.o: CFLAGS += $(shell sdl-config --cflags)
   10.26 -sdlfb: LDLIBS += $(shell sdl-config --libs) -lxenctrl -lxenstore
   10.27 -
   10.28 -clean:
   10.29 -	$(RM) *.o *~ vncfb sdlfb
   10.30 -
   10.31 -vncfb: vncfb.o xenfb.o
   10.32 -vncfb.o: CFLAGS += $(shell libvncserver-config --cflags)
   10.33 -vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl -lxenstore
   10.34 -
   10.35 -sdlfb.o xenfb.o vncfb.o: xenfb.h
    11.1 --- a/tools/xenfb/sdlfb.c	Thu Oct 25 14:35:04 2007 +0100
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,342 +0,0 @@
    11.4 -#include <SDL.h>
    11.5 -#include <errno.h>
    11.6 -#include <sys/types.h>
    11.7 -#include <sys/select.h>
    11.8 -#include <stdlib.h>
    11.9 -#include <linux/input.h>
   11.10 -#include <getopt.h>
   11.11 -#include <string.h>
   11.12 -#include "xenfb.h"
   11.13 -
   11.14 -struct SDLFBData
   11.15 -{
   11.16 -	SDL_Surface *dst;
   11.17 -	SDL_Surface *src;
   11.18 -};
   11.19 -
   11.20 -/*
   11.21 - * Map from scancode to Linux input layer keycode.  Scancodes are
   11.22 - * hardware-specific.  This map assumes a standard AT or PS/2
   11.23 - * keyboard.
   11.24 - *
   11.25 - * Why use scancodes?  We can't use key symbols, because they don't
   11.26 - * identify keys --- they're what keys are mapped to.  The standard
   11.27 - * German keymap, for instance, maps both KEY_COMMA and KEY_102ND to
   11.28 - * SDLK_LESS.
   11.29 - */
   11.30 -static int keymap[256] = {
   11.31 -	[9] = KEY_ESC,
   11.32 -	[10] = KEY_1,
   11.33 -	[11] = KEY_2,
   11.34 -	[12] = KEY_3,
   11.35 -	[13] = KEY_4,
   11.36 -	[14] = KEY_5,
   11.37 -	[15] = KEY_6,
   11.38 -	[16] = KEY_7,
   11.39 -	[17] = KEY_8,
   11.40 -	[18] = KEY_9,
   11.41 -	[19] = KEY_0,
   11.42 -	[20] = KEY_MINUS,
   11.43 -	[21] = KEY_EQUAL,
   11.44 -	[22] = KEY_BACKSPACE,
   11.45 -	[23] = KEY_TAB,
   11.46 -	[24] = KEY_Q,
   11.47 -	[25] = KEY_W,
   11.48 -	[26] = KEY_E,
   11.49 -	[27] = KEY_R,
   11.50 -	[28] = KEY_T,
   11.51 -	[29] = KEY_Y,
   11.52 -	[30] = KEY_U,
   11.53 -	[31] = KEY_I,
   11.54 -	[32] = KEY_O,
   11.55 -	[33] = KEY_P,
   11.56 -	[34] = KEY_LEFTBRACE,
   11.57 -	[35] = KEY_RIGHTBRACE,
   11.58 -	[36] = KEY_ENTER,
   11.59 -	[37] = KEY_LEFTCTRL,
   11.60 -	[38] = KEY_A,
   11.61 -	[39] = KEY_S,
   11.62 -	[40] = KEY_D,
   11.63 -	[41] = KEY_F,
   11.64 -	[42] = KEY_G,
   11.65 -	[43] = KEY_H,
   11.66 -	[44] = KEY_J,
   11.67 -	[45] = KEY_K,
   11.68 -	[46] = KEY_L,
   11.69 -	[47] = KEY_SEMICOLON,
   11.70 -	[48] = KEY_APOSTROPHE,
   11.71 -	[49] = KEY_GRAVE,
   11.72 -	[50] = KEY_LEFTSHIFT,
   11.73 -	[51] = KEY_BACKSLASH,
   11.74 -	[52] = KEY_Z,
   11.75 -	[53] = KEY_X,
   11.76 -	[54] = KEY_C,
   11.77 -	[55] = KEY_V,
   11.78 -	[56] = KEY_B,
   11.79 -	[57] = KEY_N,
   11.80 -	[58] = KEY_M,
   11.81 -	[59] = KEY_COMMA,
   11.82 -	[60] = KEY_DOT,
   11.83 -	[61] = KEY_SLASH,
   11.84 -	[62] = KEY_RIGHTSHIFT,
   11.85 -	[63] = KEY_KPASTERISK,
   11.86 -	[64] = KEY_LEFTALT,
   11.87 -	[65] = KEY_SPACE,
   11.88 -	[66] = KEY_CAPSLOCK,
   11.89 -	[67] = KEY_F1,
   11.90 -	[68] = KEY_F2,
   11.91 -	[69] = KEY_F3,
   11.92 -	[70] = KEY_F4,
   11.93 -	[71] = KEY_F5,
   11.94 -	[72] = KEY_F6,
   11.95 -	[73] = KEY_F7,
   11.96 -	[74] = KEY_F8,
   11.97 -	[75] = KEY_F9,
   11.98 -	[76] = KEY_F10,
   11.99 -	[77] = KEY_NUMLOCK,
  11.100 -	[78] = KEY_SCROLLLOCK,
  11.101 -	[79] = KEY_KP7,
  11.102 -	[80] = KEY_KP8,
  11.103 -	[81] = KEY_KP9,
  11.104 -	[82] = KEY_KPMINUS,
  11.105 -	[83] = KEY_KP4,
  11.106 -	[84] = KEY_KP5,
  11.107 -	[85] = KEY_KP6,
  11.108 -	[86] = KEY_KPPLUS,
  11.109 -	[87] = KEY_KP1,
  11.110 -	[88] = KEY_KP2,
  11.111 -	[89] = KEY_KP3,
  11.112 -	[90] = KEY_KP0,
  11.113 -	[91] = KEY_KPDOT,
  11.114 -	[94] = KEY_102ND,	/* FIXME is this correct? */
  11.115 -	[95] = KEY_F11,
  11.116 -	[96] = KEY_F12,
  11.117 -	[108] = KEY_KPENTER,
  11.118 -	[109] = KEY_RIGHTCTRL,
  11.119 -	[112] = KEY_KPSLASH,
  11.120 -	[111] = KEY_SYSRQ,
  11.121 -	[113] = KEY_RIGHTALT,
  11.122 -	[97] = KEY_HOME,
  11.123 -	[98] = KEY_UP,
  11.124 -	[99] = KEY_PAGEUP,
  11.125 -	[100] = KEY_LEFT,
  11.126 -	[102] = KEY_RIGHT,
  11.127 -	[103] = KEY_END,
  11.128 -	[104] = KEY_DOWN,
  11.129 -	[105] = KEY_PAGEDOWN,
  11.130 -	[106] = KEY_INSERT,
  11.131 -	[107] = KEY_DELETE,
  11.132 -	[110] = KEY_PAUSE,
  11.133 -	[115] = KEY_LEFTMETA,
  11.134 -	[116] = KEY_RIGHTMETA,
  11.135 -	[117] = KEY_MENU,
  11.136 -};
  11.137 -
  11.138 -static int btnmap[] = {
  11.139 -	[SDL_BUTTON_LEFT] = BTN_LEFT,
  11.140 -	[SDL_BUTTON_MIDDLE] = BTN_MIDDLE,
  11.141 -	[SDL_BUTTON_RIGHT] = BTN_RIGHT,
  11.142 -	/* FIXME not 100% sure about these: */
  11.143 -	[SDL_BUTTON_WHEELUP] = BTN_FORWARD,
  11.144 -	[SDL_BUTTON_WHEELDOWN] BTN_BACK
  11.145 -};
  11.146 -
  11.147 -static void sdl_update(struct xenfb *xenfb, int x, int y, int width, int height)
  11.148 -{
  11.149 -	struct SDLFBData *data = xenfb->user_data;
  11.150 -	SDL_Rect r = { x, y, width, height };
  11.151 -	SDL_BlitSurface(data->src, &r, data->dst, &r);
  11.152 -	SDL_UpdateRect(data->dst, x, y, width, height);
  11.153 -}
  11.154 -
  11.155 -static int sdl_on_event(struct xenfb *xenfb, SDL_Event *event)
  11.156 -{
  11.157 -	int x, y, ret;
  11.158 -
  11.159 -	switch (event->type) {
  11.160 -	case SDL_KEYDOWN:
  11.161 -	case SDL_KEYUP:
  11.162 -		if (keymap[event->key.keysym.scancode] == 0)
  11.163 -			break;
  11.164 -		ret = xenfb_send_key(xenfb,
  11.165 -				     event->type == SDL_KEYDOWN,
  11.166 -				     keymap[event->key.keysym.scancode]);
  11.167 -		if (ret < 0)
  11.168 -			fprintf(stderr, "Key %d %s lost (%s)\n",
  11.169 -				keymap[event->key.keysym.scancode],
  11.170 -				event->type == SDL_KEYDOWN ? "down" : "up",
  11.171 -				strerror(errno));
  11.172 -		break;
  11.173 -	case SDL_MOUSEMOTION:
  11.174 -		if (xenfb->abs_pointer_wanted) {
  11.175 -			SDL_GetMouseState(&x, &y);
  11.176 -			ret = xenfb_send_position(xenfb, x, y);
  11.177 -		} else {
  11.178 -			SDL_GetRelativeMouseState(&x, &y);
  11.179 -			ret = xenfb_send_motion(xenfb, x, y);
  11.180 -		}
  11.181 -		if (ret < 0)
  11.182 -			fprintf(stderr, "Pointer to %d,%d lost (%s)\n",
  11.183 -				x, y, strerror(errno));
  11.184 -		break;
  11.185 -	case SDL_MOUSEBUTTONDOWN:
  11.186 -	case SDL_MOUSEBUTTONUP:
  11.187 -		if (event->button.button >= sizeof(btnmap) / sizeof(*btnmap))
  11.188 -			break;
  11.189 -		if (btnmap[event->button.button] == 0)
  11.190 -			break;
  11.191 -		ret = xenfb_send_key(xenfb,
  11.192 -				     event->type == SDL_MOUSEBUTTONDOWN,
  11.193 -				     btnmap[event->button.button]);
  11.194 -		if (ret < 0)
  11.195 -			fprintf(stderr, "Button %d %s lost (%s)\n",
  11.196 -				btnmap[event->button.button] - BTN_MOUSE,
  11.197 -				event->type == SDL_MOUSEBUTTONDOWN ? "down" : "up",
  11.198 -				strerror(errno));
  11.199 -		break;
  11.200 -	case SDL_QUIT:
  11.201 -		return 0;
  11.202 -	}
  11.203 -
  11.204 -	return 1;
  11.205 -}
  11.206 -
  11.207 -static struct option options[] = {
  11.208 -	{ "domid", 1, NULL, 'd' },
  11.209 -	{ "title", 1, NULL, 't' },
  11.210 -	{ NULL }
  11.211 -};
  11.212 -
  11.213 -int main(int argc, char **argv)
  11.214 -{
  11.215 -	struct xenfb *xenfb;
  11.216 -	int domid = -1;
  11.217 -        char * title = NULL;
  11.218 -	fd_set readfds;
  11.219 -	int nfds;
  11.220 -	struct SDLFBData data;
  11.221 -	SDL_Rect r;
  11.222 -	struct timeval tv;
  11.223 -	SDL_Event event;
  11.224 -	int do_quit = 0;
  11.225 -	int opt;
  11.226 -	char *endp;
  11.227 -	int retval;
  11.228 -
  11.229 -	while ((opt = getopt_long(argc, argv, "d:t:", options,
  11.230 -				  NULL)) != -1) {
  11.231 -		switch (opt) {
  11.232 -                case 'd':
  11.233 -			domid = strtol(optarg, &endp, 10);
  11.234 -			if (endp == optarg || *endp) {
  11.235 -				fprintf(stderr, "Invalid domain id specified\n");
  11.236 -				exit(1);
  11.237 -			}
  11.238 -			break;
  11.239 -                case 't':
  11.240 -			title = strdup(optarg);
  11.241 -			break;
  11.242 -		case '?':
  11.243 -			exit(1);
  11.244 -                }
  11.245 -        }
  11.246 -        if (optind != argc) {
  11.247 -		fprintf(stderr, "Invalid options!\n");
  11.248 -		exit(1);
  11.249 -        }
  11.250 -        if (domid <= 0) {
  11.251 -		fprintf(stderr, "Domain ID must be specified!\n");
  11.252 -		exit(1);
  11.253 -        }
  11.254 -
  11.255 -	xenfb = xenfb_new();
  11.256 -	if (xenfb == NULL) {
  11.257 -		fprintf(stderr, "Could not create framebuffer (%s)\n",
  11.258 -			strerror(errno));
  11.259 -		exit(1);
  11.260 -        }
  11.261 -
  11.262 -	if (xenfb_attach_dom(xenfb, domid) < 0) {
  11.263 -		fprintf(stderr, "Could not connect to domain (%s)\n",
  11.264 -			strerror(errno));
  11.265 -		exit(1);
  11.266 -        }
  11.267 -
  11.268 -	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
  11.269 -		fprintf(stderr, "Could not initialize SDL\n");
  11.270 -		exit(1);
  11.271 -	}
  11.272 -
  11.273 -	data.dst = SDL_SetVideoMode(xenfb->width, xenfb->height, xenfb->depth,
  11.274 -				    SDL_SWSURFACE);
  11.275 -	if (!data.dst) {
  11.276 -		fprintf(stderr, "SDL_SetVideoMode failed\n");
  11.277 -		exit(1);
  11.278 -	}
  11.279 -
  11.280 -	data.src = SDL_CreateRGBSurfaceFrom(xenfb->pixels,
  11.281 -					    xenfb->width, xenfb->height,
  11.282 -					    xenfb->depth, xenfb->row_stride,
  11.283 -					    0xFF0000, 0xFF00, 0xFF, 0);
  11.284 -
  11.285 -	if (!data.src) {
  11.286 -		fprintf(stderr, "SDL_CreateRGBSurfaceFrom failed\n");
  11.287 -		exit(1);
  11.288 -	}
  11.289 -
  11.290 -        if (title == NULL)
  11.291 -		title = strdup("xen-sdlfb");
  11.292 -        SDL_WM_SetCaption(title, title);
  11.293 -
  11.294 -	r.x = r.y = 0;
  11.295 -	r.w = xenfb->width;
  11.296 -	r.h = xenfb->height;
  11.297 -	SDL_BlitSurface(data.src, &r, data.dst, &r);
  11.298 -	SDL_UpdateRect(data.dst, 0, 0, xenfb->width, xenfb->height);
  11.299 -
  11.300 -	xenfb->update = sdl_update;
  11.301 -	xenfb->user_data = &data;
  11.302 -
  11.303 -	SDL_ShowCursor(0);
  11.304 -
  11.305 -	/*
  11.306 -	 * We need to wait for fds becoming ready or SDL events to
  11.307 -	 * arrive.  We time out the select after 10ms to poll for SDL
  11.308 -	 * events.  Clunky, but works.  Could avoid the clunkiness
  11.309 -	 * with a separate thread.
  11.310 -	 */
  11.311 -	for (;;) {
  11.312 -		FD_ZERO(&readfds);
  11.313 -		nfds = xenfb_select_fds(xenfb, &readfds);
  11.314 -		tv = (struct timeval){0, 10000};
  11.315 -
  11.316 -		if (select(nfds, &readfds, NULL, NULL, &tv) < 0) {
  11.317 -			if (errno == EINTR)
  11.318 -				continue;
  11.319 -			fprintf(stderr,
  11.320 -				"Can't select() on event channel (%s)\n",
  11.321 -				strerror(errno));
  11.322 -			break;
  11.323 -		}
  11.324 -
  11.325 -		while (SDL_PollEvent(&event)) {
  11.326 -			if (!sdl_on_event(xenfb, &event))
  11.327 -				do_quit = 1;
  11.328 -		}
  11.329 -
  11.330 -                if (do_quit)
  11.331 -			break;
  11.332 -
  11.333 -		retval = xenfb_poll(xenfb, &readfds);
  11.334 -		if (retval == -2)
  11.335 -		    xenfb_teardown(xenfb);
  11.336 -		if (retval < 0)
  11.337 -		    break;
  11.338 -	}
  11.339 -
  11.340 -	xenfb_delete(xenfb);
  11.341 -
  11.342 -	SDL_Quit();
  11.343 -
  11.344 -	return 0;
  11.345 -}
    12.1 --- a/tools/xenfb/vncfb.c	Thu Oct 25 14:35:04 2007 +0100
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,522 +0,0 @@
    12.4 -#define _GNU_SOURCE
    12.5 -#include <errno.h>
    12.6 -#include <getopt.h>
    12.7 -#include <stdlib.h>
    12.8 -#include <signal.h>
    12.9 -#include <unistd.h>
   12.10 -#include <malloc.h>
   12.11 -#include <rfb/rfb.h>
   12.12 -#include <rfb/keysym.h>
   12.13 -#include <linux/input.h>
   12.14 -#include <xs.h>
   12.15 -#include "xenfb.h"
   12.16 -
   12.17 -/* Grab key translation support routines from qemu directory. */
   12.18 -#define qemu_mallocz(size) calloc(1, (size))
   12.19 -static const char *bios_dir = "/usr/share/xen/qemu";
   12.20 -#include "vnc_keysym.h"
   12.21 -#include "keymaps.c"
   12.22 -
   12.23 -static unsigned char atkbd_set2_keycode[512] = {
   12.24 -
   12.25 -	  0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
   12.26 -	  0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
   12.27 -	  0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
   12.28 -	  0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
   12.29 -	  0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
   12.30 -	  0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
   12.31 -	  0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
   12.32 -	 82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
   12.33 -
   12.34 -	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
   12.35 -	217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
   12.36 -	173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
   12.37 -	159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
   12.38 -	157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
   12.39 -	226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
   12.40 -	  0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
   12.41 -	110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
   12.42 -
   12.43 -};
   12.44 -
   12.45 -static unsigned char atkbd_unxlate_table[128] = {
   12.46 -
   12.47 -	  0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
   12.48 -	 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
   12.49 -	 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
   12.50 -	 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
   12.51 -	 11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
   12.52 -	114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
   12.53 -	 71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
   12.54 -	 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
   12.55 -
   12.56 -};
   12.57 -
   12.58 -unsigned char keycode_table[512];
   12.59 -
   12.60 -static void *kbd_layout;
   12.61 -uint8_t modifiers_state[256];
   12.62 -
   12.63 -static int btnmap[] = {
   12.64 -	BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE,
   12.65 -	BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK
   12.66 -};
   12.67 -
   12.68 -static void press_key_shift_down(struct xenfb* xenfb, int down, int scancode)
   12.69 -{
   12.70 -	if (down)
   12.71 -		xenfb_send_key(xenfb, 1, keycode_table[0x2a]);
   12.72 -
   12.73 -	if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
   12.74 -		fprintf(stderr, "Key %d %s lost (%s)\n",
   12.75 -			scancode, "down", strerror(errno));
   12.76 -
   12.77 -	if (!down)
   12.78 -		xenfb_send_key(xenfb, 0, keycode_table[0x2a]);
   12.79 -}
   12.80 -
   12.81 -static void press_key_shift_up(struct xenfb* xenfb, int down, int scancode)
   12.82 -{
   12.83 -	if (down) {
   12.84 -		if (modifiers_state[0x2a])
   12.85 -			xenfb_send_key(xenfb, 0, keycode_table[0x2a]);
   12.86 -		if (modifiers_state[0x36])
   12.87 -			xenfb_send_key(xenfb, 0, keycode_table[0x36]);
   12.88 -	}
   12.89 -
   12.90 -	if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
   12.91 -		fprintf(stderr, "Key %d %s lost (%s)\n",
   12.92 -			scancode, "down", strerror(errno));
   12.93 -
   12.94 -	if (!down) {
   12.95 -		if (modifiers_state[0x2a])
   12.96 -			xenfb_send_key(xenfb, 1, keycode_table[0x2a]);
   12.97 -		if (modifiers_state[0x36])
   12.98 -			xenfb_send_key(xenfb, 1, keycode_table[0x36]);
   12.99 -	}
  12.100 -}
  12.101 -
  12.102 -static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
  12.103 -{
  12.104 -	/*
  12.105 -	 * We need to map to the key's Linux input layer keycode.
  12.106 -	 * Unfortunately, we don't get the key here, only the
  12.107 -	 * rfbKeySym, which is what the key is mapped to.  Mapping
  12.108 -	 * back to the key is impossible in general, even when you
  12.109 -	 * know the keymap.  For instance, the standard German keymap
  12.110 -	 * maps both KEY_COMMA and KEY_102ND to XK_less.  We simply
  12.111 -	 * assume standard US layout.  This sucks.
  12.112 -	 */
  12.113 -	rfbScreenInfoPtr server = cl->screen;
  12.114 -	struct xenfb *xenfb = server->screenData;
  12.115 -	int scancode;
  12.116 -	int shift = 0;
  12.117 -	int shift_keys = 0;
  12.118 -
  12.119 -	if (keycode >= 'A' && keycode <= 'Z') {
  12.120 -		keycode += 'a' - 'A';
  12.121 -		shift = 1;
  12.122 -	}
  12.123 -	else {
  12.124 -		shift = keysymIsShift(kbd_layout, keycode);
  12.125 -	}
  12.126 -	shift_keys = modifiers_state[0x2a] | modifiers_state[0x36];	
  12.127 -
  12.128 -	scancode = keysym2scancode(kbd_layout, keycode);
  12.129 -	if (scancode == 0)
  12.130 -		return;
  12.131 -
  12.132 -	switch(scancode) {
  12.133 -	case 0x2a:			/* Left Shift */
  12.134 -	case 0x36:			/* Right Shift */
  12.135 -	case 0x1d:			/* Left CTRL */
  12.136 -	case 0x9d:			/* Right CTRL */
  12.137 -	case 0x38:			/* Left ALT */
  12.138 -	case 0xb8:			/* Right ALT */
  12.139 -		if (down)
  12.140 -			modifiers_state[scancode] = 1;
  12.141 -		else
  12.142 -			modifiers_state[scancode] = 0;
  12.143 -		xenfb_send_key(xenfb, down, keycode_table[scancode]); 
  12.144 -		return;
  12.145 -	case 0x45:			/* NumLock */
  12.146 -		if (!down)
  12.147 -			modifiers_state[scancode] ^= 1;
  12.148 -		xenfb_send_key(xenfb, down, keycode_table[scancode]);
  12.149 -		return;
  12.150 -	}
  12.151 -
  12.152 -	if (keycodeIsKeypad(kbd_layout, scancode)) {
  12.153 -	/* If the numlock state needs to change then simulate an additional
  12.154 -	   keypress before sending this one.  This will happen if the user
  12.155 -	   toggles numlock away from the VNC window.
  12.156 -	*/
  12.157 -		if (keysymIsNumlock(kbd_layout, keycode)) {
  12.158 -			if (!modifiers_state[0x45]) {
  12.159 -				modifiers_state[0x45] = 1;
  12.160 -				xenfb_send_key(xenfb, 1, keycode_table[0x45]);
  12.161 -				xenfb_send_key(xenfb, 0, keycode_table[0x45]);
  12.162 -			}
  12.163 -		} else {
  12.164 -			if (modifiers_state[0x45]) {
  12.165 -				modifiers_state[0x45] = 0;
  12.166 -				xenfb_send_key(xenfb, 1, keycode_table[0x45]);
  12.167 -				xenfb_send_key(xenfb, 0, keycode_table[0x45]);
  12.168 -			}
  12.169 -		}
  12.170 -	}
  12.171 -
  12.172 -	/* If the shift state needs to change then simulate an additional
  12.173 -	   keypress before sending this one.
  12.174 -	*/
  12.175 -	if (shift && !shift_keys) {
  12.176 -		press_key_shift_down(xenfb, down, scancode);
  12.177 -		return;
  12.178 -	}
  12.179 -	else if (!shift && shift_keys) {
  12.180 -		press_key_shift_up(xenfb, down, scancode);
  12.181 -		return;
  12.182 -	}
  12.183 -
  12.184 -	if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
  12.185 -		fprintf(stderr, "Key %d %s lost (%s)\n",
  12.186 -			scancode, down ? "down" : "up",
  12.187 -			strerror(errno));
  12.188 -}
  12.189 -
  12.190 -static void on_ptr_event(int buttonMask, int x, int y, rfbClientPtr cl)
  12.191 -{
  12.192 -	/* initial pointer state: at (0,0), buttons up */
  12.193 -	static int last_x, last_y, last_button;
  12.194 -	rfbScreenInfoPtr server = cl->screen;
  12.195 -	struct xenfb *xenfb = server->screenData;
  12.196 -	int i, last_down, down, ret;
  12.197 -
  12.198 -	for (i = 0; i < 8; i++) {
  12.199 -		last_down = last_button & (1 << i);
  12.200 -		down = buttonMask & (1 << i);
  12.201 -		if (down == last_down)
  12.202 -			continue;
  12.203 -		if (i >= sizeof(btnmap) / sizeof(*btnmap))
  12.204 -			break;
  12.205 -		if (btnmap[i] == 0)
  12.206 -			break;
  12.207 -		if (xenfb_send_key(xenfb, down != 0, btnmap[i]) < 0)
  12.208 -			fprintf(stderr, "Button %d %s lost (%s)\n",
  12.209 -				i, down ? "down" : "up", strerror(errno));
  12.210 -	}
  12.211 -
  12.212 -	if (x != last_x || y != last_y) {
  12.213 -		if (xenfb->abs_pointer_wanted) 
  12.214 -			ret = xenfb_send_position(xenfb, x, y);
  12.215 -		else
  12.216 -			ret = xenfb_send_motion(xenfb, x - last_x, y - last_y);
  12.217 -		if (ret < 0)
  12.218 -			fprintf(stderr, "Pointer to %d,%d lost (%s)\n",
  12.219 -				x, y, strerror(errno));
  12.220 -	}
  12.221 -
  12.222 -	last_button = buttonMask;
  12.223 -	last_x = x;
  12.224 -	last_y = y;
  12.225 -}
  12.226 -
  12.227 -static void xenstore_write_vncport(struct xs_handle *xsh, int port, int domid)
  12.228 -{
  12.229 -	char *buf, *path;
  12.230 -	char portstr[10];
  12.231 -
  12.232 -	path = xs_get_domain_path(xsh, domid);
  12.233 -	if (path == NULL) {
  12.234 -		fprintf(stderr, "Can't get domain path (%s)\n",
  12.235 -			strerror(errno));
  12.236 -		goto out;
  12.237 -	}
  12.238 -
  12.239 -	if (asprintf(&buf, "%s/console/vnc-port", path) == -1) {
  12.240 -		fprintf(stderr, "Can't make vncport path\n");
  12.241 -		goto out;
  12.242 -	}
  12.243 -
  12.244 -	if (snprintf(portstr, sizeof(portstr), "%d", port) == -1) {
  12.245 -		fprintf(stderr, "Can't make vncport value\n");
  12.246 -		goto out;
  12.247 -	}
  12.248 -
  12.249 -	if (!xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)))
  12.250 -		fprintf(stderr, "Can't set vncport (%s)\n",
  12.251 -			strerror(errno));
  12.252 -
  12.253 - out:
  12.254 -	free(buf);
  12.255 -}
  12.256 -
  12.257 -
  12.258 -static int xenstore_read_vncpasswd(struct xs_handle *xsh, int domid, char *pwbuf, int pwbuflen)
  12.259 -{
  12.260 -	char buf[256], *path, *uuid = NULL, *passwd = NULL;
  12.261 -	unsigned int len, rc = 0;
  12.262 -
  12.263 -	if (xsh == NULL) {
  12.264 -		return -1;
  12.265 -	}
  12.266 -
  12.267 -	path = xs_get_domain_path(xsh, domid);
  12.268 -	if (path == NULL) {
  12.269 -		fprintf(stderr, "xs_get_domain_path() error\n");
  12.270 -		return -1;
  12.271 -	}
  12.272 -
  12.273 -	snprintf(buf, 256, "%s/vm", path);
  12.274 -	uuid = xs_read(xsh, XBT_NULL, buf, &len);
  12.275 -	if (uuid == NULL) {
  12.276 -		fprintf(stderr, "xs_read(): uuid get error\n");
  12.277 -		free(path);
  12.278 -		return -1;
  12.279 -	}
  12.280 -
  12.281 -	snprintf(buf, 256, "%s/vncpasswd", uuid);
  12.282 -	passwd = xs_read(xsh, XBT_NULL, buf, &len);
  12.283 -	if (passwd == NULL) {
  12.284 -		free(uuid);
  12.285 -		free(path);
  12.286 -		return rc;
  12.287 -	}
  12.288 -
  12.289 -	strncpy(pwbuf, passwd, pwbuflen-1);
  12.290 -	pwbuf[pwbuflen-1] = '\0';
  12.291 -
  12.292 -	fprintf(stderr, "Got a VNC password read from XenStore\n");
  12.293 -
  12.294 -	passwd[0] = '\0';
  12.295 -	snprintf(buf, 256, "%s/vncpasswd", uuid);
  12.296 -	if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
  12.297 -		fprintf(stderr, "xs_write() vncpasswd failed\n");
  12.298 -		rc = -1;
  12.299 -	}
  12.300 -
  12.301 -	free(passwd);
  12.302 -	free(uuid);
  12.303 -	free(path);
  12.304 -
  12.305 -	return rc;
  12.306 -}
  12.307 -
  12.308 -static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h)
  12.309 -{
  12.310 -	rfbScreenInfoPtr server = xenfb->user_data;
  12.311 -	rfbMarkRectAsModified(server, x, y, x + w, y + h);
  12.312 -}
  12.313 -
  12.314 -static struct option options[] = {
  12.315 -	{ "domid", 1, NULL, 'd' },
  12.316 -	{ "vncport", 1, NULL, 'p' },
  12.317 -	{ "title", 1, NULL, 't' },
  12.318 -	{ "unused", 0, NULL, 'u' },
  12.319 -	{ "listen", 1, NULL, 'l' },
  12.320 -	{ "keymap", 1, NULL, 'k' },
  12.321 -	{ NULL }
  12.322 -};
  12.323 -
  12.324 -int main(int argc, char **argv)
  12.325 -{
  12.326 -	rfbScreenInfoPtr server;
  12.327 -	char *fake_argv[7] = { "vncfb", "-rfbport", "5901", 
  12.328 -                               "-desktop", "xen-vncfb", 
  12.329 -                               "-listen", "127.0.0.1" };
  12.330 -	int fake_argc = sizeof(fake_argv) / sizeof(fake_argv[0]);
  12.331 -	int domid = -1, port = -1;
  12.332 -	char *title = NULL;
  12.333 -	char *listen = NULL;
  12.334 -	char *keymap = NULL;
  12.335 -	bool unused = false;
  12.336 -	int opt;
  12.337 -	struct xenfb *xenfb;
  12.338 -	fd_set readfds;
  12.339 -	int nfds;
  12.340 -	char portstr[10];
  12.341 -	char *endp;
  12.342 -	int r;
  12.343 -	struct xs_handle *xsh;
  12.344 -	char vncpasswd[1024];
  12.345 -	int i;
  12.346 -
  12.347 -	vncpasswd[0] = '\0';
  12.348 -
  12.349 -	while ((opt = getopt_long(argc, argv, "d:p:t:uk:", options,
  12.350 -				  NULL)) != -1) {
  12.351 -		switch (opt) {
  12.352 -                case 'd':
  12.353 -			errno = 0;
  12.354 -			domid = strtol(optarg, &endp, 10);
  12.355 -			if (endp == optarg || *endp || errno) {
  12.356 -				fprintf(stderr, "Invalid domain id specified\n");
  12.357 -				exit(1);
  12.358 -			}
  12.359 -			break;
  12.360 -                case 'p':
  12.361 -			errno = 0;
  12.362 -			port = strtol(optarg, &endp, 10);
  12.363 -			if (endp == optarg || *endp || errno) {
  12.364 -				fprintf(stderr, "Invalid port specified\n");
  12.365 -				exit(1);
  12.366 -			}
  12.367 -			break;
  12.368 -                case 't':
  12.369 -			title = strdup(optarg);
  12.370 -			break;
  12.371 -                case 'u':
  12.372 -			unused = true;
  12.373 -			break;
  12.374 -                case 'l':
  12.375 -			listen = strdup(optarg);
  12.376 -			break;
  12.377 -                case 'k':
  12.378 -			keymap = strdup(optarg);
  12.379 -			break;
  12.380 -		case '?':
  12.381 -			exit(1);
  12.382 -                }
  12.383 -        }
  12.384 -        if (optind != argc) {
  12.385 -		fprintf(stderr, "Invalid options!\n");
  12.386 -		exit(1);
  12.387 -        }
  12.388 -        if (domid <= 0) {
  12.389 -		fprintf(stderr, "Domain ID must be specified!\n");
  12.390 -		exit(1);
  12.391 -        }
  12.392 -            
  12.393 -        if (port <= 0)
  12.394 -		port = 5900 + domid;
  12.395 -	if (snprintf(portstr, sizeof(portstr), "%d", port) == -1) {
  12.396 -		fprintf(stderr, "Invalid port specified\n");
  12.397 -		exit(1);
  12.398 -        }
  12.399 -
  12.400 -	if (keymap == NULL){
  12.401 -		keymap = "en-us";
  12.402 -	}
  12.403 -
  12.404 -	kbd_layout = init_keyboard_layout(keymap);
  12.405 -	if( !kbd_layout ){
  12.406 -		fprintf(stderr, "Invalid keyboard_layout\n");
  12.407 -		exit(1);
  12.408 -        }
  12.409 -
  12.410 -	for (i = 0; i < 128; i++) {
  12.411 -		keycode_table[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
  12.412 -		keycode_table[i | 0x80] = 
  12.413 -			atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
  12.414 -	}
  12.415 -
  12.416 -	for (i = 0; i < 256; i++ ) {
  12.417 -		modifiers_state[i] = 0;
  12.418 -	}
  12.419 -
  12.420 -	fake_argv[2] = portstr;
  12.421 -
  12.422 -        if (title != NULL)
  12.423 -		fake_argv[4] = title;
  12.424 -
  12.425 -        if (listen != NULL)
  12.426 -		fake_argv[6] = listen;
  12.427 -
  12.428 -	signal(SIGPIPE, SIG_IGN);
  12.429 -
  12.430 -	xenfb = xenfb_new();
  12.431 -	if (xenfb == NULL) {
  12.432 -		fprintf(stderr, "Could not create framebuffer (%s)\n",
  12.433 -			strerror(errno));
  12.434 -		exit(1);
  12.435 -	}
  12.436 -
  12.437 -	if (xenfb_attach_dom(xenfb, domid) < 0) {
  12.438 -		fprintf(stderr, "Could not connect to domain (%s)\n",
  12.439 -			strerror(errno));
  12.440 -		exit(1);
  12.441 -	}
  12.442 -
  12.443 -	xsh = xs_daemon_open();
  12.444 -	if (xsh == NULL) {
  12.445 -	        fprintf(stderr, "cannot open connection to xenstore\n");
  12.446 -		exit(1);
  12.447 -	}
  12.448 -
  12.449 -
  12.450 -	if (xenstore_read_vncpasswd(xsh, domid, vncpasswd,
  12.451 -				    sizeof(vncpasswd)/sizeof(char)) < 0) {
  12.452 -		fprintf(stderr, "cannot read VNC password from xenstore\n");
  12.453 -		exit(1);
  12.454 -	}
  12.455 -	  
  12.456 -
  12.457 -	server = rfbGetScreen(&fake_argc, fake_argv, 
  12.458 -			      xenfb->width, xenfb->height,
  12.459 -			      8, 3, xenfb->depth / 8);
  12.460 -	if (server == NULL) {
  12.461 -		fprintf(stderr, "Could not create VNC server\n");
  12.462 -		exit(1);
  12.463 -	}
  12.464 -
  12.465 -	xenfb->user_data = server;
  12.466 -	xenfb->update = vnc_update;
  12.467 -
  12.468 -        if (unused)
  12.469 -		server->autoPort = true;
  12.470 -
  12.471 -	if (vncpasswd[0]) {
  12.472 -		char **passwds = malloc(sizeof(char**)*2);
  12.473 -		if (!passwds) {
  12.474 -			fprintf(stderr, "cannot allocate memory (%s)\n",
  12.475 -				strerror(errno));
  12.476 -			exit(1);
  12.477 -		}
  12.478 -		fprintf(stderr, "Registered password\n");
  12.479 -		passwds[0] = vncpasswd;
  12.480 -		passwds[1] = NULL;
  12.481 -
  12.482 -		server->authPasswdData = passwds;
  12.483 -		server->passwordCheck = rfbCheckPasswordByList;
  12.484 -	} else {
  12.485 -		fprintf(stderr, "Running with no password\n");
  12.486 -	}
  12.487 -	server->serverFormat.redShift = 16;
  12.488 -	server->serverFormat.greenShift = 8;
  12.489 -	server->serverFormat.blueShift = 0;
  12.490 -	server->kbdAddEvent = on_kbd_event;
  12.491 -	server->ptrAddEvent = on_ptr_event;
  12.492 -	server->frameBuffer = xenfb->pixels;
  12.493 -	server->screenData = xenfb;
  12.494 -	server->cursor = NULL;
  12.495 -	rfbInitServer(server);
  12.496 -
  12.497 -	rfbRunEventLoop(server, -1, true);
  12.498 -
  12.499 -        xenstore_write_vncport(xsh, server->port, domid);
  12.500 -
  12.501 -	for (;;) {
  12.502 -		FD_ZERO(&readfds);
  12.503 -		nfds = xenfb_select_fds(xenfb, &readfds);
  12.504 -
  12.505 -		if (select(nfds, &readfds, NULL, NULL, NULL) < 0) {
  12.506 -			if (errno == EINTR)
  12.507 -				continue;
  12.508 -			fprintf(stderr,
  12.509 -				"Can't select() on event channel (%s)\n",
  12.510 -				strerror(errno));
  12.511 -			break;
  12.512 -		}
  12.513 -
  12.514 -		r = xenfb_poll(xenfb, &readfds);
  12.515 -		if (r == -2)
  12.516 -		    xenfb_teardown(xenfb);
  12.517 -		if (r < 0)
  12.518 -		    break;
  12.519 -	}
  12.520 -
  12.521 -	rfbScreenCleanup(server);
  12.522 -	xenfb_delete(xenfb);
  12.523 -
  12.524 -	return 0;
  12.525 -}
    13.1 --- a/tools/xenfb/xenfb.c	Thu Oct 25 14:35:04 2007 +0100
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,819 +0,0 @@
    13.4 -#include <stdarg.h>
    13.5 -#include <stdlib.h>
    13.6 -#include <sys/types.h>
    13.7 -#include <fcntl.h>
    13.8 -#include <unistd.h>
    13.9 -#include <xenctrl.h>
   13.10 -#include <xen/io/xenbus.h>
   13.11 -#include <xen/io/fbif.h>
   13.12 -#include <xen/io/kbdif.h>
   13.13 -#include <xen/io/protocols.h>
   13.14 -#include <sys/select.h>
   13.15 -#include <stdbool.h>
   13.16 -#include <xen/event_channel.h>
   13.17 -#include <sys/mman.h>
   13.18 -#include <errno.h>
   13.19 -#include <stdio.h>
   13.20 -#include <string.h>
   13.21 -#include <time.h>
   13.22 -#include <xs.h>
   13.23 -
   13.24 -#include "xenfb.h"
   13.25 -
   13.26 -// FIXME defend against malicious frontend?
   13.27 -
   13.28 -struct xenfb_device {
   13.29 -	const char *devicetype;
   13.30 -	char nodename[64];	/* backend xenstore dir */
   13.31 -	char otherend[64];	/* frontend xenstore dir */
   13.32 -	int otherend_id;	/* frontend domid */
   13.33 -	enum xenbus_state state; /* backend state */
   13.34 -	void *page;		/* shared page */
   13.35 -	evtchn_port_t port;
   13.36 -	struct xenfb_private *xenfb;
   13.37 -};
   13.38 -
   13.39 -struct xenfb_private {
   13.40 -	struct xenfb pub;
   13.41 -	int evt_xch;		/* event channel driver handle */
   13.42 -	int xc;			/* hypervisor interface handle */
   13.43 -	struct xs_handle *xsh;	/* xs daemon handle */
   13.44 -	struct xenfb_device fb, kbd;
   13.45 -	size_t fb_len;		/* size of framebuffer */
   13.46 -	char protocol[64];	/* frontend protocol */
   13.47 -};
   13.48 -
   13.49 -static void xenfb_detach_dom(struct xenfb_private *);
   13.50 -
   13.51 -static char *xenfb_path_in_dom(struct xs_handle *xsh,
   13.52 -			       char *buf, size_t size,
   13.53 -			       unsigned domid, const char *fmt, ...)
   13.54 -{
   13.55 -	va_list ap;
   13.56 -	char *domp = xs_get_domain_path(xsh, domid);
   13.57 -	int n;
   13.58 -
   13.59 -        if (domp == NULL)
   13.60 -		return NULL;
   13.61 -
   13.62 -	n = snprintf(buf, size, "%s/", domp);
   13.63 -	free(domp);
   13.64 -	if (n >= size)
   13.65 -		return NULL;
   13.66 -
   13.67 -	va_start(ap, fmt);
   13.68 -	n += vsnprintf(buf + n, size - n, fmt, ap);
   13.69 -	va_end(ap);
   13.70 -	if (n >= size)
   13.71 -		return NULL;
   13.72 -
   13.73 -	return buf;
   13.74 -}
   13.75 -
   13.76 -static int xenfb_xs_scanf1(struct xs_handle *xsh,
   13.77 -			   const char *dir, const char *node,
   13.78 -			   const char *fmt, void *dest)
   13.79 -{
   13.80 -	char buf[1024];
   13.81 -	char *p;
   13.82 -	int ret;
   13.83 -
   13.84 -	if (snprintf(buf, sizeof(buf), "%s/%s", dir, node) >= sizeof(buf)) {
   13.85 -		errno = ENOENT;
   13.86 -		return -1;
   13.87 -        }
   13.88 -	p = xs_read(xsh, XBT_NULL, buf, NULL);
   13.89 -	if (!p) {
   13.90 -		errno = ENOENT;
   13.91 -		return -1;
   13.92 -        }
   13.93 -	ret = sscanf(p, fmt, dest);
   13.94 -	free(p);
   13.95 -	if (ret != 1) {
   13.96 -		errno = EDOM;
   13.97 -		return -1;
   13.98 -        }
   13.99 -	return ret;
  13.100 -}
  13.101 -
  13.102 -static int xenfb_xs_printf(struct xs_handle *xsh,
  13.103 -			   const char *dir, const char *node, char *fmt, ...)
  13.104 -{
  13.105 -	va_list ap;
  13.106 -	char key[1024];
  13.107 -	char val[1024];
  13.108 -	int n;
  13.109 -
  13.110 -	if (snprintf(key, sizeof(key), "%s/%s", dir, node) >= sizeof(key)) {
  13.111 -		errno = ENOENT;
  13.112 -		return -1;
  13.113 -        }
  13.114 -
  13.115 -	va_start(ap, fmt);
  13.116 -	n = vsnprintf(val, sizeof(val), fmt, ap);
  13.117 -	va_end(ap);
  13.118 -	if (n >= sizeof(val)) {
  13.119 -		errno = ENOSPC; /* close enough */
  13.120 -		return -1;
  13.121 -	}
  13.122 -
  13.123 -	if (!xs_write(xsh, XBT_NULL, key, val, n))
  13.124 -		return -1;
  13.125 -	return 0;
  13.126 -}
  13.127 -
  13.128 -static void xenfb_device_init(struct xenfb_device *dev,
  13.129 -			      const char *type,
  13.130 -			      struct xenfb_private *xenfb)
  13.131 -{
  13.132 -	dev->devicetype = type;
  13.133 -	dev->otherend_id = -1;
  13.134 -	dev->port = -1;
  13.135 -	dev->xenfb = xenfb;
  13.136 -}
  13.137 -
  13.138 -int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
  13.139 -{
  13.140 -	struct xenfb_private *xenfb = dev->xenfb;
  13.141 -
  13.142 -	dev->otherend_id = domid;
  13.143 -
  13.144 -	if (!xenfb_path_in_dom(xenfb->xsh,
  13.145 -			       dev->otherend, sizeof(dev->otherend),
  13.146 -			       domid, "device/%s/0", dev->devicetype)) {
  13.147 -		errno = ENOENT;
  13.148 -		return -1;
  13.149 -	}
  13.150 -	if (!xenfb_path_in_dom(xenfb->xsh,
  13.151 -			       dev->nodename, sizeof(dev->nodename),
  13.152 -			       0, "backend/%s/%d/0", dev->devicetype, domid)) {
  13.153 -		errno = ENOENT;
  13.154 -		return -1;
  13.155 -	}
  13.156 -
  13.157 -	return 0;
  13.158 -}
  13.159 -
  13.160 -struct xenfb *xenfb_new(void)
  13.161 -{
  13.162 -	struct xenfb_private *xenfb = malloc(sizeof(*xenfb));
  13.163 -	int serrno;
  13.164 -
  13.165 -	if (xenfb == NULL)
  13.166 -		return NULL;
  13.167 -
  13.168 -	memset(xenfb, 0, sizeof(*xenfb));
  13.169 -	xenfb->evt_xch = xenfb->xc = -1;
  13.170 -	xenfb_device_init(&xenfb->fb, "vfb", xenfb);
  13.171 -	xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
  13.172 -
  13.173 -	xenfb->evt_xch = xc_evtchn_open();
  13.174 -	if (xenfb->evt_xch == -1)
  13.175 -		goto fail;
  13.176 -
  13.177 -	xenfb->xc = xc_interface_open();
  13.178 -	if (xenfb->xc == -1)
  13.179 -		goto fail;
  13.180 -
  13.181 -	xenfb->xsh = xs_daemon_open();
  13.182 -	if (!xenfb->xsh)
  13.183 -		goto fail;
  13.184 -
  13.185 -	return &xenfb->pub;
  13.186 -
  13.187 - fail:
  13.188 -	serrno = errno;
  13.189 -	xenfb_delete(&xenfb->pub);
  13.190 -	errno = serrno;
  13.191 -	return NULL;
  13.192 -}
  13.193 -
  13.194 -/* Remove the backend area in xenbus since the framebuffer really is
  13.195 -   going away. */
  13.196 -void xenfb_teardown(struct xenfb *xenfb_pub)
  13.197 -{
  13.198 -       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.199 -
  13.200 -       xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
  13.201 -       xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
  13.202 -}
  13.203 -
  13.204 -
  13.205 -void xenfb_delete(struct xenfb *xenfb_pub)
  13.206 -{
  13.207 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.208 -
  13.209 -	xenfb_detach_dom(xenfb);
  13.210 -	if (xenfb->xc >= 0)
  13.211 -		xc_interface_close(xenfb->xc);
  13.212 -	if (xenfb->evt_xch >= 0)
  13.213 -		xc_evtchn_close(xenfb->evt_xch);
  13.214 -	if (xenfb->xsh)
  13.215 -		xs_daemon_close(xenfb->xsh);
  13.216 -	free(xenfb);
  13.217 -}
  13.218 -
  13.219 -static enum xenbus_state xenfb_read_state(struct xs_handle *xsh,
  13.220 -					  const char *dir)
  13.221 -{
  13.222 -	int ret, state;
  13.223 -
  13.224 -	ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state);
  13.225 -	if (ret < 0)
  13.226 -		return XenbusStateUnknown;
  13.227 -
  13.228 -	if ((unsigned)state > XenbusStateClosed)
  13.229 -		state = XenbusStateUnknown;
  13.230 -	return state;
  13.231 -}
  13.232 -
  13.233 -static int xenfb_switch_state(struct xenfb_device *dev,
  13.234 -			      enum xenbus_state state)
  13.235 -{
  13.236 -	struct xs_handle *xsh = dev->xenfb->xsh;
  13.237 -
  13.238 -	if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0)
  13.239 -		return -1;
  13.240 -	dev->state = state;
  13.241 -	return 0;
  13.242 -}
  13.243 -
  13.244 -static int xenfb_wait_for_state(struct xs_handle *xsh, const char *dir,
  13.245 -				unsigned awaited)
  13.246 -{
  13.247 -	unsigned state, dummy;
  13.248 -	char **vec;
  13.249 -
  13.250 -	awaited |= 1 << XenbusStateUnknown;
  13.251 -
  13.252 -	for (;;) {
  13.253 -		state = xenfb_read_state(xsh, dir);
  13.254 -		if ((1 << state) & awaited)
  13.255 -			return state;
  13.256 -
  13.257 -		vec = xs_read_watch(xsh, &dummy);
  13.258 -		if (!vec)
  13.259 -			return -1;
  13.260 -		free(vec);
  13.261 -	}
  13.262 -}
  13.263 -
  13.264 -static int xenfb_wait_for_backend_creation(struct xenfb_device *dev)
  13.265 -{
  13.266 -	struct xs_handle *xsh = dev->xenfb->xsh;
  13.267 -	int state;
  13.268 -
  13.269 -	if (!xs_watch(xsh, dev->nodename, ""))
  13.270 -		return -1;
  13.271 -	state = xenfb_wait_for_state(xsh, dev->nodename,
  13.272 -			(1 << XenbusStateInitialising)
  13.273 -			| (1 << XenbusStateClosed)
  13.274 -#if 1 /* TODO fudging state to permit restarting; to be removed */
  13.275 -			| (1 << XenbusStateInitWait)
  13.276 -			| (1 << XenbusStateConnected)
  13.277 -			| (1 << XenbusStateClosing)
  13.278 -#endif
  13.279 -			);
  13.280 -	xs_unwatch(xsh, dev->nodename, "");
  13.281 -
  13.282 -	switch (state) {
  13.283 -#if 1
  13.284 -	case XenbusStateInitWait:
  13.285 -	case XenbusStateConnected:
  13.286 -		printf("Fudging state to %d\n", XenbusStateInitialising); /* FIXME */
  13.287 -#endif
  13.288 -	case XenbusStateInitialising:
  13.289 -	case XenbusStateClosing:
  13.290 -	case XenbusStateClosed:
  13.291 -		break;
  13.292 -	default:
  13.293 -		return -1;
  13.294 -	}
  13.295 -
  13.296 -	return 0;
  13.297 -}
  13.298 -
  13.299 -static int xenfb_hotplug(struct xenfb_device *dev)
  13.300 -{
  13.301 -	if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename,
  13.302 -			    "hotplug-status", "connected"))
  13.303 -		return -1;
  13.304 -	return 0;
  13.305 -}
  13.306 -
  13.307 -static int xenfb_wait_for_frontend_initialised(struct xenfb_device *dev)
  13.308 -{
  13.309 -	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
  13.310 -#if 1 /* TODO fudging state to permit restarting; to be removed */
  13.311 -			(1 << XenbusStateInitialised)
  13.312 -			| (1 << XenbusStateConnected)
  13.313 -#else
  13.314 -			1 << XenbusStateInitialised,
  13.315 -#endif
  13.316 -			)) {
  13.317 -#if 1
  13.318 -	case XenbusStateConnected:
  13.319 -		printf("Fudging state to %d\n", XenbusStateInitialised); /* FIXME */
  13.320 -#endif
  13.321 -	case XenbusStateInitialised:
  13.322 -		break;
  13.323 -	default:
  13.324 -		return -1;
  13.325 -	}
  13.326 -
  13.327 -	return 0;
  13.328 -}
  13.329 -
  13.330 -static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
  13.331 -{
  13.332 -	uint32_t *src32 = src;
  13.333 -	uint64_t *src64 = src;
  13.334 -	int i;
  13.335 -
  13.336 -	for (i = 0; i < count; i++)
  13.337 -		dst[i] = (mode == 32) ? src32[i] : src64[i];
  13.338 -}
  13.339 -
  13.340 -static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
  13.341 -{
  13.342 -	struct xenfb_page *page = xenfb->fb.page;
  13.343 -	int n_fbmfns;
  13.344 -	int n_fbdirs;
  13.345 -	unsigned long *pgmfns = NULL;
  13.346 -	unsigned long *fbmfns = NULL;
  13.347 -	void *map, *pd;
  13.348 -	int mode, ret = -1;
  13.349 -
  13.350 -	/* default to native */
  13.351 -	pd = page->pd;
  13.352 -	mode = sizeof(unsigned long) * 8;
  13.353 -
  13.354 -	if (0 == strlen(xenfb->protocol)) {
  13.355 -		/*
  13.356 -		 * Undefined protocol, some guesswork needed.
  13.357 -		 *
  13.358 -		 * Old frontends which don't set the protocol use
  13.359 -		 * one page directory only, thus pd[1] must be zero.
  13.360 -		 * pd[1] of the 32bit struct layout and the lower
  13.361 -		 * 32 bits of pd[0] of the 64bit struct layout have
  13.362 -		 * the same location, so we can check that ...
  13.363 -		 */
  13.364 -		uint32_t *ptr32 = NULL;
  13.365 -		uint32_t *ptr64 = NULL;
  13.366 -#if defined(__i386__)
  13.367 -		ptr32 = (void*)page->pd;
  13.368 -		ptr64 = ((void*)page->pd) + 4;
  13.369 -#elif defined(__x86_64__)
  13.370 -		ptr32 = ((void*)page->pd) - 4;
  13.371 -		ptr64 = (void*)page->pd;
  13.372 -#endif
  13.373 -		if (ptr32) {
  13.374 -			if (0 == ptr32[1]) {
  13.375 -				mode = 32;
  13.376 -				pd   = ptr32;
  13.377 -			} else {
  13.378 -				mode = 64;
  13.379 -				pd   = ptr64;
  13.380 -			}
  13.381 -		}
  13.382 -#if defined(__x86_64__)
  13.383 -	} else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) {
  13.384 -		/* 64bit dom0, 32bit domU */
  13.385 -		mode = 32;
  13.386 -		pd   = ((void*)page->pd) - 4;
  13.387 -#elif defined(__i386__)
  13.388 -	} else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) {
  13.389 -		/* 32bit dom0, 64bit domU */
  13.390 -		mode = 64;
  13.391 -		pd   = ((void*)page->pd) + 4;
  13.392 -#endif
  13.393 -	}
  13.394 -
  13.395 -	n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
  13.396 -	n_fbdirs = n_fbmfns * mode / 8;
  13.397 -	n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
  13.398 -
  13.399 -	pgmfns = malloc(sizeof(unsigned long) * n_fbdirs);
  13.400 -	fbmfns = malloc(sizeof(unsigned long) * n_fbmfns);
  13.401 -	if (!pgmfns || !fbmfns)
  13.402 -		goto out;
  13.403 -
  13.404 -	xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
  13.405 -	map = xc_map_foreign_pages(xenfb->xc, domid,
  13.406 -				   PROT_READ, pgmfns, n_fbdirs);
  13.407 -	if (map == NULL)
  13.408 -		goto out;
  13.409 -	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
  13.410 -	munmap(map, n_fbdirs * XC_PAGE_SIZE);
  13.411 -
  13.412 -	xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
  13.413 -				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
  13.414 -	if (xenfb->pub.pixels == NULL)
  13.415 -		goto out;
  13.416 -
  13.417 -	ret = 0; /* all is fine */
  13.418 -
  13.419 - out:
  13.420 -	if (pgmfns)
  13.421 -		free(pgmfns);
  13.422 -	if (fbmfns)
  13.423 -		free(fbmfns);
  13.424 -	return ret;
  13.425 -}
  13.426 -
  13.427 -static int xenfb_bind(struct xenfb_device *dev)
  13.428 -{
  13.429 -	struct xenfb_private *xenfb = dev->xenfb;
  13.430 -	unsigned long mfn;
  13.431 -	evtchn_port_t evtchn;
  13.432 -
  13.433 -	if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu",
  13.434 -			    &mfn) < 0)
  13.435 -		return -1;
  13.436 -	if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u",
  13.437 -			    &evtchn) < 0)
  13.438 -		return -1;
  13.439 -
  13.440 -	dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch,
  13.441 -					       dev->otherend_id, evtchn);
  13.442 -	if (dev->port == -1)
  13.443 -		return -1;
  13.444 -
  13.445 -	dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id,
  13.446 -			XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
  13.447 -	if (dev->page == NULL)
  13.448 -		return -1;
  13.449 -
  13.450 -	return 0;
  13.451 -}
  13.452 -
  13.453 -static void xenfb_unbind(struct xenfb_device *dev)
  13.454 -{
  13.455 -	if (dev->page) {
  13.456 -		munmap(dev->page, XC_PAGE_SIZE);
  13.457 -		dev->page = NULL;
  13.458 -	}
  13.459 -        if (dev->port >= 0) {
  13.460 -		xc_evtchn_unbind(dev->xenfb->evt_xch, dev->port);
  13.461 -		dev->port = -1;
  13.462 -	}
  13.463 -}
  13.464 -
  13.465 -static int xenfb_wait_for_frontend_connected(struct xenfb_device *dev)
  13.466 -{
  13.467 -	switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
  13.468 -				     1 << XenbusStateConnected)) {
  13.469 -	case XenbusStateConnected:
  13.470 -		break;
  13.471 -	default:
  13.472 -		return -1;
  13.473 -	}
  13.474 -
  13.475 -	return 0;
  13.476 -}
  13.477 -
  13.478 -static void xenfb_dev_fatal(struct xenfb_device *dev, int err,
  13.479 -			    const char *fmt, ...)
  13.480 -{
  13.481 -	struct xs_handle *xsh = dev->xenfb->xsh;
  13.482 -	va_list ap;
  13.483 -	char errdir[80];
  13.484 -	char buf[1024];
  13.485 -	int n;
  13.486 -
  13.487 -	fprintf(stderr, "%s ", dev->nodename); /* somewhat crude */
  13.488 -	va_start(ap, fmt);
  13.489 -	vfprintf(stderr, fmt, ap);
  13.490 -	va_end(ap);
  13.491 -	if (err)
  13.492 -		fprintf(stderr, " (%s)", strerror(err));
  13.493 -	putc('\n', stderr);
  13.494 -
  13.495 -	if (!xenfb_path_in_dom(xsh, errdir, sizeof(errdir), 0,
  13.496 -			       "error/%s", dev->nodename))
  13.497 -		goto out;	/* FIXME complain */
  13.498 -
  13.499 -	va_start(ap, fmt);
  13.500 -	n = snprintf(buf, sizeof(buf), "%d ", err);
  13.501 -	snprintf(buf + n, sizeof(buf) - n, fmt, ap);
  13.502 -	va_end(ap);
  13.503 -
  13.504 -	if (xenfb_xs_printf(xsh, buf, "error", "%s", buf) < 0)
  13.505 -		goto out;	/* FIXME complain */
  13.506 -
  13.507 - out:
  13.508 -	xenfb_switch_state(dev, XenbusStateClosing);
  13.509 -}
  13.510 -
  13.511 -int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
  13.512 -{
  13.513 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.514 -	struct xs_handle *xsh = xenfb->xsh;
  13.515 -	int val, serrno;
  13.516 -	struct xenfb_page *fb_page;
  13.517 -
  13.518 -	xenfb_detach_dom(xenfb);
  13.519 -
  13.520 -	xenfb_device_set_domain(&xenfb->fb, domid);
  13.521 -	xenfb_device_set_domain(&xenfb->kbd, domid);
  13.522 -
  13.523 -	if (xenfb_wait_for_backend_creation(&xenfb->fb) < 0)
  13.524 -		goto error;
  13.525 -	if (xenfb_wait_for_backend_creation(&xenfb->kbd) < 0)
  13.526 -		goto error;
  13.527 -
  13.528 -	if (xenfb_xs_printf(xsh, xenfb->kbd.nodename, "feature-abs-pointer", "1"))
  13.529 -		goto error;
  13.530 -	if (xenfb_switch_state(&xenfb->fb, XenbusStateInitWait))
  13.531 -		goto error;
  13.532 -	if (xenfb_switch_state(&xenfb->kbd, XenbusStateInitWait))
  13.533 -		goto error;
  13.534 -
  13.535 -	if (xenfb_hotplug(&xenfb->fb) < 0)
  13.536 -		goto error;
  13.537 -	if (xenfb_hotplug(&xenfb->kbd) < 0)
  13.538 -		goto error;
  13.539 -
  13.540 -	if (!xs_watch(xsh, xenfb->fb.otherend, ""))
  13.541 -		goto error;
  13.542 -	if (!xs_watch(xsh, xenfb->kbd.otherend, ""))
  13.543 -		goto error;
  13.544 -
  13.545 -	if (xenfb_wait_for_frontend_initialised(&xenfb->fb) < 0)
  13.546 -		goto error;
  13.547 -	if (xenfb_wait_for_frontend_initialised(&xenfb->kbd) < 0)
  13.548 -		goto error;
  13.549 -
  13.550 -	if (xenfb_bind(&xenfb->fb) < 0)
  13.551 -		goto error;
  13.552 -	if (xenfb_bind(&xenfb->kbd) < 0)
  13.553 -		goto error;
  13.554 -
  13.555 -	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "feature-update",
  13.556 -			    "%d", &val) < 0)
  13.557 -		val = 0;
  13.558 -	if (!val) {
  13.559 -		errno = ENOTSUP;
  13.560 -		goto error;
  13.561 -	}
  13.562 -	if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
  13.563 -			    xenfb->protocol) < 0)
  13.564 -		xenfb->protocol[0] = '\0';
  13.565 -	xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
  13.566 -
  13.567 -	/* TODO check for permitted ranges */
  13.568 -	fb_page = xenfb->fb.page;
  13.569 -	xenfb->pub.depth = fb_page->depth;
  13.570 -	xenfb->pub.width = fb_page->width;
  13.571 -	xenfb->pub.height = fb_page->height;
  13.572 -	/* TODO check for consistency with the above */
  13.573 -	xenfb->fb_len = fb_page->mem_length;
  13.574 -	xenfb->pub.row_stride = fb_page->line_length;
  13.575 -
  13.576 -	if (xenfb_map_fb(xenfb, domid) < 0)
  13.577 -		goto error;
  13.578 -
  13.579 -	if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
  13.580 -		goto error;
  13.581 -	if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
  13.582 -		goto error;
  13.583 -
  13.584 -	if (xenfb_wait_for_frontend_connected(&xenfb->kbd) < 0)
  13.585 -		goto error;
  13.586 -	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
  13.587 -			    "%d", &val) < 0)
  13.588 -		val = 0;
  13.589 -	xenfb->pub.abs_pointer_wanted = val;
  13.590 -
  13.591 -	return 0;
  13.592 -
  13.593 - error:
  13.594 -	serrno = errno;
  13.595 -	xenfb_detach_dom(xenfb);
  13.596 -	xenfb_dev_fatal(&xenfb->fb, serrno, "on fire");
  13.597 -	xenfb_dev_fatal(&xenfb->kbd, serrno, "on fire");
  13.598 -        errno = serrno;
  13.599 -        return -1;
  13.600 -}
  13.601 -
  13.602 -static void xenfb_detach_dom(struct xenfb_private *xenfb)
  13.603 -{
  13.604 -	xenfb_unbind(&xenfb->fb);
  13.605 -	xenfb_unbind(&xenfb->kbd);
  13.606 -	if (xenfb->pub.pixels) {
  13.607 -		munmap(xenfb->pub.pixels, xenfb->fb_len);
  13.608 -		xenfb->pub.pixels = NULL;
  13.609 -	}
  13.610 -}
  13.611 -
  13.612 -static void xenfb_on_fb_event(struct xenfb_private *xenfb)
  13.613 -{
  13.614 -	uint32_t prod, cons;
  13.615 -	struct xenfb_page *page = xenfb->fb.page;
  13.616 -
  13.617 -	prod = page->out_prod;
  13.618 -	if (prod == page->out_cons)
  13.619 -		return;
  13.620 -	rmb();			/* ensure we see ring contents up to prod */
  13.621 -	for (cons = page->out_cons; cons != prod; cons++) {
  13.622 -		union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
  13.623 -
  13.624 -		switch (event->type) {
  13.625 -		case XENFB_TYPE_UPDATE:
  13.626 -                    if (xenfb->pub.update)
  13.627 -			xenfb->pub.update(&xenfb->pub,
  13.628 -					  event->update.x, event->update.y,
  13.629 -					  event->update.width, event->update.height);
  13.630 -                    break;
  13.631 -		}
  13.632 -	}
  13.633 -	mb();			/* ensure we're done with ring contents */
  13.634 -	page->out_cons = cons;
  13.635 -	xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
  13.636 -}
  13.637 -
  13.638 -static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
  13.639 -{
  13.640 -	struct xenkbd_page *page = xenfb->kbd.page;
  13.641 -
  13.642 -	/* We don't understand any keyboard events, so just ignore them. */
  13.643 -	if (page->out_prod == page->out_cons)
  13.644 -		return;
  13.645 -	page->out_cons = page->out_prod;
  13.646 -	xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
  13.647 -}
  13.648 -
  13.649 -static int xenfb_on_state_change(struct xenfb_device *dev)
  13.650 -{
  13.651 -	enum xenbus_state state;
  13.652 -
  13.653 -	state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
  13.654 -
  13.655 -	switch (state) {
  13.656 -	case XenbusStateUnknown:
  13.657 -		/* There was an error reading the frontend state.  The
  13.658 -		   domain has probably gone away; in any case, there's
  13.659 -		   not much point in us continuing. */
  13.660 -		return -1;
  13.661 -	case XenbusStateInitialising:
  13.662 -	case XenbusStateInitWait:
  13.663 -	case XenbusStateInitialised:
  13.664 -	case XenbusStateConnected:
  13.665 -		break;
  13.666 -	case XenbusStateClosing:
  13.667 -		xenfb_unbind(dev);
  13.668 -		xenfb_switch_state(dev, state);
  13.669 -		break;
  13.670 -	case XenbusStateClosed:
  13.671 -		xenfb_switch_state(dev, state);
  13.672 -	}
  13.673 -	return 0;
  13.674 -}
  13.675 -
  13.676 -int xenfb_dispatch_channel(struct xenfb *xenfb_pub)
  13.677 -{
  13.678 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.679 -	evtchn_port_t port;
  13.680 -	port = xc_evtchn_pending(xenfb->evt_xch);
  13.681 -	if (port == -1)
  13.682 -		return -1;
  13.683 -
  13.684 -	if (port == xenfb->fb.port)
  13.685 -		xenfb_on_fb_event(xenfb);
  13.686 -	else if (port == xenfb->kbd.port)
  13.687 -		xenfb_on_kbd_event(xenfb);
  13.688 -
  13.689 -	if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
  13.690 -		return -1;
  13.691 -
  13.692 -	return 0;
  13.693 -}
  13.694 -
  13.695 -int xenfb_dispatch_store(struct xenfb *xenfb_pub)
  13.696 -{
  13.697 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.698 -	unsigned dummy;
  13.699 -	char **vec;
  13.700 -	int r;
  13.701 -
  13.702 -	vec = xs_read_watch(xenfb->xsh, &dummy);
  13.703 -	free(vec);
  13.704 -	r = xenfb_on_state_change(&xenfb->fb);
  13.705 -	if (r == 0)
  13.706 -		r = xenfb_on_state_change(&xenfb->kbd);
  13.707 -	if (r == -1)
  13.708 -		return -2;
  13.709 -
  13.710 -	return 0;
  13.711 -}
  13.712 -
  13.713 -
  13.714 -/* Returns 0 normally, -1 on error, or -2 if the domain went away. */
  13.715 -int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
  13.716 -{
  13.717 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.718 -	int ret;
  13.719 -
  13.720 -	if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
  13.721 -		if ((ret = xenfb_dispatch_channel(xenfb_pub)) < 0)
  13.722 -			return ret;
  13.723 -	}
  13.724 -
  13.725 -	if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) {
  13.726 -		if ((ret = xenfb_dispatch_store(xenfb_pub)) < 0)
  13.727 -			return ret;
  13.728 -	}
  13.729 -
  13.730 -	return 0;
  13.731 -}
  13.732 -
  13.733 -int xenfb_select_fds(struct xenfb *xenfb_pub, fd_set *readfds)
  13.734 -{
  13.735 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.736 -	int fd1 = xc_evtchn_fd(xenfb->evt_xch);
  13.737 -	int fd2 = xs_fileno(xenfb->xsh);
  13.738 -
  13.739 -	FD_SET(fd1, readfds);
  13.740 -	FD_SET(fd2, readfds);
  13.741 -	return fd1 > fd2 ? fd1 + 1 : fd2 + 1;
  13.742 -}
  13.743 -
  13.744 -int xenfb_get_store_fd(struct xenfb *xenfb_pub)
  13.745 -{
  13.746 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.747 -	return xs_fileno(xenfb->xsh);
  13.748 -}
  13.749 -
  13.750 -int xenfb_get_channel_fd(struct xenfb *xenfb_pub)
  13.751 -{
  13.752 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.753 -	return xc_evtchn_fd(xenfb->evt_xch);
  13.754 -}
  13.755 -
  13.756 -static int xenfb_kbd_event(struct xenfb_private *xenfb,
  13.757 -			   union xenkbd_in_event *event)
  13.758 -{
  13.759 -	uint32_t prod;
  13.760 -	struct xenkbd_page *page = xenfb->kbd.page;
  13.761 -
  13.762 -	if (xenfb->kbd.state != XenbusStateConnected)
  13.763 -		return 0;
  13.764 -
  13.765 -	prod = page->in_prod;
  13.766 -	if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
  13.767 -		errno = EAGAIN;
  13.768 -		return -1;
  13.769 -	}
  13.770 -
  13.771 -	mb();			/* ensure ring space available */
  13.772 -	XENKBD_IN_RING_REF(page, prod) = *event;
  13.773 -	wmb();			/* ensure ring contents visible */
  13.774 -	page->in_prod = prod + 1;
  13.775 -	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
  13.776 -}
  13.777 -
  13.778 -int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
  13.779 -{
  13.780 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.781 -	union xenkbd_in_event event;
  13.782 -
  13.783 -	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
  13.784 -	event.type = XENKBD_TYPE_KEY;
  13.785 -	event.key.pressed = down ? 1 : 0;
  13.786 -	event.key.keycode = keycode;
  13.787 -
  13.788 -	return xenfb_kbd_event(xenfb, &event);
  13.789 -}
  13.790 -
  13.791 -int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
  13.792 -{
  13.793 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.794 -	union xenkbd_in_event event;
  13.795 -
  13.796 -	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
  13.797 -	event.type = XENKBD_TYPE_MOTION;
  13.798 -	event.motion.rel_x = rel_x;
  13.799 -	event.motion.rel_y = rel_y;
  13.800 -
  13.801 -	return xenfb_kbd_event(xenfb, &event);
  13.802 -}
  13.803 -
  13.804 -int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
  13.805 -{
  13.806 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
  13.807 -	union xenkbd_in_event event;
  13.808 -
  13.809 -	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
  13.810 -	event.type = XENKBD_TYPE_POS;
  13.811 -	event.pos.abs_x = abs_x;
  13.812 -	event.pos.abs_y = abs_y;
  13.813 -
  13.814 -	return xenfb_kbd_event(xenfb, &event);
  13.815 -}
  13.816 -/*
  13.817 - * Local variables:
  13.818 - *  c-indent-level: 8
  13.819 - *  c-basic-offset: 8
  13.820 - *  tab-width: 8
  13.821 - * End:
  13.822 - */
    14.1 --- a/tools/xenfb/xenfb.h	Thu Oct 25 14:35:04 2007 +0100
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,39 +0,0 @@
    14.4 -#ifndef _XENFB_H_
    14.5 -#define _XENFB_H_
    14.6 -
    14.7 -#include <stdbool.h>
    14.8 -#include <sys/types.h>
    14.9 -
   14.10 -struct xenfb
   14.11 -{
   14.12 -	void *pixels;
   14.13 -
   14.14 -	int row_stride;
   14.15 -	int depth;
   14.16 -	int width;
   14.17 -	int height;
   14.18 -	int abs_pointer_wanted;
   14.19 -
   14.20 -	void *user_data;
   14.21 -
   14.22 -	void (*update)(struct xenfb *xenfb, int x, int y, int width, int height);
   14.23 -};
   14.24 -
   14.25 -struct xenfb *xenfb_new(void);
   14.26 -void xenfb_delete(struct xenfb *xenfb);
   14.27 -void xenfb_teardown(struct xenfb *xenfb);
   14.28 -
   14.29 -int xenfb_attach_dom(struct xenfb *xenfb, int domid);
   14.30 -
   14.31 -int xenfb_dispatch_store(struct xenfb *xenfb_pub);
   14.32 -int xenfb_dispatch_channel(struct xenfb *xenfb_pub);
   14.33 -int xenfb_select_fds(struct xenfb *xenfb, fd_set *readfds);
   14.34 -int xenfb_poll(struct xenfb *xenfb, fd_set *readfds);
   14.35 -int xenfb_get_store_fd(struct xenfb *xenfb_pub);
   14.36 -int xenfb_get_channel_fd(struct xenfb *xenfb_pub);
   14.37 -
   14.38 -int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode);
   14.39 -int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y);
   14.40 -int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);
   14.41 -
   14.42 -#endif