[gnome-remote-desktop] rdp-display-control: Tear down channel when client does not support it
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-remote-desktop] rdp-display-control: Tear down channel when client does not support it
- Date: Wed, 10 Aug 2022 10:10:19 +0000 (UTC)
commit b5d201c5a07c4c69881aa347d8f2374e975c8967
Author: Pascal Nowack <Pascal Nowack gmx de>
Date: Wed Jun 8 14:47:37 2022 +0200
rdp-display-control: Tear down channel when client does not support it
With the tear down handling now been hooked up, tear down the display
control channel, when the client does not support it.
There is no reason to keep the class instance, when the DVC creation
failed. It is just a waste of resources.
src/grd-rdp-display-control.c | 145 ++++++++++++++++++++++++++++++++++--------
1 file changed, 119 insertions(+), 26 deletions(-)
---
diff --git a/src/grd-rdp-display-control.c b/src/grd-rdp-display-control.c
index 62a40154..c5e01ea7 100644
--- a/src/grd-rdp-display-control.c
+++ b/src/grd-rdp-display-control.c
@@ -32,11 +32,78 @@ struct _GrdRdpDisplayControl
gboolean channel_opened;
gboolean channel_unavailable;
+ uint32_t channel_id;
+ uint32_t dvc_subscription_id;
+ gboolean subscribed_status;
+
GrdSessionRdp *session_rdp;
+
+ GSource *channel_teardown_source;
};
G_DEFINE_TYPE (GrdRdpDisplayControl, grd_rdp_display_control, G_TYPE_OBJECT)
+void
+grd_rdp_display_control_maybe_init (GrdRdpDisplayControl *display_control)
+{
+ DispServerContext *disp_context;
+
+ if (display_control->channel_opened || display_control->channel_unavailable)
+ return;
+
+ if (WaitForSingleObject (display_control->stop_event, 0) == WAIT_OBJECT_0)
+ return;
+
+ disp_context = display_control->disp_context;
+ if (disp_context->Open (disp_context))
+ {
+ g_warning ("[RDP.DISP] Failed to open channel. Terminating protocol");
+ display_control->channel_unavailable = TRUE;
+ g_source_set_ready_time (display_control->channel_teardown_source, 0);
+ return;
+ }
+ display_control->channel_opened = TRUE;
+}
+
+static void
+dvc_creation_status (gpointer user_data,
+ int32_t creation_status)
+{
+ GrdRdpDisplayControl *display_control = user_data;
+ DispServerContext *disp_context = display_control->disp_context;
+
+ if (creation_status < 0)
+ {
+ g_debug ("[RDP.DISP] Failed to open channel (CreationStatus %i). "
+ "Terminating protocol", creation_status);
+ g_source_set_ready_time (display_control->channel_teardown_source, 0);
+ return;
+ }
+
+ g_debug ("[RDP.DISP] Channel opened successfully. "
+ "Ready for receiving new monitor layouts");
+ disp_context->DisplayControlCaps (disp_context);
+}
+
+static BOOL
+disp_channel_id_assigned (DispServerContext *disp_context,
+ uint32_t channel_id)
+{
+ GrdRdpDisplayControl *display_control = disp_context->custom;
+
+ g_debug ("[RDP.DISP] DVC channel id assigned to id %u", channel_id);
+ display_control->channel_id = channel_id;
+
+ display_control->dvc_subscription_id =
+ grd_session_rdp_subscribe_dvc_creation_status (display_control->session_rdp,
+ channel_id,
+ dvc_creation_status,
+ display_control);
+ display_control->subscribed_status = TRUE;
+
+ return TRUE;
+}
+
static uint32_t
disp_monitor_layout (DispServerContext *disp_context,
const DISPLAY_CONTROL_MONITOR_LAYOUT_PDU *monitor_layout_pdu)
@@ -68,32 +135,6 @@ disp_monitor_layout (DispServerContext *disp_context,
return CHANNEL_RC_OK;
}
-void
-grd_rdp_display_control_maybe_init (GrdRdpDisplayControl *display_control)
-{
- DispServerContext *disp_context;
-
- if (display_control->channel_opened || display_control->channel_unavailable)
- return;
-
- if (WaitForSingleObject (display_control->stop_event, 0) == WAIT_OBJECT_0)
- return;
-
- disp_context = display_control->disp_context;
- if (disp_context->Open (disp_context))
- {
- g_warning ("[RDP.DISP] An error occurred while opening the DISP channel.");
- display_control->channel_unavailable = TRUE;
- return;
- }
-
- g_debug ("[RDP.DISP] Channel opened successfully. "
- "Ready for receiving new monitor layouts");
- disp_context->DisplayControlCaps (disp_context);
-
- display_control->channel_opened = TRUE;
-}
-
GrdRdpDisplayControl *
grd_rdp_display_control_new (GrdSessionRdp *session_rdp,
HANDLE vcm,
@@ -116,6 +157,7 @@ grd_rdp_display_control_new (GrdSessionRdp *session_rdp,
disp_context->MaxMonitorAreaFactorA = 8192;
disp_context->MaxMonitorAreaFactorB = 8192;
+ disp_context->ChannelIdAssigned = disp_channel_id_assigned;
disp_context->DispMonitorLayout = disp_monitor_layout;
disp_context->custom = display_control;
@@ -132,15 +174,66 @@ grd_rdp_display_control_dispose (GObject *object)
display_control->disp_context->Close (display_control->disp_context);
display_control->channel_opened = FALSE;
}
+ if (display_control->subscribed_status)
+ {
+ grd_session_rdp_unsubscribe_dvc_creation_status (display_control->session_rdp,
+ display_control->channel_id,
+ display_control->dvc_subscription_id);
+ display_control->subscribed_status = FALSE;
+ }
+
+ if (display_control->channel_teardown_source)
+ {
+ g_source_destroy (display_control->channel_teardown_source);
+ g_clear_pointer (&display_control->channel_teardown_source, g_source_unref);
+ }
g_clear_pointer (&display_control->disp_context, disp_server_context_free);
G_OBJECT_CLASS (grd_rdp_display_control_parent_class)->dispose (object);
}
+static gboolean
+tear_down_channel (gpointer user_data)
+{
+ GrdRdpDisplayControl *display_control = user_data;
+
+ g_debug ("[RDP.DISP] Tearing down channel");
+
+ g_clear_pointer (&display_control->channel_teardown_source, g_source_unref);
+
+ grd_session_rdp_tear_down_channel (display_control->session_rdp,
+ GRD_RDP_CHANNEL_DISPLAY_CONTROL);
+
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ g_source_set_ready_time (source, -1);
+
+ return callback (user_data);
+}
+
+static GSourceFuncs source_funcs =
+{
+ .dispatch = source_dispatch,
+};
+
static void
grd_rdp_display_control_init (GrdRdpDisplayControl *display_control)
{
+ GSource *channel_teardown_source;
+
+ channel_teardown_source = g_source_new (&source_funcs, sizeof (GSource));
+ g_source_set_callback (channel_teardown_source, tear_down_channel,
+ display_control, NULL);
+ g_source_set_ready_time (channel_teardown_source, -1);
+ g_source_attach (channel_teardown_source, NULL);
+ display_control->channel_teardown_source = channel_teardown_source;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]