/*
 *  xen paravirt framebuffer backend
 *
 *  Copyright IBM, Corp. 2005-2006
 *  Copyright Red Hat, Inc. 2006-2008
 *
 *  Authors:
 *       Anthony Liguori <aliguori@us.ibm.com>,
 *       Markus Armbruster <armbru@redhat.com>,
 *       Daniel P. Berrange <berrange@redhat.com>,
 *       Pat Campbell <plc@novell.com>,
 *       Gerd Hoffmann <kraxel@redhat.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "hw/hw.h"
#include "ui/console.h"
#include "sysemu/char.h"
#include "hw/xen/xen_backend.h"

#include <xen/event_channel.h>
#include <xen/io/fbif.h>
#include <xen/io/kbdif.h>
#include <xen/io/protocols.h>

#include "trace.h"

#ifndef BTN_LEFT
#define BTN_LEFT 0x110 /* from <linux/input.h> */
#endif

/* -------------------------------------------------------------------- */

struct common {
    struct XenDevice  xendev;  /* must be first */
    void              *page;
    QemuConsole       *con;
};

struct XenInput {
    struct common c;
    int abs_pointer_wanted; /* Whether guest supports absolute pointer */
    int button_state;       /* Last seen pointer button state */
    int extended;
    QEMUPutMouseEntry *qmouse;
};

#define UP_QUEUE 8

struct XenFB {
    struct common     c;
    size_t            fb_len;
    int               row_stride;
    int               depth;
    int               width;
    int               height;
    int               offset;
    void              *pixels;
    int               fbpages;
    int               feature_update;
    int               bug_trigger;
    int               have_console;
    int               do_resize;

    struct {
	int x,y,w,h;
    } up_rects[UP_QUEUE];
    int               up_count;
    int               up_fullscreen;
};

/* -------------------------------------------------------------------- */

static int common_bind(struct common *c)
{
    uint64_t mfn;

    if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &mfn) == -1)
	return -1;
    assert(mfn == (xen_pfn_t)mfn);

    if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1)
	return -1;

    c->page = xc_map_foreign_range(xen_xc, c->xendev.dom,
				   XC_PAGE_SIZE,
				   PROT_READ | PROT_WRITE, mfn);
    if (c->page == NULL)
	return -1;

    xen_be_bind_evtchn(&c->xendev);
    xen_be_printf(&c->xendev, 1, "ring mfn %"PRIx64", remote-port %d, local-port %d\n",
		  mfn, c->xendev.remote_port, c->xendev.local_port);

    return 0;
}

static void common_unbind(struct common *c)
{
    xen_be_unbind_evtchn(&c->xendev);
    if (c->page) {
	munmap(c->page, XC_PAGE_SIZE);
	c->page = NULL;
    }
}

/* -------------------------------------------------------------------- */

#if 0
/*
 * These two tables are not needed any more, but left in here
 * intentionally as documentation, to show how scancode2linux[]
 * was generated.
 *
 * Tables to map from scancode to Linux input layer keycode.
 * Scancodes are hardware-specific.  These maps assumes a
 * standard AT or PS/2 keyboard which is what QEMU feeds us.
 */
const unsigned char atkbd_set2_keycode[512] = {

     0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
     0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
     0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
     0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
     0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
     0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
     0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
    82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,

      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
    173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
    159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
    157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
    226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
    110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,

};

const unsigned char atkbd_unxlate_table[128] = {

      0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
     21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
     35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
     50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
     11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
    114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
     71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
     19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110

};
#endif

/*
 * for (i = 0; i < 128; i++) {
 *     scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
 *     scancode2linux[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
 * }
 */
static const unsigned char scancode2linux[512] = {
      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
     80, 81, 82, 83, 99,  0, 86, 87, 88,117,  0,  0, 95,183,184,185,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     93,  0,  0, 89,  0,  0, 85, 91, 90, 92,  0, 94,  0,124,121,  0,

      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    165,  0,  0,  0,  0,  0,  0,  0,  0,163,  0,  0, 96, 97,  0,  0,
    113,140,164,  0,166,  0,  0,  0,  0,  0,255,  0,  0,  0,114,  0,
    115,  0,150,  0,  0, 98,255, 99,100,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,119,119,102,103,104,  0,105,112,106,118,107,
    108,109,110,111,  0,  0,  0,  0,  0,  0,  0,125,126,127,116,142,
      0,  0,  0,143,  0,217,156,173,128,159,158,157,155,226,  0,112,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
};

/* Send an event to the keyboard frontend driver */
static int xenfb_kbd_event(struct XenInput *xenfb,
			   union xenkbd_in_event *event)
{
    struct xenkbd_page *page = xenfb->c.page;
    uint32_t prod;

    if (xenfb->c.xendev.be_state != XenbusStateConnected)
	return 0;
    if (!page)
        return 0;

    prod = page->in_prod;
    if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
	errno = EAGAIN;
	return -1;
    }

    xen_mb();		/* ensure ring space available */
    XENKBD_IN_RING_REF(page, prod) = *event;
    xen_wmb();		/* ensure ring contents visible */
    page->in_prod = prod + 1;
    return xen_be_send_notify(&xenfb->c.xendev);
}

/* Send a keyboard (or mouse button) event */
static int xenfb_send_key(struct XenInput *xenfb, bool down, int keycode)
{
    union xenkbd_in_event event;

    memset(&event, 0, XENKBD_IN_EVENT_SIZE);
    event.type = XENKBD_TYPE_KEY;
    event.key.pressed = down ? 1 : 0;
    event.key.keycode = keycode;

    return xenfb_kbd_event(xenfb, &event);
}

/* Send a relative mouse movement event */
static int xenfb_send_motion(struct XenInput *xenfb,
			     int rel_x, int rel_y, int rel_z)
{
    union xenkbd_in_event event;

    memset(&event, 0, XENKBD_IN_EVENT_SIZE);
    event.type = XENKBD_TYPE_MOTION;
    event.motion.rel_x = rel_x;
    event.motion.rel_y = rel_y;
#if __XEN_LATEST_INTERFACE_VERSION__ >= 0x00030207
    event.motion.rel_z = rel_z;
#endif

    return xenfb_kbd_event(xenfb, &event);
}

/* Send an absolute mouse movement event */
static int xenfb_send_position(struct XenInput *xenfb,
			       int abs_x, int abs_y, int z)
{
    union xenkbd_in_event event;

    memset(&event, 0, XENKBD_IN_EVENT_SIZE);
    event.type = XENKBD_TYPE_POS;
    event.pos.abs_x = abs_x;
    event.pos.abs_y = abs_y;
#if __XEN_LATEST_INTERFACE_VERSION__ == 0x00030207
    event.pos.abs_z = z;
#endif
#if __XEN_LATEST_INTERFACE_VERSION__ >= 0x00030208
    event.pos.rel_z = z;
#endif

    return xenfb_kbd_event(xenfb, &event);
}

/*
 * Send a key event from the client to the guest OS
 * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
 * We have to turn this into a Linux Input layer keycode.
 *
 * Extra complexity from the fact that with extended scancodes
 * (like those produced by arrow keys) this method gets called
 * twice, but we only want to send a single event. So we have to
 * track the '0xe0' scancode state & collapse the extended keys
 * as needed.
 *
 * Wish we could just send scancodes straight to the guest which
 * already has code for dealing with this...
 */
static void xenfb_key_event(void *opaque, int scancode)
{
    struct XenInput *xenfb = opaque;
    int down = 1;

    if (scancode == 0xe0) {
	xenfb->extended = 1;
	return;
    } else if (scancode & 0x80) {
	scancode &= 0x7f;
	down = 0;
    }
    if (xenfb->extended) {
	scancode |= 0x80;
	xenfb->extended = 0;
    }
    xenfb_send_key(xenfb, down, scancode2linux[scancode]);
}

/*
 * Send a mouse event from the client to the guest OS
 *
 * The QEMU mouse can be in either relative, or absolute mode.
 * Movement is sent separately from button state, which has to
 * be encoded as virtual key events. We also don't actually get
 * given any button up/down events, so have to track changes in
 * the button state.
 */
static void xenfb_mouse_event(void *opaque,
			      int dx, int dy, int dz, int button_state)
{
    struct XenInput *xenfb = opaque;
    DisplaySurface *surface = qemu_console_surface(xenfb->c.con);
    int dw = surface_width(surface);
    int dh = surface_height(surface);
    int i;

    trace_xenfb_mouse_event(opaque, dx, dy, dz, button_state,
                            xenfb->abs_pointer_wanted);
    if (xenfb->abs_pointer_wanted)
	xenfb_send_position(xenfb,
			    dx * (dw - 1) / 0x7fff,
			    dy * (dh - 1) / 0x7fff,
			    dz);
    else
	xenfb_send_motion(xenfb, dx, dy, dz);

    for (i = 0 ; i < 8 ; i++) {
	int lastDown = xenfb->button_state & (1 << i);
	int down = button_state & (1 << i);
	if (down == lastDown)
	    continue;

	if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
	    return;
    }
    xenfb->button_state = button_state;
}

static int input_init(struct XenDevice *xendev)
{
    xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
    return 0;
}

static int input_initialise(struct XenDevice *xendev)
{
    struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
    int rc;

    if (!in->c.con) {
        xen_be_printf(xendev, 1, "ds not set (yet)\n");
        return -1;
    }

    rc = common_bind(&in->c);
    if (rc != 0)
	return rc;

    qemu_add_kbd_event_handler(xenfb_key_event, in);
    return 0;
}

static void input_connected(struct XenDevice *xendev)
{
    struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);

    if (xenstore_read_fe_int(xendev, "request-abs-pointer",
                             &in->abs_pointer_wanted) == -1) {
        in->abs_pointer_wanted = 0;
    }

    if (in->qmouse) {
        qemu_remove_mouse_event_handler(in->qmouse);
    }
    trace_xenfb_input_connected(xendev, in->abs_pointer_wanted);
    in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
					      in->abs_pointer_wanted,
					      "Xen PVFB Mouse");
}

static void input_disconnect(struct XenDevice *xendev)
{
    struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);

    if (in->qmouse) {
	qemu_remove_mouse_event_handler(in->qmouse);
	in->qmouse = NULL;
    }
    qemu_add_kbd_event_handler(NULL, NULL);
    common_unbind(&in->c);
}

static void input_event(struct XenDevice *xendev)
{
    struct XenInput *xenfb = container_of(xendev, struct XenInput, c.xendev);
    struct xenkbd_page *page = xenfb->c.page;

    /* We don't understand any keyboard events, so just ignore them. */
    if (page->out_prod == page->out_cons)
	return;
    page->out_cons = page->out_prod;
    xen_be_send_notify(&xenfb->c.xendev);
}

/* -------------------------------------------------------------------- */

static void xenfb_copy_mfns(int mode, int count, xen_pfn_t *dst, void *src)
{
    uint32_t *src32 = src;
    uint64_t *src64 = src;
    int i;

    for (i = 0; i < count; i++)
	dst[i] = (mode == 32) ? src32[i] : src64[i];
}

static int xenfb_map_fb(struct XenFB *xenfb)
{
    struct xenfb_page *page = xenfb->c.page;
    char *protocol = xenfb->c.xendev.protocol;
    int n_fbdirs;
    xen_pfn_t *pgmfns = NULL;
    xen_pfn_t *fbmfns = NULL;
    void *map, *pd;
    int mode, ret = -1;

    /* default to native */
    pd = page->pd;
    mode = sizeof(unsigned long) * 8;

    if (!protocol) {
	/*
	 * Undefined protocol, some guesswork needed.
	 *
	 * Old frontends which don't set the protocol use
	 * one page directory only, thus pd[1] must be zero.
	 * pd[1] of the 32bit struct layout and the lower
	 * 32 bits of pd[0] of the 64bit struct layout have
	 * the same location, so we can check that ...
	 */
	uint32_t *ptr32 = NULL;
	uint32_t *ptr64 = NULL;
#if defined(__i386__)
	ptr32 = (void*)page->pd;
	ptr64 = ((void*)page->pd) + 4;
#elif defined(__x86_64__)
	ptr32 = ((void*)page->pd) - 4;
	ptr64 = (void*)page->pd;
#endif
	if (ptr32) {
	    if (ptr32[1] == 0) {
		mode = 32;
		pd   = ptr32;
	    } else {
		mode = 64;
		pd   = ptr64;
	    }
	}
#if defined(__x86_64__)
    } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
	/* 64bit dom0, 32bit domU */
	mode = 32;
	pd   = ((void*)page->pd) - 4;
#elif defined(__i386__)
    } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
	/* 32bit dom0, 64bit domU */
	mode = 64;
	pd   = ((void*)page->pd) + 4;
#endif
    }

    if (xenfb->pixels) {
        munmap(xenfb->pixels, xenfb->fbpages * XC_PAGE_SIZE);
        xenfb->pixels = NULL;
    }

    xenfb->fbpages = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
    n_fbdirs = xenfb->fbpages * mode / 8;
    n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;

    pgmfns = g_malloc0(sizeof(xen_pfn_t) * n_fbdirs);
    fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages);

    xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
    map = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
			       PROT_READ, pgmfns, n_fbdirs);
    if (map == NULL)
	goto out;
    xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
    munmap(map, n_fbdirs * XC_PAGE_SIZE);

    xenfb->pixels = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
            PROT_READ, fbmfns, xenfb->fbpages);
    if (xenfb->pixels == NULL)
	goto out;

    ret = 0; /* all is fine */

out:
    g_free(pgmfns);
    g_free(fbmfns);
    return ret;
}

static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
			      int width, int height, int depth,
			      size_t fb_len, int offset, int row_stride)
{
    size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd);
    size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz;
    size_t fb_pages = pd_len * XC_PAGE_SIZE / mfn_sz;
    size_t fb_len_max = fb_pages * XC_PAGE_SIZE;
    int max_width, max_height;

    if (fb_len_lim > fb_len_max) {
	xen_be_printf(&xenfb->c.xendev, 0, "fb size limit %zu exceeds %zu, corrected\n",
		      fb_len_lim, fb_len_max);
	fb_len_lim = fb_len_max;
    }
    if (fb_len_lim && fb_len > fb_len_lim) {
	xen_be_printf(&xenfb->c.xendev, 0, "frontend fb size %zu limited to %zu\n",
		      fb_len, fb_len_lim);
	fb_len = fb_len_lim;
    }
    if (depth != 8 && depth != 16 && depth != 24 && depth != 32) {
	xen_be_printf(&xenfb->c.xendev, 0, "can't handle frontend fb depth %d\n",
		      depth);
	return -1;
    }
    if (row_stride <= 0 || row_stride > fb_len) {
	xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend stride %d\n", row_stride);
	return -1;
    }
    max_width = row_stride / (depth / 8);
    if (width < 0 || width > max_width) {
	xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend width %d limited to %d\n",
		      width, max_width);
	width = max_width;
    }
    if (offset < 0 || offset >= fb_len) {
	xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend offset %d (max %zu)\n",
		      offset, fb_len - 1);
	return -1;
    }
    max_height = (fb_len - offset) / row_stride;
    if (height < 0 || height > max_height) {
	xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend height %d limited to %d\n",
		      height, max_height);
	height = max_height;
    }
    xenfb->fb_len = fb_len;
    xenfb->row_stride = row_stride;
    xenfb->depth = depth;
    xenfb->width = width;
    xenfb->height = height;
    xenfb->offset = offset;
    xenfb->up_fullscreen = 1;
    xenfb->do_resize = 1;
    xen_be_printf(&xenfb->c.xendev, 1, "framebuffer %dx%dx%d offset %d stride %d\n",
		  width, height, depth, offset, row_stride);
    return 0;
}

/* A convenient function for munging pixels between different depths */
#define BLT(SRC_T,DST_T,RSB,GSB,BSB,RDB,GDB,BDB)                        \
    for (line = y ; line < (y+h) ; line++) {				\
	SRC_T *src = (SRC_T *)(xenfb->pixels				\
			       + xenfb->offset				\
			       + (line * xenfb->row_stride)		\
			       + (x * xenfb->depth / 8));		\
	DST_T *dst = (DST_T *)(data					\
			       + (line * linesize)			\
			       + (x * bpp / 8));			\
	int col;							\
	const int RSS = 32 - (RSB + GSB + BSB);				\
	const int GSS = 32 - (GSB + BSB);				\
	const int BSS = 32 - (BSB);					\
	const uint32_t RSM = (~0U) << (32 - RSB);			\
	const uint32_t GSM = (~0U) << (32 - GSB);			\
	const uint32_t BSM = (~0U) << (32 - BSB);			\
	const int RDS = 32 - (RDB + GDB + BDB);				\
	const int GDS = 32 - (GDB + BDB);				\
	const int BDS = 32 - (BDB);					\
	const uint32_t RDM = (~0U) << (32 - RDB);			\
	const uint32_t GDM = (~0U) << (32 - GDB);			\
	const uint32_t BDM = (~0U) << (32 - BDB);			\
	for (col = x ; col < (x+w) ; col++) {				\
	    uint32_t spix = *src;					\
	    *dst = (((spix << RSS) & RSM & RDM) >> RDS) |		\
		(((spix << GSS) & GSM & GDM) >> GDS) |			\
		(((spix << BSS) & BSM & BDM) >> BDS);			\
	    src = (SRC_T *) ((unsigned long) src + xenfb->depth / 8);	\
	    dst = (DST_T *) ((unsigned long) dst + bpp / 8);		\
	}								\
    }


/*
 * This copies data from the guest framebuffer region, into QEMU's
 * displaysurface. qemu uses 16 or 32 bpp.  In case the pv framebuffer
 * uses something else we must convert and copy, otherwise we can
 * supply the buffer directly and no thing here.
 */
static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
{
    DisplaySurface *surface = qemu_console_surface(xenfb->c.con);
    int line, oops = 0;
    int bpp = surface_bits_per_pixel(surface);
    int linesize = surface_stride(surface);
    uint8_t *data = surface_data(surface);

    if (!is_buffer_shared(surface)) {
        switch (xenfb->depth) {
        case 8:
            if (bpp == 16) {
                BLT(uint8_t, uint16_t,   3, 3, 2,   5, 6, 5);
            } else if (bpp == 32) {
                BLT(uint8_t, uint32_t,   3, 3, 2,   8, 8, 8);
            } else {
                oops = 1;
            }
            break;
        case 24:
            if (bpp == 16) {
                BLT(uint32_t, uint16_t,  8, 8, 8,   5, 6, 5);
            } else if (bpp == 32) {
                BLT(uint32_t, uint32_t,  8, 8, 8,   8, 8, 8);
            } else {
                oops = 1;
            }
            break;
        default:
            oops = 1;
	}
    }
    if (oops) /* should not happen */
        xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
                      __FUNCTION__, xenfb->depth, bpp);

    dpy_gfx_update(xenfb->c.con, x, y, w, h);
}

#ifdef XENFB_TYPE_REFRESH_PERIOD
static int xenfb_queue_full(struct XenFB *xenfb)
{
    struct xenfb_page *page = xenfb->c.page;
    uint32_t cons, prod;

    if (!page)
        return 1;

    prod = page->in_prod;
    cons = page->in_cons;
    return prod - cons == XENFB_IN_RING_LEN;
}

static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event)
{
    uint32_t prod;
    struct xenfb_page *page = xenfb->c.page;

    prod = page->in_prod;
    /* caller ensures !xenfb_queue_full() */
    xen_mb();                   /* ensure ring space available */
    XENFB_IN_RING_REF(page, prod) = *event;
    xen_wmb();                  /* ensure ring contents visible */
    page->in_prod = prod + 1;

    xen_be_send_notify(&xenfb->c.xendev);
}

static void xenfb_send_refresh_period(struct XenFB *xenfb, int period)
{
    union xenfb_in_event event;

    memset(&event, 0, sizeof(event));
    event.type = XENFB_TYPE_REFRESH_PERIOD;
    event.refresh_period.period = period;
    xenfb_send_event(xenfb, &event);
}
#endif

/*
 * Periodic update of display.
 * Also transmit the refresh interval to the frontend.
 *
 * Never ever do any qemu display operations
 * (resize, screen update) outside this function.
 * Our screen might be inactive.  When asked for
 * an update we know it is active.
 */
static void xenfb_update(void *opaque)
{
    struct XenFB *xenfb = opaque;
    DisplaySurface *surface;
    int i;

    if (xenfb->c.xendev.be_state != XenbusStateConnected)
        return;

    if (!xenfb->feature_update) {
	/* we don't get update notifications, thus use the
	 * sledge hammer approach ... */
	xenfb->up_fullscreen = 1;
    }

    /* resize if needed */
    if (xenfb->do_resize) {
        pixman_format_code_t format;

        xenfb->do_resize = 0;
        switch (xenfb->depth) {
        case 16:
        case 32:
            /* console.c supported depth -> buffer can be used directly */
            format = qemu_default_pixman_format(xenfb->depth, true);
            surface = qemu_create_displaysurface_from
                (xenfb->width, xenfb->height, format,
                 xenfb->row_stride, xenfb->pixels + xenfb->offset);
            break;
        default:
            /* we must convert stuff */
            surface = qemu_create_displaysurface(xenfb->width, xenfb->height);
            break;
        }
        dpy_gfx_replace_surface(xenfb->c.con, surface);
        xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n",
                      xenfb->width, xenfb->height, xenfb->depth,
                      is_buffer_shared(surface) ? " (shared)" : "");
        xenfb->up_fullscreen = 1;
    }

    /* run queued updates */
    if (xenfb->up_fullscreen) {
	xen_be_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
	xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
    } else if (xenfb->up_count) {
	xen_be_printf(&xenfb->c.xendev, 3, "update: %d rects\n", xenfb->up_count);
	for (i = 0; i < xenfb->up_count; i++)
	    xenfb_guest_copy(xenfb,
			     xenfb->up_rects[i].x,
			     xenfb->up_rects[i].y,
			     xenfb->up_rects[i].w,
			     xenfb->up_rects[i].h);
    } else {
	xen_be_printf(&xenfb->c.xendev, 3, "update: nothing\n");
    }
    xenfb->up_count = 0;
    xenfb->up_fullscreen = 0;
}

static void xenfb_update_interval(void *opaque, uint64_t interval)
{
    struct XenFB *xenfb = opaque;

    if (xenfb->feature_update) {
#ifdef XENFB_TYPE_REFRESH_PERIOD
        if (xenfb_queue_full(xenfb)) {
            return;
        }
        xenfb_send_refresh_period(xenfb, interval);
#endif
    }
}

/* QEMU display state changed, so refresh the framebuffer copy */
static void xenfb_invalidate(void *opaque)
{
    struct XenFB *xenfb = opaque;
    xenfb->up_fullscreen = 1;
}

static void xenfb_handle_events(struct XenFB *xenfb)
{
    uint32_t prod, cons;
    struct xenfb_page *page = xenfb->c.page;

    prod = page->out_prod;
    if (prod == page->out_cons)
	return;
    xen_rmb();		/* ensure we see ring contents up to prod */
    for (cons = page->out_cons; cons != prod; cons++) {
	union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
	int x, y, w, h;

	switch (event->type) {
	case XENFB_TYPE_UPDATE:
	    if (xenfb->up_count == UP_QUEUE)
		xenfb->up_fullscreen = 1;
	    if (xenfb->up_fullscreen)
		break;
	    x = MAX(event->update.x, 0);
	    y = MAX(event->update.y, 0);
	    w = MIN(event->update.width, xenfb->width - x);
	    h = MIN(event->update.height, xenfb->height - y);
	    if (w < 0 || h < 0) {
                xen_be_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");
		break;
	    }
	    if (x != event->update.x ||
                y != event->update.y ||
		w != event->update.width ||
		h != event->update.height) {
                xen_be_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");
	    }
	    if (w == xenfb->width && h > xenfb->height / 2) {
		/* scroll detector: updated more than 50% of the lines,
		 * don't bother keeping track of the rectangles then */
		xenfb->up_fullscreen = 1;
	    } else {
		xenfb->up_rects[xenfb->up_count].x = x;
		xenfb->up_rects[xenfb->up_count].y = y;
		xenfb->up_rects[xenfb->up_count].w = w;
		xenfb->up_rects[xenfb->up_count].h = h;
		xenfb->up_count++;
	    }
	    break;
#ifdef XENFB_TYPE_RESIZE
	case XENFB_TYPE_RESIZE:
	    if (xenfb_configure_fb(xenfb, xenfb->fb_len,
				   event->resize.width,
				   event->resize.height,
				   event->resize.depth,
				   xenfb->fb_len,
				   event->resize.offset,
				   event->resize.stride) < 0)
		break;
	    xenfb_invalidate(xenfb);
	    break;
#endif
	}
    }
    xen_mb();		/* ensure we're done with ring contents */
    page->out_cons = cons;
}

static int fb_init(struct XenDevice *xendev)
{
#ifdef XENFB_TYPE_RESIZE
    xenstore_write_be_int(xendev, "feature-resize", 1);
#endif
    return 0;
}

static int fb_initialise(struct XenDevice *xendev)
{
    struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
    struct xenfb_page *fb_page;
    int videoram;
    int rc;

    if (xenstore_read_fe_int(xendev, "videoram", &videoram) == -1)
	videoram = 0;

    rc = common_bind(&fb->c);
    if (rc != 0)
	return rc;

    fb_page = fb->c.page;
    rc = xenfb_configure_fb(fb, videoram * 1024 * 1024U,
			    fb_page->width, fb_page->height, fb_page->depth,
			    fb_page->mem_length, 0, fb_page->line_length);
    if (rc != 0)
	return rc;

    rc = xenfb_map_fb(fb);
    if (rc != 0)
	return rc;

#if 0  /* handled in xen_init_display() for now */
    if (!fb->have_console) {
        fb->c.ds = graphic_console_init(xenfb_update,
                                        xenfb_invalidate,
                                        NULL,
                                        NULL,
                                        fb);
        fb->have_console = 1;
    }
#endif

    if (xenstore_read_fe_int(xendev, "feature-update", &fb->feature_update) == -1)
	fb->feature_update = 0;
    if (fb->feature_update)
	xenstore_write_be_int(xendev, "request-update", 1);

    xen_be_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
		  fb->feature_update, videoram);
    return 0;
}

static void fb_disconnect(struct XenDevice *xendev)
{
    struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);

    /*
     * FIXME: qemu can't un-init gfx display (yet?).
     *   Replacing the framebuffer with anonymous shared memory
     *   instead.  This releases the guest pages and keeps qemu happy.
     */
    fb->pixels = mmap(fb->pixels, fb->fbpages * XC_PAGE_SIZE,
                      PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
                      -1, 0);
    if (fb->pixels == MAP_FAILED) {
        xen_be_printf(xendev, 0,
                "Couldn't replace the framebuffer with anonymous memory errno=%d\n",
                errno);
    }
    common_unbind(&fb->c);
    fb->feature_update = 0;
    fb->bug_trigger    = 0;
}

static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
{
    struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);

    /*
     * Set state to Connected *again* once the frontend switched
     * to connected.  We must trigger the watch a second time to
     * workaround a frontend bug.
     */
    if (fb->bug_trigger == 0 && strcmp(node, "state") == 0 &&
        xendev->fe_state == XenbusStateConnected &&
        xendev->be_state == XenbusStateConnected) {
        xen_be_printf(xendev, 2, "re-trigger connected (frontend bug)\n");
        xen_be_set_state(xendev, XenbusStateConnected);
        fb->bug_trigger = 1; /* only once */
    }
}

static void fb_event(struct XenDevice *xendev)
{
    struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);

    xenfb_handle_events(xenfb);
    xen_be_send_notify(&xenfb->c.xendev);
}

/* -------------------------------------------------------------------- */

struct XenDevOps xen_kbdmouse_ops = {
    .size       = sizeof(struct XenInput),
    .init       = input_init,
    .initialise = input_initialise,
    .connected  = input_connected,
    .disconnect = input_disconnect,
    .event      = input_event,
};

struct XenDevOps xen_framebuffer_ops = {
    .size       = sizeof(struct XenFB),
    .init       = fb_init,
    .initialise = fb_initialise,
    .disconnect = fb_disconnect,
    .event      = fb_event,
    .frontend_changed = fb_frontend_changed,
};

static const GraphicHwOps xenfb_ops = {
    .invalidate  = xenfb_invalidate,
    .gfx_update  = xenfb_update,
    .update_interval = xenfb_update_interval,
};

/*
 * FIXME/TODO: Kill this.
 * Temporary needed while DisplayState reorganization is in flight.
 */
void xen_init_display(int domid)
{
    struct XenDevice *xfb, *xin;
    struct XenFB *fb;
    struct XenInput *in;
    int i = 0;

wait_more:
    i++;
    main_loop_wait(true);
    xfb = xen_be_find_xendev("vfb", domid, 0);
    xin = xen_be_find_xendev("vkbd", domid, 0);
    if (!xfb || !xin) {
        if (i < 256) {
            usleep(10000);
            goto wait_more;
        }
        xen_be_printf(NULL, 1, "displaystate setup failed\n");
        return;
    }

    /* vfb */
    fb = container_of(xfb, struct XenFB, c.xendev);
    fb->c.con = graphic_console_init(NULL, 0, &xenfb_ops, fb);
    fb->have_console = 1;

    /* vkbd */
    in = container_of(xin, struct XenInput, c.xendev);
    in->c.con = fb->c.con;

    /* retry ->init() */
    xen_be_check_state(xin);
    xen_be_check_state(xfb);
}
