[gnome-remote-desktop] rdp: Move DVC subscriptions into its own class
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-remote-desktop] rdp: Move DVC subscriptions into its own class
- Date: Wed, 10 Aug 2022 10:19:04 +0000 (UTC)
commit 813627ab11c804b437dfdfed9102d96263f5edba
Author: Pascal Nowack <Pascal Nowack gmx de>
Date: Sat Jul 23 05:54:07 2022 +0200
rdp: Move DVC subscriptions into its own class
This unclutters the session-rdp class a bit.
src/grd-rdp-audio-playback.c | 18 ++-
src/grd-rdp-audio-playback.h | 1 +
src/grd-rdp-display-control.c | 18 ++-
src/grd-rdp-display-control.h | 1 +
src/grd-rdp-dvc.c | 330 ++++++++++++++++++++++++++++++++++++++++
src/grd-rdp-dvc.h | 45 ++++++
src/grd-rdp-graphics-pipeline.c | 19 ++-
src/grd-rdp-graphics-pipeline.h | 1 +
src/grd-rdp-private.h | 2 +
src/grd-rdp-telemetry.c | 18 ++-
src/grd-rdp-telemetry.h | 1 +
src/grd-session-rdp.c | 258 ++-----------------------------
src/grd-session-rdp.h | 12 --
src/grd-types.h | 1 +
src/meson.build | 2 +
15 files changed, 442 insertions(+), 285 deletions(-)
---
diff --git a/src/grd-rdp-audio-playback.c b/src/grd-rdp-audio-playback.c
index 7fee68b8..0c222fe4 100644
--- a/src/grd-rdp-audio-playback.c
+++ b/src/grd-rdp-audio-playback.c
@@ -24,6 +24,7 @@
#include "grd-pipewire-utils.h"
#include "grd-rdp-audio-output-stream.h"
#include "grd-rdp-dsp.h"
+#include "grd-rdp-dvc.h"
#include "grd-session-rdp.h"
#define PROTOCOL_TIMEOUT_MS (10 * 1000)
@@ -68,6 +69,7 @@ struct _GrdRdpAudioPlayback
gboolean subscribed_status;
GrdSessionRdp *session_rdp;
+ GrdRdpDvc *rdp_dvc;
GMutex protocol_timeout_mutex;
GSource *channel_teardown_source;
@@ -438,10 +440,10 @@ rdpsnd_channel_id_assigned (RdpsndServerContext *rdpsnd_context,
audio_playback->channel_id = channel_id;
audio_playback->dvc_subscription_id =
- grd_session_rdp_subscribe_dvc_creation_status (audio_playback->session_rdp,
- channel_id,
- dvc_creation_status,
- audio_playback);
+ grd_rdp_dvc_subscribe_dvc_creation_status (audio_playback->rdp_dvc,
+ channel_id,
+ dvc_creation_status,
+ audio_playback);
audio_playback->subscribed_status = TRUE;
return TRUE;
@@ -640,6 +642,7 @@ encode_thread_func (gpointer data)
GrdRdpAudioPlayback *
grd_rdp_audio_playback_new (GrdSessionRdp *session_rdp,
+ GrdRdpDvc *rdp_dvc,
HANDLE vcm,
HANDLE stop_event,
rdpContext *rdp_context)
@@ -656,6 +659,7 @@ grd_rdp_audio_playback_new (GrdSessionRdp *session_rdp,
audio_playback->rdpsnd_context = rdpsnd_context;
audio_playback->stop_event = stop_event;
audio_playback->session_rdp = session_rdp;
+ audio_playback->rdp_dvc = rdp_dvc;
rdpsnd_context->use_dynamic_virtual_channel = TRUE;
rdpsnd_context->server_formats = server_formats;
@@ -706,9 +710,9 @@ grd_rdp_audio_playback_dispose (GObject *object)
}
if (audio_playback->subscribed_status)
{
- grd_session_rdp_unsubscribe_dvc_creation_status (audio_playback->session_rdp,
- audio_playback->channel_id,
- audio_playback->dvc_subscription_id);
+ grd_rdp_dvc_unsubscribe_dvc_creation_status (audio_playback->rdp_dvc,
+ audio_playback->channel_id,
+ audio_playback->dvc_subscription_id);
audio_playback->subscribed_status = FALSE;
}
diff --git a/src/grd-rdp-audio-playback.h b/src/grd-rdp-audio-playback.h
index f7ae583c..46fa2ff3 100644
--- a/src/grd-rdp-audio-playback.h
+++ b/src/grd-rdp-audio-playback.h
@@ -30,6 +30,7 @@ G_DECLARE_FINAL_TYPE (GrdRdpAudioPlayback, grd_rdp_audio_playback,
GRD, RDP_AUDIO_PLAYBACK, GObject)
GrdRdpAudioPlayback *grd_rdp_audio_playback_new (GrdSessionRdp *session_rdp,
+ GrdRdpDvc *rdp_dvc,
HANDLE vcm,
HANDLE stop_event,
rdpContext *rdp_context);
diff --git a/src/grd-rdp-display-control.c b/src/grd-rdp-display-control.c
index c5e01ea7..de271791 100644
--- a/src/grd-rdp-display-control.c
+++ b/src/grd-rdp-display-control.c
@@ -21,6 +21,7 @@
#include "grd-rdp-display-control.h"
+#include "grd-rdp-dvc.h"
#include "grd-session-rdp.h"
struct _GrdRdpDisplayControl
@@ -37,6 +38,7 @@ struct _GrdRdpDisplayControl
gboolean subscribed_status;
GrdSessionRdp *session_rdp;
+ GrdRdpDvc *rdp_dvc;
GSource *channel_teardown_source;
};
@@ -95,10 +97,10 @@ disp_channel_id_assigned (DispServerContext *disp_context,
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);
+ grd_rdp_dvc_subscribe_dvc_creation_status (display_control->rdp_dvc,
+ channel_id,
+ dvc_creation_status,
+ display_control);
display_control->subscribed_status = TRUE;
return TRUE;
@@ -137,6 +139,7 @@ disp_monitor_layout (DispServerContext *disp_context,
GrdRdpDisplayControl *
grd_rdp_display_control_new (GrdSessionRdp *session_rdp,
+ GrdRdpDvc *rdp_dvc,
HANDLE vcm,
HANDLE stop_event,
uint32_t max_monitor_count)
@@ -152,6 +155,7 @@ grd_rdp_display_control_new (GrdSessionRdp *session_rdp,
display_control->disp_context = disp_context;
display_control->stop_event = stop_event;
display_control->session_rdp = session_rdp;
+ display_control->rdp_dvc = rdp_dvc;
disp_context->MaxNumMonitors = max_monitor_count;
disp_context->MaxMonitorAreaFactorA = 8192;
@@ -176,9 +180,9 @@ grd_rdp_display_control_dispose (GObject *object)
}
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);
+ grd_rdp_dvc_unsubscribe_dvc_creation_status (display_control->rdp_dvc,
+ display_control->channel_id,
+ display_control->dvc_subscription_id);
display_control->subscribed_status = FALSE;
}
diff --git a/src/grd-rdp-display-control.h b/src/grd-rdp-display-control.h
index a8f195fb..775fe30d 100644
--- a/src/grd-rdp-display-control.h
+++ b/src/grd-rdp-display-control.h
@@ -30,6 +30,7 @@ G_DECLARE_FINAL_TYPE (GrdRdpDisplayControl, grd_rdp_display_control,
GRD, RDP_DISPLAY_CONTROL, GObject)
GrdRdpDisplayControl *grd_rdp_display_control_new (GrdSessionRdp *session_rdp,
+ GrdRdpDvc *rdp_dvc,
HANDLE vcm,
HANDLE stop_event,
uint32_t max_monitor_count);
diff --git a/src/grd-rdp-dvc.c b/src/grd-rdp-dvc.c
new file mode 100644
index 00000000..b7d45081
--- /dev/null
+++ b/src/grd-rdp-dvc.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2022 Pascal Nowack
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "grd-rdp-dvc.h"
+
+#include "grd-rdp-private.h"
+
+typedef struct _DVCSubscription
+{
+ gboolean notified;
+
+ GrdRdpDVCCreationStatusCallback callback;
+ gpointer user_data;
+} DVCSubscription;
+
+typedef struct _DVCNotification
+{
+ int32_t creation_status;
+ gboolean pending_status;
+
+ GHashTable *subscriptions;
+ uint32_t next_subscription_id;
+} DVCNotification;
+
+struct _GrdRdpDvc
+{
+ GObject parent;
+
+ GMutex dvc_notification_mutex;
+ GHashTable *dvc_table;
+ GSource *dvc_notification_source;
+};
+
+G_DEFINE_TYPE (GrdRdpDvc, grd_rdp_dvc, G_TYPE_OBJECT)
+
+static DVCNotification *
+dvc_notification_new (void)
+{
+ DVCNotification *dvc_notification;
+
+ dvc_notification = g_new0 (DVCNotification, 1);
+ dvc_notification->pending_status = TRUE;
+ dvc_notification->subscriptions = g_hash_table_new_full (NULL, NULL,
+ NULL, g_free);
+
+ return dvc_notification;
+}
+
+static uint32_t
+get_next_free_dvc_subscription_id (DVCNotification *dvc_notification)
+{
+ uint32_t subscription_id = dvc_notification->next_subscription_id;
+
+ while (g_hash_table_contains (dvc_notification->subscriptions,
+ GUINT_TO_POINTER (subscription_id)))
+ ++subscription_id;
+
+ dvc_notification->next_subscription_id = subscription_id + 1;
+
+ return subscription_id;
+}
+
+static uint32_t
+dvc_notification_add_subscription (DVCNotification *dvc_notification,
+ DVCSubscription *dvc_subscription)
+{
+ uint32_t subscription_id;
+
+ subscription_id = get_next_free_dvc_subscription_id (dvc_notification);
+ g_hash_table_insert (dvc_notification->subscriptions,
+ GUINT_TO_POINTER (subscription_id), dvc_subscription);
+
+ return subscription_id;
+}
+
+uint32_t
+grd_rdp_dvc_subscribe_dvc_creation_status (GrdRdpDvc *rdp_dvc,
+ uint32_t channel_id,
+ GrdRdpDVCCreationStatusCallback callback,
+ gpointer callback_user_data)
+{
+ DVCNotification *dvc_notification;
+ g_autofree DVCSubscription *dvc_subscription = NULL;
+ uint32_t subscription_id;
+ gboolean pending_notification = FALSE;
+
+ dvc_subscription = g_new0 (DVCSubscription, 1);
+ dvc_subscription->callback = callback;
+ dvc_subscription->user_data = callback_user_data;
+
+ g_mutex_lock (&rdp_dvc->dvc_notification_mutex);
+ if (g_hash_table_lookup_extended (rdp_dvc->dvc_table,
+ GUINT_TO_POINTER (channel_id),
+ NULL, (gpointer *) &dvc_notification))
+ {
+ subscription_id =
+ dvc_notification_add_subscription (dvc_notification,
+ g_steal_pointer (&dvc_subscription));
+
+ if (!dvc_notification->pending_status)
+ pending_notification = TRUE;
+ }
+ else
+ {
+ dvc_notification = dvc_notification_new ();
+
+ subscription_id =
+ dvc_notification_add_subscription (dvc_notification,
+ g_steal_pointer (&dvc_subscription));
+
+ g_hash_table_insert (rdp_dvc->dvc_table,
+ GUINT_TO_POINTER (channel_id), dvc_notification);
+ }
+ g_mutex_unlock (&rdp_dvc->dvc_notification_mutex);
+
+ if (pending_notification)
+ g_source_set_ready_time (rdp_dvc->dvc_notification_source, 0);
+
+ return subscription_id;
+}
+
+void
+grd_rdp_dvc_unsubscribe_dvc_creation_status (GrdRdpDvc *rdp_dvc,
+ uint32_t channel_id,
+ uint32_t subscription_id)
+{
+ DVCNotification *dvc_notification;
+
+ g_mutex_lock (&rdp_dvc->dvc_notification_mutex);
+ if (!g_hash_table_lookup_extended (rdp_dvc->dvc_table,
+ GUINT_TO_POINTER (channel_id),
+ NULL, (gpointer *) &dvc_notification))
+ g_assert_not_reached ();
+
+ g_hash_table_remove (dvc_notification->subscriptions,
+ GUINT_TO_POINTER (subscription_id));
+ g_mutex_unlock (&rdp_dvc->dvc_notification_mutex);
+}
+
+static BOOL
+dvc_creation_status (void *user_data,
+ uint32_t channel_id,
+ int32_t creation_status)
+{
+ RdpPeerContext *rdp_peer_context = user_data;
+ GrdRdpDvc *rdp_dvc = rdp_peer_context->rdp_dvc;
+ DVCNotification *dvc_notification;
+ gboolean pending_notification = FALSE;
+
+ g_debug ("[RDP.DRDYNVC] DVC channel id %u creation status: %i",
+ channel_id, creation_status);
+
+ g_mutex_lock (&rdp_dvc->dvc_notification_mutex);
+ if (g_hash_table_lookup_extended (rdp_dvc->dvc_table,
+ GUINT_TO_POINTER (channel_id),
+ NULL, (gpointer *) &dvc_notification))
+ {
+ if (dvc_notification->pending_status)
+ {
+ dvc_notification->creation_status = creation_status;
+ dvc_notification->pending_status = FALSE;
+
+ if (g_hash_table_size (dvc_notification->subscriptions) > 0)
+ pending_notification = TRUE;
+ }
+ else
+ {
+ g_warning ("[RDP.DRDYNVC] Status of channel %u already known. "
+ "Discarding result", channel_id);
+ }
+ }
+ else
+ {
+ dvc_notification = dvc_notification_new ();
+
+ dvc_notification->creation_status = creation_status;
+ dvc_notification->pending_status = FALSE;
+
+ g_hash_table_insert (rdp_dvc->dvc_table,
+ GUINT_TO_POINTER (channel_id), dvc_notification);
+ }
+ g_mutex_unlock (&rdp_dvc->dvc_notification_mutex);
+
+ if (pending_notification)
+ g_source_set_ready_time (rdp_dvc->dvc_notification_source, 0);
+
+ return TRUE;
+}
+
+GrdRdpDvc *
+grd_rdp_dvc_new (HANDLE vcm,
+ rdpContext *rdp_context)
+{
+ GrdRdpDvc *rdp_dvc;
+
+ rdp_dvc = g_object_new (GRD_TYPE_RDP_DVC, NULL);
+
+ WTSVirtualChannelManagerSetDVCCreationCallback (vcm, dvc_creation_status,
+ rdp_context);
+
+ return rdp_dvc;
+}
+
+static void
+grd_rdp_dvc_dispose (GObject *object)
+{
+ GrdRdpDvc *rdp_dvc = GRD_RDP_DVC (object);
+
+ if (rdp_dvc->dvc_notification_source)
+ {
+ g_source_destroy (rdp_dvc->dvc_notification_source);
+ g_clear_pointer (&rdp_dvc->dvc_notification_source, g_source_unref);
+ }
+
+ g_clear_pointer (&rdp_dvc->dvc_table, g_hash_table_unref);
+
+ G_OBJECT_CLASS (grd_rdp_dvc_parent_class)->dispose (object);
+}
+
+static void
+grd_rdp_dvc_finalize (GObject *object)
+{
+ GrdRdpDvc *rdp_dvc = GRD_RDP_DVC (object);
+
+ g_mutex_clear (&rdp_dvc->dvc_notification_mutex);
+
+ G_OBJECT_CLASS (grd_rdp_dvc_parent_class)->finalize (object);
+}
+
+static void
+dvc_notification_free (gpointer data)
+{
+ DVCNotification *dvc_notification = data;
+
+ g_clear_pointer (&dvc_notification->subscriptions, g_hash_table_unref);
+
+ g_free (dvc_notification);
+}
+
+static gboolean
+notify_channels (gpointer user_data)
+{
+ GrdRdpDvc *rdp_dvc = user_data;
+ GHashTableIter iter;
+ DVCNotification *dvc_notification;
+
+ g_mutex_lock (&rdp_dvc->dvc_notification_mutex);
+ g_hash_table_iter_init (&iter, rdp_dvc->dvc_table);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &dvc_notification))
+ {
+ GHashTableIter iter2;
+ DVCSubscription *dvc_subscription;
+
+ if (dvc_notification->pending_status)
+ continue;
+
+ g_hash_table_iter_init (&iter2, dvc_notification->subscriptions);
+ while (g_hash_table_iter_next (&iter2, NULL, (gpointer *) &dvc_subscription))
+ {
+ if (dvc_subscription->notified)
+ continue;
+
+ dvc_subscription->callback (dvc_subscription->user_data,
+ dvc_notification->creation_status);
+
+ dvc_subscription->notified = TRUE;
+ }
+ }
+ g_mutex_unlock (&rdp_dvc->dvc_notification_mutex);
+
+ return G_SOURCE_CONTINUE;
+}
+
+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_dvc_init (GrdRdpDvc *rdp_dvc)
+{
+ rdp_dvc->dvc_table = g_hash_table_new_full (NULL, NULL,
+ NULL, dvc_notification_free);
+
+ g_mutex_init (&rdp_dvc->dvc_notification_mutex);
+
+ rdp_dvc->dvc_notification_source = g_source_new (&source_funcs,
+ sizeof (GSource));
+ g_source_set_callback (rdp_dvc->dvc_notification_source,
+ notify_channels, rdp_dvc, NULL);
+ g_source_set_ready_time (rdp_dvc->dvc_notification_source, -1);
+ g_source_attach (rdp_dvc->dvc_notification_source, NULL);
+}
+
+static void
+grd_rdp_dvc_class_init (GrdRdpDvcClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = grd_rdp_dvc_dispose;
+ object_class->finalize = grd_rdp_dvc_finalize;
+}
diff --git a/src/grd-rdp-dvc.h b/src/grd-rdp-dvc.h
new file mode 100644
index 00000000..e8139974
--- /dev/null
+++ b/src/grd-rdp-dvc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 Pascal Nowack
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef GRD_RDP_DVC_H
+#define GRD_RDP_DVC_H
+
+#include <freerdp/channels/wtsvc.h>
+#include <glib-object.h>
+
+#define GRD_TYPE_RDP_DVC (grd_rdp_dvc_get_type ())
+G_DECLARE_FINAL_TYPE (GrdRdpDvc, grd_rdp_dvc,
+ GRD, RDP_DVC, GObject)
+
+typedef void (* GrdRdpDVCCreationStatusCallback) (gpointer user_data,
+ int32_t creation_status);
+
+GrdRdpDvc *grd_rdp_dvc_new (HANDLE vcm,
+ rdpContext *rdp_context);
+
+uint32_t grd_rdp_dvc_subscribe_dvc_creation_status (GrdRdpDvc *rdp_dvc,
+ uint32_t channel_id,
+ GrdRdpDVCCreationStatusCallback callback,
+ gpointer callback_user_data);
+
+void grd_rdp_dvc_unsubscribe_dvc_creation_status (GrdRdpDvc *rdp_dvc,
+ uint32_t channel_id,
+ uint32_t subscription_id);
+
+#endif /* GRD_RDP_DVC_H */
diff --git a/src/grd-rdp-graphics-pipeline.c b/src/grd-rdp-graphics-pipeline.c
index bf244432..e16214e0 100644
--- a/src/grd-rdp-graphics-pipeline.c
+++ b/src/grd-rdp-graphics-pipeline.c
@@ -27,6 +27,7 @@
#include "grd-hwaccel-nvidia.h"
#include "grd-rdp-buffer.h"
#include "grd-rdp-damage-detector.h"
+#include "grd-rdp-dvc.h"
#include "grd-rdp-frame-info.h"
#include "grd-rdp-gfx-frame-controller.h"
#include "grd-rdp-gfx-surface.h"
@@ -82,6 +83,7 @@ struct _GrdRdpGraphicsPipeline
gboolean subscribed_status;
GrdSessionRdp *session_rdp;
+ GrdRdpDvc *rdp_dvc;
GMainContext *pipeline_context;
GrdRdpNetworkAutodetection *network_autodetection;
wStream *encode_stream;
@@ -1128,16 +1130,15 @@ rdpgfx_channel_id_assigned (RdpgfxServerContext *rdpgfx_context,
uint32_t channel_id)
{
GrdRdpGraphicsPipeline *graphics_pipeline = rdpgfx_context->custom;
- GrdSessionRdp *session_rdp = graphics_pipeline->session_rdp;
g_debug ("[RDP.RDPGFX] DVC channel id assigned to id %u", channel_id);
graphics_pipeline->channel_id = channel_id;
graphics_pipeline->dvc_subscription_id =
- grd_session_rdp_subscribe_dvc_creation_status (session_rdp,
- channel_id,
- dvc_creation_status,
- graphics_pipeline);
+ grd_rdp_dvc_subscribe_dvc_creation_status (graphics_pipeline->rdp_dvc,
+ channel_id,
+ dvc_creation_status,
+ graphics_pipeline);
graphics_pipeline->subscribed_status = TRUE;
return TRUE;
@@ -1488,6 +1489,7 @@ grd_rdp_graphics_pipeline_maybe_init (GrdRdpGraphicsPipeline *graphics_pipeline)
GrdRdpGraphicsPipeline *
grd_rdp_graphics_pipeline_new (GrdSessionRdp *session_rdp,
+ GrdRdpDvc *rdp_dvc,
GMainContext *pipeline_context,
HANDLE vcm,
HANDLE stop_event,
@@ -1507,6 +1509,7 @@ grd_rdp_graphics_pipeline_new (GrdSessionRdp *session_rdp,
graphics_pipeline->rdpgfx_context = rdpgfx_context;
graphics_pipeline->stop_event = stop_event;
graphics_pipeline->session_rdp = session_rdp;
+ graphics_pipeline->rdp_dvc = rdp_dvc;
graphics_pipeline->pipeline_context = pipeline_context;
graphics_pipeline->network_autodetection = network_autodetection;
graphics_pipeline->encode_stream = encode_stream;
@@ -1579,9 +1582,9 @@ grd_rdp_graphics_pipeline_dispose (GObject *object)
}
if (graphics_pipeline->subscribed_status)
{
- grd_session_rdp_unsubscribe_dvc_creation_status (graphics_pipeline->session_rdp,
- graphics_pipeline->channel_id,
- graphics_pipeline->dvc_subscription_id);
+ grd_rdp_dvc_unsubscribe_dvc_creation_status (graphics_pipeline->rdp_dvc,
+ graphics_pipeline->channel_id,
+ graphics_pipeline->dvc_subscription_id);
graphics_pipeline->subscribed_status = FALSE;
}
diff --git a/src/grd-rdp-graphics-pipeline.h b/src/grd-rdp-graphics-pipeline.h
index 9bf2fc8b..3adfc207 100644
--- a/src/grd-rdp-graphics-pipeline.h
+++ b/src/grd-rdp-graphics-pipeline.h
@@ -30,6 +30,7 @@ G_DECLARE_FINAL_TYPE (GrdRdpGraphicsPipeline, grd_rdp_graphics_pipeline,
GRD, RDP_GRAPHICS_PIPELINE, GObject)
GrdRdpGraphicsPipeline *grd_rdp_graphics_pipeline_new (GrdSessionRdp *session_rdp,
+ GrdRdpDvc *rdp_dvc,
GMainContext *pipeline_context,
HANDLE vcm,
HANDLE stop_event,
diff --git a/src/grd-rdp-private.h b/src/grd-rdp-private.h
index f70f9bc3..228de8ff 100644
--- a/src/grd-rdp-private.h
+++ b/src/grd-rdp-private.h
@@ -41,6 +41,8 @@ typedef struct _RdpPeerContext
/* Virtual Channel Manager */
HANDLE vcm;
+ GrdRdpDvc *rdp_dvc;
+
GMutex channel_mutex;
GrdClipboardRdp *clipboard_rdp;
diff --git a/src/grd-rdp-telemetry.c b/src/grd-rdp-telemetry.c
index 051ffc1b..1540fbe7 100644
--- a/src/grd-rdp-telemetry.c
+++ b/src/grd-rdp-telemetry.c
@@ -21,6 +21,7 @@
#include "grd-rdp-telemetry.h"
+#include "grd-rdp-dvc.h"
#include "grd-session-rdp.h"
#define PROTOCOL_TIMEOUT_MS (10 * 1000)
@@ -39,6 +40,7 @@ struct _GrdRdpTelemetry
gboolean subscribed_status;
GrdSessionRdp *session_rdp;
+ GrdRdpDvc *rdp_dvc;
GMutex protocol_timeout_mutex;
GSource *channel_teardown_source;
@@ -119,10 +121,10 @@ telemetry_channel_id_assigned (TelemetryServerContext *telemetry_context,
telemetry->channel_id = channel_id;
telemetry->dvc_subscription_id =
- grd_session_rdp_subscribe_dvc_creation_status (telemetry->session_rdp,
- channel_id,
- dvc_creation_status,
- telemetry);
+ grd_rdp_dvc_subscribe_dvc_creation_status (telemetry->rdp_dvc,
+ channel_id,
+ dvc_creation_status,
+ telemetry);
telemetry->subscribed_status = TRUE;
return TRUE;
@@ -169,6 +171,7 @@ telemetry_rdp_telemetry (TelemetryServerContext *telemetry_context,
GrdRdpTelemetry *
grd_rdp_telemetry_new (GrdSessionRdp *session_rdp,
+ GrdRdpDvc *rdp_dvc,
HANDLE vcm,
HANDLE stop_event,
rdpContext *rdp_context)
@@ -184,6 +187,7 @@ grd_rdp_telemetry_new (GrdSessionRdp *session_rdp,
telemetry->telemetry_context = telemetry_context;
telemetry->stop_event = stop_event;
telemetry->session_rdp = session_rdp;
+ telemetry->rdp_dvc = rdp_dvc;
telemetry_context->ChannelIdAssigned = telemetry_channel_id_assigned;
telemetry_context->RdpTelemetry = telemetry_rdp_telemetry;
@@ -205,9 +209,9 @@ grd_rdp_telemetry_dispose (GObject *object)
}
if (telemetry->subscribed_status)
{
- grd_session_rdp_unsubscribe_dvc_creation_status (telemetry->session_rdp,
- telemetry->channel_id,
- telemetry->dvc_subscription_id);
+ grd_rdp_dvc_unsubscribe_dvc_creation_status (telemetry->rdp_dvc,
+ telemetry->channel_id,
+ telemetry->dvc_subscription_id);
telemetry->subscribed_status = FALSE;
}
diff --git a/src/grd-rdp-telemetry.h b/src/grd-rdp-telemetry.h
index 09c5a833..197577e1 100644
--- a/src/grd-rdp-telemetry.h
+++ b/src/grd-rdp-telemetry.h
@@ -30,6 +30,7 @@ G_DECLARE_FINAL_TYPE (GrdRdpTelemetry, grd_rdp_telemetry,
GRD, RDP_TELEMETRY, GObject)
GrdRdpTelemetry *grd_rdp_telemetry_new (GrdSessionRdp *session_rdp,
+ GrdRdpDvc *rdp_dvc,
HANDLE vcm,
HANDLE stop_event,
rdpContext *rdp_context);
diff --git a/src/grd-session-rdp.c b/src/grd-session-rdp.c
index 67d82693..c2ff29ce 100644
--- a/src/grd-session-rdp.c
+++ b/src/grd-session-rdp.c
@@ -36,6 +36,7 @@
#include "grd-rdp-buffer.h"
#include "grd-rdp-damage-detector.h"
#include "grd-rdp-display-control.h"
+#include "grd-rdp-dvc.h"
#include "grd-rdp-event-queue.h"
#include "grd-rdp-graphics-pipeline.h"
#include "grd-rdp-network-autodetection.h"
@@ -89,23 +90,6 @@ typedef struct _SessionMetrics
uint32_t skipped_frames;
} SessionMetrics;
-typedef struct _DVCSubscription
-{
- gboolean notified;
-
- GrdRdpDVCCreationStatusCallback callback;
- gpointer user_data;
-} DVCSubscription;
-
-typedef struct _DVCNotification
-{
- int32_t creation_status;
- gboolean pending_status;
-
- GHashTable *subscriptions;
- uint32_t next_subscription_id;
-} DVCNotification;
-
typedef struct _Pointer
{
uint8_t *bitmap;
@@ -168,10 +152,6 @@ struct _GrdSessionRdp
GThread *graphics_thread;
GMainContext *graphics_context;
- GMutex dvc_notification_mutex;
- GHashTable *dvc_table;
- GSource *dvc_notification_source;
-
GrdRdpSurface *rdp_surface;
Pointer *last_pointer;
GHashTable *pointer_cache;
@@ -698,110 +678,6 @@ grd_session_rdp_notify_error (GrdSessionRdp *session_rdp,
maybe_queue_close_session_idle (session_rdp);
}
-static DVCNotification *
-dvc_notification_new (void)
-{
- DVCNotification *dvc_notification;
-
- dvc_notification = g_new0 (DVCNotification, 1);
- dvc_notification->pending_status = TRUE;
- dvc_notification->subscriptions = g_hash_table_new_full (NULL, NULL,
- NULL, g_free);
-
- return dvc_notification;
-}
-
-static uint32_t
-get_next_free_dvc_subscription_id (DVCNotification *dvc_notification)
-{
- uint32_t subscription_id = dvc_notification->next_subscription_id;
-
- while (g_hash_table_contains (dvc_notification->subscriptions,
- GUINT_TO_POINTER (subscription_id)))
- ++subscription_id;
-
- dvc_notification->next_subscription_id = subscription_id + 1;
-
- return subscription_id;
-}
-
-static uint32_t
-dvc_notification_add_subscription (DVCNotification *dvc_notification,
- DVCSubscription *dvc_subscription)
-{
- uint32_t subscription_id;
-
- subscription_id = get_next_free_dvc_subscription_id (dvc_notification);
- g_hash_table_insert (dvc_notification->subscriptions,
- GUINT_TO_POINTER (subscription_id), dvc_subscription);
-
- return subscription_id;
-}
-
-uint32_t
-grd_session_rdp_subscribe_dvc_creation_status (GrdSessionRdp *session_rdp,
- uint32_t channel_id,
- GrdRdpDVCCreationStatusCallback callback,
- gpointer callback_user_data)
-{
- DVCNotification *dvc_notification;
- g_autofree DVCSubscription *dvc_subscription = NULL;
- uint32_t subscription_id;
- gboolean pending_notification = FALSE;
-
- dvc_subscription = g_new0 (DVCSubscription, 1);
- dvc_subscription->callback = callback;
- dvc_subscription->user_data = callback_user_data;
-
- g_mutex_lock (&session_rdp->dvc_notification_mutex);
- if (g_hash_table_lookup_extended (session_rdp->dvc_table,
- GUINT_TO_POINTER (channel_id),
- NULL, (gpointer *) &dvc_notification))
- {
- subscription_id =
- dvc_notification_add_subscription (dvc_notification,
- g_steal_pointer (&dvc_subscription));
-
- if (!dvc_notification->pending_status)
- pending_notification = TRUE;
- }
- else
- {
- dvc_notification = dvc_notification_new ();
-
- subscription_id =
- dvc_notification_add_subscription (dvc_notification,
- g_steal_pointer (&dvc_subscription));
-
- g_hash_table_insert (session_rdp->dvc_table,
- GUINT_TO_POINTER (channel_id), dvc_notification);
- }
- g_mutex_unlock (&session_rdp->dvc_notification_mutex);
-
- if (pending_notification)
- g_source_set_ready_time (session_rdp->dvc_notification_source, 0);
-
- return subscription_id;
-}
-
-void
-grd_session_rdp_unsubscribe_dvc_creation_status (GrdSessionRdp *session_rdp,
- uint32_t channel_id,
- uint32_t subscription_id)
-{
- DVCNotification *dvc_notification;
-
- g_mutex_lock (&session_rdp->dvc_notification_mutex);
- if (!g_hash_table_lookup_extended (session_rdp->dvc_table,
- GUINT_TO_POINTER (channel_id),
- NULL, (gpointer *) &dvc_notification))
- g_assert_not_reached ();
-
- g_hash_table_remove (dvc_notification->subscriptions,
- GUINT_TO_POINTER (subscription_id));
- g_mutex_unlock (&session_rdp->dvc_notification_mutex);
-}
-
void
grd_session_rdp_tear_down_channel (GrdSessionRdp *session_rdp,
GrdRdpChannel channel)
@@ -2034,6 +1910,8 @@ rdp_peer_context_free (freerdp_peer *peer,
if (!rdp_peer_context)
return;
+ g_clear_object (&rdp_peer_context->rdp_dvc);
+
g_clear_pointer (&rdp_peer_context->vcm, WTSCloseServer);
if (rdp_peer_context->encode_stream)
@@ -2047,56 +1925,6 @@ rdp_peer_context_free (freerdp_peer *peer,
g_mutex_clear (&rdp_peer_context->channel_mutex);
}
-static BOOL
-dvc_creation_status (void *user_data,
- uint32_t channel_id,
- int32_t creation_status)
-{
- RdpPeerContext *rdp_peer_context = user_data;
- GrdSessionRdp *session_rdp = rdp_peer_context->session_rdp;
- DVCNotification *dvc_notification;
- gboolean pending_notification = FALSE;
-
- g_debug ("[RDP.DRDYNVC] DVC channel id %u creation status: %i",
- channel_id, creation_status);
-
- g_mutex_lock (&session_rdp->dvc_notification_mutex);
- if (g_hash_table_lookup_extended (session_rdp->dvc_table,
- GUINT_TO_POINTER (channel_id),
- NULL, (gpointer *) &dvc_notification))
- {
- if (dvc_notification->pending_status)
- {
- dvc_notification->creation_status = creation_status;
- dvc_notification->pending_status = FALSE;
-
- if (g_hash_table_size (dvc_notification->subscriptions) > 0)
- pending_notification = TRUE;
- }
- else
- {
- g_warning ("[RDP.DRDYNVC] Status of channel %u already known. "
- "Discarding result", channel_id);
- }
- }
- else
- {
- dvc_notification = dvc_notification_new ();
-
- dvc_notification->creation_status = creation_status;
- dvc_notification->pending_status = FALSE;
-
- g_hash_table_insert (session_rdp->dvc_table,
- GUINT_TO_POINTER (channel_id), dvc_notification);
- }
- g_mutex_unlock (&session_rdp->dvc_notification_mutex);
-
- if (pending_notification)
- g_source_set_ready_time (session_rdp->dvc_notification_source, 0);
-
- return TRUE;
-}
-
static BOOL
rdp_peer_context_new (freerdp_peer *peer,
RdpPeerContext *rdp_peer_context)
@@ -2138,9 +1966,8 @@ rdp_peer_context_new (freerdp_peer *peer,
return FALSE;
}
- WTSVirtualChannelManagerSetDVCCreationCallback (rdp_peer_context->vcm,
- dvc_creation_status,
- rdp_peer_context);
+ rdp_peer_context->rdp_dvc = grd_rdp_dvc_new (rdp_peer_context->vcm,
+ &rdp_peer_context->rdp_context);
return TRUE;
}
@@ -2477,11 +2304,6 @@ clear_session_sources (GrdSessionRdp *session_rdp)
g_source_destroy (session_rdp->pending_encode_source);
g_clear_pointer (&session_rdp->pending_encode_source, g_source_unref);
}
- if (session_rdp->dvc_notification_source)
- {
- g_source_destroy (session_rdp->dvc_notification_source);
- g_clear_pointer (&session_rdp->dvc_notification_source, g_source_unref);
- }
}
static gboolean
@@ -2609,6 +2431,7 @@ maybe_initialize_graphics_pipeline (GrdSessionRdp *session_rdp)
g_assert (is_rdp_peer_flag_set (session_rdp, RDP_PEER_PENDING_GFX_INIT));
telemetry = grd_rdp_telemetry_new (session_rdp,
+ rdp_peer_context->rdp_dvc,
rdp_peer_context->vcm,
session_rdp->stop_event,
peer->context);
@@ -2616,6 +2439,7 @@ maybe_initialize_graphics_pipeline (GrdSessionRdp *session_rdp)
graphics_pipeline =
grd_rdp_graphics_pipeline_new (session_rdp,
+ rdp_peer_context->rdp_dvc,
session_rdp->graphics_context,
rdp_peer_context->vcm,
session_rdp->stop_event,
@@ -2634,21 +2458,22 @@ initialize_remaining_virtual_channels (GrdSessionRdp *session_rdp)
freerdp_peer *peer = session_rdp->peer;
RdpPeerContext *rdp_peer_context = (RdpPeerContext *) peer->context;
rdpSettings *rdp_settings = peer->settings;
+ GrdRdpDvc *rdp_dvc = rdp_peer_context->rdp_dvc;
+ HANDLE vcm = rdp_peer_context->vcm;
- if (WTSVirtualChannelManagerIsChannelJoined (rdp_peer_context->vcm,
- "cliprdr"))
+ if (WTSVirtualChannelManagerIsChannelJoined (vcm, "cliprdr"))
{
gboolean peer_is_on_ms_windows;
peer_is_on_ms_windows = rdp_settings->OsMajorType == OSMAJORTYPE_WINDOWS;
rdp_peer_context->clipboard_rdp =
- grd_clipboard_rdp_new (session_rdp, rdp_peer_context->vcm,
- session_rdp->stop_event, !peer_is_on_ms_windows);
+ grd_clipboard_rdp_new (session_rdp, vcm, session_rdp->stop_event,
+ !peer_is_on_ms_windows);
}
if (rdp_settings->AudioPlayback && !rdp_settings->RemoteConsoleAudio)
{
rdp_peer_context->audio_playback =
- grd_rdp_audio_playback_new (session_rdp, rdp_peer_context->vcm,
+ grd_rdp_audio_playback_new (session_rdp, rdp_dvc, vcm,
session_rdp->stop_event, peer->context);
}
}
@@ -2746,6 +2571,7 @@ grd_session_rdp_stream_ready (GrdSession *session,
{
rdp_peer_context->display_control =
grd_rdp_display_control_new (session_rdp,
+ rdp_peer_context->rdp_dvc,
rdp_peer_context->vcm,
session_rdp->stop_event,
MAX_MONITOR_COUNT);
@@ -2788,7 +2614,6 @@ grd_session_rdp_dispose (GObject *object)
g_clear_pointer (&session_rdp->pressed_unicode_keys, g_hash_table_unref);
g_clear_pointer (&session_rdp->pressed_keys, g_hash_table_unref);
g_clear_pointer (&session_rdp->pointer_cache, g_hash_table_unref);
- g_clear_pointer (&session_rdp->dvc_table, g_hash_table_unref);
g_clear_pointer (&session_rdp->stop_event, CloseHandle);
@@ -2802,7 +2627,6 @@ grd_session_rdp_finalize (GObject *object)
g_mutex_clear (&session_rdp->monitor_config_mutex);
g_mutex_clear (&session_rdp->close_session_mutex);
- g_mutex_clear (&session_rdp->dvc_notification_mutex);
g_mutex_clear (&session_rdp->rdp_flags_mutex);
g_mutex_clear (&session_rdp->pending_jobs_mutex);
g_cond_clear (&session_rdp->pending_jobs_cond);
@@ -2810,16 +2634,6 @@ grd_session_rdp_finalize (GObject *object)
G_OBJECT_CLASS (grd_session_rdp_parent_class)->finalize (object);
}
-static void
-dvc_notification_free (gpointer data)
-{
- DVCNotification *dvc_notification = data;
-
- g_clear_pointer (&dvc_notification->subscriptions, g_hash_table_unref);
-
- g_free (dvc_notification);
-}
-
static gboolean
are_pointer_bitmaps_equal (gconstpointer a,
gconstpointer b)
@@ -2846,40 +2660,6 @@ are_pointer_bitmaps_equal (gconstpointer a,
return TRUE;
}
-static gboolean
-notify_channels (gpointer user_data)
-{
- GrdSessionRdp *session_rdp = user_data;
- GHashTableIter iter;
- DVCNotification *dvc_notification;
-
- g_mutex_lock (&session_rdp->dvc_notification_mutex);
- g_hash_table_iter_init (&iter, session_rdp->dvc_table);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &dvc_notification))
- {
- GHashTableIter iter2;
- DVCSubscription *dvc_subscription;
-
- if (dvc_notification->pending_status)
- continue;
-
- g_hash_table_iter_init (&iter2, dvc_notification->subscriptions);
- while (g_hash_table_iter_next (&iter2, NULL, (gpointer *) &dvc_subscription))
- {
- if (dvc_subscription->notified)
- continue;
-
- dvc_subscription->callback (dvc_subscription->user_data,
- dvc_notification->creation_status);
-
- dvc_subscription->notified = TRUE;
- }
- }
- g_mutex_unlock (&session_rdp->dvc_notification_mutex);
-
- return G_SOURCE_CONTINUE;
-}
-
static gboolean
encode_pending_frames (gpointer user_data)
{
@@ -2933,8 +2713,6 @@ grd_session_rdp_init (GrdSessionRdp *session_rdp)
{
session_rdp->stop_event = CreateEvent (NULL, TRUE, FALSE, NULL);
- session_rdp->dvc_table = g_hash_table_new_full (NULL, NULL,
- NULL, dvc_notification_free);
session_rdp->pointer_cache = g_hash_table_new (NULL, are_pointer_bitmaps_equal);
session_rdp->pressed_keys = g_hash_table_new (NULL, NULL);
session_rdp->pressed_unicode_keys = g_hash_table_new (NULL, NULL);
@@ -2942,7 +2720,6 @@ grd_session_rdp_init (GrdSessionRdp *session_rdp)
g_cond_init (&session_rdp->pending_jobs_cond);
g_mutex_init (&session_rdp->pending_jobs_mutex);
g_mutex_init (&session_rdp->rdp_flags_mutex);
- g_mutex_init (&session_rdp->dvc_notification_mutex);
g_mutex_init (&session_rdp->close_session_mutex);
g_mutex_init (&session_rdp->monitor_config_mutex);
@@ -2950,13 +2727,6 @@ grd_session_rdp_init (GrdSessionRdp *session_rdp)
session_rdp->graphics_context = g_main_context_new ();
- session_rdp->dvc_notification_source = g_source_new (&session_source_funcs,
- sizeof (GSource));
- g_source_set_callback (session_rdp->dvc_notification_source,
- notify_channels, session_rdp, NULL);
- g_source_set_ready_time (session_rdp->dvc_notification_source, -1);
- g_source_attach (session_rdp->dvc_notification_source, NULL);
-
session_rdp->pending_encode_source = g_source_new (&session_source_funcs,
sizeof (GSource));
g_source_set_callback (session_rdp->pending_encode_source,
diff --git a/src/grd-session-rdp.h b/src/grd-session-rdp.h
index 71577a8b..6742ccf7 100644
--- a/src/grd-session-rdp.h
+++ b/src/grd-session-rdp.h
@@ -48,9 +48,6 @@ typedef enum _GrdRdpChannel
GRD_RDP_CHANNEL_TELEMETRY,
} GrdRdpChannel;
-typedef void (* GrdRdpDVCCreationStatusCallback) (gpointer user_data,
- int32_t creation_status);
-
GrdSessionRdp *grd_session_rdp_new (GrdRdpServer *rdp_server,
GSocketConnection *connection,
GrdHwAccelNvidia *hwaccel_nvidia);
@@ -58,15 +55,6 @@ GrdSessionRdp *grd_session_rdp_new (GrdRdpServer *rdp_server,
void grd_session_rdp_notify_error (GrdSessionRdp *session_rdp,
GrdSessionRdpError error_info);
-uint32_t grd_session_rdp_subscribe_dvc_creation_status (GrdSessionRdp *session_rdp,
- uint32_t channel_id,
- GrdRdpDVCCreationStatusCallback callback,
- gpointer callback_user_data);
-
-void grd_session_rdp_unsubscribe_dvc_creation_status (GrdSessionRdp *session_rdp,
- uint32_t channel_id,
- uint32_t subscription_id);
-
void grd_session_rdp_tear_down_channel (GrdSessionRdp *session_rdp,
GrdRdpChannel channel);
diff --git a/src/grd-types.h b/src/grd-types.h
index e2d337fe..123a00c9 100644
--- a/src/grd-types.h
+++ b/src/grd-types.h
@@ -37,6 +37,7 @@ typedef struct _GrdRdpBuffer GrdRdpBuffer;
typedef struct _GrdRdpBufferPool GrdRdpBufferPool;
typedef struct _GrdRdpDamageDetector GrdRdpDamageDetector;
typedef struct _GrdRdpDisplayControl GrdRdpDisplayControl;
+typedef struct _GrdRdpDvc GrdRdpDvc;
typedef struct _GrdRdpEventQueue GrdRdpEventQueue;
typedef struct _GrdRdpGfxFrameController GrdRdpGfxFrameController;
typedef struct _GrdRdpGfxFrameLog GrdRdpGfxFrameLog;
diff --git a/src/meson.build b/src/meson.build
index b274fa43..e1398589 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -87,6 +87,8 @@ if have_rdp
'grd-rdp-display-control.h',
'grd-rdp-dsp.c',
'grd-rdp-dsp.h',
+ 'grd-rdp-dvc.c',
+ 'grd-rdp-dvc.h',
'grd-rdp-event-queue.c',
'grd-rdp-event-queue.h',
'grd-rdp-frame-info.h',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]