#include "qmp-commands.h"
#include "qemu/osdep.h"
-#define VNC_REFRESH_INTERVAL_BASE 30
+#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
#define VNC_REFRESH_INTERVAL_INC 50
-#define VNC_REFRESH_INTERVAL_MAX 2000
+#define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
#include "d3des.h"
static VncDisplay *vnc_display; /* needed for info vnc */
-static DisplayChangeListener *dcl;
static int vnc_cursor_define(VncState *vs);
static void vnc_release_modifiers(VncState *vs);
static int vnc_update_client(VncState *vs, int has_dirty);
static int vnc_update_client_sync(VncState *vs, int has_dirty);
static void vnc_disconnect_start(VncState *vs);
-static void vnc_init_timer(VncDisplay *vd);
-static void vnc_remove_timer(VncDisplay *vd);
static void vnc_colordepth(VncState *vs);
static void framebuffer_update_request(VncState *vs, int incremental,
int x_position, int y_position,
int w, int h);
-static void vnc_refresh(void *opaque);
+static void vnc_refresh(DisplayChangeListener *dcl);
static int vnc_refresh_server_surface(VncDisplay *vd);
static void vnc_dpy_update(DisplayChangeListener *dcl,
- DisplayState *ds,
int x, int y, int w, int h)
{
int i;
- VncDisplay *vd = ds->opaque;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
struct VncSurface *s = &vd->guest;
- int width = ds_get_width(ds);
- int height = ds_get_height(ds);
+ int width = surface_width(vd->ds);
+ int height = surface_height(vd->ds);
h += y;
static void vnc_desktop_resize(VncState *vs)
{
- DisplayState *ds = vs->ds;
+ DisplaySurface *ds = vs->vd->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)) {
+ if (vs->client_width == surface_width(ds) &&
+ vs->client_height == surface_height(ds)) {
return;
}
- vs->client_width = ds_get_width(ds);
- vs->client_height = ds_get_height(ds);
+ vs->client_width = surface_width(ds);
+ vs->client_height = surface_height(ds);
vnc_lock_output(vs);
vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
vnc_write_u8(vs, 0);
return ptr;
}
-static void vnc_dpy_resize(DisplayChangeListener *dcl,
- DisplayState *ds)
+static void vnc_dpy_switch(DisplayChangeListener *dcl,
+ DisplaySurface *surface)
{
- VncDisplay *vd = ds->opaque;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
VncState *vs;
vnc_abort_display_jobs(vd);
/* server surface */
qemu_pixman_image_unref(vd->server);
+ vd->ds = surface;
vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
- ds_get_width(ds),
- ds_get_height(ds),
+ surface_width(vd->ds),
+ surface_height(vd->ds),
NULL, 0);
/* guest surface */
console_color_init(ds);
#endif
qemu_pixman_image_unref(vd->guest.fb);
- vd->guest.fb = pixman_image_ref(ds->surface->image);
- vd->guest.format = ds->surface->format;
+ vd->guest.fb = pixman_image_ref(surface->image);
+ vd->guest.format = surface->format;
memset(vd->guest.dirty, 0xFF, sizeof(vd->guest.dirty));
QTAILQ_FOREACH(vs, &vd->clients, next) {
}
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 = container_of(dcl, VncDisplay, dcl);
VncState *vs, *vn;
uint8_t *src_row;
uint8_t *dst_row;
}
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 ??? */
}
static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
- DisplayState *ds,
QEMUCursor *c)
{
VncDisplay *vd = vnc_display;
qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
}
- if (QTAILQ_EMPTY(&vs->vd->clients)) {
- dcl->idle = 1;
- }
-
- vnc_remove_timer(vs->vd);
if (vs->vd->lock_key_sync)
qemu_remove_led_event_handler(vs->led);
vnc_unlock_output(vs);
vnc_disconnect_start(vs);
}
+#ifdef CONFIG_VNC_TLS
+static long vnc_client_write_tls(gnutls_session_t *session,
+ const uint8_t *data,
+ size_t datalen)
+{
+ long ret = gnutls_write(*session, data, datalen);
+ if (ret < 0) {
+ if (ret == GNUTLS_E_AGAIN) {
+ errno = EAGAIN;
+ } else {
+ errno = EIO;
+ }
+ ret = -1;
+ }
+ return ret;
+}
+#endif /* CONFIG_VNC_TLS */
/*
* Called to write a chunk of data to the client socket. The data may
long ret;
#ifdef CONFIG_VNC_TLS
if (vs->tls.session) {
- ret = gnutls_write(vs->tls.session, data, datalen);
- if (ret < 0) {
- if (ret == GNUTLS_E_AGAIN)
- errno = EAGAIN;
- else
- errno = EIO;
- ret = -1;
+ ret = vnc_client_write_tls(&vs->tls.session, data, datalen);
+ } else {
+#ifdef CONFIG_VNC_WS
+ if (vs->ws_tls.session) {
+ ret = vnc_client_write_tls(&vs->ws_tls.session, data, datalen);
+ } else
+#endif /* CONFIG_VNC_WS */
+#endif /* CONFIG_VNC_TLS */
+ {
+ ret = send(vs->csock, (const void *)data, datalen, 0);
}
- } else
+#ifdef CONFIG_VNC_TLS
+ }
#endif /* CONFIG_VNC_TLS */
- ret = send(vs->csock, (const void *)data, datalen, 0);
VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
return vnc_client_io_error(vs, ret, socket_error());
}
vs->read_handler_expect = expecting;
}
+#ifdef CONFIG_VNC_TLS
+static long vnc_client_read_tls(gnutls_session_t *session, uint8_t *data,
+ size_t datalen)
+{
+ long ret = gnutls_read(*session, data, datalen);
+ if (ret < 0) {
+ if (ret == GNUTLS_E_AGAIN) {
+ errno = EAGAIN;
+ } else {
+ errno = EIO;
+ }
+ ret = -1;
+ }
+ return ret;
+}
+#endif /* CONFIG_VNC_TLS */
/*
* Called to read a chunk of data from the client socket. The data may
long ret;
#ifdef CONFIG_VNC_TLS
if (vs->tls.session) {
- ret = gnutls_read(vs->tls.session, data, datalen);
- if (ret < 0) {
- if (ret == GNUTLS_E_AGAIN)
- errno = EAGAIN;
- else
- errno = EIO;
- ret = -1;
+ ret = vnc_client_read_tls(&vs->tls.session, data, datalen);
+ } else {
+#ifdef CONFIG_VNC_WS
+ if (vs->ws_tls.session) {
+ ret = vnc_client_read_tls(&vs->ws_tls.session, data, datalen);
+ } else
+#endif /* CONFIG_VNC_WS */
+#endif /* CONFIG_VNC_TLS */
+ {
+ ret = qemu_recv(vs->csock, data, datalen, 0);
}
- } else
+#ifdef CONFIG_VNC_TLS
+ }
#endif /* CONFIG_VNC_TLS */
- ret = qemu_recv(vs->csock, data, datalen, 0);
VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
return vnc_client_io_error(vs, ret, socket_error());
}
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1);
vnc_framebuffer_update(vs, absolute, 0,
- ds_get_width(vs->ds), ds_get_height(vs->ds),
+ surface_width(vs->vd->ds),
+ surface_height(vs->vd->ds),
VNC_ENCODING_POINTER_TYPE_CHANGE);
vnc_unlock_output(vs);
vnc_flush(vs);
{
int buttons = 0;
int dz = 0;
+ int width = surface_width(vs->vd->ds);
+ int height = surface_height(vs->vd->ds);
if (button_mask & 0x01)
buttons |= MOUSE_EVENT_LBUTTON;
dz = 1;
if (vs->absolute) {
- kbd_mouse_event(ds_get_width(vs->ds) > 1 ?
- x * 0x7FFF / (ds_get_width(vs->ds) - 1) : 0x4000,
- ds_get_height(vs->ds) > 1 ?
- y * 0x7FFF / (ds_get_height(vs->ds) - 1) : 0x4000,
+ kbd_mouse_event(width > 1 ? x * 0x7FFF / (width - 1) : 0x4000,
+ height > 1 ? y * 0x7FFF / (height - 1) : 0x4000,
dz, buttons);
} else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
x -= 0x7FFF;
kbd_put_keycode(keycode | SCANCODE_UP);
}
+static int current_led_state(VncState *vs)
+{
+ int ledstate = 0;
+
+ if (vs->modifiers_state[0x46]) {
+ ledstate |= QEMU_SCROLL_LOCK_LED;
+ }
+ if (vs->modifiers_state[0x45]) {
+ ledstate |= QEMU_NUM_LOCK_LED;
+ }
+ if (vs->modifiers_state[0x3a]) {
+ ledstate |= QEMU_CAPS_LOCK_LED;
+ }
+
+ return ledstate;
+}
+
+static void vnc_led_state_change(VncState *vs)
+{
+ int ledstate = 0;
+
+ if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
+ return;
+ }
+
+ ledstate = current_led_state(vs);
+ vnc_lock_output(vs);
+ vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
+ vnc_write_u8(vs, 0);
+ vnc_write_u16(vs, 1);
+ vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
+ vnc_write_u8(vs, ledstate);
+ vnc_unlock_output(vs);
+ vnc_flush(vs);
+}
+
static void kbd_leds(void *opaque, int ledstate)
{
VncState *vs = opaque;
- int caps, num;
+ int caps, num, scr;
+ bool has_changed = (ledstate != current_led_state(vs));
caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
+ scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
if (vs->modifiers_state[0x3a] != caps) {
vs->modifiers_state[0x3a] = caps;
if (vs->modifiers_state[0x45] != num) {
vs->modifiers_state[0x45] = num;
}
+ if (vs->modifiers_state[0x46] != scr) {
+ vs->modifiers_state[0x46] = scr;
+ }
+
+ /* Sending the current led state message to the client */
+ if (has_changed) {
+ vnc_led_state_change(vs);
+ }
}
static void do_key_event(VncState *vs, int down, int keycode, int sym)
break;
}
+ /* Turn off the lock state sync logic if the client support the led
+ state extension.
+ */
if (down && vs->vd->lock_key_sync &&
+ !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
/* If the numlock state needs to change then simulate an additional
keypress before sending this one. This will happen if the user
}
if (down && vs->vd->lock_key_sync &&
+ !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
/* If the capslock state needs to change then simulate an additional
keypress before sending this one. This will happen if the user
}
}
- if (is_graphic_console()) {
+ if (qemu_console_is_graphic(NULL)) {
if (keycode & SCANCODE_GREY)
kbd_put_keycode(SCANCODE_EMUL0);
if (down)
};
int i, keycode;
- if (!is_graphic_console()) {
+ if (!qemu_console_is_graphic(NULL)) {
return;
}
for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
int keycode;
int lsym = sym;
- if (lsym >= 'A' && lsym <= 'Z' && is_graphic_console()) {
+ if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
lsym = lsym - 'A' + 'a';
}
int w, int h)
{
int i;
- const size_t width = ds_get_width(vs->ds) / 16;
+ const size_t width = surface_width(vs->vd->ds) / 16;
+ const size_t height = surface_height(vs->vd->ds);
- if (y_position > ds_get_height(vs->ds))
- y_position = ds_get_height(vs->ds);
- if (y_position + h >= ds_get_height(vs->ds))
- h = ds_get_height(vs->ds) - y_position;
+ if (y_position > height) {
+ y_position = height;
+ }
+ if (y_position + h >= height) {
+ h = height - y_position;
+ }
vs->need_update = 1;
if (!incremental) {
vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
+ vnc_framebuffer_update(vs, 0, 0,
+ surface_width(vs->vd->ds),
+ surface_height(vs->vd->ds),
VNC_ENCODING_EXT_KEY_EVENT);
vnc_unlock_output(vs);
vnc_flush(vs);
vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
+ vnc_framebuffer_update(vs, 0, 0,
+ surface_width(vs->vd->ds),
+ surface_height(vs->vd->ds),
VNC_ENCODING_AUDIO);
vnc_unlock_output(vs);
vnc_flush(vs);
case VNC_ENCODING_WMVi:
vs->features |= VNC_FEATURE_WMVI_MASK;
break;
+ case VNC_ENCODING_LED_STATE:
+ vs->features |= VNC_FEATURE_LED_STATE_MASK;
+ break;
case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
vs->tight.compression = (enc & 0x0F);
break;
}
vnc_desktop_resize(vs);
check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
+ vnc_led_state_change(vs);
}
static void set_pixel_conversion(VncState *vs)
set_pixel_conversion(vs);
- vga_hw_invalidate();
- vga_hw_update();
+ graphic_hw_invalidate(NULL);
+ graphic_hw_update(NULL);
}
static void pixel_format_message (VncState *vs) {
vs->write_pixels = vnc_write_pixels_copy;
}
-static void vnc_dpy_setdata(DisplayChangeListener *dcl,
- DisplayState *ds)
-{
- VncDisplay *vd = ds->opaque;
-
- qemu_pixman_image_unref(vd->guest.fb);
- vd->guest.fb = pixman_image_ref(ds->surface->image);
- vd->guest.format = ds->surface->format;
- vnc_dpy_update(dcl, ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
-}
-
static void vnc_colordepth(VncState *vs)
{
if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
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(vs->ds),
- ds_get_height(vs->ds), VNC_ENCODING_WMVi);
+ vnc_framebuffer_update(vs, 0, 0,
+ surface_width(vs->vd->ds),
+ surface_height(vs->vd->ds),
+ VNC_ENCODING_WMVi);
pixel_format_message(vs);
vnc_unlock_output(vs);
vnc_flush(vs);
VncDisplay *vd = vs->vd;
if (data[0] > 3) {
- vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- if (!qemu_timer_expired(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval))
- qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval);
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
}
switch (data[0]) {
}
vnc_set_share_mode(vs, mode);
- vs->client_width = ds_get_width(vs->ds);
- vs->client_height = ds_get_height(vs->ds);
+ vs->client_width = surface_width(vs->vd->ds);
+ vs->client_height = surface_height(vs->vd->ds);
vnc_write_u16(vs, vs->client_width);
vnc_write_u16(vs, vs->client_height);
return has_dirty;
}
-static void vnc_refresh(void *opaque)
+static void vnc_refresh(DisplayChangeListener *dcl)
{
- VncDisplay *vd = opaque;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
VncState *vs, *vn;
int has_dirty, rects = 0;
- vga_hw_update();
+ graphic_hw_update(NULL);
if (vnc_trylock_display(vd)) {
- vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) +
- vd->timer_interval);
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
return;
}
/* vs might be free()ed here */
}
- /* vd->timer could be NULL now if the last client disconnected,
- * in this case don't update the timer */
- if (vd->timer == NULL)
+ if (QTAILQ_EMPTY(&vd->clients)) {
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
return;
+ }
if (has_dirty && rects) {
- vd->timer_interval /= 2;
- if (vd->timer_interval < VNC_REFRESH_INTERVAL_BASE)
- vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
+ vd->dcl.update_interval /= 2;
+ if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
+ vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
+ }
} else {
- vd->timer_interval += VNC_REFRESH_INTERVAL_INC;
- if (vd->timer_interval > VNC_REFRESH_INTERVAL_MAX)
- vd->timer_interval = VNC_REFRESH_INTERVAL_MAX;
- }
- qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval);
-}
-
-static void vnc_init_timer(VncDisplay *vd)
-{
- vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
- vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
- vnc_dpy_resize(dcl, vd->ds);
- vnc_refresh(vd);
- }
-}
-
-static void vnc_remove_timer(VncDisplay *vd)
-{
- if (vd->timer != NULL && QTAILQ_EMPTY(&vd->clients)) {
- qemu_del_timer(vd->timer);
- qemu_free_timer(vd->timer);
- vd->timer = NULL;
+ vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
+ if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
+ vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
+ }
}
}
-static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket)
+static void vnc_connect(VncDisplay *vd, int csock,
+ bool skipauth, bool websocket)
{
VncState *vs = g_malloc0(sizeof(VncState));
int i;
}
VNC_DEBUG("New client on socket %d\n", csock);
- dcl->idle = 0;
- socket_set_nonblock(vs->csock);
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
+ qemu_set_nonblock(vs->csock);
#ifdef CONFIG_VNC_WS
if (websocket) {
vs->websocket = 1;
- qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs);
+#ifdef CONFIG_VNC_TLS
+ if (vd->tls.x509cert) {
+ qemu_set_fd_handler2(vs->csock, NULL, vncws_tls_handshake_peek,
+ NULL, vs);
+ } else
+#endif /* CONFIG_VNC_TLS */
+ {
+ qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read,
+ NULL, vs);
+ }
} else
#endif /* CONFIG_VNC_WS */
{
vs->initialized = true;
VncDisplay *vd = vs->vd;
- vs->ds = vd->ds;
vs->last_x = -1;
vs->last_y = -1;
QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
- vga_hw_update();
+ graphic_hw_update(NULL);
vnc_write(vs, "RFB 003.008\n", 12);
vnc_flush(vs);
vs->mouse_mode_notifier.notify = check_pointer_type_change;
qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
- vnc_init_timer(vd);
-
/* vs might be free()ed here */
}
int csock;
/* Catch-up */
- vga_hw_update();
+ graphic_hw_update(NULL);
#ifdef CONFIG_VNC_WS
if (websocket) {
csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
}
if (csock != -1) {
- vnc_connect(vs, csock, 0, websocket);
+ vnc_connect(vs, csock, false, websocket);
}
}
static void vnc_listen_regular_read(void *opaque)
{
- vnc_listen_read(opaque, 0);
+ vnc_listen_read(opaque, false);
}
#ifdef CONFIG_VNC_WS
static void vnc_listen_websocket_read(void *opaque)
{
- vnc_listen_read(opaque, 1);
+ vnc_listen_read(opaque, true);
}
#endif /* CONFIG_VNC_WS */
static const DisplayChangeListenerOps dcl_ops = {
.dpy_name = "vnc",
+ .dpy_refresh = vnc_refresh,
.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_gfx_switch = vnc_dpy_switch,
.dpy_mouse_set = vnc_mouse_set,
.dpy_cursor_define = vnc_dpy_cursor_define,
};
{
VncDisplay *vs = g_malloc0(sizeof(*vs));
- dcl = g_malloc0(sizeof(DisplayChangeListener));
-
- ds->opaque = vs;
- dcl->idle = 1;
vnc_display = vs;
vs->lsock = -1;
vs->lwebsock = -1;
#endif
- vs->ds = ds;
QTAILQ_INIT(&vs->clients);
vs->expires = TIME_MAX;
qemu_mutex_init(&vs->mutex);
vnc_start_worker_thread();
- dcl->ops = &dcl_ops;
- register_displaychangelistener(ds, dcl);
+ vs->dcl.ops = &dcl_ops;
+ register_displaychangelistener(&vs->dcl);
}
static void vnc_display_close(DisplayState *ds)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
if (!vs)
return;
static int vnc_display_disable_login(DisplayState *ds)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
if (!vs) {
return -1;
int vnc_display_password(DisplayState *ds, const char *password)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
if (!vs) {
return -EINVAL;
int vnc_display_pw_expire(DisplayState *ds, time_t expires)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
if (!vs) {
return -EINVAL;
char *vnc_display_local_addr(DisplayState *ds)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
return vnc_socket_local_addr("%s:%s", vs->lsock);
}
void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
const char *options;
int password = 0;
int reverse = 0;
if (csock < 0) {
goto fail;
}
- vnc_connect(vs, csock, 0, 0);
+ vnc_connect(vs, csock, false, false);
} else {
/* listen for connects */
char *dpy;
#endif /* CONFIG_VNC_WS */
}
-void vnc_display_add_client(DisplayState *ds, int csock, int skipauth)
+void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
- vnc_connect(vs, csock, skipauth, 0);
+ vnc_connect(vs, csock, skipauth, false);
}