geometry: change the channel API to mutualize things
Try to mutualize things that are platform independant in the geometry client channel. Sponsored by: Rangee GmbH (http://www.rangee.de)
This commit is contained in:
parent
c44605299f
commit
adac409d1b
@ -72,7 +72,29 @@ struct _GEOMETRY_PLUGIN
|
||||
typedef struct _GEOMETRY_PLUGIN GEOMETRY_PLUGIN;
|
||||
|
||||
|
||||
static UINT32 geometry_read_RGNDATA(wStream* s, UINT32 len, FREERDP_RGNDATA* rgndata)
|
||||
static UINT32 mappedGeometryHash(UINT64 *g)
|
||||
{
|
||||
return (UINT32)((*g >> 32) + (*g & 0xffffffff));
|
||||
}
|
||||
|
||||
static BOOL mappedGeometryKeyCompare(UINT64 *g1, UINT64 *g2)
|
||||
{
|
||||
return *g1 == *g2;
|
||||
}
|
||||
|
||||
static void mappedGeometryFree(MAPPED_GEOMETRY *g)
|
||||
{
|
||||
free(g->geometry.rects);
|
||||
free(g);
|
||||
}
|
||||
|
||||
|
||||
void freerdp_rgndata_reset(FREERDP_RGNDATA *data)
|
||||
{
|
||||
data->nRectCount = 0;
|
||||
}
|
||||
|
||||
static UINT32 geometry_read_RGNDATA(wStream *s, UINT32 len, FREERDP_RGNDATA *rgndata)
|
||||
{
|
||||
UINT32 dwSize, iType;
|
||||
INT32 right, bottom;
|
||||
@ -117,12 +139,14 @@ static UINT32 geometry_read_RGNDATA(wStream* s, UINT32 len, FREERDP_RGNDATA* rgn
|
||||
if (rgndata->nRectCount)
|
||||
{
|
||||
int i;
|
||||
RDP_RECT *tmp = realloc(rgndata->rects, rgndata->nRectCount * sizeof(RDP_RECT));
|
||||
|
||||
if (!(rgndata->rects = calloc(rgndata->nRectCount, sizeof(RDP_RECT))))
|
||||
if (!tmp)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate memory for %"PRIu32" RECTs", rgndata->nRectCount);
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
rgndata->rects = tmp;
|
||||
|
||||
for (i = 0; i < rgndata->nRectCount; i++)
|
||||
{
|
||||
@ -146,10 +170,13 @@ static UINT32 geometry_read_RGNDATA(wStream* s, UINT32 len, FREERDP_RGNDATA* rgn
|
||||
static UINT geometry_recv_pdu(GEOMETRY_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
UINT32 length, cbGeometryBuffer;
|
||||
MAPPED_GEOMETRY_PACKET packet;
|
||||
MAPPED_GEOMETRY *mappedGeometry;
|
||||
GEOMETRY_PLUGIN* geometry;
|
||||
GeometryClientContext* context;
|
||||
UINT ret;
|
||||
GeometryClientContext *context;
|
||||
UINT ret = CHANNEL_RC_OK;
|
||||
UINT32 version, updateType, geometryType;
|
||||
UINT64 id;
|
||||
|
||||
geometry = (GEOMETRY_PLUGIN*) callback->plugin;
|
||||
context = (GeometryClientContext*)geometry->iface.pInterface;
|
||||
|
||||
@ -167,44 +194,107 @@ static UINT geometry_recv_pdu(GEOMETRY_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, packet.version);
|
||||
Stream_Read_UINT64(s, packet.mappingId);
|
||||
Stream_Read_UINT32(s, packet.updateType);
|
||||
Stream_Read_UINT32(s, version);
|
||||
Stream_Read_UINT64(s, id);
|
||||
Stream_Read_UINT32(s, updateType);
|
||||
Stream_Seek_UINT32(s); /* flags */
|
||||
Stream_Read_UINT64(s, packet.topLevelId);
|
||||
Stream_Read_INT32(s, packet.left);
|
||||
Stream_Read_INT32(s, packet.top);
|
||||
Stream_Read_INT32(s, packet.right);
|
||||
Stream_Read_INT32(s, packet.bottom);
|
||||
Stream_Read_INT32(s, packet.topLevelLeft);
|
||||
Stream_Read_INT32(s, packet.topLevelTop);
|
||||
Stream_Read_INT32(s, packet.topLevelRight);
|
||||
Stream_Read_INT32(s, packet.topLevelBottom);
|
||||
Stream_Read_UINT32(s, packet.geometryType);
|
||||
Stream_Read_UINT32(s, cbGeometryBuffer);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < cbGeometryBuffer)
|
||||
mappedGeometry = HashTable_GetItemValue(context->geometries, &id);
|
||||
|
||||
if (updateType == GEOMETRY_CLEAR )
|
||||
{
|
||||
WLog_ERR(TAG, "invalid packet length");
|
||||
return ERROR_INVALID_DATA;
|
||||
if (!mappedGeometry)
|
||||
{
|
||||
WLog_ERR(TAG, "geometry 0x%"PRIx64" not found here, ignoring clear command", id);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "clearing geometry 0x%"PRIx64"", id);
|
||||
|
||||
if (mappedGeometry->MappedGeometryClear && !mappedGeometry->MappedGeometryClear(mappedGeometry))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
HashTable_Remove(context->geometries, &id);
|
||||
}
|
||||
|
||||
ZeroMemory(&packet.geometry, sizeof(packet.geometry));
|
||||
|
||||
if (cbGeometryBuffer)
|
||||
else if (updateType == GEOMETRY_UPDATE)
|
||||
{
|
||||
ret = geometry_read_RGNDATA(s, cbGeometryBuffer, &packet.geometry);
|
||||
BOOL newOne = FALSE;
|
||||
|
||||
if (ret != CHANNEL_RC_OK)
|
||||
return ret;
|
||||
if (!mappedGeometry)
|
||||
{
|
||||
newOne = TRUE;
|
||||
WLog_DBG(TAG, "creating geometry 0x%"PRIx64"", id);
|
||||
mappedGeometry = calloc(1, sizeof(MAPPED_GEOMETRY));
|
||||
if (!mappedGeometry)
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
|
||||
mappedGeometry->mappingId = id;
|
||||
|
||||
if (HashTable_Add(context->geometries, &(mappedGeometry->mappingId), mappedGeometry) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to register geometry 0x%"PRIx64" in the table", id);
|
||||
free(mappedGeometry);
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_DBG(TAG, "updating geometry 0x%"PRIx64"", id);
|
||||
}
|
||||
|
||||
Stream_Read_UINT64(s, mappedGeometry->topLevelId);
|
||||
|
||||
Stream_Read_INT32(s, mappedGeometry->left);
|
||||
Stream_Read_INT32(s, mappedGeometry->top);
|
||||
Stream_Read_INT32(s, mappedGeometry->right);
|
||||
Stream_Read_INT32(s, mappedGeometry->bottom);
|
||||
|
||||
Stream_Read_INT32(s, mappedGeometry->topLevelLeft);
|
||||
Stream_Read_INT32(s, mappedGeometry->topLevelTop);
|
||||
Stream_Read_INT32(s, mappedGeometry->topLevelRight);
|
||||
Stream_Read_INT32(s, mappedGeometry->topLevelBottom);
|
||||
|
||||
Stream_Read_UINT32(s, geometryType);
|
||||
|
||||
Stream_Read_UINT32(s, cbGeometryBuffer);
|
||||
if (Stream_GetRemainingLength(s) < cbGeometryBuffer)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid packet length");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
if (cbGeometryBuffer)
|
||||
{
|
||||
ret = geometry_read_RGNDATA(s, cbGeometryBuffer, &mappedGeometry->geometry);
|
||||
if (ret != CHANNEL_RC_OK)
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_rgndata_reset(&mappedGeometry->geometry);
|
||||
}
|
||||
|
||||
if (newOne)
|
||||
{
|
||||
if (context->MappedGeometryAdded && !context->MappedGeometryAdded(context, mappedGeometry))
|
||||
{
|
||||
WLog_ERR(TAG, "geometry added callback failed");
|
||||
ret = ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mappedGeometry->MappedGeometryUpdate && !mappedGeometry->MappedGeometryUpdate(mappedGeometry))
|
||||
{
|
||||
WLog_ERR(TAG, "geometry update callback failed");
|
||||
ret = ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = CHANNEL_RC_OK;
|
||||
|
||||
if (context->MappedGeometryPacket)
|
||||
ret = context->MappedGeometryPacket(context, &packet);
|
||||
|
||||
free(packet.geometry.rects);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -304,7 +394,6 @@ static UINT geometry_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
* Channel Client Interface
|
||||
*/
|
||||
|
||||
|
||||
#ifdef BUILTIN_CHANNELS
|
||||
#define DVCPluginEntry geometry_DVCPluginEntry
|
||||
#else
|
||||
@ -342,10 +431,14 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
if (!context)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
free(geometry);
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
goto error_context;
|
||||
}
|
||||
|
||||
context->geometries = HashTable_New(FALSE);
|
||||
context->geometries->hash = (HASH_TABLE_HASH_FN)mappedGeometryHash;
|
||||
context->geometries->keyCompare = (HASH_TABLE_KEY_COMPARE_FN)mappedGeometryKeyCompare;
|
||||
context->geometries->valueFree = (HASH_TABLE_VALUE_FREE_FN)mappedGeometryFree;
|
||||
|
||||
context->handle = (void*) geometry;
|
||||
geometry->iface.pInterface = (void*) context;
|
||||
geometry->context = context;
|
||||
@ -358,4 +451,9 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
error_context:
|
||||
free(geometry);
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ struct _FREERDP_RGNDATA
|
||||
|
||||
typedef struct _FREERDP_RGNDATA FREERDP_RGNDATA;
|
||||
|
||||
|
||||
struct _MAPPED_GEOMETRY_PACKET
|
||||
{
|
||||
UINT32 version;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef FREERDP_CHANNELS_CLIENT_GEOMETRY_H
|
||||
#define FREERDP_CHANNELS_CLIENT_GEOMETRY_H
|
||||
|
||||
#include <winpr/collections.h>
|
||||
#include <freerdp/channels/geometry.h>
|
||||
|
||||
/**
|
||||
@ -28,14 +29,31 @@
|
||||
typedef struct _geometry_client_context GeometryClientContext;
|
||||
|
||||
|
||||
typedef UINT (*pcMappedGeometryPacket)(GeometryClientContext* context, MAPPED_GEOMETRY_PACKET *packet);
|
||||
typedef struct _MAPPED_GEOMETRY MAPPED_GEOMETRY;
|
||||
typedef BOOL (*pcMappedGeometryAdded)(GeometryClientContext* context, MAPPED_GEOMETRY *geometry);
|
||||
typedef BOOL (*pcMappedGeometryUpdate)(MAPPED_GEOMETRY *geometry);
|
||||
typedef BOOL (*pcMappedGeometryClear)(MAPPED_GEOMETRY *geometry);
|
||||
|
||||
struct _MAPPED_GEOMETRY
|
||||
{
|
||||
UINT64 mappingId;
|
||||
UINT64 topLevelId;
|
||||
INT32 left, top, right, bottom;
|
||||
INT32 topLevelLeft, topLevelTop, topLevelRight, topLevelBottom;
|
||||
FREERDP_RGNDATA geometry;
|
||||
|
||||
void *custom;
|
||||
pcMappedGeometryUpdate MappedGeometryUpdate;
|
||||
pcMappedGeometryClear MappedGeometryClear;
|
||||
};
|
||||
|
||||
struct _geometry_client_context
|
||||
{
|
||||
wHashTable *geometries;
|
||||
void* handle;
|
||||
void* custom;
|
||||
|
||||
pcMappedGeometryPacket MappedGeometryPacket;
|
||||
pcMappedGeometryAdded MappedGeometryAdded;
|
||||
};
|
||||
|
||||
#endif /* FREERDP_CHANNELS_CLIENT_GEOMETRY_H */
|
||||
|
Loading…
Reference in New Issue
Block a user