diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c index c6f14227..cf459183 100644 --- a/src/protocols/rdp/client.c +++ b/src/protocols/rdp/client.c @@ -600,3 +600,40 @@ 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) { + + if (data->bounded) { + + /* Get rect coordinates */ + int clipped_left = *x; + int clipped_top = *y; + int clipped_right = clipped_left + *w - 1; + int clipped_bottom = clipped_top + *h - 1; + + /* 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; + + /* Clip right */ + if (clipped_right < data->bounds_left) clipped_right = data->bounds_left; + 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; + + /* Clip bottom */ + if (clipped_bottom < data->bounds_top) clipped_bottom = data->bounds_top; + else if (clipped_bottom > data->bounds_bottom) clipped_bottom = data->bounds_bottom; + + /* Store new rect dimensions */ + *x = clipped_left; + *y = clipped_top; + *w = clipped_right - clipped_left + 1; + *h = clipped_bottom - clipped_top + 1; + + } + +} + + diff --git a/src/protocols/rdp/client.h b/src/protocols/rdp/client.h index 1bb8ca73..5fc19e69 100644 --- a/src/protocols/rdp/client.h +++ b/src/protocols/rdp/client.h @@ -219,5 +219,11 @@ typedef struct rdp_freerdp_context { } 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. + */ +void 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 55114cce..46f25695 100644 --- a/src/protocols/rdp/rdp_gdi.c +++ b/src/protocols/rdp/rdp_gdi.c @@ -44,41 +44,6 @@ #include "client.h" #include "rdp_bitmap.h" -static void __guac_rdp_clip_rect(rdp_guac_client_data* data, int* x, int* y, int* w, int* h) { - - if (data->bounded) { - - /* Get rect coordinates */ - int clipped_left = *x; - int clipped_top = *y; - int clipped_right = clipped_left + *w - 1; - int clipped_bottom = clipped_top + *h - 1; - - /* 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; - - /* Clip right */ - if (clipped_right < data->bounds_left) clipped_right = data->bounds_left; - 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; - - /* Clip bottom */ - if (clipped_bottom < data->bounds_top) clipped_bottom = data->bounds_top; - else if (clipped_bottom > data->bounds_bottom) clipped_bottom = data->bounds_bottom; - - /* Store new rect dimensions */ - *x = clipped_left; - *y = clipped_top; - *w = clipped_right - clipped_left + 1; - *h = clipped_bottom - clipped_top + 1; - - } - -} guac_transfer_function guac_rdp_rop3_transfer_function(guac_client* client, int rop3) { @@ -152,7 +117,7 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) { pthread_mutex_lock(&(data->update_lock)); /* Clip operation to bounds */ - __guac_rdp_clip_rect(data, &x, &y, &w, &h); + guac_rdp_clip_rect(data, &x, &y, &w, &h); switch (dstblt->bRop) { @@ -240,7 +205,7 @@ 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); + guac_rdp_clip_rect(data, &x, &y, &w, &h); /* Render rectangle based on ROP */ switch (patblt->bRop) { @@ -330,7 +295,7 @@ void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) { pthread_mutex_lock(&(data->update_lock)); /* Clip operation to bounds */ - __guac_rdp_clip_rect(data, &x, &y, &w, &h); + guac_rdp_clip_rect(data, &x, &y, &w, &h); /* Update source coordinates */ x_src += x - scrblt->nLeftRect; @@ -371,7 +336,7 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) { pthread_mutex_lock(&(data->update_lock)); /* Clip operation to bounds */ - __guac_rdp_clip_rect(data, &x, &y, &w, &h); + guac_rdp_clip_rect(data, &x, &y, &w, &h); /* Update source coordinates */ x_src += x - memblt->nLeftRect; @@ -479,7 +444,7 @@ 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); + guac_rdp_clip_rect(data, &x, &y, &w, &h); 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 50b4f178..fa86692f 100644 --- a/src/protocols/rdp/rdp_glyph.c +++ b/src/protocols/rdp/rdp_glyph.c @@ -218,6 +218,9 @@ void guac_rdp_glyph_enddraw(rdpContext* context, if (width > max_width) width = max_width; 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); + /* Ensure data is ready */ cairo_surface_flush(glyph_surface);