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; }
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; }
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; }
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); } }
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); } }