}
}
-/**
- * do_info_vnc(): Show VNC server information
- *
- * Return a QDict with server information. Connected clients are returned
- * as a QList of QDicts.
- *
- * The main QDict contains the following:
- *
- * - "enabled": true or false
- * - "host": server's IP address
- * - "family": address family ("ipv4" or "ipv6")
- * - "service": server's port number
- * - "auth": authentication method
- * - "clients": a QList of all connected clients
- *
- * Clients are described by a QDict, with the following information:
- *
- * - "host": client's IP address
- * - "family": address family ("ipv4" or "ipv6")
- * - "service": client's port number
- * - "x509_dname": TLS dname (optional)
- * - "sasl_username": SASL username (optional)
- *
- * Example:
- *
- * { "enabled": true, "host": "0.0.0.0", "service": "50402", "auth": "vnc",
- * "family": "ipv4",
- * "clients": [{ "host": "127.0.0.1", "service": "50401", "family": "ipv4" }]}
- */
void do_info_vnc(Monitor *mon, QObject **ret_data)
{
if (vnc_display == NULL || vnc_display->display == NULL) {
buffer->offset += len;
}
+static void vnc_desktop_resize(VncState *vs)
+{
+ DisplayState *ds = vs->ds;
+
+ if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
+ return;
+ }
+ if (vs->client_width == ds_get_width(ds) &&
+ vs->client_height == ds_get_height(ds)) {
+ return;
+ }
+ vs->client_width = ds_get_width(ds);
+ vs->client_height = ds_get_height(ds);
+ vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
+ vnc_write_u8(vs, 0);
+ vnc_write_u16(vs, 1); /* number of rects */
+ vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
+ VNC_ENCODING_DESKTOPRESIZE);
+ vnc_flush(vs);
+}
+
static void vnc_dpy_resize(DisplayState *ds)
{
- int size_changed;
VncDisplay *vd = ds->opaque;
VncState *vs;
vd->guest.ds = qemu_mallocz(sizeof(*vd->guest.ds));
if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
console_color_init(ds);
- size_changed = ds_get_width(ds) != vd->guest.ds->width ||
- ds_get_height(ds) != vd->guest.ds->height;
*(vd->guest.ds) = *(ds->surface);
memset(vd->guest.dirty, 0xFF, sizeof(vd->guest.dirty));
QTAILQ_FOREACH(vs, &vd->clients, next) {
vnc_colordepth(vs);
- if (size_changed) {
- if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
- VNC_ENCODING_DESKTOPRESIZE);
- vnc_flush(vs);
- }
- }
+ vnc_desktop_resize(vs);
if (vs->vd->cursor) {
vnc_cursor_define(vs);
}
int y;
int n_rectangles;
int saved_offset;
+ int width, height;
int n;
if (vs->output.offset && !vs->audio_cap && !vs->force_update)
saved_offset = vs->output.offset;
vnc_write_u16(vs, 0);
- for (y = 0; y < vd->server->height; y++) {
+ width = MIN(vd->server->width, vs->client_width);
+ height = MIN(vd->server->height, vs->client_height);
+
+ for (y = 0; y < height; y++) {
int x;
int last_x = -1;
- for (x = 0; x < vd->server->width / 16; x++) {
+ for (x = 0; x < width / 16; x++) {
if (vnc_get_bit(vs->dirty[y], x)) {
if (last_x == -1) {
last_x = x;
break;
}
}
+ vnc_desktop_resize(vs);
check_pointer_type_change(&vs->mouse_mode_notifier);
}
char buf[1024];
int size;
- vnc_write_u16(vs, ds_get_width(vs->ds));
- vnc_write_u16(vs, ds_get_height(vs->ds));
+ vs->client_width = ds_get_width(vs->ds);
+ vs->client_height = ds_get_height(vs->ds);
+ vnc_write_u16(vs, vs->client_width);
+ vnc_write_u16(vs, vs->client_height);
pixel_format_message(vs);