summaryrefslogtreecommitdiffstats
path: root/plugins/rdp/rdp_monitor.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 17:06:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 17:06:32 +0000
commit2dad5357405ad33cfa792f04b3ab62a5d188841e (patch)
treeb8f8893942060fe3cfb04ac374cda96fdfc8f453 /plugins/rdp/rdp_monitor.c
parentInitial commit. (diff)
downloadremmina-2dad5357405ad33cfa792f04b3ab62a5d188841e.tar.xz
remmina-2dad5357405ad33cfa792f04b3ab62a5d188841e.zip
Adding upstream version 1.4.34+dfsg.upstream/1.4.34+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/rdp/rdp_monitor.c')
-rw-r--r--plugins/rdp/rdp_monitor.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/plugins/rdp/rdp_monitor.c b/plugins/rdp/rdp_monitor.c
new file mode 100644
index 0000000..4aaf413
--- /dev/null
+++ b/plugins/rdp/rdp_monitor.c
@@ -0,0 +1,231 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2016-2020 Antenore Gatta, Giovanni Panozzo
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. * If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. * If you
+ * do not wish to do so, delete this exception statement from your
+ * version. * If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ *
+ */
+
+#include "rdp_plugin.h"
+#include "rdp_monitor.h"
+
+/** @ToDo Utility functions should be moved somewhere else */
+gint remmina_rdp_utils_strpos(const gchar *haystack, const gchar *needle)
+{
+ TRACE_CALL(__func__);
+ const gchar *sub;
+
+ if (!*needle)
+ return -1;
+
+ sub = strstr(haystack, needle);
+ if (!sub)
+ return -1;
+
+ return sub - haystack;
+}
+
+/* https://github.com/adlocode/xfwm4/blob/1d21be9ffc0fa1cea91905a07d1446c5227745f4/common/xfwm-common.c */
+
+
+/**
+ * Set the MonitorIDs, the maxwidth and maxheight
+ *
+ * - number of monitors
+ * - Geometry of each
+ * - Choosen by the user
+ * - Primary monitor
+ * - Otherwise use current monitor as the origin
+ *
+ * The origin must be 0,0
+ */
+void remmina_rdp_monitor_get (rfContext *rfi, gchar **monitorids, guint32 *maxwidth, guint32 *maxheight)
+{
+ TRACE_CALL(__func__);
+
+ GdkDisplay *display;
+ GdkMonitor *monitor;
+ gboolean has_custom_monitors = FALSE;
+
+ gboolean primary_found = FALSE;
+
+ gint n_monitors;
+ gint scale;
+ gint index = 0;
+ gint count = 0;
+
+ static gchar buffer[256];
+ gint buffer_offset = 0;
+
+ GdkRectangle geometry = { 0, 0, 0, 0 };
+ GdkRectangle tempgeom = { 0, 0, 0, 0 };
+ GdkRectangle destgeom = { 0, 0, 0, 0 };
+ rdpSettings* settings;
+ if (!rfi || !rfi->clientContext.context.settings)
+ return;
+
+ settings = rfi->clientContext.context.settings;
+
+ *maxwidth = freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth);
+ *maxheight = freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight);
+
+ display = gdk_display_get_default ();
+ n_monitors = gdk_display_get_n_monitors(display);
+
+ /* Get monitor at windows curently in use */
+ //w = gtk_widget_get_window(rfi->drawing_area);
+
+ //current_monitor = gdk_display_get_monitor_at_window (display, w);
+
+ /* we got monitorids as options */
+ if (*monitorids)
+ has_custom_monitors = TRUE;
+
+ rdpMonitor* base = (rdpMonitor *)freerdp_settings_get_pointer(settings, FreeRDP_MonitorDefArray);
+ for (gint i = 0; i < n_monitors; ++i) {
+ rdpMonitor* current;
+ if (has_custom_monitors) {
+ REMMINA_PLUGIN_DEBUG("We have custom monitors");
+ gchar itoc[11];
+ snprintf(itoc, sizeof(itoc), "%d", i);
+ if (remmina_rdp_utils_strpos(*monitorids, itoc) < 0 ) {
+ REMMINA_PLUGIN_DEBUG("Monitor n %d it's out of the provided list", i);
+ index += 1;
+ continue;
+ }
+ }
+
+ monitor = gdk_display_get_monitor(display, i);
+ if (monitor == NULL) {
+ REMMINA_PLUGIN_DEBUG("Monitor n %d does not exist or is not active", i);
+ index +=1;
+ continue;
+ }
+
+ monitor = gdk_display_get_monitor(display, index);
+ current = &base[index];
+ REMMINA_PLUGIN_DEBUG("Monitor n %d", index);
+ /* If the desktop env in use doesn't have the working area concept
+ * gdk_monitor_get_workarea will return the monitor geometry*/
+ //gdk_monitor_get_workarea (monitor, &geometry);
+ gdk_monitor_get_geometry (monitor, &geometry);
+ current->x = geometry.x;
+ REMMINA_PLUGIN_DEBUG("Monitor n %d x: %d", index, geometry.x);
+ current->y = geometry.y;
+ REMMINA_PLUGIN_DEBUG("Monitor n %d y: %d", index, geometry.y);
+ /* geometry contain the application geometry, to obtain the real one
+ * we must multiply by the scale factor */
+ scale = gdk_monitor_get_scale_factor (monitor);
+ REMMINA_PLUGIN_DEBUG("Monitor n %d scale: %d", index, scale);
+ geometry.x *= scale;
+ geometry.y *= scale;
+ geometry.width *= scale;
+ geometry.height *= scale;
+ REMMINA_PLUGIN_DEBUG("Monitor n %d width: %d", index, geometry.width);
+ REMMINA_PLUGIN_DEBUG("Monitor n %d height: %d", index, geometry.height);
+ current->width = geometry.width;
+ current->height = geometry.height;
+ current->attributes.physicalHeight = gdk_monitor_get_height_mm (monitor);
+ REMMINA_PLUGIN_DEBUG("Monitor n %d physical height: %d", i, current->attributes.physicalHeight);
+ current->attributes.physicalWidth = gdk_monitor_get_width_mm (monitor);
+ REMMINA_PLUGIN_DEBUG("Monitor n %d physical width: %d", i, current->attributes.physicalWidth);
+ current->orig_screen = index;
+ if (!primary_found) {
+ freerdp_settings_set_uint32(settings, FreeRDP_MonitorLocalShiftX, current->x);
+ freerdp_settings_set_uint32(settings, FreeRDP_MonitorLocalShiftY, current->y);
+ }
+ if (gdk_monitor_is_primary(monitor)) {
+ REMMINA_PLUGIN_DEBUG ("Primary monitor found with id: %d", index);
+ current->is_primary = TRUE;
+ primary_found = TRUE;
+ if (current->x != 0 || current->y != 0)
+ {
+ REMMINA_PLUGIN_DEBUG ("Primary monitor not at 0,0 coordinates: %d", index);
+ freerdp_settings_set_uint32(settings, FreeRDP_MonitorLocalShiftX, current->x);
+ freerdp_settings_set_uint32(settings, FreeRDP_MonitorLocalShiftY, current->y);
+ }
+ } else {
+ if (!primary_found && current->x == 0 &&
+ current->y == 0)
+ {
+ REMMINA_PLUGIN_DEBUG ("Monitor %d has 0,0 coordinates", index);
+ current->is_primary = TRUE;
+ freerdp_settings_set_uint32(settings, FreeRDP_MonitorLocalShiftX, current->x);
+ freerdp_settings_set_uint32(settings, FreeRDP_MonitorLocalShiftY, current->y);
+ primary_found = TRUE;
+ REMMINA_PLUGIN_DEBUG ("Primary monitor set to id: %d", index);
+ }
+ }
+ REMMINA_PLUGIN_DEBUG ("Local X Shift: %d", freerdp_settings_get_uint32(settings, FreeRDP_MonitorLocalShiftX));
+ REMMINA_PLUGIN_DEBUG ("Local Y Shift: %d", freerdp_settings_get_uint32(settings, FreeRDP_MonitorLocalShiftY));
+ //current->x =
+ //current->x - freerdp_settings_get_uint32(settings, FreeRDP_MonitorLocalShiftX);
+ //REMMINA_PLUGIN_DEBUG("Monitor n %d calculated x: %d", index, current->x);
+ //current->y =
+ //current->y - freerdp_settings_get_uint32(settings, FreeRDP_MonitorLocalShiftY);
+ //REMMINA_PLUGIN_DEBUG("Monitor n %d calculated y: %d", index, current->y);
+
+ if (buffer_offset == 0)
+ buffer_offset = g_sprintf(buffer + buffer_offset, "%d", i);
+ else
+ buffer_offset = g_sprintf(buffer + buffer_offset, ",%d", i);
+ REMMINA_PLUGIN_DEBUG("Monitor IDs buffer: %s", buffer);
+ gdk_rectangle_union(&tempgeom, &geometry, &destgeom);
+ memcpy(&tempgeom, &destgeom, sizeof tempgeom);
+ count++;
+ index++;
+
+ }
+ freerdp_settings_set_uint32(settings, FreeRDP_MonitorCount, index);
+ /* Subtract monitor shift from monitor variables for server-side use.
+ * We maintain monitor shift value as Window requires the primary monitor to have a
+ * coordinate of 0,0 In some X configurations, no monitor may have a coordinate of 0,0. This
+ * can also be happen if the user requests specific monitors from the command-line as well.
+ * So, we make sure to translate our primary monitor's upper-left corner to 0,0 on the
+ * server.
+ */
+ for (gint i = 0; i < freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount); i++)
+ {
+ rdpMonitor* current = &base[i];
+ current->x =
+ current->x - freerdp_settings_get_uint32(settings, FreeRDP_MonitorLocalShiftX);
+ REMMINA_PLUGIN_DEBUG("Monitor n %d calculated x: %d", i, current->x);
+ current->y =
+ current->y - freerdp_settings_get_uint32(settings, FreeRDP_MonitorLocalShiftY);
+ REMMINA_PLUGIN_DEBUG("Monitor n %d calculated y: %d", i, current->y);
+ }
+
+ REMMINA_PLUGIN_DEBUG("%d monitors on %d have been configured", freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount), count);
+ *maxwidth = destgeom.width;
+ *maxheight = destgeom.height;
+ REMMINA_PLUGIN_DEBUG("maxw and maxh: %ux%u", *maxwidth, *maxheight);
+ if (n_monitors > 1)
+ freerdp_settings_set_bool(rfi->clientContext.context.settings, FreeRDP_SupportMonitorLayoutPdu, TRUE);
+ *monitorids = g_strdup(buffer);
+}