diff options
-rw-r--r-- | plugins/spice/spice_plugin.c | 9 | ||||
-rw-r--r-- | src/remmina_message_panel.c | 25 | ||||
-rw-r--r-- | src/remmina_message_panel.h | 2 | ||||
-rw-r--r-- | src/remmina_protocol_widget.c | 138 |
4 files changed, 132 insertions, 42 deletions
diff --git a/plugins/spice/spice_plugin.c b/plugins/spice/spice_plugin.c index 771daa216..1e8a656e6 100644 --- a/plugins/spice/spice_plugin.c +++ b/plugins/spice/spice_plugin.c @@ -234,11 +234,13 @@ static gboolean remmina_plugin_spice_ask_auth(RemminaProtocolWidget *gp) ret = remmina_plugin_service->protocol_plugin_init_authpwd(gp, REMMINA_AUTHPWD_TYPE_PROTOCOL, !disablepasswordstoring); if (ret == GTK_RESPONSE_OK) { + gchar *password = remmina_plugin_service->protocol_plugin_init_get_password(gp); + if (remmina_plugin_service->protocol_plugin_init_get_savepassword(gp)) + remmina_plugin_service->file_set_string( remminafile, "password", password ); g_object_set(gpdata->session, "password", - remmina_plugin_service->protocol_plugin_init_get_password(gp), + password, NULL); - return TRUE; }else { return FALSE; @@ -269,7 +271,8 @@ static void remmina_plugin_spice_main_channel_event_cb(SpiceChannel *channel, Sp if (remmina_plugin_spice_ask_auth(gp)) { remmina_plugin_spice_open_connection(gp); }else{ - remmina_plugin_service->protocol_plugin_set_error(gp, _("Invalid password.")); + /* Connection is cancelled by the user by clicking cancel on auth panel, close it without showing errors */ + // remmina_plugin_service->protocol_plugin_set_error(gp, _("Invalid password.")); remmina_plugin_spice_close_connection(gp); } break; diff --git a/src/remmina_message_panel.c b/src/remmina_message_panel.c index fc90ddba0..392ee4654 100644 --- a/src/remmina_message_panel.c +++ b/src/remmina_message_panel.c @@ -54,6 +54,14 @@ typedef struct } RemminaMessagePanelPrivate; G_DEFINE_TYPE_WITH_PRIVATE (RemminaMessagePanel, remmina_message_panel, GTK_TYPE_BOX) + +enum { + RESPONSE, + LAST_SIGNAL +}; + +static guint messagepanel_signals[LAST_SIGNAL]; + static const gchar btn_response_key[] = "btn_response"; static void remmina_message_panel_init (RemminaMessagePanel *mp) @@ -65,6 +73,16 @@ static void remmina_message_panel_class_init(RemminaMessagePanelClass *class) { TRACE_CALL(__func__); // class->transform_text = my_app_label_real_transform_text; + + messagepanel_signals[RESPONSE] = + g_signal_new ("response", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (RemminaMessagePanelClass, response), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_INT); } RemminaMessagePanel *remmina_message_panel_new() @@ -153,6 +171,7 @@ void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar * gtk_widget_show_all(GTK_WIDGET(mp)); } + void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data) { /* @@ -445,7 +464,7 @@ void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePan priv->response_callback = response_callback; priv->response_callback_data = response_callback_data; - g_signal_connect_swapped (username_entry, "activate", (GCallback)gtk_widget_grab_focus, password_entry); + if (username_entry) g_signal_connect_swapped (username_entry, "activate", (GCallback)gtk_widget_grab_focus, password_entry); g_signal_connect_swapped (password_entry, "activate", (GCallback)gtk_widget_grab_focus, button_ok); g_object_set_data(G_OBJECT(button_cancel), btn_response_key, (void *)GTK_RESPONSE_CANCEL); g_signal_connect(G_OBJECT(button_cancel), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp); @@ -760,4 +779,8 @@ gchar* remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int ent return gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->w[entryid])); } +void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id) +{ + g_signal_emit(mp, messagepanel_signals[RESPONSE], 0, response_id); +} diff --git a/src/remmina_message_panel.h b/src/remmina_message_panel.h index 2102890fb..a9de12bcf 100644 --- a/src/remmina_message_panel.h +++ b/src/remmina_message_panel.h @@ -43,6 +43,7 @@ G_DECLARE_DERIVABLE_TYPE(RemminaMessagePanel, remmina_message_panel, REMMINA, ME struct _RemminaMessagePanelClass { GtkBoxClass parent_class; + void (* response) (RemminaMessagePanel *mp, gint response_id); }; enum { @@ -80,6 +81,7 @@ void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid); void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename); gchar* remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid); +void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id); G_END_DECLS diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c index d53ba2bdb..eff3c4664 100644 --- a/src/remmina_protocol_widget.c +++ b/src/remmina_protocol_widget.c @@ -1067,6 +1067,7 @@ struct remmina_protocol_widget_dialog_mt_data_t { char *str1; enum panel_type dtype; unsigned pflags; + gboolean called_from_subthread; /* Running status */ pthread_mutex_t pt_mutex; pthread_cond_t pt_cond; @@ -1091,14 +1092,20 @@ static void authuserpwd_mt_cb(void *user_data, int button) d->gp->priv->clientkey = remmina_message_panel_field_get_filename(d->gp->priv->auth_message_panel, REMMINA_MESSAGE_PANEL_CLIENTKEYFILE); } } - /* Hide and destroy message panel, we can do it now because we are on the main thread */ - remmina_connection_object_destroy_message_panel(d->gp->cnnobj, d->gp->priv->auth_message_panel); - /* Awake the locked subthread */ - pthread_mutex_lock(&d->pt_mutex); + if (d->called_from_subthread) { + /* Hide and destroy message panel, we can do it now because we are on the main thread */ + remmina_connection_object_destroy_message_panel(d->gp->cnnobj, d->gp->priv->auth_message_panel); + + /* Awake the locked subthread, when called from subthread */ + pthread_mutex_lock(&d->pt_mutex); + pthread_cond_signal(&d->pt_cond); + pthread_mutex_unlock(&d->pt_mutex); + } else { + /* Signal completion, when called from main thread. Message panel will be destroyed by the caller */ + remmina_message_panel_response(d->gp->priv->auth_message_panel, button); + } - pthread_cond_signal(&d->pt_cond); - pthread_mutex_unlock(&d->pt_mutex); } static gboolean remmina_protocol_widget_dialog_mt_setup(gpointer user_data) @@ -1151,35 +1158,106 @@ static gboolean remmina_protocol_widget_dialog_mt_setup(gpointer user_data) return FALSE; } +typedef struct +{ + RemminaMessagePanel *mp; + GMainLoop *loop; + gint response; + gboolean destroyed; +} MpRunInfo; + +static void shutdown_loop (MpRunInfo *mpri) +{ + if (g_main_loop_is_running (mpri->loop)) + g_main_loop_quit (mpri->loop); +} + +static void run_response_handler(RemminaMessagePanel *mp, gint response_id, gpointer data) +{ + MpRunInfo *mpri = (MpRunInfo *)data; + mpri->response = response_id; + shutdown_loop(mpri); +} + +static void run_unmap_handler(RemminaMessagePanel *mp, gpointer data) +{ + MpRunInfo *mpri = (MpRunInfo *)data; + mpri->response = GTK_RESPONSE_CANCEL; + shutdown_loop(mpri); +} + +static void run_destroy_handler (RemminaMessagePanel *mp, gpointer data) +{ + MpRunInfo *mpri = (MpRunInfo *)data; + mpri->destroyed = TRUE; + mpri->response = GTK_RESPONSE_CANCEL; + shutdown_loop(mpri); +} + static int remmina_protocol_widget_dialog(enum panel_type dtype, RemminaProtocolWidget* gp, unsigned pflags, const char *str1) { struct remmina_protocol_widget_dialog_mt_data_t *d = (struct remmina_protocol_widget_dialog_mt_data_t*)g_malloc( sizeof(struct remmina_protocol_widget_dialog_mt_data_t) ); int rcbutton; - if (remmina_masterthread_exec_is_main_thread()) { - printf("REMMINA warning. %s should not be called from the master thread.\n", __func__); - } - d->gp = gp; d->pflags = pflags; d->dtype = dtype; d->str1 = g_strdup(str1); + d->called_from_subthread = FALSE; + + if (remmina_masterthread_exec_is_main_thread()) { + /* Run the MessagePanel in main thread, in a very similar way of gtk_dialog_run() */ + MpRunInfo mpri = { NULL, NULL, GTK_RESPONSE_CANCEL, FALSE }; + + gulong unmap_handler; + gulong destroy_handler; + gulong response_handler; + + remmina_protocol_widget_dialog_mt_setup(d); + + mpri.mp = d->gp->priv->auth_message_panel; + + if (!gtk_widget_get_visible(GTK_WIDGET(mpri.mp))) + gtk_widget_show(GTK_WIDGET(mpri.mp)); + response_handler = g_signal_connect (mpri.mp, "response", G_CALLBACK (run_response_handler), &mpri); + unmap_handler = g_signal_connect (mpri.mp, "unmap", G_CALLBACK (run_unmap_handler), &mpri); + destroy_handler = g_signal_connect (mpri.mp, "destroy", G_CALLBACK (run_destroy_handler),&mpri); + + g_object_ref(mpri.mp); + + mpri.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (mpri.loop); + g_main_loop_unref (mpri.loop); + + if (!mpri.destroyed) { + g_signal_handler_disconnect (mpri.mp, response_handler); + g_signal_handler_disconnect (mpri.mp, destroy_handler); + g_signal_handler_disconnect (mpri.mp, unmap_handler); + } + g_object_unref(mpri.mp); + + remmina_connection_object_destroy_message_panel(d->gp->cnnobj, d->gp->priv->auth_message_panel); + + rcbutton = mpri.response; + + } else { + d->called_from_subthread = TRUE; + // pthread_cleanup_push(ptcleanup, (void*)d); + pthread_cond_init(&d->pt_cond, NULL); + pthread_mutex_init(&d->pt_mutex, NULL); + g_idle_add(remmina_protocol_widget_dialog_mt_setup, d); + pthread_mutex_lock(&d->pt_mutex); + pthread_cond_wait(&d->pt_cond, &d->pt_mutex); + // pthread_cleanup_pop(0); + pthread_mutex_destroy(&d->pt_mutex); + pthread_cond_destroy(&d->pt_cond); + + rcbutton = d->rcbutton; + } - // pthread_cleanup_push(ptcleanup, (void*)d); - pthread_cond_init(&d->pt_cond, NULL); - pthread_mutex_init(&d->pt_mutex, NULL); - g_idle_add(remmina_protocol_widget_dialog_mt_setup, d); - pthread_mutex_lock(&d->pt_mutex); - pthread_cond_wait(&d->pt_cond, &d->pt_mutex); - // pthread_cleanup_pop(0); - pthread_mutex_destroy(&d->pt_mutex); - pthread_cond_destroy(&d->pt_cond); - - rcbutton = d->rcbutton; g_free(d->str1); g_free(d); - return rcbutton; } @@ -1583,22 +1661,6 @@ void remmina_protocol_widget_send_keys_signals(GtkWidget *widget, const guint *k void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget* gp) { TRACE_CALL(__func__); - GdkDisplay *display; -#if GTK_CHECK_VERSION(3, 20, 0) - /** @todo rename to "seat" */ - GdkSeat *seat; - GdkDevice *device; -#else - GdkDeviceManager *device_manager; - GdkDevice *device; -#endif - GdkScreen *screen; -#if GTK_CHECK_VERSION(3, 22, 0) - GdkMonitor *monitor; -#else - gint monitor; -#endif - gint x, y; GdkRectangle rect; gint w, h; gint wfile, hfile; |