From 2dad5357405ad33cfa792f04b3ab62a5d188841e Mon Sep 17 00:00:00 2001
From: Daniel Baumann <daniel.baumann@progress-linux.org>
Date: Sat, 27 Apr 2024 19:06:32 +0200
Subject: Adding upstream version 1.4.34+dfsg.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
---
 plugins/telepathy/CMakeLists.txt                   |  66 ++++
 plugins/telepathy/Remmina.client                   |   8 +
 ...freedesktop.Telepathy.Client.Remmina.service.in |   3 +
 plugins/telepathy/telepathy_channel_handler.c      | 373 +++++++++++++++++++++
 plugins/telepathy/telepathy_channel_handler.h      |  43 +++
 plugins/telepathy/telepathy_handler.c              | 128 +++++++
 plugins/telepathy/telepathy_handler.h              |  57 ++++
 plugins/telepathy/telepathy_plugin.c               |  77 +++++
 8 files changed, 755 insertions(+)
 create mode 100644 plugins/telepathy/CMakeLists.txt
 create mode 100644 plugins/telepathy/Remmina.client
 create mode 100644 plugins/telepathy/org.freedesktop.Telepathy.Client.Remmina.service.in
 create mode 100644 plugins/telepathy/telepathy_channel_handler.c
 create mode 100644 plugins/telepathy/telepathy_channel_handler.h
 create mode 100644 plugins/telepathy/telepathy_handler.c
 create mode 100644 plugins/telepathy/telepathy_handler.h
 create mode 100644 plugins/telepathy/telepathy_plugin.c

(limited to 'plugins/telepathy')

diff --git a/plugins/telepathy/CMakeLists.txt b/plugins/telepathy/CMakeLists.txt
new file mode 100644
index 0000000..0314368
--- /dev/null
+++ b/plugins/telepathy/CMakeLists.txt
@@ -0,0 +1,66 @@
+# remmina-plugin-telepathy - The GTK+ Remote Desktop Client
+#
+# Copyright (C) 2011 Marc-Andre Moreau
+# Copyright (C) 2014-2023 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_TELEPATHY_SRCS
+        telepathy_plugin.c
+        telepathy_handler.c
+        telepathy_channel_handler.c
+        )
+
+add_library(remmina-plugin-telepathy MODULE ${REMMINA_PLUGIN_TELEPATHY_SRCS})
+set_target_properties(remmina-plugin-telepathy PROPERTIES PREFIX "")
+set_target_properties(remmina-plugin-telepathy PROPERTIES NO_SONAME 1)
+
+find_required_package(GTK3)
+pkg_check_modules(PC_DBUS_GLIB dbus-glib-1)
+
+include_directories(${REMMINA_COMMON_INCLUDE_DIRS} ${TELEPATHY_INCLUDE_DIRS})
+target_link_libraries(remmina-plugin-telepathy ${REMMINA_COMMON_LIBRARIES}
+    ${TELEPATHY_LIBRARIES} ${PC_DBUS_GLIB_LIBRARIES})
+
+install(TARGETS remmina-plugin-telepathy DESTINATION ${REMMINA_PLUGINDIR})
+
+# Telepathy client file
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Remmina.client
+    DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/telepathy/clients)
+
+# DBus activation file
+if(NOT REMMINA_BINARY_PATH)
+    set(REMMINA_BINARY_PATH ${CMAKE_INSTALL_FULL_BINDIR}/remmina)
+endif()
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Telepathy.Client.Remmina.service.in
+    ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.Remmina.service @ONLY)
+
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.Remmina.service
+    DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/dbus-1/services)
diff --git a/plugins/telepathy/Remmina.client b/plugins/telepathy/Remmina.client
new file mode 100644
index 0000000..e5baf37
--- /dev/null
+++ b/plugins/telepathy/Remmina.client
@@ -0,0 +1,8 @@
+[org.freedesktop.Telepathy.Client]
+Interfaces=org.freedesktop.Telepathy.Client.Handler;org.freedesktop.Telepathy.Client.Interface.Requests
+
+[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 0]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.StreamTube
+org.freedesktop.Telepathy.Channel.TargetHandleType u=1
+org.freedesktop.Telepathy.Channel.Requested b=false
+org.freedesktop.Telepathy.Channel.Type.StreamTube.Service s=rfb
diff --git a/plugins/telepathy/org.freedesktop.Telepathy.Client.Remmina.service.in b/plugins/telepathy/org.freedesktop.Telepathy.Client.Remmina.service.in
new file mode 100644
index 0000000..95c0cf7
--- /dev/null
+++ b/plugins/telepathy/org.freedesktop.Telepathy.Client.Remmina.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.Telepathy.Client.Remmina
+Exec=@REMMINA_BINARY_PATH@ -x telepathy
diff --git a/plugins/telepathy/telepathy_channel_handler.c b/plugins/telepathy/telepathy_channel_handler.c
new file mode 100644
index 0000000..b690d97
--- /dev/null
+++ b/plugins/telepathy/telepathy_channel_handler.c
@@ -0,0 +1,373 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2010 Vic Lee
+ * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
+ * Copyright (C) 2016-2023 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 <telepathy-glib/account.h>
+#include <telepathy-glib/channel.h>
+#include <telepathy-glib/contact.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/defs.h>
+#include <telepathy-glib/handle.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/svc-client.h>
+#include <telepathy-glib/util.h>
+#include "telepathy_channel_handler.h"
+
+extern RemminaPluginService *remmina_plugin_telepathy_service;
+
+typedef struct _RemminaTpChannelHandler {
+	gchar *connection_path;
+	gchar *channel_path;
+	GHashTable *channel_properties;
+	DBusGMethodInvocation *context;
+
+	GtkWidget *proto_widget;
+	guint disconnect_handler;
+
+	TpDBusDaemon *bus;
+	TpAccount *account;
+	TpConnection *connection;
+	TpChannel *channel;
+
+	gchar *alias;
+	gchar *host;
+	guint port;
+	gchar *protocol;
+} RemminaTpChannelHandler;
+
+static void remmina_tp_channel_handler_free(RemminaTpChannelHandler *chandler)
+{
+	TRACE_CALL(__func__);
+	if (chandler->disconnect_handler) {
+		g_signal_handler_disconnect(chandler->proto_widget, chandler->disconnect_handler);
+		chandler->disconnect_handler = 0;
+	}
+	g_free(chandler->connection_path);
+	g_free(chandler->channel_path);
+	g_hash_table_destroy(chandler->channel_properties);
+	if (chandler->bus) {
+		g_object_unref(chandler->bus);
+	}
+	if (chandler->account) {
+		g_object_unref(chandler->account);
+	}
+	if (chandler->connection) {
+		g_object_unref(chandler->connection);
+	}
+	if (chandler->channel) {
+		g_object_unref(chandler->channel);
+	}
+	if (chandler->alias) {
+		g_free(chandler->alias);
+	}
+	if (chandler->host) {
+		g_free(chandler->host);
+	}
+	if (chandler->protocol) {
+		g_free(chandler->protocol);
+	}
+	g_free(chandler);
+}
+
+static void remmina_tp_channel_handler_channel_closed(TpChannel *channel, gpointer user_data, GObject *self)
+{
+	TRACE_CALL(__func__);
+	RemminaTpChannelHandler *chandler = (RemminaTpChannelHandler*)user_data;
+
+	g_print("%s: %s\n", __func__, chandler->channel_path);
+	remmina_tp_channel_handler_free(chandler);
+}
+
+static void remmina_tp_channel_handler_on_disconnect(GtkWidget *widget, RemminaTpChannelHandler *chandler)
+{
+	TRACE_CALL(__func__);
+	g_print("%s: %s\n", __func__, chandler->channel_path);
+	g_signal_handler_disconnect(widget, chandler->disconnect_handler);
+	chandler->disconnect_handler = 0;
+	tp_cli_channel_call_close(chandler->channel, -1, NULL, NULL, NULL, NULL);
+}
+
+static void remmina_tp_channel_handler_connect(RemminaTpChannelHandler *chandler)
+{
+	TRACE_CALL(__func__);
+	RemminaFile *remminafile;
+	gchar *s;
+
+	remminafile = remmina_plugin_telepathy_service->file_new();
+	remmina_plugin_telepathy_service->file_set_string(remminafile, "name", chandler->alias);
+	remmina_plugin_telepathy_service->file_set_string(remminafile, "protocol", chandler->protocol);
+	s = g_strdup_printf("[%s]:%i", chandler->host, chandler->port);
+	remmina_plugin_telepathy_service->file_set_string(remminafile, "server", s);
+	g_free(s);
+	remmina_plugin_telepathy_service->file_set_int(remminafile, "colordepth", 8);
+
+	g_free(chandler->alias);
+	chandler->alias = NULL;
+	g_free(chandler->protocol);
+	chandler->protocol = NULL;
+
+	chandler->proto_widget = remmina_plugin_telepathy_service->open_connection(remminafile,
+		G_CALLBACK(remmina_tp_channel_handler_on_disconnect), chandler, &chandler->disconnect_handler);
+}
+
+static void remmina_tp_channel_handler_get_service(TpProxy *channel, const GValue *service, const GError *error,
+						   gpointer user_data, GObject *weak_object)
+{
+	TRACE_CALL(__func__);
+	RemminaTpChannelHandler *chandler = (RemminaTpChannelHandler*)user_data;
+	const gchar *svc;
+
+	if (error != NULL) {
+		g_print("%s: %s", __func__, error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+	svc = g_value_get_string(service);
+	g_print("%s: %s %s:%u\n", __func__, svc, chandler->host, chandler->port);
+
+	if (g_strcmp0(svc, "rfb") == 0) {
+		chandler->protocol = g_strdup("VNC");
+	}else  {
+		chandler->protocol = g_ascii_strup(svc, -1);
+	}
+	remmina_tp_channel_handler_connect(chandler);
+}
+
+static void remmina_tp_channel_handler_accept(TpChannel *channel, const GValue *address, const GError *error,
+					      gpointer user_data, GObject *weak_object)
+{
+	TRACE_CALL(__func__);
+	RemminaTpChannelHandler *chandler = (RemminaTpChannelHandler*)user_data;
+
+	if (error != NULL) {
+		g_print("%s: %s", __func__, error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+
+	dbus_g_type_struct_get(address, 0, &chandler->host, 1, &chandler->port, G_MAXUINT);
+
+	tp_cli_dbus_properties_call_get(channel, -1, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "Service",
+		remmina_tp_channel_handler_get_service, chandler, NULL, NULL);
+}
+
+static void remmina_tp_channel_handler_on_response(GtkDialog *dialog, gint response_id, RemminaTpChannelHandler *chandler)
+{
+	TRACE_CALL(__func__);
+	GValue noop =
+	{ 0 };
+	GError *error;
+
+	if (response_id == GTK_RESPONSE_YES) {
+		g_value_init(&noop, G_TYPE_INT);
+		tp_cli_channel_type_stream_tube_call_accept(chandler->channel, -1, TP_SOCKET_ADDRESS_TYPE_IPV4,
+			TP_SOCKET_ACCESS_CONTROL_LOCALHOST, &noop, remmina_tp_channel_handler_accept, chandler, NULL,
+			NULL);
+		g_value_unset(&noop);
+		tp_svc_client_handler_return_from_handle_channels(chandler->context);
+	}else  {
+		error = g_error_new(TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Channel rejected by user.");
+		dbus_g_method_return_error(chandler->context, error);
+		g_error_free(error);
+		remmina_tp_channel_handler_free(chandler);
+	}
+}
+
+static void remmina_tp_channel_handler_get_contacts(TpConnection *connection, guint n_contacts, TpContact * const *contacts,
+						    guint n_failed, const TpHandle *failed, const GError *error, gpointer user_data, GObject *weak_object)
+{
+	TRACE_CALL(__func__);
+	RemminaTpChannelHandler *chandler = (RemminaTpChannelHandler*)user_data;
+	TpContact *contact;
+	gchar *token;
+	const gchar *cm;
+	const gchar *protocol;
+	gchar *filename;
+	GdkPixbuf *pixbuf;
+	GtkWidget *image;
+	GtkWidget *dialog;
+
+	if (error != NULL) {
+		g_print("%s: %s", __func__, error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+	if (n_contacts <= 0) {
+		g_print("%s: no contacts\n", __func__);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+	contact = contacts[0];
+	chandler->alias = g_strdup(tp_contact_get_alias(contact));
+
+	dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
+		_("%s wants to share their desktop.\nDo you accept?"), chandler->alias);
+	g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(remmina_tp_channel_handler_on_response), chandler);
+	g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), NULL);
+	gtk_window_set_title(GTK_WINDOW(dialog), _("Desktop sharing invitation"));
+	remmina_plugin_telepathy_service->ui_register(dialog);
+	gtk_widget_show(dialog);
+
+	token = (gchar*)tp_contact_get_avatar_token(contact);
+	if (token == NULL) {
+		return;
+	}
+	protocol = tp_connection_get_protocol_name(chandler->connection);
+	cm = tp_connection_get_cm_name(chandler->connection);
+	if (!protocol || !cm) {
+		return;
+	}
+	token = tp_escape_as_identifier(token);
+	filename = g_build_filename(g_get_user_cache_dir(), "telepathy", "avatars", cm, protocol, token, NULL);
+	g_free(token);
+	if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
+		pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
+		if (pixbuf) {
+			image = gtk_image_new_from_pixbuf(pixbuf);
+			gtk_widget_show(image);
+			g_object_unref(pixbuf);
+			gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog), image);
+		}
+	}
+	g_free(filename);
+}
+
+static void remmina_tp_channel_handler_channel_ready(TpChannel *channel, const GError *channel_error, gpointer user_data)
+{
+	TRACE_CALL(__func__);
+	RemminaTpChannelHandler *chandler = (RemminaTpChannelHandler*)user_data;
+	TpHandle handle;
+	GError *error = NULL;
+	TpContactFeature features[] =
+	{ TP_CONTACT_FEATURE_ALIAS, TP_CONTACT_FEATURE_AVATAR_TOKEN };
+
+	if (channel_error != NULL) {
+		g_print("%s: %s\n", __func__, channel_error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+
+	if (tp_cli_channel_connect_to_closed(channel, remmina_tp_channel_handler_channel_closed, chandler, NULL, NULL, &error)
+	    == NULL) {
+		g_print("tp_cli_channel_connect_to_closed: %s\n", channel_error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+	g_print("%s: %s\n", __func__, chandler->channel_path);
+
+	handle = tp_channel_get_handle(channel, NULL);
+	tp_connection_get_contacts_by_handle(chandler->connection, 1, &handle, G_N_ELEMENTS(features), features,
+		remmina_tp_channel_handler_get_contacts, chandler, NULL, NULL);
+}
+
+static void remmina_tp_channel_handler_connection_ready(TpConnection *connection, const GError *connection_error,
+							gpointer user_data)
+{
+	TRACE_CALL(__func__);
+	RemminaTpChannelHandler *chandler = (RemminaTpChannelHandler*)user_data;
+	GError *error = NULL;
+
+	if (connection_error != NULL) {
+		g_print("%s: %s\n", __func__, connection_error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+
+	chandler->channel = tp_channel_new_from_properties(connection, chandler->channel_path, chandler->channel_properties,
+		&error);
+	if (chandler->channel == NULL) {
+		g_print("tp_channel_new_from_properties: %s\n", error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+	tp_channel_call_when_ready(chandler->channel, remmina_tp_channel_handler_channel_ready, chandler);
+}
+
+static void remmina_tp_channel_handler_account_ready(GObject *account, GAsyncResult *res, gpointer user_data)
+{
+	TRACE_CALL(__func__);
+	RemminaTpChannelHandler *chandler = (RemminaTpChannelHandler*)user_data;
+	GError *error = NULL;
+
+	if (!tp_account_prepare_finish(TP_ACCOUNT(account), res, &error)) {
+		g_print("tp_account_prepare_finish: %s\n", error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+
+	chandler->connection = tp_connection_new(chandler->bus, NULL, chandler->connection_path, &error);
+	if (chandler->connection == NULL) {
+		g_print("tp_connection_new: %s\n", error->message);
+		remmina_tp_channel_handler_free(chandler);
+		return;
+	}
+	tp_connection_call_when_ready(chandler->connection, remmina_tp_channel_handler_connection_ready, chandler);
+}
+
+void remmina_tp_channel_handler_new(const gchar *account_path, const gchar *connection_path, const gchar *channel_path,
+				    GHashTable *channel_properties, DBusGMethodInvocation *context)
+{
+	TRACE_CALL(__func__);
+	TpDBusDaemon *bus;
+	TpAccount *account;
+	GError *error = NULL;
+	RemminaTpChannelHandler *chandler;
+
+	bus = tp_dbus_daemon_dup(&error);
+	if (bus == NULL) {
+		g_print("tp_dbus_daemon_dup: %s", error->message);
+		return;
+	}
+	account = tp_account_new(bus, account_path, &error);
+	if (account == NULL) {
+		g_object_unref(bus);
+		g_print("tp_account_new: %s", error->message);
+		return;
+	}
+
+	chandler = g_new0(RemminaTpChannelHandler, 1);
+	chandler->bus = bus;
+	chandler->account = account;
+	chandler->connection_path = g_strdup(connection_path);
+	chandler->channel_path = g_strdup(channel_path);
+	chandler->channel_properties = tp_asv_new(NULL, NULL);
+	tp_g_hash_table_update(chandler->channel_properties, channel_properties, (GBoxedCopyFunc)g_strdup,
+		(GBoxedCopyFunc)tp_g_value_slice_dup);
+	chandler->context = context;
+
+	tp_account_prepare_async(account, NULL, remmina_tp_channel_handler_account_ready, chandler);
+}
+
diff --git a/plugins/telepathy/telepathy_channel_handler.h b/plugins/telepathy/telepathy_channel_handler.h
new file mode 100644
index 0000000..675dcae
--- /dev/null
+++ b/plugins/telepathy/telepathy_channel_handler.h
@@ -0,0 +1,43 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2010 Vic Lee
+ * Copyright (C) 2017-2023 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.
+ *
+ */
+
+#pragma once
+
+G_BEGIN_DECLS
+
+void
+remmina_tp_channel_handler_new(const gchar *account_path, const gchar *connection_path, const gchar *channel_path, GHashTable *channel_properties, DBusGMethodInvocation *context);
+
+G_END_DECLS
diff --git a/plugins/telepathy/telepathy_handler.c b/plugins/telepathy/telepathy_handler.c
new file mode 100644
index 0000000..5b3ef6f
--- /dev/null
+++ b/plugins/telepathy/telepathy_handler.c
@@ -0,0 +1,128 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2010 Vic Lee
+ * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
+ * Copyright (C) 2016-2023 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 <gmodule.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/defs.h>
+#include <telepathy-glib/svc-client.h>
+#include "telepathy_channel_handler.h"
+#include "telepathy_handler.h"
+
+extern RemminaPluginService *remmina_plugin_telepathy_service;
+
+#define REMMINA_TP_BUS_NAME TP_CLIENT_BUS_NAME_BASE "Remmina"
+#define REMMINA_TP_OBJECT_PATH TP_CLIENT_OBJECT_PATH_BASE "Remmina"
+
+static void remmina_tp_handler_iface_init(gpointer g_iface, gpointer iface_data);
+
+G_DEFINE_TYPE_WITH_CODE(RemminaTpHandler, remmina_tp_handler, G_TYPE_OBJECT,
+	G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CLIENT, NULL);
+	G_IMPLEMENT_INTERFACE( TP_TYPE_SVC_CLIENT_HANDLER, remmina_tp_handler_iface_init);
+	);
+
+static void remmina_tp_handler_class_init(RemminaTpHandlerClass *klass)
+{
+	TRACE_CALL(__func__);
+}
+
+static void remmina_tp_handler_init(RemminaTpHandler *handler)
+{
+	TRACE_CALL(__func__);
+}
+
+static void remmina_tp_handler_handle_channels(TpSvcClientHandler *handler, const char *account_path,
+					       const char *connection_path, const GPtrArray *channels, const GPtrArray *requests_satisfied,
+					       guint64 user_action_time, GHashTable *handler_info, DBusGMethodInvocation *context)
+{
+	TRACE_CALL(__func__);
+	gint i;
+	GArray *array;
+
+	for (i = 0; i < channels->len; i++) {
+		array = g_ptr_array_index(channels, i);
+		remmina_tp_channel_handler_new(account_path, connection_path,
+			(const gchar*)g_value_get_boxed(&g_array_index(array, GValue, 0)),
+			(GHashTable*)g_value_get_boxed(&g_array_index(array, GValue, 1)), context);
+	}
+}
+
+static void remmina_tp_handler_iface_init(gpointer g_iface, gpointer iface_data)
+{
+	TRACE_CALL(__func__);
+	TpSvcClientHandlerClass *klass = (TpSvcClientHandlerClass*)g_iface;
+
+#define IMPLEMENT(x) tp_svc_client_handler_implement_ ## x(klass, remmina_tp_handler_ ## x)
+	IMPLEMENT(handle_channels);
+#undef IMPLEMENT
+}
+
+static gboolean remmina_tp_handler_register(RemminaTpHandler *handler)
+{
+	TRACE_CALL(__func__);
+	TpDBusDaemon *bus;
+	GError *error = NULL;
+
+	bus = tp_dbus_daemon_dup(&error);
+	if (bus == NULL) {
+		g_print("tp_dbus_daemon_dup: %s", error->message);
+		return FALSE;
+	}
+	if (!tp_dbus_daemon_request_name(bus, REMMINA_TP_BUS_NAME, FALSE, &error)) {
+		g_object_unref(bus);
+		g_print("tp_dbus_daemon_request_name: %s", error->message);
+		return FALSE;
+	}
+	dbus_g_connection_register_g_object(
+		tp_proxy_get_dbus_connection(TP_PROXY(bus)),
+		REMMINA_TP_OBJECT_PATH, G_OBJECT(handler));
+	g_object_unref(bus);
+	g_print("%s: bus_name " REMMINA_TP_BUS_NAME
+		" object_path " REMMINA_TP_OBJECT_PATH "\n", __func__);
+	return TRUE;
+}
+
+RemminaTpHandler*
+remmina_tp_handler_new(void)
+{
+	TRACE_CALL(__func__);
+	RemminaTpHandler *handler;
+
+	handler = REMMINA_TP_HANDLER(g_object_new(REMMINA_TYPE_TP_HANDLER, NULL));
+	remmina_tp_handler_register(handler);
+	return handler;
+}
+
diff --git a/plugins/telepathy/telepathy_handler.h b/plugins/telepathy/telepathy_handler.h
new file mode 100644
index 0000000..c4bfb69
--- /dev/null
+++ b/plugins/telepathy/telepathy_handler.h
@@ -0,0 +1,57 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2010 Vic Lee
+ * Copyright (C) 2017-2023 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.
+ *
+ */
+
+#pragma once
+
+G_BEGIN_DECLS
+
+#define REMMINA_TYPE_TP_HANDLER           (remmina_tp_handler_get_type())
+#define REMMINA_TP_HANDLER(obj)           (G_TYPE_CHECK_INSTANCE_CAST((obj), REMMINA_TYPE_TP_HANDLER, RemminaTpHandler))
+#define REMMINA_TP_HANDLER_CLASS(obj)     (G_TYPE_CHECK_CLASS_CAST((obj), REMMINA_TYPE_TP_HANDLER, RemminaTpHandlerClass))
+#define REMMINA_IS_TP_HANDLER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj), REMMINA_TYPE_TP_HANDLER))
+#define REMMINA_IS_TP_HANDLER_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE((obj), REMMINA_TYPE_TP_HANDLER))
+#define REMMINA_TP_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), REMMINA_TYPE_TP_HANDLER, RemminaTpHandlerClass))
+
+typedef struct _RemminaTpHandler {
+	GObject parent;
+} RemminaTpHandler;
+
+typedef struct _RemminaTpHandlerClass {
+	GObjectClass parent_class;
+} RemminaTpHandlerClass;
+
+RemminaTpHandler *remmina_tp_handler_new(void);
+
+G_END_DECLS
diff --git a/plugins/telepathy/telepathy_plugin.c b/plugins/telepathy/telepathy_plugin.c
new file mode 100644
index 0000000..263096b
--- /dev/null
+++ b/plugins/telepathy/telepathy_plugin.c
@@ -0,0 +1,77 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2010 Vic Lee
+ * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
+ * Copyright (C) 2016-2023 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 "telepathy_handler.h"
+
+RemminaPluginService *remmina_plugin_telepathy_service = NULL;
+
+static RemminaTpHandler *remmina_tp_handler = NULL;
+
+void remmina_plugin_telepathy_entry(void)
+{
+	TRACE_CALL(__func__);
+	if (remmina_tp_handler == NULL) {
+		remmina_tp_handler = remmina_tp_handler_new();
+	}
+}
+
+/* Entry plugin definition and features */
+static RemminaEntryPlugin remmina_plugin_telepathy =
+{
+	REMMINA_PLUGIN_TYPE_ENTRY,                      // Type
+	"telepathy",                                    // Name
+	N_("Telepathy - Desktop Sharing"),              // Description
+	GETTEXT_PACKAGE,                                // Translation domain
+	VERSION,                                        // Version number
+	remmina_plugin_telepathy_entry                  // Plugin entry function
+};
+
+G_MODULE_EXPORT gboolean
+remmina_plugin_entry(RemminaPluginService *service)
+{
+	TRACE_CALL(__func__);
+	remmina_plugin_telepathy_service = service;
+
+	bindtextdomain(GETTEXT_PACKAGE, REMMINA_RUNTIME_LOCALEDIR);
+	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+
+	if (!service->register_plugin((RemminaPlugin*)&remmina_plugin_telepathy)) {
+		return FALSE;
+	}
+	return TRUE;
+}
+
-- 
cgit v1.2.3