2011-08-24 19:20:41 +04:00
|
|
|
/**
|
2012-10-09 07:02:04 +04:00
|
|
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
2011-08-24 19:20:41 +04:00
|
|
|
* Glyph Cache
|
|
|
|
*
|
|
|
|
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2012-08-15 01:09:01 +04:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2012-09-24 02:41:07 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2012-11-20 08:49:08 +04:00
|
|
|
#include <winpr/crt.h>
|
|
|
|
|
2013-03-22 00:45:25 +04:00
|
|
|
#include <winpr/stream.h>
|
2011-08-24 19:20:41 +04:00
|
|
|
|
2014-09-12 16:36:29 +04:00
|
|
|
#include <freerdp/log.h>
|
2011-08-24 19:20:41 +04:00
|
|
|
#include <freerdp/cache/pointer.h>
|
2014-09-12 16:36:29 +04:00
|
|
|
|
|
|
|
|
|
|
|
#define TAG FREERDP_TAG("cache.pointer")
|
2011-08-24 19:20:41 +04:00
|
|
|
|
2015-04-14 11:14:23 +03:00
|
|
|
BOOL update_pointer_position(rdpContext* context, POINTER_POSITION_UPDATE* pointer_position)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
2015-04-14 11:14:23 +03:00
|
|
|
return Pointer_SetPosition(context, pointer_position->xPos, pointer_position->yPos);
|
2011-10-12 02:51:45 +04:00
|
|
|
}
|
|
|
|
|
2015-04-14 11:14:23 +03:00
|
|
|
BOOL update_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system)
|
2011-10-12 02:51:45 +04:00
|
|
|
{
|
2012-02-24 16:44:23 +04:00
|
|
|
switch (pointer_system->type)
|
|
|
|
{
|
|
|
|
case SYSPTR_NULL:
|
|
|
|
Pointer_SetNull(context);
|
|
|
|
break;
|
2011-10-12 02:51:45 +04:00
|
|
|
|
2012-02-24 16:44:23 +04:00
|
|
|
case SYSPTR_DEFAULT:
|
|
|
|
Pointer_SetDefault(context);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2014-09-12 16:36:29 +04:00
|
|
|
WLog_ERR(TAG, "Unknown system pointer type (0x%08X)", pointer_system->type);
|
2012-02-24 16:44:23 +04:00
|
|
|
}
|
2015-04-14 11:14:23 +03:00
|
|
|
return TRUE;
|
2011-10-12 02:51:45 +04:00
|
|
|
}
|
|
|
|
|
2015-04-14 11:14:23 +03:00
|
|
|
BOOL update_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_color)
|
2011-10-12 02:51:45 +04:00
|
|
|
{
|
2012-03-29 02:34:56 +04:00
|
|
|
rdpPointer* pointer;
|
|
|
|
rdpCache* cache = context->cache;
|
|
|
|
|
|
|
|
pointer = Pointer_Alloc(context);
|
|
|
|
|
|
|
|
if (pointer != NULL)
|
|
|
|
{
|
|
|
|
pointer->xorBpp = 24;
|
|
|
|
pointer->xPos = pointer_color->xPos;
|
|
|
|
pointer->yPos = pointer_color->yPos;
|
|
|
|
pointer->width = pointer_color->width;
|
|
|
|
pointer->height = pointer_color->height;
|
|
|
|
pointer->lengthAndMask = pointer_color->lengthAndMask;
|
|
|
|
pointer->lengthXorMask = pointer_color->lengthXorMask;
|
2011-10-12 02:51:45 +04:00
|
|
|
|
2013-06-28 17:17:37 +04:00
|
|
|
if (pointer->lengthAndMask && pointer_color->xorMaskData)
|
|
|
|
{
|
|
|
|
pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask);
|
2015-04-14 11:14:23 +03:00
|
|
|
if (!pointer->andMaskData)
|
|
|
|
goto out_fail;
|
|
|
|
|
2013-06-28 17:17:37 +04:00
|
|
|
CopyMemory(pointer->andMaskData, pointer_color->andMaskData, pointer->lengthAndMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pointer->lengthXorMask && pointer_color->xorMaskData)
|
|
|
|
{
|
|
|
|
pointer->xorMaskData = (BYTE*) malloc(pointer->lengthXorMask);
|
2015-04-14 11:14:23 +03:00
|
|
|
if (!pointer->xorMaskData)
|
|
|
|
goto out_fail;
|
2013-06-28 17:17:37 +04:00
|
|
|
CopyMemory(pointer->xorMaskData, pointer_color->xorMaskData, pointer->lengthXorMask);
|
|
|
|
}
|
2012-03-29 02:34:56 +04:00
|
|
|
pointer->New(context, pointer);
|
|
|
|
pointer_cache_put(cache->pointer, pointer_color->cacheIndex, pointer);
|
|
|
|
Pointer_Set(context, pointer);
|
2015-04-14 11:14:23 +03:00
|
|
|
return TRUE;
|
2012-03-29 02:34:56 +04:00
|
|
|
}
|
2015-04-14 11:14:23 +03:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
out_fail:
|
|
|
|
free(pointer->andMaskData);
|
|
|
|
free(pointer->xorMaskData);
|
|
|
|
free(pointer);
|
|
|
|
return FALSE;
|
2011-10-12 02:51:45 +04:00
|
|
|
}
|
|
|
|
|
2015-04-14 11:14:23 +03:00
|
|
|
BOOL update_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new)
|
2011-10-12 02:51:45 +04:00
|
|
|
{
|
|
|
|
rdpPointer* pointer;
|
2011-11-22 02:48:03 +04:00
|
|
|
rdpCache* cache = context->cache;
|
2011-10-12 02:51:45 +04:00
|
|
|
|
2011-11-22 02:48:03 +04:00
|
|
|
pointer = Pointer_Alloc(context);
|
2011-10-12 02:51:45 +04:00
|
|
|
|
|
|
|
if (pointer != NULL)
|
|
|
|
{
|
|
|
|
pointer->xorBpp = pointer_new->xorBpp;
|
|
|
|
pointer->xPos = pointer_new->colorPtrAttr.xPos;
|
|
|
|
pointer->yPos = pointer_new->colorPtrAttr.yPos;
|
|
|
|
pointer->width = pointer_new->colorPtrAttr.width;
|
|
|
|
pointer->height = pointer_new->colorPtrAttr.height;
|
|
|
|
pointer->lengthAndMask = pointer_new->colorPtrAttr.lengthAndMask;
|
|
|
|
pointer->lengthXorMask = pointer_new->colorPtrAttr.lengthXorMask;
|
2013-01-29 03:42:32 +04:00
|
|
|
|
|
|
|
pointer->andMaskData = pointer->xorMaskData = NULL;
|
|
|
|
|
|
|
|
if (pointer->lengthAndMask)
|
|
|
|
{
|
|
|
|
pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask);
|
2015-04-14 11:14:23 +03:00
|
|
|
if (!pointer->andMaskData)
|
|
|
|
goto out_fail;
|
2013-01-29 03:42:32 +04:00
|
|
|
CopyMemory(pointer->andMaskData, pointer_new->colorPtrAttr.andMaskData, pointer->lengthAndMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pointer->lengthXorMask)
|
|
|
|
{
|
|
|
|
pointer->xorMaskData = (BYTE*) malloc(pointer->lengthXorMask);
|
|
|
|
CopyMemory(pointer->xorMaskData, pointer_new->colorPtrAttr.xorMaskData, pointer->lengthXorMask);
|
|
|
|
}
|
2011-10-12 02:51:45 +04:00
|
|
|
|
2011-11-22 02:48:03 +04:00
|
|
|
pointer->New(context, pointer);
|
2011-10-12 02:51:45 +04:00
|
|
|
pointer_cache_put(cache->pointer, pointer_new->colorPtrAttr.cacheIndex, pointer);
|
2011-11-22 02:48:03 +04:00
|
|
|
Pointer_Set(context, pointer);
|
2015-04-14 11:14:23 +03:00
|
|
|
return TRUE;
|
2011-10-12 02:51:45 +04:00
|
|
|
}
|
2015-04-14 11:14:23 +03:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
out_fail:
|
|
|
|
free(pointer->andMaskData);
|
|
|
|
free(pointer->xorMaskData);
|
|
|
|
free(pointer);
|
|
|
|
return FALSE;
|
2011-10-12 02:51:45 +04:00
|
|
|
}
|
|
|
|
|
2015-04-14 11:14:23 +03:00
|
|
|
BOOL update_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached)
|
2011-10-12 02:51:45 +04:00
|
|
|
{
|
|
|
|
rdpPointer* pointer;
|
2011-11-22 02:48:03 +04:00
|
|
|
rdpCache* cache = context->cache;
|
2011-10-12 02:51:45 +04:00
|
|
|
|
|
|
|
pointer = pointer_cache_get(cache->pointer, pointer_cached->cacheIndex);
|
2011-12-16 20:14:55 +04:00
|
|
|
|
|
|
|
if (pointer != NULL)
|
2015-04-14 11:14:23 +03:00
|
|
|
{
|
2011-12-16 20:14:55 +04:00
|
|
|
Pointer_Set(context, pointer);
|
2015-04-14 11:14:23 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
2011-10-12 02:51:45 +04:00
|
|
|
}
|
|
|
|
|
2012-10-09 11:26:39 +04:00
|
|
|
rdpPointer* pointer_cache_get(rdpPointerCache* pointer_cache, UINT32 index)
|
2011-10-12 02:51:45 +04:00
|
|
|
{
|
|
|
|
rdpPointer* pointer;
|
|
|
|
|
|
|
|
if (index >= pointer_cache->cacheSize)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
2014-09-12 16:36:29 +04:00
|
|
|
WLog_ERR(TAG, "invalid pointer index:%d", index);
|
2011-08-24 19:20:41 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
pointer = pointer_cache->entries[index];
|
2011-08-24 19:20:41 +04:00
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
return pointer;
|
2011-08-24 19:20:41 +04:00
|
|
|
}
|
|
|
|
|
2012-10-09 11:26:39 +04:00
|
|
|
void pointer_cache_put(rdpPointerCache* pointer_cache, UINT32 index, rdpPointer* pointer)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
2012-02-02 06:11:46 +04:00
|
|
|
rdpPointer* prevPointer;
|
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
if (index >= pointer_cache->cacheSize)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
2014-09-12 16:36:29 +04:00
|
|
|
WLog_ERR(TAG, "invalid pointer index:%d", index);
|
2011-08-24 19:20:41 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-02-02 06:11:46 +04:00
|
|
|
prevPointer = pointer_cache->entries[index];
|
|
|
|
|
|
|
|
if (prevPointer != NULL)
|
|
|
|
Pointer_Free(pointer_cache->update->context, prevPointer);
|
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
pointer_cache->entries[index] = pointer;
|
2011-08-24 19:20:41 +04:00
|
|
|
}
|
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
void pointer_cache_register_callbacks(rdpUpdate* update)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
2011-11-22 02:48:03 +04:00
|
|
|
rdpPointerUpdate* pointer = update->pointer;
|
|
|
|
|
|
|
|
pointer->PointerPosition = update_pointer_position;
|
|
|
|
pointer->PointerSystem = update_pointer_system;
|
|
|
|
pointer->PointerColor = update_pointer_color;
|
|
|
|
pointer->PointerNew = update_pointer_new;
|
|
|
|
pointer->PointerCached = update_pointer_cached;
|
2011-10-12 02:51:45 +04:00
|
|
|
}
|
2011-08-24 19:20:41 +04:00
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
rdpPointerCache* pointer_cache_new(rdpSettings* settings)
|
|
|
|
{
|
|
|
|
rdpPointerCache* pointer_cache;
|
2011-08-24 19:20:41 +04:00
|
|
|
|
2012-11-20 08:49:08 +04:00
|
|
|
pointer_cache = (rdpPointerCache*) malloc(sizeof(rdpPointerCache));
|
2011-10-12 02:51:45 +04:00
|
|
|
|
|
|
|
if (pointer_cache != NULL)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
2012-11-20 08:49:08 +04:00
|
|
|
ZeroMemory(pointer_cache, sizeof(rdpPointerCache));
|
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
pointer_cache->settings = settings;
|
2012-11-08 00:13:14 +04:00
|
|
|
pointer_cache->cacheSize = settings->PointerCacheSize;
|
2011-10-12 02:51:45 +04:00
|
|
|
pointer_cache->update = ((freerdp*) settings->instance)->update;
|
2012-11-20 08:49:08 +04:00
|
|
|
|
|
|
|
pointer_cache->entries = (rdpPointer**) malloc(sizeof(rdpPointer*) * pointer_cache->cacheSize);
|
|
|
|
ZeroMemory(pointer_cache->entries, sizeof(rdpPointer*) * pointer_cache->cacheSize);
|
2011-08-24 19:20:41 +04:00
|
|
|
}
|
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
return pointer_cache;
|
2011-08-24 19:20:41 +04:00
|
|
|
}
|
|
|
|
|
2011-10-12 02:51:45 +04:00
|
|
|
void pointer_cache_free(rdpPointerCache* pointer_cache)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
2011-10-12 02:51:45 +04:00
|
|
|
if (pointer_cache != NULL)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
|
|
|
int i;
|
2011-10-12 02:51:45 +04:00
|
|
|
rdpPointer* pointer;
|
2011-08-24 19:20:41 +04:00
|
|
|
|
2011-12-04 02:24:18 +04:00
|
|
|
for (i = 0; i < (int) pointer_cache->cacheSize; i++)
|
2011-08-24 19:20:41 +04:00
|
|
|
{
|
2011-10-12 02:51:45 +04:00
|
|
|
pointer = pointer_cache->entries[i];
|
|
|
|
|
|
|
|
if (pointer != NULL)
|
2013-06-28 17:17:37 +04:00
|
|
|
{
|
2012-02-02 03:42:20 +04:00
|
|
|
Pointer_Free(pointer_cache->update->context, pointer);
|
2013-06-28 17:17:37 +04:00
|
|
|
pointer_cache->entries[i] = NULL;
|
|
|
|
}
|
2011-08-24 19:20:41 +04:00
|
|
|
}
|
|
|
|
|
2012-10-09 07:21:26 +04:00
|
|
|
free(pointer_cache->entries);
|
|
|
|
free(pointer_cache);
|
2011-08-24 19:20:41 +04:00
|
|
|
}
|
|
|
|
}
|