static BOOL xf_gdi_update_screen(xfContext* xfc, const SURFACE_BITS_COMMAND* cmd, const BYTE* pSrcData) { BOOL ret; XImage* image; if (!xfc || !pSrcData) return FALSE; XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) pSrcData, cmd->width, cmd->height, xfc->scanline_pad, 0); if (image) { XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XFree(image); ret = xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); } XSetClipMask(xfc->display, xfc->gc, None); return ret; }
static BOOL xf_gdi_update_screen(xfContext* xfc, const BYTE* pSrcData, UINT32 scanline, const REGION16* pRegion) { BOOL ret = FALSE; XImage* image; UINT32 i, nbRects; const RECTANGLE_16* rects; UINT32 bpp; if (!xfc || !pSrcData) return FALSE; if (!(rects = region16_rects(pRegion, &nbRects))) return TRUE; if (xfc->depth > 16) bpp = 4; else if (xfc->depth > 8) bpp = 2; else bpp = 1; XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); for (i = 0; i < nbRects; i++) { UINT32 left = rects[i].left; UINT32 top = rects[i].top; UINT32 width = rects[i].right - rects[i].left; UINT32 height = rects[i].bottom - rects[i].top; const BYTE* src = pSrcData + top * scanline + bpp * left; image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) src, width, height, xfc->scanline_pad, scanline); if (!image) break; image->byte_order = LSBFirst; image->bitmap_bit_order = LSBFirst; XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, left, top, width, height); image->data = NULL; XDestroyImage(image); ret = xf_gdi_surface_update_frame(xfc, left, top, width, height); } XSetClipMask(xfc->display, xfc->gc, None); return ret; }
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) { int i, tx, ty; XImage* image; RFX_MESSAGE* message; xfInfo* xfi = ((xfContext*) context)->xfi; RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context; NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context; if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX) { message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetClipRectangles(xfi->display, xfi->gc, surface_bits_command->destLeft, surface_bits_command->destTop, (XRectangle*) message->rects, message->num_rects, YXBanded); /* Draw the tiles to primary surface, each is 64x64. */ for (i = 0; i < message->num_tiles; i++) { image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) message->tiles[i]->data, 64, 64, 32, 0); tx = message->tiles[i]->x + surface_bits_command->destLeft; ty = message->tiles[i]->y + surface_bits_command->destTop; XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, tx, ty, 64, 64); XFree(image); } /* Copy the updated region from backstore to the window. */ for (i = 0; i < message->num_rects; i++) { tx = message->rects[i].x + surface_bits_command->destLeft; ty = message->rects[i].y + surface_bits_command->destTop; xf_gdi_surface_update_frame(xfi, tx, ty, message->rects[i].width, message->rects[i].height); } XSetClipMask(xfi->display, xfi->gc, None); rfx_message_free(rfx_context, message); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC) { nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); xfi->bmp_codec_nsc = (BYTE*) realloc(xfi->bmp_codec_nsc, surface_bits_command->width * surface_bits_command->height * 4); freerdp_image_flip(nsc_context->bmpdata, xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32); image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32, 0); XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XFree(image); xf_gdi_surface_update_frame(xfi, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XSetClipMask(xfi->display, xfi->gc, None); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) { XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); /* Validate that the data received is large enough */ if( surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8 <= surface_bits_command->bitmapDataLength ) { xfi->bmp_codec_none = (BYTE*) realloc(xfi->bmp_codec_none, surface_bits_command->width * surface_bits_command->height * 4); freerdp_image_flip(surface_bits_command->bitmapData, xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32); image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0); XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XFree(image); xf_gdi_surface_update_frame(xfi, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XSetClipMask(xfi->display, xfi->gc, None); } else { printf("Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height); } } else { printf("Unsupported codecID %d\n", surface_bits_command->codecID); } }
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) { int i, tx, ty; XImage* image; BYTE* pSrcData; BYTE* pDstData; RFX_MESSAGE* message; xfContext* xfc = (xfContext*) context; xf_lock_x11(xfc, FALSE); if (cmd->codecID == RDP_CODEC_ID_REMOTEFX) { freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX); message = rfx_process_message(xfc->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetClipRectangles(xfc->display, xfc->gc, cmd->destLeft, cmd->destTop, (XRectangle*) message->rects, message->numRects, YXBanded); if (xfc->bitmap_size < (64 * 64 * 4)) { xfc->bitmap_size = 64 * 64 * 4; xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) return; } /* Draw the tiles to primary surface, each is 64x64. */ for (i = 0; i < message->numTiles; i++) { pSrcData = message->tiles[i]->data; pDstData = pSrcData; if ((xfc->depth != 24) || (xfc->depth != 32)) { pDstData = xfc->bitmap_buffer; freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, 64, 64, pSrcData, PIXEL_FORMAT_XRGB32, -1, 0, 0, xfc->palette); } image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) pDstData, 64, 64, xfc->scanline_pad, 0); tx = message->tiles[i]->x + cmd->destLeft; ty = message->tiles[i]->y + cmd->destTop; XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, tx, ty, 64, 64); XFree(image); } /* Copy the updated region from backstore to the window. */ for (i = 0; i < message->numRects; i++) { tx = message->rects[i].x + cmd->destLeft; ty = message->rects[i].y + cmd->destTop; if (!xfc->remote_app) { XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, tx, ty, message->rects[i].width, message->rects[i].height, tx, ty); } xf_gdi_surface_update_frame(xfc, tx, ty, message->rects[i].width, message->rects[i].height); } XSetClipMask(xfc->display, xfc->gc, None); rfx_message_free(xfc->codecs->rfx, message); } else if (cmd->codecID == RDP_CODEC_ID_NSCODEC) { freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC); nsc_process_message(xfc->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); if (xfc->bitmap_size < (cmd->width * cmd->height * 4)) { xfc->bitmap_size = cmd->width * cmd->height * 4; xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) return; } pSrcData = xfc->codecs->nsc->BitmapData; pDstData = xfc->bitmap_buffer; freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, xfc->palette); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0); XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XFree(image); if (!xfc->remote_app) { XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, cmd->destLeft, cmd->destTop); } xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XSetClipMask(xfc->display, xfc->gc, None); } else if (cmd->codecID == RDP_CODEC_ID_NONE) { XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); if (xfc->bitmap_size < (cmd->width * cmd->height * 4)) { xfc->bitmap_size = cmd->width * cmd->height * 4; xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) return; } pSrcData = cmd->bitmapData; pDstData = xfc->bitmap_buffer; freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, xfc->palette); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0); XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XFree(image); if (!xfc->remote_app) { XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, cmd->destLeft, cmd->destTop); } xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XSetClipMask(xfc->display, xfc->gc, None); } else { WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); } xf_unlock_x11(xfc, FALSE); }