Merge pull request #5266 from akallabeth/file_list_synth

Added a proper synthesizer for FileGroupDescriptorW to text/uri-list
This commit is contained in:
Martin Fleisz
2019-05-08 15:05:05 +02:00
committed by GitHub
5 changed files with 128 additions and 29 deletions

View File

@@ -854,6 +854,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

@@ -1387,6 +1387,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
{
@@ -1436,10 +1443,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]",
ClipboardGetFormatName(clipboard->system, dstFormatId),
ClipboardGetFormatName(clipboard->system, srcFormatId));
return ERROR_INTERNAL_ERROR;
WLog_WARN(TAG, "failed to get clipboard data in format %s [source format %s]",
ClipboardGetFormatName(clipboard->system, dstFormatId),
ClipboardGetFormatName(clipboard->system, srcFormatId));
return CHANNEL_RC_OK;
}
if (nullTerminated)
@@ -1716,6 +1723,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,18 +51,19 @@ struct _wClipboardDelegate
{
wClipboard* clipboard;
void* custom;
char* basePath;
UINT (*ClientRequestFileSize)(wClipboardDelegate*, const wClipboardFileSizeRequest*);
UINT (*ClipboardFileSizeSuccess)(wClipboardDelegate*, const wClipboardFileSizeRequest*,
UINT64 fileSize);
UINT (*ClipboardFileSizeFailure)(wClipboardDelegate*, const wClipboardFileSizeRequest*,
UINT errorCode);
UINT(*ClientRequestFileSize)(wClipboardDelegate*, const wClipboardFileSizeRequest*);
UINT(*ClipboardFileSizeSuccess)(wClipboardDelegate*, const wClipboardFileSizeRequest*,
UINT64 fileSize);
UINT(*ClipboardFileSizeFailure)(wClipboardDelegate*, const wClipboardFileSizeRequest*,
UINT errorCode);
UINT (*ClientRequestFileRange)(wClipboardDelegate*, const wClipboardFileRangeRequest*);
UINT (*ClipboardFileRangeSuccess)(wClipboardDelegate*, const wClipboardFileRangeRequest*,
const BYTE* data, UINT32 size);
UINT (*ClipboardFileRangeFailure)(wClipboardDelegate*, const wClipboardFileRangeRequest*,
UINT errorCode);
UINT(*ClientRequestFileRange)(wClipboardDelegate*, const wClipboardFileRangeRequest*);
UINT(*ClipboardFileRangeSuccess)(wClipboardDelegate*, const wClipboardFileRangeRequest*,
const BYTE* data, UINT32 size);
UINT(*ClipboardFileRangeFailure)(wClipboardDelegate*, const wClipboardFileRangeRequest*,
UINT errorCode);
};
#ifdef __cplusplus
@@ -80,19 +82,20 @@ WINPR_API UINT32 ClipboardGetRegisteredFormatIds(wClipboard* clipboard, UINT32**
WINPR_API UINT32 ClipboardRegisterFormat(wClipboard* clipboard, const char* name);
WINPR_API BOOL ClipboardRegisterSynthesizer(wClipboard* clipboard, UINT32 formatId,
UINT32 syntheticId, CLIPBOARD_SYNTHESIZE_FN pfnSynthesize);
UINT32 syntheticId, CLIPBOARD_SYNTHESIZE_FN pfnSynthesize);
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));
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

@@ -575,6 +575,88 @@ 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 = 0;
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++)
{
int rc;
const FILEDESCRIPTOR* cur = &descriptors[x];
size_t curLen = _wcsnlen(cur->cFileName, ARRAYSIZE(cur->cFileName));
char* curName = NULL;
rc = ConvertFromUnicode(CP_UTF8, 0, cur->cFileName, (int)curLen, &curName, 0, NULL, NULL);
if (rc != (int)curLen)
{
free(curName);
free(dst);
return NULL;
}
rc = _snprintf(&dst[pos], alloc - pos, "%s/%s\r\n", clipboard->delegate.basePath, curName);
free(curName);
if (rc < 0)
{
free(dst);
return NULL;
}
pos += (size_t)rc;
}
*pSize = (UINT32)alloc;
clipboard->fileListSequenceNumber = clipboard->sequenceNumber;
return dst;
}
static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard)
{
UINT32 file_group_format_id;
@@ -597,6 +679,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);