[gnome-remote-desktop] rdp: Add display control class
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-remote-desktop] rdp: Add display control class
- Date: Thu, 3 Mar 2022 14:23:09 +0000 (UTC)
commit c2aad5113469cb59facac799b8c68ce591754c0e
Author: Pascal Nowack <Pascal Nowack gmx de>
Date: Tue Jan 26 18:27:53 2021 +0100
rdp: Add display control class
This class will be used by the Display Control channel, which is a very
simple dynamic channel, as it only has two PDUs.
The first PDU is the DISPLAYCONTROL_CAPS_PDU, which is sent initially
by the server side, containing the constraints of the monitor
configurations.
The second PDU is the DISPLAYCONTROL_MONITOR_LAYOUT_PDU, which is sent
by the client side, to request a monitor layout change.
When receiving a new monitor layout, create a new internal monitor
configuration and use the previous implemented API in session-rdp to
submit the new configuration.
src/grd-rdp-display-control.c | 155 ++++++++++++++++++++++++++++++++++++++++++
src/grd-rdp-display-control.h | 39 +++++++++++
src/grd-types.h | 1 +
src/meson.build | 2 +
4 files changed, 197 insertions(+)
---
diff --git a/src/grd-rdp-display-control.c b/src/grd-rdp-display-control.c
new file mode 100644
index 00000000..15b0f302
--- /dev/null
+++ b/src/grd-rdp-display-control.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2021 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-display-control.h"
+
+#include "grd-session-rdp.h"
+
+struct _GrdRdpDisplayControl
+{
+ GObject parent;
+
+ DispServerContext *disp_context;
+ HANDLE stop_event;
+ gboolean channel_opened;
+ gboolean channel_unavailable;
+
+ GrdSessionRdp *session_rdp;
+};
+
+G_DEFINE_TYPE (GrdRdpDisplayControl, grd_rdp_display_control, G_TYPE_OBJECT)
+
+static uint32_t
+disp_monitor_layout (DispServerContext *disp_context,
+ const DISPLAY_CONTROL_MONITOR_LAYOUT_PDU *monitor_layout_pdu)
+{
+ GrdRdpDisplayControl *display_control = disp_context->custom;
+ GrdSessionRdp *session_rdp = display_control->session_rdp;
+ GrdRdpMonitorConfig *monitor_config;
+
+ if (monitor_layout_pdu->NumMonitors > disp_context->MaxNumMonitors)
+ {
+ g_warning ("[RDP.DISP] Received invalid monitor layout pdu "
+ "(exceeded maximum monitor count). Ignoring PDU...");
+ return CHANNEL_RC_OK;
+ }
+
+ g_debug ("[RDP.DISP] Received new monitor layout. PDU contains %i monitors",
+ monitor_layout_pdu->NumMonitors);
+
+ monitor_config =
+ grd_rdp_monitor_config_new_from_disp_monitor_layout (monitor_layout_pdu);
+ if (!monitor_config)
+ {
+ g_warning ("[RDP.DISP] Monitor layout PDU is invalid. Ignoring PDU...");
+ return CHANNEL_RC_OK;
+ }
+
+ grd_session_rdp_submit_new_monitor_config (session_rdp, monitor_config);
+
+ return CHANNEL_RC_OK;
+}
+
+void
+grd_rdp_display_control_maybe_init (GrdRdpDisplayControl *display_control)
+{
+ DispServerContext *disp_context;
+
+ if (!display_control)
+ return;
+
+ 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,
+ HANDLE stop_event,
+ uint32_t max_monitor_count)
+{
+ GrdRdpDisplayControl *display_control;
+ DispServerContext *disp_context;
+
+ display_control = g_object_new (GRD_TYPE_RDP_DISPLAY_CONTROL, NULL);
+ disp_context = disp_server_context_new (vcm);
+ if (!disp_context)
+ g_error ("[RDP.DISP] Failed to create server context");
+
+ display_control->disp_context = disp_context;
+ display_control->stop_event = stop_event;
+ display_control->session_rdp = session_rdp;
+
+ disp_context->MaxNumMonitors = max_monitor_count;
+ disp_context->MaxMonitorAreaFactorA = 8192;
+ disp_context->MaxMonitorAreaFactorB = 8192;
+
+ disp_context->DispMonitorLayout = disp_monitor_layout;
+ disp_context->custom = display_control;
+
+ return display_control;
+}
+
+static void
+grd_rdp_display_control_dispose (GObject *object)
+{
+ GrdRdpDisplayControl *display_control = GRD_RDP_DISPLAY_CONTROL (object);
+
+ if (display_control->channel_opened)
+ {
+ display_control->disp_context->Close (display_control->disp_context);
+ display_control->channel_opened = FALSE;
+ }
+
+ g_clear_pointer (&display_control->disp_context, disp_server_context_free);
+
+ G_OBJECT_CLASS (grd_rdp_display_control_parent_class)->dispose (object);
+}
+
+static void
+grd_rdp_display_control_init (GrdRdpDisplayControl *display_control)
+{
+}
+
+static void
+grd_rdp_display_control_class_init (GrdRdpDisplayControlClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = grd_rdp_display_control_dispose;
+}
diff --git a/src/grd-rdp-display-control.h b/src/grd-rdp-display-control.h
new file mode 100644
index 00000000..a8f195fb
--- /dev/null
+++ b/src/grd-rdp-display-control.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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_DISPLAY_CONTROL_H
+#define GRD_RDP_DISPLAY_CONTROL_H
+
+#include <freerdp/server/disp.h>
+#include <glib-object.h>
+
+#include "grd-types.h"
+
+#define GRD_TYPE_RDP_DISPLAY_CONTROL (grd_rdp_display_control_get_type ())
+G_DECLARE_FINAL_TYPE (GrdRdpDisplayControl, grd_rdp_display_control,
+ GRD, RDP_DISPLAY_CONTROL, GObject)
+
+GrdRdpDisplayControl *grd_rdp_display_control_new (GrdSessionRdp *session_rdp,
+ HANDLE vcm,
+ HANDLE stop_event,
+ uint32_t max_monitor_count);
+
+void grd_rdp_display_control_maybe_init (GrdRdpDisplayControl *display_control);
+
+#endif /* GRD_RDP_DISPLAY_CONTROL_H */
diff --git a/src/grd-types.h b/src/grd-types.h
index b67474a8..03bcdc4d 100644
--- a/src/grd-types.h
+++ b/src/grd-types.h
@@ -30,6 +30,7 @@ typedef struct _GrdClipboardVnc GrdClipboardVnc;
typedef struct _GrdEglThread GrdEglThread;
typedef struct _GrdHwAccelNvidia GrdHwAccelNvidia;
typedef struct _GrdRdpDamageDetector GrdRdpDamageDetector;
+typedef struct _GrdRdpDisplayControl GrdRdpDisplayControl;
typedef struct _GrdRdpEventQueue GrdRdpEventQueue;
typedef struct _GrdRdpBuffer GrdRdpBuffer;
typedef struct _GrdRdpBufferPool GrdRdpBufferPool;
diff --git a/src/meson.build b/src/meson.build
index 1e409ab7..4364ba9e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -59,6 +59,8 @@ if have_rdp
'grd-rdp-damage-detector-cuda.h',
'grd-rdp-damage-detector-memcmp.c',
'grd-rdp-damage-detector-memcmp.h',
+ 'grd-rdp-display-control.c',
+ 'grd-rdp-display-control.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]