channels/gfx: add surface table helper, surface creation/deletion

This commit is contained in:
Marc-André Moreau 2014-06-11 17:48:04 -04:00
parent 2a82684521
commit fbea223ecf
5 changed files with 94 additions and 0 deletions

View File

@ -854,11 +854,41 @@ static int rdpgfx_plugin_terminated(IWTSPlugin* pPlugin)
zgfx_context_free(gfx->zgfx);
HashTable_Free(gfx->SurfaceTable);
free(gfx);
return 0;
}
int rdpgfx_set_surface_data(RdpgfxClientContext* context, UINT16 surfaceId, void* pData)
{
ULONG_PTR key;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle;
key = ((ULONG_PTR) surfaceId) + 1;
if (pData)
HashTable_Add(gfx->SurfaceTable, (void*) key, pData);
else
HashTable_Remove(gfx->SurfaceTable, (void*) key);
return 1;
}
void* rdpgfx_get_surface_data(RdpgfxClientContext* context, UINT16 surfaceId)
{
ULONG_PTR key;
void* pData = NULL;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle;
key = ((ULONG_PTR) surfaceId) + 1;
pData = HashTable_GetItemValue(gfx->SurfaceTable, (void*) key);
return pData;
}
#ifdef STATIC_CHANNELS
#define DVCPluginEntry rdpgfx_DVCPluginEntry
#endif
@ -885,6 +915,11 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
gfx->iface.Disconnected = NULL;
gfx->iface.Terminated = rdpgfx_plugin_terminated;
gfx->SurfaceTable = HashTable_New(TRUE);
if (!gfx->SurfaceTable)
return -1;
context = (RdpgfxClientContext*) calloc(1, sizeof(RdpgfxClientContext));
if (!context)
@ -892,6 +927,9 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
context->handle = (void*) gfx;
context->SetSurfaceData = rdpgfx_set_surface_data;
context->GetSurfaceData = rdpgfx_get_surface_data;
gfx->iface.pInterface = (void*) context;
gfx->zgfx = zgfx_context_new(FALSE);

View File

@ -25,6 +25,7 @@
#include <freerdp/addin.h>
#include <winpr/wlog.h>
#include <winpr/collections.h>
#include <freerdp/client/rdpgfx.h>
@ -66,6 +67,8 @@ struct _RDPGFX_PLUGIN
ZGFX_CONTEXT* zgfx;
UINT32 UnacknowledgedFrames;
UINT32 TotalDecodedFrames;
wHashTable* SurfaceTable;
};
typedef struct _RDPGFX_PLUGIN RDPGFX_PLUGIN;

View File

@ -306,16 +306,52 @@ int xf_DeleteEncodingContext(RdpgfxClientContext* context, RDPGFX_DELETE_ENCODIN
int xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface)
{
xfGfxSurface* surface;
xfContext* xfc = (xfContext*) context->custom;
printf("xf_CreateSurface: surfaceId: %d width: %d height: %d format: 0x%02X\n",
createSurface->surfaceId, createSurface->width, createSurface->height, createSurface->pixelFormat);
surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface));
if (!surface)
return -1;
surface->surfaceId = createSurface->surfaceId;
surface->width = (UINT32) createSurface->width;
surface->height = (UINT32) createSurface->height;
surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE;
surface->data = (BYTE*) calloc(1, surface->width * surface->height * 4);
if (!surface->data)
return -1;
surface->image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
(char*) surface->data, surface->width, surface->height, 32, 0);
context->SetSurfaceData(context, surface->surfaceId, (void*) surface);
return 1;
}
int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface)
{
xfGfxSurface* surface = NULL;
surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId);
printf("xf_DeleteSurface: surfaceId: %d\n", deleteSurface->surfaceId);
if (surface)
{
XFree(surface->image);
free(surface->data);
free(surface);
}
context->SetSurfaceData(context, deleteSurface->surfaceId, NULL);
return 1;
}

View File

@ -23,6 +23,17 @@
#include "xf_client.h"
#include "xfreerdp.h"
struct xf_gfx_surface
{
UINT16 surfaceId;
UINT32 width;
UINT32 height;
BOOL alpha;
BYTE* data;
XImage* image;
};
typedef struct xf_gfx_surface xfGfxSurface;
void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx);
#endif /* __XF_GRAPHICS_PIPELINE_H */

View File

@ -45,6 +45,9 @@ typedef int (*pcRdpgfxEvictCacheEntry)(RdpgfxClientContext* context, RDPGFX_EVIC
typedef int (*pcRdpgfxMapSurfaceToOutput)(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput);
typedef int (*pcRdpgfxMapSurfaceToWindow)(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow);
typedef int (*pcRdpgfxSetSurfaceData)(RdpgfxClientContext* context, UINT16 surfaceId, void* pData);
typedef void* (*pcRdpgfxGetSurfaceData)(RdpgfxClientContext* context, UINT16 surfaceId);
struct _rdpgfx_client_context
{
void* handle;
@ -66,6 +69,9 @@ struct _rdpgfx_client_context
pcRdpgfxEvictCacheEntry EvictCacheEntry;
pcRdpgfxMapSurfaceToOutput MapSurfaceToOutput;
pcRdpgfxMapSurfaceToWindow MapSurfaceToWindow;
pcRdpgfxSetSurfaceData SetSurfaceData;
pcRdpgfxGetSurfaceData GetSurfaceData;
};
#endif /* FREERDP_CHANNEL_CLIENT_RDPGFX_H */