diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 17:06:32 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 17:06:32 +0000 |
commit | 2dad5357405ad33cfa792f04b3ab62a5d188841e (patch) | |
tree | b8f8893942060fe3cfb04ac374cda96fdfc8f453 /plugins/rdp/rdp_monitor.c | |
parent | Initial commit. (diff) | |
download | remmina-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.c | 231 |
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); +} |