void curses_display_init(DisplayState *ds, int full_screen)
{
    DisplayChangeListener *dcl;
#ifndef _WIN32
    if (!isatty(1)) {
        fprintf(stderr, "We need a terminal output\n");
        exit(1);
    }
#endif

    curses_setup();
    curses_keyboard_setup();
    atexit(curses_atexit);

#ifndef _WIN32
#if defined(SIGWINCH) && defined(KEY_RESIZE)
    /* some curses implementations provide a handler, but we
     * want to be sure this is handled regardless of the library */
    signal(SIGWINCH, curses_winch_handler);
#endif
#endif

    dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
    dcl->dpy_update = curses_update;
    dcl->dpy_resize = curses_resize;
    dcl->dpy_refresh = curses_refresh;
    dcl->dpy_text_cursor = curses_cursor_position;
    register_displaychangelistener(ds, dcl);
    qemu_free_displaysurface(ds);
    ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen);

    invalidate = 1;
}
Example #2
0
static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
{
    VGACommonState *vga = &qxl->vga;
    int i;

    if (qxl->guest_primary.resized) {
        qxl->guest_primary.resized = 0;
        qxl->guest_primary.data = qxl_phys2virt(qxl,
                                                qxl->guest_primary.surface.mem,
                                                MEMSLOT_GROUP_GUEST);
        if (!qxl->guest_primary.data) {
            return;
        }
        qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
        qxl->num_dirty_rects = 1;
        trace_qxl_render_guest_primary_resized(
            qxl->guest_primary.surface.width,
            qxl->guest_primary.surface.height,
            qxl->guest_primary.qxl_stride,
            qxl->guest_primary.bytes_pp,
            qxl->guest_primary.bits_pp);
        if (qxl->guest_primary.qxl_stride > 0) {
            qemu_free_displaysurface(vga->ds);
            vga->ds->surface = qemu_create_displaysurface_from
                               (qxl->guest_primary.surface.width,
                                qxl->guest_primary.surface.height,
                                qxl->guest_primary.bits_pp,
                                qxl->guest_primary.abs_stride,
                                qxl->guest_primary.data);
        } else {
            qemu_resize_displaysurface(vga->ds,
                                       qxl->guest_primary.surface.width,
                                       qxl->guest_primary.surface.height);
        }
        dpy_resize(vga->ds);
    }

    if (!qxl->guest_primary.data) {
        return;
    }
    for (i = 0; i < qxl->num_dirty_rects; i++) {
        if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
            break;
        }
        if (qxl->dirty[i].left < 0 ||
                qxl->dirty[i].top < 0 ||
                qxl->dirty[i].left > qxl->dirty[i].right ||
                qxl->dirty[i].top > qxl->dirty[i].bottom ||
                qxl->dirty[i].right > qxl->guest_primary.surface.width ||
                qxl->dirty[i].bottom > qxl->guest_primary.surface.height) {
            continue;
        }
        qxl_blit(qxl, qxl->dirty+i);
        dpy_update(vga->ds,
                   qxl->dirty[i].left, qxl->dirty[i].top,
                   qxl->dirty[i].right - qxl->dirty[i].left,
                   qxl->dirty[i].bottom - qxl->dirty[i].top);
    }
    qxl->num_dirty_rects = 0;
}
Example #3
0
static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
{
    VGACommonState *vga = &qxl->vga;
    int i;

    if (qxl->guest_primary.resized) {
        qxl->guest_primary.resized = 0;
        qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
        qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
        qxl->num_dirty_rects = 1;
        trace_qxl_render_guest_primary_resized(
               qxl->guest_primary.surface.width,
               qxl->guest_primary.surface.height,
               qxl->guest_primary.qxl_stride,
               qxl->guest_primary.bytes_pp,
               qxl->guest_primary.bits_pp);
        if (qxl->guest_primary.qxl_stride > 0) {
            qemu_free_displaysurface(vga->ds);
            vga->ds->surface = qemu_create_displaysurface_from
                (qxl->guest_primary.surface.width,
                 qxl->guest_primary.surface.height,
                 qxl->guest_primary.bits_pp,
                 qxl->guest_primary.abs_stride,
                 qxl->guest_primary.data,
                 false);
        } else {
            qemu_resize_displaysurface(vga->ds,
                    qxl->guest_primary.surface.width,
                    qxl->guest_primary.surface.height);
        }
        dpy_gfx_resize(vga->ds);
    }
    for (i = 0; i < qxl->num_dirty_rects; i++) {
        if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
            break;
        }
        qxl_blit(qxl, qxl->dirty+i);
        dpy_gfx_update(vga->ds,
                       qxl->dirty[i].left, qxl->dirty[i].top,
                       qxl->dirty[i].right - qxl->dirty[i].left,
                       qxl->dirty[i].bottom - qxl->dirty[i].top);
    }
    qxl->num_dirty_rects = 0;
}
/*
 * 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;
    struct DisplayChangeListener *l;
    int i;

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

    if (xenfb->feature_update) {
#ifdef XENFB_TYPE_REFRESH_PERIOD
        int period = 99999999;
        int idle = 1;

	if (xenfb_queue_full(xenfb))
	    return;

        for (l = xenfb->c.ds->listeners; l != NULL; l = l->next) {
            if (l->idle)
                continue;
            idle = 0;
            if (!l->gui_timer_interval) {
                if (period > GUI_REFRESH_INTERVAL)
                    period = GUI_REFRESH_INTERVAL;
            } else {
                if (period > l->gui_timer_interval)
                    period = l->gui_timer_interval;
            }
        }
        if (idle)
	    period = XENFB_NO_REFRESH;

	if (xenfb->refresh_period != period) {
	    xenfb_send_refresh_period(xenfb, period);
	    xenfb->refresh_period = period;
            xen_be_printf(&xenfb->c.xendev, 1, "refresh period: %d\n", period);
	}
#else
	; /* nothing */
#endif
    } else {
	/* we don't get update notifications, thus use the
	 * sledge hammer approach ... */
	xenfb->up_fullscreen = 1;
    }

    /* resize if needed */
    if (xenfb->do_resize) {
        xenfb->do_resize = 0;
        switch (xenfb->depth) {
        case 16:
        case 32:
            /* console.c supported depth -> buffer can be used directly */
            qemu_free_displaysurface(xenfb->c.ds);
            xenfb->c.ds->surface = qemu_create_displaysurface_from
                (xenfb->width, xenfb->height, xenfb->depth,
                 xenfb->row_stride, xenfb->pixels + xenfb->offset);
            break;
        default:
            /* we must convert stuff */
            qemu_resize_displaysurface(xenfb->c.ds, xenfb->width, xenfb->height);
            break;
        }
        xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n",
                      xenfb->width, xenfb->height, xenfb->depth,
                      is_buffer_shared(xenfb->c.ds->surface) ? " (shared)" : "");
        dpy_resize(xenfb->c.ds);
        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;
}
Example #5
0
void qxl_render_update(PCIQXLDevice *qxl)
{
    VGACommonState *vga = &qxl->vga;
    QXLRect dirty[32], update;
    void *ptr;
    int i;

    if (qxl->guest_primary.resized) {
        qxl->guest_primary.resized = 0;

        if (qxl->guest_primary.flipped) {
            qemu_free(qxl->guest_primary.flipped);
            qxl->guest_primary.flipped = NULL;
        }
        qemu_free_displaysurface(vga->ds);

        qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset);
        if (qxl->guest_primary.stride < 0) {
            /* spice surface is upside down -> need extra buffer to flip */
            qxl->guest_primary.stride = -qxl->guest_primary.stride;
            qxl->guest_primary.flipped = qemu_malloc(qxl->guest_primary.surface.width *
                                                     qxl->guest_primary.stride);
            ptr = qxl->guest_primary.flipped;
        } else {
            ptr = qxl->guest_primary.data;
        }
        dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n",
               __FUNCTION__,
               qxl->guest_primary.surface.width,
               qxl->guest_primary.surface.height,
               qxl->guest_primary.stride,
               qxl->guest_primary.bytes_pp,
               qxl->guest_primary.bits_pp,
               qxl->guest_primary.flipped ? "yes" : "no");
        vga->ds->surface =
            qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
                                            qxl->guest_primary.surface.height,
                                            qxl->guest_primary.bits_pp,
                                            qxl->guest_primary.stride,
                                            ptr);
        dpy_resize(vga->ds);
    }

    if (!qxl->guest_primary.commands) {
        return;
    }
    qxl->guest_primary.commands = 0;

    update.left   = 0;
    update.right  = qxl->guest_primary.surface.width;
    update.top    = 0;
    update.bottom = qxl->guest_primary.surface.height;

    memset(dirty, 0, sizeof(dirty));
    qxl->ssd.worker->update_area(qxl->ssd.worker, 0, &update,
                                 dirty, ARRAY_SIZE(dirty), 1);

    for (i = 0; i < ARRAY_SIZE(dirty); i++) {
        if (qemu_spice_rect_is_empty(dirty+i)) {
            break;
        }
        if (qxl->guest_primary.flipped) {
            qxl_flip(qxl, dirty+i);
        }
        dpy_update(vga->ds,
                   dirty[i].left, dirty[i].top,
                   dirty[i].right - dirty[i].left,
                   dirty[i].bottom - dirty[i].top);
    }
}
Example #6
0
void qxl_render_update(PCIQXLDevice *qxl)
{
    VGACommonState *vga = &qxl->vga;
    QXLRect dirty[32], update;
    void *ptr;
    int i, redraw = 0;

    if (!is_buffer_shared(vga->ds->surface)) {
        dprint(qxl, 1, "%s: restoring shared displaysurface\n", __func__);
        qxl->guest_primary.resized++;
        qxl->guest_primary.commands++;
        redraw = 1;
    }

    if (qxl->guest_primary.resized) {
        qxl->guest_primary.resized = 0;

        if (qxl->guest_primary.flipped) {
            g_free(qxl->guest_primary.flipped);
            qxl->guest_primary.flipped = NULL;
        }
        qemu_free_displaysurface(vga->ds);

        qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
        if (qxl->guest_primary.qxl_stride < 0) {
            /* spice surface is upside down -> need extra buffer to flip */
            qxl->guest_primary.flipped =
                g_malloc(qxl->guest_primary.surface.width *
                         qxl->guest_primary.abs_stride);
            ptr = qxl->guest_primary.flipped;
        } else {
            ptr = qxl->guest_primary.data;
        }
        dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n",
               __FUNCTION__,
               qxl->guest_primary.surface.width,
               qxl->guest_primary.surface.height,
               qxl->guest_primary.qxl_stride,
               qxl->guest_primary.bytes_pp,
               qxl->guest_primary.bits_pp,
               qxl->guest_primary.flipped ? "yes" : "no");
        vga->ds->surface =
            qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
                                            qxl->guest_primary.surface.height,
                                            qxl->guest_primary.bits_pp,
                                            qxl->guest_primary.abs_stride,
                                            ptr);
        dpy_resize(vga->ds);
    }

    if (!qxl->guest_primary.commands) {
        return;
    }
    qxl->guest_primary.commands = 0;

    update.left   = 0;
    update.right  = qxl->guest_primary.surface.width;
    update.top    = 0;
    update.bottom = qxl->guest_primary.surface.height;

    memset(dirty, 0, sizeof(dirty));
    qxl_spice_update_area(qxl, 0, &update,
                          dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
    if (redraw) {
        memset(dirty, 0, sizeof(dirty));
        dirty[0] = update;
    }

    for (i = 0; i < ARRAY_SIZE(dirty); i++) {
        if (qemu_spice_rect_is_empty(dirty+i)) {
            break;
        }
        if (qxl->guest_primary.flipped) {
            qxl_flip(qxl, dirty+i);
        }
        dpy_update(vga->ds,
                   dirty[i].left, dirty[i].top,
                   dirty[i].right - dirty[i].left,
                   dirty[i].bottom - dirty[i].top);
    }
}