diff options
author | Giovanni Panozzo <giovanni@panozzo.it> | 2021-07-16 23:57:45 +0300 |
---|---|---|
committer | Giovanni Panozzo <giovanni@panozzo.it> | 2021-07-18 21:58:19 +0300 |
commit | aeaf5dec42dd7899a8679d6b7770ac8cb63bf121 (patch) | |
tree | 2d92291a345257b7629bcf53c3f1c7e914ad4d4f | |
parent | 575983eadcbe77b97f8777053194b72ed38d1b40 (diff) |
Step7fileclip2021
-rw-r--r-- | plugins/rdp/rdp_cliprdr.c | 31 | ||||
-rw-r--r-- | plugins/rdp/rdp_plugin.h | 5 | ||||
-rw-r--r-- | src/remmina_masterthread_exec.c | 3 | ||||
-rw-r--r-- | src/remmina_masterthread_exec.h | 2 | ||||
-rw-r--r-- | src/remmina_plugin_manager.c | 3 | ||||
-rw-r--r-- | src/remmina_protocol_widget.c | 19 | ||||
-rw-r--r-- | src/remmina_protocol_widget.h | 1 |
7 files changed, 61 insertions, 3 deletions
diff --git a/plugins/rdp/rdp_cliprdr.c b/plugins/rdp/rdp_cliprdr.c index 7ba6aaa9b..f78b08c8b 100644 --- a/plugins/rdp/rdp_cliprdr.c +++ b/plugins/rdp/rdp_cliprdr.c @@ -45,6 +45,11 @@ #define CLIPBOARD_TRANSFER_WAIT_TIME 6 +enum { + REMMINA_RDP_CLIPRDR_FORMAT_COPIED_FILES = 0x34670001 // use an ID that can't conflict with RDP clipboard format like CF_TEXT. +}; + + UINT32 remmina_rdp_cliprdr_get_format_from_gdkatom(GdkAtom atom) { TRACE_CALL(__func__); @@ -229,7 +234,7 @@ static UINT remmina_rdp_cliprdr_server_capabilities(CliprdrClientContext *contex caps = (const CLIPRDR_CAPABILITY_SET*) capsPtr; if (caps->capabilitySetType == CB_CAPSTYPE_GENERAL) { generalCaps = (const CLIPRDR_GENERAL_CAPABILITY_SET*) caps; - if (generalCaps->generalFlags & CB_STREAM_FILECLIP_ENABLED) { + if (generalCaps->generalFlags & CB_STREAM_FILECLIP_ENABLED) { REMMINA_PLUGIN_DEBUG("Remote RDP server supports CB_STREAM_FILECLIP_ENABLED"); clipboard->streams_supported = TRUE; } @@ -254,11 +259,14 @@ static UINT remmina_rdp_cliprdr_server_format_list(CliprdrClientContext *context CLIPRDR_FORMAT *format; CLIPRDR_FORMAT_LIST_RESPONSE formatListResponse; const char *serverFormatName; + gboolean have_files; int has_dib_level = 0; int i; + have_files = FALSE; + clipboard = (rfClipboard *)context->custom; gp = clipboard->rfi->protocol_widget; GtkTargetList *list = gtk_target_list_new(NULL, 0); @@ -303,7 +311,21 @@ static UINT remmina_rdp_cliprdr_server_format_list(CliprdrClientContext *context serverFormatName = "CF_LOCALE"; } else if (format->formatId == CF_METAFILEPICT) { serverFormatName = "CF_METAFILEPICT"; + } else if (format->formatName && strcmp(format->formatName, "FileGroupDescriptorW") == 0) { + /* Files (1 of 3). Put a special reference inside the clipboard and take note of formatId */ + GdkAtom atom; + have_files = TRUE; + atom = gdk_atom_intern("x-special/remmina-copied-files", TRUE); + gtk_target_list_add(list, atom, 0, REMMINA_RDP_CLIPRDR_FORMAT_COPIED_FILES); + clipboard->filegroupdescriptorw_id = format->formatId; + } else if (format->formatName && strcmp(format->formatName, "FileContents") == 0) { + /* Files (2 of 3). take note of formatId for FileContents*/ + clipboard->filecontents_id = format->formatId; + } else if (format->formatName && strcmp(format->formatName, "Preferred DropEffect") == 0) { + /* Files (3 of 3). take note of formatId for Preferred DropEffect */ + clipboard->preferred_dropeffect_id = format->formatId; } + REMMINA_PLUGIN_DEBUG("the server has clipboard format %d: %s", format->formatId, serverFormatName); } @@ -316,7 +338,7 @@ static UINT remmina_rdp_cliprdr_server_format_list(CliprdrClientContext *context gtk_target_list_add(list, atom, 0, CF_DIB); } - /* Now we tell GTK to change the local keyboard calling gtk_clipboard_set_with_owner + /* Now we tell GTK to change the local clipboard calling gtk_clipboard_set_with_owner * via REMMINA_RDP_UI_CLIPBOARD_SET_DATA * GTK will immediately fire an "owner-change" event, that we should ignore */ @@ -327,6 +349,11 @@ static UINT remmina_rdp_cliprdr_server_format_list(CliprdrClientContext *context ui->clipboard.targetlist = list; remmina_rdp_event_queue_ui_sync_retint(gp, ui); + /* Signal the protocol widget that whe have files or we don't */ + printf("GIO: remmina_plugin_service = %p\n",remmina_plugin_service); + printf("GIO: gp = %p\n",gp); + remmina_plugin_service->protocol_plugin_emit_signal_with_int_param(gp, "pastefiles-status", have_files ? -1 : -2); + /* Send FormatListResponse to server */ formatListResponse.msgType = CB_FORMAT_LIST_RESPONSE; diff --git a/plugins/rdp/rdp_plugin.h b/plugins/rdp/rdp_plugin.h index 1a96f4e68..a925dafd1 100644 --- a/plugins/rdp/rdp_plugin.h +++ b/plugins/rdp/rdp_plugin.h @@ -124,6 +124,11 @@ struct rf_clipboard { gboolean file_formats_registered; UINT32 file_capability_flags; + UINT32 filegroupdescriptorw_id; + UINT32 filecontents_id; + UINT32 preferred_dropeffect_id; + + }; typedef struct rf_clipboard rfClipboard; diff --git a/src/remmina_masterthread_exec.c b/src/remmina_masterthread_exec.c index 36de9266e..f0dead8e6 100644 --- a/src/remmina_masterthread_exec.c +++ b/src/remmina_masterthread_exec.c @@ -72,6 +72,9 @@ static gboolean remmina_masterthread_exec_callback(RemminaMTExecData *d) case FUNC_PROTOCOLWIDGET_EMIT_SIGNAL: remmina_protocol_widget_emit_signal(d->p.protocolwidget_emit_signal.gp, d->p.protocolwidget_emit_signal.signal_name); break; + case FUNC_PROTOCOLWIDGET_EMIT_SIGNAL_WITH_PARAM: + remmina_protocol_widget_emit_signal_with_int_param(d->p.protocolwidget_emit_signal.gp, d->p.protocolwidget_emit_signal.signal_name, d->p.protocolwidget_emit_signal.int_param); + break; case FUNC_PROTOCOLWIDGET_MPPROGRESS: d->p.protocolwidget_mpprogress.ret_mp = remmina_protocol_widget_mpprogress(d->p.protocolwidget_mpprogress.cnnobj, d->p.protocolwidget_mpprogress.message, d->p.protocolwidget_mpprogress.response_callback, d->p.protocolwidget_mpprogress.response_callback_data); diff --git a/src/remmina_masterthread_exec.h b/src/remmina_masterthread_exec.h index 63eb06e08..a9169ef85 100644 --- a/src/remmina_masterthread_exec.h +++ b/src/remmina_masterthread_exec.h @@ -46,6 +46,7 @@ typedef struct remmina_masterthread_exec_data { FUNC_FTP_CLIENT_UPDATE_TASK, FUNC_FTP_CLIENT_GET_WAITING_TASK, FUNC_SFTP_CLIENT_CONFIRM_RESUME, FUNC_PROTOCOLWIDGET_EMIT_SIGNAL, + FUNC_PROTOCOLWIDGET_EMIT_SIGNAL_WITH_PARAM, FUNC_PROTOCOLWIDGET_MPPROGRESS, FUNC_PROTOCOLWIDGET_MPDESTROY, FUNC_PROTOCOLWIDGET_MPSHOWRETRY, @@ -80,6 +81,7 @@ typedef struct remmina_masterthread_exec_data { struct { RemminaProtocolWidget * gp; const gchar * signal_name; + int int_param; } protocolwidget_emit_signal; struct { RemminaConnectionObject * cnnobj; diff --git a/src/remmina_plugin_manager.c b/src/remmina_plugin_manager.c index fa3a41eb6..5b919d661 100644 --- a/src/remmina_plugin_manager.c +++ b/src/remmina_plugin_manager.c @@ -250,7 +250,8 @@ RemminaPluginService remmina_plugin_manager_service = remmina_masterthread_exec_is_main_thread, remmina_gtksocket_available, remmina_protocol_widget_get_profile_remote_width, - remmina_protocol_widget_get_profile_remote_height + remmina_protocol_widget_get_profile_remote_height, + remmina_protocol_widget_emit_signal_with_int_param }; const char *get_filename_ext(const char *filename) { diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c index 7bc063de0..33820c9ee 100644 --- a/src/remmina_protocol_widget.c +++ b/src/remmina_protocol_widget.c @@ -743,6 +743,25 @@ gboolean remmina_protocol_widget_unmap_event(RemminaProtocolWidget *gp) return gp->priv->plugin->unmap_event(gp); } +void remmina_protocol_widget_emit_signal_with_int_param(RemminaProtocolWidget* gp, const gchar* signal_name, int int_param) +{ + TRACE_CALL(__func__); + + if ( !remmina_masterthread_exec_is_main_thread() ) { + /* Allow the execution of this function from a non main thread */ + RemminaMTExecData *d; + d = (RemminaMTExecData*)g_malloc( sizeof(RemminaMTExecData) ); + d->func = FUNC_PROTOCOLWIDGET_EMIT_SIGNAL_WITH_PARAM; + d->p.protocolwidget_emit_signal.signal_name = signal_name; + d->p.protocolwidget_emit_signal.gp = gp; + d->p.protocolwidget_emit_signal.int_param = int_param; + remmina_masterthread_exec_and_wait(d); + g_free(d); + return; + } + g_signal_emit_by_name(G_OBJECT(gp), signal_name, int_param); +} + void remmina_protocol_widget_emit_signal(RemminaProtocolWidget *gp, const gchar *signal_name) { TRACE_CALL(__func__); diff --git a/src/remmina_protocol_widget.h b/src/remmina_protocol_widget.h index 79f08b818..fe450ebed 100644 --- a/src/remmina_protocol_widget.h +++ b/src/remmina_protocol_widget.h @@ -116,6 +116,7 @@ void remmina_protocol_widget_call_feature_by_type(RemminaProtocolWidget *gp, Rem void remmina_protocol_widget_call_feature_by_ref(RemminaProtocolWidget *gp, const RemminaProtocolFeature *feature); /* Provide thread-safe way to emit signals */ void remmina_protocol_widget_emit_signal(RemminaProtocolWidget *gp, const gchar *signal_name); +void remmina_protocol_widget_emit_signal_with_int_param(RemminaProtocolWidget* gp, const gchar* signal_name, int int_param); void remmina_protocol_widget_register_hostkey(RemminaProtocolWidget *gp, GtkWidget *widget); typedef gboolean (*RemminaHostkeyFunc)(RemminaProtocolWidget *gp, guint keyval, gboolean release); |