Blame winpr/libwinpr/clipboard/clipboard.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * Clipboard Functions
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2014 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 <winpr/crt.h>
Packit 1fb8d4
#include <winpr/collections.h>
Packit 1fb8d4
#include <winpr/wlog.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/clipboard.h>
Packit 1fb8d4
Packit 1fb8d4
#include "clipboard.h"
Packit 1fb8d4
Packit 1fb8d4
#ifdef WITH_WCLIPBOARD_POSIX
Packit 1fb8d4
#include "posix.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include "../log.h"
Packit 1fb8d4
#define TAG WINPR_TAG("clipboard")
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Clipboard (Windows):
Packit 1fb8d4
 * msdn.microsoft.com/en-us/library/windows/desktop/ms648709/
Packit 1fb8d4
 *
Packit 1fb8d4
 * W3C Clipboard API and events:
Packit 1fb8d4
 * http://www.w3.org/TR/clipboard-apis/
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
const char* CF_STANDARD_STRINGS[CF_MAX] =
Packit 1fb8d4
{
Packit 1fb8d4
	"CF_RAW",		/* 0 */
Packit 1fb8d4
	"CF_TEXT",		/* 1 */
Packit 1fb8d4
	"CF_BITMAP",		/* 2 */
Packit 1fb8d4
	"CF_METAFILEPICT",	/* 3 */
Packit 1fb8d4
	"CF_SYLK",		/* 4 */
Packit 1fb8d4
	"CF_DIF",		/* 5 */
Packit 1fb8d4
	"CF_TIFF",		/* 6 */
Packit 1fb8d4
	"CF_OEMTEXT",		/* 7 */
Packit 1fb8d4
	"CF_DIB",		/* 8 */
Packit 1fb8d4
	"CF_PALETTE",		/* 9 */
Packit 1fb8d4
	"CF_PENDATA",		/* 10 */
Packit 1fb8d4
	"CF_RIFF",		/* 11 */
Packit 1fb8d4
	"CF_WAVE",		/* 12 */
Packit 1fb8d4
	"CF_UNICODETEXT",	/* 13 */
Packit 1fb8d4
	"CF_ENHMETAFILE",	/* 14 */
Packit 1fb8d4
	"CF_HDROP",		/* 15 */
Packit 1fb8d4
	"CF_LOCALE",		/* 16 */
Packit 1fb8d4
	"CF_DIBV5"		/* 17 */
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
wClipboardFormat* ClipboardFindFormat(wClipboard* clipboard, UINT32 formatId,
Packit 1fb8d4
                                      const char* name)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 index;
Packit 1fb8d4
	wClipboardFormat* format = NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (formatId)
Packit 1fb8d4
	{
Packit 1fb8d4
		for (index = 0; index < clipboard->numFormats; index++)
Packit 1fb8d4
		{
Packit 1fb8d4
			if (formatId == clipboard->formats[index].formatId)
Packit 1fb8d4
			{
Packit 1fb8d4
				format = &clipboard->formats[index];
Packit 1fb8d4
				break;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (name)
Packit 1fb8d4
	{
Packit 1fb8d4
		for (index = 0; index < clipboard->numFormats; index++)
Packit 1fb8d4
		{
Packit 1fb8d4
			if (strcmp(name, clipboard->formats[index].formatName) == 0)
Packit 1fb8d4
			{
Packit 1fb8d4
				format = &clipboard->formats[index];
Packit 1fb8d4
				break;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		/* special "CF_RAW" case */
Packit 1fb8d4
		if (clipboard->numFormats > 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			format = &clipboard->formats[0];
Packit 1fb8d4
Packit 1fb8d4
			if (format->formatId)
Packit 1fb8d4
				return NULL;
Packit 1fb8d4
Packit 1fb8d4
			if (!format->formatName
Packit 1fb8d4
			    || (strcmp(format->formatName, CF_STANDARD_STRINGS[0]) == 0))
Packit 1fb8d4
				return format;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return format;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
wClipboardSynthesizer* ClipboardFindSynthesizer(wClipboardFormat* format,
Packit 1fb8d4
        UINT32 formatId)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 index;
Packit 1fb8d4
	wClipboardSynthesizer* synthesizer;
Packit 1fb8d4
Packit 1fb8d4
	if (!format)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (format->numSynthesizers < 1)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < format->numSynthesizers; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		synthesizer = &(format->synthesizers[index]);
Packit 1fb8d4
Packit 1fb8d4
		if (formatId == synthesizer->syntheticId)
Packit 1fb8d4
			return synthesizer;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ClipboardLock(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	EnterCriticalSection(&(clipboard->lock));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ClipboardUnlock(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	LeaveCriticalSection(&(clipboard->lock));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL ClipboardEmpty(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (clipboard->data)
Packit 1fb8d4
	{
Packit 1fb8d4
		free((void*) clipboard->data);
Packit 1fb8d4
		clipboard->data = NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	clipboard->size = 0;
Packit 1fb8d4
	clipboard->formatId = 0;
Packit 1fb8d4
	clipboard->sequenceNumber++;
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
UINT32 ClipboardCountRegisteredFormats(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	return clipboard->numFormats;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
UINT32 ClipboardGetRegisteredFormatIds(wClipboard* clipboard,
Packit 1fb8d4
                                       UINT32** ppFormatIds)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 index;
Packit 1fb8d4
	UINT32* pFormatIds;
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	if (!ppFormatIds)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	pFormatIds = *ppFormatIds;
Packit 1fb8d4
Packit 1fb8d4
	if (!pFormatIds)
Packit 1fb8d4
	{
Packit 1fb8d4
		pFormatIds = calloc(clipboard->numFormats, sizeof(UINT32));
Packit 1fb8d4
Packit 1fb8d4
		if (!pFormatIds)
Packit 1fb8d4
			return 0;
Packit 1fb8d4
Packit 1fb8d4
		*ppFormatIds = pFormatIds;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < clipboard->numFormats; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		format = &(clipboard->formats[index]);
Packit 1fb8d4
		pFormatIds[index] = format->formatId;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return clipboard->numFormats;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
UINT32 ClipboardRegisterFormat(wClipboard* clipboard, const char* name)
Packit 1fb8d4
{
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	format = ClipboardFindFormat(clipboard, 0, name);
Packit 1fb8d4
Packit 1fb8d4
	if (format)
Packit 1fb8d4
		return format->formatId;
Packit 1fb8d4
Packit 1fb8d4
	if ((clipboard->numFormats + 1) >= clipboard->maxFormats)
Packit 1fb8d4
	{
Packit 1fb8d4
		UINT32 numFormats = clipboard->maxFormats * 2;
Packit 1fb8d4
		wClipboardFormat* tmpFormat;
Packit 1fb8d4
		tmpFormat = (wClipboardFormat*) realloc(clipboard->formats,
Packit 1fb8d4
		                                        numFormats * sizeof(wClipboardFormat));
Packit 1fb8d4
Packit 1fb8d4
		if (!tmpFormat)
Packit 1fb8d4
			return 0;
Packit 1fb8d4
Packit 1fb8d4
		clipboard->formats  = tmpFormat;
Packit 1fb8d4
		clipboard->maxFormats = numFormats;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	format = &(clipboard->formats[clipboard->numFormats]);
Packit 1fb8d4
	ZeroMemory(format, sizeof(wClipboardFormat));
Packit 1fb8d4
Packit 1fb8d4
	if (name)
Packit 1fb8d4
	{
Packit 1fb8d4
		format->formatName = _strdup(name);
Packit 1fb8d4
Packit 1fb8d4
		if (!format->formatName)
Packit 1fb8d4
			return 0;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	format->formatId = clipboard->nextFormatId++;
Packit 1fb8d4
	clipboard->numFormats++;
Packit 1fb8d4
	return format->formatId;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL ClipboardRegisterSynthesizer(wClipboard* clipboard, UINT32 formatId,
Packit 1fb8d4
                                  UINT32 syntheticId, CLIPBOARD_SYNTHESIZE_FN pfnSynthesize)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 index;
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
	wClipboardSynthesizer* synthesizer;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	format = ClipboardFindFormat(clipboard, formatId, NULL);
Packit 1fb8d4
Packit 1fb8d4
	if (!format)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (format->formatId == syntheticId)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	synthesizer = ClipboardFindSynthesizer(format, formatId);
Packit 1fb8d4
Packit 1fb8d4
	if (!synthesizer)
Packit 1fb8d4
	{
Packit 1fb8d4
		wClipboardSynthesizer* tmpSynthesizer;
Packit 1fb8d4
		UINT32 numSynthesizers = format->numSynthesizers + 1;
Packit 1fb8d4
		tmpSynthesizer = (wClipboardSynthesizer*) realloc(format->synthesizers,
Packit 1fb8d4
		                 numSynthesizers * sizeof(wClipboardSynthesizer));
Packit 1fb8d4
Packit 1fb8d4
		if (!tmpSynthesizer)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		format->synthesizers  = tmpSynthesizer;
Packit 1fb8d4
		format->numSynthesizers = numSynthesizers;
Packit 1fb8d4
		index = numSynthesizers - 1;
Packit 1fb8d4
		synthesizer = &(format->synthesizers[index]);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ZeroMemory(synthesizer, sizeof(wClipboardSynthesizer));
Packit 1fb8d4
	synthesizer->syntheticId = syntheticId;
Packit 1fb8d4
	synthesizer->pfnSynthesize = pfnSynthesize;
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
UINT32 ClipboardCountFormats(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 count;
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	format = ClipboardFindFormat(clipboard, clipboard->formatId, NULL);
Packit 1fb8d4
Packit 1fb8d4
	if (!format)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	count = 1 + format->numSynthesizers;
Packit 1fb8d4
	return count;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
UINT32 ClipboardGetFormatIds(wClipboard* clipboard, UINT32** ppFormatIds)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 index;
Packit 1fb8d4
	UINT32 count;
Packit 1fb8d4
	UINT32* pFormatIds;
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
	wClipboardSynthesizer* synthesizer;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	format = ClipboardFindFormat(clipboard, clipboard->formatId, NULL);
Packit 1fb8d4
Packit 1fb8d4
	if (!format)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	count = 1 + format->numSynthesizers;
Packit 1fb8d4
Packit 1fb8d4
	if (!ppFormatIds)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	pFormatIds = *ppFormatIds;
Packit 1fb8d4
Packit 1fb8d4
	if (!pFormatIds)
Packit 1fb8d4
	{
Packit 1fb8d4
		pFormatIds = calloc(count, sizeof(UINT32));
Packit 1fb8d4
Packit 1fb8d4
		if (!pFormatIds)
Packit 1fb8d4
			return 0;
Packit 1fb8d4
Packit 1fb8d4
		*ppFormatIds = pFormatIds;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	pFormatIds[0] = format->formatId;
Packit 1fb8d4
Packit 1fb8d4
	for (index = 1; index < count; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		synthesizer = &(format->synthesizers[index - 1]);
Packit 1fb8d4
		pFormatIds[index] = synthesizer->syntheticId;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return count;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL ClipboardInitFormats(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 formatId = 0;
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	for (formatId = 0; formatId < CF_MAX; formatId++, clipboard->numFormats++)
Packit 1fb8d4
	{
Packit 1fb8d4
		format = &(clipboard->formats[clipboard->numFormats]);
Packit 1fb8d4
		ZeroMemory(format, sizeof(wClipboardFormat));
Packit 1fb8d4
		format->formatId = formatId;
Packit 1fb8d4
		format->formatName = _strdup(CF_STANDARD_STRINGS[formatId]);
Packit 1fb8d4
		if (!format->formatName)
Packit 1fb8d4
			goto error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!ClipboardInitSynthesizers(clipboard))
Packit 1fb8d4
		goto error;
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
Packit 1fb8d4
error:
Packit 1fb8d4
	for (formatId = 0; formatId < clipboard->numFormats; formatId++)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(clipboard->formats[formatId].formatName);
Packit 1fb8d4
		free(clipboard->formats[formatId].synthesizers);
Packit 1fb8d4
	}
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
UINT32 ClipboardGetFormatId(wClipboard* clipboard, const char* name)
Packit 1fb8d4
{
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	format = ClipboardFindFormat(clipboard, 0, name);
Packit 1fb8d4
Packit 1fb8d4
	if (!format)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	return format->formatId;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
const char* ClipboardGetFormatName(wClipboard* clipboard, UINT32 formatId)
Packit 1fb8d4
{
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	format = ClipboardFindFormat(clipboard, formatId, NULL);
Packit 1fb8d4
Packit 1fb8d4
	if (!format)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	return format->formatName;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void* ClipboardGetData(wClipboard* clipboard, UINT32 formatId, UINT32* pSize)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 SrcSize = 0;
Packit 1fb8d4
	UINT32 DstSize = 0;
Packit 1fb8d4
	void* pSrcData = NULL;
Packit 1fb8d4
	void* pDstData = NULL;
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
	wClipboardSynthesizer* synthesizer;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (!pSize)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	*pSize = 0;
Packit 1fb8d4
	format = ClipboardFindFormat(clipboard, clipboard->formatId, NULL);
Packit 1fb8d4
Packit 1fb8d4
	if (!format)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	SrcSize = clipboard->size;
Packit 1fb8d4
	pSrcData = (void*) clipboard->data;
Packit 1fb8d4
Packit 1fb8d4
	if (formatId == format->formatId)
Packit 1fb8d4
	{
Packit 1fb8d4
		DstSize = SrcSize;
Packit 1fb8d4
		pDstData = malloc(DstSize);
Packit 1fb8d4
Packit 1fb8d4
		if (!pDstData)
Packit 1fb8d4
			return NULL;
Packit 1fb8d4
Packit 1fb8d4
		CopyMemory(pDstData, pSrcData, SrcSize);
Packit 1fb8d4
		*pSize = DstSize;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		synthesizer = ClipboardFindSynthesizer(format, formatId);
Packit 1fb8d4
Packit 1fb8d4
		if (!synthesizer || !synthesizer->pfnSynthesize)
Packit 1fb8d4
			return NULL;
Packit 1fb8d4
Packit 1fb8d4
		DstSize = SrcSize;
Packit 1fb8d4
		pDstData = synthesizer->pfnSynthesize(clipboard, format->formatId, pSrcData,
Packit 1fb8d4
		                                      &DstSize);
Packit 1fb8d4
		*pSize = DstSize;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return pDstData;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL ClipboardSetData(wClipboard* clipboard, UINT32 formatId, const void* data,
Packit 1fb8d4
                      UINT32 size)
Packit 1fb8d4
{
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	format = ClipboardFindFormat(clipboard, formatId, NULL);
Packit 1fb8d4
Packit 1fb8d4
	if (!format)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	free((void*) clipboard->data);
Packit 1fb8d4
	clipboard->data = malloc(size);
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard->data)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	memcpy(clipboard->data, data, size);
Packit 1fb8d4
	clipboard->size = size;
Packit 1fb8d4
	clipboard->formatId = formatId;
Packit 1fb8d4
	clipboard->sequenceNumber++;
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
UINT64 ClipboardGetOwner(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	return clipboard->ownerId;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ClipboardSetOwner(wClipboard* clipboard, UINT64 ownerId)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	clipboard->ownerId = ownerId;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
wClipboardDelegate* ClipboardGetDelegate(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	return &clipboard->delegate;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ClipboardInitLocalFileSubsystem(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * There can be only one local file subsystem active.
Packit 1fb8d4
	 * Return as soon as initialization succeeds.
Packit 1fb8d4
	 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef WITH_WCLIPBOARD_POSIX
Packit 1fb8d4
	if (ClipboardInitPosixFileSubsystem(clipboard))
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "initialized POSIX local file subsystem");
Packit 1fb8d4
		return;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_WARN(TAG, "failed to initialize POSIX local file subsystem");
Packit 1fb8d4
	}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
	WLog_INFO(TAG, "failed to initialize local file subsystem, file transfer not available");
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
wClipboard* ClipboardCreate()
Packit 1fb8d4
{
Packit 1fb8d4
	wClipboard* clipboard;
Packit 1fb8d4
Packit 1fb8d4
	clipboard = (wClipboard*) calloc(1, sizeof(wClipboard));
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	clipboard->nextFormatId = 0xC000;
Packit 1fb8d4
	clipboard->sequenceNumber = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (!InitializeCriticalSectionAndSpinCount(&(clipboard->lock), 4000))
Packit 1fb8d4
		goto error_free_clipboard;
Packit 1fb8d4
Packit 1fb8d4
	clipboard->numFormats = 0;
Packit 1fb8d4
	clipboard->maxFormats = 64;
Packit 1fb8d4
Packit 1fb8d4
	clipboard->formats = (wClipboardFormat*)
Packit 1fb8d4
		calloc(clipboard->maxFormats, sizeof(wClipboardFormat));
Packit 1fb8d4
	if (!clipboard->formats)
Packit 1fb8d4
		goto error_free_lock;
Packit 1fb8d4
Packit 1fb8d4
	if (!ClipboardInitFormats(clipboard))
Packit 1fb8d4
		goto error_free_formats;
Packit 1fb8d4
Packit 1fb8d4
	clipboard->delegate.clipboard = clipboard;
Packit 1fb8d4
Packit 1fb8d4
	ClipboardInitLocalFileSubsystem(clipboard);
Packit 1fb8d4
Packit 1fb8d4
	return clipboard;
Packit 1fb8d4
Packit 1fb8d4
error_free_formats:
Packit 1fb8d4
	free(clipboard->formats);
Packit 1fb8d4
error_free_lock:
Packit 1fb8d4
	DeleteCriticalSection(&(clipboard->lock));
Packit 1fb8d4
error_free_clipboard:
Packit 1fb8d4
	free(clipboard);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ClipboardDestroy(wClipboard* clipboard)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 index;
Packit 1fb8d4
	wClipboardFormat* format;
Packit 1fb8d4
Packit 1fb8d4
	if (!clipboard)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	ArrayList_Free(clipboard->localFiles);
Packit 1fb8d4
	clipboard->localFiles = NULL;
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < clipboard->numFormats; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		format = &(clipboard->formats[index]);
Packit 1fb8d4
		free((void*) format->formatName);
Packit 1fb8d4
Packit 1fb8d4
		if (format->synthesizers)
Packit 1fb8d4
		{
Packit 1fb8d4
			free(format->synthesizers);
Packit 1fb8d4
			format->synthesizers = NULL;
Packit 1fb8d4
			format->numSynthesizers = 0;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	free((void*) clipboard->data);
Packit 1fb8d4
	clipboard->data = NULL;
Packit 1fb8d4
	clipboard->size = 0;
Packit 1fb8d4
	clipboard->numFormats = 0;
Packit 1fb8d4
	free(clipboard->formats);
Packit 1fb8d4
	DeleteCriticalSection(&(clipboard->lock));
Packit 1fb8d4
	free(clipboard);
Packit 1fb8d4
}