Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for issue #744 #752

Merged
merged 1 commit into from
Jan 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions remmina-plugins/rdp/rdp_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ void remmina_rdp_event_update_rect(RemminaProtocolWidget* gp, gint x, gint y, gi
gtk_widget_queue_draw_area(rfi->drawing_area, x, y, w, h);
}

static gboolean remmina_rdp_event_update_scale_factor(RemminaProtocolWidget* gp)
static void remmina_rdp_event_update_scale_factor(RemminaProtocolWidget* gp)
{
TRACE_CALL("remmina_rdp_event_update_scale_factor");
GtkAllocation a;
Expand Down Expand Up @@ -260,8 +260,14 @@ static gboolean remmina_rdp_event_update_scale_factor(RemminaProtocolWidget* gp)
if ((gpwidth > 1) && (gpheight > 1))
gtk_widget_queue_draw_area(GTK_WIDGET(gp), 0, 0, gpwidth, gpheight);

rfi->scale_handler = 0;
}

static gboolean remmina_rdp_event_update_scale_factor_async(RemminaProtocolWidget* gp)
{
TRACE_CALL("remmina_rdp_event_update_scale_factor_async");
rfContext* rfi = GET_PLUGIN_DATA(gp);
rfi->scale_handler = 0;
remmina_rdp_event_update_scale_factor(gp);
return FALSE;
}

Expand Down Expand Up @@ -301,7 +307,7 @@ static gboolean remmina_rdp_event_on_configure(GtkWidget* widget, GdkEventConfig
if (rfi->scale_handler)
g_source_remove(rfi->scale_handler);

rfi->scale_handler = g_timeout_add(300, (GSourceFunc) remmina_rdp_event_update_scale_factor, gp);
rfi->scale_handler = g_timeout_add(300, (GSourceFunc) remmina_rdp_event_update_scale_factor_async, gp);

return FALSE;
}
Expand Down Expand Up @@ -743,6 +749,8 @@ static void remmina_rdp_event_connected(RemminaProtocolWidget* gp, RemminaPlugin
TRACE_CALL("remmina_rdp_event_connected");
rfContext* rfi = GET_PLUGIN_DATA(gp);

remmina_plugin_service->protocol_plugin_emit_signal(gp, "connect");

gtk_widget_realize(rfi->drawing_area);

remmina_rdp_event_create_cairo_surface(rfi);
Expand Down
14 changes: 6 additions & 8 deletions remmina-plugins/rdp/rdp_plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,6 @@ static BOOL remmina_rdp_post_connect(freerdp* instance)
freerdp_channels_post_connect(instance->context->channels, instance);
rfi->connected = True;

remmina_plugin_service->protocol_plugin_emit_signal(gp, "connect");

ui = g_new0(RemminaPluginRdpUiObject, 1);
ui->type = REMMINA_RDP_UI_CONNECTED;
rf_queue_ui(gp, ui);
Expand Down Expand Up @@ -475,8 +473,6 @@ static void remmina_rdp_main_loop(RemminaProtocolWidget* gp)
gchar buf[100];
rfContext* rfi = GET_PLUGIN_DATA(gp);



while (!freerdp_shall_disconnect(rfi->instance))
{
nCount = freerdp_get_event_handles(rfi->instance->context, &handles[0], 64);
Expand Down Expand Up @@ -960,7 +956,9 @@ static gpointer remmina_rdp_main_thread(gpointer data)
remmina_rdp_main(gp);
rfi->thread = 0;

IDLE_ADD((GSourceFunc) remmina_plugin_service->protocol_plugin_close_connection, gp);
/* Signal main thread that we closed the connection. But wait 200ms, because we may
* have outstaiding events to process in the meanwhile */
g_timeout_add(200, ((GSourceFunc) remmina_plugin_service->protocol_plugin_close_connection), gp);

return NULL;
}
Expand Down Expand Up @@ -1034,9 +1032,6 @@ static gboolean remmina_rdp_close_connection(RemminaProtocolWidget* gp)

}


remmina_plugin_service->protocol_plugin_emit_signal(gp, "disconnect");

if (instance)
{
if ( rfi->connected ) {
Expand Down Expand Up @@ -1089,6 +1084,9 @@ static gboolean remmina_rdp_close_connection(RemminaProtocolWidget* gp)
/* Remove instance->context from gp object data to avoid double free */
g_object_steal_data(G_OBJECT(gp), "plugin-data");

/* Now let remmina to complete its disconnection tasks */
remmina_plugin_service->protocol_plugin_emit_signal(gp, "disconnect");

return FALSE;
}

Expand Down
79 changes: 53 additions & 26 deletions remmina/src/remmina_connection_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ struct _RemminaConnectionHolder

gboolean hostkey_activated;
gboolean hostkey_used;

};

enum
Expand Down Expand Up @@ -264,13 +265,13 @@ static void remmina_connection_window_class_init(RemminaConnectionWindowClass* k

}

static void remmina_connection_holder_disconnect(RemminaConnectionHolder* cnnhld)
static void remmina_connection_holder_disconnect_current_page(RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_disconnect");
TRACE_CALL("remmina_connection_holder_disconnect_current_page");
DECLARE_CNNOBJ

/* Notify the RemminaProtocolWidget to disconnect, but not to close the window here.
The window will be destroyed in RemminaProtocolWidget "disconnect" signal */
/* Disconnects the connection which is currently in view in the notebook */

remmina_protocol_widget_close_connection(REMMINA_PROTOCOL_WIDGET(cnnobj->proto));
}

Expand Down Expand Up @@ -305,15 +306,35 @@ static void remmina_connection_holder_keyboard_grab(RemminaConnectionHolder* cnn
}
}

static void remmina_connection_window_close_all_connections(RemminaConnectionWindow* cnnwin)
{
RemminaConnectionWindowPriv* priv = cnnwin->priv;
GtkNotebook* notebook = GTK_NOTEBOOK(priv->notebook);
GtkWidget* w;
RemminaConnectionObject* cnnobj;
gint i, n;

if (GTK_IS_WIDGET(notebook))
{
n = gtk_notebook_get_n_pages(notebook);
for (i = n - 1; i >= 0; i--)
{
w = gtk_notebook_get_nth_page(notebook, i);
cnnobj = (RemminaConnectionObject*) g_object_get_data(G_OBJECT(w), "cnnobj");
/* Do close the connection on this tab */
remmina_protocol_widget_close_connection(REMMINA_PROTOCOL_WIDGET(cnnobj->proto));
}
}

}

static gboolean remmina_connection_window_delete_event(GtkWidget* widget, GdkEvent* event, gpointer data)
{
TRACE_CALL("remmina_connection_window_delete_event");
RemminaConnectionHolder* cnnhld = (RemminaConnectionHolder*) data;
RemminaConnectionWindowPriv* priv = cnnhld->cnnwin->priv;
RemminaConnectionObject* cnnobj;
GtkNotebook* notebook = GTK_NOTEBOOK(priv->notebook);
GtkWidget* dialog;
GtkWidget* w;
gint i, n;

n = gtk_notebook_get_n_pages(notebook);
Expand All @@ -327,17 +348,11 @@ static gboolean remmina_connection_window_delete_event(GtkWidget* widget, GdkEve
if (i != GTK_RESPONSE_YES)
return TRUE;
}
/* Just in case the connection already closed by the server before clicking yes */
if (GTK_IS_WIDGET(notebook))
{
n = gtk_notebook_get_n_pages(notebook);
for (i = n - 1; i >= 0; i--)
{
w = gtk_notebook_get_nth_page(notebook, i);
cnnobj = (RemminaConnectionObject*) g_object_get_data(G_OBJECT(w), "cnnobj");
remmina_protocol_widget_close_connection(REMMINA_PROTOCOL_WIDGET(cnnobj->proto));
}
}
remmina_connection_window_close_all_connections(cnnhld->cnnwin);

gtk_widget_destroy(GTK_WIDGET(cnnhld->cnnwin));
cnnhld->cnnwin = NULL;

return TRUE;
}

Expand Down Expand Up @@ -384,6 +399,7 @@ static void remmina_connection_window_destroy(GtkWidget* widget, RemminaConnecti
cnnhld->cnnwin->priv = NULL;
cnnhld->cnnwin = NULL;
}

}

gboolean remmina_connection_window_notify_widget_toolbar_placement(GtkWidget *widget, gpointer data)
Expand Down Expand Up @@ -1517,7 +1533,7 @@ static void remmina_connection_holder_toolbar_minimize(GtkWidget* widget, Remmin
static void remmina_connection_holder_toolbar_disconnect(GtkWidget* widget, RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_toolbar_disconnect");
remmina_connection_holder_disconnect(cnnhld);
remmina_connection_holder_disconnect_current_page(cnnhld);
}

static void remmina_connection_holder_toolbar_grab(GtkWidget* widget, RemminaConnectionHolder* cnnhld)
Expand Down Expand Up @@ -2502,12 +2518,16 @@ static void remmina_connection_holder_on_page_removed(GtkNotebook* notebook, Gtk
RemminaConnectionHolder* cnnhld)
{
TRACE_CALL("remmina_connection_holder_on_page_removed");

if (!cnnhld->cnnwin)
return;

if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(cnnhld->cnnwin->priv->notebook)) <= 0)
{
gtk_widget_destroy(GTK_WIDGET(cnnhld->cnnwin));
cnnhld->cnnwin = NULL;
g_free(cnnhld);
}

}

GtkNotebook*
Expand Down Expand Up @@ -3066,7 +3086,7 @@ static gboolean remmina_connection_window_hostkey_func(RemminaProtocolWidget* gp
}
else if (keyval == remmina_pref.shortcutkey_disconnect)
{
remmina_connection_holder_disconnect(cnnhld);
remmina_connection_holder_disconnect_current_page(cnnhld);
}
else if (keyval == remmina_pref.shortcutkey_toolbar)
{
Expand Down Expand Up @@ -3218,6 +3238,18 @@ static void remmina_connection_object_on_disconnect(RemminaProtocolWidget* gp, R
TRACE_CALL("remmina_connection_object_on_disconnect");
RemminaConnectionHolder* cnnhld = cnnobj->cnnhld;
GtkWidget* dialog;
GtkWidget* pparent;


/* Detach the protocol widget from the notebook now, or we risk that a
* window delete will destroy cnnobj->proto before we complete disconnection.
*/
pparent = gtk_widget_get_parent(cnnobj->proto);
if (pparent != NULL)
{
g_object_ref(cnnobj->proto);
gtk_container_remove(GTK_CONTAINER(pparent), cnnobj->proto);
}

cnnobj->connected = FALSE;

Expand All @@ -3237,6 +3269,7 @@ static void remmina_connection_object_on_disconnect(RemminaProtocolWidget* gp, R
}
}
remmina_file_free(cnnobj->remmina_file);
cnnobj->remmina_file = NULL;

if (remmina_protocol_widget_has_error(gp))
{
Expand All @@ -3247,12 +3280,6 @@ static void remmina_connection_object_on_disconnect(RemminaProtocolWidget* gp, R
remmina_widget_pool_register(dialog);
}

if (cnnobj->window)
{
gtk_widget_destroy(cnnobj->window);
cnnobj->window = NULL;
}

if (cnnhld && cnnhld->cnnwin && cnnobj->scrolled_container)
{
gtk_notebook_remove_page(
Expand Down
7 changes: 5 additions & 2 deletions remmina/src/remmina_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@

static gboolean cb_closewidget(GtkWidget *widget, gpointer data)
{
gtk_widget_destroy(widget);
TRACE_CALL("cb_closewidget");
/* The correct way to close a remmina_connection_window is to send
* it a "delete-event" signal. Simply destroying it will not close
* all network connections */
g_signal_emit_by_name(G_OBJECT(widget), "delete-event", NULL);
return TRUE;
}

void remmina_exec_exitremmina()
{
TRACE_CALL("remmina_exec_exitremmina");

int n;

/* Destroy all widgets, main window included */
Expand Down
3 changes: 3 additions & 0 deletions remmina/src/remmina_masterthread_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ static gboolean remmina_masterthread_exec_callback(RemminaMTExecData *d)
case FUNC_FTP_CLIENT_GET_WAITING_TASK:
d->p.ftp_client_get_waiting_task.retval = remmina_ftp_client_get_waiting_task( d->p.ftp_client_get_waiting_task.client );
break;
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_SFTP_CLIENT_CONFIRM_RESUME:
#ifdef HAVE_LIBSSH
d->p.sftp_client_confirm_resume.retval = remmina_sftp_client_confirm_resume( d->p.sftp_client_confirm_resume.client,
Expand Down
6 changes: 6 additions & 0 deletions remmina/src/remmina_masterthread_exec.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ typedef struct remmina_masterthread_exec_data
FUNC_DIALOG_CERT, FUNC_DIALOG_CERTCHANGED, FUNC_DIALOG_AUTHX509,
FUNC_FTP_CLIENT_UPDATE_TASK, FUNC_FTP_CLIENT_GET_WAITING_TASK,
FUNC_SFTP_CLIENT_CONFIRM_RESUME,
FUNC_PROTOCOLWIDGET_EMIT_SIGNAL,
FUNC_VTE_TERMINAL_SET_ENCODING_AND_PTY
} func;

Expand Down Expand Up @@ -133,6 +134,11 @@ typedef struct remmina_masterthread_exec_data
RemminaFTPClient *client;
RemminaFTPTask* retval;
} ftp_client_get_waiting_task;
struct
{
RemminaProtocolWidget* gp;
const gchar* signal_name;
} protocolwidget_emit_signal;
#if defined (HAVE_LIBSSH) && defined (HAVE_LIBVTE)
struct
{
Expand Down
31 changes: 18 additions & 13 deletions remmina/src/remmina_protocol_widget.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,11 @@ static void remmina_protocol_widget_destroy(RemminaProtocolWidget* gp, gpointer
TRACE_CALL("remmina_protocol_widget_destroy");
remmina_protocol_widget_hide_init_dialog(gp);
g_free(gp->priv->features);
gp->priv->features = NULL;
g_free(gp->priv->error_message);
gp->priv->error_message = NULL;
g_free(gp->priv);
gp->priv = NULL;
}

static void remmina_protocol_widget_connect(RemminaProtocolWidget* gp, gpointer data)
Expand Down Expand Up @@ -427,23 +430,25 @@ void remmina_protocol_widget_send_keystrokes(RemminaProtocolWidget* gp, GtkMenuI
return;
}

static gboolean remmina_protocol_widget_emit_signal_timeout(gpointer user_data)
{
TRACE_CALL("remmina_protocol_widget_emit_signal_timeout");
RemminaProtocolWidgetSignalData* data = (RemminaProtocolWidgetSignalData*) user_data;
g_signal_emit_by_name(G_OBJECT(data->gp), data->signal_name);
g_free(data);
return FALSE;
}

void remmina_protocol_widget_emit_signal(RemminaProtocolWidget* gp, const gchar* signal_name)
{
TRACE_CALL("remmina_protocol_widget_emit_signal");
RemminaProtocolWidgetSignalData* data;
data = g_new(RemminaProtocolWidgetSignalData, 1);
data->gp = gp;
data->signal_name = signal_name;
TIMEOUT_ADD(0, remmina_protocol_widget_emit_signal_timeout, data);

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;
d->p.protocolwidget_emit_signal.signal_name = signal_name;
d->p.protocolwidget_emit_signal.gp = gp;
remmina_masterthread_exec_and_wait(d);
g_free(d);
return;
}
g_signal_emit_by_name(G_OBJECT(gp), signal_name);

}

const RemminaProtocolFeature* remmina_protocol_widget_get_features(RemminaProtocolWidget* gp)
Expand Down
15 changes: 14 additions & 1 deletion remmina/src/remmina_widget_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,29 @@ gint remmina_widget_pool_foreach(RemminaWidgetPoolForEachFunc callback, gpointer
GtkWidget *widget;
gint i;
gint n = 0;
GPtrArray *wpcpy = NULL;

if (remmina_widget_pool == NULL)
return 0;

/* Make a copy of remmina_widget_pool, so we can survive when callback()
* remove an element from remmina_widget_pool */

wpcpy = g_ptr_array_sized_new(remmina_widget_pool->len);

for (i = 0; i < remmina_widget_pool->len; i++)
g_ptr_array_add(wpcpy, g_ptr_array_index(remmina_widget_pool, i));

/* Scan the remmina_widget_pool and call callbac() on every element */
for (i = 0; i < wpcpy->len; i++)
{
widget = GTK_WIDGET(g_ptr_array_index(remmina_widget_pool, i));
widget = GTK_WIDGET(g_ptr_array_index(wpcpy, i));
if (callback(widget, data))
n++;
}

/* Free the copy */
g_ptr_array_unref(wpcpy);
return n;
}