/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_CreateSurface(RdpgfxClientContext* context, const RDPGFX_CREATE_SURFACE_PDU* createSurface) { gdiGfxSurface* surface; rdpGdi* gdi = (rdpGdi*) context->custom; surface = (gdiGfxSurface*) calloc(1, sizeof(gdiGfxSurface)); if (!surface) return ERROR_INTERNAL_ERROR; surface->codecs = codecs_new(gdi->context); if (!surface->codecs) { free(surface); return CHANNEL_RC_NO_MEMORY; } if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_ALL, createSurface->width, createSurface->height)) { free(surface); return ERROR_INTERNAL_ERROR; } surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; switch (createSurface->pixelFormat) { case GFX_PIXEL_FORMAT_ARGB_8888: surface->format = PIXEL_FORMAT_BGRA32; break; case GFX_PIXEL_FORMAT_XRGB_8888: surface->format = PIXEL_FORMAT_BGRX32; break; default: free(surface); return ERROR_INTERNAL_ERROR; } surface->scanline = gfx_align_scanline(surface->width * 4, 16); surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); if (!surface->data) { free(surface); return ERROR_INTERNAL_ERROR; } surface->outputMapped = FALSE; region16_init(&surface->invalidRegion); context->SetSurfaceData(context, surface->surfaceId, (void*) surface); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceToCache(RdpgfxClientContext* context, const RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache) { const RECTANGLE_16* rect; gdiGfxSurface* surface; gdiGfxCacheEntry* cacheEntry; rect = &(surfaceToCache->rectSrc); surface = (gdiGfxSurface*) context->GetSurfaceData(context, surfaceToCache->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; cacheEntry = (gdiGfxCacheEntry*) calloc(1, sizeof(gdiGfxCacheEntry)); if (!cacheEntry) return ERROR_NOT_ENOUGH_MEMORY; cacheEntry->width = (UINT32)(rect->right - rect->left); cacheEntry->height = (UINT32)(rect->bottom - rect->top); cacheEntry->format = surface->format; cacheEntry->scanline = gfx_align_scanline(cacheEntry->width * 4, 16); cacheEntry->data = (BYTE*) calloc(cacheEntry->height, cacheEntry->scanline); if (!cacheEntry->data) { free(cacheEntry); return ERROR_NOT_ENOUGH_MEMORY; } if (!freerdp_image_copy(cacheEntry->data, cacheEntry->format, cacheEntry->scanline, 0, 0, cacheEntry->width, cacheEntry->height, surface->data, surface->format, surface->scanline, rect->left, rect->top, NULL, FREERDP_FLIP_NONE)) { free(cacheEntry); return ERROR_INTERNAL_ERROR; } return context->SetCacheSlotData(context, surfaceToCache->cacheSlot, (void*) cacheEntry); }