#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 };
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,
qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
}
- if (QTAILQ_EMPTY(&vs->vd->clients)) {
- vs->vd->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);
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]) {
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;
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);
- graphic_hw_update(NULL);
- 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;
+ }
}
}
}
VNC_DEBUG("New client on socket %d\n", csock);
- vd->dcl.idle = 0;
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
qemu_set_nonblock(vs->csock);
#ifdef CONFIG_VNC_WS
if (websocket) {
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 */
}
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_switch = vnc_dpy_switch,
{
VncDisplay *vs = g_malloc0(sizeof(*vs));
- vs->dcl.idle = 1;
vnc_display = vs;
vs->lsock = -1;