This commit is contained in:
Armin Novak 2023-02-21 15:13:07 +01:00 committed by akallabeth
parent 3d3e577190
commit 1522b5aa91
5 changed files with 18 additions and 205 deletions

View File

@ -62,9 +62,6 @@
#define TAG CLIENT_TAG("x11") #define TAG CLIENT_TAG("x11")
#define CB_FORMAT_GNOMECOPIEDFILES 0xD015
#define CB_FORMAT_MATECOPIEDFILES 0xD016
#define MAX_CLIPBOARD_FORMATS 255 #define MAX_CLIPBOARD_FORMATS 255
#define WIN32_FILETIME_TO_UNIX_EPOCH_USEC UINT64_C(116444736000000000) #define WIN32_FILETIME_TO_UNIX_EPOCH_USEC UINT64_C(116444736000000000)
@ -198,6 +195,7 @@ struct xf_clipboard
#endif #endif
}; };
static const char* mime_text_plain = "text/plain";
static const char* mime_uri_list = "text/uri-list"; static const char* mime_uri_list = "text/uri-list";
static const char* mime_FileGroupDescriptorW = "FileGroupDescriptorW"; static const char* mime_FileGroupDescriptorW = "FileGroupDescriptorW";
static const char* mime_nautilus_clipboard = "x-special/nautilus-clipboard"; static const char* mime_nautilus_clipboard = "x-special/nautilus-clipboard";
@ -836,7 +834,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
case CF_OEMTEXT: case CF_OEMTEXT:
case CF_UNICODETEXT: case CF_UNICODETEXT:
size = strlen((char*)data) + 1; size = strlen((char*)data) + 1;
srcFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); srcFormatId = ClipboardGetFormatId(clipboard->system, mime_text_plain);
break; break;
case CF_DIB: case CF_DIB:
@ -851,14 +849,6 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
srcFormatId = ClipboardGetFormatId(clipboard->system, mime_uri_list); srcFormatId = ClipboardGetFormatId(clipboard->system, mime_uri_list);
break; break;
case CB_FORMAT_GNOMECOPIEDFILES:
srcFormatId = ClipboardGetFormatId(clipboard->system, mime_gnome_copied_files);
break;
case CB_FORMAT_MATECOPIEDFILES:
srcFormatId = ClipboardGetFormatId(clipboard->system, mime_mate_copied_files);
break;
default: default:
xf_cliprdr_send_data_response(clipboard, NULL, 0); xf_cliprdr_send_data_response(clipboard, NULL, 0);
return; return;
@ -2312,19 +2302,11 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context,
switch (dstTargetFormat->formatId) switch (dstTargetFormat->formatId)
{ {
case CF_UNICODETEXT: case CF_UNICODETEXT:
dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); dstFormatId = ClipboardGetFormatId(clipboard->system, mime_text_plain);
break; break;
case CB_FORMAT_TEXTURILIST: case CB_FORMAT_TEXTURILIST:
dstFormatId = ClipboardGetFormatId(clipboard->system, mime_uri_list); dstFormatId = ClipboardGetFormatId(clipboard->system, mime_uri_list);
break; break;
case CB_FORMAT_GNOMECOPIEDFILES:
dstFormatId =
ClipboardGetFormatId(clipboard->system, mime_gnome_copied_files);
break;
case CB_FORMAT_MATECOPIEDFILES:
dstFormatId =
ClipboardGetFormatId(clipboard->system, mime_mate_copied_files);
break;
default: default:
break; break;
} }
@ -2339,19 +2321,19 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context,
{ {
case CF_TEXT: case CF_TEXT:
srcFormatId = CF_TEXT; srcFormatId = CF_TEXT;
dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); dstFormatId = ClipboardGetFormatId(clipboard->system, mime_text_plain);
nullTerminated = TRUE; nullTerminated = TRUE;
break; break;
case CF_OEMTEXT: case CF_OEMTEXT:
srcFormatId = CF_OEMTEXT; srcFormatId = CF_OEMTEXT;
dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); dstFormatId = ClipboardGetFormatId(clipboard->system, mime_text_plain);
nullTerminated = TRUE; nullTerminated = TRUE;
break; break;
case CF_UNICODETEXT: case CF_UNICODETEXT:
srcFormatId = CF_UNICODETEXT; srcFormatId = CF_UNICODETEXT;
dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); dstFormatId = ClipboardGetFormatId(clipboard->system, mime_text_plain);
nullTerminated = TRUE; nullTerminated = TRUE;
break; break;
@ -3259,28 +3241,6 @@ xfClipboard* xf_clipboard_new(xfContext* xfc, BOOL relieveFilenameRestriction)
clientFormat = &clipboard->clientFormats[n++]; clientFormat = &clipboard->clientFormats[n++];
} }
if (ClipboardGetFormatId(clipboard->system, mime_gnome_copied_files))
{
clipboard->file_formats_registered = TRUE;
clientFormat->atom = XInternAtom(xfc->display, mime_gnome_copied_files, False);
clientFormat->formatId = CB_FORMAT_GNOMECOPIEDFILES;
clientFormat->formatName = _strdup(mime_FileGroupDescriptorW);
if (!clientFormat->formatName)
goto error;
clientFormat = &clipboard->clientFormats[n++];
}
if (ClipboardGetFormatId(clipboard->system, mime_mate_copied_files))
{
clipboard->file_formats_registered = TRUE;
clientFormat->atom = XInternAtom(xfc->display, mime_mate_copied_files, False);
clientFormat->formatId = CB_FORMAT_MATECOPIEDFILES;
clientFormat->formatName = _strdup(mime_FileGroupDescriptorW);
if (!clientFormat->formatName)
goto error;
}
clipboard->numClientFormats = n; clipboard->numClientFormats = n;
clipboard->targets[0] = XInternAtom(xfc->display, "TIMESTAMP", FALSE); clipboard->targets[0] = XInternAtom(xfc->display, "TIMESTAMP", FALSE);

View File

@ -32,8 +32,6 @@
#include "../log.h" #include "../log.h"
#define TAG WINPR_TAG("clipboard") #define TAG WINPR_TAG("clipboard")
const char* mime_utf8_string = "UTF8_STRING";
/** /**
* Clipboard (Windows): * Clipboard (Windows):
* msdn.microsoft.com/en-us/library/windows/desktop/ms648709/ * msdn.microsoft.com/en-us/library/windows/desktop/ms648709/

View File

@ -72,11 +72,4 @@ WINPR_LOCAL BOOL ClipboardInitSynthesizers(wClipboard* clipboard);
WINPR_LOCAL char* parse_uri_to_local_file(const char* uri, size_t uri_len); WINPR_LOCAL char* parse_uri_to_local_file(const char* uri, size_t uri_len);
extern const char* mime_utf8_string;
extern const char* mime_uri_list;
extern const char* mime_FileGroupDescriptorW;
extern const char* mime_nautilus_clipboard;
extern const char* mime_gnome_copied_files;
extern const char* mime_mate_copied_files;
#endif /* WINPR_CLIPBOARD_PRIVATE_H */ #endif /* WINPR_CLIPBOARD_PRIVATE_H */

View File

@ -25,6 +25,7 @@
#include "clipboard.h" #include "clipboard.h"
static const char* mime_text_plain = "text/plain";
/** /**
* Standard Clipboard Formats: * Standard Clipboard Formats:
* http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168/ * http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168/
@ -55,10 +56,7 @@ static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId
return pDstData; return pDstData;
} }
else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) || else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
(formatId == ClipboardGetFormatId(clipboard, mime_utf8_string)) || (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
(formatId == ClipboardGetFormatId(clipboard, "text/plain")) ||
(formatId == ClipboardGetFormatId(clipboard, "TEXT")) ||
(formatId == ClipboardGetFormatId(clipboard, "STRING")))
{ {
size = *pSize; size = *pSize;
pDstData = ConvertLineEndingToCRLF(data, &size); pDstData = ConvertLineEndingToCRLF(data, &size);
@ -118,10 +116,7 @@ static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 f
WCHAR* pDstData = NULL; WCHAR* pDstData = NULL;
if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) || if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
(formatId == ClipboardGetFormatId(clipboard, mime_utf8_string)) || (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
(formatId == ClipboardGetFormatId(clipboard, "text/plain")) ||
(formatId == ClipboardGetFormatId(clipboard, "TEXT")) ||
(formatId == ClipboardGetFormatId(clipboard, "STRING")))
{ {
size_t len = 0; size_t len = 0;
if (!pSize || (*pSize > INT32_MAX)) if (!pSize || (*pSize > INT32_MAX))
@ -172,9 +167,7 @@ static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 form
return pDstData; return pDstData;
} }
else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) || else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
(formatId == ClipboardGetFormatId(clipboard, "text/plain")) || (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
(formatId == ClipboardGetFormatId(clipboard, "TEXT")) ||
(formatId == ClipboardGetFormatId(clipboard, "STRING")))
{ {
int rc; int rc;
size = *pSize; size = *pSize;
@ -493,7 +486,7 @@ BOOL ClipboardInitSynthesizers(wClipboard* clipboard)
ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_UNICODETEXT, ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext); clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_LOCALE, clipboard_synthesize_cf_locale); ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_LOCALE, clipboard_synthesize_cf_locale);
altFormatId = ClipboardRegisterFormat(clipboard, mime_utf8_string); altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
ClipboardRegisterSynthesizer(clipboard, CF_TEXT, altFormatId, clipboard_synthesize_utf8_string); ClipboardRegisterSynthesizer(clipboard, CF_TEXT, altFormatId, clipboard_synthesize_utf8_string);
/** /**
* CF_OEMTEXT * CF_OEMTEXT
@ -502,7 +495,7 @@ BOOL ClipboardInitSynthesizers(wClipboard* clipboard)
ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_UNICODETEXT, ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext); clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_LOCALE, clipboard_synthesize_cf_locale); ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_LOCALE, clipboard_synthesize_cf_locale);
altFormatId = ClipboardRegisterFormat(clipboard, mime_utf8_string); altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, altFormatId, ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, altFormatId,
clipboard_synthesize_utf8_string); clipboard_synthesize_utf8_string);
/** /**
@ -513,13 +506,13 @@ BOOL ClipboardInitSynthesizers(wClipboard* clipboard)
clipboard_synthesize_cf_oemtext); clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_LOCALE, ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_LOCALE,
clipboard_synthesize_cf_locale); clipboard_synthesize_cf_locale);
altFormatId = ClipboardRegisterFormat(clipboard, mime_utf8_string); altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, altFormatId, ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, altFormatId,
clipboard_synthesize_utf8_string); clipboard_synthesize_utf8_string);
/** /**
* UTF8_STRING * UTF8_STRING
*/ */
formatId = ClipboardRegisterFormat(clipboard, mime_utf8_string); formatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
if (formatId) if (formatId)
{ {
@ -535,39 +528,7 @@ BOOL ClipboardInitSynthesizers(wClipboard* clipboard)
/** /**
* text/plain * text/plain
*/ */
formatId = ClipboardRegisterFormat(clipboard, "text/plain"); formatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
if (formatId)
{
ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT, clipboard_synthesize_cf_text);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
clipboard_synthesize_cf_locale);
}
/**
* TEXT
*/
formatId = ClipboardRegisterFormat(clipboard, "TEXT");
if (formatId)
{
ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT, clipboard_synthesize_cf_text);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
clipboard_synthesize_cf_oemtext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
clipboard_synthesize_cf_unicodetext);
ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
clipboard_synthesize_cf_locale);
}
/**
* STRING
*/
formatId = ClipboardRegisterFormat(clipboard, "STRING");
if (formatId) if (formatId)
{ {

View File

@ -49,11 +49,8 @@
#include "../log.h" #include "../log.h"
#define TAG WINPR_TAG("clipboard.synthetic.file") #define TAG WINPR_TAG("clipboard.synthetic.file")
const char* mime_uri_list = "text/uri-list"; static const char* mime_uri_list = "text/uri-list";
const char* mime_FileGroupDescriptorW = "FileGroupDescriptorW"; static const char* mime_FileGroupDescriptorW = "FileGroupDescriptorW";
const char* mime_nautilus_clipboard = "x-special/nautilus-clipboard";
const char* mime_gnome_copied_files = "x-special/gnome-copied-files";
const char* mime_mate_copied_files = "x-special/mate-copied-files";
struct synthetic_file struct synthetic_file
{ {
@ -698,48 +695,6 @@ static BOOL process_mate_copied_files(wClipboard* clipboard, const char* data, U
return process_files(clipboard, data, pSize, "copy\n"); return process_files(clipboard, data, pSize, "copy\n");
} }
static BOOL process_nautilus_clipboard(wClipboard* clipboard, const char* data, UINT32 pSize)
{
return process_files(clipboard, data, pSize, "x-special/nautilus-clipboard\ncopy\n");
}
static void* convert_gnome_copied_files_to_filedescriptors(wClipboard* clipboard, UINT32 formatId,
const void* data, UINT32* pSize)
{
const UINT32 expected = ClipboardGetFormatId(clipboard, mime_gnome_copied_files);
if (formatId != expected)
return NULL;
if (!process_gnome_copied_files(clipboard, (const char*)data, *pSize))
return NULL;
return convert_any_uri_list_to_filedescriptors(clipboard, formatId, pSize);
}
static void* convert_mate_copied_files_to_filedescriptors(wClipboard* clipboard, UINT32 formatId,
const void* data, UINT32* pSize)
{
const UINT32 expected = ClipboardGetFormatId(clipboard, mime_mate_copied_files);
if (formatId != expected)
return NULL;
if (!process_mate_copied_files(clipboard, (const char*)data, *pSize))
return NULL;
return convert_any_uri_list_to_filedescriptors(clipboard, formatId, pSize);
}
static void* convert_nautilus_clipboard_to_filedescriptors(wClipboard* clipboard, UINT32 formatId,
const void* data, UINT32* pSize)
{
const UINT32 expected = ClipboardGetFormatId(clipboard, mime_nautilus_clipboard);
if (formatId != expected)
return NULL;
if (!process_nautilus_clipboard(clipboard, (const char*)data, *pSize))
return NULL;
return convert_any_uri_list_to_filedescriptors(clipboard, formatId, pSize);
}
static size_t count_special_chars(const WCHAR* str) static size_t count_special_chars(const WCHAR* str)
{ {
size_t count = 0; size_t count = 0;
@ -1013,39 +968,11 @@ static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard)
wObject* obj; wObject* obj;
UINT32 file_group_format_id; UINT32 file_group_format_id;
UINT32 local_file_format_id; UINT32 local_file_format_id;
UINT32 local_gnome_file_format_id;
UINT32 local_mate_file_format_id;
UINT32 local_nautilus_file_format_id;
/*
1. Gnome Nautilus based file manager (Nautilus only with version >= 3.30 AND < 40):
TARGET: UTF8_STRING
format: x-special/nautilus-clipboard\copy\n\file://path\n\0
2. Kde Dolpin and Qt:
TARGET: text/uri-list
format: file:path\r\n\0
See:
GTK: https://docs.gtk.org/glib/struct.Uri.html
uri syntax: https://www.rfc-editor.org/rfc/rfc3986#section-3
uri-lists fomat: https://www.rfc-editor.org/rfc/rfc2483#section-5
3. Gnome and others (Unity/XFCE/Nautilus < 3.30/Nautilus >= 40):
TARGET: x-special/gnome-copied-files
format: copy\nfile://path\n\0
4. Mate Caja:
TARGET: x-special/mate-copied-files
format: copy\nfile://path\n
TODO: other file managers do not use previous targets and formats.
*/
local_gnome_file_format_id = ClipboardRegisterFormat(clipboard, mime_gnome_copied_files);
local_mate_file_format_id = ClipboardRegisterFormat(clipboard, mime_mate_copied_files);
local_nautilus_file_format_id = ClipboardRegisterFormat(clipboard, mime_utf8_string);
file_group_format_id = ClipboardRegisterFormat(clipboard, mime_FileGroupDescriptorW); file_group_format_id = ClipboardRegisterFormat(clipboard, mime_FileGroupDescriptorW);
local_file_format_id = ClipboardRegisterFormat(clipboard, mime_uri_list); local_file_format_id = ClipboardRegisterFormat(clipboard, mime_uri_list);
if (!file_group_format_id || !local_file_format_id || !local_gnome_file_format_id || if (!file_group_format_id || !local_file_format_id)
!local_mate_file_format_id || !local_nautilus_file_format_id)
goto error; goto error;
clipboard->localFiles = ArrayList_New(FALSE); clipboard->localFiles = ArrayList_New(FALSE);
@ -1064,32 +991,6 @@ static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard)
convert_filedescriptors_to_uri_list)) convert_filedescriptors_to_uri_list))
goto error_free_local_files; goto error_free_local_files;
if (!ClipboardRegisterSynthesizer(clipboard, local_gnome_file_format_id, file_group_format_id,
convert_gnome_copied_files_to_filedescriptors))
goto error_free_local_files;
if (!ClipboardRegisterSynthesizer(clipboard, file_group_format_id, local_gnome_file_format_id,
convert_filedescriptors_to_gnome_copied_files))
goto error_free_local_files;
if (!ClipboardRegisterSynthesizer(clipboard, local_mate_file_format_id, file_group_format_id,
convert_mate_copied_files_to_filedescriptors))
goto error_free_local_files;
if (!ClipboardRegisterSynthesizer(clipboard, file_group_format_id, local_mate_file_format_id,
convert_filedescriptors_to_mate_copied_files))
goto error_free_local_files;
if (!ClipboardRegisterSynthesizer(clipboard, local_nautilus_file_format_id,
file_group_format_id,
convert_nautilus_clipboard_to_filedescriptors))
goto error_free_local_files;
if (!ClipboardRegisterSynthesizer(clipboard, file_group_format_id,
local_nautilus_file_format_id,
convert_filedescriptors_to_nautilus_clipboard))
goto error_free_local_files;
return TRUE; return TRUE;
error_free_local_files: error_free_local_files:
ArrayList_Free(clipboard->localFiles); ArrayList_Free(clipboard->localFiles);