Blame libfreerdp/cache/pointer.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 * Glyph Cache
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <stdio.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/stream.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/log.h>
Packit 1fb8d4
#include <freerdp/cache/pointer.h>
Packit 1fb8d4
Packit 1fb8d4
#include "pointer.h"
Packit 1fb8d4
Packit 1fb8d4
#define TAG FREERDP_TAG("cache.pointer")
Packit 1fb8d4
Packit Service 5a9772
static BOOL pointer_cache_put(rdpPointerCache* pointer_cache, UINT32 index, rdpPointer* pointer);
Packit Service 5a9772
static const rdpPointer* pointer_cache_get(rdpPointerCache* pointer_cache, UINT32 index);
Packit 1fb8d4
Packit 1fb8d4
static void pointer_free(rdpContext* context, rdpPointer* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	if (pointer)
Packit 1fb8d4
	{
Packit 1fb8d4
		IFCALL(pointer->Free, context, pointer);
Packit 1fb8d4
Packit 1fb8d4
		if (pointer->xorMaskData)
Packit 1fb8d4
		{
Packit 1fb8d4
			free(pointer->xorMaskData);
Packit 1fb8d4
			pointer->xorMaskData = NULL;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		if (pointer->andMaskData)
Packit 1fb8d4
		{
Packit 1fb8d4
			free(pointer->andMaskData);
Packit 1fb8d4
			pointer->andMaskData = NULL;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		free(pointer);
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL update_pointer_position(rdpContext* context,
Packit 1fb8d4
                                    const POINTER_POSITION_UPDATE* pointer_position)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpPointer* pointer;
Packit 1fb8d4
Packit Service 5a9772
	if (!context || !context->graphics || !context->graphics->Pointer_Prototype ||
Packit Service 5a9772
	    !pointer_position)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	pointer = context->graphics->Pointer_Prototype;
Packit 1fb8d4
	return IFCALLRESULT(TRUE, pointer->SetPosition, context, pointer_position->xPos,
Packit Service 5a9772
	                    pointer_position->yPos);
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL update_pointer_system(rdpContext* context, const POINTER_SYSTEM_UPDATE* pointer_system)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpPointer* pointer;
Packit 1fb8d4
Packit Service 5a9772
	if (!context || !context->graphics || !context->graphics->Pointer_Prototype || !pointer_system)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	pointer = context->graphics->Pointer_Prototype;
Packit 1fb8d4
Packit 1fb8d4
	switch (pointer_system->type)
Packit 1fb8d4
	{
Packit 1fb8d4
		case SYSPTR_NULL:
Packit 1fb8d4
			return IFCALLRESULT(TRUE, pointer->SetNull, context);
Packit 1fb8d4
Packit 1fb8d4
		case SYSPTR_DEFAULT:
Packit 1fb8d4
			return IFCALLRESULT(TRUE, pointer->SetDefault, context);
Packit 1fb8d4
Packit 1fb8d4
		default:
Packit Service 5a9772
			WLog_ERR(TAG, "Unknown system pointer type (0x%08" PRIX32 ")", pointer_system->type);
Packit 1fb8d4
	}
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL upate_pointer_copy_andxor(rdpPointer* pointer, const BYTE* andMaskData,
Packit Service 5a9772
                                      size_t lengthAndMask, const BYTE* xorMaskData,
Packit Service 5a9772
                                      size_t lengthXorMask)
Packit Service 5a9772
{
Packit Service 5a9772
	pointer->lengthAndMask = 0;
Packit Service 5a9772
	pointer->lengthXorMask = 0;
Packit Service 5a9772
Packit Service 5a9772
	if (lengthAndMask && andMaskData)
Packit Service 5a9772
	{
Packit Service 5a9772
		pointer->lengthAndMask = lengthAndMask;
Packit Service 5a9772
		pointer->andMaskData = (BYTE*)malloc(lengthAndMask);
Packit Service 5a9772
Packit Service 5a9772
		if (!pointer->andMaskData)
Packit Service 5a9772
			return FALSE;
Packit Service 5a9772
Packit Service 5a9772
		CopyMemory(pointer->andMaskData, andMaskData, lengthAndMask);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (lengthXorMask && xorMaskData)
Packit Service 5a9772
	{
Packit Service 5a9772
		pointer->lengthXorMask = lengthXorMask;
Packit Service 5a9772
		pointer->xorMaskData = (BYTE*)malloc(lengthXorMask);
Packit Service 5a9772
Packit Service 5a9772
		if (!pointer->xorMaskData)
Packit Service 5a9772
			return FALSE;
Packit Service 5a9772
Packit Service 5a9772
		CopyMemory(pointer->xorMaskData, xorMaskData, lengthXorMask);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return TRUE;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static BOOL update_pointer_color(rdpContext* context, const POINTER_COLOR_UPDATE* pointer_color)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpPointer* pointer;
Packit 1fb8d4
	rdpCache* cache = context->cache;
Packit 1fb8d4
	pointer = Pointer_Alloc(context);
Packit 1fb8d4
Packit 1fb8d4
	if (pointer != NULL)
Packit 1fb8d4
	{
Packit 1fb8d4
		pointer->xorBpp = 24;
Packit 1fb8d4
		pointer->xPos = pointer_color->xPos;
Packit 1fb8d4
		pointer->yPos = pointer_color->yPos;
Packit 1fb8d4
		pointer->width = pointer_color->width;
Packit 1fb8d4
		pointer->height = pointer_color->height;
Packit 1fb8d4
Packit Service 5a9772
		if (!upate_pointer_copy_andxor(pointer, pointer_color->andMaskData,
Packit Service 5a9772
		                               pointer_color->lengthAndMask, pointer_color->xorMaskData,
Packit Service 5a9772
		                               pointer_color->lengthXorMask))
Packit Service 5a9772
			goto out_fail;
Packit 1fb8d4
Packit Service 5a9772
		if (!IFCALLRESULT(TRUE, pointer->New, context, pointer))
Packit Service 5a9772
			goto out_fail;
Packit 1fb8d4
Packit Service 5a9772
		if (!pointer_cache_put(cache->pointer, pointer_color->cacheIndex, pointer))
Packit Service 5a9772
			goto out_fail;
Packit 1fb8d4
Packit Service 5a9772
		return IFCALLRESULT(TRUE, pointer->Set, context, pointer);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return FALSE;
Packit Service 5a9772
out_fail:
Packit Service 5a9772
	pointer_free(context, pointer);
Packit Service 5a9772
	return FALSE;
Packit Service 5a9772
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL update_pointer_large(rdpContext* context, const POINTER_LARGE_UPDATE* pointer_large)
Packit Service 5a9772
{
Packit Service 5a9772
	rdpPointer* pointer = Pointer_Alloc(context);
Packit Service 5a9772
	rdpCache* cache = context->cache;
Packit 1fb8d4
Packit Service 5a9772
	if (pointer != NULL)
Packit Service 5a9772
	{
Packit Service 5a9772
		pointer->xorBpp = pointer_large->xorBpp;
Packit Service 5a9772
		pointer->xPos = pointer_large->hotSpotX;
Packit Service 5a9772
		pointer->yPos = pointer_large->hotSpotY;
Packit Service 5a9772
		pointer->width = pointer_large->width;
Packit Service 5a9772
		pointer->height = pointer_large->height;
Packit Service 5a9772
Packit Service 5a9772
		if (!upate_pointer_copy_andxor(pointer, pointer_large->andMaskData,
Packit Service 5a9772
		                               pointer_large->lengthAndMask, pointer_large->xorMaskData,
Packit Service 5a9772
		                               pointer_large->lengthXorMask))
Packit Service 5a9772
			goto out_fail;
Packit 1fb8d4
Packit 1fb8d4
		if (!IFCALLRESULT(TRUE, pointer->New, context, pointer))
Packit 1fb8d4
			goto out_fail;
Packit 1fb8d4
Packit Service 5a9772
		if (!pointer_cache_put(cache->pointer, pointer_large->cacheIndex, pointer))
Packit 1fb8d4
			goto out_fail;
Packit 1fb8d4
Packit 1fb8d4
		return IFCALLRESULT(TRUE, pointer->Set, context, pointer);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
out_fail:
Packit 1fb8d4
	pointer_free(context, pointer);
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL update_pointer_new(rdpContext* context, const POINTER_NEW_UPDATE* pointer_new)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpPointer* pointer;
Packit 1fb8d4
	rdpCache* cache;
Packit 1fb8d4
Packit 1fb8d4
	if (!context || !pointer_new)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	cache = context->cache;
Packit 1fb8d4
	pointer = Pointer_Alloc(context);
Packit 1fb8d4
Packit 1fb8d4
	if (!pointer)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	pointer->xorBpp = pointer_new->xorBpp;
Packit 1fb8d4
	pointer->xPos = pointer_new->colorPtrAttr.xPos;
Packit 1fb8d4
	pointer->yPos = pointer_new->colorPtrAttr.yPos;
Packit 1fb8d4
	pointer->width = pointer_new->colorPtrAttr.width;
Packit 1fb8d4
	pointer->height = pointer_new->colorPtrAttr.height;
Packit Service 5a9772
	if (!upate_pointer_copy_andxor(
Packit Service 5a9772
	        pointer, pointer_new->colorPtrAttr.andMaskData, pointer_new->colorPtrAttr.lengthAndMask,
Packit Service 5a9772
	        pointer_new->colorPtrAttr.xorMaskData, pointer_new->colorPtrAttr.lengthXorMask))
Packit Service 5a9772
		goto out_fail;
Packit 1fb8d4
Packit 1fb8d4
	if (!IFCALLRESULT(TRUE, pointer->New, context, pointer))
Packit 1fb8d4
		goto out_fail;
Packit 1fb8d4
Packit Service 5a9772
	if (!pointer_cache_put(cache->pointer, pointer_new->colorPtrAttr.cacheIndex, pointer))
Packit 1fb8d4
		goto out_fail;
Packit 1fb8d4
Packit 1fb8d4
	return IFCALLRESULT(TRUE, pointer->Set, context, pointer);
Packit 1fb8d4
out_fail:
Packit 1fb8d4
	pointer_free(context, pointer);
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL update_pointer_cached(rdpContext* context, const POINTER_CACHED_UPDATE* pointer_cached)
Packit 1fb8d4
{
Packit 1fb8d4
	const rdpPointer* pointer;
Packit 1fb8d4
	rdpCache* cache = context->cache;
Packit 1fb8d4
	pointer = pointer_cache_get(cache->pointer, pointer_cached->cacheIndex);
Packit 1fb8d4
Packit 1fb8d4
	if (pointer != NULL)
Packit 1fb8d4
		return IFCALLRESULT(TRUE, pointer->Set, context, pointer);
Packit 1fb8d4
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
const rdpPointer* pointer_cache_get(rdpPointerCache* pointer_cache, UINT32 index)
Packit 1fb8d4
{
Packit 1fb8d4
	const rdpPointer* pointer;
Packit 1fb8d4
Packit 1fb8d4
	if (index >= pointer_cache->cacheSize)
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "invalid pointer index:%" PRIu32 "", index);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	pointer = pointer_cache->entries[index];
Packit 1fb8d4
	return pointer;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
BOOL pointer_cache_put(rdpPointerCache* pointer_cache, UINT32 index, rdpPointer* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpPointer* prevPointer;
Packit 1fb8d4
Packit 1fb8d4
	if (index >= pointer_cache->cacheSize)
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "invalid pointer index:%" PRIu32 "", index);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	prevPointer = pointer_cache->entries[index];
Packit 1fb8d4
	pointer_free(pointer_cache->update->context, prevPointer);
Packit 1fb8d4
	pointer_cache->entries[index] = pointer;
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void pointer_cache_register_callbacks(rdpUpdate* update)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpPointerUpdate* pointer = update->pointer;
Packit 1fb8d4
	pointer->PointerPosition = update_pointer_position;
Packit 1fb8d4
	pointer->PointerSystem = update_pointer_system;
Packit 1fb8d4
	pointer->PointerColor = update_pointer_color;
Packit Service 5a9772
	pointer->PointerLarge = update_pointer_large;
Packit 1fb8d4
	pointer->PointerNew = update_pointer_new;
Packit 1fb8d4
	pointer->PointerCached = update_pointer_cached;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
rdpPointerCache* pointer_cache_new(rdpSettings* settings)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpPointerCache* pointer_cache;
Packit Service 5a9772
	pointer_cache = (rdpPointerCache*)calloc(1, sizeof(rdpPointerCache));
Packit 1fb8d4
Packit 1fb8d4
	if (!pointer_cache)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	pointer_cache->settings = settings;
Packit 1fb8d4
	pointer_cache->cacheSize = settings->PointerCacheSize;
Packit Service 5a9772
	pointer_cache->update = ((freerdp*)settings->instance)->update;
Packit Service 5a9772
	pointer_cache->entries = (rdpPointer**)calloc(pointer_cache->cacheSize, sizeof(rdpPointer*));
Packit 1fb8d4
Packit 1fb8d4
	if (!pointer_cache->entries)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(pointer_cache);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return pointer_cache;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void pointer_cache_free(rdpPointerCache* pointer_cache)
Packit 1fb8d4
{
Packit 1fb8d4
	if (pointer_cache != NULL)
Packit 1fb8d4
	{
Packit 1fb8d4
		UINT32 i;
Packit 1fb8d4
		rdpPointer* pointer;
Packit 1fb8d4
Packit 1fb8d4
		for (i = 0; i < pointer_cache->cacheSize; i++)
Packit 1fb8d4
		{
Packit 1fb8d4
			pointer = pointer_cache->entries[i];
Packit 1fb8d4
			pointer_free(pointer_cache->update->context, pointer);
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		free(pointer_cache->entries);
Packit 1fb8d4
		free(pointer_cache);
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
POINTER_COLOR_UPDATE* copy_pointer_color_update(rdpContext* context,
Packit Service 5a9772
                                                const POINTER_COLOR_UPDATE* src)
Packit 1fb8d4
{
Packit 1fb8d4
	POINTER_COLOR_UPDATE* dst = calloc(1, sizeof(POINTER_COLOR_UPDATE));
Packit 1fb8d4
Packit 1fb8d4
	if (!dst || !src)
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	*dst = *src;
Packit 1fb8d4
Packit 1fb8d4
	if (src->lengthAndMask > 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		dst->andMaskData = calloc(src->lengthAndMask, sizeof(BYTE));
Packit 1fb8d4
Packit 1fb8d4
		if (!dst->andMaskData)
Packit 1fb8d4
			goto fail;
Packit 1fb8d4
Packit 1fb8d4
		memcpy(dst->andMaskData, src->andMaskData, src->lengthAndMask);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (src->lengthXorMask > 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		dst->xorMaskData = calloc(src->lengthXorMask, sizeof(BYTE));
Packit 1fb8d4
Packit 1fb8d4
		if (!dst->xorMaskData)
Packit 1fb8d4
			goto fail;
Packit 1fb8d4
Packit 1fb8d4
		memcpy(dst->xorMaskData, src->xorMaskData, src->lengthXorMask);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return dst;
Packit 1fb8d4
fail:
Packit 1fb8d4
	free_pointer_color_update(context, dst);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void free_pointer_color_update(rdpContext* context, POINTER_COLOR_UPDATE* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!pointer)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	free(pointer->xorMaskData);
Packit 1fb8d4
	free(pointer->andMaskData);
Packit 1fb8d4
	free(pointer);
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
POINTER_LARGE_UPDATE* copy_pointer_large_update(rdpContext* context,
Packit Service 5a9772
                                                const POINTER_LARGE_UPDATE* src)
Packit Service 5a9772
{
Packit Service 5a9772
	POINTER_LARGE_UPDATE* dst = calloc(1, sizeof(POINTER_LARGE_UPDATE));
Packit Service 5a9772
Packit Service 5a9772
	if (!dst || !src)
Packit Service 5a9772
		goto fail;
Packit Service 5a9772
Packit Service 5a9772
	*dst = *src;
Packit Service 5a9772
Packit Service 5a9772
	if (src->lengthAndMask > 0)
Packit Service 5a9772
	{
Packit Service 5a9772
		dst->andMaskData = calloc(src->lengthAndMask, sizeof(BYTE));
Packit Service 5a9772
Packit Service 5a9772
		if (!dst->andMaskData)
Packit Service 5a9772
			goto fail;
Packit Service 5a9772
Packit Service 5a9772
		memcpy(dst->andMaskData, src->andMaskData, src->lengthAndMask);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (src->lengthXorMask > 0)
Packit Service 5a9772
	{
Packit Service 5a9772
		dst->xorMaskData = calloc(src->lengthXorMask, sizeof(BYTE));
Packit Service 5a9772
Packit Service 5a9772
		if (!dst->xorMaskData)
Packit Service 5a9772
			goto fail;
Packit Service 5a9772
Packit Service 5a9772
		memcpy(dst->xorMaskData, src->xorMaskData, src->lengthXorMask);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return dst;
Packit Service 5a9772
fail:
Packit Service 5a9772
	free_pointer_large_update(context, dst);
Packit Service 5a9772
	return NULL;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
void free_pointer_large_update(rdpContext* context, POINTER_LARGE_UPDATE* pointer)
Packit Service 5a9772
{
Packit Service 5a9772
	WINPR_UNUSED(context);
Packit Service 5a9772
	if (!pointer)
Packit Service 5a9772
		return;
Packit Service 5a9772
Packit Service 5a9772
	free(pointer->xorMaskData);
Packit Service 5a9772
	free(pointer->andMaskData);
Packit Service 5a9772
	free(pointer);
Packit Service 5a9772
}
Packit Service 5a9772
Packit 1fb8d4
POINTER_NEW_UPDATE* copy_pointer_new_update(rdpContext* context, const POINTER_NEW_UPDATE* src)
Packit 1fb8d4
{
Packit 1fb8d4
	POINTER_NEW_UPDATE* dst = calloc(1, sizeof(POINTER_NEW_UPDATE));
Packit 1fb8d4
Packit 1fb8d4
	if (!dst || !src)
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	*dst = *src;
Packit 1fb8d4
Packit 1fb8d4
	if (src->colorPtrAttr.lengthAndMask > 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		dst->colorPtrAttr.andMaskData = calloc(src->colorPtrAttr.lengthAndMask, sizeof(BYTE));
Packit 1fb8d4
Packit 1fb8d4
		if (!dst->colorPtrAttr.andMaskData)
Packit 1fb8d4
			goto fail;
Packit 1fb8d4
Packit 1fb8d4
		memcpy(dst->colorPtrAttr.andMaskData, src->colorPtrAttr.andMaskData,
Packit 1fb8d4
		       src->colorPtrAttr.lengthAndMask);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (src->colorPtrAttr.lengthXorMask > 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		dst->colorPtrAttr.xorMaskData = calloc(src->colorPtrAttr.lengthXorMask, sizeof(BYTE));
Packit 1fb8d4
Packit 1fb8d4
		if (!dst->colorPtrAttr.xorMaskData)
Packit 1fb8d4
			goto fail;
Packit 1fb8d4
Packit 1fb8d4
		memcpy(dst->colorPtrAttr.xorMaskData, src->colorPtrAttr.xorMaskData,
Packit 1fb8d4
		       src->colorPtrAttr.lengthXorMask);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return dst;
Packit 1fb8d4
fail:
Packit 1fb8d4
	free_pointer_new_update(context, dst);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void free_pointer_new_update(rdpContext* context, POINTER_NEW_UPDATE* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!pointer)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	free(pointer->colorPtrAttr.xorMaskData);
Packit 1fb8d4
	free(pointer->colorPtrAttr.andMaskData);
Packit 1fb8d4
	free(pointer);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
POINTER_CACHED_UPDATE* copy_pointer_cached_update(rdpContext* context,
Packit Service 5a9772
                                                  const POINTER_CACHED_UPDATE* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	POINTER_CACHED_UPDATE* dst = calloc(1, sizeof(POINTER_CACHED_UPDATE));
Packit 1fb8d4
Packit 1fb8d4
	if (!dst)
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	*dst = *pointer;
Packit 1fb8d4
	return dst;
Packit 1fb8d4
fail:
Packit 1fb8d4
	free_pointer_cached_update(context, dst);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void free_pointer_cached_update(rdpContext* context, POINTER_CACHED_UPDATE* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	free(pointer);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void free_pointer_position_update(rdpContext* context, POINTER_POSITION_UPDATE* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	free(pointer);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
POINTER_POSITION_UPDATE* copy_pointer_position_update(rdpContext* context,
Packit Service 5a9772
                                                      const POINTER_POSITION_UPDATE* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	POINTER_POSITION_UPDATE* dst = calloc(1, sizeof(POINTER_POSITION_UPDATE));
Packit 1fb8d4
Packit 1fb8d4
	if (!dst || !pointer)
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	*dst = *pointer;
Packit 1fb8d4
	return dst;
Packit 1fb8d4
fail:
Packit 1fb8d4
	free_pointer_position_update(context, dst);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void free_pointer_system_update(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	free(pointer);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
POINTER_SYSTEM_UPDATE* copy_pointer_system_update(rdpContext* context,
Packit Service 5a9772
                                                  const POINTER_SYSTEM_UPDATE* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	POINTER_SYSTEM_UPDATE* dst = calloc(1, sizeof(POINTER_SYSTEM_UPDATE));
Packit 1fb8d4
Packit 1fb8d4
	if (!dst || !pointer)
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	*dst = *pointer;
Packit 1fb8d4
	return dst;
Packit 1fb8d4
fail:
Packit 1fb8d4
	free_pointer_system_update(context, dst);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}