diff options
Diffstat (limited to 'ui/vnc-jobs.c')
-rw-r--r-- | ui/vnc-jobs.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index dbbfbefe56..4562bf8928 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -32,6 +32,7 @@ #include "qemu/sockets.h" #include "qemu/main-loop.h" #include "block/aio.h" +#include "trace.h" /* * Locking: @@ -94,6 +95,8 @@ int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h) { VncRectEntry *entry = g_new0(VncRectEntry, 1); + trace_vnc_job_add_rect(job->vs, job, x, y, w, h); + entry->rect.x = x; entry->rect.y = y; entry->rect.w = w; @@ -190,6 +193,8 @@ static void vnc_async_encoding_start(VncState *orig, VncState *local) local->zlib = orig->zlib; local->hextile = orig->hextile; local->zrle = orig->zrle; + local->client_width = orig->client_width; + local->client_height = orig->client_height; } static void vnc_async_encoding_end(VncState *orig, VncState *local) @@ -202,6 +207,34 @@ static void vnc_async_encoding_end(VncState *orig, VncState *local) orig->lossy_rect = local->lossy_rect; } +static bool vnc_worker_clamp_rect(VncState *vs, VncJob *job, VncRect *rect) +{ + trace_vnc_job_clamp_rect(vs, job, rect->x, rect->y, rect->w, rect->h); + + if (rect->x >= vs->client_width) { + goto discard; + } + rect->w = MIN(vs->client_width - rect->x, rect->w); + if (rect->w == 0) { + goto discard; + } + + if (rect->y >= vs->client_height) { + goto discard; + } + rect->h = MIN(vs->client_height - rect->y, rect->h); + if (rect->h == 0) { + goto discard; + } + + trace_vnc_job_clamped_rect(vs, job, rect->x, rect->y, rect->w, rect->h); + return true; + + discard: + trace_vnc_job_discard_rect(vs, job, rect->x, rect->y, rect->w, rect->h); + return false; +} + static int vnc_worker_thread_loop(VncJobQueue *queue) { VncJob *job; @@ -260,14 +293,17 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) goto disconnected; } - n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y, - entry->rect.w, entry->rect.h); + if (vnc_worker_clamp_rect(&vs, job, &entry->rect)) { + n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y, + entry->rect.w, entry->rect.h); - if (n >= 0) { - n_rectangles += n; + if (n >= 0) { + n_rectangles += n; + } } g_free(entry); } + trace_vnc_job_nrects(&vs, job, n_rectangles); vnc_unlock_display(job->vs->vd); /* Put n_rectangles at the beginning of the message */ |