Commit 7d957bd8cbcbf56f7916d375e65042d767f544b5

Authored by aliguori
1 parent 8927bcfd

DisplayState interface change (Stefano Stabellini)

This patch changes the DisplayState interface adding support for
multiple frontends at the same time (sdl and vnc) and implements most
of the benefit of the shared_buf patch without the added complexity.

Currently DisplayState is managed by sdl (or vnc) and sdl (or vnc) is
also responsible for allocating the data and setting the depth.
Vga.c (or another backend) will do any necessary conversion.

The idea is to change it so that is vga.c (or another backend) together
with console.c that fully manage the DisplayState interface allocating
data and setting the depth (either 16 or 32 bit, if the guest uses a
different resolution or is in text mode, vga.c (or another backend) is
in charge of doing the conversion seamlessly).

The other idea is that DisplayState supports *multiple* frontends
like sdl and vnc; each of them can register some callbacks to be called
when a display event occurs.

The interesting changes are:

- the new structures and related functions in console.h and console.c

in particular the following functions are very helpful to manage a
DisplaySurface:

qemu_create_displaysurface
qemu_resize_displaysurface
qemu_create_displaysurface_from
qemu_free_displaysurface

- console_select and qemu_console_resize in console.c
this two functions manage multiple consoles on a single host display

- moving code around in hw/vga.c
as for the shared_buf patch this is necessary to be able to handle a dynamic
DisplaySurface bpp

- changes to vga_draw_graphic in hw/vga.c
this is the place where the DisplaySurface buffer is shared with the
videoram, when possible;


Compared to the last version the only changes are:

- do not remove support to dpy_copy in cirrus_vga
- change the name of the displaysurface handling functions

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6336 c046a42c-6fe2-441c-8c8c-71466251a162
console.c
@@ -1044,12 +1044,15 @@ void console_select(unsigned int index) @@ -1044,12 +1044,15 @@ void console_select(unsigned int index)
1044 1044
1045 if (index >= MAX_CONSOLES) 1045 if (index >= MAX_CONSOLES)
1046 return; 1046 return;
  1047 + active_console->g_width = ds_get_width(active_console->ds);
  1048 + active_console->g_height = ds_get_height(active_console->ds);
1047 s = consoles[index]; 1049 s = consoles[index];
1048 if (s) { 1050 if (s) {
  1051 + DisplayState *ds = s->ds;
1049 active_console = s; 1052 active_console = s;
1050 - if (s->console_type != TEXT_CONSOLE && s->g_width && s->g_height  
1051 - && (s->g_width != ds_get_width(s->ds) || s->g_height != ds_get_height(s->ds)))  
1052 - dpy_resize(s->ds, s->g_width, s->g_height); 1053 + ds->surface = qemu_resize_displaysurface(ds->surface, s->g_width,
  1054 + s->g_height, 32, 4 * s->g_width);
  1055 + dpy_resize(s->ds);
1053 vga_hw_invalidate(); 1056 vga_hw_invalidate();
1054 } 1057 }
1055 } 1058 }
@@ -1157,16 +1160,6 @@ void kbd_put_keysym(int keysym) @@ -1157,16 +1160,6 @@ void kbd_put_keysym(int keysym)
1157 static void text_console_invalidate(void *opaque) 1160 static void text_console_invalidate(void *opaque)
1158 { 1161 {
1159 TextConsole *s = (TextConsole *) opaque; 1162 TextConsole *s = (TextConsole *) opaque;
1160 -  
1161 - if (s->g_width != ds_get_width(s->ds) || s->g_height != ds_get_height(s->ds)) {  
1162 - if (s->console_type == TEXT_CONSOLE_FIXED_SIZE)  
1163 - dpy_resize(s->ds, s->g_width, s->g_height);  
1164 - else {  
1165 - s->g_width = ds_get_width(s->ds);  
1166 - s->g_height = ds_get_height(s->ds);  
1167 - text_console_resize(s);  
1168 - }  
1169 - }  
1170 console_refresh(s); 1163 console_refresh(s);
1171 } 1164 }
1172 1165
@@ -1346,13 +1339,12 @@ CharDriverState *text_console_init(DisplayState *ds, const char *p) @@ -1346,13 +1339,12 @@ CharDriverState *text_console_init(DisplayState *ds, const char *p)
1346 1339
1347 void qemu_console_resize(QEMUConsole *console, int width, int height) 1340 void qemu_console_resize(QEMUConsole *console, int width, int height)
1348 { 1341 {
1349 - if (console->g_width != width || console->g_height != height  
1350 - || !ds_get_data(console->ds)) {  
1351 - console->g_width = width;  
1352 - console->g_height = height;  
1353 - if (active_console == console) {  
1354 - dpy_resize(console->ds, width, height);  
1355 - } 1342 + console->g_width = width;
  1343 + console->g_height = height;
  1344 + if (active_console == console) {
  1345 + DisplayState *ds = console->ds;
  1346 + ds->surface = qemu_resize_displaysurface(ds->surface, width, height, 32, 4 * width);
  1347 + dpy_resize(console->ds);
1356 } 1348 }
1357 } 1349 }
1358 1350
@@ -1360,12 +1352,137 @@ void qemu_console_copy(QEMUConsole *console, int src_x, int src_y, @@ -1360,12 +1352,137 @@ void qemu_console_copy(QEMUConsole *console, int src_x, int src_y,
1360 int dst_x, int dst_y, int w, int h) 1352 int dst_x, int dst_y, int w, int h)
1361 { 1353 {
1362 if (active_console == console) { 1354 if (active_console == console) {
1363 - if (console->ds->dpy_copy)  
1364 - console->ds->dpy_copy(console->ds,  
1365 - src_x, src_y, dst_x, dst_y, w, h);  
1366 - else {  
1367 - /* TODO */  
1368 - console->ds->dpy_update(console->ds, dst_x, dst_y, w, h);  
1369 - } 1355 + dpy_copy(console->ds, src_x, src_y, dst_x, dst_y, w, h);
1370 } 1356 }
1371 } 1357 }
  1358 +
  1359 +static PixelFormat qemu_default_pixelformat(int bpp)
  1360 +{
  1361 + PixelFormat pf;
  1362 +
  1363 + memset(&pf, 0x00, sizeof(PixelFormat));
  1364 +
  1365 + pf.bits_per_pixel = bpp;
  1366 + pf.bytes_per_pixel = bpp / 8;
  1367 + pf.depth = bpp == 32 ? 24 : bpp;
  1368 +
  1369 + switch (bpp) {
  1370 + case 8:
  1371 + pf.rmask = 0x000000E0;
  1372 + pf.gmask = 0x0000001C;
  1373 + pf.bmask = 0x00000003;
  1374 + pf.rmax = 7;
  1375 + pf.gmax = 7;
  1376 + pf.bmax = 3;
  1377 + pf.rshift = 5;
  1378 + pf.gshift = 2;
  1379 + pf.bshift = 0;
  1380 + break;
  1381 + case 16:
  1382 + pf.rmask = 0x0000F800;
  1383 + pf.gmask = 0x000007E0;
  1384 + pf.bmask = 0x0000001F;
  1385 + pf.rmax = 31;
  1386 + pf.gmax = 63;
  1387 + pf.bmax = 31;
  1388 + pf.rshift = 11;
  1389 + pf.gshift = 5;
  1390 + pf.bshift = 0;
  1391 + break;
  1392 + case 24:
  1393 + case 32:
  1394 + pf.rmask = 0x00FF0000;
  1395 + pf.gmask = 0x0000FF00;
  1396 + pf.bmask = 0x000000FF;
  1397 + pf.rmax = 255;
  1398 + pf.gmax = 255;
  1399 + pf.bmax = 255;
  1400 + pf.rshift = 16;
  1401 + pf.gshift = 8;
  1402 + pf.bshift = 0;
  1403 + break;
  1404 + default:
  1405 + break;
  1406 + }
  1407 + return pf;
  1408 +}
  1409 +
  1410 +DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize)
  1411 +{
  1412 + DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
  1413 + if (surface == NULL) {
  1414 + fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
  1415 + exit(1);
  1416 + }
  1417 +
  1418 + surface->width = width;
  1419 + surface->height = height;
  1420 + surface->linesize = linesize;
  1421 + surface->pf = qemu_default_pixelformat(bpp);
  1422 +#ifdef WORDS_BIGENDIAN
  1423 + surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
  1424 +#else
  1425 + surface->flags = QEMU_ALLOCATED_FLAG;
  1426 +#endif
  1427 + surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height);
  1428 + if (surface->data == NULL) {
  1429 + fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
  1430 + exit(1);
  1431 + }
  1432 +
  1433 + return surface;
  1434 +}
  1435 +
  1436 +DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
  1437 + int width, int height, int bpp, int linesize)
  1438 +{
  1439 + surface->width = width;
  1440 + surface->height = height;
  1441 + surface->linesize = linesize;
  1442 + surface->pf = qemu_default_pixelformat(bpp);
  1443 + if (surface->flags & QEMU_ALLOCATED_FLAG)
  1444 + surface->data = (uint8_t*) qemu_realloc(surface->data, surface->linesize * surface->height);
  1445 + else
  1446 + surface->data = (uint8_t*) qemu_malloc(surface->linesize * surface->height);
  1447 + if (surface->data == NULL) {
  1448 + fprintf(stderr, "qemu_resize_displaysurface: malloc failed\n");
  1449 + exit(1);
  1450 + }
  1451 +#ifdef WORDS_BIGENDIAN
  1452 + surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
  1453 +#else
  1454 + surface->flags = QEMU_ALLOCATED_FLAG;
  1455 +#endif
  1456 +
  1457 + return surface;
  1458 +}
  1459 +
  1460 +DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
  1461 + int linesize, uint8_t *data)
  1462 +{
  1463 + DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
  1464 + if (surface == NULL) {
  1465 + fprintf(stderr, "qemu_create_displaysurface_from: malloc failed\n");
  1466 + exit(1);
  1467 + }
  1468 +
  1469 + surface->width = width;
  1470 + surface->height = height;
  1471 + surface->linesize = linesize;
  1472 + surface->pf = qemu_default_pixelformat(bpp);
  1473 +#ifdef WORDS_BIGENDIAN
  1474 + surface->flags = QEMU_BIG_ENDIAN_FLAG;
  1475 +#endif
  1476 + surface->data = data;
  1477 +
  1478 + return surface;
  1479 +}
  1480 +
  1481 +void qemu_free_displaysurface(DisplaySurface *surface)
  1482 +{
  1483 + if (surface == NULL)
  1484 + return;
  1485 + if (surface->flags & QEMU_ALLOCATED_FLAG)
  1486 + qemu_free(surface->data);
  1487 + qemu_free(surface);
  1488 +}
console.h
@@ -73,75 +73,168 @@ void kbd_put_keysym(int keysym); @@ -73,75 +73,168 @@ void kbd_put_keysym(int keysym);
73 73
74 /* consoles */ 74 /* consoles */
75 75
76 -struct DisplayState {  
77 - uint8_t *data;  
78 - int linesize;  
79 - int depth;  
80 - int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */ 76 +#define QEMU_BIG_ENDIAN_FLAG 0x01
  77 +#define QEMU_ALLOCATED_FLAG 0x02
  78 +
  79 +struct PixelFormat {
  80 + uint8_t bits_per_pixel;
  81 + uint8_t bytes_per_pixel;
  82 + uint8_t depth; /* color depth in bits */
  83 + uint32_t rmask, gmask, bmask, amask;
  84 + uint8_t rshift, gshift, bshift, ashift;
  85 + uint8_t rmax, gmax, bmax, amax;
  86 +};
  87 +
  88 +struct DisplaySurface {
  89 + uint8_t flags;
81 int width; 90 int width;
82 int height; 91 int height;
83 - void *opaque;  
84 - struct QEMUTimer *gui_timer; 92 + int linesize; /* bytes per line */
  93 + uint8_t *data;
  94 +
  95 + struct PixelFormat pf;
  96 +};
  97 +
  98 +struct DisplayChangeListener {
  99 + int idle;
85 uint64_t gui_timer_interval; 100 uint64_t gui_timer_interval;
86 - int idle; /* there is nothing to update (window invisible), set by vnc/sdl */  
87 101
88 void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h); 102 void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
89 - void (*dpy_resize)(struct DisplayState *s, int w, int h); 103 + void (*dpy_resize)(struct DisplayState *s);
  104 + void (*dpy_setdata)(struct DisplayState *s);
90 void (*dpy_refresh)(struct DisplayState *s); 105 void (*dpy_refresh)(struct DisplayState *s);
91 void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, 106 void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
92 int dst_x, int dst_y, int w, int h); 107 int dst_x, int dst_y, int w, int h);
93 void (*dpy_fill)(struct DisplayState *s, int x, int y, 108 void (*dpy_fill)(struct DisplayState *s, int x, int y,
94 int w, int h, uint32_t c); 109 int w, int h, uint32_t c);
95 void (*dpy_text_cursor)(struct DisplayState *s, int x, int y); 110 void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
  111 +
  112 + struct DisplayChangeListener *next;
  113 +};
  114 +
  115 +struct DisplayState {
  116 + struct DisplaySurface *surface;
  117 + void *opaque;
  118 + struct QEMUTimer *gui_timer;
  119 +
  120 + struct DisplayChangeListener* listeners;
  121 +
96 void (*mouse_set)(int x, int y, int on); 122 void (*mouse_set)(int x, int y, int on);
97 void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y, 123 void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
98 uint8_t *image, uint8_t *mask); 124 uint8_t *image, uint8_t *mask);
99 }; 125 };
100 126
  127 +DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize);
  128 +DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
  129 + int width, int height, int bpp, int linesize);
  130 +DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
  131 + int linesize, uint8_t *data);
  132 +void qemu_free_displaysurface(DisplaySurface *surface);
  133 +
  134 +static inline int is_buffer_shared(DisplaySurface *surface)
  135 +{
  136 + return (!(surface->flags & QEMU_ALLOCATED_FLAG));
  137 +}
  138 +
  139 +static inline void register_displaychangelistener(DisplayState *ds, DisplayChangeListener *dcl)
  140 +{
  141 + dcl->next = ds->listeners;
  142 + ds->listeners = dcl;
  143 +}
  144 +
101 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h) 145 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
102 { 146 {
103 - s->dpy_update(s, x, y, w, h); 147 + struct DisplayChangeListener *dcl = s->listeners;
  148 + while (dcl != NULL) {
  149 + dcl->dpy_update(s, x, y, w, h);
  150 + dcl = dcl->next;
  151 + }
104 } 152 }
105 153
106 -static inline void dpy_resize(DisplayState *s, int w, int h) 154 +static inline void dpy_resize(DisplayState *s)
107 { 155 {
108 - s->dpy_resize(s, w, h); 156 + struct DisplayChangeListener *dcl = s->listeners;
  157 + while (dcl != NULL) {
  158 + dcl->dpy_resize(s);
  159 + dcl = dcl->next;
  160 + }
109 } 161 }
110 162
111 -static inline void dpy_cursor(DisplayState *s, int x, int y) 163 +static inline void dpy_setdata(DisplayState *s)
112 { 164 {
113 - if (s->dpy_text_cursor)  
114 - s->dpy_text_cursor(s, x, y); 165 + struct DisplayChangeListener *dcl = s->listeners;
  166 + while (dcl != NULL) {
  167 + if (dcl->dpy_setdata) dcl->dpy_setdata(s);
  168 + dcl = dcl->next;
  169 + }
  170 +}
  171 +
  172 +static inline void dpy_refresh(DisplayState *s)
  173 +{
  174 + struct DisplayChangeListener *dcl = s->listeners;
  175 + while (dcl != NULL) {
  176 + if (dcl->dpy_refresh) dcl->dpy_refresh(s);
  177 + dcl = dcl->next;
  178 + }
  179 +}
  180 +
  181 +static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
  182 + int dst_x, int dst_y, int w, int h) {
  183 + struct DisplayChangeListener *dcl = s->listeners;
  184 + while (dcl != NULL) {
  185 + if (dcl->dpy_copy)
  186 + dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
  187 + else /* TODO */
  188 + dcl->dpy_update(s, dst_x, dst_y, w, h);
  189 + dcl = dcl->next;
  190 + }
  191 +}
  192 +
  193 +static inline void dpy_fill(struct DisplayState *s, int x, int y,
  194 + int w, int h, uint32_t c) {
  195 + struct DisplayChangeListener *dcl = s->listeners;
  196 + while (dcl != NULL) {
  197 + if (dcl->dpy_fill) dcl->dpy_fill(s, x, y, w, h, c);
  198 + dcl = dcl->next;
  199 + }
  200 +}
  201 +
  202 +static inline void dpy_cursor(struct DisplayState *s, int x, int y) {
  203 + struct DisplayChangeListener *dcl = s->listeners;
  204 + while (dcl != NULL) {
  205 + if (dcl->dpy_text_cursor) dcl->dpy_text_cursor(s, x, y);
  206 + dcl = dcl->next;
  207 + }
115 } 208 }
116 209
117 static inline int ds_get_linesize(DisplayState *ds) 210 static inline int ds_get_linesize(DisplayState *ds)
118 { 211 {
119 - return ds->linesize; 212 + return ds->surface->linesize;
120 } 213 }
121 214
122 static inline uint8_t* ds_get_data(DisplayState *ds) 215 static inline uint8_t* ds_get_data(DisplayState *ds)
123 { 216 {
124 - return ds->data; 217 + return ds->surface->data;
125 } 218 }
126 219
127 static inline int ds_get_width(DisplayState *ds) 220 static inline int ds_get_width(DisplayState *ds)
128 { 221 {
129 - return ds->width; 222 + return ds->surface->width;
130 } 223 }
131 224
132 static inline int ds_get_height(DisplayState *ds) 225 static inline int ds_get_height(DisplayState *ds)
133 { 226 {
134 - return ds->height; 227 + return ds->surface->height;
135 } 228 }
136 229
137 static inline int ds_get_bits_per_pixel(DisplayState *ds) 230 static inline int ds_get_bits_per_pixel(DisplayState *ds)
138 { 231 {
139 - return ds->depth; 232 + return ds->surface->pf.bits_per_pixel;
140 } 233 }
141 234
142 static inline int ds_get_bytes_per_pixel(DisplayState *ds) 235 static inline int ds_get_bytes_per_pixel(DisplayState *ds)
143 { 236 {
144 - return (ds->depth / 8); 237 + return ds->surface->pf.bytes_per_pixel;
145 } 238 }
146 239
147 typedef unsigned long console_ch_t; 240 typedef unsigned long console_ch_t;
curses.c
@@ -97,13 +97,13 @@ static void curses_calc_pad(void) @@ -97,13 +97,13 @@ static void curses_calc_pad(void)
97 } 97 }
98 } 98 }
99 99
100 -static void curses_resize(DisplayState *ds, int w, int h) 100 +static void curses_resize(DisplayState *ds)
101 { 101 {
102 - if (w == gwidth && h == gheight) 102 + if (ds_get_width(ds) == gwidth && ds_get_height(ds) == gheight)
103 return; 103 return;
104 104
105 - gwidth = w;  
106 - gheight = h; 105 + gwidth = ds_get_width(ds);
  106 + gheight = ds_get_height(ds);
107 107
108 curses_calc_pad(); 108 curses_calc_pad();
109 } 109 }
@@ -169,8 +169,8 @@ static void curses_refresh(DisplayState *ds) @@ -169,8 +169,8 @@ static void curses_refresh(DisplayState *ds)
169 clear(); 169 clear();
170 refresh(); 170 refresh();
171 curses_calc_pad(); 171 curses_calc_pad();
172 - ds->width = FONT_WIDTH * width;  
173 - ds->height = FONT_HEIGHT * height; 172 + ds->surface->width = FONT_WIDTH * width;
  173 + ds->surface->height = FONT_HEIGHT * height;
174 vga_hw_invalidate(); 174 vga_hw_invalidate();
175 invalidate = 0; 175 invalidate = 0;
176 } 176 }
@@ -197,8 +197,8 @@ static void curses_refresh(DisplayState *ds) @@ -197,8 +197,8 @@ static void curses_refresh(DisplayState *ds)
197 refresh(); 197 refresh();
198 curses_calc_pad(); 198 curses_calc_pad();
199 curses_update(ds, 0, 0, width, height); 199 curses_update(ds, 0, 0, width, height);
200 - ds->width = FONT_WIDTH * width;  
201 - ds->height = FONT_HEIGHT * height; 200 + ds->surface->width = FONT_WIDTH * width;
  201 + ds->surface->height = FONT_HEIGHT * height;
202 continue; 202 continue;
203 } 203 }
204 #endif 204 #endif
@@ -338,6 +338,7 @@ static void curses_keyboard_setup(void) @@ -338,6 +338,7 @@ static void curses_keyboard_setup(void)
338 338
339 void curses_display_init(DisplayState *ds, int full_screen) 339 void curses_display_init(DisplayState *ds, int full_screen)
340 { 340 {
  341 + DisplayChangeListener *dcl;
341 #ifndef _WIN32 342 #ifndef _WIN32
342 if (!isatty(1)) { 343 if (!isatty(1)) {
343 fprintf(stderr, "We need a terminal output\n"); 344 fprintf(stderr, "We need a terminal output\n");
@@ -357,18 +358,19 @@ void curses_display_init(DisplayState *ds, int full_screen) @@ -357,18 +358,19 @@ void curses_display_init(DisplayState *ds, int full_screen)
357 #endif 358 #endif
358 #endif 359 #endif
359 360
360 - ds->data = (void *) screen;  
361 - ds->linesize = 0;  
362 - ds->depth = 0;  
363 - ds->width = 640;  
364 - ds->height = 400;  
365 - ds->dpy_update = curses_update;  
366 - ds->dpy_resize = curses_resize;  
367 - ds->dpy_refresh = curses_refresh;  
368 - ds->dpy_text_cursor = curses_cursor_position; 361 + dcl = (DisplayChangeListener *) qemu_mallocz(sizeof(DisplayChangeListener));
  362 + if (!dcl)
  363 + exit(1);
  364 + dcl->dpy_update = curses_update;
  365 + dcl->dpy_resize = curses_resize;
  366 + dcl->dpy_refresh = curses_refresh;
  367 + dcl->dpy_text_cursor = curses_cursor_position;
  368 + register_displaychangelistener(ds, dcl);
  369 + qemu_free_displaysurface(ds->surface);
  370 + ds->surface = qemu_create_displaysurface_from(80, 25, 0, 0, (uint8_t*) screen);
369 371
370 invalidate = 1; 372 invalidate = 1;
371 373
372 /* Standard VGA initial text mode dimensions */ 374 /* Standard VGA initial text mode dimensions */
373 - curses_resize(ds, 80, 25); 375 + curses_resize(ds);
374 } 376 }
hw/cirrus_vga.c
@@ -793,22 +793,9 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) @@ -793,22 +793,9 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
793 if (BLTUNSAFE(s)) 793 if (BLTUNSAFE(s))
794 return 0; 794 return 0;
795 795
796 - if (s->ds->dpy_copy) {  
797 - cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,  
798 - s->cirrus_blt_srcaddr - s->start_addr,  
799 - s->cirrus_blt_width, s->cirrus_blt_height);  
800 - } else {  
801 - (*s->cirrus_rop) (s, s->vram_ptr +  
802 - (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),  
803 - s->vram_ptr +  
804 - (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),  
805 - s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,  
806 - s->cirrus_blt_width, s->cirrus_blt_height);  
807 -  
808 - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,  
809 - s->cirrus_blt_dstpitch, s->cirrus_blt_width,  
810 - s->cirrus_blt_height);  
811 - } 796 + cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
  797 + s->cirrus_blt_srcaddr - s->start_addr,
  798 + s->cirrus_blt_width, s->cirrus_blt_height);
812 799
813 return 1; 800 return 1;
814 } 801 }
hw/nseries.c
@@ -1360,7 +1360,8 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device, @@ -1360,7 +1360,8 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
1360 /* FIXME: We shouldn't really be doing this here. The LCD controller 1360 /* FIXME: We shouldn't really be doing this here. The LCD controller
1361 will set the size once configured, so this just sets an initial 1361 will set the size once configured, so this just sets an initial
1362 size until the guest activates the display. */ 1362 size until the guest activates the display. */
1363 - dpy_resize(ds, 800, 480); 1363 + ds->surface = qemu_resize_displaysurface(ds->surface, 800, 480, 32, 4 * 800);
  1364 + dpy_resize(ds);
1364 } 1365 }
1365 1366
1366 static struct arm_boot_info n800_binfo = { 1367 static struct arm_boot_info n800_binfo = {
hw/palm.c
@@ -277,7 +277,8 @@ static void palmte_init(ram_addr_t ram_size, int vga_ram_size, @@ -277,7 +277,8 @@ static void palmte_init(ram_addr_t ram_size, int vga_ram_size,
277 /* FIXME: We shouldn't really be doing this here. The LCD controller 277 /* FIXME: We shouldn't really be doing this here. The LCD controller
278 will set the size once configured, so this just sets an initial 278 will set the size once configured, so this just sets an initial
279 size until the guest activates the display. */ 279 size until the guest activates the display. */
280 - dpy_resize(ds, 320, 320); 280 + ds->surface = qemu_resize_displaysurface(ds->surface, 320, 320, 32, 4 * 320);
  281 + dpy_resize(ds);
281 } 282 }
282 283
283 QEMUMachine palmte_machine = { 284 QEMUMachine palmte_machine = {
hw/vga.c
@@ -1243,6 +1243,10 @@ static void vga_get_text_resolution(VGAState *s, int *pwidth, int *pheight, @@ -1243,6 +1243,10 @@ static void vga_get_text_resolution(VGAState *s, int *pwidth, int *pheight,
1243 *pcheight = cheight; 1243 *pcheight = cheight;
1244 } 1244 }
1245 1245
  1246 +typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
  1247 +
  1248 +static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS];
  1249 +
1246 /* 1250 /*
1247 * Text mode update 1251 * Text mode update
1248 * Missing: 1252 * Missing:
@@ -1266,9 +1270,6 @@ static void vga_draw_text(VGAState *s, int full_update) @@ -1266,9 +1270,6 @@ static void vga_draw_text(VGAState *s, int full_update)
1266 1270
1267 vga_dirty_log_stop(s); 1271 vga_dirty_log_stop(s);
1268 1272
1269 - full_update |= update_palette16(s);  
1270 - palette = s->last_palette;  
1271 -  
1272 /* compute font data address (in plane 2) */ 1273 /* compute font data address (in plane 2) */
1273 v = s->sr[3]; 1274 v = s->sr[3];
1274 offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2; 1275 offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
@@ -1303,16 +1304,23 @@ static void vga_draw_text(VGAState *s, int full_update) @@ -1303,16 +1304,23 @@ static void vga_draw_text(VGAState *s, int full_update)
1303 } 1304 }
1304 1305
1305 if (width != s->last_width || height != s->last_height || 1306 if (width != s->last_width || height != s->last_height ||
1306 - cw != s->last_cw || cheight != s->last_ch) { 1307 + cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1307 s->last_scr_width = width * cw; 1308 s->last_scr_width = width * cw;
1308 s->last_scr_height = height * cheight; 1309 s->last_scr_height = height * cheight;
1309 qemu_console_resize(s->console, s->last_scr_width, s->last_scr_height); 1310 qemu_console_resize(s->console, s->last_scr_width, s->last_scr_height);
  1311 + s->last_depth = 0;
1310 s->last_width = width; 1312 s->last_width = width;
1311 s->last_height = height; 1313 s->last_height = height;
1312 s->last_ch = cheight; 1314 s->last_ch = cheight;
1313 s->last_cw = cw; 1315 s->last_cw = cw;
1314 full_update = 1; 1316 full_update = 1;
1315 } 1317 }
  1318 + s->rgb_to_pixel =
  1319 + rgb_to_pixel_dup_table[get_depth_index(s->ds)];
  1320 + full_update |= update_palette16(s);
  1321 + palette = s->last_palette;
  1322 + x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
  1323 +
1316 cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr; 1324 cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
1317 if (cursor_offset != s->cursor_offset || 1325 if (cursor_offset != s->cursor_offset ||
1318 s->cr[0xa] != s->cursor_start || 1326 s->cr[0xa] != s->cursor_start ||
@@ -1504,8 +1512,6 @@ static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = { @@ -1504,8 +1512,6 @@ static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
1504 vga_draw_line32_16bgr, 1512 vga_draw_line32_16bgr,
1505 }; 1513 };
1506 1514
1507 -typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);  
1508 -  
1509 static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = { 1515 static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {
1510 rgb_to_pixel8_dup, 1516 rgb_to_pixel8_dup,
1511 rgb_to_pixel15_dup, 1517 rgb_to_pixel15_dup,
@@ -1580,7 +1586,7 @@ static void vga_sync_dirty_bitmap(VGAState *s) @@ -1580,7 +1586,7 @@ static void vga_sync_dirty_bitmap(VGAState *s)
1580 */ 1586 */
1581 static void vga_draw_graphic(VGAState *s, int full_update) 1587 static void vga_draw_graphic(VGAState *s, int full_update)
1582 { 1588 {
1583 - int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask; 1589 + int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask, depth;
1584 int width, height, shift_control, line_offset, page0, page1, bwidth, bits; 1590 int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
1585 int disp_width, multi_scan, multi_run; 1591 int disp_width, multi_scan, multi_run;
1586 uint8_t *d; 1592 uint8_t *d;
@@ -1663,16 +1669,41 @@ static void vga_draw_graphic(VGAState *s, int full_update) @@ -1663,16 +1669,41 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1663 } 1669 }
1664 vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)]; 1670 vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
1665 1671
1666 - if (disp_width != s->last_width ||  
1667 - height != s->last_height) {  
1668 - qemu_console_resize(s->console, disp_width, height); 1672 + depth = s->get_bpp(s);
  1673 + if (s->line_offset != s->last_line_offset ||
  1674 + disp_width != s->last_width ||
  1675 + height != s->last_height ||
  1676 + s->last_depth != depth) {
  1677 + if (depth == 16 || depth == 32) {
  1678 + if (is_graphic_console()) {
  1679 + qemu_free_displaysurface(s->ds->surface);
  1680 + s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
  1681 + s->line_offset,
  1682 + s->vram_ptr + (s->start_addr * 4));
  1683 + dpy_resize(s->ds);
  1684 + } else {
  1685 + qemu_console_resize(s->console, disp_width, height);
  1686 + }
  1687 + } else {
  1688 + qemu_console_resize(s->console, disp_width, height);
  1689 + }
1669 s->last_scr_width = disp_width; 1690 s->last_scr_width = disp_width;
1670 s->last_scr_height = height; 1691 s->last_scr_height = height;
1671 s->last_width = disp_width; 1692 s->last_width = disp_width;
1672 s->last_height = height; 1693 s->last_height = height;
  1694 + s->last_line_offset = s->line_offset;
  1695 + s->last_depth = depth;
1673 full_update = 1; 1696 full_update = 1;
  1697 + } else if (is_graphic_console() && is_buffer_shared(s->ds->surface) &&
  1698 + (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
  1699 + s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
  1700 + dpy_setdata(s->ds);
1674 } 1701 }
1675 - if (s->cursor_invalidate) 1702 +
  1703 + s->rgb_to_pixel =
  1704 + rgb_to_pixel_dup_table[get_depth_index(s->ds)];
  1705 +
  1706 + if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)
1676 s->cursor_invalidate(s); 1707 s->cursor_invalidate(s);
1677 1708
1678 line_offset = s->line_offset; 1709 line_offset = s->line_offset;
@@ -1718,9 +1749,11 @@ static void vga_draw_graphic(VGAState *s, int full_update) @@ -1718,9 +1749,11 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1718 page_min = page0; 1749 page_min = page0;
1719 if (page1 > page_max) 1750 if (page1 > page_max)
1720 page_max = page1; 1751 page_max = page1;
1721 - vga_draw_line(s, d, s->vram_ptr + addr, width);  
1722 - if (s->cursor_draw_line)  
1723 - s->cursor_draw_line(s, d, y); 1752 + if (!(is_buffer_shared(s->ds->surface))) {
  1753 + vga_draw_line(s, d, s->vram_ptr + addr, width);
  1754 + if (s->cursor_draw_line)
  1755 + s->cursor_draw_line(s, d, y);
  1756 + }
1724 } else { 1757 } else {
1725 if (y_start >= 0) { 1758 if (y_start >= 0) {
1726 /* flush to display */ 1759 /* flush to display */
@@ -1767,6 +1800,8 @@ static void vga_draw_blank(VGAState *s, int full_update) @@ -1767,6 +1800,8 @@ static void vga_draw_blank(VGAState *s, int full_update)
1767 return; 1800 return;
1768 vga_dirty_log_stop(s); 1801 vga_dirty_log_stop(s);
1769 1802
  1803 + s->rgb_to_pixel =
  1804 + rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1770 if (ds_get_bits_per_pixel(s->ds) == 8) 1805 if (ds_get_bits_per_pixel(s->ds) == 8)
1771 val = s->rgb_to_pixel(0, 0, 0); 1806 val = s->rgb_to_pixel(0, 0, 0);
1772 else 1807 else
@@ -1793,9 +1828,6 @@ static void vga_update_display(void *opaque) @@ -1793,9 +1828,6 @@ static void vga_update_display(void *opaque)
1793 if (ds_get_bits_per_pixel(s->ds) == 0) { 1828 if (ds_get_bits_per_pixel(s->ds) == 0) {
1794 /* nothing to do */ 1829 /* nothing to do */
1795 } else { 1830 } else {
1796 - s->rgb_to_pixel =  
1797 - rgb_to_pixel_dup_table[get_depth_index(s->ds)];  
1798 -  
1799 full_update = 0; 1831 full_update = 0;
1800 if (!(s->ar_index & 0x20)) { 1832 if (!(s->ar_index & 0x20)) {
1801 graphic_mode = GMODE_BLANK; 1833 graphic_mode = GMODE_BLANK;
@@ -1966,7 +1998,9 @@ static void vga_update_text(void *opaque, console_ch_t *chardata) @@ -1966,7 +1998,9 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
1966 cw != s->last_cw || cheight != s->last_ch) { 1998 cw != s->last_cw || cheight != s->last_ch) {
1967 s->last_scr_width = width * cw; 1999 s->last_scr_width = width * cw;
1968 s->last_scr_height = height * cheight; 2000 s->last_scr_height = height * cheight;
1969 - qemu_console_resize(s->console, width, height); 2001 + s->ds->surface->width = width;
  2002 + s->ds->surface->height = height;
  2003 + dpy_resize(s->ds);
1970 s->last_width = width; 2004 s->last_width = width;
1971 s->last_height = height; 2005 s->last_height = height;
1972 s->last_ch = cheight; 2006 s->last_ch = cheight;
@@ -2047,7 +2081,9 @@ static void vga_update_text(void *opaque, console_ch_t *chardata) @@ -2047,7 +2081,9 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
2047 s->last_width = 60; 2081 s->last_width = 60;
2048 s->last_height = height = 3; 2082 s->last_height = height = 3;
2049 dpy_cursor(s->ds, -1, -1); 2083 dpy_cursor(s->ds, -1, -1);
2050 - qemu_console_resize(s->console, s->last_width, height); 2084 + s->ds->surface->width = s->last_width;
  2085 + s->ds->surface->height = height;
  2086 + dpy_resize(s->ds);
2051 2087
2052 for (dst = chardata, i = 0; i < s->last_width * height; i ++) 2088 for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2053 console_write_ch(dst ++, ' '); 2089 console_write_ch(dst ++, ' ');
@@ -2505,12 +2541,8 @@ static void vga_save_dpy_update(DisplayState *s, @@ -2505,12 +2541,8 @@ static void vga_save_dpy_update(DisplayState *s,
2505 { 2541 {
2506 } 2542 }
2507 2543
2508 -static void vga_save_dpy_resize(DisplayState *s, int w, int h) 2544 +static void vga_save_dpy_resize(DisplayState *s)
2509 { 2545 {
2510 - s->linesize = w * 4;  
2511 - s->data = qemu_mallocz(h * s->linesize);  
2512 - vga_save_w = w;  
2513 - vga_save_h = h;  
2514 } 2546 }
2515 2547
2516 static void vga_save_dpy_refresh(DisplayState *s) 2548 static void vga_save_dpy_refresh(DisplayState *s)
@@ -2570,24 +2602,29 @@ static void vga_screen_dump_common(VGAState *s, const char *filename, @@ -2570,24 +2602,29 @@ static void vga_screen_dump_common(VGAState *s, const char *filename,
2570 int w, int h) 2602 int w, int h)
2571 { 2603 {
2572 DisplayState *saved_ds, ds1, *ds = &ds1; 2604 DisplayState *saved_ds, ds1, *ds = &ds1;
  2605 + DisplayChangeListener dcl;
2573 2606
2574 /* XXX: this is a little hackish */ 2607 /* XXX: this is a little hackish */
2575 vga_invalidate_display(s); 2608 vga_invalidate_display(s);
2576 saved_ds = s->ds; 2609 saved_ds = s->ds;
2577 2610
2578 memset(ds, 0, sizeof(DisplayState)); 2611 memset(ds, 0, sizeof(DisplayState));
2579 - ds->dpy_update = vga_save_dpy_update;  
2580 - ds->dpy_resize = vga_save_dpy_resize;  
2581 - ds->dpy_refresh = vga_save_dpy_refresh;  
2582 - ds->depth = 32; 2612 + memset(&dcl, 0, sizeof(DisplayChangeListener));
  2613 + dcl.dpy_update = vga_save_dpy_update;
  2614 + dcl.dpy_resize = vga_save_dpy_resize;
  2615 + dcl.dpy_refresh = vga_save_dpy_refresh;
  2616 + register_displaychangelistener(ds, &dcl);
  2617 + ds->surface = qemu_create_displaysurface(ds_get_width(saved_ds),
  2618 + ds_get_height(saved_ds), 32, 4 * ds_get_width(saved_ds));
2583 2619
2584 - ds->linesize = w * sizeof(uint32_t);  
2585 - ds->data = qemu_mallocz(h * ds->linesize);  
2586 s->ds = ds; 2620 s->ds = ds;
2587 s->graphic_mode = -1; 2621 s->graphic_mode = -1;
2588 vga_update_display(s); 2622 vga_update_display(s);
2589 - ppm_save(filename, ds->data, w, h, ds->linesize);  
2590 - qemu_free(ds->data); 2623 +
  2624 + ppm_save(filename, ds_get_data(ds), vga_save_w, vga_save_h,
  2625 + ds_get_linesize(ds));
  2626 +
  2627 + qemu_free_displaysurface(ds->surface);
2591 s->ds = saved_ds; 2628 s->ds = saved_ds;
2592 } 2629 }
2593 2630
hw/vga_int.h
@@ -154,9 +154,11 @@ typedef void (* vga_update_retrace_info_fn)(struct VGAState *s); @@ -154,9 +154,11 @@ typedef void (* vga_update_retrace_info_fn)(struct VGAState *s);
154 uint32_t line_compare; \ 154 uint32_t line_compare; \
155 uint32_t start_addr; \ 155 uint32_t start_addr; \
156 uint32_t plane_updated; \ 156 uint32_t plane_updated; \
  157 + uint32_t last_line_offset; \
157 uint8_t last_cw, last_ch; \ 158 uint8_t last_cw, last_ch; \
158 uint32_t last_width, last_height; /* in chars or pixels */ \ 159 uint32_t last_width, last_height; /* in chars or pixels */ \
159 uint32_t last_scr_width, last_scr_height; /* in pixels */ \ 160 uint32_t last_scr_width, last_scr_height; /* in pixels */ \
  161 + uint32_t last_depth; /* in bits */ \
160 uint8_t cursor_start, cursor_end; \ 162 uint8_t cursor_start, cursor_end; \
161 uint32_t cursor_offset; \ 163 uint32_t cursor_offset; \
162 unsigned int (*rgb_to_pixel)(unsigned int r, \ 164 unsigned int (*rgb_to_pixel)(unsigned int r, \
qemu-common.h
@@ -166,6 +166,9 @@ typedef struct HCIInfo HCIInfo; @@ -166,6 +166,9 @@ typedef struct HCIInfo HCIInfo;
166 typedef struct AudioState AudioState; 166 typedef struct AudioState AudioState;
167 typedef struct BlockDriverState BlockDriverState; 167 typedef struct BlockDriverState BlockDriverState;
168 typedef struct DisplayState DisplayState; 168 typedef struct DisplayState DisplayState;
  169 +typedef struct DisplayChangeListener DisplayChangeListener;
  170 +typedef struct DisplaySurface DisplaySurface;
  171 +typedef struct PixelFormat PixelFormat;
169 typedef struct TextConsole TextConsole; 172 typedef struct TextConsole TextConsole;
170 typedef TextConsole QEMUConsole; 173 typedef TextConsole QEMUConsole;
171 typedef struct CharDriverState CharDriverState; 174 typedef struct CharDriverState CharDriverState;
@@ -31,7 +31,9 @@ @@ -31,7 +31,9 @@
31 #include <signal.h> 31 #include <signal.h>
32 #endif 32 #endif
33 33
34 -static SDL_Surface *screen; 34 +static DisplayChangeListener *dcl;
  35 +static SDL_Surface *real_screen;
  36 +static SDL_Surface *guest_screen = NULL;
35 static int gui_grab; /* if true, all keyboard/mouse events are grabbed */ 37 static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
36 static int last_vm_running; 38 static int last_vm_running;
37 static int gui_saved_grab; 39 static int gui_saved_grab;
@@ -52,11 +54,34 @@ static SDL_Cursor *guest_sprite = 0; @@ -52,11 +54,34 @@ static SDL_Cursor *guest_sprite = 0;
52 54
53 static void sdl_update(DisplayState *ds, int x, int y, int w, int h) 55 static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
54 { 56 {
  57 + SDL_Rect rec;
  58 + rec.x = x;
  59 + rec.y = y;
  60 + rec.w = w;
  61 + rec.h = h;
55 // printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h); 62 // printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
56 - SDL_UpdateRect(screen, x, y, w, h); 63 +
  64 + SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
  65 + SDL_Flip(real_screen);
  66 +}
  67 +
  68 +static void sdl_setdata(DisplayState *ds)
  69 +{
  70 + SDL_Rect rec;
  71 + rec.x = 0;
  72 + rec.y = 0;
  73 + rec.w = real_screen->w;
  74 + rec.h = real_screen->h;
  75 +
  76 + if (guest_screen != NULL) SDL_FreeSurface(guest_screen);
  77 +
  78 + guest_screen = SDL_CreateRGBSurfaceFrom(ds_get_data(ds), ds_get_width(ds), ds_get_height(ds),
  79 + ds_get_bits_per_pixel(ds), ds_get_linesize(ds),
  80 + ds->surface->pf.rmask, ds->surface->pf.gmask,
  81 + ds->surface->pf.bmask, ds->surface->pf.amask);
57 } 82 }
58 83
59 -static void sdl_resize(DisplayState *ds, int w, int h) 84 +static void sdl_resize(DisplayState *ds)
60 { 85 {
61 int flags; 86 int flags;
62 87
@@ -68,40 +93,23 @@ static void sdl_resize(DisplayState *ds, int w, int h) @@ -68,40 +93,23 @@ static void sdl_resize(DisplayState *ds, int w, int h)
68 if (gui_noframe) 93 if (gui_noframe)
69 flags |= SDL_NOFRAME; 94 flags |= SDL_NOFRAME;
70 95
71 - width = w;  
72 - height = h;  
73 -  
74 again: 96 again:
75 - screen = SDL_SetVideoMode(w, h, 0, flags);  
76 - if (!screen) { 97 + real_screen = SDL_SetVideoMode(ds_get_width(ds), ds_get_height(ds), 0, flags);
  98 + if (!real_screen) {
77 fprintf(stderr, "Could not open SDL display\n"); 99 fprintf(stderr, "Could not open SDL display\n");
78 exit(1); 100 exit(1);
79 } 101 }
80 - if (!screen->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) { 102 + if (!real_screen->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) {
81 flags &= ~SDL_HWSURFACE; 103 flags &= ~SDL_HWSURFACE;
82 goto again; 104 goto again;
83 } 105 }
84 106
85 - if (!screen->pixels) { 107 + if (!real_screen->pixels) {
86 fprintf(stderr, "Could not open SDL display\n"); 108 fprintf(stderr, "Could not open SDL display\n");
87 exit(1); 109 exit(1);
88 } 110 }
89 - ds->data = screen->pixels;  
90 - ds->linesize = screen->pitch;  
91 - ds->depth = screen->format->BitsPerPixel;  
92 - /* SDL BitsPerPixel never indicates any values other than  
93 - multiples of 8, so we need to check for strange depths. */  
94 - if (ds->depth == 16) {  
95 - uint32_t mask;  
96 -  
97 - mask = screen->format->Rmask;  
98 - mask |= screen->format->Gmask;  
99 - mask |= screen->format->Bmask;  
100 - if ((mask & 0x8000) == 0)  
101 - ds->depth = 15;  
102 - }  
103 - ds->width = w;  
104 - ds->height = h; 111 +
  112 + sdl_setdata(ds);
105 } 113 }
106 114
107 /* generic keyboard conversion */ 115 /* generic keyboard conversion */
@@ -337,7 +345,7 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state @@ -337,7 +345,7 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state
337 static void toggle_full_screen(DisplayState *ds) 345 static void toggle_full_screen(DisplayState *ds)
338 { 346 {
339 gui_fullscreen = !gui_fullscreen; 347 gui_fullscreen = !gui_fullscreen;
340 - sdl_resize(ds, screen->w, screen->h); 348 + sdl_resize(ds);
341 if (gui_fullscreen) { 349 if (gui_fullscreen) {
342 gui_saved_grab = gui_grab; 350 gui_saved_grab = gui_grab;
343 sdl_grab_start(); 351 sdl_grab_start();
@@ -366,7 +374,7 @@ static void sdl_refresh(DisplayState *ds) @@ -366,7 +374,7 @@ static void sdl_refresh(DisplayState *ds)
366 while (SDL_PollEvent(ev)) { 374 while (SDL_PollEvent(ev)) {
367 switch (ev->type) { 375 switch (ev->type) {
368 case SDL_VIDEOEXPOSE: 376 case SDL_VIDEOEXPOSE:
369 - sdl_update(ds, 0, 0, screen->w, screen->h); 377 + sdl_update(ds, 0, 0, real_screen->w, real_screen->h);
370 break; 378 break;
371 case SDL_KEYDOWN: 379 case SDL_KEYDOWN:
372 case SDL_KEYUP: 380 case SDL_KEYUP:
@@ -521,12 +529,12 @@ static void sdl_refresh(DisplayState *ds) @@ -521,12 +529,12 @@ static void sdl_refresh(DisplayState *ds)
521 if (ev->active.state & SDL_APPACTIVE) { 529 if (ev->active.state & SDL_APPACTIVE) {
522 if (ev->active.gain) { 530 if (ev->active.gain) {
523 /* Back to default interval */ 531 /* Back to default interval */
524 - ds->gui_timer_interval = 0;  
525 - ds->idle = 0; 532 + dcl->gui_timer_interval = 0;
  533 + dcl->idle = 0;
526 } else { 534 } else {
527 /* Sleeping interval */ 535 /* Sleeping interval */
528 - ds->gui_timer_interval = 500;  
529 - ds->idle = 1; 536 + dcl->gui_timer_interval = 500;
  537 + dcl->idle = 1;
530 } 538 }
531 } 539 }
532 break; 540 break;
@@ -539,7 +547,7 @@ static void sdl_refresh(DisplayState *ds) @@ -539,7 +547,7 @@ static void sdl_refresh(DisplayState *ds)
539 static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c) 547 static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
540 { 548 {
541 SDL_Rect dst = { x, y, w, h }; 549 SDL_Rect dst = { x, y, w, h };
542 - SDL_FillRect(screen, &dst, c); 550 + SDL_FillRect(real_screen, &dst, c);
543 } 551 }
544 552
545 static void sdl_mouse_warp(int x, int y, int on) 553 static void sdl_mouse_warp(int x, int y, int on)
@@ -635,14 +643,18 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) @@ -635,14 +643,18 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
635 exit(1); 643 exit(1);
636 } 644 }
637 645
638 - ds->dpy_update = sdl_update;  
639 - ds->dpy_resize = sdl_resize;  
640 - ds->dpy_refresh = sdl_refresh;  
641 - ds->dpy_fill = sdl_fill; 646 + dcl = qemu_mallocz(sizeof(DisplayChangeListener));
  647 + if (!dcl)
  648 + exit(1);
  649 + dcl->dpy_update = sdl_update;
  650 + dcl->dpy_resize = sdl_resize;
  651 + dcl->dpy_refresh = sdl_refresh;
  652 + dcl->dpy_setdata = sdl_setdata;
  653 + dcl->dpy_fill = sdl_fill;
642 ds->mouse_set = sdl_mouse_warp; 654 ds->mouse_set = sdl_mouse_warp;
643 ds->cursor_define = sdl_mouse_define; 655 ds->cursor_define = sdl_mouse_define;
  656 + register_displaychangelistener(ds, dcl);
644 657
645 - sdl_resize(ds, 640, 400);  
646 sdl_update_caption(); 658 sdl_update_caption();
647 SDL_EnableKeyRepeat(250, 50); 659 SDL_EnableKeyRepeat(250, 50);
648 gui_grab = 0; 660 gui_grab = 0;
@@ -193,6 +193,7 @@ enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; @@ -193,6 +193,7 @@ enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
193 DisplayState display_state; 193 DisplayState display_state;
194 int nographic; 194 int nographic;
195 static int curses; 195 static int curses;
  196 +static int sdl;
196 const char* keyboard_layout = NULL; 197 const char* keyboard_layout = NULL;
197 int64_t ticks_per_sec; 198 int64_t ticks_per_sec;
198 ram_addr_t ram_size; 199 ram_addr_t ram_size;
@@ -2764,20 +2765,21 @@ static void dumb_update(DisplayState *ds, int x, int y, int w, int h) @@ -2764,20 +2765,21 @@ static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
2764 { 2765 {
2765 } 2766 }
2766 2767
2767 -static void dumb_resize(DisplayState *ds, int w, int h) 2768 +static void dumb_resize(DisplayState *ds)
2768 { 2769 {
2769 } 2770 }
2770 2771
2771 static void dumb_display_init(DisplayState *ds) 2772 static void dumb_display_init(DisplayState *ds)
2772 { 2773 {
2773 - ds->data = NULL;  
2774 - ds->linesize = 0;  
2775 - ds->depth = 0;  
2776 - ds->dpy_update = dumb_update;  
2777 - ds->dpy_resize = dumb_resize;  
2778 - ds->dpy_refresh = NULL;  
2779 - ds->gui_timer_interval = 0;  
2780 - ds->idle = 1; 2774 + DisplayChangeListener *dcl = qemu_mallocz(sizeof(DisplayChangeListener));
  2775 + if (!dcl)
  2776 + exit(1);
  2777 + dcl->dpy_update = dumb_update;
  2778 + dcl->dpy_resize = dumb_resize;
  2779 + dcl->dpy_refresh = NULL;
  2780 + dcl->idle = 1;
  2781 + dcl->gui_timer_interval = 500;
  2782 + register_displaychangelistener(ds, dcl);
2781 } 2783 }
2782 2784
2783 /***********************************************************/ 2785 /***********************************************************/
@@ -3360,13 +3362,19 @@ static QEMUMachine *find_machine(const char *name) @@ -3360,13 +3362,19 @@ static QEMUMachine *find_machine(const char *name)
3360 3362
3361 static void gui_update(void *opaque) 3363 static void gui_update(void *opaque)
3362 { 3364 {
  3365 + uint64_t interval = GUI_REFRESH_INTERVAL;
3363 DisplayState *ds = opaque; 3366 DisplayState *ds = opaque;
3364 - ds->dpy_refresh(ds);  
3365 - qemu_mod_timer(ds->gui_timer,  
3366 - (ds->gui_timer_interval ?  
3367 - ds->gui_timer_interval :  
3368 - GUI_REFRESH_INTERVAL)  
3369 - + qemu_get_clock(rt_clock)); 3367 + DisplayChangeListener *dcl = ds->listeners;
  3368 +
  3369 + dpy_refresh(ds);
  3370 +
  3371 + while (dcl != NULL) {
  3372 + if (dcl->gui_timer_interval &&
  3373 + dcl->gui_timer_interval < interval)
  3374 + interval = dcl->gui_timer_interval;
  3375 + dcl = dcl->next;
  3376 + }
  3377 + qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
3370 } 3378 }
3371 3379
3372 struct vm_change_state_entry { 3380 struct vm_change_state_entry {
@@ -3848,6 +3856,7 @@ static void help(int exitcode) @@ -3848,6 +3856,7 @@ static void help(int exitcode)
3848 "-no-frame open SDL window without a frame and window decorations\n" 3856 "-no-frame open SDL window without a frame and window decorations\n"
3849 "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n" 3857 "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
3850 "-no-quit disable SDL window close capability\n" 3858 "-no-quit disable SDL window close capability\n"
  3859 + "-sdl enable SDL\n"
3851 #endif 3860 #endif
3852 #ifdef TARGET_I386 3861 #ifdef TARGET_I386
3853 "-no-fd-bootchk disable boot signature checking for floppy disks\n" 3862 "-no-fd-bootchk disable boot signature checking for floppy disks\n"
@@ -4064,6 +4073,7 @@ enum { @@ -4064,6 +4073,7 @@ enum {
4064 QEMU_OPTION_no_frame, 4073 QEMU_OPTION_no_frame,
4065 QEMU_OPTION_alt_grab, 4074 QEMU_OPTION_alt_grab,
4066 QEMU_OPTION_no_quit, 4075 QEMU_OPTION_no_quit,
  4076 + QEMU_OPTION_sdl,
4067 QEMU_OPTION_pidfile, 4077 QEMU_OPTION_pidfile,
4068 QEMU_OPTION_no_kqemu, 4078 QEMU_OPTION_no_kqemu,
4069 QEMU_OPTION_kernel_kqemu, 4079 QEMU_OPTION_kernel_kqemu,
@@ -4176,6 +4186,7 @@ static const QEMUOption qemu_options[] = { @@ -4176,6 +4186,7 @@ static const QEMUOption qemu_options[] = {
4176 { "no-frame", 0, QEMU_OPTION_no_frame }, 4186 { "no-frame", 0, QEMU_OPTION_no_frame },
4177 { "alt-grab", 0, QEMU_OPTION_alt_grab }, 4187 { "alt-grab", 0, QEMU_OPTION_alt_grab },
4178 { "no-quit", 0, QEMU_OPTION_no_quit }, 4188 { "no-quit", 0, QEMU_OPTION_no_quit },
  4189 + { "sdl", 0, QEMU_OPTION_sdl },
4179 #endif 4190 #endif
4180 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, 4191 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
4181 { "win2k-hack", 0, QEMU_OPTION_win2k_hack }, 4192 { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
@@ -4495,6 +4506,7 @@ int main(int argc, char **argv, char **envp) @@ -4495,6 +4506,7 @@ int main(int argc, char **argv, char **envp)
4495 const char *kernel_filename, *kernel_cmdline; 4506 const char *kernel_filename, *kernel_cmdline;
4496 const char *boot_devices = ""; 4507 const char *boot_devices = "";
4497 DisplayState *ds = &display_state; 4508 DisplayState *ds = &display_state;
  4509 + DisplayChangeListener *dcl;
4498 int cyls, heads, secs, translation; 4510 int cyls, heads, secs, translation;
4499 const char *net_clients[MAX_NET_CLIENTS]; 4511 const char *net_clients[MAX_NET_CLIENTS];
4500 int nb_net_clients; 4512 int nb_net_clients;
@@ -5007,6 +5019,9 @@ int main(int argc, char **argv, char **envp) @@ -5007,6 +5019,9 @@ int main(int argc, char **argv, char **envp)
5007 case QEMU_OPTION_no_quit: 5019 case QEMU_OPTION_no_quit:
5008 no_quit = 1; 5020 no_quit = 1;
5009 break; 5021 break;
  5022 + case QEMU_OPTION_sdl:
  5023 + sdl = 1;
  5024 + break;
5010 #endif 5025 #endif
5011 case QEMU_OPTION_pidfile: 5026 case QEMU_OPTION_pidfile:
5012 pid_file = optarg; 5027 pid_file = optarg;
@@ -5404,6 +5419,7 @@ int main(int argc, char **argv, char **envp) @@ -5404,6 +5419,7 @@ int main(int argc, char **argv, char **envp)
5404 5419
5405 /* terminal init */ 5420 /* terminal init */
5406 memset(&display_state, 0, sizeof(display_state)); 5421 memset(&display_state, 0, sizeof(display_state));
  5422 + ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
5407 if (nographic) { 5423 if (nographic) {
5408 if (curses) { 5424 if (curses) {
5409 fprintf(stderr, "fatal: -nographic can't be used with -curses\n"); 5425 fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
@@ -5411,26 +5427,30 @@ int main(int argc, char **argv, char **envp) @@ -5411,26 +5427,30 @@ int main(int argc, char **argv, char **envp)
5411 } 5427 }
5412 /* nearly nothing to do */ 5428 /* nearly nothing to do */
5413 dumb_display_init(ds); 5429 dumb_display_init(ds);
5414 - } else if (vnc_display != NULL) {  
5415 - vnc_display_init(ds);  
5416 - if (vnc_display_open(ds, vnc_display) < 0)  
5417 - exit(1);  
5418 - } else 5430 + } else {
5419 #if defined(CONFIG_CURSES) 5431 #if defined(CONFIG_CURSES)
5420 - if (curses) {  
5421 - curses_display_init(ds, full_screen);  
5422 - } else 5432 + if (curses) {
  5433 + /* At the moment curses cannot be used with other displays */
  5434 + curses_display_init(ds, full_screen);
  5435 + } else
5423 #endif 5436 #endif
5424 - { 5437 + {
  5438 + if (vnc_display != NULL) {
  5439 + vnc_display_init(ds);
  5440 + if (vnc_display_open(ds, vnc_display) < 0)
  5441 + exit(1);
  5442 + }
  5443 + if (sdl || !vnc_display)
5425 #if defined(CONFIG_SDL) 5444 #if defined(CONFIG_SDL)
5426 - sdl_display_init(ds, full_screen, no_frame); 5445 + sdl_display_init(ds, full_screen, no_frame);
5427 #elif defined(CONFIG_COCOA) 5446 #elif defined(CONFIG_COCOA)
5428 - cocoa_display_init(ds, full_screen); 5447 + cocoa_display_init(ds, full_screen);
5429 #else 5448 #else
5430 - dumb_display_init(ds); 5449 + dumb_display_init(ds);
5431 #endif 5450 #endif
  5451 + }
5432 } 5452 }
5433 - 5453 + dpy_resize(ds);
5434 #ifndef _WIN32 5454 #ifndef _WIN32
5435 /* must be after terminal init, SDL library changes signal handlers */ 5455 /* must be after terminal init, SDL library changes signal handlers */
5436 termsig_setup(); 5456 termsig_setup();
@@ -5541,11 +5561,14 @@ int main(int argc, char **argv, char **envp) @@ -5541,11 +5561,14 @@ int main(int argc, char **argv, char **envp)
5541 } 5561 }
5542 } 5562 }
5543 5563
5544 - if (display_state.dpy_refresh) {  
5545 - display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);  
5546 - qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock)); 5564 + dcl = ds->listeners;
  5565 + while (dcl != NULL) {
  5566 + if (dcl->dpy_refresh != NULL) {
  5567 + display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
  5568 + qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
  5569 + }
  5570 + dcl = dcl->next;
5547 } 5571 }
5548 -  
5549 #ifdef CONFIG_GDBSTUB 5572 #ifdef CONFIG_GDBSTUB
5550 if (use_gdbstub) { 5573 if (use_gdbstub) {
5551 /* XXX: use standard host:port notation and modify options 5574 /* XXX: use standard host:port notation and modify options
@@ -180,6 +180,7 @@ struct VncState @@ -180,6 +180,7 @@ struct VncState
180 }; 180 };
181 181
182 static VncState *vnc_state; /* needed for info vnc */ 182 static VncState *vnc_state; /* needed for info vnc */
  183 +static DisplayChangeListener *dcl;
183 184
184 void do_info_vnc(void) 185 void do_info_vnc(void)
185 { 186 {
@@ -213,7 +214,7 @@ static void vnc_flush(VncState *vs); @@ -213,7 +214,7 @@ static void vnc_flush(VncState *vs);
213 static void vnc_update_client(void *opaque); 214 static void vnc_update_client(void *opaque);
214 static void vnc_client_read(void *opaque); 215 static void vnc_client_read(void *opaque);
215 216
216 -static void vnc_colordepth(DisplayState *ds, int depth); 217 +static void vnc_colordepth(DisplayState *ds);
217 218
218 static inline void vnc_set_bit(uint32_t *d, int k) 219 static inline void vnc_set_bit(uint32_t *d, int k)
219 { 220 {
@@ -291,35 +292,30 @@ static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, @@ -291,35 +292,30 @@ static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
291 vnc_write_s32(vs, encoding); 292 vnc_write_s32(vs, encoding);
292 } 293 }
293 294
294 -static void vnc_dpy_resize(DisplayState *ds, int w, int h) 295 +static void vnc_dpy_resize(DisplayState *ds)
295 { 296 {
296 int size_changed; 297 int size_changed;
297 VncState *vs = ds->opaque; 298 VncState *vs = ds->opaque;
298 299
299 - ds->data = qemu_realloc(ds->data, w * h * vs->depth);  
300 - vs->old_data = qemu_realloc(vs->old_data, w * h * vs->depth); 300 + vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
301 301
302 - if (ds->data == NULL || vs->old_data == NULL) { 302 + if (vs->old_data == NULL) {
303 fprintf(stderr, "vnc: memory allocation failed\n"); 303 fprintf(stderr, "vnc: memory allocation failed\n");
304 exit(1); 304 exit(1);
305 } 305 }
306 306
307 - if (ds->depth != vs->depth * 8) {  
308 - ds->depth = vs->depth * 8; 307 + if (ds_get_bytes_per_pixel(ds) != vs->depth)
309 console_color_init(ds); 308 console_color_init(ds);
310 - }  
311 - size_changed = ds->width != w || ds->height != h;  
312 - ds->width = w;  
313 - ds->height = h;  
314 - ds->linesize = w * vs->depth; 309 + vnc_colordepth(ds);
  310 + size_changed = ds_get_width(ds) != vs->width || ds_get_height(ds) != vs->height;
315 if (size_changed) { 311 if (size_changed) {
316 - vs->width = ds->width;  
317 - vs->height = ds->height; 312 + vs->width = ds_get_width(ds);
  313 + vs->height = ds_get_height(ds);
318 if (vs->csock != -1 && vs->has_resize) { 314 if (vs->csock != -1 && vs->has_resize) {
319 vnc_write_u8(vs, 0); /* msg id */ 315 vnc_write_u8(vs, 0); /* msg id */
320 vnc_write_u8(vs, 0); 316 vnc_write_u8(vs, 0);
321 vnc_write_u16(vs, 1); /* number of rects */ 317 vnc_write_u16(vs, 1); /* number of rects */
322 - vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223); 318 + vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), -223);
323 vnc_flush(vs); 319 vnc_flush(vs);
324 } 320 }
325 } 321 }
@@ -494,36 +490,10 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) @@ -494,36 +490,10 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
494 490
495 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h) 491 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
496 { 492 {
497 - int src, dst;  
498 - uint8_t *src_row;  
499 - uint8_t *dst_row;  
500 - char *old_row;  
501 - int y = 0;  
502 - int pitch = ds_get_linesize(ds);  
503 VncState *vs = ds->opaque; 493 VncState *vs = ds->opaque;
504 494
505 vnc_update_client(vs); 495 vnc_update_client(vs);
506 496
507 - if (dst_y > src_y) {  
508 - y = h - 1;  
509 - pitch = -pitch;  
510 - }  
511 -  
512 - src = (ds_get_linesize(ds) * (src_y + y) + vs->depth * src_x);  
513 - dst = (ds_get_linesize(ds) * (dst_y + y) + vs->depth * dst_x);  
514 -  
515 - src_row = ds_get_data(ds) + src;  
516 - dst_row = ds_get_data(ds) + dst;  
517 - old_row = vs->old_data + dst;  
518 -  
519 - for (y = 0; y < h; y++) {  
520 - memmove(old_row, src_row, w * vs->depth);  
521 - memmove(dst_row, src_row, w * vs->depth);  
522 - src_row += pitch;  
523 - dst_row += pitch;  
524 - old_row += pitch;  
525 - }  
526 -  
527 vnc_write_u8(vs, 0); /* msg id */ 497 vnc_write_u8(vs, 0); /* msg id */
528 vnc_write_u8(vs, 0); 498 vnc_write_u8(vs, 0);
529 vnc_write_u16(vs, 1); /* number of rects */ 499 vnc_write_u16(vs, 1); /* number of rects */
@@ -770,7 +740,7 @@ static int vnc_client_io_error(VncState *vs, int ret, int last_errno) @@ -770,7 +740,7 @@ static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
770 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL); 740 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
771 closesocket(vs->csock); 741 closesocket(vs->csock);
772 vs->csock = -1; 742 vs->csock = -1;
773 - vs->ds->idle = 1; 743 + dcl->idle = 1;
774 buffer_reset(&vs->input); 744 buffer_reset(&vs->input);
775 buffer_reset(&vs->output); 745 buffer_reset(&vs->output);
776 vs->need_update = 0; 746 vs->need_update = 0;
@@ -1226,7 +1196,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) @@ -1226,7 +1196,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1226 vs->has_pointer_type_change = 0; 1196 vs->has_pointer_type_change = 0;
1227 vs->has_WMVi = 0; 1197 vs->has_WMVi = 0;
1228 vs->absolute = -1; 1198 vs->absolute = -1;
1229 - vs->ds->dpy_copy = NULL; 1199 + dcl->dpy_copy = NULL;
1230 1200
1231 for (i = n_encodings - 1; i >= 0; i--) { 1201 for (i = n_encodings - 1; i >= 0; i--) {
1232 switch (encodings[i]) { 1202 switch (encodings[i]) {
@@ -1234,7 +1204,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) @@ -1234,7 +1204,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1234 vs->has_hextile = 0; 1204 vs->has_hextile = 0;
1235 break; 1205 break;
1236 case 1: /* CopyRect */ 1206 case 1: /* CopyRect */
1237 - vs->ds->dpy_copy = vnc_copy; 1207 + dcl->dpy_copy = vnc_copy;
1238 break; 1208 break;
1239 case 5: /* Hextile */ 1209 case 5: /* Hextile */
1240 vs->has_hextile = 1; 1210 vs->has_hextile = 1;
@@ -1387,33 +1357,25 @@ static void pixel_format_message (VncState *vs) { @@ -1387,33 +1357,25 @@ static void pixel_format_message (VncState *vs) {
1387 vnc_write(vs, pad, 3); /* padding */ 1357 vnc_write(vs, pad, 3); /* padding */
1388 } 1358 }
1389 1359
1390 -static void vnc_colordepth(DisplayState *ds, int depth) 1360 +static void vnc_dpy_setdata(DisplayState *ds)
  1361 +{
  1362 + /* We don't have to do anything */
  1363 +}
  1364 +
  1365 +static void vnc_colordepth(DisplayState *ds)
1391 { 1366 {
1392 int host_big_endian_flag; 1367 int host_big_endian_flag;
1393 struct VncState *vs = ds->opaque; 1368 struct VncState *vs = ds->opaque;
1394 1369
1395 - switch (depth) {  
1396 - case 24:  
1397 - if (ds->depth == 32) return;  
1398 - depth = 32;  
1399 - break;  
1400 - case 15:  
1401 - case 8:  
1402 - case 0:  
1403 - return;  
1404 - default:  
1405 - break;  
1406 - }  
1407 -  
1408 #ifdef WORDS_BIGENDIAN 1370 #ifdef WORDS_BIGENDIAN
1409 host_big_endian_flag = 1; 1371 host_big_endian_flag = 1;
1410 #else 1372 #else
1411 host_big_endian_flag = 0; 1373 host_big_endian_flag = 0;
1412 #endif 1374 #endif
1413 1375
1414 - switch (depth) { 1376 + switch (ds_get_bits_per_pixel(ds)) {
1415 case 8: 1377 case 8:
1416 - vs->depth = depth / 8; 1378 + vs->depth = 1;
1417 vs->server_red_max = 7; 1379 vs->server_red_max = 7;
1418 vs->server_green_max = 7; 1380 vs->server_green_max = 7;
1419 vs->server_blue_max = 3; 1381 vs->server_blue_max = 3;
@@ -1422,7 +1384,7 @@ static void vnc_colordepth(DisplayState *ds, int depth) @@ -1422,7 +1384,7 @@ static void vnc_colordepth(DisplayState *ds, int depth)
1422 vs->server_blue_shift = 0; 1384 vs->server_blue_shift = 0;
1423 break; 1385 break;
1424 case 16: 1386 case 16:
1425 - vs->depth = depth / 8; 1387 + vs->depth = 2;
1426 vs->server_red_max = 31; 1388 vs->server_red_max = 31;
1427 vs->server_green_max = 63; 1389 vs->server_green_max = 63;
1428 vs->server_blue_max = 31; 1390 vs->server_blue_max = 31;
@@ -1448,7 +1410,7 @@ static void vnc_colordepth(DisplayState *ds, int depth) @@ -1448,7 +1410,7 @@ static void vnc_colordepth(DisplayState *ds, int depth)
1448 vnc_write_u8(vs, 0); /* msg id */ 1410 vnc_write_u8(vs, 0); /* msg id */
1449 vnc_write_u8(vs, 0); 1411 vnc_write_u8(vs, 0);
1450 vnc_write_u16(vs, 1); /* number of rects */ 1412 vnc_write_u16(vs, 1); /* number of rects */
1451 - vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669); 1413 + vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), 0x574D5669);
1452 pixel_format_message(vs); 1414 pixel_format_message(vs);
1453 vnc_flush(vs); 1415 vnc_flush(vs);
1454 } else { 1416 } else {
@@ -2237,7 +2199,7 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len) @@ -2237,7 +2199,7 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2237 static void vnc_connect(VncState *vs) 2199 static void vnc_connect(VncState *vs)
2238 { 2200 {
2239 VNC_DEBUG("New client on socket %d\n", vs->csock); 2201 VNC_DEBUG("New client on socket %d\n", vs->csock);
2240 - vs->ds->idle = 0; 2202 + dcl->idle = 0;
2241 socket_set_nonblock(vs->csock); 2203 socket_set_nonblock(vs->csock);
2242 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); 2204 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
2243 vnc_write(vs, "RFB 003.008\n", 12); 2205 vnc_write(vs, "RFB 003.008\n", 12);
@@ -2247,7 +2209,7 @@ static void vnc_connect(VncState *vs) @@ -2247,7 +2209,7 @@ static void vnc_connect(VncState *vs)
2247 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); 2209 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
2248 vs->has_resize = 0; 2210 vs->has_resize = 0;
2249 vs->has_hextile = 0; 2211 vs->has_hextile = 0;
2250 - vs->ds->dpy_copy = NULL; 2212 + dcl->dpy_copy = NULL;
2251 vnc_update_client(vs); 2213 vnc_update_client(vs);
2252 reset_keys(vs); 2214 reset_keys(vs);
2253 } 2215 }
@@ -2272,11 +2234,12 @@ void vnc_display_init(DisplayState *ds) @@ -2272,11 +2234,12 @@ void vnc_display_init(DisplayState *ds)
2272 VncState *vs; 2234 VncState *vs;
2273 2235
2274 vs = qemu_mallocz(sizeof(VncState)); 2236 vs = qemu_mallocz(sizeof(VncState));
2275 - if (!vs) 2237 + dcl = qemu_mallocz(sizeof(DisplayChangeListener));
  2238 + if (!vs || !dcl)
2276 exit(1); 2239 exit(1);
2277 2240
2278 ds->opaque = vs; 2241 ds->opaque = vs;
2279 - ds->idle = 1; 2242 + dcl->idle = 1;
2280 vnc_state = vs; 2243 vnc_state = vs;
2281 vs->display = NULL; 2244 vs->display = NULL;
2282 vs->password = NULL; 2245 vs->password = NULL;
@@ -2298,13 +2261,11 @@ void vnc_display_init(DisplayState *ds) @@ -2298,13 +2261,11 @@ void vnc_display_init(DisplayState *ds)
2298 2261
2299 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs); 2262 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
2300 2263
2301 - vs->ds->data = NULL;  
2302 - vs->ds->dpy_update = vnc_dpy_update;  
2303 - vs->ds->dpy_resize = vnc_dpy_resize;  
2304 - vs->ds->dpy_refresh = NULL;  
2305 -  
2306 - vnc_colordepth(vs->ds, 32);  
2307 - vnc_dpy_resize(vs->ds, 640, 400); 2264 + dcl->dpy_update = vnc_dpy_update;
  2265 + dcl->dpy_resize = vnc_dpy_resize;
  2266 + dcl->dpy_setdata = vnc_dpy_setdata;
  2267 + dcl->dpy_refresh = NULL;
  2268 + register_displaychangelistener(ds, dcl);
2308 2269
2309 vs->as.freq = 44100; 2270 vs->as.freq = 44100;
2310 vs->as.nchannels = 2; 2271 vs->as.nchannels = 2;