DisplayState *ds = s->ds;
active_console = s;
if (ds_get_bits_per_pixel(s->ds)) {
- ds->surface = qemu_resize_displaysurface(ds->surface, s->g_width,
+ ds->surface = qemu_resize_displaysurface(ds, s->g_width,
s->g_height, 32, 4 * s->g_width);
} else {
s->ds->surface->width = s->width;
ds = (DisplayState *) qemu_mallocz(sizeof(DisplayState));
if (ds == NULL)
return NULL;
- ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
+ ds->allocator = &default_allocator;
+ ds->surface = qemu_create_displaysurface(ds, 640, 480, 32, 640 * 4);
s = new_console(ds, GRAPHIC_CONSOLE);
if (s == NULL) {
- qemu_free_displaysurface(ds->surface);
+ qemu_free_displaysurface(ds);
qemu_free(ds);
return NULL;
}
s->g_width = width;
s->g_height = height;
if (is_graphic_console()) {
- ds->surface = qemu_resize_displaysurface(ds->surface, width, height, 32, 4 * width);
+ ds->surface = qemu_resize_displaysurface(ds, width, height, 32, 4 * width);
dpy_resize(ds);
}
}
return pf;
}
-DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize)
+DisplaySurface* defaultallocator_create_displaysurface(int width, int height, int bpp, int linesize)
{
DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
if (surface == NULL) {
- fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
+ fprintf(stderr, "defaultallocator_create_displaysurface: malloc failed\n");
exit(1);
}
#endif
surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height);
if (surface->data == NULL) {
- fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
+ fprintf(stderr, "defaultallocator_create_displaysurface: malloc failed\n");
exit(1);
}
return surface;
}
-DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
+DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
int width, int height, int bpp, int linesize)
{
surface->width = width;
else
surface->data = (uint8_t*) qemu_malloc(surface->linesize * surface->height);
if (surface->data == NULL) {
- fprintf(stderr, "qemu_resize_displaysurface: malloc failed\n");
+ fprintf(stderr, "defaultallocator_resize_displaysurface: malloc failed\n");
exit(1);
}
#ifdef WORDS_BIGENDIAN
return surface;
}
-void qemu_free_displaysurface(DisplaySurface *surface)
+void defaultallocator_free_displaysurface(DisplaySurface *surface)
{
if (surface == NULL)
return;
struct DisplayChangeListener *next;
};
+struct DisplayAllocator {
+ DisplaySurface* (*create_displaysurface)(int width, int height, int bpp, int linesize);
+ DisplaySurface* (*resize_displaysurface)(DisplaySurface *surface,
+ int width, int height, int bpp, int linesize);
+ void (*free_displaysurface)(DisplaySurface *surface);
+};
+
struct DisplayState {
struct DisplaySurface *surface;
void *opaque;
struct QEMUTimer *gui_timer;
+ struct DisplayAllocator* allocator;
struct DisplayChangeListener* listeners;
void (*mouse_set)(int x, int y, int on);
void register_displaystate(DisplayState *ds);
DisplayState *get_displaystate(void);
-DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize);
-DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
- int width, int height, int bpp, int linesize);
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data);
-void qemu_free_displaysurface(DisplaySurface *surface);
PixelFormat qemu_different_endianness_pixelformat(int bpp);
PixelFormat qemu_default_pixelformat(int bpp);
+extern struct DisplayAllocator default_allocator;
+DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da);
+DisplaySurface* defaultallocator_create_displaysurface(int width, int height, int bpp, int linesize);
+DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
+ int width, int height, int bpp, int linesize);
+void defaultallocator_free_displaysurface(DisplaySurface *surface);
+
+static inline DisplaySurface* qemu_create_displaysurface(DisplayState *ds, int width, int height, int bpp, int linesize)
+{
+ return ds->allocator->create_displaysurface(width, height, bpp, linesize);
+}
+
+static inline DisplaySurface* qemu_resize_displaysurface(DisplayState *ds, int width, int height, int bpp, int linesize)
+{
+ return ds->allocator->resize_displaysurface(ds->surface, width, height, bpp, linesize);
+}
+
+static inline void qemu_free_displaysurface(DisplayState *ds)
+{
+ ds->allocator->free_displaysurface(ds->surface);
+}
+
static inline int is_buffer_shared(DisplaySurface *surface)
{
return (!(surface->flags & QEMU_ALLOCATED_FLAG));
dcl->dpy_refresh = curses_refresh;
dcl->dpy_text_cursor = curses_cursor_position;
register_displaychangelistener(ds, dcl);
- qemu_free_displaysurface(ds->surface);
+ qemu_free_displaysurface(ds);
ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen);
invalidate = 1;
/* FIXME: We shouldn't really be doing this here. The LCD controller
will set the size once configured, so this just sets an initial
size until the guest activates the display. */
- ds->surface = qemu_resize_displaysurface(ds->surface, 800, 480, 32, 4 * 800);
+ ds->surface = qemu_resize_displaysurface(ds, 800, 480, 32, 4 * 800);
dpy_resize(ds);
}
/* FIXME: We shouldn't really be doing this here. The LCD controller
will set the size once configured, so this just sets an initial
size until the guest activates the display. */
- ds->surface = qemu_resize_displaysurface(ds->surface, 320, 320, 32, 4 * 320);
+ ds->surface = qemu_resize_displaysurface(ds, 320, 320, 32, 4 * 320);
dpy_resize(ds);
}
if (depth == 32) {
#endif
if (is_graphic_console()) {
- qemu_free_displaysurface(s->ds->surface);
+ qemu_free_displaysurface(s->ds);
s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
s->line_offset,
s->vram_ptr + (s->start_addr * 4));
dcl.dpy_resize = vga_save_dpy_resize;
dcl.dpy_refresh = vga_save_dpy_refresh;
register_displaychangelistener(ds, &dcl);
- ds->surface = qemu_create_displaysurface(w, h, 32, 4 * w);
+ ds->surface = qemu_create_displaysurface(ds, w, h, 32, 4 * w);
s->ds = ds;
s->graphic_mode = -1;
ppm_save(filename, ds->surface);
- qemu_free_displaysurface(ds->surface);
+ qemu_free_displaysurface(ds);
s->ds = saved_ds;
}
typedef struct DisplayState DisplayState;
typedef struct DisplayChangeListener DisplayChangeListener;
typedef struct DisplaySurface DisplaySurface;
+typedef struct DisplayAllocator DisplayAllocator;
typedef struct PixelFormat PixelFormat;
typedef struct TextConsole TextConsole;
typedef TextConsole QEMUConsole;
/***********************************************************/
/* register display */
+struct DisplayAllocator default_allocator = {
+ defaultallocator_create_displaysurface,
+ defaultallocator_resize_displaysurface,
+ defaultallocator_free_displaysurface
+};
+
void register_displaystate(DisplayState *ds)
{
DisplayState **s;
return display_state;
}
+DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
+{
+ if(ds->allocator == &default_allocator) ds->allocator = da;
+ return ds->allocator;
+}
+
/* dumb display */
static void dumb_display_init(void)
fprintf(stderr, "dumb_display_init: DisplayState allocation failed\n");
exit(1);
}
- ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
+ ds->allocator = &default_allocator;
+ ds->surface = qemu_create_displaysurface(ds, 640, 480, 32, 640 * 4);
register_displaystate(ds);
}
kernel_filename, kernel_cmdline, initrd_filename, cpu_model,
direct_pci);
+ if (loadvm)
+ do_loadvm(loadvm);
+
/* init USB devices */
if (usb_enabled) {
for(i = 0; i < usb_devices_index; i++) {
}
#endif
- if (loadvm)
- do_loadvm(loadvm);
-
if (incoming) {
autostart = 0; /* fixme how to deal with -daemonize */
qemu_start_incoming_migration(incoming);
}
}
+
+static DisplaySurface* xenfb_create_displaysurface(int width, int height, int bpp, int linesize)
+{
+ DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
+ if (surface == NULL) {
+ fprintf(stderr, "xenfb_create_displaysurface: malloc failed\n");
+ exit(1);
+ }
+
+ surface->width = width;
+ surface->height = height;
+ surface->linesize = linesize;
+ surface->pf = qemu_default_pixelformat(bpp);
+#ifdef WORDS_BIGENDIAN
+ surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
+#else
+ surface->flags = QEMU_ALLOCATED_FLAG;
+#endif
+ surface->data = xs->nonshared_vram;
+
+ return surface;
+}
+
+static DisplaySurface* xenfb_resize_displaysurface(DisplaySurface *surface,
+ int width, int height, int bpp, int linesize)
+{
+ surface->width = width;
+ surface->height = height;
+ surface->linesize = linesize;
+ surface->pf = qemu_default_pixelformat(bpp);
+#ifdef WORDS_BIGENDIAN
+ surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
+#else
+ surface->flags = QEMU_ALLOCATED_FLAG;
+#endif
+ surface->data = xs->nonshared_vram;
+
+ return surface;
+}
+
+static void xenfb_free_displaysurface(DisplaySurface *surface)
+{
+ if (surface == NULL)
+ return;
+ qemu_free(surface);
+}
+
+static void xenfb_pv_display_allocator(void)
+{
+ DisplaySurface *ds;
+ DisplayAllocator *da = qemu_mallocz(sizeof(DisplayAllocator));
+ da->create_displaysurface = xenfb_create_displaysurface;
+ da->resize_displaysurface = xenfb_resize_displaysurface;
+ da->free_displaysurface = xenfb_free_displaysurface;
+ if (register_displayallocator(xs->ds, da) != da) {
+ fprintf(stderr, "xenfb_pv_display_allocator: could not register DisplayAllocator\n");
+ exit(1);
+ }
+
+ xs->nonshared_vram = qemu_memalign(PAGE_SIZE, vga_ram_size);
+ if (!xs->nonshared_vram) {
+ fprintf(stderr, "xenfb_pv_display_allocator: could not allocate nonshared_vram\n");
+ exit(1);
+ }
+
+ ds = xenfb_create_displaysurface(ds_get_width(xs->ds), ds_get_height(xs->ds), ds_get_bits_per_pixel(xs->ds), ds_get_linesize(xs->ds));
+ qemu_free_displaysurface(xs->ds);
+ xs->ds->surface = ds;
+}
+
int xenfb_pv_display_init(DisplayState *ds)
{
struct fbfront_dev *fb_dev;
init_SEMAPHORE(&xs->kbd_sem, 0);
xs->ds = ds;
- xs->nonshared_vram = ds_get_data(ds);
+
+ xenfb_pv_display_allocator();
create_thread("kbdfront", kbdfront_thread, (void*) xs);