GUACAMOLE-188: Merge alpha component support for common surface.
This commit is contained in:
commit
d831a4b9df
@ -336,20 +336,43 @@ void guac_common_surface_transfer(guac_common_surface* src, int sx, int sy, int
|
|||||||
guac_transfer_function op, guac_common_surface* dst, int dx, int dy);
|
guac_transfer_function op, guac_common_surface* dst, int dx, int dy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a solid color rectangle at the given coordinates on the given surface.
|
* Assigns the given value to all pixels within a rectangle of the given
|
||||||
|
* surface. The color of all pixels within the rectangle, including the alpha
|
||||||
|
* component, is entirely replaced.
|
||||||
*
|
*
|
||||||
* @param surface The surface to draw upon.
|
* @param surface
|
||||||
* @param x The X coordinate of the upper-left corner of the rectangle.
|
* The surface to draw upon.
|
||||||
* @param y The Y coordinate of the upper-left corner of the rectangle.
|
*
|
||||||
* @param w The width of the rectangle.
|
* @param x
|
||||||
* @param h The height of the rectangle.
|
* The X coordinate of the upper-left corner of the rectangle.
|
||||||
* @param red The red component of the color of the rectangle.
|
*
|
||||||
* @param green The green component of the color of the rectangle.
|
* @param y
|
||||||
* @param blue The blue component of the color of the rectangle.
|
* The Y coordinate of the upper-left corner of the rectangle.
|
||||||
|
*
|
||||||
|
* @param w
|
||||||
|
* The width of the rectangle.
|
||||||
|
*
|
||||||
|
* @param h
|
||||||
|
* The height of the rectangle.
|
||||||
|
*
|
||||||
|
* @param red
|
||||||
|
* The red component of the color value to assign to all pixels within the
|
||||||
|
* rectangle.
|
||||||
|
*
|
||||||
|
* @param green
|
||||||
|
* The green component of the color value to assign to all pixels within
|
||||||
|
* the rectangle.
|
||||||
|
*
|
||||||
|
* @param blue
|
||||||
|
* The blue component of the color value to assign to all pixels within the
|
||||||
|
* rectangle.
|
||||||
|
*
|
||||||
|
* @param alpha
|
||||||
|
* The alpha component of the color value to assign to all pixels within
|
||||||
|
* the rectangle.
|
||||||
*/
|
*/
|
||||||
void guac_common_surface_rect(guac_common_surface* surface,
|
void guac_common_surface_set(guac_common_surface* surface, int x, int y,
|
||||||
int x, int y, int w, int h,
|
int w, int h, int red, int green, int blue, int alpha);
|
||||||
int red, int green, int blue);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the coordinates and dimensions of a rectangle, clips all future
|
* Given the coordinates and dimensions of a rectangle, clips all future
|
||||||
|
@ -224,6 +224,54 @@ static void __guac_common_clip_rect(guac_common_surface* surface,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a rectangle within the given surface contains only fully
|
||||||
|
* opaque pixels.
|
||||||
|
*
|
||||||
|
* @param surface
|
||||||
|
* The surface to check.
|
||||||
|
*
|
||||||
|
* @param rect
|
||||||
|
* The rectangle to check.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Non-zero if the rectangle contains only fully opaque pixels, zero
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
static int __guac_common_surface_is_opaque(guac_common_surface* surface,
|
||||||
|
guac_common_rect* rect) {
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
int stride = surface ->stride;
|
||||||
|
unsigned char* buffer =
|
||||||
|
surface->buffer + (stride * rect->y) + (4 * rect->x);
|
||||||
|
|
||||||
|
/* For each row */
|
||||||
|
for (y = 0; y < rect->height; y++) {
|
||||||
|
|
||||||
|
/* Search for a non-opaque pixel */
|
||||||
|
uint32_t* current = (uint32_t*) buffer;
|
||||||
|
for (x=0; x < rect->width; x++) {
|
||||||
|
|
||||||
|
/* Rectangle is non-opaque if a single non-opaque pixel is found */
|
||||||
|
uint32_t color = *(current++);
|
||||||
|
if ((color & 0xFF000000) != 0xFF000000)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next row */
|
||||||
|
buffer += stride;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rectangle is opaque */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the given rectangle should be combined into the existing
|
* Returns whether the given rectangle should be combined into the existing
|
||||||
* dirty rectangle, to be eventually flushed as a "png" instruction.
|
* dirty rectangle, to be eventually flushed as a "png" instruction.
|
||||||
@ -730,24 +778,41 @@ static int __guac_common_surface_transfer_int(guac_transfer_function op, uint32_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a rectangle of solid color within the backing surface of the
|
* Assigns the given value to all pixels within a rectangle of the backing
|
||||||
* given destination surface.
|
* surface of the given destination surface. The color of all pixels within the
|
||||||
|
* rectangle, including the alpha component, is entirely replaced.
|
||||||
*
|
*
|
||||||
* @param dst The destination surface.
|
* @param dst
|
||||||
* @param rect The rectangle to draw.
|
* The destination surface.
|
||||||
* @param red The red component of the color of the rectangle.
|
*
|
||||||
* @param green The green component of the color of the rectangle.
|
* @param rect
|
||||||
* @param blue The blue component of the color of the rectangle.
|
* The rectangle to draw.
|
||||||
|
*
|
||||||
|
* @param red
|
||||||
|
* The red component of the color value to assign to all pixels within the
|
||||||
|
* rectangle.
|
||||||
|
*
|
||||||
|
* @param green
|
||||||
|
* The green component of the color value to assign to all pixels within
|
||||||
|
* the rectangle.
|
||||||
|
*
|
||||||
|
* @param blue
|
||||||
|
* The blue component of the color value to assign to all pixels within the
|
||||||
|
* rectangle.
|
||||||
|
*
|
||||||
|
* @param alpha
|
||||||
|
* The alpha component of the color value to assign to all pixels within
|
||||||
|
* the rectangle.
|
||||||
*/
|
*/
|
||||||
static void __guac_common_surface_rect(guac_common_surface* dst, guac_common_rect* rect,
|
static void __guac_common_surface_set(guac_common_surface* dst,
|
||||||
int red, int green, int blue) {
|
guac_common_rect* rect, int red, int green, int blue, int alpha) {
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
int dst_stride;
|
int dst_stride;
|
||||||
unsigned char* dst_buffer;
|
unsigned char* dst_buffer;
|
||||||
|
|
||||||
uint32_t color = 0xFF000000 | (red << 16) | (green << 8) | blue;
|
uint32_t color = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||||
|
|
||||||
int min_x = rect->width - 1;
|
int min_x = rect->width - 1;
|
||||||
int min_y = rect->height - 1;
|
int min_y = rect->height - 1;
|
||||||
@ -1063,7 +1128,7 @@ guac_common_surface* guac_common_surface_alloc(guac_client* client,
|
|||||||
pthread_mutex_init(&surface->_lock, NULL);
|
pthread_mutex_init(&surface->_lock, NULL);
|
||||||
|
|
||||||
/* Create corresponding Cairo surface */
|
/* Create corresponding Cairo surface */
|
||||||
surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
|
surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w);
|
||||||
surface->buffer = calloc(h, surface->stride);
|
surface->buffer = calloc(h, surface->stride);
|
||||||
|
|
||||||
/* Create corresponding heat map */
|
/* Create corresponding heat map */
|
||||||
@ -1130,7 +1195,7 @@ void guac_common_surface_resize(guac_common_surface* surface, int w, int h) {
|
|||||||
/* Re-initialize at new size */
|
/* Re-initialize at new size */
|
||||||
surface->width = w;
|
surface->width = w;
|
||||||
surface->height = h;
|
surface->height = h;
|
||||||
surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
|
surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w);
|
||||||
surface->buffer = calloc(h, surface->stride);
|
surface->buffer = calloc(h, surface->stride);
|
||||||
__guac_common_bound_rect(surface, &surface->clip_rect, NULL, NULL);
|
__guac_common_bound_rect(surface, &surface->clip_rect, NULL, NULL);
|
||||||
|
|
||||||
@ -1373,8 +1438,8 @@ complete:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_common_surface_rect(guac_common_surface* surface,
|
void guac_common_surface_set(guac_common_surface* surface,
|
||||||
int x, int y, int w, int h, int red, int green, int blue) {
|
int x, int y, int w, int h, int red, int green, int blue, int alpha) {
|
||||||
|
|
||||||
pthread_mutex_lock(&surface->_lock);
|
pthread_mutex_lock(&surface->_lock);
|
||||||
|
|
||||||
@ -1390,19 +1455,31 @@ void guac_common_surface_rect(guac_common_surface* surface,
|
|||||||
goto complete;
|
goto complete;
|
||||||
|
|
||||||
/* Update backing surface */
|
/* Update backing surface */
|
||||||
__guac_common_surface_rect(surface, &rect, red, green, blue);
|
__guac_common_surface_set(surface, &rect, red, green, blue, alpha);
|
||||||
if (rect.width <= 0 || rect.height <= 0)
|
if (rect.width <= 0 || rect.height <= 0)
|
||||||
goto complete;
|
goto complete;
|
||||||
|
|
||||||
|
/* Handle as normal draw if non-opaque */
|
||||||
|
if (alpha != 0xFF) {
|
||||||
|
|
||||||
|
/* Flush if not combining */
|
||||||
|
if (!__guac_common_should_combine(surface, &rect, 0))
|
||||||
|
__guac_common_surface_flush_deferred(surface);
|
||||||
|
|
||||||
|
/* Always defer draws */
|
||||||
|
__guac_common_mark_dirty(surface, &rect);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Defer if combining */
|
/* Defer if combining */
|
||||||
if (__guac_common_should_combine(surface, &rect, 1))
|
else if (__guac_common_should_combine(surface, &rect, 1))
|
||||||
__guac_common_mark_dirty(surface, &rect);
|
__guac_common_mark_dirty(surface, &rect);
|
||||||
|
|
||||||
/* Otherwise, flush and draw immediately */
|
/* Otherwise, flush and draw immediately */
|
||||||
else {
|
else {
|
||||||
__guac_common_surface_flush(surface);
|
__guac_common_surface_flush(surface);
|
||||||
guac_protocol_send_rect(socket, layer, rect.x, rect.y, rect.width, rect.height);
|
guac_protocol_send_rect(socket, layer, rect.x, rect.y, rect.width, rect.height);
|
||||||
guac_protocol_send_cfill(socket, GUAC_COMP_OVER, layer, red, green, blue, 0xFF);
|
guac_protocol_send_cfill(socket, GUAC_COMP_OVER, layer, red, green, blue, alpha);
|
||||||
surface->realized = 1;
|
surface->realized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1444,8 +1521,12 @@ void guac_common_surface_reset_clip(guac_common_surface* surface) {
|
|||||||
*
|
*
|
||||||
* @param surface
|
* @param surface
|
||||||
* The surface to flush.
|
* The surface to flush.
|
||||||
|
*
|
||||||
|
* @param opaque
|
||||||
|
* Whether the rectangle being flushed contains only fully-opaque pixels.
|
||||||
*/
|
*/
|
||||||
static void __guac_common_surface_flush_to_png(guac_common_surface* surface) {
|
static void __guac_common_surface_flush_to_png(guac_common_surface* surface,
|
||||||
|
int opaque) {
|
||||||
|
|
||||||
if (surface->dirty) {
|
if (surface->dirty) {
|
||||||
|
|
||||||
@ -1457,10 +1538,30 @@ static void __guac_common_surface_flush_to_png(guac_common_surface* surface) {
|
|||||||
+ surface->dirty_rect.y * surface->stride
|
+ surface->dirty_rect.y * surface->stride
|
||||||
+ surface->dirty_rect.x * 4;
|
+ surface->dirty_rect.x * 4;
|
||||||
|
|
||||||
cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer,
|
cairo_surface_t* rect;
|
||||||
|
|
||||||
|
/* Use RGB24 if the image is fully opaque */
|
||||||
|
if (opaque)
|
||||||
|
rect = cairo_image_surface_create_for_data(buffer,
|
||||||
CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
|
CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
|
||||||
surface->dirty_rect.height, surface->stride);
|
surface->dirty_rect.height, surface->stride);
|
||||||
|
|
||||||
|
/* Otherwise ARGB32 is needed */
|
||||||
|
else {
|
||||||
|
|
||||||
|
rect = cairo_image_surface_create_for_data(buffer,
|
||||||
|
CAIRO_FORMAT_ARGB32, surface->dirty_rect.width,
|
||||||
|
surface->dirty_rect.height, surface->stride);
|
||||||
|
|
||||||
|
/* Clear destination rect first */
|
||||||
|
guac_protocol_send_rect(socket, layer,
|
||||||
|
surface->dirty_rect.x, surface->dirty_rect.y,
|
||||||
|
surface->dirty_rect.width, surface->dirty_rect.height);
|
||||||
|
guac_protocol_send_cfill(socket, GUAC_COMP_ROUT, layer,
|
||||||
|
0x00, 0x00, 0x00, 0xFF);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Send PNG for rect */
|
/* Send PNG for rect */
|
||||||
guac_client_stream_png(surface->client, socket, GUAC_COMP_OVER,
|
guac_client_stream_png(surface->client, socket, GUAC_COMP_OVER,
|
||||||
layer, surface->dirty_rect.x, surface->dirty_rect.y, rect);
|
layer, surface->dirty_rect.x, surface->dirty_rect.y, rect);
|
||||||
@ -1531,8 +1632,12 @@ static void __guac_common_surface_flush_to_jpeg(guac_common_surface* surface) {
|
|||||||
*
|
*
|
||||||
* @param surface
|
* @param surface
|
||||||
* The surface to flush.
|
* The surface to flush.
|
||||||
|
*
|
||||||
|
* @param opaque
|
||||||
|
* Whether the rectangle being flushed contains only fully-opaque pixels.
|
||||||
*/
|
*/
|
||||||
static void __guac_common_surface_flush_to_webp(guac_common_surface* surface) {
|
static void __guac_common_surface_flush_to_webp(guac_common_surface* surface,
|
||||||
|
int opaque) {
|
||||||
|
|
||||||
if (surface->dirty) {
|
if (surface->dirty) {
|
||||||
|
|
||||||
@ -1552,10 +1657,20 @@ static void __guac_common_surface_flush_to_webp(guac_common_surface* surface) {
|
|||||||
+ surface->dirty_rect.y * surface->stride
|
+ surface->dirty_rect.y * surface->stride
|
||||||
+ surface->dirty_rect.x * 4;
|
+ surface->dirty_rect.x * 4;
|
||||||
|
|
||||||
cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer,
|
cairo_surface_t* rect;
|
||||||
|
|
||||||
|
/* Use RGB24 if the image is fully opaque */
|
||||||
|
if (opaque)
|
||||||
|
rect = cairo_image_surface_create_for_data(buffer,
|
||||||
CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
|
CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
|
||||||
surface->dirty_rect.height, surface->stride);
|
surface->dirty_rect.height, surface->stride);
|
||||||
|
|
||||||
|
/* Otherwise ARGB32 is needed */
|
||||||
|
else
|
||||||
|
rect = cairo_image_surface_create_for_data(buffer,
|
||||||
|
CAIRO_FORMAT_ARGB32, surface->dirty_rect.width,
|
||||||
|
surface->dirty_rect.height, surface->stride);
|
||||||
|
|
||||||
/* Send WebP for rect */
|
/* Send WebP for rect */
|
||||||
guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
|
guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
|
||||||
surface->dirty_rect.x, surface->dirty_rect.y, rect,
|
surface->dirty_rect.x, surface->dirty_rect.y, rect,
|
||||||
@ -1684,19 +1799,22 @@ static void __guac_common_surface_flush(guac_common_surface* surface) {
|
|||||||
|
|
||||||
flushed++;
|
flushed++;
|
||||||
|
|
||||||
|
int opaque = __guac_common_surface_is_opaque(surface,
|
||||||
|
&surface->dirty_rect);
|
||||||
|
|
||||||
/* Prefer WebP when reasonable */
|
/* Prefer WebP when reasonable */
|
||||||
if (__guac_common_surface_should_use_webp(surface,
|
if (__guac_common_surface_should_use_webp(surface,
|
||||||
&surface->dirty_rect))
|
&surface->dirty_rect))
|
||||||
__guac_common_surface_flush_to_webp(surface);
|
__guac_common_surface_flush_to_webp(surface, opaque);
|
||||||
|
|
||||||
/* If not WebP, JPEG is the next best (lossy) choice */
|
/* If not WebP, JPEG is the next best (lossy) choice */
|
||||||
else if (__guac_common_surface_should_use_jpeg(surface,
|
else if (opaque && __guac_common_surface_should_use_jpeg(
|
||||||
&surface->dirty_rect))
|
surface, &surface->dirty_rect))
|
||||||
__guac_common_surface_flush_to_jpeg(surface);
|
__guac_common_surface_flush_to_jpeg(surface);
|
||||||
|
|
||||||
/* Use PNG if no lossy formats are appropriate */
|
/* Use PNG if no lossy formats are appropriate */
|
||||||
else
|
else
|
||||||
__guac_common_surface_flush_to_png(surface);
|
__guac_common_surface_flush_to_png(surface, opaque);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1755,7 +1873,7 @@ void guac_common_surface_dup(guac_common_surface* surface, guac_user* user,
|
|||||||
|
|
||||||
/* Get entire surface */
|
/* Get entire surface */
|
||||||
cairo_surface_t* rect = cairo_image_surface_create_for_data(
|
cairo_surface_t* rect = cairo_image_surface_create_for_data(
|
||||||
surface->buffer, CAIRO_FORMAT_RGB24,
|
surface->buffer, CAIRO_FORMAT_ARGB32,
|
||||||
surface->width, surface->height, surface->stride);
|
surface->width, surface->height, surface->stride);
|
||||||
|
|
||||||
/* Send PNG for rect */
|
/* Send PNG for rect */
|
||||||
|
@ -113,7 +113,8 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) {
|
|||||||
case 0:
|
case 0:
|
||||||
|
|
||||||
/* Send black rectangle */
|
/* Send black rectangle */
|
||||||
guac_common_surface_rect(current_surface, x, y, w, h, 0, 0, 0);
|
guac_common_surface_set(current_surface, x, y, w, h,
|
||||||
|
0x00, 0x00, 0x00, 0xFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* DSTINVERT */
|
/* DSTINVERT */
|
||||||
@ -128,7 +129,8 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) {
|
|||||||
|
|
||||||
/* Whiteness */
|
/* Whiteness */
|
||||||
case 0xFF:
|
case 0xFF:
|
||||||
guac_common_surface_rect(current_surface, x, y, w, h, 0xFF, 0xFF, 0xFF);
|
guac_common_surface_set(current_surface, x, y, w, h,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Unsupported ROP3 */
|
/* Unsupported ROP3 */
|
||||||
@ -175,7 +177,8 @@ 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_common_surface_rect(current_surface, x, y, w, h, 0, 0, 0);
|
guac_common_surface_set(current_surface, x, y, w, h,
|
||||||
|
0x00, 0x00, 0x00, 0xFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If NOP, do nothing */
|
/* If NOP, do nothing */
|
||||||
@ -185,15 +188,17 @@ 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_common_surface_rect(current_surface, x, y, w, h,
|
guac_common_surface_set(current_surface, x, y, w, h,
|
||||||
(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_common_surface_rect(current_surface, x, y, w, h, 0xFF, 0xFF, 0xFF);
|
guac_common_surface_set(current_surface, x, y, w, h,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Otherwise, invert entire rect */
|
/* Otherwise, invert entire rect */
|
||||||
@ -250,7 +255,8 @@ 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_common_surface_rect(current_surface, x, y, w, h, 0, 0, 0);
|
guac_common_surface_set(current_surface, x, y, w, h,
|
||||||
|
0x00, 0x00, 0x00, 0xFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If NOP, do nothing */
|
/* If NOP, do nothing */
|
||||||
@ -294,7 +300,8 @@ 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_common_surface_rect(current_surface, x, y, w, h, 0xFF, 0xFF, 0xFF);
|
guac_common_surface_set(current_surface, x, y, w, h,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Otherwise, use transfer */
|
/* Otherwise, use transfer */
|
||||||
@ -330,10 +337,11 @@ void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect
|
|||||||
int w = opaque_rect->nWidth;
|
int w = opaque_rect->nWidth;
|
||||||
int h = opaque_rect->nHeight;
|
int h = opaque_rect->nHeight;
|
||||||
|
|
||||||
guac_common_surface_rect(current_surface, x, y, w, h,
|
guac_common_surface_set(current_surface, x, y, w, h,
|
||||||
(color >> 16) & 0xFF,
|
(color >> 16) & 0xFF,
|
||||||
(color >> 8 ) & 0xFF,
|
(color >> 8 ) & 0xFF,
|
||||||
(color ) & 0xFF);
|
(color ) & 0xFF,
|
||||||
|
0xFF);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,10 +136,12 @@ void guac_rdp_glyph_begindraw(rdpContext* context,
|
|||||||
/* Convert background color */
|
/* Convert background color */
|
||||||
bgcolor = guac_rdp_convert_color(context, bgcolor);
|
bgcolor = guac_rdp_convert_color(context, bgcolor);
|
||||||
|
|
||||||
guac_common_surface_rect(rdp_client->current_surface, x, y, width, height,
|
guac_common_surface_set(rdp_client->current_surface,
|
||||||
|
x, y, width, height,
|
||||||
(bgcolor & 0xFF0000) >> 16,
|
(bgcolor & 0xFF0000) >> 16,
|
||||||
(bgcolor & 0x00FF00) >> 8,
|
(bgcolor & 0x00FF00) >> 8,
|
||||||
bgcolor & 0x0000FF);
|
(bgcolor & 0x0000FF),
|
||||||
|
0xFF);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,13 +773,14 @@ void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send rect */
|
/* Send rect */
|
||||||
guac_common_surface_rect(
|
guac_common_surface_set(
|
||||||
display->display_surface,
|
display->display_surface,
|
||||||
col * display->char_width,
|
col * display->char_width,
|
||||||
row * display->char_height,
|
row * display->char_height,
|
||||||
rect_width * display->char_width,
|
rect_width * display->char_width,
|
||||||
rect_height * display->char_height,
|
rect_height * display->char_height,
|
||||||
guac_color->red, guac_color->green, guac_color->blue);
|
guac_color->red, guac_color->green, guac_color->blue,
|
||||||
|
0xFF);
|
||||||
|
|
||||||
} /* end if clear operation */
|
} /* end if clear operation */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user