GUAC-656: Migrate RDP to guac_common_surface.

This commit is contained in:
Michael Jumper 2014-04-30 11:44:06 -07:00
parent f6ccfd1211
commit f8ac59798f
7 changed files with 95 additions and 147 deletions

View File

@ -650,7 +650,6 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
guac_client_data->rdp_inst = rdp_inst; guac_client_data->rdp_inst = rdp_inst;
guac_client_data->bounded = FALSE; guac_client_data->bounded = FALSE;
guac_client_data->mouse_button_mask = 0; guac_client_data->mouse_button_mask = 0;
guac_client_data->current_surface = GUAC_DEFAULT_LAYER;
guac_client_data->clipboard = guac_common_clipboard_alloc(GUAC_RDP_CLIPBOARD_MAX_LENGTH); guac_client_data->clipboard = guac_common_clipboard_alloc(GUAC_RDP_CLIPBOARD_MAX_LENGTH);
guac_client_data->requested_clipboard_format = CB_FORMAT_TEXT; guac_client_data->requested_clipboard_format = CB_FORMAT_TEXT;
guac_client_data->audio = NULL; guac_client_data->audio = NULL;
@ -707,10 +706,6 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
/* Send connection name */ /* Send connection name */
guac_protocol_send_name(client->socket, settings->hostname); guac_protocol_send_name(client->socket, settings->hostname);
/* Send size */
guac_protocol_send_size(client->socket, GUAC_DEFAULT_LAYER,
settings->width, settings->height);
/* Create glyph surfaces */ /* Create glyph surfaces */
guac_client_data->opaque_glyph_surface = cairo_image_surface_create( guac_client_data->opaque_glyph_surface = cairo_image_surface_create(
CAIRO_FORMAT_RGB24, settings->width, settings->height); CAIRO_FORMAT_RGB24, settings->width, settings->height);
@ -718,6 +713,11 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
guac_client_data->trans_glyph_surface = cairo_image_surface_create( guac_client_data->trans_glyph_surface = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32, settings->width, settings->height); CAIRO_FORMAT_ARGB32, settings->width, settings->height);
/* Create default surface */
guac_client_data->default_surface = guac_common_surface_alloc(client->socket, GUAC_DEFAULT_LAYER,
settings->width, settings->height);
guac_client_data->current_surface = guac_client_data->default_surface;
/* Set default pointer */ /* Set default pointer */
guac_common_set_pointer_cursor(client); guac_common_set_pointer_cursor(client);

View File

@ -28,6 +28,7 @@
#include "guac_clipboard.h" #include "guac_clipboard.h"
#include "guac_list.h" #include "guac_list.h"
#include "guac_surface.h"
#include "rdp_fs.h" #include "rdp_fs.h"
#include "rdp_keymap.h" #include "rdp_keymap.h"
#include "rdp_settings.h" #include "rdp_settings.h"
@ -120,10 +121,15 @@ typedef struct rdp_guac_client_data {
cairo_t* glyph_cairo; cairo_t* glyph_cairo;
/** /**
* The Guacamole layer that GDI operations should draw to. RDP messages * The display.
* exist which change this surface to allow drawing to occur off-screen.
*/ */
const guac_layer* current_surface; guac_common_surface* default_surface;
/**
* The surface that GDI operations should draw to. RDP messages exist which
* change this surface to allow drawing to occur off-screen.
*/
guac_common_surface* current_surface;
/** /**
* Whether graphical operations are restricted to a specific bounding * Whether graphical operations are restricted to a specific bounding

View File

@ -25,6 +25,7 @@
#include "client.h" #include "client.h"
#include "guac_handlers.h" #include "guac_handlers.h"
#include "guac_list.h" #include "guac_list.h"
#include "guac_surface.h"
#include "rdp_cliprdr.h" #include "rdp_cliprdr.h"
#include "rdp_keymap.h" #include "rdp_keymap.h"
#include "rdp_rail.h" #include "rdp_rail.h"
@ -92,6 +93,7 @@ int rdp_guac_client_free_handler(guac_client* client) {
/* Free client data */ /* Free client data */
guac_common_clipboard_free(guac_client_data->clipboard); guac_common_clipboard_free(guac_client_data->clipboard);
guac_common_surface_free(guac_client_data->default_surface);
cairo_surface_destroy(guac_client_data->opaque_glyph_surface); cairo_surface_destroy(guac_client_data->opaque_glyph_surface);
cairo_surface_destroy(guac_client_data->trans_glyph_surface); cairo_surface_destroy(guac_client_data->trans_glyph_surface);
free(guac_client_data); free(guac_client_data);

View File

@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include "client.h" #include "client.h"
#include "guac_surface.h"
#include "rdp_bitmap.h" #include "rdp_bitmap.h"
#include <pthread.h> #include <pthread.h>
@ -48,28 +49,29 @@ void guac_rdp_cache_bitmap(rdpContext* context, rdpBitmap* bitmap) {
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
guac_socket* socket = client->socket; guac_socket* socket = client->socket;
/* Allocate buffer */ /* Allocate surface */
guac_layer* buffer = guac_client_alloc_buffer(client); guac_layer* buffer = guac_client_alloc_buffer(client);
guac_common_surface* surface = guac_common_surface_alloc(socket, buffer, bitmap->width, bitmap->height);
/* Cache image data if present */ /* Cache image data if present */
if (bitmap->data != NULL) { if (bitmap->data != NULL) {
/* Create surface from image data */ /* Create surface from image data */
cairo_surface_t* surface = cairo_image_surface_create_for_data( cairo_surface_t* image = cairo_image_surface_create_for_data(
bitmap->data, CAIRO_FORMAT_RGB24, bitmap->data, CAIRO_FORMAT_RGB24,
bitmap->width, bitmap->height, 4*bitmap->width); bitmap->width, bitmap->height, 4*bitmap->width);
/* Send surface to buffer */ /* Send surface to buffer */
guac_protocol_send_png(socket, guac_common_surface_draw(surface, 0, 0, image);
GUAC_COMP_SRC, buffer, 0, 0, surface);
/* Free surface */ /* Free surface */
cairo_surface_destroy(surface); cairo_surface_destroy(image);
} }
/* Store buffer reference in bitmap */ /* Store buffer reference in bitmap */
((guac_rdp_bitmap*) bitmap)->layer = buffer; ((guac_rdp_bitmap*) bitmap)->buffer = buffer;
((guac_rdp_bitmap*) bitmap)->surface = surface;
} }
@ -97,8 +99,9 @@ void guac_rdp_bitmap_new(rdpContext* context, rdpBitmap* bitmap) {
} }
/* No corresponding layer yet - caching is deferred. */ /* No corresponding surface yet - caching is deferred. */
((guac_rdp_bitmap*) bitmap)->layer = NULL; ((guac_rdp_bitmap*) bitmap)->buffer = NULL;
((guac_rdp_bitmap*) bitmap)->surface = NULL;
/* Start at zero usage */ /* Start at zero usage */
((guac_rdp_bitmap*) bitmap)->used = 0; ((guac_rdp_bitmap*) bitmap)->used = 0;
@ -108,39 +111,35 @@ void guac_rdp_bitmap_new(rdpContext* context, rdpBitmap* bitmap) {
void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) { void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) {
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
guac_socket* socket = client->socket; rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data;
guac_common_surface* surface = ((guac_rdp_bitmap*) bitmap)->surface;
int width = bitmap->right - bitmap->left + 1; int width = bitmap->right - bitmap->left + 1;
int height = bitmap->bottom - bitmap->top + 1; int height = bitmap->bottom - bitmap->top + 1;
/* If not cached, cache if necessary */ /* If not cached, cache if necessary */
if (((guac_rdp_bitmap*) bitmap)->layer == NULL if (surface == NULL && ((guac_rdp_bitmap*) bitmap)->used >= 1)
&& ((guac_rdp_bitmap*) bitmap)->used >= 1)
guac_rdp_cache_bitmap(context, bitmap); guac_rdp_cache_bitmap(context, bitmap);
/* If cached, retrieve from cache */ /* If cached, retrieve from cache */
if (((guac_rdp_bitmap*) bitmap)->layer != NULL) if (surface != NULL)
guac_protocol_send_copy(socket, guac_common_surface_copy(surface, 0, 0, width, height,
((guac_rdp_bitmap*) bitmap)->layer, client_data->default_surface, bitmap->left, bitmap->top);
0, 0, width, height,
GUAC_COMP_OVER,
GUAC_DEFAULT_LAYER, bitmap->left, bitmap->top);
/* Otherwise, draw with stored image data */ /* Otherwise, draw with stored image data */
else if (bitmap->data != NULL) { else if (bitmap->data != NULL) {
/* Create surface from image data */ /* Create surface from image data */
cairo_surface_t* surface = cairo_image_surface_create_for_data( cairo_surface_t* image = cairo_image_surface_create_for_data(
bitmap->data, CAIRO_FORMAT_RGB24, bitmap->data, CAIRO_FORMAT_RGB24,
width, height, 4*bitmap->width); width, height, 4*bitmap->width);
/* Send surface to buffer */ /* Draw image on default surface */
guac_protocol_send_png(socket, guac_common_surface_draw(client_data->default_surface, bitmap->left, bitmap->top, image);
GUAC_COMP_OVER, GUAC_DEFAULT_LAYER,
bitmap->left, bitmap->top, surface);
/* Free surface */ /* Free surface */
cairo_surface_destroy(surface); cairo_surface_destroy(image);
} }
@ -150,20 +149,28 @@ void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) {
} }
void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) { void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) {
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
guac_layer* buffer = ((guac_rdp_bitmap*) bitmap)->buffer;
guac_common_surface* surface = ((guac_rdp_bitmap*) bitmap)->surface;
/* If cached, free buffer */ /* If cached, free buffer */
if (((guac_rdp_bitmap*) bitmap)->layer != NULL) if (buffer != NULL)
guac_client_free_buffer(client, ((guac_rdp_bitmap*) bitmap)->layer); guac_client_free_buffer(client, buffer);
/* If cached, free surface */
if (surface != NULL)
guac_common_surface_free(surface);
} }
void guac_rdp_bitmap_setsurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary) { void guac_rdp_bitmap_setsurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary) {
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data;
if (primary) if (primary)
((rdp_guac_client_data*) client->data)->current_surface client_data->current_surface = client_data->default_surface;
= GUAC_DEFAULT_LAYER;
else { else {
@ -174,11 +181,10 @@ void guac_rdp_bitmap_setsurface(rdpContext* context, rdpBitmap* bitmap, BOOL pri
} }
/* If not available as a surface, make available. */ /* If not available as a surface, make available. */
if (((guac_rdp_bitmap*) bitmap)->layer == NULL) if (((guac_rdp_bitmap*) bitmap)->surface == NULL)
guac_rdp_cache_bitmap(context, bitmap); guac_rdp_cache_bitmap(context, bitmap);
((rdp_guac_client_data*) client->data)->current_surface client_data->current_surface = ((guac_rdp_bitmap*) bitmap)->surface;
= ((guac_rdp_bitmap*) bitmap)->layer;
} }

View File

@ -25,6 +25,7 @@
#define _GUAC_RDP_RDP_BITMAP_H #define _GUAC_RDP_RDP_BITMAP_H
#include "config.h" #include "config.h"
#include "guac_surface.h"
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <guacamole/protocol.h> #include <guacamole/protocol.h>
@ -43,9 +44,14 @@ typedef struct guac_rdp_bitmap {
rdpBitmap bitmap; rdpBitmap bitmap;
/** /**
* Guacamole layer containing cached image data. * The allocated buffer which backs this bitmap.
*/ */
guac_layer* layer; guac_layer* buffer;
/**
* Surface containing cached image data.
*/
guac_common_surface* surface;
/** /**
* The number of times a bitmap has been used. * The number of times a bitmap has been used.

View File

@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include "client.h" #include "client.h"
#include "guac_surface.h"
#include "rdp_bitmap.h" #include "rdp_bitmap.h"
#include <pthread.h> #include <pthread.h>
@ -96,7 +97,7 @@ guac_transfer_function guac_rdp_rop3_transfer_function(guac_client* client,
void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) { void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) {
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface; guac_common_surface* current_surface = ((rdp_guac_client_data*) client->data)->current_surface;
int x = dstblt->nLeftRect; int x = dstblt->nLeftRect;
int y = dstblt->nTopRect; int y = dstblt->nTopRect;
@ -114,23 +115,13 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) {
case 0: case 0:
/* Send black rectangle */ /* Send black rectangle */
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_common_surface_rect(current_surface, x, y, w, h, 0, 0, 0);
guac_protocol_send_cfill(client->socket,
GUAC_COMP_OVER, current_layer,
0, 0, 0, 255);
break; break;
/* DSTINVERT */ /* DSTINVERT */
case 0x55: case 0x55:
guac_common_surface_transfer(current_surface, x, y, w, h,
/* Invert */ GUAC_TRANSFER_BINARY_NDEST, current_surface, x, y);
guac_protocol_send_transfer(client->socket,
current_layer, x, y, w, h,
GUAC_TRANSFER_BINARY_NDEST,
current_layer, x, y);
break; break;
/* NOP */ /* NOP */
@ -139,11 +130,7 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) {
/* Whiteness */ /* Whiteness */
case 0xFF: case 0xFF:
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_common_surface_rect(current_surface, x, y, w, h, 0xFF, 0xFF, 0xFF);
guac_protocol_send_cfill(client->socket,
GUAC_COMP_OVER, current_layer,
0xFF, 0xFF, 0xFF, 0xFF);
break; break;
/* Unsupported ROP3 */ /* Unsupported ROP3 */
@ -170,7 +157,7 @@ void guac_rdp_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) {
/* Get client and current layer */ /* Get client and current layer */
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
const guac_layer* current_layer = guac_common_surface* current_surface =
((rdp_guac_client_data*) client->data)->current_surface; ((rdp_guac_client_data*) client->data)->current_surface;
int x = patblt->nLeftRect; int x = patblt->nLeftRect;
@ -180,9 +167,6 @@ void guac_rdp_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) {
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data; rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
/* Layer for actual transfer */
guac_layer* buffer;
/* /*
* Warn that rendering is a fallback, as the server should not be sending * Warn that rendering is a fallback, as the server should not be sending
* this order. * this order.
@ -199,11 +183,7 @@ void guac_rdp_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) {
/* If blackness, send black rectangle */ /* If blackness, send black rectangle */
case 0x00: case 0x00:
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_common_surface_rect(current_surface, x, y, w, h, 0, 0, 0);
guac_protocol_send_cfill(client->socket,
GUAC_COMP_OVER, current_layer,
0x00, 0x00, 0x00, 0xFF);
break; break;
/* If NOP, do nothing */ /* If NOP, do nothing */
@ -213,53 +193,21 @@ void guac_rdp_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) {
/* If operation is just a copy, send foreground only */ /* If operation is just a copy, send foreground only */
case 0xCC: case 0xCC:
case 0xF0: case 0xF0:
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_common_surface_rect(current_surface, x, y, w, h,
guac_protocol_send_cfill(client->socket,
GUAC_COMP_OVER, current_layer,
(patblt->foreColor >> 16) & 0xFF, (patblt->foreColor >> 16) & 0xFF,
(patblt->foreColor >> 8 ) & 0xFF, (patblt->foreColor >> 8 ) & 0xFF,
(patblt->foreColor ) & 0xFF, (patblt->foreColor ) & 0xFF);
0xFF);
break; break;
/* If whiteness, send white rectangle */ /* If whiteness, send white rectangle */
case 0xFF: case 0xFF:
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_common_surface_rect(current_surface, x, y, w, h, 0xFF, 0xFF, 0xFF);
guac_protocol_send_cfill(client->socket,
GUAC_COMP_OVER, current_layer,
0xFF, 0xFF, 0xFF, 0xFF);
break; break;
/* Otherwise, invert entire rect */ /* Otherwise, invert entire rect */
default: default:
guac_common_surface_transfer(current_surface, x, y, w, h,
/* Allocate buffer for transfer */ GUAC_TRANSFER_BINARY_NDEST, current_surface, x, y);
buffer = guac_client_alloc_buffer(client);
/* Send rectangle stroke */
guac_protocol_send_rect(client->socket, buffer,
0, 0, w, h);
/* Fill rectangle with fore color only */
guac_protocol_send_cfill(client->socket, GUAC_COMP_OVER, buffer,
0xFF, 0xFF, 0xFF, 0xFF);
/* Transfer */
guac_protocol_send_transfer(client->socket,
/* ... from buffer */
buffer, 0, 0, w, h,
/* ... inverting */
GUAC_TRANSFER_BINARY_XOR,
/* ... to current layer */
current_layer, x, y);
/* Done with buffer */
guac_client_free_buffer(client, buffer);
} }
@ -268,7 +216,7 @@ void guac_rdp_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) {
void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) { void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) {
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface; guac_common_surface* current_surface = ((rdp_guac_client_data*) client->data)->current_surface;
int x = scrblt->nLeftRect; int x = scrblt->nLeftRect;
int y = scrblt->nTopRect; int y = scrblt->nTopRect;
@ -288,17 +236,15 @@ void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) {
y_src += y - scrblt->nTopRect; y_src += y - scrblt->nTopRect;
/* Copy screen rect to current surface */ /* Copy screen rect to current surface */
guac_protocol_send_copy(client->socket, guac_common_surface_copy(data->default_surface, x_src, y_src, w, h,
GUAC_DEFAULT_LAYER, x_src, y_src, w, h, current_surface, x, y);
GUAC_COMP_OVER, current_layer, x, y);
} }
void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) { void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface; guac_common_surface* current_surface = ((rdp_guac_client_data*) client->data)->current_surface;
guac_socket* socket = client->socket;
guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap; guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap;
int x = memblt->nLeftRect; int x = memblt->nLeftRect;
@ -329,11 +275,7 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
/* If blackness, send black rectangle */ /* If blackness, send black rectangle */
case 0x00: case 0x00:
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_common_surface_rect(current_surface, x, y, w, h, 0, 0, 0);
guac_protocol_send_cfill(client->socket,
GUAC_COMP_OVER, current_layer,
0x00, 0x00, 0x00, 0xFF);
break; break;
/* If NOP, do nothing */ /* If NOP, do nothing */
@ -344,12 +286,11 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
case 0xCC: case 0xCC:
/* If not cached, cache if necessary */ /* If not cached, cache if necessary */
if (((guac_rdp_bitmap*) bitmap)->layer == NULL if (bitmap->surface == NULL && bitmap->used >= 1)
&& ((guac_rdp_bitmap*) bitmap)->used >= 1)
guac_rdp_cache_bitmap(context, memblt->bitmap); guac_rdp_cache_bitmap(context, memblt->bitmap);
/* If not cached, send as PNG */ /* If not cached, send as PNG */
if (bitmap->layer == NULL) { if (bitmap->surface == NULL) {
if (memblt->bitmap->data != NULL) { if (memblt->bitmap->data != NULL) {
/* Create surface from image data */ /* Create surface from image data */
@ -358,9 +299,7 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
CAIRO_FORMAT_RGB24, w, h, 4*memblt->bitmap->width); CAIRO_FORMAT_RGB24, w, h, 4*memblt->bitmap->width);
/* Send surface to buffer */ /* Send surface to buffer */
guac_protocol_send_png(socket, guac_common_surface_draw(current_surface, x, y, surface);
GUAC_COMP_OVER, current_layer,
x, y, surface);
/* Free surface */ /* Free surface */
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
@ -370,9 +309,8 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
/* Otherwise, copy */ /* Otherwise, copy */
else else
guac_protocol_send_copy(socket, guac_common_surface_copy(bitmap->surface, x_src, y_src, w, h,
bitmap->layer, x_src, y_src, w, h, current_surface, x, y);
GUAC_COMP_OVER, current_layer, x, y);
/* Increment usage counter */ /* Increment usage counter */
((guac_rdp_bitmap*) bitmap)->used++; ((guac_rdp_bitmap*) bitmap)->used++;
@ -381,24 +319,19 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
/* If whiteness, send white rectangle */ /* If whiteness, send white rectangle */
case 0xFF: case 0xFF:
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_common_surface_rect(current_surface, x, y, w, h, 0xFF, 0xFF, 0xFF);
guac_protocol_send_cfill(client->socket,
GUAC_COMP_OVER, current_layer,
0xFF, 0xFF, 0xFF, 0xFF);
break; break;
/* Otherwise, use transfer */ /* Otherwise, use transfer */
default: default:
/* If not available as a surface, make available. */ /* If not available as a surface, make available. */
if (bitmap->layer == NULL) if (bitmap->surface == NULL)
guac_rdp_cache_bitmap(context, memblt->bitmap); guac_rdp_cache_bitmap(context, memblt->bitmap);
guac_protocol_send_transfer(socket, guac_common_surface_transfer(bitmap->surface, x_src, y_src, w, h,
bitmap->layer, x_src, y_src, w, h, guac_rdp_rop3_transfer_function(client, memblt->bRop),
guac_rdp_rop3_transfer_function(client, memblt->bRop), current_surface, x, y);
current_layer, x, y);
/* Increment usage counter */ /* Increment usage counter */
((guac_rdp_bitmap*) bitmap)->used++; ((guac_rdp_bitmap*) bitmap)->used++;
@ -417,7 +350,7 @@ void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect
client_data->settings.color_depth, 32, client_data->settings.color_depth, 32,
((rdp_freerdp_context*) context)->clrconv); ((rdp_freerdp_context*) context)->clrconv);
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface; guac_common_surface* current_surface = ((rdp_guac_client_data*) client->data)->current_surface;
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data; rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
@ -430,14 +363,10 @@ void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect
if (guac_rdp_clip_rect(data, &x, &y, &w, &h)) if (guac_rdp_clip_rect(data, &x, &y, &w, &h))
return; return;
guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_common_surface_rect(current_surface, x, y, w, h,
guac_protocol_send_cfill(client->socket,
GUAC_COMP_OVER, current_layer,
(color >> 16) & 0xFF, (color >> 16) & 0xFF,
(color >> 8 ) & 0xFF, (color >> 8 ) & 0xFF,
(color ) & 0xFF, (color ) & 0xFF);
255);
} }

View File

@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include "client.h" #include "client.h"
#include "guac_surface.h"
#include "rdp_glyph.h" #include "rdp_glyph.h"
#include <pthread.h> #include <pthread.h>
@ -199,7 +200,7 @@ void guac_rdp_glyph_enddraw(rdpContext* context,
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data; rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface; guac_common_surface* current_surface = ((rdp_guac_client_data*) client->data)->current_surface;
/* Use glyph surface to provide image data for glyph rectangle */ /* Use glyph surface to provide image data for glyph rectangle */
cairo_surface_t* glyph_surface = guac_client_data->glyph_surface; cairo_surface_t* glyph_surface = guac_client_data->glyph_surface;
@ -225,10 +226,8 @@ void guac_rdp_glyph_enddraw(rdpContext* context,
cairo_image_surface_get_format(glyph_surface), cairo_image_surface_get_format(glyph_surface),
width, height, stride); width, height, stride);
/* Send surface with all glyphs to layer */ /* Send surface with all glyphs to current surface */
guac_protocol_send_png(client->socket, guac_common_surface_draw(current_surface, x, y, surface);
GUAC_COMP_OVER, current_layer, x, y,
surface);
/* Destroy surface */ /* Destroy surface */
cairo_surface_destroy(surface); cairo_surface_destroy(surface);