/*
 *  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 "qemu/osdep.h"
#include "qemu/units.h"

#include "ui/input.h"
#include "ui/console.h"
#include "hw/xen/xen-legacy-backend.h"

#include "hw/xen/interface/io/fbif.h"
#include "hw/xen/interface/io/kbdif.h"
#include "hw/xen/interface/io/protocols.h"

#include "trace.h"

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

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

struct common {
    struct XenLegacyDevice  xendev;  /* must be first */
    void              *page;
};

struct XenInput {
    struct common c;
    int abs_pointer_wanted; /* Whether guest supports absolute pointer */
    int raw_pointer_wanted; /* Whether guest supports raw (unscaled) pointer */
    QemuInputHandlerState *qkbd;
    QemuInputHandlerState *qmou;
    int axis[INPUT_AXIS__MAX];
    int wheel;
};

#define UP_QUEUE 8

struct XenFB {
    struct common     c;
    QemuConsole       *con;
    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               do_resize;

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

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

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

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

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

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

    xen_be_bind_evtchn(&c->xendev);
    xen_pv_printf(&c->xendev, 1,
                  "ring mfn %"PRI_xen_pfn", 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_pv_unbind_evtchn(&c->xendev);
    if (c->page) {
        qemu_xen_foreignmem_unmap(c->page, 1);
        c->page = NULL;
    }
}

/* -------------------------------------------------------------------- */
/* 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_pv_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;
    event.motion.rel_z = rel_z;

    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;
    event.pos.rel_z = z;

    return xenfb_kbd_event(xenfb, &event);
}

/*
 * Send a key event from the client to the guest OS
 * QEMU gives us a QCode.
 * We have to turn this into a Linux Input layer keycode.
 *
 * Wish we could just send scancodes straight to the guest which
 * already has code for dealing with this...
 */
static void xenfb_key_event(DeviceState *dev, QemuConsole *src,
                            InputEvent *evt)
{
    struct XenInput *xenfb = (struct XenInput *)dev;
    InputKeyEvent *key = evt->u.key.data;
    int qcode = qemu_input_key_value_to_qcode(key->key);
    int lnx;

    if (qcode < qemu_input_map_qcode_to_linux_len) {
        lnx = qemu_input_map_qcode_to_linux[qcode];

        if (lnx) {
            trace_xenfb_key_event(xenfb, lnx, key->down);
            xenfb_send_key(xenfb, key->down, lnx);
        }
    }
}

/*
 * 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(DeviceState *dev, QemuConsole *src,
                              InputEvent *evt)
{
    struct XenInput *xenfb = (struct XenInput *)dev;
    InputBtnEvent *btn;
    InputMoveEvent *move;
    QemuConsole *con;
    DisplaySurface *surface;
    int scale;

    switch (evt->type) {
    case INPUT_EVENT_KIND_BTN:
        btn = evt->u.btn.data;
        switch (btn->button) {
        case INPUT_BUTTON_LEFT:
            xenfb_send_key(xenfb, btn->down, BTN_LEFT);
            break;
        case INPUT_BUTTON_RIGHT:
            xenfb_send_key(xenfb, btn->down, BTN_LEFT + 1);
            break;
        case INPUT_BUTTON_MIDDLE:
            xenfb_send_key(xenfb, btn->down, BTN_LEFT + 2);
            break;
        case INPUT_BUTTON_WHEEL_UP:
            if (btn->down) {
                xenfb->wheel--;
            }
            break;
        case INPUT_BUTTON_WHEEL_DOWN:
            if (btn->down) {
                xenfb->wheel++;
            }
            break;
        default:
            break;
        }
        break;

    case INPUT_EVENT_KIND_ABS:
        move = evt->u.abs.data;
        if (xenfb->raw_pointer_wanted) {
            xenfb->axis[move->axis] = move->value;
        } else {
            con = qemu_console_lookup_by_index(0);
            if (!con) {
                xen_pv_printf(&xenfb->c.xendev, 0, "No QEMU console available");
                return;
            }
            surface = qemu_console_surface(con);
            switch (move->axis) {
            case INPUT_AXIS_X:
                scale = surface_width(surface) - 1;
                break;
            case INPUT_AXIS_Y:
                scale = surface_height(surface) - 1;
                break;
            default:
                scale = 0x8000;
                break;
            }
            xenfb->axis[move->axis] = move->value * scale / 0x7fff;
        }
        break;

    case INPUT_EVENT_KIND_REL:
        move = evt->u.rel.data;
        xenfb->axis[move->axis] += move->value;
        break;

    default:
        break;
    }
}

static void xenfb_mouse_sync(DeviceState *dev)
{
    struct XenInput *xenfb = (struct XenInput *)dev;

    trace_xenfb_mouse_event(xenfb, xenfb->axis[INPUT_AXIS_X],
                            xenfb->axis[INPUT_AXIS_Y],
                            xenfb->wheel, 0,
                            xenfb->abs_pointer_wanted);
    if (xenfb->abs_pointer_wanted) {
        xenfb_send_position(xenfb, xenfb->axis[INPUT_AXIS_X],
                            xenfb->axis[INPUT_AXIS_Y],
                            xenfb->wheel);
    } else {
        xenfb_send_motion(xenfb, xenfb->axis[INPUT_AXIS_X],
                          xenfb->axis[INPUT_AXIS_Y],
                          xenfb->wheel);
        xenfb->axis[INPUT_AXIS_X] = 0;
        xenfb->axis[INPUT_AXIS_Y] = 0;
    }
    xenfb->wheel = 0;
}

static QemuInputHandler xenfb_keyboard = {
    .name  = "Xen PV Keyboard",
    .mask  = INPUT_EVENT_MASK_KEY,
    .event = xenfb_key_event,
};

static QemuInputHandler xenfb_abs_mouse = {
    .name  = "Xen PV Mouse",
    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
    .event = xenfb_mouse_event,
    .sync  = xenfb_mouse_sync,
};

static QemuInputHandler xenfb_rel_mouse = {
    .name  = "Xen PV Mouse",
    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
    .event = xenfb_mouse_event,
    .sync  = xenfb_mouse_sync,
};

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

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

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

    return 0;
}

static void input_connected(struct XenLegacyDevice *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 (xenstore_read_fe_int(xendev, "request-raw-pointer",
                             &in->raw_pointer_wanted) == -1) {
        in->raw_pointer_wanted = 0;
    }
    if (in->raw_pointer_wanted && in->abs_pointer_wanted == 0) {
        xen_pv_printf(xendev, 0, "raw pointer set without abs pointer");
    }

    if (in->qkbd) {
        qemu_input_handler_unregister(in->qkbd);
    }
    if (in->qmou) {
        qemu_input_handler_unregister(in->qmou);
    }
    trace_xenfb_input_connected(xendev, in->abs_pointer_wanted);

    in->qkbd = qemu_input_handler_register((DeviceState *)in, &xenfb_keyboard);
    in->qmou = qemu_input_handler_register((DeviceState *)in,
               in->abs_pointer_wanted ? &xenfb_abs_mouse : &xenfb_rel_mouse);

    if (in->raw_pointer_wanted) {
        qemu_input_handler_activate(in->qkbd);
        qemu_input_handler_activate(in->qmou);
    }
}

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

    if (in->qkbd) {
        qemu_input_handler_unregister(in->qkbd);
        in->qkbd = NULL;
    }
    if (in->qmou) {
        qemu_input_handler_unregister(in->qmou);
        in->qmou = NULL;
    }
    common_unbind(&in->c);
}

static void input_event(struct XenLegacyDevice *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_pv_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 = DIV_ROUND_UP(xenfb->fb_len, XC_PAGE_SIZE);
    n_fbdirs = xenfb->fbpages * mode / 8;
    n_fbdirs = DIV_ROUND_UP(n_fbdirs, XC_PAGE_SIZE);

    pgmfns = g_new0(xen_pfn_t, n_fbdirs);
    fbmfns = g_new0(xen_pfn_t, xenfb->fbpages);

    xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
    map = qemu_xen_foreignmem_map(xenfb->c.xendev.dom, NULL, PROT_READ,
                                  n_fbdirs, pgmfns, NULL);
    if (map == NULL)
        goto out;
    xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
    qemu_xen_foreignmem_unmap(map, n_fbdirs);

    xenfb->pixels = qemu_xen_foreignmem_map(xenfb->c.xendev.dom, NULL,
                                            PROT_READ, xenfb->fbpages,
                                            fbmfns, NULL);
    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_field(struct xenfb_page, pd[0]);
    size_t pd_len = sizeof_field(struct xenfb_page, 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_pv_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_pv_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_pv_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_pv_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_pv_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_pv_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_pv_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_pv_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->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_pv_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
                      __func__, xenfb->depth, bpp);

    dpy_gfx_update(xenfb->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_pv_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->con, surface);
        xen_pv_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_pv_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
        xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
    } else if (xenfb->up_count) {
        xen_pv_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_pv_printf(&xenfb->c.xendev, 3, "update: nothing\n");
    }
    xenfb->up_count = 0;
    xenfb->up_fullscreen = 0;
}

static void xenfb_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
{
    struct XenFB *xenfb = opaque;
    uint32_t refresh_rate;

    if (xenfb->feature_update) {
#ifdef XENFB_TYPE_REFRESH_PERIOD
        if (xenfb_queue_full(xenfb)) {
            return;
        }

        refresh_rate = info->refresh_rate;
        if (!refresh_rate) {
            refresh_rate = 75;
        }

        /* T = 1 / f = 1 [s*Hz] / f = 1000*1000 [ms*mHz] / f */
        xenfb_send_refresh_period(xenfb, 1000 * 1000 / refresh_rate);
#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, out_cons;
    struct xenfb_page *page = xenfb->c.page;

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

        switch (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_pv_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_pv_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 XenLegacyDevice *xendev)
{
#ifdef XENFB_TYPE_RESIZE
    xenstore_write_be_int(xendev, "feature-resize", 1);
#endif
    return 0;
}

static int fb_initialise(struct XenLegacyDevice *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 * MiB,
                            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;

    fb->con = graphic_console_init(NULL, 0, &xenfb_ops, fb);

    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_pv_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
                  fb->feature_update, videoram);
    return 0;
}

static void fb_disconnect(struct XenLegacyDevice *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.
     */
    qemu_xen_foreignmem_unmap(fb->pixels, fb->fbpages);
    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_pv_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 XenLegacyDevice *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_pv_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 XenLegacyDevice *xendev)
{
    struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);

    xenfb_handle_events(xenfb);
    xen_pv_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,
    .ui_info     = xenfb_ui_info,
};
