diff --git a/winpr/libwinpr/clipboard/clipboard.c b/winpr/libwinpr/clipboard/clipboard.c index c3b73c6b0..7cc8c1b72 100644 --- a/winpr/libwinpr/clipboard/clipboard.c +++ b/winpr/libwinpr/clipboard/clipboard.c @@ -32,6 +32,8 @@ #include "../log.h" #define TAG WINPR_TAG("clipboard") +const char* mime_text_plain = "text/plain"; + /** * Clipboard (Windows): * msdn.microsoft.com/en-us/library/windows/desktop/ms648709/ @@ -115,18 +117,12 @@ static wClipboardFormat* ClipboardFindFormat(wClipboard* clipboard, UINT32 forma static wClipboardSynthesizer* ClipboardFindSynthesizer(wClipboardFormat* format, UINT32 formatId) { - UINT32 index; - wClipboardSynthesizer* synthesizer; - if (!format) return NULL; - if (format->numSynthesizers < 1) - return NULL; - - for (index = 0; index < format->numSynthesizers; index++) + for (UINT32 index = 0; index < format->numSynthesizers; index++) { - synthesizer = &(format->synthesizers[index]); + wClipboardSynthesizer* synthesizer = &(format->synthesizers[index]); if (formatId == synthesizer->syntheticId) return synthesizer; @@ -287,7 +283,6 @@ BOOL ClipboardRegisterSynthesizer(wClipboard* clipboard, UINT32 formatId, UINT32 synthesizer = &(format->synthesizers[index]); } - ZeroMemory(synthesizer, sizeof(wClipboardSynthesizer)); synthesizer->syntheticId = syntheticId; synthesizer->pfnSynthesize = pfnSynthesize; return TRUE; diff --git a/winpr/libwinpr/clipboard/clipboard.h b/winpr/libwinpr/clipboard/clipboard.h index d34b83bc1..b3dc4d07e 100644 --- a/winpr/libwinpr/clipboard/clipboard.h +++ b/winpr/libwinpr/clipboard/clipboard.h @@ -72,4 +72,6 @@ WINPR_LOCAL BOOL ClipboardInitSynthesizers(wClipboard* clipboard); WINPR_LOCAL char* parse_uri_to_local_file(const char* uri, size_t uri_len); +extern const char* mime_text_plain; + #endif /* WINPR_CLIPBOARD_PRIVATE_H */ diff --git a/winpr/libwinpr/clipboard/synthetic.c b/winpr/libwinpr/clipboard/synthetic.c index 41bbe2678..dc4e5cca0 100644 --- a/winpr/libwinpr/clipboard/synthetic.c +++ b/winpr/libwinpr/clipboard/synthetic.c @@ -25,7 +25,6 @@ #include "clipboard.h" -static const char* mime_text_plain = "text/plain"; /** * Standard Clipboard Formats: * http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168/ diff --git a/winpr/libwinpr/clipboard/synthetic_file.c b/winpr/libwinpr/clipboard/synthetic_file.c index a633935f3..c40371b1c 100644 --- a/winpr/libwinpr/clipboard/synthetic_file.c +++ b/winpr/libwinpr/clipboard/synthetic_file.c @@ -51,6 +51,8 @@ static const char* mime_uri_list = "text/uri-list"; static const char* mime_FileGroupDescriptorW = "FileGroupDescriptorW"; +static const char* mime_gnome_copied_files = "x-special/gnome-copied-files"; +static const char* mime_mate_copied_files = "x-special/mate-copied-files"; struct synthetic_file { @@ -695,6 +697,35 @@ static BOOL process_mate_copied_files(wClipboard* clipboard, const char* data, U 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 size_t count_special_chars(const WCHAR* str) { size_t count = 0; @@ -968,11 +999,37 @@ static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard) wObject* obj; UINT32 file_group_format_id; UINT32 local_file_format_id; + UINT32 local_gnome_file_format_id; + UINT32 local_mate_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); file_group_format_id = ClipboardRegisterFormat(clipboard, mime_FileGroupDescriptorW); local_file_format_id = ClipboardRegisterFormat(clipboard, mime_uri_list); - if (!file_group_format_id || !local_file_format_id) + if (!file_group_format_id || !local_file_format_id || !local_gnome_file_format_id || + !local_mate_file_format_id) goto error; clipboard->localFiles = ArrayList_New(FALSE); @@ -991,6 +1048,22 @@ static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard) convert_filedescriptors_to_uri_list)) 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; + return TRUE; error_free_local_files: ArrayList_Free(clipboard->localFiles);