[gnome-remote-desktop] clipboard: Split up SelectionRead requests
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-remote-desktop] clipboard: Split up SelectionRead requests
- Date: Wed, 28 Jul 2021 15:25:40 +0000 (UTC)
commit 60e1d251559187637178915dcd857ce090c0a233
Author: Pascal Nowack <Pascal Nowack gmx de>
Date: Sun Apr 25 17:38:27 2021 +0200
clipboard: Split up SelectionRead requests
In order to be able to handle SelectionRead requests in an async way,
request_server_content_for_mime_type() needs to be adjusted to not to
directly return the data.
The function now becomes a void function, meaning no data returns to
the calling function.
To return the fetched data to the clipboard implementation, use a newly
introduced vfunc.
Functionality wise, nothing changes in this commit, since the backends
still get their data in the same way, except that the calling function
is not the same any more, as the part, that processes the returned
data, is now a separate function.
src/grd-clipboard-rdp.c | 323 +++++++++++++++++++++++++++---------------------
src/grd-clipboard-vnc.c | 67 +++++-----
src/grd-clipboard.c | 19 +--
src/grd-clipboard.h | 8 +-
4 files changed, 233 insertions(+), 184 deletions(-)
---
diff --git a/src/grd-clipboard-rdp.c b/src/grd-clipboard-rdp.c
index 73d4a62..e00a38a 100644
--- a/src/grd-clipboard-rdp.c
+++ b/src/grd-clipboard-rdp.c
@@ -99,7 +99,9 @@ struct _GrdClipboardRdp
char *fuse_mount_path;
GrdRdpFuseClipboard *rdp_fuse_clipboard;
GHashTable *format_data_cache;
+
GrdMimeType which_unicode_format;
+ ServerFormatDataRequestContext *format_data_request_context;
HANDLE format_data_received_event;
CLIPRDR_FORMAT_DATA_RESPONSE *format_data_response;
@@ -909,6 +911,159 @@ grd_clipboard_rdp_request_client_content_for_mime_type (GrdClipboard *clipbo
return g_memdup2 (dst_data, dst_size);
}
+static void
+#ifdef HAVE_FREERDP_2_3
+serialize_file_list (FILEDESCRIPTORW *files,
+ uint32_t n_files,
+ uint8_t **dst_data,
+ uint32_t *dst_size)
+{
+ FILEDESCRIPTORW *file;
+#else
+serialize_file_list (FILEDESCRIPTOR *files,
+ uint32_t n_files,
+ uint8_t **dst_data,
+ uint32_t *dst_size)
+{
+ FILEDESCRIPTOR *file;
+#endif /* HAVE_FREERDP_2_3 */
+ wStream* s = NULL;
+ uint64_t last_write_time;
+ uint32_t i, j;
+
+ if (!files || !dst_data || !dst_size)
+ return;
+
+ if (!(s = Stream_New (NULL, 4 + n_files * CLIPRDR_FILEDESCRIPTOR_SIZE)))
+ return;
+
+ Stream_Write_UINT32 (s, n_files); /* cItems */
+ for (i = 0; i < n_files; ++i)
+ {
+ file = &files[i];
+
+ Stream_Write_UINT32 (s, file->dwFlags); /* flags */
+ Stream_Zero (s, 32); /* reserved1 */
+ Stream_Write_UINT32 (s, file->dwFileAttributes); /* fileAttributes */
+ Stream_Zero (s, 16); /* reserved2 */
+
+ last_write_time = file->ftLastWriteTime.dwHighDateTime;
+ last_write_time <<= 32;
+ last_write_time += file->ftLastWriteTime.dwLowDateTime;
+
+ Stream_Write_UINT64 (s, last_write_time); /* lastWriteTime */
+ Stream_Write_UINT32 (s, file->nFileSizeHigh); /* fileSizeHigh */
+ Stream_Write_UINT32 (s, file->nFileSizeLow); /* fileSizeLow */
+
+ for (j = 0; j < 260; j++) /* cFileName */
+ Stream_Write_UINT16 (s, file->cFileName[j]);
+ }
+
+ Stream_SealLength (s);
+ Stream_GetLength (s, *dst_size);
+ Stream_GetBuffer (s, *dst_data);
+
+ Stream_Free (s, FALSE);
+}
+
+static void
+grd_clipboard_rdp_submit_requested_server_content (GrdClipboard *clipboard,
+ uint8_t *src_data,
+ uint32_t src_size)
+{
+ GrdClipboardRdp *clipboard_rdp = GRD_CLIPBOARD_RDP (clipboard);
+ CliprdrServerContext *cliprdr_context = clipboard_rdp->cliprdr_context;
+ ServerFormatDataRequestContext *request_context;
+ CLIPRDR_FORMAT_DATA_RESPONSE format_data_response = {0};
+ GrdMimeType mime_type;
+ uint32_t src_format_id;
+ uint32_t dst_format_id;
+ uint8_t *dst_data = NULL;
+ uint32_t dst_size = 0;
+ BOOL success;
+
+ request_context = g_steal_pointer (&clipboard_rdp->format_data_request_context);
+ mime_type = request_context->mime_type;
+ src_format_id = request_context->src_format_id;
+ dst_format_id = request_context->dst_format_id;
+
+ if (src_data)
+ {
+ if (request_context->needs_conversion)
+ {
+ if (request_context->needs_null_terminator)
+ {
+ char *pnull_terminator;
+
+ src_data = g_realloc (src_data, src_size + 1);
+ pnull_terminator = (char *) src_data + src_size;
+ *pnull_terminator = '\0';
+ ++src_size;
+ }
+
+ success = ClipboardSetData (clipboard_rdp->system,
+ src_format_id, src_data, src_size);
+ if (success)
+ {
+ dst_data = ClipboardGetData (clipboard_rdp->system,
+ dst_format_id, &dst_size);
+
+ if (dst_data && mime_type == GRD_MIME_TYPE_TEXT_URILIST)
+ {
+ uint64_t serial = clipboard_rdp->serial;
+ ClipDataEntry *entry;
+#ifdef HAVE_FREERDP_2_3
+ FILEDESCRIPTORW *files;
+ uint32_t n_files;
+
+ files = (FILEDESCRIPTORW *) dst_data;
+ n_files = dst_size / sizeof (FILEDESCRIPTORW);
+#else
+ FILEDESCRIPTOR *files;
+ uint32_t n_files;
+
+ files = (FILEDESCRIPTOR *) dst_data;
+ n_files = dst_size / sizeof (FILEDESCRIPTOR);
+#endif /* HAVE_FREERDP_2_3 */
+
+ dst_data = NULL;
+ dst_size = 0;
+ serialize_file_list (files, n_files, &dst_data, &dst_size);
+
+ g_free (files);
+
+ clipboard_rdp->has_file_list = TRUE;
+ if (g_hash_table_lookup_extended (clipboard_rdp->serial_entry_table,
+ GUINT_TO_POINTER (serial),
+ NULL, (gpointer *) &entry))
+ entry->has_file_list = TRUE;
+ }
+ }
+ if (!success || !dst_data)
+ g_warning ("[RDP.CLIPRDR] Converting clipboard content failed");
+ }
+ else
+ {
+ dst_data = g_steal_pointer (&src_data);
+ dst_size = src_size;
+ }
+ }
+
+ format_data_response.msgType = CB_FORMAT_DATA_RESPONSE;
+ format_data_response.msgFlags = dst_data ? CB_RESPONSE_OK : CB_RESPONSE_FAIL;
+ format_data_response.dataLen = dst_size;
+ format_data_response.requestedFormatData = dst_data;
+
+ cliprdr_context->ServerFormatDataResponse (cliprdr_context,
+ &format_data_response);
+
+ g_free (src_data);
+ g_free (dst_data);
+ g_free (request_context);
+
+ SetEvent (clipboard_rdp->completed_format_data_request_event);
+}
+
/**
* FreeRDP already updated our capabilites after the client told us
* about its capabilities, there is nothing to do here
@@ -1427,165 +1582,47 @@ cliprdr_client_unlock_clipboard_data (CliprdrServerContext *clipr
return CHANNEL_RC_OK;
}
-static void
-#ifdef HAVE_FREERDP_2_3
-serialize_file_list (FILEDESCRIPTORW *files,
- uint32_t n_files,
- uint8_t **dst_data,
- uint32_t *dst_size)
-{
- FILEDESCRIPTORW *file;
-#else
-serialize_file_list (FILEDESCRIPTOR *files,
- uint32_t n_files,
- uint8_t **dst_data,
- uint32_t *dst_size)
-{
- FILEDESCRIPTOR *file;
-#endif /* HAVE_FREERDP_2_3 */
- wStream* s = NULL;
- uint64_t last_write_time;
- uint32_t i, j;
-
- if (!files || !dst_data || !dst_size)
- return;
-
- if (!(s = Stream_New (NULL, 4 + n_files * CLIPRDR_FILEDESCRIPTOR_SIZE)))
- return;
-
- Stream_Write_UINT32 (s, n_files); /* cItems */
- for (i = 0; i < n_files; ++i)
- {
- file = &files[i];
-
- Stream_Write_UINT32 (s, file->dwFlags); /* flags */
- Stream_Zero (s, 32); /* reserved1 */
- Stream_Write_UINT32 (s, file->dwFileAttributes); /* fileAttributes */
- Stream_Zero (s, 16); /* reserved2 */
-
- last_write_time = file->ftLastWriteTime.dwHighDateTime;
- last_write_time <<= 32;
- last_write_time += file->ftLastWriteTime.dwLowDateTime;
-
- Stream_Write_UINT64 (s, last_write_time); /* lastWriteTime */
- Stream_Write_UINT32 (s, file->nFileSizeHigh); /* fileSizeHigh */
- Stream_Write_UINT32 (s, file->nFileSizeLow); /* fileSizeLow */
-
- for (j = 0; j < 260; j++) /* cFileName */
- Stream_Write_UINT16 (s, file->cFileName[j]);
- }
-
- Stream_SealLength (s);
- Stream_GetLength (s, *dst_size);
- Stream_GetBuffer (s, *dst_data);
-
- Stream_Free (s, FALSE);
-}
-
static gboolean
request_server_format_data (gpointer user_data)
{
- ServerFormatDataRequestContext *request_context = user_data;
- GrdClipboardRdp *clipboard_rdp = request_context->clipboard_rdp;
+ GrdClipboardRdp *clipboard_rdp = user_data;
GrdClipboard *clipboard = GRD_CLIPBOARD (clipboard_rdp);
CliprdrServerContext *cliprdr_context = clipboard_rdp->cliprdr_context;
- CLIPRDR_FORMAT_DATA_RESPONSE format_data_response = {0};
- GrdMimeType mime_type = request_context->mime_type;
- uint32_t src_format_id = request_context->src_format_id;
- uint32_t dst_format_id = request_context->dst_format_id;
- uint8_t *src_data, *dst_data;
- uint32_t src_size, dst_size;
- BOOL success;
+ ServerFormatDataRequestContext *request_context;
+ GrdMimeType mime_type;
- dst_data = src_data = NULL;
- dst_size = src_size = 0;
+ request_context = clipboard_rdp->format_data_request_context;
+ mime_type = request_context->mime_type;
- if (g_hash_table_contains (clipboard_rdp->allowed_server_formats,
- GUINT_TO_POINTER (mime_type)))
+ if (!g_hash_table_contains (clipboard_rdp->allowed_server_formats,
+ GUINT_TO_POINTER (mime_type)))
{
- src_data = grd_clipboard_request_server_content_for_mime_type (clipboard,
- mime_type,
- &src_size);
- }
- if (src_data)
- {
- if (request_context->needs_conversion)
- {
- if (request_context->needs_null_terminator)
- {
- char *pnull_terminator;
-
- src_data = g_realloc (src_data, src_size + 1);
- pnull_terminator = (char *) src_data + src_size;
- *pnull_terminator = '\0';
- ++src_size;
- }
-
- success = ClipboardSetData (clipboard_rdp->system,
- src_format_id, src_data, src_size);
- if (success)
- {
- dst_data = ClipboardGetData (clipboard_rdp->system,
- dst_format_id, &dst_size);
+ CLIPRDR_FORMAT_DATA_RESPONSE format_data_response = {0};
- if (dst_data && mime_type == GRD_MIME_TYPE_TEXT_URILIST)
- {
- uint64_t serial = clipboard_rdp->serial;
- ClipDataEntry *entry;
-#ifdef HAVE_FREERDP_2_3
- FILEDESCRIPTORW *files;
- uint32_t n_files;
-
- files = (FILEDESCRIPTORW *) dst_data;
- n_files = dst_size / sizeof (FILEDESCRIPTORW);
-#else
- FILEDESCRIPTOR *files;
- uint32_t n_files;
+ format_data_response.msgType = CB_FORMAT_DATA_RESPONSE;
+ format_data_response.msgFlags = CB_RESPONSE_FAIL;
- files = (FILEDESCRIPTOR *) dst_data;
- n_files = dst_size / sizeof (FILEDESCRIPTOR);
-#endif /* HAVE_FREERDP_2_3 */
+ cliprdr_context->ServerFormatDataResponse (cliprdr_context,
+ &format_data_response);
- dst_data = NULL;
- dst_size = 0;
- serialize_file_list (files, n_files, &dst_data, &dst_size);
+ g_clear_pointer (&clipboard_rdp->format_data_request_context, g_free);
- g_free (files);
+ WaitForSingleObject (clipboard_rdp->format_data_request_received_event,
+ INFINITE);
+ clipboard_rdp->server_format_data_request_id = 0;
+ ResetEvent (clipboard_rdp->format_data_request_received_event);
+ SetEvent (clipboard_rdp->completed_format_data_request_event);
- clipboard_rdp->has_file_list = TRUE;
- if (g_hash_table_lookup_extended (clipboard_rdp->serial_entry_table,
- GUINT_TO_POINTER (serial),
- NULL, (gpointer *) &entry))
- entry->has_file_list = TRUE;
- }
- }
- if (!success || !dst_data)
- g_warning ("[RDP.CLIPRDR] Converting clipboard content failed");
- }
- else
- {
- dst_data = g_steal_pointer (&src_data);
- dst_size = src_size;
- }
+ return G_SOURCE_REMOVE;
}
- format_data_response.msgType = CB_FORMAT_DATA_RESPONSE;
- format_data_response.msgFlags = dst_data ? CB_RESPONSE_OK : CB_RESPONSE_FAIL;
- format_data_response.dataLen = dst_size;
- format_data_response.requestedFormatData = dst_data;
-
- cliprdr_context->ServerFormatDataResponse (cliprdr_context,
- &format_data_response);
-
- g_free (src_data);
- g_free (dst_data);
- g_free (request_context);
+ grd_clipboard_request_server_content_for_mime_type_async (clipboard,
+ mime_type);
WaitForSingleObject (clipboard_rdp->format_data_request_received_event,
INFINITE);
clipboard_rdp->server_format_data_request_id = 0;
ResetEvent (clipboard_rdp->format_data_request_received_event);
- SetEvent (clipboard_rdp->completed_format_data_request_event);
return G_SOURCE_REMOVE;
}
@@ -1686,8 +1723,11 @@ cliprdr_client_format_data_request (CliprdrServerContext *cliprdr_c
request_context->needs_null_terminator = needs_null_terminator;
request_context->needs_conversion = needs_conversion;
+ g_assert (!clipboard_rdp->format_data_request_context);
+ clipboard_rdp->format_data_request_context = request_context;
+
clipboard_rdp->server_format_data_request_id =
- g_idle_add (request_server_format_data, request_context);
+ g_idle_add (request_server_format_data, clipboard_rdp);
SetEvent (clipboard_rdp->format_data_request_received_event);
return CHANNEL_RC_OK;
@@ -2028,6 +2068,7 @@ grd_clipboard_rdp_dispose (GObject *object)
if (clipboard_rdp->clipboard_retrieval_id)
g_clear_pointer (&clipboard_rdp->clipboard_retrieval_context.entry, g_free);
+ g_clear_pointer (&clipboard_rdp->format_data_request_context, g_free);
g_clear_pointer (&clipboard_rdp->queued_server_formats, g_list_free);
g_clear_pointer (&clipboard_rdp->pending_server_formats, g_list_free);
g_hash_table_foreach_remove (clipboard_rdp->format_data_cache,
@@ -2155,4 +2196,6 @@ grd_clipboard_rdp_class_init (GrdClipboardRdpClass *klass)
grd_clipboard_rdp_update_client_mime_type_list;
clipboard_class->request_client_content_for_mime_type =
grd_clipboard_rdp_request_client_content_for_mime_type;
+ clipboard_class->submit_requested_server_content =
+ grd_clipboard_rdp_submit_requested_server_content;
}
diff --git a/src/grd-clipboard-vnc.c b/src/grd-clipboard-vnc.c
index 9e1ce04..d0a8df4 100644
--- a/src/grd-clipboard-vnc.c
+++ b/src/grd-clipboard-vnc.c
@@ -34,38 +34,6 @@ struct _GrdClipboardVnc
G_DEFINE_TYPE (GrdClipboardVnc, grd_clipboard_vnc, GRD_TYPE_CLIPBOARD);
-static void
-update_vnc_clipboard (GrdClipboardVnc *clipboard_vnc,
- GrdMimeType text_mime_type)
-{
- GrdClipboard *clipboard = GRD_CLIPBOARD (clipboard_vnc);
- g_autoptr (GError) error = NULL;
- uint8_t *src_data;
- uint32_t src_size;
- char *dst_data;
-
- src_data = grd_clipboard_request_server_content_for_mime_type (clipboard,
- text_mime_type,
- &src_size);
- if (!src_data)
- return;
-
- dst_data = g_convert ((char *) src_data, src_size,
- "iso8859-1", "utf-8",
- NULL, NULL, &error);
- if (!dst_data)
- {
- g_warning ("[VNC.Clipboard] Failed to convert clipboard content: %s",
- error->message);
- return;
- }
-
- grd_session_vnc_set_client_clipboard_text (clipboard_vnc->session_vnc,
- dst_data, strlen (dst_data));
-
- g_free (dst_data);
-}
-
static void
grd_clipboard_vnc_update_client_mime_type_list (GrdClipboard *clipboard,
GList *mime_type_list)
@@ -104,7 +72,8 @@ grd_clipboard_vnc_update_client_mime_type_list (GrdClipboard *clipboard,
{
g_clear_pointer (&clipboard_vnc->clipboard_utf8_string, g_free);
- update_vnc_clipboard (clipboard_vnc, mime_type);
+ grd_clipboard_request_server_content_for_mime_type_async (clipboard,
+ mime_type);
}
g_list_free (mime_type_list);
@@ -122,6 +91,36 @@ grd_clipboard_vnc_request_client_content_for_mime_type (GrdClipboard *clipbo
return g_memdup2 (clipboard_vnc->clipboard_utf8_string, *size);
}
+static void
+grd_clipboard_vnc_submit_requested_server_content (GrdClipboard *clipboard,
+ uint8_t *src_data,
+ uint32_t src_size)
+{
+ GrdClipboardVnc *clipboard_vnc = GRD_CLIPBOARD_VNC (clipboard);
+ g_autoptr (GError) error = NULL;
+ char *dst_data;
+
+ if (!src_data)
+ return;
+
+ dst_data = g_convert ((char *) src_data, src_size,
+ "iso8859-1", "utf-8",
+ NULL, NULL, &error);
+ if (!dst_data)
+ {
+ g_warning ("[VNC.Clipboard] Failed to convert clipboard content: %s",
+ error->message);
+ g_free (src_data);
+ return;
+ }
+
+ grd_session_vnc_set_client_clipboard_text (clipboard_vnc->session_vnc,
+ dst_data, strlen (dst_data));
+
+ g_free (src_data);
+ g_free (dst_data);
+}
+
void
grd_clipboard_vnc_maybe_enable_clipboard (GrdClipboardVnc *clipboard_vnc)
{
@@ -203,4 +202,6 @@ grd_clipboard_vnc_class_init (GrdClipboardVncClass *klass)
grd_clipboard_vnc_update_client_mime_type_list;
clipboard_class->request_client_content_for_mime_type =
grd_clipboard_vnc_request_client_content_for_mime_type;
+ clipboard_class->submit_requested_server_content =
+ grd_clipboard_vnc_submit_requested_server_content;
}
diff --git a/src/grd-clipboard.c b/src/grd-clipboard.c
index 0fc8ca6..cbc4702 100644
--- a/src/grd-clipboard.c
+++ b/src/grd-clipboard.c
@@ -75,27 +75,30 @@ grd_clipboard_update_server_mime_type_list (GrdClipboard *clipboard,
g_list_free (mime_type_tables);
}
-uint8_t *
-grd_clipboard_request_server_content_for_mime_type (GrdClipboard *clipboard,
- GrdMimeType mime_type,
- uint32_t *size)
+void
+grd_clipboard_request_server_content_for_mime_type_async (GrdClipboard *clipboard,
+ GrdMimeType mime_type)
{
+ GrdClipboardClass *klass = GRD_CLIPBOARD_GET_CLASS (clipboard);
GrdClipboardPrivate *priv = grd_clipboard_get_instance_private (clipboard);
uint8_t *data;
+ uint32_t size;
+
+ if (!klass->submit_requested_server_content)
+ return;
- *size = 0;
if (!priv->enabled)
- return NULL;
+ return;
g_debug ("Clipboard[SelectionRead]: Requesting data from servers clipboard"
" (mime type: %s)", grd_mime_type_to_string (mime_type));
- data = grd_session_selection_read (priv->session, mime_type, size);
+ data = grd_session_selection_read (priv->session, mime_type, &size);
if (data)
g_debug ("Clipboard[SelectionRead]: Request successful");
else
g_debug ("Clipboard[SelectionRead]: Request failed");
- return data;
+ klass->submit_requested_server_content (clipboard, data, size);
}
void
diff --git a/src/grd-clipboard.h b/src/grd-clipboard.h
index 2e38d24..93249d0 100644
--- a/src/grd-clipboard.h
+++ b/src/grd-clipboard.h
@@ -38,14 +38,16 @@ struct _GrdClipboardClass
uint8_t *(*request_client_content_for_mime_type) (GrdClipboard *clipboard,
GrdMimeTypeTable *mime_type_table,
uint32_t *size);
+ void (*submit_requested_server_content) (GrdClipboard *clipboard,
+ uint8_t *data,
+ uint32_t size);
};
void grd_clipboard_update_server_mime_type_list (GrdClipboard *clipboard,
GList *mime_type_tables);
-uint8_t *grd_clipboard_request_server_content_for_mime_type (GrdClipboard *clipboard,
- GrdMimeType mime_type,
- uint32_t *size);
+void grd_clipboard_request_server_content_for_mime_type_async (GrdClipboard *clipboard,
+ GrdMimeType mime_type);
void grd_clipboard_initialize (GrdClipboard *clipboard,
GrdSession *session);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]