Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/Remmina/Remmina.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Panozzo <giovanni@panozzo.it>2021-07-16 23:57:45 +0300
committerGiovanni Panozzo <giovanni@panozzo.it>2021-07-18 21:58:19 +0300
commitaeaf5dec42dd7899a8679d6b7770ac8cb63bf121 (patch)
tree2d92291a345257b7629bcf53c3f1c7e914ad4d4f
parent575983eadcbe77b97f8777053194b72ed38d1b40 (diff)
-rw-r--r--plugins/rdp/rdp_cliprdr.c31
-rw-r--r--plugins/rdp/rdp_plugin.h5
-rw-r--r--src/remmina_masterthread_exec.c3
-rw-r--r--src/remmina_masterthread_exec.h2
-rw-r--r--src/remmina_plugin_manager.c3
-rw-r--r--src/remmina_protocol_widget.c19
-rw-r--r--src/remmina_protocol_widget.h1
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);