console: fix displaychangelisteners interface
Split callbacks into separate Ops struct. Pass DisplayChangeListener pointer as first argument to all callbacks. Uninline a bunch of display functions and move them from console.h to console.c Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
225dc991b0
commit
7c20b4a374
18
hw/qxl.c
18
hw/qxl.c
|
@ -1866,21 +1866,25 @@ static void qxl_vm_change_state_handler(void *opaque, int running,
|
||||||
|
|
||||||
/* display change listener */
|
/* display change listener */
|
||||||
|
|
||||||
static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
|
static void display_update(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *ds,
|
||||||
|
int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (qxl0->mode == QXL_MODE_VGA) {
|
if (qxl0->mode == QXL_MODE_VGA) {
|
||||||
qemu_spice_display_update(&qxl0->ssd, x, y, w, h);
|
qemu_spice_display_update(&qxl0->ssd, x, y, w, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_resize(struct DisplayState *ds)
|
static void display_resize(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *ds)
|
||||||
{
|
{
|
||||||
if (qxl0->mode == QXL_MODE_VGA) {
|
if (qxl0->mode == QXL_MODE_VGA) {
|
||||||
qemu_spice_display_resize(&qxl0->ssd);
|
qemu_spice_display_resize(&qxl0->ssd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_refresh(struct DisplayState *ds)
|
static void display_refresh(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *ds)
|
||||||
{
|
{
|
||||||
if (qxl0->mode == QXL_MODE_VGA) {
|
if (qxl0->mode == QXL_MODE_VGA) {
|
||||||
qemu_spice_display_refresh(&qxl0->ssd);
|
qemu_spice_display_refresh(&qxl0->ssd);
|
||||||
|
@ -1891,10 +1895,11 @@ static void display_refresh(struct DisplayState *ds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisplayChangeListener display_listener = {
|
static DisplayChangeListenerOps display_listener_ops = {
|
||||||
|
.dpy_name = "spice/qxl",
|
||||||
.dpy_gfx_update = display_update,
|
.dpy_gfx_update = display_update,
|
||||||
.dpy_gfx_resize = display_resize,
|
.dpy_gfx_resize = display_resize,
|
||||||
.dpy_refresh = display_refresh,
|
.dpy_refresh = display_refresh,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void qxl_init_ramsize(PCIQXLDevice *qxl)
|
static void qxl_init_ramsize(PCIQXLDevice *qxl)
|
||||||
|
@ -2076,7 +2081,8 @@ static int qxl_init_primary(PCIDevice *dev)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
register_displaychangelistener(vga->ds, &display_listener);
|
qxl->ssd.dcl.ops = &display_listener_ops;
|
||||||
|
register_displaychangelistener(vga->ds, &qxl->ssd.dcl);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,24 +147,46 @@ void cursor_set_mono(QEMUCursor *c,
|
||||||
void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *mask);
|
void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *mask);
|
||||||
void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask);
|
void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask);
|
||||||
|
|
||||||
|
typedef struct DisplayChangeListenerOps {
|
||||||
|
const char *dpy_name;
|
||||||
|
|
||||||
|
void (*dpy_refresh)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s);
|
||||||
|
|
||||||
|
void (*dpy_gfx_update)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s,
|
||||||
|
int x, int y, int w, int h);
|
||||||
|
void (*dpy_gfx_resize)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s);
|
||||||
|
void (*dpy_gfx_setdata)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s);
|
||||||
|
void (*dpy_gfx_copy)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s, int src_x, int src_y,
|
||||||
|
int dst_x, int dst_y, int w, int h);
|
||||||
|
|
||||||
|
void (*dpy_text_cursor)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s,
|
||||||
|
int x, int y);
|
||||||
|
void (*dpy_text_resize)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s,
|
||||||
|
int w, int h);
|
||||||
|
void (*dpy_text_update)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s,
|
||||||
|
int x, int y, int w, int h);
|
||||||
|
|
||||||
|
void (*dpy_mouse_set)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s,
|
||||||
|
int x, int y, int on);
|
||||||
|
void (*dpy_cursor_define)(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *s,
|
||||||
|
QEMUCursor *cursor);
|
||||||
|
} DisplayChangeListenerOps;
|
||||||
|
|
||||||
struct DisplayChangeListener {
|
struct DisplayChangeListener {
|
||||||
int idle;
|
int idle;
|
||||||
uint64_t gui_timer_interval;
|
uint64_t gui_timer_interval;
|
||||||
|
const DisplayChangeListenerOps *ops;
|
||||||
void (*dpy_refresh)(struct DisplayState *s);
|
DisplayState *ds;
|
||||||
|
|
||||||
void (*dpy_gfx_update)(struct DisplayState *s, int x, int y, int w, int h);
|
|
||||||
void (*dpy_gfx_resize)(struct DisplayState *s);
|
|
||||||
void (*dpy_gfx_setdata)(struct DisplayState *s);
|
|
||||||
void (*dpy_gfx_copy)(struct DisplayState *s, int src_x, int src_y,
|
|
||||||
int dst_x, int dst_y, int w, int h);
|
|
||||||
|
|
||||||
void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
|
|
||||||
void (*dpy_text_resize)(struct DisplayState *s, int w, int h);
|
|
||||||
void (*dpy_text_update)(struct DisplayState *s, int x, int y, int w, int h);
|
|
||||||
|
|
||||||
void (*dpy_mouse_set)(struct DisplayState *s, int x, int y, int on);
|
|
||||||
void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
|
|
||||||
|
|
||||||
QLIST_ENTRY(DisplayChangeListener) next;
|
QLIST_ENTRY(DisplayChangeListener) next;
|
||||||
};
|
};
|
||||||
|
@ -210,145 +232,22 @@ static inline int is_buffer_shared(DisplaySurface *surface)
|
||||||
|
|
||||||
void gui_setup_refresh(DisplayState *ds);
|
void gui_setup_refresh(DisplayState *ds);
|
||||||
|
|
||||||
static inline void register_displaychangelistener(DisplayState *ds, DisplayChangeListener *dcl)
|
void register_displaychangelistener(DisplayState *ds,
|
||||||
{
|
DisplayChangeListener *dcl);
|
||||||
QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
|
void unregister_displaychangelistener(DisplayChangeListener *dcl);
|
||||||
gui_setup_refresh(ds);
|
|
||||||
if (dcl->dpy_gfx_resize) {
|
|
||||||
dcl->dpy_gfx_resize(ds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void unregister_displaychangelistener(DisplayState *ds,
|
void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h);
|
||||||
DisplayChangeListener *dcl)
|
void dpy_gfx_resize(DisplayState *s);
|
||||||
{
|
void dpy_gfx_setdata(DisplayState *s);
|
||||||
QLIST_REMOVE(dcl, next);
|
void dpy_refresh(DisplayState *s);
|
||||||
gui_setup_refresh(ds);
|
void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
|
||||||
}
|
int dst_x, int dst_y, int w, int h);
|
||||||
|
void dpy_text_cursor(struct DisplayState *s, int x, int y);
|
||||||
static inline void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
|
void dpy_text_update(DisplayState *s, int x, int y, int w, int h);
|
||||||
{
|
void dpy_text_resize(DisplayState *s, int w, int h);
|
||||||
struct DisplayChangeListener *dcl;
|
void dpy_mouse_set(struct DisplayState *s, int x, int y, int on);
|
||||||
int width = pixman_image_get_width(s->surface->image);
|
void dpy_cursor_define(struct DisplayState *s, QEMUCursor *cursor);
|
||||||
int height = pixman_image_get_height(s->surface->image);
|
bool dpy_cursor_define_supported(struct DisplayState *s);
|
||||||
|
|
||||||
x = MAX(x, 0);
|
|
||||||
y = MAX(y, 0);
|
|
||||||
x = MIN(x, width);
|
|
||||||
y = MIN(y, height);
|
|
||||||
w = MIN(w, width - x);
|
|
||||||
h = MIN(h, height - y);
|
|
||||||
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_gfx_update) {
|
|
||||||
dcl->dpy_gfx_update(s, x, y, w, h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_gfx_resize(DisplayState *s)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_gfx_resize) {
|
|
||||||
dcl->dpy_gfx_resize(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_gfx_setdata(DisplayState *s)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_gfx_setdata) {
|
|
||||||
dcl->dpy_gfx_setdata(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_refresh(DisplayState *s)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_refresh) {
|
|
||||||
dcl->dpy_refresh(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
|
|
||||||
int dst_x, int dst_y, int w, int h)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_gfx_copy) {
|
|
||||||
dcl->dpy_gfx_copy(s, src_x, src_y, dst_x, dst_y, w, h);
|
|
||||||
} else { /* TODO */
|
|
||||||
dcl->dpy_gfx_update(s, dst_x, dst_y, w, h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_text_cursor) {
|
|
||||||
dcl->dpy_text_cursor(s, x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_text_update(DisplayState *s, int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_text_update) {
|
|
||||||
dcl->dpy_text_update(s, x, y, w, h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_text_resize(DisplayState *s, int w, int h)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_text_resize) {
|
|
||||||
dcl->dpy_text_resize(s, w, h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_mouse_set) {
|
|
||||||
dcl->dpy_mouse_set(s, x, y, on);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dpy_cursor_define(struct DisplayState *s, QEMUCursor *cursor)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_cursor_define) {
|
|
||||||
dcl->dpy_cursor_define(s, cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool dpy_cursor_define_supported(struct DisplayState *s)
|
|
||||||
{
|
|
||||||
struct DisplayChangeListener *dcl;
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (dcl->dpy_cursor_define) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ds_get_linesize(DisplayState *ds)
|
static inline int ds_get_linesize(DisplayState *ds)
|
||||||
{
|
{
|
||||||
|
|
|
@ -72,6 +72,7 @@ typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
|
||||||
|
|
||||||
struct SimpleSpiceDisplay {
|
struct SimpleSpiceDisplay {
|
||||||
DisplayState *ds;
|
DisplayState *ds;
|
||||||
|
DisplayChangeListener dcl;
|
||||||
void *buf;
|
void *buf;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
QXLWorker *worker;
|
QXLWorker *worker;
|
||||||
|
|
|
@ -960,6 +960,8 @@ dma_map_wait(void *dbs) "dbs=%p"
|
||||||
# console.h
|
# console.h
|
||||||
displaysurface_free(void *display_state, void *display_surface) "state=%p surface=%p"
|
displaysurface_free(void *display_state, void *display_surface) "state=%p surface=%p"
|
||||||
displaysurface_resize(void *display_state, void *display_surface, int width, int height) "state=%p surface=%p %dx%d"
|
displaysurface_resize(void *display_state, void *display_surface, int width, int height) "state=%p surface=%p %dx%d"
|
||||||
|
displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
|
||||||
|
displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
|
||||||
|
|
||||||
# vga.c
|
# vga.c
|
||||||
ppm_save(const char *filename, void *display_surface) "%s surface=%p"
|
ppm_save(const char *filename, void *display_surface) "%s surface=%p"
|
||||||
|
|
26
ui/cocoa.m
26
ui/cocoa.m
|
@ -969,7 +969,9 @@ int main (int argc, const char * argv[]) {
|
||||||
|
|
||||||
|
|
||||||
#pragma mark qemu
|
#pragma mark qemu
|
||||||
static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
|
static void cocoa_update(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
|
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
|
||||||
|
|
||||||
|
@ -986,14 +988,16 @@ static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
|
||||||
[cocoaView setNeedsDisplayInRect:rect];
|
[cocoaView setNeedsDisplayInRect:rect];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cocoa_resize(DisplayState *ds)
|
static void cocoa_resize(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
COCOA_DEBUG("qemu_cocoa: cocoa_resize\n");
|
COCOA_DEBUG("qemu_cocoa: cocoa_resize\n");
|
||||||
|
|
||||||
[cocoaView resizeContentToWidth:(int)(ds_get_width(ds)) height:(int)(ds_get_height(ds)) displayState:ds];
|
[cocoaView resizeContentToWidth:(int)(ds_get_width(ds)) height:(int)(ds_get_height(ds)) displayState:ds];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cocoa_refresh(DisplayState *ds)
|
static void cocoa_refresh(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
|
COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
|
||||||
|
|
||||||
|
@ -1030,6 +1034,14 @@ static void cocoa_cleanup(void)
|
||||||
g_free(dcl);
|
g_free(dcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const DisplayChangeListenerOps dcl_ops = {
|
||||||
|
.dpy_name = "cocoa",
|
||||||
|
.dpy_gfx_update = cocoa_update;
|
||||||
|
.dpy_gfx_resize = cocoa_resize;
|
||||||
|
.dpy_gfx_setdata = cocoa_setdata;
|
||||||
|
.dpy_refresh = cocoa_refresh;
|
||||||
|
};
|
||||||
|
|
||||||
void cocoa_display_init(DisplayState *ds, int full_screen)
|
void cocoa_display_init(DisplayState *ds, int full_screen)
|
||||||
{
|
{
|
||||||
COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");
|
COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");
|
||||||
|
@ -1037,12 +1049,8 @@ void cocoa_display_init(DisplayState *ds, int full_screen)
|
||||||
dcl = g_malloc0(sizeof(DisplayChangeListener));
|
dcl = g_malloc0(sizeof(DisplayChangeListener));
|
||||||
|
|
||||||
// register vga output callbacks
|
// register vga output callbacks
|
||||||
dcl->dpy_gfx_update = cocoa_update;
|
dcl->ops = &dcl_ops;
|
||||||
dcl->dpy_gfx_resize = cocoa_resize;
|
register_displaychangelistener(ds, dcl);
|
||||||
dcl->dpy_refresh = cocoa_refresh;
|
|
||||||
dcl->dpy_gfx_setdata = cocoa_setdata;
|
|
||||||
|
|
||||||
register_displaychangelistener(ds, dcl);
|
|
||||||
|
|
||||||
// register cleanup function
|
// register cleanup function
|
||||||
atexit(cocoa_cleanup);
|
atexit(cocoa_cleanup);
|
||||||
|
|
144
ui/console.c
144
ui/console.c
|
@ -1374,6 +1374,150 @@ void qemu_free_displaysurface(DisplayState *ds)
|
||||||
g_free(ds->surface);
|
g_free(ds->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void register_displaychangelistener(DisplayState *ds,
|
||||||
|
DisplayChangeListener *dcl)
|
||||||
|
{
|
||||||
|
trace_displaychangelistener_register(dcl, dcl->ops->dpy_name);
|
||||||
|
dcl->ds = ds;
|
||||||
|
QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
|
||||||
|
gui_setup_refresh(ds);
|
||||||
|
if (dcl->ops->dpy_gfx_resize) {
|
||||||
|
dcl->ops->dpy_gfx_resize(dcl, ds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregister_displaychangelistener(DisplayChangeListener *dcl)
|
||||||
|
{
|
||||||
|
DisplayState *ds = dcl->ds;
|
||||||
|
trace_displaychangelistener_unregister(dcl, dcl->ops->dpy_name);
|
||||||
|
QLIST_REMOVE(dcl, next);
|
||||||
|
gui_setup_refresh(ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
int width = pixman_image_get_width(s->surface->image);
|
||||||
|
int height = pixman_image_get_height(s->surface->image);
|
||||||
|
|
||||||
|
x = MAX(x, 0);
|
||||||
|
y = MAX(y, 0);
|
||||||
|
x = MIN(x, width);
|
||||||
|
y = MIN(y, height);
|
||||||
|
w = MIN(w, width - x);
|
||||||
|
h = MIN(h, height - y);
|
||||||
|
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_gfx_update) {
|
||||||
|
dcl->ops->dpy_gfx_update(dcl, s, x, y, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_gfx_resize(DisplayState *s)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_gfx_resize) {
|
||||||
|
dcl->ops->dpy_gfx_resize(dcl, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_gfx_setdata(DisplayState *s)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_gfx_setdata) {
|
||||||
|
dcl->ops->dpy_gfx_setdata(dcl, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_refresh(DisplayState *s)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_refresh) {
|
||||||
|
dcl->ops->dpy_refresh(dcl, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
|
||||||
|
int dst_x, int dst_y, int w, int h)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_gfx_copy) {
|
||||||
|
dcl->ops->dpy_gfx_copy(dcl, s, src_x, src_y, dst_x, dst_y, w, h);
|
||||||
|
} else { /* TODO */
|
||||||
|
dcl->ops->dpy_gfx_update(dcl, s, dst_x, dst_y, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_text_cursor(struct DisplayState *s, int x, int y)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_text_cursor) {
|
||||||
|
dcl->ops->dpy_text_cursor(dcl, s, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_text_update(DisplayState *s, int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_text_update) {
|
||||||
|
dcl->ops->dpy_text_update(dcl, s, x, y, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_text_resize(DisplayState *s, int w, int h)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_text_resize) {
|
||||||
|
dcl->ops->dpy_text_resize(dcl, s, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_mouse_set) {
|
||||||
|
dcl->ops->dpy_mouse_set(dcl, s, x, y, on);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dpy_cursor_define(struct DisplayState *s, QEMUCursor *cursor)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_cursor_define) {
|
||||||
|
dcl->ops->dpy_cursor_define(dcl, s, cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dpy_cursor_define_supported(struct DisplayState *s)
|
||||||
|
{
|
||||||
|
struct DisplayChangeListener *dcl;
|
||||||
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
|
if (dcl->ops->dpy_cursor_define) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void dumb_display_init(void)
|
static void dumb_display_init(void)
|
||||||
{
|
{
|
||||||
DisplayState *ds = g_malloc0(sizeof(DisplayState));
|
DisplayState *ds = g_malloc0(sizeof(DisplayState));
|
||||||
|
|
32
ui/curses.c
32
ui/curses.c
|
@ -35,12 +35,15 @@
|
||||||
#define FONT_HEIGHT 16
|
#define FONT_HEIGHT 16
|
||||||
#define FONT_WIDTH 8
|
#define FONT_WIDTH 8
|
||||||
|
|
||||||
|
static DisplayChangeListener *dcl;
|
||||||
static console_ch_t screen[160 * 100];
|
static console_ch_t screen[160 * 100];
|
||||||
static WINDOW *screenpad = NULL;
|
static WINDOW *screenpad = NULL;
|
||||||
static int width, height, gwidth, gheight, invalidate;
|
static int width, height, gwidth, gheight, invalidate;
|
||||||
static int px, py, sminx, sminy, smaxx, smaxy;
|
static int px, py, sminx, sminy, smaxx, smaxy;
|
||||||
|
|
||||||
static void curses_update(DisplayState *ds, int x, int y, int w, int h)
|
static void curses_update(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
chtype *line;
|
chtype *line;
|
||||||
|
|
||||||
|
@ -91,7 +94,9 @@ static void curses_calc_pad(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void curses_resize(DisplayState *ds, int width, int height)
|
static void curses_resize(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int width, int height)
|
||||||
{
|
{
|
||||||
if (width == gwidth && height == gheight) {
|
if (width == gwidth && height == gheight) {
|
||||||
return;
|
return;
|
||||||
|
@ -128,7 +133,9 @@ static void curses_winch_handler(int signum)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void curses_cursor_position(DisplayState *ds, int x, int y)
|
static void curses_cursor_position(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int x, int y)
|
||||||
{
|
{
|
||||||
if (x >= 0) {
|
if (x >= 0) {
|
||||||
x = sminx + x - px;
|
x = sminx + x - px;
|
||||||
|
@ -154,7 +161,8 @@ static void curses_cursor_position(DisplayState *ds, int x, int y)
|
||||||
|
|
||||||
static kbd_layout_t *kbd_layout = NULL;
|
static kbd_layout_t *kbd_layout = NULL;
|
||||||
|
|
||||||
static void curses_refresh(DisplayState *ds)
|
static void curses_refresh(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
int chr, nextchr, keysym, keycode, keycode_alt;
|
int chr, nextchr, keysym, keycode, keycode_alt;
|
||||||
|
|
||||||
|
@ -187,7 +195,7 @@ static void curses_refresh(DisplayState *ds)
|
||||||
clear();
|
clear();
|
||||||
refresh();
|
refresh();
|
||||||
curses_calc_pad();
|
curses_calc_pad();
|
||||||
curses_update(ds, 0, 0, width, height);
|
curses_update(dcl, ds, 0, 0, width, height);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -323,9 +331,16 @@ static void curses_keyboard_setup(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const DisplayChangeListenerOps dcl_ops = {
|
||||||
|
.dpy_name = "curses",
|
||||||
|
.dpy_text_update = curses_update,
|
||||||
|
.dpy_text_resize = curses_resize,
|
||||||
|
.dpy_refresh = curses_refresh,
|
||||||
|
.dpy_text_cursor = curses_cursor_position,
|
||||||
|
};
|
||||||
|
|
||||||
void curses_display_init(DisplayState *ds, int full_screen)
|
void curses_display_init(DisplayState *ds, int full_screen)
|
||||||
{
|
{
|
||||||
DisplayChangeListener *dcl;
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (!isatty(1)) {
|
if (!isatty(1)) {
|
||||||
fprintf(stderr, "We need a terminal output\n");
|
fprintf(stderr, "We need a terminal output\n");
|
||||||
|
@ -346,10 +361,7 @@ void curses_display_init(DisplayState *ds, int full_screen)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
|
dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
|
||||||
dcl->dpy_text_update = curses_update;
|
dcl->ops = &dcl_ops;
|
||||||
dcl->dpy_text_resize = curses_resize;
|
|
||||||
dcl->dpy_refresh = curses_refresh;
|
|
||||||
dcl->dpy_text_cursor = curses_cursor_position;
|
|
||||||
register_displaychangelistener(ds, dcl);
|
register_displaychangelistener(ds, dcl);
|
||||||
|
|
||||||
invalidate = 1;
|
invalidate = 1;
|
||||||
|
|
30
ui/gtk.c
30
ui/gtk.c
|
@ -227,7 +227,8 @@ static void gd_update_caption(GtkDisplayState *s)
|
||||||
|
|
||||||
/** DisplayState Callbacks **/
|
/** DisplayState Callbacks **/
|
||||||
|
|
||||||
static void gd_update(DisplayState *ds, int x, int y, int w, int h)
|
static void gd_update(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
GtkDisplayState *s = ds->opaque;
|
GtkDisplayState *s = ds->opaque;
|
||||||
int x1, x2, y1, y2;
|
int x1, x2, y1, y2;
|
||||||
|
@ -259,12 +260,14 @@ static void gd_update(DisplayState *ds, int x, int y, int w, int h)
|
||||||
gtk_widget_queue_draw_area(s->drawing_area, mx + x1, my + y1, (x2 - x1), (y2 - y1));
|
gtk_widget_queue_draw_area(s->drawing_area, mx + x1, my + y1, (x2 - x1), (y2 - y1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gd_refresh(DisplayState *ds)
|
static void gd_refresh(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
vga_hw_update();
|
vga_hw_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gd_resize(DisplayState *ds)
|
static void gd_resize(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
GtkDisplayState *s = ds->opaque;
|
GtkDisplayState *s = ds->opaque;
|
||||||
cairo_format_t kind;
|
cairo_format_t kind;
|
||||||
|
@ -382,7 +385,7 @@ static gboolean gd_window_close(GtkWidget *widget, GdkEvent *event,
|
||||||
GtkDisplayState *s = opaque;
|
GtkDisplayState *s = opaque;
|
||||||
|
|
||||||
if (!no_quit) {
|
if (!no_quit) {
|
||||||
unregister_displaychangelistener(s->ds, &s->dcl);
|
unregister_displaychangelistener(&s->dcl);
|
||||||
qmp_quit(NULL);
|
qmp_quit(NULL);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -735,7 +738,7 @@ static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
|
||||||
s->scale_x += .25;
|
s->scale_x += .25;
|
||||||
s->scale_y += .25;
|
s->scale_y += .25;
|
||||||
|
|
||||||
gd_resize(s->ds);
|
gd_resize(&s->dcl, s->ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
|
static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
|
||||||
|
@ -751,7 +754,7 @@ static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
|
||||||
s->scale_x = MAX(s->scale_x, .25);
|
s->scale_x = MAX(s->scale_x, .25);
|
||||||
s->scale_y = MAX(s->scale_y, .25);
|
s->scale_y = MAX(s->scale_y, .25);
|
||||||
|
|
||||||
gd_resize(s->ds);
|
gd_resize(&s->dcl, s->ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
|
static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
|
||||||
|
@ -761,7 +764,7 @@ static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
|
||||||
s->scale_x = 1.0;
|
s->scale_x = 1.0;
|
||||||
s->scale_y = 1.0;
|
s->scale_y = 1.0;
|
||||||
|
|
||||||
gd_resize(s->ds);
|
gd_resize(&s->dcl, s->ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
|
static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
|
||||||
|
@ -775,7 +778,7 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
|
||||||
s->free_scale = FALSE;
|
s->free_scale = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gd_resize(s->ds);
|
gd_resize(&s->dcl, s->ds);
|
||||||
|
|
||||||
gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
|
gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
|
||||||
gtk_widget_queue_draw_area(s->drawing_area, 0, 0, ww, wh);
|
gtk_widget_queue_draw_area(s->drawing_area, 0, 0, ww, wh);
|
||||||
|
@ -1281,6 +1284,13 @@ static void gd_create_menus(GtkDisplayState *s)
|
||||||
gtk_menu_shell_append(GTK_MENU_SHELL(s->menu_bar), s->view_menu_item);
|
gtk_menu_shell_append(GTK_MENU_SHELL(s->menu_bar), s->view_menu_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const DisplayChangeListenerOps dcl_ops = {
|
||||||
|
.dpy_name = "gtk",
|
||||||
|
.dpy_gfx_update = gd_update,
|
||||||
|
.dpy_gfx_resize = gd_resize,
|
||||||
|
.dpy_refresh = gd_refresh,
|
||||||
|
};
|
||||||
|
|
||||||
void gtk_display_init(DisplayState *ds)
|
void gtk_display_init(DisplayState *ds)
|
||||||
{
|
{
|
||||||
GtkDisplayState *s = g_malloc0(sizeof(*s));
|
GtkDisplayState *s = g_malloc0(sizeof(*s));
|
||||||
|
@ -1289,9 +1299,7 @@ void gtk_display_init(DisplayState *ds)
|
||||||
|
|
||||||
ds->opaque = s;
|
ds->opaque = s;
|
||||||
s->ds = ds;
|
s->ds = ds;
|
||||||
s->dcl.dpy_gfx_update = gd_update;
|
s->dcl.ops = &dcl_ops;
|
||||||
s->dcl.dpy_gfx_resize = gd_resize;
|
|
||||||
s->dcl.dpy_refresh = gd_refresh;
|
|
||||||
|
|
||||||
s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
#if GTK_CHECK_VERSION(3, 2, 0)
|
#if GTK_CHECK_VERSION(3, 2, 0)
|
||||||
|
|
44
ui/sdl.c
44
ui/sdl.c
|
@ -59,7 +59,9 @@ static SDL_PixelFormat host_format;
|
||||||
static int scaling_active = 0;
|
static int scaling_active = 0;
|
||||||
static Notifier mouse_mode_notifier;
|
static Notifier mouse_mode_notifier;
|
||||||
|
|
||||||
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
|
static void sdl_update(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
// printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
|
// printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
|
||||||
SDL_Rect rec;
|
SDL_Rect rec;
|
||||||
|
@ -81,7 +83,8 @@ static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
|
||||||
SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h);
|
SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdl_setdata(DisplayState *ds)
|
static void sdl_setdata(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
if (guest_screen != NULL) SDL_FreeSurface(guest_screen);
|
if (guest_screen != NULL) SDL_FreeSurface(guest_screen);
|
||||||
|
|
||||||
|
@ -114,7 +117,8 @@ static void do_sdl_resize(int width, int height, int bpp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdl_resize(DisplayState *ds)
|
static void sdl_resize(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
if (!scaling_active) {
|
if (!scaling_active) {
|
||||||
do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
|
do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
|
||||||
|
@ -122,7 +126,7 @@ static void sdl_resize(DisplayState *ds)
|
||||||
do_sdl_resize(real_screen->w, real_screen->h,
|
do_sdl_resize(real_screen->w, real_screen->h,
|
||||||
ds_get_bits_per_pixel(ds));
|
ds_get_bits_per_pixel(ds));
|
||||||
}
|
}
|
||||||
sdl_setdata(ds);
|
sdl_setdata(dcl, ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generic keyboard conversion */
|
/* generic keyboard conversion */
|
||||||
|
@ -514,7 +518,7 @@ static void handle_keydown(DisplayState *ds, SDL_Event *ev)
|
||||||
case 0x16: /* 'u' key on US keyboard */
|
case 0x16: /* 'u' key on US keyboard */
|
||||||
if (scaling_active) {
|
if (scaling_active) {
|
||||||
scaling_active = 0;
|
scaling_active = 0;
|
||||||
sdl_resize(ds);
|
sdl_resize(dcl, ds);
|
||||||
vga_hw_invalidate();
|
vga_hw_invalidate();
|
||||||
vga_hw_update();
|
vga_hw_update();
|
||||||
}
|
}
|
||||||
|
@ -753,7 +757,8 @@ static void handle_activation(DisplayState *ds, SDL_Event *ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdl_refresh(DisplayState *ds)
|
static void sdl_refresh(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
SDL_Event ev1, *ev = &ev1;
|
SDL_Event ev1, *ev = &ev1;
|
||||||
|
|
||||||
|
@ -768,7 +773,7 @@ static void sdl_refresh(DisplayState *ds)
|
||||||
while (SDL_PollEvent(ev)) {
|
while (SDL_PollEvent(ev)) {
|
||||||
switch (ev->type) {
|
switch (ev->type) {
|
||||||
case SDL_VIDEOEXPOSE:
|
case SDL_VIDEOEXPOSE:
|
||||||
sdl_update(ds, 0, 0, real_screen->w, real_screen->h);
|
sdl_update(dcl, ds, 0, 0, real_screen->w, real_screen->h);
|
||||||
break;
|
break;
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
handle_keydown(ds, ev);
|
handle_keydown(ds, ev);
|
||||||
|
@ -803,7 +808,9 @@ static void sdl_refresh(DisplayState *ds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
|
static void sdl_mouse_warp(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int x, int y, int on)
|
||||||
{
|
{
|
||||||
if (on) {
|
if (on) {
|
||||||
if (!guest_cursor)
|
if (!guest_cursor)
|
||||||
|
@ -819,7 +826,9 @@ static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
|
||||||
guest_x = x, guest_y = y;
|
guest_x = x, guest_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdl_mouse_define(DisplayState *ds, QEMUCursor *c)
|
static void sdl_mouse_define(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
QEMUCursor *c)
|
||||||
{
|
{
|
||||||
uint8_t *image, *mask;
|
uint8_t *image, *mask;
|
||||||
int bpl;
|
int bpl;
|
||||||
|
@ -849,6 +858,16 @@ static void sdl_cleanup(void)
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const DisplayChangeListenerOps dcl_ops = {
|
||||||
|
.dpy_name = "sdl",
|
||||||
|
.dpy_gfx_update = sdl_update,
|
||||||
|
.dpy_gfx_resize = sdl_resize,
|
||||||
|
.dpy_refresh = sdl_refresh,
|
||||||
|
.dpy_gfx_setdata = sdl_setdata,
|
||||||
|
.dpy_mouse_set = sdl_mouse_warp,
|
||||||
|
.dpy_cursor_define = sdl_mouse_define,
|
||||||
|
};
|
||||||
|
|
||||||
void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
|
void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -917,12 +936,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
dcl = g_malloc0(sizeof(DisplayChangeListener));
|
dcl = g_malloc0(sizeof(DisplayChangeListener));
|
||||||
dcl->dpy_gfx_update = sdl_update;
|
dcl->ops = &dcl_ops;
|
||||||
dcl->dpy_gfx_resize = sdl_resize;
|
|
||||||
dcl->dpy_refresh = sdl_refresh;
|
|
||||||
dcl->dpy_gfx_setdata = sdl_setdata;
|
|
||||||
dcl->dpy_mouse_set = sdl_mouse_warp;
|
|
||||||
dcl->dpy_cursor_define = sdl_mouse_define;
|
|
||||||
register_displaychangelistener(ds, dcl);
|
register_displaychangelistener(ds, dcl);
|
||||||
|
|
||||||
mouse_mode_notifier.notify = sdl_mouse_mode_change;
|
mouse_mode_notifier.notify = sdl_mouse_mode_change;
|
||||||
|
|
|
@ -583,25 +583,30 @@ static const QXLInterface dpy_interface = {
|
||||||
|
|
||||||
static SimpleSpiceDisplay sdpy;
|
static SimpleSpiceDisplay sdpy;
|
||||||
|
|
||||||
static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
|
static void display_update(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *ds,
|
||||||
|
int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
qemu_spice_display_update(&sdpy, x, y, w, h);
|
qemu_spice_display_update(&sdpy, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_resize(struct DisplayState *ds)
|
static void display_resize(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *ds)
|
||||||
{
|
{
|
||||||
qemu_spice_display_resize(&sdpy);
|
qemu_spice_display_resize(&sdpy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_refresh(struct DisplayState *ds)
|
static void display_refresh(DisplayChangeListener *dcl,
|
||||||
|
struct DisplayState *ds)
|
||||||
{
|
{
|
||||||
qemu_spice_display_refresh(&sdpy);
|
qemu_spice_display_refresh(&sdpy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisplayChangeListener display_listener = {
|
static const DisplayChangeListenerOps display_listener_ops = {
|
||||||
|
.dpy_name = "spice",
|
||||||
.dpy_gfx_update = display_update,
|
.dpy_gfx_update = display_update,
|
||||||
.dpy_gfx_resize = display_resize,
|
.dpy_gfx_resize = display_resize,
|
||||||
.dpy_refresh = display_refresh,
|
.dpy_refresh = display_refresh,
|
||||||
};
|
};
|
||||||
|
|
||||||
void qemu_spice_display_init(DisplayState *ds)
|
void qemu_spice_display_init(DisplayState *ds)
|
||||||
|
@ -615,5 +620,7 @@ void qemu_spice_display_init(DisplayState *ds)
|
||||||
|
|
||||||
qemu_spice_create_host_memslot(&sdpy);
|
qemu_spice_create_host_memslot(&sdpy);
|
||||||
qemu_spice_create_host_primary(&sdpy);
|
qemu_spice_create_host_primary(&sdpy);
|
||||||
register_displaychangelistener(ds, &display_listener);
|
|
||||||
|
sdpy.dcl.ops = &display_listener_ops;
|
||||||
|
register_displaychangelistener(ds, &sdpy.dcl);
|
||||||
}
|
}
|
||||||
|
|
44
ui/vnc.c
44
ui/vnc.c
|
@ -430,7 +430,9 @@ static void framebuffer_update_request(VncState *vs, int incremental,
|
||||||
static void vnc_refresh(void *opaque);
|
static void vnc_refresh(void *opaque);
|
||||||
static int vnc_refresh_server_surface(VncDisplay *vd);
|
static int vnc_refresh_server_surface(VncDisplay *vd);
|
||||||
|
|
||||||
static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
|
static void vnc_dpy_update(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
VncDisplay *vd = ds->opaque;
|
VncDisplay *vd = ds->opaque;
|
||||||
|
@ -573,7 +575,8 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnc_dpy_resize(DisplayState *ds)
|
static void vnc_dpy_resize(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
VncDisplay *vd = ds->opaque;
|
VncDisplay *vd = ds->opaque;
|
||||||
VncState *vs;
|
VncState *vs;
|
||||||
|
@ -735,7 +738,10 @@ static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, i
|
||||||
vnc_flush(vs);
|
vnc_flush(vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
|
static void vnc_dpy_copy(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int src_x, int src_y,
|
||||||
|
int dst_x, int dst_y, int w, int h)
|
||||||
{
|
{
|
||||||
VncDisplay *vd = ds->opaque;
|
VncDisplay *vd = ds->opaque;
|
||||||
VncState *vs, *vn;
|
VncState *vs, *vn;
|
||||||
|
@ -806,7 +812,9 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnc_mouse_set(DisplayState *ds, int x, int y, int visible)
|
static void vnc_mouse_set(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
int x, int y, int visible)
|
||||||
{
|
{
|
||||||
/* can we ask the client(s) to move the pointer ??? */
|
/* can we ask the client(s) to move the pointer ??? */
|
||||||
}
|
}
|
||||||
|
@ -832,7 +840,9 @@ static int vnc_cursor_define(VncState *vs)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnc_dpy_cursor_define(DisplayState *ds, QEMUCursor *c)
|
static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds,
|
||||||
|
QEMUCursor *c)
|
||||||
{
|
{
|
||||||
VncDisplay *vd = vnc_display;
|
VncDisplay *vd = vnc_display;
|
||||||
VncState *vs;
|
VncState *vs;
|
||||||
|
@ -1972,14 +1982,15 @@ static void pixel_format_message (VncState *vs) {
|
||||||
vs->write_pixels = vnc_write_pixels_copy;
|
vs->write_pixels = vnc_write_pixels_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnc_dpy_setdata(DisplayState *ds)
|
static void vnc_dpy_setdata(DisplayChangeListener *dcl,
|
||||||
|
DisplayState *ds)
|
||||||
{
|
{
|
||||||
VncDisplay *vd = ds->opaque;
|
VncDisplay *vd = ds->opaque;
|
||||||
|
|
||||||
qemu_pixman_image_unref(vd->guest.fb);
|
qemu_pixman_image_unref(vd->guest.fb);
|
||||||
vd->guest.fb = pixman_image_ref(ds->surface->image);
|
vd->guest.fb = pixman_image_ref(ds->surface->image);
|
||||||
vd->guest.format = ds->surface->format;
|
vd->guest.format = ds->surface->format;
|
||||||
vnc_dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
|
vnc_dpy_update(dcl, ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnc_colordepth(VncState *vs)
|
static void vnc_colordepth(VncState *vs)
|
||||||
|
@ -2686,7 +2697,7 @@ static void vnc_init_timer(VncDisplay *vd)
|
||||||
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
|
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
|
||||||
if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
|
if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
|
||||||
vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
|
vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
|
||||||
vnc_dpy_resize(vd->ds);
|
vnc_dpy_resize(dcl, vd->ds);
|
||||||
vnc_refresh(vd);
|
vnc_refresh(vd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2822,6 +2833,16 @@ static void vnc_listen_websocket_read(void *opaque)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_VNC_WS */
|
#endif /* CONFIG_VNC_WS */
|
||||||
|
|
||||||
|
static const DisplayChangeListenerOps dcl_ops = {
|
||||||
|
.dpy_name = "vnc",
|
||||||
|
.dpy_gfx_copy = vnc_dpy_copy,
|
||||||
|
.dpy_gfx_update = vnc_dpy_update,
|
||||||
|
.dpy_gfx_resize = vnc_dpy_resize,
|
||||||
|
.dpy_gfx_setdata = vnc_dpy_setdata,
|
||||||
|
.dpy_mouse_set = vnc_mouse_set,
|
||||||
|
.dpy_cursor_define = vnc_dpy_cursor_define,
|
||||||
|
};
|
||||||
|
|
||||||
void vnc_display_init(DisplayState *ds)
|
void vnc_display_init(DisplayState *ds)
|
||||||
{
|
{
|
||||||
VncDisplay *vs = g_malloc0(sizeof(*vs));
|
VncDisplay *vs = g_malloc0(sizeof(*vs));
|
||||||
|
@ -2852,12 +2873,7 @@ void vnc_display_init(DisplayState *ds)
|
||||||
qemu_mutex_init(&vs->mutex);
|
qemu_mutex_init(&vs->mutex);
|
||||||
vnc_start_worker_thread();
|
vnc_start_worker_thread();
|
||||||
|
|
||||||
dcl->dpy_gfx_copy = vnc_dpy_copy;
|
dcl->ops = &dcl_ops;
|
||||||
dcl->dpy_gfx_update = vnc_dpy_update;
|
|
||||||
dcl->dpy_gfx_resize = vnc_dpy_resize;
|
|
||||||
dcl->dpy_gfx_setdata = vnc_dpy_setdata;
|
|
||||||
dcl->dpy_mouse_set = vnc_mouse_set;
|
|
||||||
dcl->dpy_cursor_define = vnc_dpy_cursor_define;
|
|
||||||
register_displaychangelistener(ds, dcl);
|
register_displaychangelistener(ds, dcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
vl.c
6
vl.c
|
@ -1639,13 +1639,13 @@ void gui_setup_refresh(DisplayState *ds)
|
||||||
bool have_text = false;
|
bool have_text = false;
|
||||||
|
|
||||||
QLIST_FOREACH(dcl, &ds->listeners, next) {
|
QLIST_FOREACH(dcl, &ds->listeners, next) {
|
||||||
if (dcl->dpy_refresh != NULL) {
|
if (dcl->ops->dpy_refresh != NULL) {
|
||||||
need_timer = true;
|
need_timer = true;
|
||||||
}
|
}
|
||||||
if (dcl->dpy_gfx_update != NULL) {
|
if (dcl->ops->dpy_gfx_update != NULL) {
|
||||||
have_gfx = true;
|
have_gfx = true;
|
||||||
}
|
}
|
||||||
if (dcl->dpy_text_update != NULL) {
|
if (dcl->ops->dpy_text_update != NULL) {
|
||||||
have_text = true;
|
have_text = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue