From 4a3a530fdeb70a0f695df6bb9ec7b0945ddc8ea9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 19 Jul 2013 12:21:34 -0700 Subject: [PATCH] Fix guac_rdp_clip_rect() handling of completely clipped rects. --- src/protocols/rdp/client.c | 12 +++++++----- src/protocols/rdp/client.h | 5 ++++- src/protocols/rdp/rdp_gdi.c | 15 ++++++++++----- src/protocols/rdp/rdp_glyph.c | 30 ++++++++++++++++-------------- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c index 2e58282d..a19e065b 100644 --- a/src/protocols/rdp/client.c +++ b/src/protocols/rdp/client.c @@ -619,7 +619,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) { } -void guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h) { +int guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h) { if (data->bounded) { @@ -631,18 +631,18 @@ void guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* /* Clip left */ if (clipped_left < data->bounds_left) clipped_left = data->bounds_left; - else if (clipped_left > data->bounds_right) clipped_left = data->bounds_right; + else if (clipped_left > data->bounds_right) return 1; /* Clip right */ - if (clipped_right < data->bounds_left) clipped_right = data->bounds_left; + if (clipped_right < data->bounds_left) return 1; else if (clipped_right > data->bounds_right) clipped_right = data->bounds_right; /* Clip top */ if (clipped_top < data->bounds_top) clipped_top = data->bounds_top; - else if (clipped_top > data->bounds_bottom) clipped_top = data->bounds_bottom; + else if (clipped_top > data->bounds_bottom) return 1; /* Clip bottom */ - if (clipped_bottom < data->bounds_top) clipped_bottom = data->bounds_top; + if (clipped_bottom < data->bounds_top) return 1; else if (clipped_bottom > data->bounds_bottom) clipped_bottom = data->bounds_bottom; /* Store new rect dimensions */ @@ -653,6 +653,8 @@ void guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* } + return 0; + } diff --git a/src/protocols/rdp/client.h b/src/protocols/rdp/client.h index f03e0eaa..9df91256 100644 --- a/src/protocols/rdp/client.h +++ b/src/protocols/rdp/client.h @@ -222,8 +222,11 @@ typedef struct rdp_freerdp_context { /** * Given the coordinates and dimensions of a rectangle, clips the rectangle to be * within the clipping bounds of the client data, if clipping is active. + * + * Returns 0 if the rectangle given is visible at all, and 1 if the entire + * rectangls is outside the clipping rectangle and this invisible. */ -void guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h); +int guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h); #endif diff --git a/src/protocols/rdp/rdp_gdi.c b/src/protocols/rdp/rdp_gdi.c index cf07827c..fa6b4fdb 100644 --- a/src/protocols/rdp/rdp_gdi.c +++ b/src/protocols/rdp/rdp_gdi.c @@ -115,7 +115,8 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) { /* Clip operation to bounds */ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data; - guac_rdp_clip_rect(data, &x, &y, &w, &h); + if (guac_rdp_clip_rect(data, &x, &y, &w, &h)) + return; switch (dstblt->bRop) { @@ -201,7 +202,8 @@ void guac_rdp_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { "negotiated client capabilities)"); /* Clip operation to bounds */ - guac_rdp_clip_rect(data, &x, &y, &w, &h); + if (guac_rdp_clip_rect(data, &x, &y, &w, &h)) + return; /* Render rectangle based on ROP */ switch (patblt->bRop) { @@ -289,7 +291,8 @@ void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) { /* Clip operation to bounds */ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data; - guac_rdp_clip_rect(data, &x, &y, &w, &h); + if (guac_rdp_clip_rect(data, &x, &y, &w, &h)) + return; /* Update source coordinates */ x_src += x - scrblt->nLeftRect; @@ -326,7 +329,8 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) { } /* Clip operation to bounds */ - guac_rdp_clip_rect(data, &x, &y, &w, &h); + if (guac_rdp_clip_rect(data, &x, &y, &w, &h)) + return; /* Update source coordinates */ x_src += x - memblt->nLeftRect; @@ -431,7 +435,8 @@ void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect int h = opaque_rect->nHeight; /* Clip operation to bounds */ - guac_rdp_clip_rect(data, &x, &y, &w, &h); + if (guac_rdp_clip_rect(data, &x, &y, &w, &h)) + return; guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); diff --git a/src/protocols/rdp/rdp_glyph.c b/src/protocols/rdp/rdp_glyph.c index 92d9927f..44f33ef4 100644 --- a/src/protocols/rdp/rdp_glyph.c +++ b/src/protocols/rdp/rdp_glyph.c @@ -222,24 +222,26 @@ void guac_rdp_glyph_enddraw(rdpContext* context, if (height > max_height) height = max_height; /* Clip operation to clipping region, if any */ - guac_rdp_clip_rect(guac_client_data, &x, &y, &width, &height); + if (!guac_rdp_clip_rect(guac_client_data, &x, &y, &width, &height)) { - /* Ensure data is ready */ - cairo_surface_flush(glyph_surface); + /* Ensure data is ready */ + cairo_surface_flush(glyph_surface); - /* Create surface for subsection with text */ - cairo_surface_t* surface = cairo_image_surface_create_for_data( - cairo_image_surface_get_data(glyph_surface) + 4*x + y*stride, - cairo_image_surface_get_format(glyph_surface), - width, height, stride); + /* Create surface for subsection with text */ + cairo_surface_t* surface = cairo_image_surface_create_for_data( + cairo_image_surface_get_data(glyph_surface) + 4*x + y*stride, + cairo_image_surface_get_format(glyph_surface), + width, height, stride); - /* Send surface with all glyphs to layer */ - guac_protocol_send_png(client->socket, - GUAC_COMP_OVER, current_layer, x, y, - surface); + /* Send surface with all glyphs to layer */ + guac_protocol_send_png(client->socket, + GUAC_COMP_OVER, current_layer, x, y, + surface); - /* Destroy surface */ - cairo_surface_destroy(surface); + /* Destroy surface */ + cairo_surface_destroy(surface); + + } /* Destroy cairo instance */ cairo_destroy(guac_client_data->glyph_cairo);