Added a proper synthesizer for FileGroupDescriptorW to text/uri-list

The file clipboard delegate needs a base URI to operate on for
systems that are not WIN32. Added that to the context and abort
conversion, if that is not set. (currently not fully implemented)
This commit is contained in:
Armin Novak 2019-02-20 17:05:47 +01:00
parent 22974ff9d8
commit 32ea44c037
5 changed files with 111 additions and 29 deletions

View File

@ -851,6 +851,8 @@ wfClipboard* wlf_clipboard_new(wlfContext* wfc)
clipboard->system = ClipboardCreate();
clipboard->delegate = ClipboardGetDelegate(clipboard->system);
clipboard->delegate->custom = clipboard;
/* TODO: set up a filesystem base path for local URI */
/* clipboard->delegate->basePath = "file:///tmp/foo/bar/gaga"; */
clipboard->delegate->ClipboardFileSizeSuccess = wlf_cliprdr_clipboard_file_size_success;
clipboard->delegate->ClipboardFileSizeFailure = wlf_cliprdr_clipboard_file_size_failure;
clipboard->delegate->ClipboardFileRangeSuccess = wlf_cliprdr_clipboard_file_range_success;

View File

@ -1380,6 +1380,13 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext*
dstFormatId = ClipboardGetFormatId(clipboard->system, "text/html");
nullTerminated = TRUE;
}
if (strcmp(clipboard->data_format_name, "FileGroupDescriptorW") == 0)
{
srcFormatId = ClipboardGetFormatId(clipboard->system, "FileGroupDescriptorW");
dstFormatId = ClipboardGetFormatId(clipboard->system, "text/uri-list");
nullTerminated = FALSE;
}
}
else
{
@ -1429,10 +1436,10 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext*
if (!pDstData)
{
WLog_ERR(TAG, "failed to get clipboard data in format %s [source format %s]",
WLog_WARN(TAG, "failed to get clipboard data in format %s [source format %s]",
ClipboardGetFormatName(clipboard->system, dstFormatId),
ClipboardGetFormatName(clipboard->system, srcFormatId));
return ERROR_INTERNAL_ERROR;
return CHANNEL_RC_OK;
}
if (nullTerminated)
@ -1704,6 +1711,8 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
clipboard->incr_atom = XInternAtom(xfc->display, "INCR", FALSE);
clipboard->delegate = ClipboardGetDelegate(clipboard->system);
clipboard->delegate->custom = clipboard;
/* TODO: set up a filesystem base path for local URI */
/* clipboard->delegate->basePath = "file:///tmp/foo/bar/gaga"; */
clipboard->delegate->ClipboardFileSizeSuccess = xf_cliprdr_clipboard_file_size_success;
clipboard->delegate->ClipboardFileSizeFailure = xf_cliprdr_clipboard_file_size_failure;
clipboard->delegate->ClipboardFileRangeSuccess = xf_cliprdr_clipboard_file_range_success;

View File

@ -25,7 +25,8 @@
typedef struct _wClipboard wClipboard;
typedef void* (*CLIPBOARD_SYNTHESIZE_FN)(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize);
typedef void* (*CLIPBOARD_SYNTHESIZE_FN)(wClipboard* clipboard, UINT32 formatId, const void* data,
UINT32* pSize);
struct _wClipboardFileSizeRequest
{
@ -50,17 +51,18 @@ struct _wClipboardDelegate
{
wClipboard* clipboard;
void* custom;
char* basePath;
UINT (*ClientRequestFileSize)(wClipboardDelegate*, const wClipboardFileSizeRequest*);
UINT (*ClipboardFileSizeSuccess)(wClipboardDelegate*, const wClipboardFileSizeRequest*,
UINT(*ClientRequestFileSize)(wClipboardDelegate*, const wClipboardFileSizeRequest*);
UINT(*ClipboardFileSizeSuccess)(wClipboardDelegate*, const wClipboardFileSizeRequest*,
UINT64 fileSize);
UINT (*ClipboardFileSizeFailure)(wClipboardDelegate*, const wClipboardFileSizeRequest*,
UINT(*ClipboardFileSizeFailure)(wClipboardDelegate*, const wClipboardFileSizeRequest*,
UINT errorCode);
UINT (*ClientRequestFileRange)(wClipboardDelegate*, const wClipboardFileRangeRequest*);
UINT (*ClipboardFileRangeSuccess)(wClipboardDelegate*, const wClipboardFileRangeRequest*,
UINT(*ClientRequestFileRange)(wClipboardDelegate*, const wClipboardFileRangeRequest*);
UINT(*ClipboardFileRangeSuccess)(wClipboardDelegate*, const wClipboardFileRangeRequest*,
const BYTE* data, UINT32 size);
UINT (*ClipboardFileRangeFailure)(wClipboardDelegate*, const wClipboardFileRangeRequest*,
UINT(*ClipboardFileRangeFailure)(wClipboardDelegate*, const wClipboardFileRangeRequest*,
UINT errorCode);
};
@ -85,14 +87,15 @@ WINPR_API BOOL ClipboardRegisterSynthesizer(wClipboard* clipboard, UINT32 format
WINPR_API UINT32 ClipboardGetFormatId(wClipboard* clipboard, const char* name);
WINPR_API const char* ClipboardGetFormatName(wClipboard* clipboard, UINT32 formatId);
WINPR_API void* ClipboardGetData(wClipboard* clipboard, UINT32 formatId, UINT32* pSize);
WINPR_API BOOL ClipboardSetData(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32 size);
WINPR_API BOOL ClipboardSetData(wClipboard* clipboard, UINT32 formatId, const void* data,
UINT32 size);
WINPR_API UINT64 ClipboardGetOwner(wClipboard* clipboard);
WINPR_API void ClipboardSetOwner(wClipboard* clipboard, UINT64 ownerId);
WINPR_API wClipboardDelegate* ClipboardGetDelegate(wClipboard* clipboard);
WINPR_API wClipboard* ClipboardCreate();
WINPR_API wClipboard* ClipboardCreate(void);
WINPR_API void ClipboardDestroy(wClipboard* clipboard);
#ifdef __cplusplus

View File

@ -373,6 +373,7 @@ BOOL ClipboardInitFormats(wClipboard* clipboard)
ZeroMemory(format, sizeof(wClipboardFormat));
format->formatId = formatId;
format->formatName = _strdup(CF_STANDARD_STRINGS[formatId]);
if (!format->formatName)
goto error;
}
@ -381,13 +382,14 @@ BOOL ClipboardInitFormats(wClipboard* clipboard)
goto error;
return TRUE;
error:
for (formatId = 0; formatId < clipboard->numFormats; formatId++)
{
free(clipboard->formats[formatId].formatName);
free(clipboard->formats[formatId].synthesizers);
}
return FALSE;
}
@ -522,13 +524,12 @@ wClipboardDelegate* ClipboardGetDelegate(wClipboard* clipboard)
return &clipboard->delegate;
}
void ClipboardInitLocalFileSubsystem(wClipboard* clipboard)
static void ClipboardInitLocalFileSubsystem(wClipboard* clipboard)
{
/*
* There can be only one local file subsystem active.
* Return as soon as initialization succeeds.
*/
#ifdef WITH_WCLIPBOARD_POSIX
if (ClipboardInitPosixFileSubsystem(clipboard))
{
@ -539,16 +540,16 @@ void ClipboardInitLocalFileSubsystem(wClipboard* clipboard)
{
WLog_WARN(TAG, "failed to initialize POSIX local file subsystem");
}
#endif
#endif
WLog_INFO(TAG, "failed to initialize local file subsystem, file transfer not available");
}
wClipboard* ClipboardCreate()
wClipboard* ClipboardCreate(void)
{
wClipboard* clipboard;
clipboard = (wClipboard*) calloc(1, sizeof(wClipboard));
if (!clipboard)
return NULL;
@ -560,9 +561,9 @@ wClipboard* ClipboardCreate()
clipboard->numFormats = 0;
clipboard->maxFormats = 64;
clipboard->formats = (wClipboardFormat*)
calloc(clipboard->maxFormats, sizeof(wClipboardFormat));
if (!clipboard->formats)
goto error_free_lock;
@ -570,11 +571,8 @@ wClipboard* ClipboardCreate()
goto error_free_formats;
clipboard->delegate.clipboard = clipboard;
ClipboardInitLocalFileSubsystem(clipboard);
return clipboard;
error_free_formats:
free(clipboard->formats);
error_free_lock:

View File

@ -573,6 +573,71 @@ static void* convert_uri_list_to_filedescriptors(wClipboard* clipboard, UINT32 f
return descriptors;
}
static void* convert_filedescriptors_to_uri_list(wClipboard* clipboard, UINT32 formatId,
const void* data, UINT32* pSize)
{
const FILEDESCRIPTOR* descriptors;
UINT32 nrDescriptors;
size_t count, x, alloc, pos, baseLength = 0;
const char* src = (const char*) data;
char* dst;
if (!clipboard || !data || !pSize)
return NULL;
if (*pSize < sizeof(UINT32))
return NULL;
if (clipboard->delegate.basePath)
baseLength = strnlen(clipboard->delegate.basePath, MAX_PATH);
if (baseLength < 1)
return NULL;
if (clipboard->delegate.ClientRequestFileSize)
nrDescriptors = (UINT32)(src[3] << 24) | (UINT32)(src[2] << 16) | (UINT32)(src[1] << 8) |
(src[0] & 0xFF);
count = (*pSize - 4) / sizeof(FILEDESCRIPTOR);
if ((count < 1) || (count != nrDescriptors))
return NULL;
descriptors = (const FILEDESCRIPTOR*)&src[4];
if (formatId != ClipboardGetFormatId(clipboard, "FileGroupDescriptorW"))
return NULL;
alloc = 0;
/* Get total size of file names */
for (x = 0; x < count; x++)
alloc += _wcsnlen(descriptors[x].cFileName, ARRAYSIZE(descriptors[x].cFileName));
/* Append a prefix file:// and postfix \r\n for each file */
alloc += (sizeof("/\r\n") + baseLength) * count;
dst = calloc(alloc, sizeof(char));
if (!dst)
return NULL;
pos = 0;
for (x = 0; x < count; x++)
{
const FILEDESCRIPTOR* cur = &descriptors[x];
size_t curLen = _wcsnlen(cur->cFileName, ARRAYSIZE(cur->cFileName));
char* curName = NULL;
ConvertFromUnicode(CP_UTF8, 0, cur->cFileName, curLen, &curName, 0, NULL, NULL);
pos += _snprintf(&dst[pos], alloc - pos, "%s/%s\r\n", clipboard->delegate.basePath, curName);
free(curName);
}
*pSize = alloc;
clipboard->fileListSequenceNumber = clipboard->sequenceNumber;
return dst;
}
static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard)
{
UINT32 file_group_format_id;
@ -595,6 +660,11 @@ static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard)
convert_uri_list_to_filedescriptors))
goto error_free_local_files;
if (!ClipboardRegisterSynthesizer(clipboard,
file_group_format_id, local_file_format_id,
convert_filedescriptors_to_uri_list))
goto error_free_local_files;
return TRUE;
error_free_local_files:
ArrayList_Free(clipboard->localFiles);