/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_CreateSurface(RdpgfxClientContext* context, const RDPGFX_CREATE_SURFACE_PDU* createSurface) { size_t size; xfGfxSurface* surface; rdpGdi* gdi = (rdpGdi*)context->custom; xfContext* xfc = (xfContext*) gdi->context; surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface)); if (!surface) return CHANNEL_RC_NO_MEMORY; surface->gdi.codecs = codecs_new(gdi->context); if (!surface->gdi.codecs) { free(surface); return CHANNEL_RC_NO_MEMORY; } if (!freerdp_client_codecs_prepare(surface->gdi.codecs, FREERDP_CODEC_ALL, createSurface->width, createSurface->height)) { free(surface); return ERROR_INTERNAL_ERROR; } surface->gdi.surfaceId = createSurface->surfaceId; surface->gdi.width = (UINT32) createSurface->width; surface->gdi.height = (UINT32) createSurface->height; switch (createSurface->pixelFormat) { case GFX_PIXEL_FORMAT_ARGB_8888: surface->gdi.format = PIXEL_FORMAT_BGRA32; break; case GFX_PIXEL_FORMAT_XRGB_8888: surface->gdi.format = PIXEL_FORMAT_BGRX32; break; default: free(surface); return ERROR_INTERNAL_ERROR; } surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel( surface->gdi.format); surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad); size = surface->gdi.scanline * surface->gdi.height; surface->gdi.data = (BYTE*) _aligned_malloc(size, 16); if (!surface->gdi.data) { free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->gdi.data, size); if (gdi->dstFormat == surface->gdi.format) { surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->gdi.data, surface->gdi.width, surface->gdi.height, xfc->scanline_pad, surface->gdi.scanline); } else { UINT32 width = surface->gdi.width; UINT32 bytes = GetBytesPerPixel(gdi->dstFormat); surface->stageScanline = width * bytes; surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad); size = surface->stageScanline * surface->gdi.height; surface->stage = (BYTE*) _aligned_malloc(size, 16); if (!surface->stage) { _aligned_free(surface->gdi.data); free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->stage, size); surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->stage, surface->gdi.width, surface->gdi.height, xfc->scanline_pad, surface->gdi.scanline); } surface->gdi.outputMapped = FALSE; region16_init(&surface->gdi.invalidRegion); context->SetSurfaceData(context, surface->gdi.surfaceId, (void*) surface); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_CreateSurface(RdpgfxClientContext* context, const RDPGFX_CREATE_SURFACE_PDU* createSurface) { UINT ret = CHANNEL_RC_NO_MEMORY; size_t size; xfGfxSurface* surface; rdpGdi* gdi = (rdpGdi*)context->custom; xfContext* xfc = (xfContext*) gdi->context; surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface)); if (!surface) return CHANNEL_RC_NO_MEMORY; surface->gdi.codecs = gdi->context->codecs; if (!surface->gdi.codecs) { WLog_ERR(TAG, "%s: global GDI codecs aren't set", __FUNCTION__); goto out_free; } surface->gdi.surfaceId = createSurface->surfaceId; surface->gdi.width = (UINT32) createSurface->width; surface->gdi.height = (UINT32) createSurface->height; switch (createSurface->pixelFormat) { case GFX_PIXEL_FORMAT_ARGB_8888: surface->gdi.format = PIXEL_FORMAT_BGRA32; break; case GFX_PIXEL_FORMAT_XRGB_8888: surface->gdi.format = PIXEL_FORMAT_BGRX32; break; default: WLog_ERR(TAG, "%s: unknown pixelFormat 0x%"PRIx32"", __FUNCTION__, createSurface->pixelFormat); ret = ERROR_INTERNAL_ERROR; goto out_free; } surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel(surface->gdi.format); surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad); size = surface->gdi.scanline * surface->gdi.height; surface->gdi.data = (BYTE*)_aligned_malloc(size, 16); if (!surface->gdi.data) { WLog_ERR(TAG, "%s: unable to allocate GDI data", __FUNCTION__); goto out_free; } ZeroMemory(surface->gdi.data, size); if (AreColorFormatsEqualNoAlpha(gdi->dstFormat, surface->gdi.format)) { surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->gdi.data, surface->gdi.width, surface->gdi.height, xfc->scanline_pad, surface->gdi.scanline); } else { UINT32 width = surface->gdi.width; UINT32 bytes = GetBytesPerPixel(gdi->dstFormat); surface->stageScanline = width * bytes; surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad); size = surface->stageScanline * surface->gdi.height; surface->stage = (BYTE*) _aligned_malloc(size, 16); if (!surface->stage) { WLog_ERR(TAG, "%s: unable to allocate stage buffer", __FUNCTION__); goto out_free_gdidata; } ZeroMemory(surface->stage, size); surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->stage, surface->gdi.width, surface->gdi.height, xfc->scanline_pad, surface->stageScanline); } if (!surface->image) { WLog_ERR(TAG, "%s: an error occurred when creating the XImage", __FUNCTION__); goto error_surface_image; } surface->image->byte_order = LSBFirst; surface->image->bitmap_bit_order = LSBFirst; surface->gdi.outputMapped = FALSE; region16_init(&surface->gdi.invalidRegion); if (context->SetSurfaceData(context, surface->gdi.surfaceId, (void*) surface) != CHANNEL_RC_OK) { WLog_ERR(TAG, "%s: an error occurred during SetSurfaceData", __FUNCTION__); goto error_set_surface_data; } return CHANNEL_RC_OK; error_set_surface_data: surface->image->data = NULL; XDestroyImage(surface->image); error_surface_image: _aligned_free(surface->stage); out_free_gdidata: _aligned_free(surface->gdi.data); out_free: free(surface); return ret; }