#include "qemu-timer.h"
#include "acl.h"
-#define VNC_REFRESH_INTERVAL (1000 / 30)
+#define VNC_REFRESH_INTERVAL_BASE 30
+#define VNC_REFRESH_INTERVAL_INC 50
+#define VNC_REFRESH_INTERVAL_MAX 2000
#include "vnc_keysym.h"
#include "d3des.h"
3) resolutions > 1024
*/
-static void vnc_update_client(VncState *vs, int has_dirty);
+static int vnc_update_client(VncState *vs, int has_dirty);
static void vnc_disconnect_start(VncState *vs);
static void vnc_disconnect_finish(VncState *vs);
static void vnc_init_timer(VncDisplay *vd);
return h;
}
-static void vnc_update_client(VncState *vs, int has_dirty)
+static int vnc_update_client(VncState *vs, int has_dirty)
{
if (vs->need_update && vs->csock != -1) {
VncDisplay *vd = vs->vd;
if (vs->output.offset && !vs->audio_cap && !vs->force_update)
/* kernel send buffers are full -> drop frames to throttle */
- return;
+ return 0;
if (!has_dirty && !vs->audio_cap && !vs->force_update)
- return;
+ return 0;
/*
* Send screen updates to the vnc client using the server
vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
vnc_flush(vs);
vs->force_update = 0;
-
+ return n_rectangles;
}
if (vs->csock == -1)
vnc_disconnect_finish(vs);
+
+ return 0;
}
/* audio */
{
int i;
uint16_t limit;
+ VncDisplay *vd = vs->vd;
+
+ if (data[0] > 3) {
+ vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
+ if (!qemu_timer_expired(vd->timer, qemu_get_clock(rt_clock) + vd->timer_interval))
+ qemu_mod_timer(vd->timer, qemu_get_clock(rt_clock) + vd->timer_interval);
+ }
switch (data[0]) {
case 0:
{
VncDisplay *vd = opaque;
VncState *vs = NULL;
- int has_dirty = 0;
+ int has_dirty = 0, rects = 0;
vga_hw_update();
vs = vd->clients;
while (vs != NULL) {
- vnc_update_client(vs, has_dirty);
+ rects += vnc_update_client(vs, has_dirty);
vs = vs->next;
}
- qemu_mod_timer(vd->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
+ if (has_dirty && rects) {
+ vd->timer_interval /= 2;
+ if (vd->timer_interval < VNC_REFRESH_INTERVAL_BASE)
+ vd->timer_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(rt_clock) + vd->timer_interval);
}
static void vnc_init_timer(VncDisplay *vd)
{
+ vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
if (vd->timer == NULL && vd->clients != NULL) {
vd->timer = qemu_new_timer(rt_clock, vnc_refresh, vd);
vnc_refresh(vd);
{
VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ if (!vs) {
+ return -1;
+ }
+
if (vs->password) {
qemu_free(vs->password);
vs->password = NULL;
if (password && password[0]) {
if (!(vs->password = qemu_strdup(password)))
return -1;
+ if (vs->auth == VNC_AUTH_NONE) {
+ vs->auth = VNC_AUTH_VNC;
+ }
+ } else {
+ vs->auth = VNC_AUTH_NONE;
}
return 0;