Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/Remmina/remmina-plugins.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntenore Gatta (tmow) <antenore@simbiosi.org>2021-06-30 08:14:53 +0300
committerAntenore Gatta (tmow) <antenore@simbiosi.org>2021-06-30 08:14:53 +0300
commitae75b74ca7215fc44eee5558b51262e99a504fd8 (patch)
treed085f8ad87a6395e2b53bd3be1c6dde0689989b4
parent34c174020b10d10d00c277ee922254d3654868dd (diff)
parent73724a5c0412cf8259aab65491b025e166b9a202 (diff)
Add 'plugins/xdmcp/' from commit '73724a5c0412cf8259aab65491b025e166b9a202'
git-subtree-dir: plugins/xdmcp git-subtree-mainline: 34c174020b10d10d00c277ee922254d3654868dd git-subtree-split: 73724a5c0412cf8259aab65491b025e166b9a202
-rw-r--r--plugins/xdmcp/CMakeLists.txt54
-rw-r--r--plugins/xdmcp/scalable/emblems/remmina-xdmcp-ssh-symbolic.svg89
-rw-r--r--plugins/xdmcp/scalable/emblems/remmina-xdmcp-symbolic.svg109
-rw-r--r--plugins/xdmcp/xdmcp_plugin.c425
4 files changed, 677 insertions, 0 deletions
diff --git a/plugins/xdmcp/CMakeLists.txt b/plugins/xdmcp/CMakeLists.txt
new file mode 100644
index 0000000..df0f09c
--- /dev/null
+++ b/plugins/xdmcp/CMakeLists.txt
@@ -0,0 +1,54 @@
+# remmina-plugin-xdmcp - The GTK+ Remote Desktop Client
+#
+# Copyright (C) 2011 Marc-Andre Moreau
+# Copyright (C) 2014-2021 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.
+
+
+set(REMMINA_PLUGIN_XDMCP_SRCS xdmcp_plugin.c)
+
+add_library(remmina-plugin-xdmcp MODULE ${REMMINA_PLUGIN_XDMCP_SRCS})
+set_target_properties(remmina-plugin-xdmcp PROPERTIES PREFIX "")
+set_target_properties(remmina-plugin-xdmcp PROPERTIES NO_SONAME 1)
+
+include_directories(${REMMINA_COMMON_INCLUDE_DIRS})
+target_link_libraries(remmina-plugin-xdmcp ${REMMINA_COMMON_LIBRARIES})
+
+install(TARGETS remmina-plugin-xdmcp DESTINATION ${REMMINA_PLUGINDIR})
+
+
+install(FILES
+ scalable/emblems/remmina-xdmcp-ssh-symbolic.svg
+ scalable/emblems/remmina-xdmcp-symbolic.svg
+ DESTINATION ${APPICONSCALE_EMBLEMS_DIR})
+
+if(WITH_ICON_CACHE)
+ gtk_update_icon_cache("${REMMINA_DATADIR}/icons/hicolor")
+endif()
diff --git a/plugins/xdmcp/scalable/emblems/remmina-xdmcp-ssh-symbolic.svg b/plugins/xdmcp/scalable/emblems/remmina-xdmcp-ssh-symbolic.svg
new file mode 100644
index 0000000..d76baf8
--- /dev/null
+++ b/plugins/xdmcp/scalable/emblems/remmina-xdmcp-ssh-symbolic.svg
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ viewBox="0 0 26.458334 26.458332"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.2 2405546, 2018-03-11"
+ sodipodi:docname="remmina-xdmcp-ssh-symbolic.svg">
+ <defs
+ id="defs2" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="25.558198"
+ inkscape:cy="61.982189"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:document-rotation="0"
+ showgrid="false"
+ borderlayer="true"
+ inkscape:showpageshadow="true"
+ units="px"
+ inkscape:pagecheckerboard="false"
+ showguides="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1041"
+ inkscape:window-x="1600"
+ inkscape:window-y="18"
+ inkscape:window-maximized="0"
+ objecttolerance="10"
+ guidetolerance="10"
+ inkscape:snap-tangential="true"
+ inkscape:snap-perpendicular="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid10"
+ dotted="false"
+ originx="-179.27136"
+ originy="-128.69822" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <cc:license
+ rdf:resource="" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-179.27135,-141.84345)">
+ <g
+ id="g817"
+ transform="matrix(0.93878631,0,0,0.93878631,13.549948,10.22929)">
+ <path
+ style="isolation:isolate;fill:#000000;stroke-width:0.93878627"
+ d="M 49.884766 0.27539062 C 34.886727 0.27539062 22.888672 12.506314 22.888672 27.273438 L 22.888672 32.117188 L 9.7363281 32.117188 L 9.7363281 99.724609 L 31.220703 99.724609 L 90.263672 99.724609 L 90.263672 32.117188 L 76.880859 32.117188 L 76.880859 27.273438 C 76.880859 12.275364 64.651854 0.27539062 49.884766 0.27539062 z M 49.654297 14.582031 C 56.806908 14.582031 62.34375 20.350818 62.34375 27.273438 L 62.34375 32.117188 L 36.732422 32.117188 L 36.732422 27.273438 L 36.962891 27.273438 C 36.962891 20.119868 42.732636 14.582031 49.654297 14.582031 z M 19.505859 35.171875 L 35.611328 35.171875 L 49.972656 54.789062 L 64.388672 35.171875 L 80.494141 35.171875 L 58.105469 65.525391 L 81.126953 96.828125 L 65.023438 96.828125 L 49.972656 76.427734 L 34.976562 96.828125 L 18.873047 96.828125 L 42 65.525391 L 19.505859 35.171875 z "
+ transform="matrix(0.28183552,0,0,0.28183552,176.52729,140.19608)"
+ id="path79" />
+ </g>
+ </g>
+</svg>
diff --git a/plugins/xdmcp/scalable/emblems/remmina-xdmcp-symbolic.svg b/plugins/xdmcp/scalable/emblems/remmina-xdmcp-symbolic.svg
new file mode 100644
index 0000000..f27500d
--- /dev/null
+++ b/plugins/xdmcp/scalable/emblems/remmina-xdmcp-symbolic.svg
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ viewBox="0 0 26.458334 26.458333"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.2 2405546, 2018-03-11"
+ sodipodi:docname="remmina-xdmcp-symbolic.svg">
+ <defs
+ id="defs2" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.74199836"
+ inkscape:cx="-124.28004"
+ inkscape:cy="-28.204733"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:document-rotation="0"
+ showgrid="false"
+ borderlayer="true"
+ inkscape:showpageshadow="true"
+ units="px"
+ inkscape:pagecheckerboard="false"
+ showguides="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1041"
+ inkscape:window-x="1600"
+ inkscape:window-y="18"
+ inkscape:window-maximized="0"
+ objecttolerance="10"
+ guidetolerance="10"
+ inkscape:snap-tangential="true"
+ inkscape:snap-perpendicular="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid10"
+ dotted="false"
+ originx="-190.61239"
+ originy="-78.157086" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <cc:license
+ rdf:resource="" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-190.61238,-192.38458)">
+ <g
+ transform="matrix(0.26458333,0,0,0.26458333,153.78079,124.26165)"
+ style="isolation:isolate"
+ id="RDP Icons">
+ <g
+ id="Group" />
+ <g
+ id="g50">
+ <path
+ style="fill:#000000"
+ d="M 50 0.41992188 C 22.636001 0.41992188 0.41992188 22.636001 0.41992188 50 C 0.41992188 77.363999 22.636001 99.580078 50 99.580078 C 77.363999 99.580078 99.580078 77.363999 99.580078 50 C 99.580078 22.636001 77.363999 0.41992188 50 0.41992188 z M 19.505859 19.171875 L 35.611328 19.171875 L 49.972656 38.787109 L 64.388672 19.171875 L 80.494141 19.171875 L 58.105469 49.525391 L 81.126953 80.828125 L 65.023438 80.828125 L 49.972656 60.427734 L 34.976562 80.828125 L 18.873047 80.828125 L 42 49.525391 L 19.505859 19.171875 z "
+ transform="translate(139.20601,257.47249)"
+ id="path48" />
+ </g>
+ <g
+ id="g62">
+ <g
+ id="g52" />
+ <g
+ id="g54" />
+ <g
+ id="g56" />
+ <g
+ id="g60">
+ <g
+ id="g58" />
+ </g>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/plugins/xdmcp/xdmcp_plugin.c b/plugins/xdmcp/xdmcp_plugin.c
new file mode 100644
index 0000000..8e4fce3
--- /dev/null
+++ b/plugins/xdmcp/xdmcp_plugin.c
@@ -0,0 +1,425 @@
+/*
+ * Remmina - The GTK Remote Desktop Client
+ * Copyright (C) 2010 Vic Lee
+ * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
+ * Copyright (C) 2016-2021 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 "common/remmina_plugin.h"
+#include <gtk/gtkx.h>
+
+INCLUDE_GET_AVAILABLE_XDISPLAY
+
+#define REMMINA_PLUGIN_XDMCP_FEATURE_TOOL_SENDCTRLALTDEL 1
+#define REMMINA_PLUGIN_XDMCP_FEATURE_GTKSOCKET 1
+
+#define GET_PLUGIN_DATA(gp) (RemminaPluginXdmcpData*)g_object_get_data(G_OBJECT(gp), "plugin-data");
+
+/* Forward declaration */
+static RemminaProtocolPlugin remmina_plugin_xdmcp;
+
+typedef struct _RemminaPluginXdmcpData {
+ GtkWidget *socket;
+ gint socket_id;
+ GPid pid;
+ gint output_fd;
+ gint error_fd;
+ gint display;
+ gboolean ready;
+
+ pthread_t thread;
+
+} RemminaPluginXdmcpData;
+
+static RemminaPluginService *remmina_plugin_service = NULL;
+
+
+static void remmina_plugin_xdmcp_on_plug_added(GtkSocket *socket, RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ RemminaPluginXdmcpData *gpdata = GET_PLUGIN_DATA(gp);
+
+ remmina_plugin_service->protocol_plugin_signal_connection_opened(gp);
+ gpdata->ready = TRUE;
+}
+
+static void remmina_plugin_xdmcp_on_plug_removed(GtkSocket *socket, RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ remmina_plugin_service->protocol_plugin_signal_connection_closed(gp);
+}
+
+static gboolean remmina_plugin_xdmcp_start_xephyr(RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ RemminaPluginXdmcpData *gpdata = GET_PLUGIN_DATA(gp);
+ RemminaFile *remminafile;
+ gchar *argv[50];
+ gint argc;
+ gchar *host;
+ gint i;
+ GError *error = NULL;
+ gboolean ret;
+
+ remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
+
+ gpdata->display = remmina_get_available_xdisplay();
+ if (gpdata->display == 0) {
+ remmina_plugin_service->protocol_plugin_set_error(gp, _("Ran out of available local X display numbers."));
+ return FALSE;
+ }
+
+ argc = 0;
+ argv[argc++] = g_strdup("Xephyr");
+
+ argv[argc++] = g_strdup_printf(":%i", gpdata->display);
+
+ argv[argc++] = g_strdup("-parent");
+ argv[argc++] = g_strdup_printf("%i", gpdata->socket_id);
+
+ /* All Xephyr version between 1.5.0 and 1.6.4 will break when "-screen" argument is specified with "-parent".
+ * It’s not possible to support colour depth if you have those Xephyr version. Please see this bug
+ * http://bugs.freedesktop.org/show_bug.cgi?id=24144
+ * As a workaround, a "Default" colour depth will not add the "-screen" argument.
+ */
+ i = remmina_plugin_service->file_get_int(remminafile, "colordepth", 8);
+ if (i >= 8) {
+ argv[argc++] = g_strdup("-screen");
+ argv[argc++] = g_strdup_printf("%ix%ix%i",
+ remmina_plugin_service->get_profile_remote_width(gp),
+ remmina_plugin_service->get_profile_remote_height(gp), i);
+ }
+
+ if (i == 2) {
+ argv[argc++] = g_strdup("-grayscale");
+ }
+
+ if (remmina_plugin_service->file_get_int(remminafile, "showcursor", FALSE)) {
+ argv[argc++] = g_strdup("-host-cursor");
+ }
+ if (remmina_plugin_service->file_get_int(remminafile, "once", FALSE)) {
+ argv[argc++] = g_strdup("-once");
+ }
+ /* Listen on TCP protocol */
+ if (remmina_plugin_service->file_get_int(remminafile, "listen_on_tcp", FALSE)) {
+ argv[argc++] = g_strdup("-listen");
+ argv[argc++] = g_strdup("tcp");
+ }
+
+ if (!remmina_plugin_service->file_get_int(remminafile, "ssh_tunnel_enabled", FALSE)) {
+ remmina_plugin_service->get_server_port(remmina_plugin_service->file_get_string(remminafile, "server"), 0,
+ &host, &i);
+
+ argv[argc++] = g_strdup("-query");
+ argv[argc++] = host;
+
+ if (i) {
+ argv[argc++] = g_strdup("-port");
+ argv[argc++] = g_strdup_printf("%i", i);
+ }
+ }else {
+ /* When the connection is through an SSH tunnel, it connects back to local Unix socket,
+ * so for security we can disable TCP listening */
+ argv[argc++] = g_strdup("-nolisten");
+ argv[argc++] = g_strdup("tcp");
+
+ /* FIXME: It’s better to get the magic cookie back from xqproxy, then call xauth,
+ * instead of disable access control */
+ argv[argc++] = g_strdup("-ac");
+ }
+
+ argv[argc++] = NULL;
+
+ ret = g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &gpdata->pid, &error);
+ for (i = 0; i < argc; i++)
+ g_free(argv[i]);
+
+ if (!ret) {
+ remmina_plugin_service->protocol_plugin_set_error(gp, "%s", error->message);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean remmina_plugin_xdmcp_tunnel_init_callback(RemminaProtocolWidget *gp, gint remotedisplay, const gchar *server,
+ gint port)
+{
+ TRACE_CALL(__func__);
+ RemminaPluginXdmcpData *gpdata = GET_PLUGIN_DATA(gp);
+ RemminaFile *remminafile;
+
+ remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
+
+ if (!remmina_plugin_xdmcp_start_xephyr(gp))
+ return FALSE;
+ while (!gpdata->ready)
+ sleep(1);
+
+ remmina_plugin_service->protocol_plugin_set_display(gp, gpdata->display);
+
+ if (remmina_plugin_service->file_get_string(remminafile, "exec")) {
+ return remmina_plugin_service->protocol_plugin_ssh_exec(gp, FALSE, "DISPLAY=localhost:%i.0 %s", remotedisplay,
+ remmina_plugin_service->file_get_string(remminafile, "exec"));
+ }else {
+ return remmina_plugin_service->protocol_plugin_ssh_exec(gp, TRUE,
+ "xqproxy -display %i -host %s -port %i -query -manage", remotedisplay, server, port);
+ }
+}
+
+static gboolean remmina_plugin_xdmcp_main(RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ RemminaPluginXdmcpData *gpdata = GET_PLUGIN_DATA(gp);
+ RemminaFile *remminafile;
+
+ remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
+
+ if (remmina_plugin_service->file_get_int(remminafile, "ssh_tunnel_enabled", FALSE)) {
+ if (!remmina_plugin_service->protocol_plugin_start_xport_tunnel(gp, remmina_plugin_xdmcp_tunnel_init_callback)) {
+ gpdata->thread = 0;
+ return FALSE;
+ }
+ }else {
+ if (!remmina_plugin_xdmcp_start_xephyr(gp)) {
+ gpdata->thread = 0;
+ return FALSE;
+ }
+ }
+
+ gpdata->thread = 0;
+ return TRUE;
+}
+
+static gpointer
+remmina_plugin_xdmcp_main_thread(gpointer data)
+{
+ TRACE_CALL(__func__);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+
+ CANCEL_ASYNC
+ if (!remmina_plugin_xdmcp_main((RemminaProtocolWidget*)data)) {
+ IDLE_ADD((GSourceFunc)remmina_plugin_service->protocol_plugin_signal_connection_closed, data);
+ }
+ return NULL;
+}
+
+static void remmina_plugin_xdmcp_init(RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ RemminaPluginXdmcpData *gpdata;
+
+ gpdata = g_new0(RemminaPluginXdmcpData, 1);
+ g_object_set_data_full(G_OBJECT(gp), "plugin-data", gpdata, g_free);
+
+ gpdata->socket = gtk_socket_new();
+ remmina_plugin_service->protocol_plugin_register_hostkey(gp, gpdata->socket);
+ gtk_widget_show(gpdata->socket);
+ g_signal_connect(G_OBJECT(gpdata->socket), "plug-added", G_CALLBACK(remmina_plugin_xdmcp_on_plug_added), gp);
+ g_signal_connect(G_OBJECT(gpdata->socket), "plug-removed", G_CALLBACK(remmina_plugin_xdmcp_on_plug_removed), gp);
+ gtk_container_add(GTK_CONTAINER(gp), gpdata->socket);
+
+}
+
+
+
+static gboolean remmina_plugin_xdmcp_open_connection(RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ RemminaPluginXdmcpData *gpdata = GET_PLUGIN_DATA(gp);
+ RemminaFile *remminafile;
+ gint width, height;
+
+ if (!remmina_plugin_service->gtksocket_available()) {
+ remmina_plugin_service->protocol_plugin_set_error(gp,
+ _("The protocol “%s” is unavailable because GtkSocket only works under X.Org."),
+ remmina_plugin_xdmcp.name);
+ return FALSE;
+ }
+
+ remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
+
+ width = remmina_plugin_service->get_profile_remote_width(gp);
+ height = remmina_plugin_service->get_profile_remote_height(gp);
+ remmina_plugin_service->protocol_plugin_set_width(gp, width);
+ remmina_plugin_service->protocol_plugin_set_height(gp, height);
+ gtk_widget_set_size_request(GTK_WIDGET(gp), width, height);
+ gpdata->socket_id = gtk_socket_get_id(GTK_SOCKET(gpdata->socket));
+
+
+ if (remmina_plugin_service->file_get_int(remminafile, "ssh_tunnel_enabled", FALSE)) {
+ if (pthread_create(&gpdata->thread, NULL, remmina_plugin_xdmcp_main_thread, gp)) {
+ remmina_plugin_service->protocol_plugin_set_error(gp,
+ "Could not start pthread. Using non-threaded mode instead…");
+ gpdata->thread = 0;
+ return FALSE;
+ }else {
+ return TRUE;
+ }
+ }else {
+ return remmina_plugin_xdmcp_main(gp);
+ }
+
+}
+
+static gboolean remmina_plugin_xdmcp_close_connection(RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ RemminaPluginXdmcpData *gpdata = GET_PLUGIN_DATA(gp);
+
+ if (gpdata->thread) {
+ pthread_cancel(gpdata->thread);
+ if (gpdata->thread) pthread_join(gpdata->thread, NULL);
+ }
+
+ if (gpdata->pid) {
+ kill(gpdata->pid, SIGTERM);
+ g_spawn_close_pid(gpdata->pid);
+ gpdata->pid = 0;
+ }
+
+ remmina_plugin_service->protocol_plugin_signal_connection_closed(gp);
+
+ return FALSE;
+}
+
+/* Send Ctrl+Alt+Del keystrokes to the plugin socket widget */
+static void remmina_plugin_xdmcp_send_ctrlaltdel(RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ guint keys[] = { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_Delete };
+ RemminaPluginXdmcpData *gpdata = GET_PLUGIN_DATA(gp);
+
+ remmina_plugin_service->protocol_plugin_send_keys_signals(gpdata->socket,
+ keys, G_N_ELEMENTS(keys), GDK_KEY_PRESS | GDK_KEY_RELEASE);
+}
+
+static gboolean remmina_plugin_xdmcp_query_feature(RemminaProtocolWidget *gp, const RemminaProtocolFeature *feature)
+{
+ TRACE_CALL(__func__);
+ return TRUE;
+}
+
+static void remmina_plugin_xdmcp_call_feature(RemminaProtocolWidget *gp, const RemminaProtocolFeature *feature)
+{
+ TRACE_CALL(__func__);
+
+ switch (feature->id) {
+ case REMMINA_PLUGIN_XDMCP_FEATURE_TOOL_SENDCTRLALTDEL:
+ remmina_plugin_xdmcp_send_ctrlaltdel(gp);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Array of key/value pairs for colour depths */
+static gpointer colordepth_list[] =
+{
+ "0", N_("Default"),
+ "2", N_("Grayscale"),
+ "8", N_("256 colours"),
+ "16", N_("High colour (16 bit)"),
+ "24", N_("True colour (24 bit)"),
+ NULL
+};
+
+/* Array of RemminaProtocolSetting for basic settings.
+ * Each item is composed by:
+ * a) RemminaProtocolSettingType for setting type
+ * b) Setting name
+ * c) Setting description
+ * d) Compact disposition
+ * e) Values for REMMINA_PROTOCOL_SETTING_TYPE_SELECT or REMMINA_PROTOCOL_SETTING_TYPE_COMBO
+ * f) Setting tooltip
+ */
+static const RemminaProtocolSetting remmina_plugin_xdmcp_basic_settings[] =
+{
+ { REMMINA_PROTOCOL_SETTING_TYPE_SERVER, "server", NULL, FALSE, NULL, NULL },
+ { REMMINA_PROTOCOL_SETTING_TYPE_RESOLUTION, "resolution", NULL, FALSE, NULL, NULL },
+ { REMMINA_PROTOCOL_SETTING_TYPE_SELECT, "colordepth", N_("Colour depth"), FALSE, colordepth_list, NULL },
+ { REMMINA_PROTOCOL_SETTING_TYPE_TEXT, "exec", N_("Start-up program"), FALSE, NULL, NULL },
+ { REMMINA_PROTOCOL_SETTING_TYPE_CHECK, "showcursor", N_("Use local cursor"), FALSE, NULL, NULL },
+ { REMMINA_PROTOCOL_SETTING_TYPE_CHECK, "once", N_("Disconnect after first session"), FALSE, NULL, NULL },
+ { REMMINA_PROTOCOL_SETTING_TYPE_CHECK, "listen_on_tcp", N_("Listen for TCP connections"), FALSE, NULL, NULL },
+ { REMMINA_PROTOCOL_SETTING_TYPE_END, NULL, NULL, FALSE, NULL, NULL }
+};
+
+/* Array for available features.
+ * The last element of the array must be REMMINA_PROTOCOL_FEATURE_TYPE_END. */
+static const RemminaProtocolFeature remmina_plugin_xdmcp_features[] =
+{
+ { REMMINA_PROTOCOL_FEATURE_TYPE_TOOL, REMMINA_PLUGIN_XDMCP_FEATURE_TOOL_SENDCTRLALTDEL, N_("Send Ctrl+Alt+Delete"), NULL, NULL },
+ { REMMINA_PROTOCOL_FEATURE_TYPE_GTKSOCKET, REMMINA_PLUGIN_XDMCP_FEATURE_GTKSOCKET, NULL, NULL, NULL},
+ { REMMINA_PROTOCOL_FEATURE_TYPE_END, 0, NULL, NULL, NULL }
+};
+
+/* Protocol plugin definition and features */
+static RemminaProtocolPlugin remmina_plugin_xdmcp =
+{
+ REMMINA_PLUGIN_TYPE_PROTOCOL, // Type
+ "XDMCP", // Name
+ N_("XDMCP - X Remote Session"), // Description
+ GETTEXT_PACKAGE, // Translation domain
+ VERSION, // Version number
+ "remmina-xdmcp-symbolic", // Icon for normal connection
+ "remmina-xdmcp-ssh-symbolic", // Icon for SSH connection
+ remmina_plugin_xdmcp_basic_settings, // Array for basic settings
+ NULL, // Array for advanced settings
+ REMMINA_PROTOCOL_SSH_SETTING_TUNNEL, // SSH settings type
+ remmina_plugin_xdmcp_features, // Array for available features
+ remmina_plugin_xdmcp_init, // Plugin initialization
+ remmina_plugin_xdmcp_open_connection, // Plugin open connection
+ remmina_plugin_xdmcp_close_connection, // Plugin close connection
+ remmina_plugin_xdmcp_query_feature, // Query for available features
+ remmina_plugin_xdmcp_call_feature, // Call a feature
+ NULL, // Send a keystroke
+ NULL, // No screenshot support available
+ NULL, // RCW map event
+ NULL // RCW unmap event
+};
+
+G_MODULE_EXPORT gboolean
+remmina_plugin_entry(RemminaPluginService *service)
+{
+ TRACE_CALL(__func__);
+ remmina_plugin_service = service;
+
+ bindtextdomain(GETTEXT_PACKAGE, REMMINA_RUNTIME_LOCALEDIR);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+
+ if (!service->register_plugin((RemminaPlugin*)&remmina_plugin_xdmcp)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}