void guac_rdp_bitmap_setsurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary) { guac_client* client = ((rdp_freerdp_context*) context)->client; rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data; if (primary) client_data->current_surface = client_data->default_surface; else { /* Make sure that the recieved bitmap is not NULL before processing */ if (bitmap == NULL) { guac_client_log(client, GUAC_LOG_INFO, "NULL bitmap found in bitmap_setsurface instruction."); return; } /* If not available as a surface, make available. */ if (((guac_rdp_bitmap*) bitmap)->surface == NULL) guac_rdp_cache_bitmap(context, bitmap); client_data->current_surface = ((guac_rdp_bitmap*) bitmap)->surface; } }
void guac_rdp_bitmap_setsurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary) { guac_client* client = ((rdp_freerdp_context*) context)->client; if (primary) ((rdp_guac_client_data*) client->data)->current_surface = GUAC_DEFAULT_LAYER; else { /* Make sure that the recieved bitmap is not NULL before processing */ if (bitmap == NULL) { guac_client_log_info(client, "NULL bitmap found in bitmap_setsurface instruction."); return; } /* If not available as a surface, make available. */ if (((guac_rdp_bitmap*) bitmap)->layer == NULL) guac_rdp_cache_bitmap(context, bitmap); ((rdp_guac_client_data*) client->data)->current_surface = ((guac_rdp_bitmap*) bitmap)->layer; } }
void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) { guac_client* client = ((rdp_freerdp_context*) context)->client; guac_socket* socket = client->socket; int width = bitmap->right - bitmap->left + 1; int height = bitmap->bottom - bitmap->top + 1; /* If not cached, cache if necessary */ if (((guac_rdp_bitmap*) bitmap)->layer == NULL && ((guac_rdp_bitmap*) bitmap)->used >= 1) guac_rdp_cache_bitmap(context, bitmap); /* If cached, retrieve from cache */ if (((guac_rdp_bitmap*) bitmap)->layer != NULL) guac_protocol_send_copy(socket, ((guac_rdp_bitmap*) bitmap)->layer, 0, 0, width, height, GUAC_COMP_OVER, GUAC_DEFAULT_LAYER, bitmap->left, bitmap->top); /* Otherwise, draw with stored image data */ else if (bitmap->data != NULL) { /* Create surface from image data */ cairo_surface_t* surface = cairo_image_surface_create_for_data( bitmap->data, CAIRO_FORMAT_RGB24, width, height, 4*bitmap->width); /* Send surface to buffer */ guac_protocol_send_png(socket, GUAC_COMP_OVER, GUAC_DEFAULT_LAYER, bitmap->left, bitmap->top, surface); /* Free surface */ cairo_surface_destroy(surface); } /* Increment usage counter */ ((guac_rdp_bitmap*) bitmap)->used++; }
void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) { guac_client* client = ((rdp_freerdp_context*) context)->client; 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 height = bitmap->bottom - bitmap->top + 1; /* If not cached, cache if necessary */ if (surface == NULL && ((guac_rdp_bitmap*) bitmap)->used >= 1) guac_rdp_cache_bitmap(context, bitmap); /* If cached, retrieve from cache */ if (surface != NULL) guac_common_surface_copy(surface, 0, 0, width, height, client_data->default_surface, bitmap->left, bitmap->top); /* Otherwise, draw with stored image data */ else if (bitmap->data != NULL) { /* Create surface from image data */ cairo_surface_t* image = cairo_image_surface_create_for_data( bitmap->data, CAIRO_FORMAT_RGB24, width, height, 4*bitmap->width); /* Draw image on default surface */ guac_common_surface_draw(client_data->default_surface, bitmap->left, bitmap->top, image); /* Free surface */ cairo_surface_destroy(image); } /* Increment usage counter */ ((guac_rdp_bitmap*) bitmap)->used++; }
void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) { guac_client* client = ((rdp_freerdp_context*) context)->client; guac_common_surface* current_surface = ((rdp_guac_client_data*) client->data)->current_surface; guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap; int x = memblt->nLeftRect; int y = memblt->nTopRect; int w = memblt->nWidth; int h = memblt->nHeight; int x_src = memblt->nXSrc; int y_src = memblt->nYSrc; /* Make sure that the recieved bitmap is not NULL before processing */ if (bitmap == NULL) { guac_client_log(client, GUAC_LOG_INFO, "NULL bitmap found in memblt instruction."); return; } switch (memblt->bRop) { /* If blackness, send black rectangle */ case 0x00: guac_common_surface_rect(current_surface, x, y, w, h, 0, 0, 0); break; /* If NOP, do nothing */ case 0xAA: break; /* If operation is just SRC, simply copy */ case 0xCC: /* If not cached, cache if necessary */ if (bitmap->surface == NULL && bitmap->used >= 1) guac_rdp_cache_bitmap(context, memblt->bitmap); /* If not cached, send as PNG */ if (bitmap->surface == NULL) { if (memblt->bitmap->data != NULL) { /* Create surface from image data */ cairo_surface_t* surface = cairo_image_surface_create_for_data( memblt->bitmap->data + 4*(x_src + y_src*memblt->bitmap->width), CAIRO_FORMAT_RGB24, w, h, 4*memblt->bitmap->width); /* Send surface to buffer */ guac_common_surface_draw(current_surface, x, y, surface); /* Free surface */ cairo_surface_destroy(surface); } } /* Otherwise, copy */ else guac_common_surface_copy(bitmap->surface, x_src, y_src, w, h, current_surface, x, y); /* Increment usage counter */ ((guac_rdp_bitmap*) bitmap)->used++; break; /* If whiteness, send white rectangle */ case 0xFF: guac_common_surface_rect(current_surface, x, y, w, h, 0xFF, 0xFF, 0xFF); break; /* Otherwise, use transfer */ default: /* If not available as a surface, make available. */ if (bitmap->surface == NULL) guac_rdp_cache_bitmap(context, memblt->bitmap); guac_common_surface_transfer(bitmap->surface, x_src, y_src, w, h, guac_rdp_rop3_transfer_function(client, memblt->bRop), current_surface, x, y); /* Increment usage counter */ ((guac_rdp_bitmap*) bitmap)->used++; } }
void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) { guac_client* client = ((rdp_freerdp_context*) context)->client; const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface; guac_socket* socket = client->socket; guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap; int x = memblt->nLeftRect; int y = memblt->nTopRect; int w = memblt->nWidth; int h = memblt->nHeight; int x_src = memblt->nXSrc; int y_src = memblt->nYSrc; rdp_guac_client_data* data = (rdp_guac_client_data*) client->data; pthread_mutex_lock(&(data->update_lock)); /* Clip operation to bounds */ __guac_rdp_clip_rect(data, &x, &y, &w, &h); /* Update source coordinates */ x_src += x - memblt->nLeftRect; y_src += y - memblt->nTopRect; switch (memblt->bRop) { /* If blackness, send black rectangle */ case 0x00: guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_protocol_send_cfill(client->socket, GUAC_COMP_OVER, current_layer, 0x00, 0x00, 0x00, 0xFF); break; /* If NOP, do nothing */ case 0xAA: break; /* If operation is just SRC, simply copy */ case 0xCC: /* If not cached, cache if necessary */ if (((guac_rdp_bitmap*) bitmap)->layer == NULL && ((guac_rdp_bitmap*) bitmap)->used >= 1) guac_rdp_cache_bitmap(context, memblt->bitmap); /* If not cached, send as PNG */ if (bitmap->layer == NULL) { if (memblt->bitmap->data != NULL) { /* Create surface from image data */ cairo_surface_t* surface = cairo_image_surface_create_for_data( memblt->bitmap->data + 4*(x_src + y_src*memblt->bitmap->width), CAIRO_FORMAT_RGB24, w, h, 4*memblt->bitmap->width); /* Send surface to buffer */ guac_protocol_send_png(socket, GUAC_COMP_OVER, current_layer, x, y, surface); /* Free surface */ cairo_surface_destroy(surface); } } /* Otherwise, copy */ else guac_protocol_send_copy(socket, bitmap->layer, x_src, y_src, w, h, GUAC_COMP_OVER, current_layer, x, y); /* Increment usage counter */ ((guac_rdp_bitmap*) bitmap)->used++; break; /* If whiteness, send white rectangle */ case 0xFF: guac_protocol_send_rect(client->socket, current_layer, x, y, w, h); guac_protocol_send_cfill(client->socket, GUAC_COMP_OVER, current_layer, 0xFF, 0xFF, 0xFF, 0xFF); break; /* Otherwise, use transfer */ default: /* If not available as a surface, make available. */ if (bitmap->layer == NULL) guac_rdp_cache_bitmap(context, memblt->bitmap); guac_protocol_send_transfer(socket, bitmap->layer, x_src, y_src, w, h, guac_rdp_rop3_transfer_function(client, memblt->bRop), current_layer, x, y); /* Increment usage counter */ ((guac_rdp_bitmap*) bitmap)->used++; } pthread_mutex_unlock(&(data->update_lock)); }