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:
parent
22974ff9d8
commit
32ea44c037
@ -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;
|
||||
|
@ -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]",
|
||||
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)
|
||||
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user