GUAC-656: Migrate RDP to guac_common_surface.
This commit is contained in:
parent
f6ccfd1211
commit
f8ac59798f
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user