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

gitlab.com/Remmina/Remmina.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToolsDevler <info@toolsdevler.net>2022-04-28 20:18:01 +0300
committerToolsDevler <info@toolsdevler.net>2022-04-28 20:24:35 +0300
commit86288afc25aa3f6f6ba5af7252d75c0673ae4819 (patch)
tree646067b765d321ede064145474dc55740ba82ebf
parentc62e93b0f3b24d1505d8375eb4cede33204b348a (diff)
First working version of python as a language wrapperextract-python-plugin
-rw-r--r--plugins/CMakeLists.txt2
-rw-r--r--plugins/python_wrapper/python_wrapper_common.c21
-rw-r--r--plugins/python_wrapper/python_wrapper_common.h12
-rw-r--r--plugins/python_wrapper/python_wrapper_protocol.c18
-rw-r--r--plugins/python_wrapper/python_wrapper_protocol_widget.c6
-rw-r--r--plugins/python_wrapper/python_wrapper_remmina.c7
-rw-r--r--src/CMakeLists.txt44
-rw-r--r--src/include/remmina/plugin.h66
-rw-r--r--src/remmina_language_wrapper.h121
-rw-r--r--src/remmina_plugin_manager.c118
-rw-r--r--src/remmina_plugin_python.c176
-rw-r--r--src/remmina_plugin_python.h80
-rw-r--r--src/remmina_plugin_python_common.c312
-rw-r--r--src/remmina_plugin_python_common.h279
-rw-r--r--src/remmina_plugin_python_entry.c101
-rw-r--r--src/remmina_plugin_python_entry.h61
-rw-r--r--src/remmina_plugin_python_file.c161
-rw-r--r--src/remmina_plugin_python_file.h61
-rw-r--r--src/remmina_plugin_python_pref.c104
-rw-r--r--src/remmina_plugin_python_pref.h61
-rw-r--r--src/remmina_plugin_python_protocol.c317
-rw-r--r--src/remmina_plugin_python_protocol.h107
-rw-r--r--src/remmina_plugin_python_protocol_widget.c846
-rw-r--r--src/remmina_plugin_python_protocol_widget.h63
-rw-r--r--src/remmina_plugin_python_remmina.c1225
-rw-r--r--src/remmina_plugin_python_remmina.h92
-rw-r--r--src/remmina_plugin_python_remmina_file.c205
-rw-r--r--src/remmina_plugin_python_remmina_file.h61
-rw-r--r--src/remmina_plugin_python_secret.c138
-rw-r--r--src/remmina_plugin_python_secret.h67
-rw-r--r--src/remmina_plugin_python_tool.c84
-rw-r--r--src/remmina_plugin_python_tool.h68
-rw-r--r--src/remmina_protocol_widget.c5
-rw-r--r--src/remmina_protocol_widget.h1
34 files changed, 328 insertions, 4762 deletions
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index 1075bd7fd..2b8512d7b 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -169,6 +169,8 @@ if(WITH_NX)
endif()
endif()
+add_subdirectory(python_wrapper)
+
#find_suggested_package(TELEPATHY)
#if(TELEPATHY_FOUND)
#add_subdirectory(telepathy)
diff --git a/plugins/python_wrapper/python_wrapper_common.c b/plugins/python_wrapper/python_wrapper_common.c
index 8185729ac..1b1c77d51 100644
--- a/plugins/python_wrapper/python_wrapper_common.c
+++ b/plugins/python_wrapper/python_wrapper_common.c
@@ -277,14 +277,12 @@ RemminaTypeHint python_wrapper_to_generic(PyObject* field, gpointer* target)
return REMMINA_TYPEHINT_UNDEFINED;
}
-PyPlugin* python_wrapper_get_plugin(RemminaProtocolWidget* gp)
+PyPlugin* python_wrapper_get_plugin(const gchar* name)
{
TRACE_CALL(__func__);
assert(plugin_map);
- assert(gp);
-
- const gchar* name = python_wrapper_get_service()->protocol_widget_get_name(gp);
+ assert(name);
for (gint i = 0; i < plugin_map->len; ++i)
{
@@ -298,6 +296,21 @@ PyPlugin* python_wrapper_get_plugin(RemminaProtocolWidget* gp)
return NULL;
}
+PyPlugin* python_wrapper_get_plugin_by_protocol_widget(RemminaProtocolWidget* gp)
+{
+ TRACE_CALL(__func__);
+
+ assert(plugin_map);
+ assert(gp);
+
+ const gchar* name = python_wrapper_get_service()->protocol_widget_get_name(gp);
+ if (!name) {
+ return NULL;
+ }
+
+ return python_wrapper_get_plugin(name);
+}
+
void init_pygobject()
{
pygobject_init(-1, -1, -1);
diff --git a/plugins/python_wrapper/python_wrapper_common.h b/plugins/python_wrapper/python_wrapper_common.h
index 188b7274c..9831609c4 100644
--- a/plugins/python_wrapper/python_wrapper_common.h
+++ b/plugins/python_wrapper/python_wrapper_common.h
@@ -260,7 +260,17 @@ char* python_wrapper_copy_string_from_python(PyObject* string, Py_ssize_t len);
*
* @return A pointer to a PyPlugin instance if successful. Otherwise NULL is returned.
*/
-PyPlugin* python_wrapper_get_plugin(RemminaProtocolWidget* gp);
+PyPlugin* python_wrapper_get_plugin(const gchar* name);
+
+/**
+ * @brief Tries to find the Python plugin matching to the given instance of RemminaPlugin.
+ *
+ * @param plugin_map An array of PyPlugin pointers to search.
+ * @param instance The RemminaPlugin instance to find the correct PyPlugin instance for.
+ *
+ * @return A pointer to a PyPlugin instance if successful. Otherwise NULL is returned.
+ */
+PyPlugin* python_wrapper_get_plugin_by_protocol_widget(RemminaProtocolWidget* gp);
/**
* Creates a new GtkWidget
diff --git a/plugins/python_wrapper/python_wrapper_protocol.c b/plugins/python_wrapper/python_wrapper_protocol.c
index 911936647..19c90f9a1 100644
--- a/plugins/python_wrapper/python_wrapper_protocol.c
+++ b/plugins/python_wrapper/python_wrapper_protocol.c
@@ -62,7 +62,7 @@ void python_wrapper_protocol_init(void)
void remmina_protocol_init_wrapper(RemminaProtocolWidget* gp)
{
TRACE_CALL(__func__);
- PyPlugin* py_plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* py_plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
py_plugin->gp->gp = gp;
CallPythonMethod(py_plugin->instance, "init", "O", py_plugin->gp);
}
@@ -70,7 +70,7 @@ void remmina_protocol_init_wrapper(RemminaProtocolWidget* gp)
gboolean remmina_protocol_open_connection_wrapper(RemminaProtocolWidget* gp)
{
TRACE_CALL(__func__);
- PyPlugin* py_plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* py_plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
if (py_plugin)
{
PyObject* result = CallPythonMethod(py_plugin->instance, "open_connection", "O", py_plugin->gp);
@@ -85,7 +85,7 @@ gboolean remmina_protocol_open_connection_wrapper(RemminaProtocolWidget* gp)
gboolean remmina_protocol_close_connection_wrapper(RemminaProtocolWidget* gp)
{
TRACE_CALL(__func__);
- PyPlugin* py_plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* py_plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyObject* result = CallPythonMethod(py_plugin->instance, "close_connection", "O", py_plugin->gp);
return result == Py_True;
}
@@ -94,7 +94,7 @@ gboolean remmina_protocol_query_feature_wrapper(RemminaProtocolWidget* gp,
const RemminaProtocolFeature* feature)
{
TRACE_CALL(__func__);
- PyPlugin* py_plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* py_plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyRemminaProtocolFeature* pyFeature = python_wrapper_protocol_feature_new();
pyFeature->type = (gint)feature->type;
pyFeature->id = feature->id;
@@ -116,7 +116,7 @@ gboolean remmina_protocol_query_feature_wrapper(RemminaProtocolWidget* gp,
void remmina_protocol_call_feature_wrapper(RemminaProtocolWidget* gp, const RemminaProtocolFeature* feature)
{
TRACE_CALL(__func__);
- PyPlugin* py_plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* py_plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyRemminaProtocolFeature* pyFeature = python_wrapper_protocol_feature_new();
pyFeature->type = (gint)feature->type;
pyFeature->id = feature->id;
@@ -142,7 +142,7 @@ void remmina_protocol_send_keytrokes_wrapper(RemminaProtocolWidget* gp,
const gint keylen)
{
TRACE_CALL(__func__);
- PyPlugin* py_plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* py_plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyObject* obj = PyList_New(keylen);
Py_IncRef(obj);
for (int i = 0; i < keylen; ++i)
@@ -158,7 +158,7 @@ gboolean remmina_protocol_get_plugin_screenshot_wrapper(RemminaProtocolWidget* g
{
TRACE_CALL(__func__);
- PyPlugin* py_plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* py_plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyRemminaPluginScreenshotData* data = python_wrapper_screenshot_data_new();
Py_IncRef((PyObject*)data);
PyObject* result = CallPythonMethod(py_plugin->instance, "get_plugin_screenshot", "OO", py_plugin->gp, data);
@@ -190,14 +190,14 @@ gboolean remmina_protocol_get_plugin_screenshot_wrapper(RemminaProtocolWidget* g
gboolean remmina_protocol_map_event_wrapper(RemminaProtocolWidget* gp)
{
- PyPlugin* plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyObject* result = CallPythonMethod(plugin->instance, "map_event", "O", plugin->gp);
return PyBool_Check(result) && result == Py_True;
}
gboolean remmina_protocol_unmap_event_wrapper(RemminaProtocolWidget* gp)
{
- PyPlugin* plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyObject* result = CallPythonMethod(plugin->instance, "unmap_event", "O", plugin->gp);
return PyBool_Check(result) && result == Py_True;
}
diff --git a/plugins/python_wrapper/python_wrapper_protocol_widget.c b/plugins/python_wrapper/python_wrapper_protocol_widget.c
index f3e5dae9b..cd46dcc88 100644
--- a/plugins/python_wrapper/python_wrapper_protocol_widget.c
+++ b/plugins/python_wrapper/python_wrapper_protocol_widget.c
@@ -495,7 +495,7 @@ static PyObject* protocol_widget_start_reverse_tunnel(PyRemminaProtocolWidget* s
static gboolean xport_tunnel_init(RemminaProtocolWidget* gp, gint remotedisplay, const gchar* server, gint port)
{
TRACE_CALL(__func__);
- PyPlugin* plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyObject* result = PyObject_CallMethod(plugin->instance, "xport_tunnel_init", "Oisi", gp, remotedisplay, server, port);
return PyObject_IsTrue(result);
}
@@ -758,13 +758,13 @@ static PyObject* protocol_widget_ssh_exec(PyRemminaProtocolWidget* self, PyObjec
static void _on_send_callback_wrapper(RemminaProtocolWidget* gp, const gchar* text)
{
- PyPlugin* plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyObject_CallMethod(plugin->instance, "on_send", "Os", gp, text);
}
static void _on_destroy_callback_wrapper(RemminaProtocolWidget* gp)
{
- PyPlugin* plugin = python_wrapper_get_plugin(gp);
+ PyPlugin* plugin = python_wrapper_get_plugin_by_protocol_widget(gp);
PyObject_CallMethod(plugin->instance, "on_destroy", "O", gp);
}
diff --git a/plugins/python_wrapper/python_wrapper_remmina.c b/plugins/python_wrapper/python_wrapper_remmina.c
index 36dac924c..eeda8d2f1 100644
--- a/plugins/python_wrapper/python_wrapper_remmina.c
+++ b/plugins/python_wrapper/python_wrapper_remmina.c
@@ -811,10 +811,15 @@ static PyObject* remmina_register_plugin_wrapper(PyObject* self, PyObject* plugi
plugin->gp = python_wrapper_protocol_widget_create();
}
- python_wrapper_get_service()->register_plugin((RemminaPlugin*)remmina_plugin);
+ if (python_wrapper_get_service()->register_plugin((RemminaPlugin*)remmina_plugin)) {
+ g_print("%s: Successfully reigstered!\n", remmina_plugin->name);
+ } else {
+ g_print("%s: Failed to reigster!\n", remmina_plugin->name);
+ }
}
}
+ PyErr_Clear();
return Py_None;
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a743f5d9a..8d7ddadbb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -141,50 +141,6 @@ set(RESOURCE_LIST
${CMAKE_CURRENT_SOURCE_DIR}/../data/ui/remmina_spinner.glade
${CMAKE_CURRENT_SOURCE_DIR}/../data/ui/remmina_string_list.glade
${CMAKE_CURRENT_SOURCE_DIR}/../data/ui/remmina_unlock.glade)
-
-option(WITH_PYTHONLIBS "Enable Python plugins support" OFF)
-if(WITH_PYTHONLIBS)
- message(STATUS "Python plugins support enabled")
- find_suggested_package(PythonLibs)
- if(PythonLibs_FOUND)
- message(STATUS "Python libs found, Python support enabled")
- add_definitions(-DWITH_PYTHONLIBS)
- list(FIND REMMINA_SRCS "remmina_exec.c" SRCINDEX)
- message(DEBUG "remmina_exec.c found at index: " ${SRCINDEX})
- # Index calculated at "remmina_exec.c" position (43 as of today)
- list(
- INSERT
- REMMINA_SRCS
- ${SRCINDEX}
- "remmina_plugin_python.c"
- "remmina_plugin_python.h"
- "remmina_plugin_python_protocol.c"
- "remmina_plugin_python_protocol.h"
- "remmina_plugin_python_entry.c"
- "remmina_plugin_python_entry.h"
- "remmina_plugin_python_file.c"
- "remmina_plugin_python_file.h"
- "remmina_plugin_python_secret.c"
- "remmina_plugin_python_secret.h"
- "remmina_plugin_python_tool.c"
- "remmina_plugin_python_tool.h"
- "remmina_plugin_python_pref.c"
- "remmina_plugin_python_pref.h"
- "remmina_plugin_python_common.c"
- "remmina_plugin_python_common.h"
- "remmina_plugin_python_remmina.c"
- "remmina_plugin_python_remmina.h"
- "remmina_plugin_python_protocol_widget.c"
- "remmina_plugin_python_protocol_widget.h"
- "remmina_plugin_python_remmina_file.c"
- "remmina_plugin_python_remmina_file.h")
- else()
- message(STATUS "Python plugins support enabled, but Python libs not found")
- endif()
-else()
- message(STATUS "Python plugins support disabled")
-endif()
-
message(DEBUG "Source list set to: " ${REMMINA_SRCS})
compile_gresources(
diff --git a/src/include/remmina/plugin.h b/src/include/remmina/plugin.h
index c75289af8..0a0433cb0 100644
--- a/src/include/remmina/plugin.h
+++ b/src/include/remmina/plugin.h
@@ -36,6 +36,7 @@
#pragma once
+#include <gtk/gtk.h>
#include <stdarg.h>
#include <remmina/types.h>
#include "remmina/remmina_trace_calls.h"
@@ -48,7 +49,8 @@ typedef enum {
REMMINA_PLUGIN_TYPE_FILE = 2,
REMMINA_PLUGIN_TYPE_TOOL = 3,
REMMINA_PLUGIN_TYPE_PREF = 4,
- REMMINA_PLUGIN_TYPE_SECRET = 5
+ REMMINA_PLUGIN_TYPE_SECRET = 5,
+ REMMINA_PLUGIN_TYPE_LANGUAGE_WRAPPER = 6
} RemminaPluginType;
typedef struct _RemminaPlugin {
@@ -145,6 +147,18 @@ typedef struct _RemminaSecretPlugin {
void (*delete_password)(struct _RemminaSecretPlugin* instance, RemminaFile *remminafile, const gchar *key);
} RemminaSecretPlugin;
+typedef struct _RemminaLanguageWrapperPlugin {
+ RemminaPluginType type;
+ const gchar * name;
+ const gchar * description;
+ const gchar * domain;
+ const gchar * version;
+ const gchar ** supported_extentions;
+
+ gboolean (*init)(struct _RemminaLanguageWrapperPlugin* instance);
+ gboolean (*load)(struct _RemminaLanguageWrapperPlugin* instance, const gchar* plugin_file);
+} RemminaLanguageWrapperPlugin;
+
/* Plugin Service is a struct containing a list of function pointers,
* which is passed from Remmina main program to the plugin module
* through the plugin entry function remmina_plugin_entry() */
@@ -236,6 +250,56 @@ typedef struct _RemminaPluginService {
gboolean (*gtksocket_available)(void);
gint (*get_profile_remote_width)(RemminaProtocolWidget *gp);
gint (*get_profile_remote_height)(RemminaProtocolWidget *gp);
+ const gchar*(*protocol_widget_get_name)(RemminaProtocolWidget *gp);
+ const gint(*protocol_widget_get_width)(RemminaProtocolWidget *gp);
+ const gint(*protocol_widget_get_height)(RemminaProtocolWidget *gp);
+ void(*protocol_widget_set_width)(RemminaProtocolWidget *gp, gint width);
+ void(*protocol_widget_set_height)(RemminaProtocolWidget *gp, gint height);
+ RemminaScaleMode(*protocol_widget_get_current_scale_mode)(RemminaProtocolWidget *gp);
+ gboolean (*protocol_widget_get_expand)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_set_expand)(RemminaProtocolWidget *gp, gboolean expand);
+ void (*protocol_widget_set_error)(RemminaProtocolWidget *gp, const gchar* msg);
+ gboolean (*protocol_widget_has_error)(RemminaProtocolWidget *gp);
+ GtkWidget *(*protocol_widget_gtkviewport)(RemminaProtocolWidget *gp);
+ gboolean (*protocol_widget_is_closed)(RemminaProtocolWidget *gp);
+ RemminaFile *(*protocol_widget_get_file)(RemminaProtocolWidget *gp);
+ gint (*protocol_widget_panel_auth)(RemminaProtocolWidget *gp, RemminaMessagePanelFlags pflags,
+ const gchar *title, const gchar *default_username, const gchar *default_password, const gchar *default_domain, const gchar *password_prompt);
+ void (*protocol_widget_register_hostkey)(RemminaProtocolWidget *gp, GtkWidget *widget);
+ gchar *(*protocol_widget_start_direct_tunnel)(RemminaProtocolWidget *gp, gint default_port, gboolean port_plus);
+ gboolean (*protocol_widget_start_reverse_tunnel)(RemminaProtocolWidget *gp, gint local_port);
+ void (*protocol_widget_send_keys_signals)(GtkWidget *widget, const guint *keyvals, int keyvals_length, GdkEventType action);
+ void (*protocol_widget_chat_receive)(RemminaProtocolWidget *gp, const gchar *text);
+ void (*protocol_widget_panel_hide)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_chat_open)(RemminaProtocolWidget *gp, const gchar *name,
+ void (*on_send)(RemminaProtocolWidget *gp, const gchar *text), void (*on_destroy)(RemminaProtocolWidget *gp));
+ gboolean (*protocol_widget_ssh_exec)(RemminaProtocolWidget *gp, gboolean wait, const gchar *fmt, ...);
+ void (*protocol_widget_panel_show)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_panel_show_retry)(RemminaProtocolWidget *gp);
+ gboolean (*protocol_widget_start_xport_tunnel)(RemminaProtocolWidget *gp, RemminaXPortTunnelInitFunc init_func);
+ void (*protocol_widget_set_display)(RemminaProtocolWidget *gp, gint display);
+ void (*protocol_widget_signal_connection_closed)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_signal_connection_opened)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_update_align)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_unlock_dynres)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_desktop_resize)(RemminaProtocolWidget *gp);
+ gint (*protocol_widget_panel_new_certificate)(RemminaProtocolWidget *gp, const gchar *subject, const gchar *issuer, const gchar *fingerprint);
+ gint (*protocol_widget_panel_changed_certificate)(RemminaProtocolWidget *gp, const gchar *subject, const gchar *issuer, const gchar *new_fingerprint, const gchar *old_fingerprint);
+ gchar *(*protocol_widget_get_username)(RemminaProtocolWidget *gp);
+ gchar *(*protocol_widget_get_password)(RemminaProtocolWidget *gp);
+ gchar *(*protocol_widget_get_domain)(RemminaProtocolWidget *gp);
+ gboolean (*protocol_widget_get_savepassword)(RemminaProtocolWidget *gp);
+ gint (*protocol_widget_panel_authx509)(RemminaProtocolWidget *gp);
+ gchar *(*protocol_widget_get_cacert)(RemminaProtocolWidget *gp);
+ gchar *(*protocol_widget_get_cacrl)(RemminaProtocolWidget *gp);
+ gchar *(*protocol_widget_get_clientcert)(RemminaProtocolWidget *gp);
+ gchar *(*protocol_widget_get_clientkey)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_save_cred)(RemminaProtocolWidget *gp);
+ void (*protocol_widget_panel_show_listen)(RemminaProtocolWidget *gp, gint port);
+ void (*widget_pool_register)(GtkWidget *widget);
+ GtkWidget *(*rcw_open_from_file_full)(RemminaFile *remminafile, GCallback disconnect_cb, gpointer data, guint *handler);
+ void (*show_dialog)(GtkMessageType msg, GtkButtonsType buttons, const gchar* message);
+ GtkWindow *(*get_window)(void);
} RemminaPluginService;
/* "Prototype" of the plugin entry function */
diff --git a/src/remmina_language_wrapper.h b/src/remmina_language_wrapper.h
new file mode 100644
index 000000000..e7def6ab1
--- /dev/null
+++ b/src/remmina_language_wrapper.h
@@ -0,0 +1,121 @@
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2009-2011 Vic Lee
+ * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
+ * Copyright (C) 2016-2022 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 <glib-object.h>
+#include <gobject/gvaluecollector.h>
+
+#include "remmina/types.h"
+
+#pragma once
+
+G_BEGIN_DECLS
+
+struct _RemminaLanguageWrapperPlugin {
+ gchar * extention;
+ GHashTable * plugin_mappings;
+};
+
+/**
+ * used in remmina_ssh.c and remmina_ssh_plugin.c
+ *
+ * #define SSH_AUTH_METHOD_UNKNOWN 0x0000u
+ * #define SSH_AUTH_METHOD_NONE 0x0001u
+ * #define SSH_AUTH_METHOD_PASSWORD 0x0002u
+ * #define SSH_AUTH_METHOD_PUBLICKEY 0x0004u
+ * #define SSH_AUTH_METHOD_HOSTBASED 0x0008u
+ * #define SSH_AUTH_METHOD_INTERACTIVE 0x0010u
+ * #define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020u
+ */
+enum {
+ SSH_AUTH_PASSWORD,
+ SSH_AUTH_PUBLICKEY,
+ SSH_AUTH_AGENT,
+ SSH_AUTH_AUTO_PUBLICKEY,
+ SSH_AUTH_GSSAPI,
+ SSH_AUTH_KBDINTERACTIVE
+};
+
+
+#define TOOLBAR_OPACITY_LEVEL 8
+#define TOOLBAR_OPACITY_MIN 0.2
+
+/* Create a empty .remmina file */
+RemminaFile *remmina_file_new(void);
+RemminaFile *remmina_file_copy(const gchar *filename);
+void remmina_file_generate_filename(RemminaFile *remminafile);
+void remmina_file_set_filename(RemminaFile *remminafile, const gchar *filename);
+void remmina_file_set_statefile(RemminaFile *remminafile);
+void remmina_file_state_last_success(RemminaFile *remminafile);
+const gchar *remmina_file_get_filename(RemminaFile *remminafile);
+const gchar *remmina_file_get_statefile(RemminaFile *remminafile);
+/* Load a new .remmina file and return the allocated RemminaFile object */
+RemminaFile *remmina_file_load(const gchar *filename);
+/* Settings get/set functions */
+void remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value);
+void remmina_file_set_string_ref(RemminaFile *remminafile, const gchar *setting, gchar *value);
+const gchar *remmina_file_get_string(RemminaFile *remminafile, const gchar *setting);
+gchar *remmina_file_get_secret(RemminaFile *remminafile, const gchar *setting);
+gchar *remmina_file_format_properties(RemminaFile *remminafile, const gchar *setting);
+void remmina_file_set_int(RemminaFile *remminafile, const gchar *setting, gint value);
+gint remmina_file_get_int(RemminaFile *remminafile, const gchar *setting, gint default_value);
+void remmina_file_store_secret_plugin_password(RemminaFile *remminafile, const gchar *key, const gchar *value);
+gboolean remmina_file_remove_key(RemminaFile *remminafile, const gchar *setting);
+void remmina_file_set_state(RemminaFile *remminafile, const gchar *setting, const gchar *value);
+const gchar *remmina_file_get_state(RemminaFile *remminafile, const gchar *setting);
+void remmina_file_set_state_int(RemminaFile *remminafile, const gchar *setting, gint value);
+gint remmina_file_get_state_int(RemminaFile *remminafile, const gchar *setting, gint default_value);
+gdouble remmina_file_get_state_double(RemminaFile *remminafile, const gchar *setting, gdouble default_value);
+/* Create or overwrite the .remmina file */
+void remmina_file_save(RemminaFile *remminafile);
+/* Free the RemminaFile object */
+void remmina_file_free(RemminaFile *remminafile);
+/* Duplicate a RemminaFile object */
+RemminaFile *remmina_file_dup(RemminaFile *remminafile);
+/* Get the protocol icon name */
+const gchar *remmina_file_get_icon_name(RemminaFile *remminafile);
+/* Duplicate a temporary RemminaFile and change the protocol */
+RemminaFile *remmina_file_dup_temp_protocol(RemminaFile *remminafile, const gchar *new_protocol);
+/* Delete a .remmina file */
+void remmina_file_delete(const gchar *filename);
+/* Delete a "password" field and save into .remmina file */
+void remmina_file_unsave_passwords(RemminaFile *remminafile);
+/* Function used to update the atime and mtime of a given remmina file, partially
+ * taken from suckless sbase */
+gchar *remmina_file_get_datetime(RemminaFile *remminafile);
+/* Function used to update the atime and mtime of a given remmina file */
+void remmina_file_touch(RemminaFile *remminafile);
+
+G_END_DECLS
diff --git a/src/remmina_plugin_manager.c b/src/remmina_plugin_manager.c
index f61f236d4..fbb9ced6c 100644
--- a/src/remmina_plugin_manager.c
+++ b/src/remmina_plugin_manager.c
@@ -46,6 +46,7 @@
#include <gdk/gdkx.h>
#include "remmina_public.h"
+#include "remmina_main.h"
#include "remmina_file_manager.h"
#include "remmina_pref.h"
#include "remmina_protocol_widget.h"
@@ -54,9 +55,6 @@
#include "rcw.h"
#include "remmina_plugin_manager.h"
#include "remmina_plugin_native.h"
-#ifdef WITH_PYTHONLIBS
-#include "remmina_plugin_python.h"
-#endif
#include "remmina_public.h"
#include "remmina_masterthread_exec.h"
#include "remmina/remmina_trace_calls.h"
@@ -70,7 +68,7 @@ static GHashTable *encrypted_settings_cache = NULL;
static RemminaSecretPlugin *remmina_secret_plugin = NULL;
static const gchar *remmina_plugin_type_name[] =
-{ N_("Protocol"), N_("Entry"), N_("File"), N_("Tool"), N_("Preference"), N_("Secret"), NULL };
+{ N_("Protocol"), N_("Entry"), N_("File"), N_("Tool"), N_("Preference"), N_("Secret"), N_("Language Wrapper"), NULL };
static gint remmina_plugin_manager_compare_func(RemminaPlugin **a, RemminaPlugin **b)
{
@@ -257,7 +255,55 @@ RemminaPluginService remmina_plugin_manager_service =
remmina_masterthread_exec_is_main_thread,
remmina_gtksocket_available,
remmina_protocol_widget_get_profile_remote_width,
- remmina_protocol_widget_get_profile_remote_height
+ remmina_protocol_widget_get_profile_remote_height,
+ remmina_protocol_widget_get_name,
+ remmina_protocol_widget_get_width,
+ remmina_protocol_widget_get_height,
+ remmina_protocol_widget_set_width,
+ remmina_protocol_widget_set_height,
+ remmina_protocol_widget_get_current_scale_mode,
+ remmina_protocol_widget_set_expand,
+ remmina_protocol_widget_set_error,
+ remmina_protocol_widget_has_error,
+ remmina_protocol_widget_gtkviewport,
+ remmina_protocol_widget_get_expand,
+ remmina_protocol_widget_is_closed,
+ remmina_protocol_widget_get_file,
+ remmina_protocol_widget_panel_auth,
+ remmina_protocol_widget_register_hostkey,
+ remmina_protocol_widget_start_direct_tunnel,
+ remmina_protocol_widget_start_reverse_tunnel,
+ remmina_protocol_widget_send_keys_signals,
+ remmina_protocol_widget_chat_receive,
+ remmina_protocol_widget_panel_hide,
+ remmina_protocol_widget_chat_open,
+ remmina_protocol_widget_ssh_exec,
+ remmina_protocol_widget_panel_show,
+ remmina_protocol_widget_panel_show_retry,
+ remmina_protocol_widget_start_xport_tunnel,
+ remmina_protocol_widget_set_display,
+ remmina_protocol_widget_signal_connection_closed,
+ remmina_protocol_widget_signal_connection_opened,
+ remmina_protocol_widget_update_align,
+ remmina_protocol_widget_unlock_dynres,
+ remmina_protocol_widget_desktop_resize,
+ remmina_protocol_widget_panel_new_certificate,
+ remmina_protocol_widget_panel_changed_certificate,
+ remmina_protocol_widget_get_username,
+ remmina_protocol_widget_get_password,
+ remmina_protocol_widget_get_domain,
+ remmina_protocol_widget_get_savepassword,
+ remmina_protocol_widget_panel_authx509,
+ remmina_protocol_widget_get_cacert,
+ remmina_protocol_widget_get_cacrl,
+ remmina_protocol_widget_get_clientcert,
+ remmina_protocol_widget_get_clientkey,
+ remmina_protocol_widget_save_cred,
+ remmina_protocol_widget_panel_show_listen,
+ remmina_widget_pool_register,
+ rcw_open_from_file_full,
+ remmina_main_show_dialog,
+ remmina_main_get_window,
};
const char *get_filename_ext(const char *filename) {
@@ -267,23 +313,6 @@ const char *get_filename_ext(const char *filename) {
return dot + 1;
}
-static void remmina_plugin_manager_load_plugin(const gchar *name)
-{
- const char* ext = get_filename_ext(name);
-
- if (g_str_equal(G_MODULE_SUFFIX, ext)) {
- remmina_plugin_native_load(&remmina_plugin_manager_service, name);
- } else if (g_str_equal("py", ext)) {
-#ifdef WITH_PYTHONLIBS
- remmina_plugin_python_load(&remmina_plugin_manager_service, name);
-#else
- REMMINA_DEBUG("Python support not compiled, cannot load Python plugins");
-#endif
- } else {
- g_print("%s: Skip unsupported file type '%s'\n", name, ext);
- }
-}
-
static gint compare_secret_plugin_init_order(gconstpointer a, gconstpointer b)
{
RemminaSecretPlugin *sa, *sb;
@@ -306,14 +335,13 @@ void remmina_plugin_manager_init()
gchar *fullpath;
RemminaPlugin *plugin;
RemminaSecretPlugin *sp;
- int i;
+ int i, j;
GSList *secret_plugins;
GSList *sple;
+ GPtrArray *alternative_language_plugins;
remmina_plugin_table = g_ptr_array_new();
-#ifdef WITH_PYTHONLIBS
- remmina_plugin_python_init();
-#endif
+ alternative_language_plugins = g_ptr_array_new();
if (!g_module_supported()) {
g_print("Dynamic loading of plugins is not supported on this platform!\n");
@@ -329,14 +357,44 @@ void remmina_plugin_manager_init()
if ((ptr = strrchr(name, '.')) == NULL)
continue;
ptr++;
- if (!remmina_plugin_manager_loader_supported(ptr))
- continue;
fullpath = g_strdup_printf(REMMINA_RUNTIME_PLUGINDIR "/%s", name);
- remmina_plugin_manager_load_plugin(fullpath);
+ if (!remmina_plugin_manager_loader_supported(ptr)) {
+ g_ptr_array_add(alternative_language_plugins, g_strdup_printf(REMMINA_RUNTIME_PLUGINDIR "/%s", name));
+ continue;
+ }
+ remmina_plugin_native_load(&remmina_plugin_manager_service, fullpath);
g_free(fullpath);
}
g_dir_close(dir);
+ while (alternative_language_plugins->len > 0) {
+ gboolean has_loaded = FALSE;
+ const gchar* name = (const gchar*)g_ptr_array_remove_index(alternative_language_plugins, 0);
+ const gchar* ext = get_filename_ext(name);
+
+ for (j = 0; j < remmina_plugin_table->len && !has_loaded; j++) {
+ plugin = (RemminaPlugin*)g_ptr_array_index(remmina_plugin_table, j);
+ if (plugin->type == REMMINA_PLUGIN_TYPE_LANGUAGE_WRAPPER) {
+ RemminaLanguageWrapperPlugin* wrapper_plugin = (RemminaLanguageWrapperPlugin*)plugin;
+ const gchar** supported_extention = wrapper_plugin->supported_extentions;
+ while (*supported_extention) {
+ if (g_str_equal(*supported_extention, ext)) {
+ has_loaded = wrapper_plugin->load(wrapper_plugin, name);
+ if (has_loaded) {
+ break;
+ }
+ }
+ supported_extention++;
+ }
+ if (has_loaded) break;
+ }
+ }
+
+ if (!has_loaded) {
+ g_print("%s: Skip unsupported file type '%s'\n", name, ext);
+ }
+ }
+
/* Now all secret plugins needs to initialize, following their init_order.
* The 1st plugin which will initialize correctly will be
* the default remmina_secret_plugin */
@@ -369,7 +427,7 @@ void remmina_plugin_manager_init()
gboolean remmina_plugin_manager_loader_supported(const char *filetype) {
TRACE_CALL(__func__);
- return g_str_equal("py", filetype) || g_str_equal(G_MODULE_SUFFIX, filetype);
+ return g_str_equal(G_MODULE_SUFFIX, filetype);
}
RemminaPlugin* remmina_plugin_manager_get_plugin(RemminaPluginType type, const gchar *name)
diff --git a/src/remmina_plugin_python.c b/src/remmina_plugin_python.c
deleted file mode 100644
index be83a4635..000000000
--- a/src/remmina_plugin_python.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2022 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.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "config.h"
-#include "remmina/remmina_trace_calls.h"
-#include "remmina_plugin_python_common.h"
-#include "remmina_plugin_python.h"
-#include "remmina_plugin_python_remmina.h"
-#include "remmina_plugin_python_protocol_widget.h"
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * An null terminated array of commands that are executed after the initialization of the Python engine. Every entry
- * represents a line of Python code.
- */
-static const char
- * python_init_commands[] = { "import sys", "sys.path.append('" REMMINA_RUNTIME_PLUGINDIR "')", NULL // Sentinel
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// U T I L S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief Extracts the filename without extension from a path.
- *
- * @param in The string to extract the filename from
- * @param out The resulting filename without extension (must point to allocated memory).
- *
- * @return The length of the filename extracted.
- */
-static int basename_no_ext(const char* in, char** out)
-{
- TRACE_CALL(__func__);
-
- assert(in);
- assert(out);
-
- const char* base = strrchr(in, '/');
- if (base)
- {
- base++;
- }
-
- const char* base_end = strrchr(base, '.');
- if (!base_end)
- {
- base_end = base + strlen(base);
- }
-
- const int length = base_end - base;
- const int memsize = sizeof(char*) * ((length) + 1);
-
- *out = (char*)remmina_plugin_python_malloc(memsize);
-
- memset(*out, 0, memsize);
- strncpy(*out, base, length);
- (*out)[length] = '\0';
-
- return length;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void remmina_plugin_python_init(void)
-{
- TRACE_CALL(__func__);
-
- remmina_plugin_python_module_init();
- Py_Initialize();
-
- for (const char** ptr = python_init_commands; *ptr; ++ptr)
- {
- PyRun_SimpleString(*ptr);
- }
-
- remmina_plugin_python_protocol_widget_init();
-}
-
-gboolean remmina_plugin_python_load(RemminaPluginService* service, const char* name)
-{
- TRACE_CALL(__func__);
-
- assert(service);
- assert(name);
-
- remmina_plugin_python_set_service(service);
-
- char* filename = NULL;
- if (basename_no_ext(name, &filename) == 0)
- {
- g_printerr("[%s:%d]: Can not extract filename from '%s'!\n", __FILE__, __LINE__, name);
- return FALSE;
- }
-
- PyObject* plugin_name = PyUnicode_DecodeFSDefault(filename);
-
- if (!plugin_name)
- {
- free(filename);
- g_printerr("[%s:%d]: Error converting plugin filename to PyUnicode!\n", __FILE__, __LINE__);
- return FALSE;
- }
-
- wchar_t* program_name = NULL;
- Py_ssize_t len = PyUnicode_AsWideChar(plugin_name, program_name, 0);
- if (len <= 0)
- {
- free(filename);
- g_printerr("[%s:%d]: Failed allocating %lu bytes!\n", __FILE__, __LINE__, (sizeof(wchar_t) * len));
- return FALSE;
- }
-
- program_name = (wchar_t*)remmina_plugin_python_malloc(sizeof(wchar_t) * len);
- if (!program_name)
- {
- free(filename);
- g_printerr("[%s:%d]: Failed allocating %lu bytes!\n", __FILE__, __LINE__, (sizeof(wchar_t) * len));
- return FALSE;
- }
-
- PyUnicode_AsWideChar(plugin_name, program_name, len);
-
- PySys_SetArgv(1, &program_name);
-
- if (PyImport_Import(plugin_name))
- {
- free(filename);
- return TRUE;
- }
-
- g_print("[%s:%d]: Failed to load python plugin file: '%s'\n", __FILE__, __LINE__, name);
- PyErr_Print();
- free(filename);
-
- return FALSE;
-}
diff --git a/src/remmina_plugin_python.h b/src/remmina_plugin_python.h
deleted file mode 100644
index 97f53768d..000000000
--- a/src/remmina_plugin_python.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2022 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.
- */
-
-/**
- * @file remmina_plugin_python.h
- *
- * @brief Declares the interface between the Python plugin implementation and Remmina covering the initialization of
- * the implementation and the load function, that allows Remmina to load plugins into the application.
- *
- * @details When Remmina discovers Python scripts in the plugin root folder the plugin manager passes the path to the
- * Python plugin loader. There it gets executed and the plugin classes get mapped to "real" Remmina plugin
- * instances.
- *
- * For the communication between Remmina and Python the python module called 'remmina' is initialized and
- * loaded into the environment of the plugin script (@see remmina_plugin_python_module.c).
- *
- * @see http://www.remmina.org/wp for more information.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina/plugin.h"
-
-G_BEGIN_DECLS
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief Initializes the Python plugin loaders.
- * @details This does not load any plugins but initializes the implementation (e.g. globals and the Python engine).
- */
-void remmina_plugin_python_init(void);
-
-/**
- * @brief Loads a plugin from the Remmina plugin folder with the given name.
- *
- * @param service The instance of the service providing an API between Remmina and its plugins.
- * @param filename The filename of the plugin to load.
- *
- * @return TRUE on success, FALSE otherwise.
- */
-gboolean remmina_plugin_python_load(RemminaPluginService* service, const gchar* filename);
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_common.c b/src/remmina_plugin_python_common.c
deleted file mode 100644
index 527d96d6a..000000000
--- a/src/remmina_plugin_python_common.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#include "pygobject.h"
-#pragma GCC diagnostic pop
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * A cache to store the last result that has been returned by the Python code using CallPythonMethod
- * (@see remmina_plugin_python_common.h)
- */
-static PyObject* __last_result;
-static GPtrArray* plugin_map = NULL;
-
-static RemminaPluginService* remmina_plugin_service;
-
-const char* ATTR_NAME = "name";
-const char* ATTR_ICON_NAME = "icon_name";
-const char* ATTR_DESCRIPTION = "description";
-const char* ATTR_VERSION = "version";
-const char* ATTR_ICON_NAME_SSH = "icon_name_ssh";
-const char* ATTR_FEATURES = "features";
-const char* ATTR_BASIC_SETTINGS = "basic_settings";
-const char* ATTR_ADVANCED_SETTINGS = "advanced_settings";
-const char* ATTR_SSH_SETTING = "ssh_setting";
-const char* ATTR_EXPORT_HINTS = "export_hints";
-const char* ATTR_PREF_LABEL = "pref_label";
-const char* ATTR_INIT_ORDER = "init_order";
-
-/**
- * To prevent some memory related attacks or accidental allocation of an excessive amount of byes, this limit should
- * always be used to check for a sane amount of bytes to allocate.
- */
-static const int REASONABLE_LIMIT_FOR_MALLOC = 1024 * 1024;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-PyObject* remmina_plugin_python_last_result(void)
-{
- TRACE_CALL(__func__);
-
- return __last_result;
-}
-
-PyObject* remmina_plugin_python_last_result_set(PyObject* last_result)
-{
- TRACE_CALL(__func__);
-
- return __last_result = last_result;
-}
-
-gboolean remmina_plugin_python_check_error(void)
-{
- TRACE_CALL(__func__);
-
- if (PyErr_Occurred())
- {
- PyErr_Print();
- return TRUE;
- }
-
- return FALSE;
-}
-
-void remmina_plugin_python_log_method_call(PyObject* instance, const char* method)
-{
- TRACE_CALL(__func__);
-
- assert(instance);
- assert(method);
- g_print("Python@%ld: %s.%s(...) -> %s\n",
- PyObject_Hash(instance),
- instance->ob_type->tp_name,
- method,
- PyUnicode_AsUTF8(PyObject_Str(remmina_plugin_python_last_result())));
-}
-
-long remmina_plugin_python_get_attribute_long(PyObject* instance, const char* attr_name, long def)
-{
- TRACE_CALL(__func__);
-
- assert(instance);
- assert(attr_name);
- PyObject* attr = PyObject_GetAttrString(instance, attr_name);
- if (attr && PyLong_Check(attr))
- {
- return PyLong_AsLong(attr);
- }
-
- return def;
-}
-
-gboolean remmina_plugin_python_check_attribute(PyObject* instance, const char* attr_name)
-{
- TRACE_CALL(__func__);
-
- assert(instance);
- assert(attr_name);
- if (PyObject_HasAttrString(instance, attr_name))
- {
- return TRUE;
- }
-
- g_printerr("Python plugin instance is missing member: %s\n", attr_name);
- return FALSE;
-}
-
-void* remmina_plugin_python_malloc(int bytes)
-{
- TRACE_CALL(__func__);
-
- assert(bytes > 0);
- assert(bytes <= REASONABLE_LIMIT_FOR_MALLOC);
-
- void* result = malloc(bytes);
-
- if (!result)
- {
- g_printerr("Unable to allocate %d bytes in memory!\n", bytes);
- perror("malloc");
- }
-
- return result;
-}
-
-char* remmina_plugin_python_copy_string_from_python(PyObject* string, Py_ssize_t len)
-{
- TRACE_CALL(__func__);
-
- char* result = NULL;
- if (len <= 0 || string == NULL)
- {
- return NULL;
- }
-
- const char* py_str = PyUnicode_AsUTF8(string);
- if (py_str)
- {
- const int label_size = sizeof(char) * (len + 1);
- result = (char*)remmina_plugin_python_malloc(label_size);
- result[len] = '\0';
- memcpy(result, py_str, len);
- }
-
- return result;
-}
-
-void remmina_plugin_python_set_service(RemminaPluginService* service)
-{
- remmina_plugin_service = service;
-}
-
-RemminaPluginService* remmina_plugin_python_get_service(void)
-{
- return remmina_plugin_service;
-}
-
-void remmina_plugin_python_add_plugin(PyPlugin* plugin)
-{
- TRACE_CALL(__func__);
-
- if (!plugin_map)
- {
- plugin_map = g_ptr_array_new();
- }
-
- PyPlugin* test = remmina_plugin_python_get_plugin(plugin->generic_plugin->name);
- if (test)
- {
- g_printerr("A plugin named '%s' has already been registered! Skipping...", plugin->generic_plugin->name);
- }
- else
- {
- g_ptr_array_add(plugin_map, plugin);
- }
-}
-
-RemminaTypeHint remmina_plugin_python_to_generic(PyObject* field, gpointer* target)
-{
- TRACE_CALL(__func__);
-
- if (PyUnicode_Check(field))
- {
- Py_ssize_t len = PyUnicode_GetLength(field);
-
- if (len > 0)
- {
- *target = remmina_plugin_python_copy_string_from_python(field, len);
- }
- else
- {
- *target = "";
- }
-
- return REMMINA_TYPEHINT_STRING;
- }
- else if (PyBool_Check(field))
- {
- *target = remmina_plugin_python_malloc(sizeof(long));
- long* long_target = (long*)target;
- *long_target = PyLong_AsLong(field);
- return REMMINA_TYPEHINT_BOOLEAN;
- }
- else if (PyLong_Check(field))
- {
- *target = remmina_plugin_python_malloc(sizeof(long));
- long* long_target = (long*)target;
- *long_target = PyLong_AsLong(field);
- return REMMINA_TYPEHINT_SIGNED;
- }
- else if (PyTuple_Check(field))
- {
- Py_ssize_t len = PyTuple_Size(field);
- if (len)
- {
- gpointer* dest = (gpointer*)remmina_plugin_python_malloc(sizeof(gpointer) * (len + 1));
- memset(dest, 0, sizeof(gpointer) * (len + 1));
-
- for (Py_ssize_t i = 0; i < len; ++i)
- {
- PyObject* item = PyTuple_GetItem(field, i);
- remmina_plugin_python_to_generic(item, dest + i);
- }
-
- *target = dest;
- }
- return REMMINA_TYPEHINT_TUPLE;
- }
-
- *target = NULL;
- return REMMINA_TYPEHINT_UNDEFINED;
-}
-
-PyPlugin* remmina_plugin_python_get_plugin(const char* name)
-{
- TRACE_CALL(__func__);
-
- assert(plugin_map);
- assert(name);
-
- for (gint i = 0; i < plugin_map->len; ++i)
- {
- PyPlugin* plugin = (PyPlugin*)g_ptr_array_index(plugin_map, i);
- if (plugin->generic_plugin && plugin->generic_plugin->name && g_str_equal(name, plugin->generic_plugin->name))
- {
- return plugin;
- }
- }
-
- return NULL;
-}
-
-void init_pygobject()
-{
- pygobject_init(-1, -1, -1);
-}
-
-GtkWidget* new_pywidget(GObject* obj)
-{
- return (GtkWidget*)pygobject_new(obj);
-}
-
-GtkWidget* get_pywidget(PyObject* obj)
-{
- return (GtkWidget*)pygobject_get(obj);
-}
diff --git a/src/remmina_plugin_python_common.h b/src/remmina_plugin_python_common.h
deleted file mode 100644
index 21557bb65..000000000
--- a/src/remmina_plugin_python_common.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_common.h
- *
- * @brief Contains functions and constants that are commonly used throughout the Python plugin implementation.
- *
- * @details These functions should not be used outside of the Python plugin implementation, since everything is intended
- * to be used with the Python engine.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-#include <Python.h>
-#include <glib.h>
-#include <Python.h>
-#include <structmember.h>
-
-#include "remmina/plugin.h"
-#include "config.h"
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-// - Attribute names
-
-extern const char* ATTR_NAME;
-extern const char* ATTR_ICON_NAME;
-extern const char* ATTR_DESCRIPTION;
-extern const char* ATTR_VERSION;
-extern const char* ATTR_ICON_NAME_SSH;
-extern const char* ATTR_FEATURES;
-extern const char* ATTR_BASIC_SETTINGS;
-extern const char* ATTR_ADVANCED_SETTINGS;
-extern const char* ATTR_SSH_SETTING;
-extern const char* ATTR_EXPORT_HINTS;
-extern const char* ATTR_PREF_LABEL;
-extern const char* ATTR_INIT_ORDER;
-
-// You can enable this for debuggin purposes or specify it in the build.
-// #define WITH_PYTHON_TRACE_CALLS
-
-/**
- * If WITH_PYTHON_TRACE_CALLS is defined, it logs the calls to the Python code and errors in case.
- */
-#ifdef WITH_PYTHON_TRACE_CALLS
-#define CallPythonMethod(instance, name, params, ...) \
- remmina_plugin_python_last_result_set(PyObject_CallMethod(instance, name, params, ##__VA_ARGS__)); \
- remmina_plugin_python_log_method_call(instance, name); \
- remmina_plugin_python_check_error()
-#else
-/**
- * If WITH_TRACE_CALL is not defined, it still logs errors but doesn't print the call anymore.
- */
-#define CallPythonMethod(instance, name, params, ...) \
- PyObject_CallMethod(instance, name, params, ##__VA_ARGS__); \
- remmina_plugin_python_check_error()
-#endif // WITH_PYTHON_TRACE_CALLS
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// T Y P E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @brief The Python abstraction of the protocol widget struct.
- *
- * @details This struct is responsible to provide the same accessibility to the protocol widget for Python as for
- * native plugins.
- */
-typedef struct
-{
- PyObject_HEAD
- RemminaProtocolWidget* gp;
-} PyRemminaProtocolWidget;
-
-/**
- * @brief Maps an instance of a Python plugin to a Remmina one.
- *
- * @details This is used to map a Python plugin instance to the Remmina plugin one. Also instance specific data as the
- * protocol widget are stored in this struct.
- */
-typedef struct
-{
- RemminaProtocolPlugin* protocol_plugin;
- RemminaFilePlugin* file_plugin;
- RemminaSecretPlugin* secret_plugin;
- RemminaToolPlugin* tool_plugin;
- RemminaEntryPlugin* entry_plugin;
- RemminaPrefPlugin* pref_plugin;
- RemminaPlugin* generic_plugin;
- PyRemminaProtocolWidget* gp;
- PyObject* instance;
-} PyPlugin;
-
-/**
- * A struct used to communicate data between Python and C without strict data type.
- */
-typedef struct
-{
- PyObject_HEAD;
- RemminaTypeHint type_hint;
- gpointer raw;
-} PyGeneric;
-
-/**
- * Checks if self is set and returns NULL if not.
- */
-#define SELF_CHECK() if (!self) { \
- g_printerr("[%s:%d]: self is null!\n", __FILE__, __LINE__); \
- PyErr_SetString(PyExc_RuntimeError, "Method is not called from an instance (self is null)!"); \
- return NULL; \
- }
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Creates a new instance of PyGeneric.
- */
-PyGeneric* remmina_plugin_python_generic_new(void);
-
-/**
- * Registers the given plugin if no other plugin with the same name has been already registered.
- */
-void remmina_plugin_python_add_plugin(PyPlugin* plugin);
-
-/**
- * Sets the pointer to the plugin service of Remmina.
- */
-void remmina_plugin_python_set_service(RemminaPluginService* service);
-
-/**
- * Extracts data from a PyObject instance to a generic pointer and returns a type hint if it could be determined.
- */
-RemminaTypeHint remmina_plugin_python_to_generic(PyObject* field, gpointer* target);
-
-/**
- * Gets the result of the last python method call.
- */
-PyObject* remmina_plugin_python_last_result(void);
-
-/**
- * @brief Sets the result of the last python method call.
- *
- * @return Returns the passed result (it's done to be compatible with the CallPythonMethod macro).
- */
-PyObject* remmina_plugin_python_last_result_set(PyObject* result);
-
-/**
- * @brief Prints a log message to inform the user a python message has been called.
- *
- * @detail This method is called from the CALL_PYTHON macro if WITH_PYTHON_TRACE_CALLS is defined.
- *
- * @param instance The instance that contains the called method.
- * @param method The name of the method called.
- */
-void remmina_plugin_python_log_method_call(PyObject* instance, const char* method);
-
-/**
- * @brief Checks if an error has occurred and prints it.
- *
- * @return Returns TRUE if an error has occurred.
- */
-gboolean remmina_plugin_python_check_error(void);
-
-/**
- * @brief Gets the attribute as long value.
- *
- * @param instance The instance of the object to get the attribute.
- * @param constant_name The name of the attribute to get.
- * @param def The value to return if the attribute doesn't exist or is not set.
- *
- * @return The value attribute as long.
- */
-long remmina_plugin_python_get_attribute_long(PyObject* instance, const char* attr_name, long def);
-
-/**
- * @brief Checks if a given attribute exists.
- *
- * @param instance The object to check for the attribute.
- * @param attr_name The name of the attribute to check.
- *
- * @return Returns TRUE if the attribute exists.
- */
-gboolean remmina_plugin_python_check_attribute(PyObject* instance, const char* attr_name);
-
-/**
- * @brief Allocates memory and checks for errors before returning.
- *
- * @param bytes Amount of bytes to allocate.
- *
- * @return Address to the allocated memory.
- */
-void* remmina_plugin_python_malloc(int bytes);
-
-/**
- * @biref Copies a string from a Python object to a new point in memory.
- *
- * @param string The python object, containing the string to copy.
- * @param len The length of the string to copy.
- *
- * @return A char pointer to the new copy of the string.
- */
-char* remmina_plugin_python_copy_string_from_python(PyObject* string, Py_ssize_t len);
-
-/**
- * @brief Tries to find the Python plugin matching to the given instance of RemminaPlugin.
- *
- * @param plugin_map An array of PyPlugin pointers to search.
- * @param instance The RemminaPlugin instance to find the correct PyPlugin instance for.
- *
- * @return A pointer to a PyPlugin instance if successful. Otherwise NULL is returned.
- */
-PyPlugin* remmina_plugin_python_get_plugin(const char* name);
-
-/**
- * Creates a new GtkWidget
- * @param obj
- * @return
- */
-GtkWidget* new_pywidget(GObject* obj);
-
-/**
- * Extracts a GtkWidget from a PyObject instance.
- * @param obj
- * @return
- */
-GtkWidget* get_pywidget(PyObject* obj);
-
-/**
- * Initializes the pygobject library. This needs to be called before any Python plugin is being initialized.
- */
-void init_pygobject(void);
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_entry.c b/src/remmina_plugin_python_entry.c
deleted file mode 100644
index 54a478b18..000000000
--- a/src/remmina_plugin_python_entry.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_entry.c
- * @brief Contains the wiring of a Python pluing based on RemminaPluginProtocol.
- * @author Mathias Winterhalter
- * @date 07.04.2021
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-#include "remmina_plugin_python_entry.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void remmina_plugin_python_entry_init(void)
-{
- TRACE_CALL(__func__);
-}
-
-void remmina_plugin_python_entry_entry_func_wrapper(RemminaEntryPlugin* instance)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- if (plugin)
- {
- CallPythonMethod(plugin->instance, "entry_func", NULL);
- }
-}
-
-RemminaPlugin* remmina_plugin_python_create_entry_plugin(PyPlugin* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* instance = plugin->instance;
-
- if (!remmina_plugin_python_check_attribute(instance, ATTR_NAME)
- || !remmina_plugin_python_check_attribute(instance, ATTR_VERSION)
- || !remmina_plugin_python_check_attribute(instance, ATTR_DESCRIPTION))
- {
- g_printerr("Unable to create entry plugin. Aborting!\n");
- return NULL;
- }
-
- RemminaEntryPlugin* remmina_plugin = (RemminaEntryPlugin*)remmina_plugin_python_malloc(sizeof(RemminaEntryPlugin));
-
- remmina_plugin->type = REMMINA_PLUGIN_TYPE_ENTRY;
- remmina_plugin->domain = GETTEXT_PACKAGE;
- remmina_plugin->name = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_NAME));
- remmina_plugin->version = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_VERSION));
- remmina_plugin->description = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_DESCRIPTION));
- remmina_plugin->entry_func = remmina_plugin_python_entry_entry_func_wrapper;
-
- plugin->entry_plugin = remmina_plugin;
- plugin->generic_plugin = (RemminaPlugin*)remmina_plugin;
-
- remmina_plugin_python_add_plugin(plugin);
-
- return (RemminaPlugin*)remmina_plugin;
-}
diff --git a/src/remmina_plugin_python_entry.h b/src/remmina_plugin_python_entry.h
deleted file mode 100644
index 3b4c3ee38..000000000
--- a/src/remmina_plugin_python_entry.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_entry.h
- *
- * @brief Contains the specialisation of RemminaPluginEntry plugins in Python.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-/**
- * Initializes the Python plugin specialisation for entry plugins.
- */
-void remmina_plugin_python_entry_init(void);
-
-/**
- * @brief Creates a new instance of the RemminaPluginEntry, initializes its members and references the wrapper
- * functions.
- * @param instance The instance of the Python plugin.
- * @return Returns a new instance of the RemminaPlugin (must be freed!).
- */
-RemminaPlugin* remmina_plugin_python_create_entry_plugin(PyPlugin* instance);
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_file.c b/src/remmina_plugin_python_file.c
deleted file mode 100644
index 71a4dcd75..000000000
--- a/src/remmina_plugin_python_file.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-#include "remmina_plugin_python_file.h"
-#include "remmina_plugin_python_remmina_file.h"
-#include "remmina_file.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void remmina_plugin_python_file_init(void)
-{
- TRACE_CALL(__func__);
-}
-
-gboolean remmina_plugin_python_file_import_test_func_wrapper(RemminaFilePlugin* instance, const gchar* from_file)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = NULL;
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
-
- if (plugin)
- {
- result = CallPythonMethod(plugin->instance, "import_test_func", "s", from_file);
- }
-
- return result == Py_None || result != Py_False;
-}
-
-RemminaFile* remmina_plugin_python_file_import_func_wrapper(RemminaFilePlugin* instance, const gchar* from_file)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = NULL;
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- if (!plugin)
- {
- return NULL;
- }
-
- result = CallPythonMethod(plugin->instance, "import_func", "s", from_file);
-
- if (result == Py_None || result == Py_False)
- {
- return NULL;
- }
-
- return ((PyRemminaFile*)result)->file;
-}
-
-gboolean remmina_plugin_python_file_export_test_func_wrapper(RemminaFilePlugin* instance, RemminaFile* file)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = NULL;
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- if (plugin)
- {
- result = CallPythonMethod(plugin->instance,
- "export_test_func",
- "O",
- remmina_plugin_python_remmina_file_to_python(file));
- }
-
- return result == Py_None || result != Py_False;
-}
-
-gboolean
-remmina_plugin_python_file_export_func_wrapper(RemminaFilePlugin* instance, RemminaFile* file, const gchar* to_file)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = NULL;
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- if (plugin)
- {
- result = CallPythonMethod(plugin->instance, "export_func", "s", to_file);
- }
-
- return result == Py_None || result != Py_False;
-}
-
-RemminaPlugin* remmina_plugin_python_create_file_plugin(PyPlugin* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* instance = plugin->instance;
- Py_IncRef(instance);
-
- if (!remmina_plugin_python_check_attribute(instance, ATTR_NAME))
- {
- g_printerr("Unable to create file plugin. Aborting!\n");
- return NULL;
- }
-
- RemminaFilePlugin* remmina_plugin = (RemminaFilePlugin*)remmina_plugin_python_malloc(sizeof(RemminaFilePlugin));
-
- remmina_plugin->type = REMMINA_PLUGIN_TYPE_FILE;
- remmina_plugin->domain = GETTEXT_PACKAGE;
- remmina_plugin->name = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_NAME));
- remmina_plugin->version = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_VERSION));
- remmina_plugin->description = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_DESCRIPTION));
- remmina_plugin->export_hints = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_EXPORT_HINTS));
-
- remmina_plugin->import_test_func = remmina_plugin_python_file_import_test_func_wrapper;
- remmina_plugin->import_func = remmina_plugin_python_file_import_func_wrapper;
- remmina_plugin->export_test_func = remmina_plugin_python_file_export_test_func_wrapper;
- remmina_plugin->export_func = remmina_plugin_python_file_export_func_wrapper;
-
- plugin->file_plugin = remmina_plugin;
- plugin->generic_plugin = (RemminaPlugin*)remmina_plugin;
-
- remmina_plugin_python_add_plugin(plugin);
-
- return (RemminaPlugin*)remmina_plugin;
-}
diff --git a/src/remmina_plugin_python_file.h b/src/remmina_plugin_python_file.h
deleted file mode 100644
index b45326f7f..000000000
--- a/src/remmina_plugin_python_file.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_file.h
- *
- * @brief Contains the specialisation of RemminaPluginFile plugins in Python.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-/**
- * Initializes the Python plugin specialisation for file plugins.
- */
-void remmina_plugin_python_file_init(void);
-
-/**
- * @brief Creates a new instance of the RemminaPluginFile, initializes its members and references the wrapper
- * functions.
- * @param instance The instance of the Python plugin.
- * @return Returns a new instance of the RemminaPlugin (must be freed!).
- */
-RemminaPlugin* remmina_plugin_python_create_file_plugin(PyPlugin* instance);
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_pref.c b/src/remmina_plugin_python_pref.c
deleted file mode 100644
index b799d105a..000000000
--- a/src/remmina_plugin_python_pref.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-#include "remmina_plugin_python_pref.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void remmina_plugin_python_pref_init(void)
-{
- TRACE_CALL(__func__);
-
-}
-
-/**
- * @brief
- */
-GtkWidget* remmina_plugin_python_pref_get_pref_body_wrapper(RemminaPrefPlugin* instance)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
-
- PyObject* result = CallPythonMethod(plugin->instance, "get_pref_body", NULL, NULL);
- if (result == Py_None || result == NULL)
- {
- return NULL;
- }
-
- return get_pywidget(result);
-}
-
-RemminaPlugin* remmina_plugin_python_create_pref_plugin(PyPlugin* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* instance = plugin->instance;
-
- if (!remmina_plugin_python_check_attribute(instance, ATTR_NAME)
- || !remmina_plugin_python_check_attribute(instance, ATTR_VERSION)
- || !remmina_plugin_python_check_attribute(instance, ATTR_DESCRIPTION)
- || !remmina_plugin_python_check_attribute(instance, ATTR_PREF_LABEL))
- {
- g_printerr("Unable to create pref plugin. Aborting!\n");
- return NULL;
- }
-
- RemminaPrefPlugin* remmina_plugin = (RemminaPrefPlugin*)remmina_plugin_python_malloc(sizeof(RemminaPrefPlugin));
-
- remmina_plugin->type = REMMINA_PLUGIN_TYPE_PREF;
- remmina_plugin->domain = GETTEXT_PACKAGE;
- remmina_plugin->name = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_NAME));
- remmina_plugin->version = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_VERSION));
- remmina_plugin->description = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_DESCRIPTION));
- remmina_plugin->pref_label = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_PREF_LABEL));
- remmina_plugin->get_pref_body = remmina_plugin_python_pref_get_pref_body_wrapper;
-
- plugin->pref_plugin = remmina_plugin;
- plugin->generic_plugin = (RemminaPlugin*)remmina_plugin;
-
- remmina_plugin_python_add_plugin(plugin);
-
- return (RemminaPlugin*)remmina_plugin;
-}
diff --git a/src/remmina_plugin_python_pref.h b/src/remmina_plugin_python_pref.h
deleted file mode 100644
index ede1357ab..000000000
--- a/src/remmina_plugin_python_pref.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_pref.h
- *
- * @brief Contains the specialisation of RemminaPluginFile plugins in Python.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-/**
- * Initializes the Python plugin specialisation for preferences plugins.
- */
-void remmina_plugin_python_pref_init(void);
-
-/**
- * @brief Creates a new instance of the RemminaPluginPref, initializes its members and references the wrapper
- * functions.
- * @param instance The instance of the Python plugin.
- * @return Returns a new instance of the RemminaPlugin (must be freed!).
- */
-RemminaPlugin* remmina_plugin_python_create_pref_plugin(PyPlugin* instance);
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_protocol.c b/src/remmina_plugin_python_protocol.c
deleted file mode 100644
index d01b2a657..000000000
--- a/src/remmina_plugin_python_protocol.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2022 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_common.c
- * @brief
- * @author Mathias Winterhalter
- * @date 07.04.2021
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-#include "remmina_plugin_python_protocol.h"
-#include "remmina_plugin_python_remmina.h"
-
-#include "remmina_protocol_widget.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void remmina_plugin_python_protocol_init(void)
-{
- TRACE_CALL(__func__);
-}
-
-void remmina_protocol_init_wrapper(RemminaProtocolWidget* gp)
-{
- TRACE_CALL(__func__);
- PyPlugin* py_plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- py_plugin->gp->gp = gp;
- CallPythonMethod(py_plugin->instance, "init", "O", py_plugin->gp);
-}
-
-gboolean remmina_protocol_open_connection_wrapper(RemminaProtocolWidget* gp)
-{
- TRACE_CALL(__func__);
- PyPlugin* py_plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- if (py_plugin)
- {
- PyObject* result = CallPythonMethod(py_plugin->instance, "open_connection", "O", py_plugin->gp);
- return result == Py_True;
- }
- else
- {
- return gtk_false();
- }
-}
-
-gboolean remmina_protocol_close_connection_wrapper(RemminaProtocolWidget* gp)
-{
- TRACE_CALL(__func__);
- PyPlugin* py_plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyObject* result = CallPythonMethod(py_plugin->instance, "close_connection", "O", py_plugin->gp);
- return result == Py_True;
-}
-
-gboolean remmina_protocol_query_feature_wrapper(RemminaProtocolWidget* gp,
- const RemminaProtocolFeature* feature)
-{
- TRACE_CALL(__func__);
- PyPlugin* py_plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyRemminaProtocolFeature* pyFeature = remmina_plugin_python_protocol_feature_new();
- pyFeature->type = (gint)feature->type;
- pyFeature->id = feature->id;
- pyFeature->opt1 = remmina_plugin_python_generic_new();
- pyFeature->opt1->raw = feature->opt1;
- pyFeature->opt2 = remmina_plugin_python_generic_new();
- pyFeature->opt2->raw = feature->opt2;
- pyFeature->opt3 = remmina_plugin_python_generic_new();
- pyFeature->opt3->raw = feature->opt3;
-
- PyObject* result = CallPythonMethod(py_plugin->instance, "query_feature", "OO", py_plugin->gp, pyFeature);
- Py_DecRef((PyObject*)pyFeature);
- Py_DecRef((PyObject*)pyFeature->opt1);
- Py_DecRef((PyObject*)pyFeature->opt2);
- Py_DecRef((PyObject*)pyFeature->opt3);
- return result == Py_True;
-}
-
-void remmina_protocol_call_feature_wrapper(RemminaProtocolWidget* gp, const RemminaProtocolFeature* feature)
-{
- TRACE_CALL(__func__);
- PyPlugin* py_plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyRemminaProtocolFeature* pyFeature = remmina_plugin_python_protocol_feature_new();
- pyFeature->type = (gint)feature->type;
- pyFeature->id = feature->id;
- pyFeature->opt1 = remmina_plugin_python_generic_new();
- pyFeature->opt1->raw = feature->opt1;
- pyFeature->opt1->type_hint = feature->opt1_type_hint;
- pyFeature->opt2 = remmina_plugin_python_generic_new();
- pyFeature->opt2->raw = feature->opt2;
- pyFeature->opt2->type_hint = feature->opt2_type_hint;
- pyFeature->opt3 = remmina_plugin_python_generic_new();
- pyFeature->opt3->raw = feature->opt3;
- pyFeature->opt3->type_hint = feature->opt3_type_hint;
-
- CallPythonMethod(py_plugin->instance, "call_feature", "OO", py_plugin->gp, pyFeature);
- Py_DecRef((PyObject*)pyFeature);
- Py_DecRef((PyObject*)pyFeature->opt1);
- Py_DecRef((PyObject*)pyFeature->opt2);
- Py_DecRef((PyObject*)pyFeature->opt3);
-}
-
-void remmina_protocol_send_keytrokes_wrapper(RemminaProtocolWidget* gp,
- const guint keystrokes[],
- const gint keylen)
-{
- TRACE_CALL(__func__);
- PyPlugin* py_plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyObject* obj = PyList_New(keylen);
- Py_IncRef(obj);
- for (int i = 0; i < keylen; ++i)
- {
- PyList_SetItem(obj, i, PyLong_FromLong(keystrokes[i]));
- }
- CallPythonMethod(py_plugin->instance, "send_keystrokes", "OO", py_plugin->gp, obj);
- Py_DecRef(obj);
-}
-
-gboolean remmina_protocol_get_plugin_screenshot_wrapper(RemminaProtocolWidget* gp,
- RemminaPluginScreenshotData* rpsd)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* py_plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyRemminaPluginScreenshotData* data = remmina_plugin_python_screenshot_data_new();
- Py_IncRef((PyObject*)data);
- PyObject* result = CallPythonMethod(py_plugin->instance, "get_plugin_screenshot", "OO", py_plugin->gp, data);
- if (result == Py_True)
- {
- if (!PyByteArray_Check((PyObject*)data->buffer))
- {
- g_printerr("Unable to parse screenshot data. 'buffer' needs to be an byte array!");
- return 0;
- }
- Py_ssize_t buffer_len = PyByteArray_Size((PyObject*)data->buffer);
-
- // Is being freed by Remmina!
- rpsd->buffer = (unsigned char*)remmina_plugin_python_malloc(sizeof(unsigned char) * buffer_len);
- if (!rpsd->buffer)
- {
- return 0;
- }
- memcpy(rpsd->buffer, PyByteArray_AsString((PyObject*)data->buffer), sizeof(unsigned char) * buffer_len);
- rpsd->bytesPerPixel = data->bytesPerPixel;
- rpsd->bitsPerPixel = data->bitsPerPixel;
- rpsd->height = data->height;
- rpsd->width = data->width;
- }
- Py_DecRef((PyObject*)data->buffer);
- Py_DecRef((PyObject*)data);
- return result == Py_True;
-}
-
-gboolean remmina_protocol_map_event_wrapper(RemminaProtocolWidget* gp)
-{
- PyPlugin* plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyObject* result = CallPythonMethod(plugin->instance, "map_event", "O", plugin->gp);
- return PyBool_Check(result) && result == Py_True;
-}
-
-gboolean remmina_protocol_unmap_event_wrapper(RemminaProtocolWidget* gp)
-{
- PyPlugin* plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyObject* result = CallPythonMethod(plugin->instance, "unmap_event", "O", plugin->gp);
- return PyBool_Check(result) && result == Py_True;
-}
-
-RemminaPlugin* remmina_plugin_python_create_protocol_plugin(PyPlugin* plugin)
-{
- PyObject* instance = plugin->instance;
-
- if (!remmina_plugin_python_check_attribute(instance, ATTR_ICON_NAME_SSH)
- || !remmina_plugin_python_check_attribute(instance, ATTR_ICON_NAME)
- || !remmina_plugin_python_check_attribute(instance, ATTR_FEATURES)
- || !remmina_plugin_python_check_attribute(instance, ATTR_BASIC_SETTINGS)
- || !remmina_plugin_python_check_attribute(instance, ATTR_ADVANCED_SETTINGS)
- || !remmina_plugin_python_check_attribute(instance, ATTR_SSH_SETTING))
- {
- g_printerr("Unable to create protocol plugin. Aborting!\n");
- return NULL;
- }
-
- RemminaProtocolPlugin* remmina_plugin = (RemminaProtocolPlugin*)remmina_plugin_python_malloc(sizeof(RemminaProtocolPlugin));
-
- remmina_plugin->type = REMMINA_PLUGIN_TYPE_PROTOCOL;
- remmina_plugin->domain = GETTEXT_PACKAGE;
- remmina_plugin->basic_settings = NULL;
- remmina_plugin->advanced_settings = NULL;
- remmina_plugin->features = NULL;
-
- remmina_plugin->name = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_NAME));
- remmina_plugin->description = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_DESCRIPTION));
- remmina_plugin->version = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_VERSION));
- remmina_plugin->icon_name = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_ICON_NAME));
- remmina_plugin->icon_name_ssh = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_ICON_NAME_SSH));
-
- PyObject* list = PyObject_GetAttrString(instance, "basic_settings");
- Py_ssize_t len = PyList_Size(list);
- if (len)
- {
- RemminaProtocolSetting* basic_settings = (RemminaProtocolSetting*)remmina_plugin_python_malloc(
- sizeof(RemminaProtocolSetting) * (len + 1));
- memset(basic_settings, 0, sizeof(RemminaProtocolSetting) * (len + 1));
-
- for (Py_ssize_t i = 0; i < len; ++i)
- {
- RemminaProtocolSetting* dest = basic_settings + i;
- remmina_plugin_python_to_protocol_setting(dest, PyList_GetItem(list, i));
- }
- RemminaProtocolSetting* dest = basic_settings + len;
- dest->type = REMMINA_PROTOCOL_SETTING_TYPE_END;
- remmina_plugin->basic_settings = basic_settings;
- }
-
- list = PyObject_GetAttrString(instance, "advanced_settings");
- len = PyList_Size(list);
- if (len)
- {
- RemminaProtocolSetting* advanced_settings = (RemminaProtocolSetting*)remmina_plugin_python_malloc(
- sizeof(RemminaProtocolSetting) * (len + 1));
- memset(advanced_settings, 0, sizeof(RemminaProtocolSetting) * (len + 1));
-
- for (Py_ssize_t i = 0; i < len; ++i)
- {
- RemminaProtocolSetting* dest = advanced_settings + i;
- remmina_plugin_python_to_protocol_setting(dest, PyList_GetItem(list, i));
- }
-
- RemminaProtocolSetting* dest = advanced_settings + len;
- dest->type = REMMINA_PROTOCOL_SETTING_TYPE_END;
-
- remmina_plugin->advanced_settings = advanced_settings;
- }
-
- list = PyObject_GetAttrString(instance, "features");
- len = PyList_Size(list);
- if (len)
- {
- RemminaProtocolFeature* features = (RemminaProtocolFeature*)remmina_plugin_python_malloc(
- sizeof(RemminaProtocolFeature) * (len + 1));
- memset(features, 0, sizeof(RemminaProtocolFeature) * (len + 1));
-
- for (Py_ssize_t i = 0; i < len; ++i)
- {
- RemminaProtocolFeature* dest = features + i;
- remmina_plugin_python_to_protocol_feature(dest, PyList_GetItem(list, i));
- }
-
- RemminaProtocolFeature* dest = features + len;
- dest->type = REMMINA_PROTOCOL_FEATURE_TYPE_END;
-
- remmina_plugin->features = features;
- }
-
- remmina_plugin->ssh_setting = (RemminaProtocolSSHSetting)remmina_plugin_python_get_attribute_long(instance,
- ATTR_SSH_SETTING,
- REMMINA_PROTOCOL_SSH_SETTING_NONE);
-
- remmina_plugin->init = remmina_protocol_init_wrapper; // Plugin initialization
- remmina_plugin->open_connection = remmina_protocol_open_connection_wrapper; // Plugin open connection
- remmina_plugin->close_connection = remmina_protocol_close_connection_wrapper; // Plugin close connection
- remmina_plugin->query_feature = remmina_protocol_query_feature_wrapper; // Query for available features
- remmina_plugin->call_feature = remmina_protocol_call_feature_wrapper; // Call a feature
- remmina_plugin->send_keystrokes =
- remmina_protocol_send_keytrokes_wrapper; // Send a keystroke
- remmina_plugin->get_plugin_screenshot =
- remmina_protocol_get_plugin_screenshot_wrapper; // Screenshot support unavailable
-
- remmina_plugin->map_event = remmina_protocol_map_event_wrapper;
- remmina_plugin->unmap_event = remmina_protocol_unmap_event_wrapper;
-
- plugin->protocol_plugin = remmina_plugin;
- plugin->generic_plugin = (RemminaPlugin*)remmina_plugin;
-
- remmina_plugin_python_add_plugin(plugin);
-
- return (RemminaPlugin*)remmina_plugin;
-} \ No newline at end of file
diff --git a/src/remmina_plugin_python_protocol.h b/src/remmina_plugin_python_protocol.h
deleted file mode 100644
index 42724dcc6..000000000
--- a/src/remmina_plugin_python_protocol.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2022 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_protocol.h
- *
- * @brief Contains the specialisation of RemminaPluginFile plugins in Python.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina/plugin.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-/**
- * Wrapper for a Python object that contains a pointer to an instance of RemminaProtocolFeature.
- */
-typedef struct
-{
- PyObject_HEAD
- RemminaProtocolFeatureType type;
- gint id;
- PyGeneric* opt1;
- PyGeneric* opt2;
- PyGeneric* opt3;
-} PyRemminaProtocolFeature;
-
-/**
- *
- */
-typedef struct
-{
- PyObject_HEAD
- PyByteArrayObject* buffer;
- int bitsPerPixel;
- int bytesPerPixel;
- int width;
- int height;
-} PyRemminaPluginScreenshotData;
-
-/**
- * Initializes the Python plugin specialisation for protocol plugins.
- */
-void remmina_plugin_python_protocol_init(void);
-
-/**
- * @brief Creates a new instance of the RemminaPluginProtocol, initializes its members and references the wrapper
- * functions.
- *
- * @param instance The instance of the Python plugin.
- *
- * @return Returns a new instance of the RemminaPlugin (must be freed!).
- */
-RemminaPlugin* remmina_plugin_python_create_protocol_plugin(PyPlugin* plugin);
-
-/**
- *
- * @return
- */
-PyRemminaProtocolFeature* remmina_plugin_python_protocol_feature_new(void);
-
-/**
- *
- * @return
- */
-PyRemminaPluginScreenshotData* remmina_plugin_python_screenshot_data_new(void);
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_protocol_widget.c b/src/remmina_plugin_python_protocol_widget.c
deleted file mode 100644
index eceb22422..000000000
--- a/src/remmina_plugin_python_protocol_widget.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2022 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.
- */
-
-/**
- * @file remmina_plugin_python_protocol_widget.c
- * @brief Implementation of the Protocol Widget API.
- * @author Mathias Winterhalter
- * @date 19.11.2020
- *
- * The RemminaPluginService provides an API for plugins to interact with Remmina. The
- * module called 'remmina' forwards this interface to make it accessible for Python
- * scripts.
- *
- * This is an example of a minimal protocol plugin:
- *
- * @code
- * import remmina
- *
- * class MyProtocol:
- * def __init__(self):
- * self.name = "MyProtocol"
- * self.description = "Example protocol plugin to explain how Python plugins work."
- * self.version = "0.1"
- * self.icon_name = ""
- * self.icon_name_ssh = ""
- *
- * def init(self, handle):
- * print("This is getting logged to the standard output of Remmina.")
- * remmina.log_print("For debugging purposes it would be better to log the output to the %s window %s!" % ("debug", ":)"))
- * self.init_your_stuff(handle)
- *
- * def open_connection(self, handle):
- * if not self.connect():
- * remmina.log_print("Error! Can not connect...")
- * return False
- *
- * remmina.remmina_signal_connected(handle)
- * remmina.log_print("Connection established!")
- * return True
- *
- *
- * def close_connection(self, handle):
- * self.disconnect()
- * return True
- *
- * plugin = MyProtocol()
- * remmina.register_plugin(plugin)
- * @endcode
- *
- *
- *
- * @see http://www.remmina.org/wp for more information.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N L U C E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-#include "remmina/plugin.h"
-#include "remmina_protocol_widget.h"
-#include "remmina/types.h"
-#include "remmina_plugin_python_remmina_file.h"
-#include "remmina_plugin_python_protocol_widget.h"
-#include "remmina_plugin_python_protocol.h"
-
-// -- Python Type -> RemminaWidget
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-static PyObject* protocol_widget_get_viewport(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_width(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_set_width(PyRemminaProtocolWidget* self, PyObject* var_width);
-static PyObject* protocol_widget_get_height(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_set_height(PyRemminaProtocolWidget* self, PyObject* var_height);
-static PyObject* protocol_widget_get_current_scale_mode(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_expand(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_set_expand(PyRemminaProtocolWidget* self, PyObject* var_expand);
-static PyObject* protocol_widget_has_error(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_set_error(PyRemminaProtocolWidget* self, PyObject* var_msg);
-static PyObject* protocol_widget_is_closed(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_file(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_emit_signal(PyRemminaProtocolWidget* self, PyObject* var_signal);
-static PyObject* protocol_widget_register_hostkey(PyRemminaProtocolWidget* self, PyObject* var_widget);
-static PyObject* protocol_widget_start_direct_tunnel(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_start_reverse_tunnel(PyRemminaProtocolWidget* self, PyObject* var_local_port);
-static PyObject* protocol_widget_start_xport_tunnel(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_set_display(PyRemminaProtocolWidget* self, PyObject* var_display);
-static PyObject* protocol_widget_signal_connection_closed(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_signal_connection_opened(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_update_align(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_unlock_dynres(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_desktop_resize(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_panel_new_certificate(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_panel_changed_certificate(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_username(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_password(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_domain(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_savepassword(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_panel_authx509(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_cacert(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_cacrl(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_clientcert(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_get_clientkey(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_save_cred(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_panel_show_listen(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_panel_show_retry(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_panel_show(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_panel_hide(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_ssh_exec(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_chat_open(PyRemminaProtocolWidget* self, PyObject* var_name);
-static PyObject* protocol_widget_chat_close(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_chat_receive(PyRemminaProtocolWidget* self, PyObject* args);
-static PyObject* protocol_widget_send_keys_signals(PyRemminaProtocolWidget* self, PyObject* args);
-
-static struct PyMethodDef python_protocol_widget_type_methods[] =
- {{ "get_viewport", (PyCFunction)protocol_widget_get_viewport, METH_NOARGS, "" },
- { "get_width", (PyCFunction)protocol_widget_get_width, METH_NOARGS, "" },
- { "set_width", (PyCFunction)protocol_widget_set_width, METH_VARARGS, "" },
- { "get_height", (PyCFunction)protocol_widget_get_height, METH_VARARGS, "" },
- { "set_height", (PyCFunction)protocol_widget_set_height, METH_VARARGS, "" },
- { "get_current_scale_mode", (PyCFunction)protocol_widget_get_current_scale_mode, METH_VARARGS, "" },
- { "get_expand", (PyCFunction)protocol_widget_get_expand, METH_VARARGS, "" },
- { "set_expand", (PyCFunction)protocol_widget_set_expand, METH_VARARGS, "" },
- { "has_error", (PyCFunction)protocol_widget_has_error, METH_VARARGS, "" },
- { "set_error", (PyCFunction)protocol_widget_set_error, METH_VARARGS, "" },
- { "is_closed", (PyCFunction)protocol_widget_is_closed, METH_VARARGS, "" },
- { "get_file", (PyCFunction)protocol_widget_get_file, METH_NOARGS, "" },
- { "emit_signal", (PyCFunction)protocol_widget_emit_signal, METH_VARARGS, "" },
- { "register_hostkey", (PyCFunction)protocol_widget_register_hostkey, METH_VARARGS, "" },
- { "start_direct_tunnel", (PyCFunction)protocol_widget_start_direct_tunnel, METH_VARARGS | METH_KEYWORDS, "" },
- { "start_reverse_tunnel", (PyCFunction)protocol_widget_start_reverse_tunnel, METH_VARARGS, "" },
- { "start_xport_tunnel", (PyCFunction)protocol_widget_start_xport_tunnel, METH_VARARGS, "" },
- { "set_display", (PyCFunction)protocol_widget_set_display, METH_VARARGS, "" },
- { "signal_connection_closed", (PyCFunction)protocol_widget_signal_connection_closed, METH_VARARGS, "" },
- { "signal_connection_opened", (PyCFunction)protocol_widget_signal_connection_opened, METH_VARARGS, "" },
- { "update_align", (PyCFunction)protocol_widget_update_align, METH_VARARGS, "" },
- { "unlock_dynres", (PyCFunction)protocol_widget_unlock_dynres, METH_VARARGS, "" },
- { "desktop_resize", (PyCFunction)protocol_widget_desktop_resize, METH_VARARGS, "" },
- { "panel_new_certificate", (PyCFunction)protocol_widget_panel_new_certificate, METH_VARARGS | METH_KEYWORDS, "" },
- { "panel_changed_certificate", (PyCFunction)protocol_widget_panel_changed_certificate,
- METH_VARARGS | METH_KEYWORDS, "" },
- { "get_username", (PyCFunction)protocol_widget_get_username, METH_VARARGS, "" },
- { "get_password", (PyCFunction)protocol_widget_get_password, METH_VARARGS, "" },
- { "get_domain", (PyCFunction)protocol_widget_get_domain, METH_VARARGS, "" },
- { "get_savepassword", (PyCFunction)protocol_widget_get_savepassword, METH_VARARGS, "" },
- { "panel_authx509", (PyCFunction)protocol_widget_panel_authx509, METH_VARARGS, "" },
- { "get_cacert", (PyCFunction)protocol_widget_get_cacert, METH_VARARGS, "" },
- { "get_cacrl", (PyCFunction)protocol_widget_get_cacrl, METH_VARARGS, "" },
- { "get_clientcert", (PyCFunction)protocol_widget_get_clientcert, METH_VARARGS, "" },
- { "get_clientkey", (PyCFunction)protocol_widget_get_clientkey, METH_VARARGS, "" },
- { "save_cred", (PyCFunction)protocol_widget_save_cred, METH_VARARGS, "" },
- { "panel_show_listen", (PyCFunction)protocol_widget_panel_show_listen, METH_VARARGS, "" },
- { "panel_show_retry", (PyCFunction)protocol_widget_panel_show_retry, METH_VARARGS, "" },
- { "panel_show", (PyCFunction)protocol_widget_panel_show, METH_VARARGS, "" },
- { "panel_hide", (PyCFunction)protocol_widget_panel_hide, METH_VARARGS, "" },
- { "ssh_exec", (PyCFunction)protocol_widget_ssh_exec, METH_VARARGS | METH_KEYWORDS, "" },
- { "chat_open", (PyCFunction)protocol_widget_chat_open, METH_VARARGS, "" },
- { "chat_close", (PyCFunction)protocol_widget_chat_close, METH_VARARGS, "" },
- { "chat_receive", (PyCFunction)protocol_widget_chat_receive, METH_VARARGS, "" },
- { "send_keys_signals", (PyCFunction)protocol_widget_send_keys_signals, METH_VARARGS | METH_KEYWORDS, "" },
- { NULL }};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-static PyObject* python_protocol_feature_new(PyTypeObject* type, PyObject* kws, PyObject* args)
-{
- TRACE_CALL(__func__);
- PyRemminaProtocolWidget* self;
- self = (PyRemminaProtocolWidget*)type->tp_alloc(type, 0);
- if (!self)
- {
- return NULL;
- }
-
- return (PyObject*)self;
-}
-
-static int python_protocol_feature_init(PyObject* self, PyObject* args, PyObject* kwds)
-{
- return 0;
-}
-
-static PyTypeObject python_protocol_widget_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "remmina.RemminaProtocolWidget",
- .tp_doc = "RemminaProtocolWidget",
- .tp_basicsize = sizeof(PyRemminaProtocolWidget),
- .tp_itemsize = 0,
- .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_new = python_protocol_feature_new,
- .tp_init = python_protocol_feature_init,
- .tp_methods = python_protocol_widget_type_methods
-};
-
-PyRemminaProtocolWidget* remmina_plugin_python_protocol_widget_create(void)
-{
- TRACE_CALL(__func__);
-
- PyRemminaProtocolWidget* result = PyObject_NEW(PyRemminaProtocolWidget, &python_protocol_widget_type);
- assert(result);
-
- PyErr_Print();
- Py_INCREF(result);
- result->gp = NULL;
- return result;
-}
-
-void remmina_plugin_python_protocol_widget_init(void)
-{
- init_pygobject();
-}
-
-void remmina_plugin_python_protocol_widget_type_ready(void)
-{
- TRACE_CALL(__func__);
- if (PyType_Ready(&python_protocol_widget_type) < 0)
- {
- g_printerr("Error initializing remmina.RemminaWidget!\n");
- PyErr_Print();
- }
-}
-
-static PyObject* protocol_widget_get_viewport(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
- return (PyObject*)new_pywidget(G_OBJECT(remmina_protocol_widget_gtkviewport(self->gp)));
-}
-
-static PyObject* protocol_widget_get_width(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("i", remmina_protocol_widget_get_width(self->gp));
-}
-
-static PyObject* protocol_widget_set_width(PyRemminaProtocolWidget* self, PyObject* var_width)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!var_width)
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- if (PyLong_Check(var_width))
- {
- g_printerr("[%s:%d@%s]: Argument is not of type Long!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- gint width = (gint)PyLong_AsLong(var_width);
- remmina_protocol_widget_set_height(self->gp, width);
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_get_height(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("i", remmina_protocol_widget_get_height(self->gp));
-}
-
-static PyObject* protocol_widget_set_height(PyRemminaProtocolWidget* self, PyObject* var_height)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!var_height)
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- if (PyLong_Check(var_height))
- {
- g_printerr("[%s:%d@%s]: Argument is not of type Long!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- gint height = (gint)PyLong_AsLong(var_height);
- remmina_protocol_widget_set_height(self->gp, height);
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_get_current_scale_mode(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("i", remmina_protocol_widget_get_current_scale_mode(self->gp));
-}
-
-static PyObject* protocol_widget_get_expand(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("p", remmina_protocol_widget_get_expand(self->gp));
-}
-
-static PyObject* protocol_widget_set_expand(PyRemminaProtocolWidget* self, PyObject* var_expand)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!var_expand)
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- if (PyBool_Check(var_expand))
- {
- g_printerr("[%s:%d@%s]: Argument is not of type Boolean!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- remmina_protocol_widget_set_expand(self->gp, PyObject_IsTrue(var_expand));
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_has_error(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("p", remmina_protocol_widget_has_error(self->gp));
-}
-
-static PyObject* protocol_widget_set_error(PyRemminaProtocolWidget* self, PyObject* var_msg)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!var_msg)
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- if (PyUnicode_Check(var_msg))
- {
- g_printerr("[%s:%d@%s]: Argument is not of type String!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- const gchar* msg = PyUnicode_AsUTF8(var_msg);
- remmina_protocol_widget_set_error(self->gp, msg);
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_is_closed(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("p", remmina_protocol_widget_is_closed(self->gp));
-}
-
-static PyObject* protocol_widget_get_file(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- RemminaFile* file = remmina_protocol_widget_get_file(self->gp);
- return (PyObject*)remmina_plugin_python_remmina_file_to_python(file);
-}
-
-static PyObject* protocol_widget_emit_signal(PyRemminaProtocolWidget* self, PyObject* var_signal)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!var_signal)
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- if (PyUnicode_Check(var_signal))
- {
- g_printerr("[%s:%d@%s]: Argument is not of type String!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- remmina_protocol_widget_set_error(self->gp, PyUnicode_AsUTF8(var_signal));
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_register_hostkey(PyRemminaProtocolWidget* self, PyObject* var_widget)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!var_widget)
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- remmina_protocol_widget_register_hostkey(self->gp, get_pywidget(var_widget));
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_start_direct_tunnel(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- gint default_port;
- gboolean port_plus;
-
- if (!args)
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- }
-
- if (PyArg_ParseTuple(args, "ii", &default_port, &port_plus))
- {
- return Py_BuildValue("s", remmina_protocol_widget_start_direct_tunnel(self->gp, default_port, port_plus));
- }
- else
- {
- PyErr_Print();
- return NULL;
- }
- return Py_None;
-}
-
-static PyObject* protocol_widget_start_reverse_tunnel(PyRemminaProtocolWidget* self, PyObject* var_local_port)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!PyLong_Check(var_local_port))
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- if (!PyLong_Check(var_local_port))
- {
- g_printerr("[%s:%d@%s]: Argument is not of type Long!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- return Py_BuildValue("p", remmina_protocol_widget_start_reverse_tunnel(self->gp, (gint)PyLong_AsLong(var_local_port)));
-}
-
-static gboolean xport_tunnel_init(RemminaProtocolWidget* gp, gint remotedisplay, const gchar* server, gint port)
-{
- TRACE_CALL(__func__);
- PyPlugin* plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyObject* result = PyObject_CallMethod(plugin->instance, "xport_tunnel_init", "Oisi", gp, remotedisplay, server, port);
- return PyObject_IsTrue(result);
-}
-
-static PyObject* protocol_widget_start_xport_tunnel(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("p", remmina_protocol_widget_start_xport_tunnel(self->gp, xport_tunnel_init));
-}
-
-static PyObject* protocol_widget_set_display(PyRemminaProtocolWidget* self, PyObject* var_display)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!var_display)
- {
- g_printerr("[%s:%d@%s]: Argument is null!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- if (!PyLong_Check(var_display))
- {
- g_printerr("[%s:%d@%s]: Argument is not of type Long!\n", __FILE__, __LINE__, __func__);
- return NULL;
- }
-
- remmina_protocol_widget_set_display(self->gp, (gint)PyLong_AsLong(var_display));
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_signal_connection_closed(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_signal_connection_closed(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_signal_connection_opened(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_signal_connection_opened(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_update_align(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_update_align(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_unlock_dynres(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_unlock_dynres(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_desktop_resize(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_desktop_resize(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_panel_new_certificate(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
- gchar* subject, * issuer, * fingerprint;
-
- if (PyArg_ParseTuple(args, "sss", &subject, &issuer, &fingerprint))
- {
- remmina_protocol_widget_panel_new_certificate(self->gp, subject, issuer, fingerprint);
- }
- else
- {
- PyErr_Print();
- return NULL;
- }
- return Py_None;
-}
-
-static PyObject* protocol_widget_panel_changed_certificate(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
- gchar* subject, * issuer, * new_fingerprint, * old_fingerprint;
-
- if (PyArg_ParseTuple(args, "sss", &subject, &issuer, &new_fingerprint, &old_fingerprint))
- {
- remmina_protocol_widget_panel_changed_certificate(self->gp, subject, issuer, new_fingerprint, old_fingerprint);
- }
- else
- {
- PyErr_Print();
- return NULL;
- }
- return Py_None;
-}
-
-static PyObject* protocol_widget_get_username(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("s", remmina_protocol_widget_get_username(self->gp));
-}
-
-static PyObject* protocol_widget_get_password(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("s", remmina_protocol_widget_get_password(self->gp));
-}
-
-static PyObject* protocol_widget_get_domain(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("s", remmina_protocol_widget_get_domain(self->gp));
-}
-
-static PyObject* protocol_widget_get_savepassword(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("p", remmina_protocol_widget_get_savepassword(self->gp));
-}
-
-static PyObject* protocol_widget_panel_authx509(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("i", remmina_protocol_widget_panel_authx509(self->gp));
-}
-
-static PyObject* protocol_widget_get_cacert(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("s", remmina_protocol_widget_get_cacert(self->gp));
-}
-
-static PyObject* protocol_widget_get_cacrl(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("s", remmina_protocol_widget_get_cacrl(self->gp));
-}
-
-static PyObject* protocol_widget_get_clientcert(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("s", remmina_protocol_widget_get_clientcert(self->gp));
-}
-
-static PyObject* protocol_widget_get_clientkey(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- return Py_BuildValue("s", remmina_protocol_widget_get_clientkey(self->gp));
-}
-
-static PyObject* protocol_widget_save_cred(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_save_cred(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_panel_show_listen(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
- gint port = 0;
-
- if (PyArg_ParseTuple(args, "i", &port))
- {
- remmina_protocol_widget_panel_show_listen(self->gp, port);
- }
- else
- {
- PyErr_Print();
- return NULL;
- }
- return Py_None;
-}
-
-static PyObject* protocol_widget_panel_show_retry(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_panel_show_retry(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_panel_show(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_panel_show(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_panel_hide(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_panel_hide(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_ssh_exec(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
- gboolean wait;
- gchar* cmd;
-
- if (PyArg_ParseTuple(args, "ps", &wait, &cmd))
- {
- remmina_protocol_widget_ssh_exec(self->gp, wait, cmd);
- }
- else
- {
- PyErr_Print();
- return NULL;
- }
- return Py_None;
-}
-
-static void _on_send_callback_wrapper(RemminaProtocolWidget* gp, const gchar* text)
-{
- PyPlugin* plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyObject_CallMethod(plugin->instance, "on_send", "Os", gp, text);
-}
-
-static void _on_destroy_callback_wrapper(RemminaProtocolWidget* gp)
-{
- PyPlugin* plugin = remmina_plugin_python_get_plugin(gp->plugin->name);
- PyObject_CallMethod(plugin->instance, "on_destroy", "O", gp);
-}
-
-static PyObject* protocol_widget_chat_open(PyRemminaProtocolWidget* self, PyObject* var_name)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- if (!PyUnicode_Check(var_name))
- {
- g_printerr("[%s:%d@%s]: Argument is not of type String!\n", __FILE__, __LINE__, __func__);
- }
-
- remmina_protocol_widget_chat_open(self->gp,
- PyUnicode_AsUTF8(var_name),
- _on_send_callback_wrapper,
- _on_destroy_callback_wrapper);
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_chat_close(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
-
- remmina_protocol_widget_panel_hide(self->gp);
- return Py_None;
-}
-
-static PyObject* protocol_widget_chat_receive(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
- gchar* text;
-
- if (PyArg_ParseTuple(args, "s", &text))
- {
- remmina_protocol_widget_chat_receive(self->gp, text);
- }
- else
- {
- PyErr_Print();
- return NULL;
- }
-
- return Py_None;
-}
-
-static PyObject* protocol_widget_send_keys_signals(PyRemminaProtocolWidget* self, PyObject* args)
-{
- TRACE_CALL(__func__);
- SELF_CHECK();
- guint* keyvals;
- int length;
- GdkEventType event_type;
- PyObject* widget;
-
- if (PyArg_ParseTuple(args, "Osii", &widget, &keyvals, &length, &event_type) && widget && keyvals)
- {
- if (event_type < GDK_NOTHING || event_type >= GDK_EVENT_LAST)
- {
- g_printerr("[%s:%d@%s]: %d is not a known value for GdkEventType!\n", __FILE__, __LINE__, __func__, event_type);
- return NULL;
- }
- else
- {
- remmina_protocol_widget_send_keys_signals((GtkWidget*)widget, keyvals, length, event_type);
- }
- }
- else
- {
- PyErr_Print();
- return NULL;
- }
-
- return Py_None;
-}
diff --git a/src/remmina_plugin_python_protocol_widget.h b/src/remmina_plugin_python_protocol_widget.h
deleted file mode 100644
index dcbbc8093..000000000
--- a/src/remmina_plugin_python_protocol_widget.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2016-2022 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.
- */
-
-/**
- * @file remmina_plugin_python_protocol_widget.h
- *
- * @brief Contains the implementation of the widget handling used from the protocol plugin.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-/**
- * Initializes the widget backend of the protocol plugin implementation.
- */
-void remmina_plugin_python_protocol_widget_init(void);
-
-/**
- * Initializes Python types used for protocol widgets.
- */
-void remmina_plugin_python_protocol_widget_type_ready(void);
-
-/**
- * Creates a new instance of PyRemminaProtocolWidget and initializes its fields.
- */
-PyRemminaProtocolWidget* remmina_plugin_python_protocol_widget_create();
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_remmina.c b/src/remmina_plugin_python_remmina.c
deleted file mode 100644
index ad0ebc7a4..000000000
--- a/src/remmina_plugin_python_remmina.c
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2016-2022 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.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-#include "remmina_main.h"
-#include "remmina_plugin_manager.h"
-#include "remmina/plugin.h"
-#include "remmina/types.h"
-#include "remmina_protocol_widget.h"
-#include "remmina_log.h"
-
-#include "remmina_plugin_python_remmina.h"
-#include "remmina_plugin_python_protocol_widget.h"
-
-#include "remmina_plugin_python_entry.h"
-#include "remmina_plugin_python_file.h"
-#include "remmina_plugin_python_protocol.h"
-#include "remmina_plugin_python_tool.h"
-#include "remmina_plugin_python_secret.h"
-#include "remmina_plugin_python_pref.h"
-
-#include "remmina_pref.h"
-#include "remmina_ssh.h"
-#include "remmina_file_manager.h"
-#include "remmina_widget_pool.h"
-#include "remmina_public.h"
-#include "remmina_masterthread_exec.h"
-
-#include "rcw.h"
-#include "remmina_plugin_python_remmina_file.h"
-
-#include <string.h>
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-/**
- * Util function to check if a specific member is define in a Python object.
- */
-gboolean remmina_plugin_python_check_mandatory_member(PyObject* instance, const gchar* member);
-
-static PyObject* remmina_plugin_python_debug_wrapper(PyObject* self, PyObject* msg);
-static PyObject* remmina_register_plugin_wrapper(PyObject* self, PyObject* plugin);
-static PyObject* remmina_file_get_datadir_wrapper(PyObject* self, PyObject* plugin);
-static PyObject* remmina_file_new_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* remmina_pref_set_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* remmina_pref_get_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* remmina_pref_get_scale_quality_wrapper(PyObject* self, PyObject* plugin);
-static PyObject* remmina_pref_get_sshtunnel_port_wrapper(PyObject* self, PyObject* plugin);
-static PyObject* remmina_pref_get_ssh_loglevel_wrapper(PyObject* self, PyObject* plugin);
-static PyObject* remmina_pref_get_ssh_parseconfig_wrapper(PyObject* self, PyObject* plugin);
-static PyObject* remmina_pref_keymap_get_keyval_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* remmina_plugin_python_log_print_wrapper(PyObject* self, PyObject* arg);
-static PyObject* remmina_widget_pool_register_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* rcw_open_from_file_full_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* remmina_public_get_server_port_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* remmina_masterthread_exec_is_main_thread_wrapper(PyObject* self, PyObject* plugin);
-static PyObject* remmina_gtksocket_available_wrapper(PyObject* self, PyObject* plugin);
-static PyObject*
-remmina_protocol_widget_get_profile_remote_height_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject*
-remmina_protocol_widget_get_profile_remote_width_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* remmina_plugin_python_show_dialog_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-static PyObject* remmina_plugin_python_get_mainwindow_wrapper(PyObject* self, PyObject* args);
-static PyObject* remmina_protocol_plugin_signal_connection_opened_wrapper(PyObject* self, PyObject* args);
-static PyObject* remmina_protocol_plugin_signal_connection_closed_wrapper(PyObject* self, PyObject* args);
-static PyObject* remmina_protocol_plugin_init_auth_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
-
-/**
- * Declares functions for the Remmina module. These functions can be called from Python and are wired to one of the
- * functions here in this file.
- */
-static PyMethodDef remmina_python_module_type_methods[] = {
- /**
- * The first function that need to be called from the plugin code, since it registers the Python class acting as
- * a Remmina plugin. Without this call the plugin will not be recognized.
- */
- { "register_plugin", remmina_register_plugin_wrapper, METH_O, NULL },
-
- /**
- * Prints a string into the Remmina log infrastructure.
- */
- { "log_print", remmina_plugin_python_log_print_wrapper, METH_VARARGS, NULL },
-
- /**
- * Prints a debug message if enabled.
- */
- { "debug", remmina_plugin_python_debug_wrapper, METH_VARARGS, NULL },
-
- /**
- * Shows a GTK+ dialog.
- */
- { "show_dialog", (PyCFunction)remmina_plugin_python_show_dialog_wrapper, METH_VARARGS | METH_KEYWORDS,
- NULL },
-
- /**
- * Returns the GTK+ object of the main window of Remmina.
- */
- { "get_main_window", remmina_plugin_python_get_mainwindow_wrapper, METH_NOARGS, NULL },
-
- /**
- * Calls remmina_file_get_datadir and returns its result.
- */
- { "get_datadir", remmina_file_get_datadir_wrapper, METH_VARARGS, NULL },
-
- /**
- * Calls remmina_file_new and returns its result.
- */
- { "file_new", (PyCFunction)remmina_file_new_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
-
- /**
- * Calls remmina_pref_set_value and returns its result.
- */
- { "pref_set_value", (PyCFunction)remmina_pref_set_value_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
-
- /**
- * Calls remmina_pref_get_value and returns its result.
- */
- { "pref_get_value", (PyCFunction)remmina_pref_get_value_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
-
- /**
- * Calls remmina_pref_get_scale_quality and returns its result.
- */
- { "pref_get_scale_quality", remmina_pref_get_scale_quality_wrapper, METH_VARARGS, NULL },
-
- /**
- * Calls remmina_pref_get_sshtunnel_port and returns its result.
- */
- { "pref_get_sshtunnel_port", remmina_pref_get_sshtunnel_port_wrapper, METH_VARARGS, NULL },
-
- /**
- * Calls remmina_pref_get_ssh_loglevel and returns its result.
- */
- { "pref_get_ssh_loglevel", remmina_pref_get_ssh_loglevel_wrapper, METH_VARARGS, NULL },
-
- /**
- * Calls remmina_pref_get_ssh_parseconfig and returns its result.
- */
- { "pref_get_ssh_parseconfig", remmina_pref_get_ssh_parseconfig_wrapper, METH_VARARGS, NULL },
-
- /**
- * Calls remmina_pref_keymap_get_keyval and returns its result.
- */
- { "pref_keymap_get_keyval", (PyCFunction)remmina_pref_keymap_get_keyval_wrapper, METH_VARARGS | METH_KEYWORDS,
- NULL },
-
- /**
- * Calls remmina_widget_pool_register and returns its result.
- */
- { "widget_pool_register", (PyCFunction)remmina_widget_pool_register_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
-
- /**
- * Calls rcw_open_from_file_full and returns its result.
- */
- { "rcw_open_from_file_full", (PyCFunction)rcw_open_from_file_full_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
-
- /**
- * Calls remmina_public_get_server_port and returns its result.
- */
- { "public_get_server_port", (PyCFunction)remmina_public_get_server_port_wrapper, METH_VARARGS | METH_KEYWORDS,
- NULL },
-
- /**
- * Calls remmina_masterthread_exec_is_main_thread and returns its result.
- */
- { "masterthread_exec_is_main_thread", remmina_masterthread_exec_is_main_thread_wrapper, METH_VARARGS, NULL },
-
- /**
- * Calls remmina_gtksocket_available and returns its result.
- */
- { "gtksocket_available", remmina_gtksocket_available_wrapper, METH_VARARGS, NULL },
-
- /**
- * Calls remmina_protocol_widget_get_profile_remote_width and returns its result.
- */
- { "protocol_widget_get_profile_remote_width",
- (PyCFunction)remmina_protocol_widget_get_profile_remote_width_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
-
- /**
- * Calls remmina_protocol_widget_get_profile_remote_height and returns its result.
- */
- { "protocol_widget_get_profile_remote_height",
- (PyCFunction)remmina_protocol_widget_get_profile_remote_height_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
- { "protocol_plugin_signal_connection_opened", (PyCFunction)remmina_protocol_plugin_signal_connection_opened_wrapper,
- METH_VARARGS, NULL },
-
- { "protocol_plugin_signal_connection_closed", (PyCFunction)remmina_protocol_plugin_signal_connection_closed_wrapper,
- METH_VARARGS, NULL },
-
- { "protocol_plugin_init_auth", (PyCFunction)remmina_protocol_plugin_init_auth_wrapper, METH_VARARGS | METH_KEYWORDS,
- NULL },
-
- /* Sentinel */
- { NULL }
-};
-
-/**
- * Adapter struct to handle Remmina protocol settings.
- */
-typedef struct
-{
- PyObject_HEAD
- RemminaProtocolSettingType settingType;
- gchar* name;
- gchar* label;
- gboolean compact;
- PyObject* opt1;
- PyObject* opt2;
-} PyRemminaProtocolSetting;
-
-/**
- * The definition of the Python module 'remmina'.
- */
-static PyModuleDef remmina_python_module_type = {
- PyModuleDef_HEAD_INIT,
- .m_name = "remmina",
- .m_doc = "Remmina API.",
- .m_size = -1,
- .m_methods = remmina_python_module_type_methods
-};
-
-// -- Python Object -> Setting
-
-/**
- * Initializes the memory and the fields of the remmina.Setting Python type.
- * @details This function is callback for the Python engine.
- */
-static PyObject* python_protocol_setting_new(PyTypeObject* type, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- PyRemminaProtocolSetting* self = (PyRemminaProtocolSetting*)type->tp_alloc(type, 0);
-
- if (!self)
- {
- return NULL;
- }
-
- self->name = "";
- self->label = "";
- self->compact = FALSE;
- self->opt1 = NULL;
- self->opt2 = NULL;
- self->settingType = 0;
-
- return (PyObject*)self;
-}
-
-/**
- * Constructor of the remmina.Setting Python type.
- * @details This function is callback for the Python engine.
- */
-static int python_protocol_setting_init(PyRemminaProtocolSetting* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static gchar* kwlist[] = { "type", "name", "label", "compact", "opt1", "opt2", NULL };
- PyObject* name;
- PyObject* label;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|lOOpOO", kwlist,
- &self->settingType, &name, &label, &self->compact, &self->opt1, &self->opt2))
- {
- return -1;
- }
-
- Py_ssize_t len = PyUnicode_GetLength(label);
- if (len == 0)
- {
- self->label = "";
- }
- else
- {
- self->label = remmina_plugin_python_copy_string_from_python(label, len);
- if (!self->label)
- {
- g_printerr("Unable to extract label during initialization of Python settings module!\n");
- remmina_plugin_python_check_error();
- }
- }
-
- len = PyUnicode_GetLength(name);
- if (len == 0)
- {
- self->name = "";
- }
- else
- {
- self->name = remmina_plugin_python_copy_string_from_python(label, len);
- if (!self->name)
- {
- g_printerr("Unable to extract name during initialization of Python settings module!\n");
- remmina_plugin_python_check_error();
- }
- }
-
- return 0;
-}
-
-static PyMemberDef python_protocol_setting_type_members[] = {
- { "settingType", offsetof(PyRemminaProtocolSetting, settingType), T_INT, 0, NULL },
- { "name", offsetof(PyRemminaProtocolSetting, name), T_STRING, 0, NULL },
- { "label", offsetof(PyRemminaProtocolSetting, label), T_STRING, 0, NULL },
- { "compact", offsetof(PyRemminaProtocolSetting, compact), T_BOOL, 0, NULL },
- { "opt1", offsetof(PyRemminaProtocolSetting, opt1), T_OBJECT, 0, NULL },
- { "opt2", offsetof(PyRemminaProtocolSetting, opt2), T_OBJECT, 0, NULL },
- { NULL }
-};
-
-static PyTypeObject python_protocol_setting_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "remmina.Setting",
- .tp_doc = "Remmina Setting information",
- .tp_basicsize = sizeof(PyRemminaProtocolSetting),
- .tp_itemsize = 0,
- .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_new = python_protocol_setting_new,
- .tp_init = (initproc)python_protocol_setting_init,
- .tp_members = python_protocol_setting_type_members
-};
-
-// -- Python Type -> Feature
-
-
-static PyMemberDef python_protocol_feature_members[] = {
- { "type", T_INT, offsetof(PyRemminaProtocolFeature, type), 0, NULL },
- { "id", T_INT, offsetof(PyRemminaProtocolFeature, id), 0, NULL },
- { "opt1", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt1), 0, NULL },
- { "opt2", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt2), 0, NULL },
- { "opt3", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt3), 0, NULL },
- { NULL }
-};
-
-PyObject* python_protocol_feature_new(PyTypeObject* type, PyObject* kws, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- PyRemminaProtocolFeature* self;
- self = (PyRemminaProtocolFeature*)type->tp_alloc(type, 0);
- if (!self)
- return NULL;
-
- self->id = 0;
- self->type = 0;
- self->opt1 = (PyGeneric*)Py_None;
- self->opt1->raw = NULL;
- self->opt1->type_hint = REMMINA_TYPEHINT_UNDEFINED;
- self->opt2 = (PyGeneric*)Py_None;
- self->opt2->raw = NULL;
- self->opt2->type_hint = REMMINA_TYPEHINT_UNDEFINED;
- self->opt3 = (PyGeneric*)Py_None;
- self->opt3->raw = NULL;
- self->opt3->type_hint = REMMINA_TYPEHINT_UNDEFINED;
-
- return (PyObject*)self;
-}
-
-static int python_protocol_feature_init(PyRemminaProtocolFeature* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "type", "id", "opt1", "opt2", "opt3", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|llOOO", kwlist, &self->type, &self->id, &self->opt1, &self
- ->opt2, &self->opt3))
- return -1;
-
- return 0;
-}
-
-static PyTypeObject python_protocol_feature_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "remmina.ProtocolFeature",
- .tp_doc = "Remmina Setting information",
- .tp_basicsize = sizeof(PyRemminaProtocolFeature),
- .tp_itemsize = 0,
- .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_new = python_protocol_feature_new,
- .tp_init = (initproc)python_protocol_feature_init,
- .tp_members = python_protocol_feature_members
-};
-
-PyRemminaProtocolFeature* remmina_plugin_python_protocol_feature_new(void)
-{
- PyRemminaProtocolFeature* feature = (PyRemminaProtocolFeature*)PyObject_New(PyRemminaProtocolFeature, &python_protocol_feature_type);
- feature->id = 0;
- feature->opt1 = remmina_plugin_python_generic_new();
- feature->opt1->raw = NULL;
- feature->opt1->type_hint = REMMINA_TYPEHINT_UNDEFINED;
- feature->opt2 = remmina_plugin_python_generic_new();
- feature->opt2->raw = NULL;
- feature->opt2->type_hint = REMMINA_TYPEHINT_UNDEFINED;
- feature->opt3 = remmina_plugin_python_generic_new();
- feature->opt3->raw = NULL;
- feature->opt3->type_hint = REMMINA_TYPEHINT_UNDEFINED;
- feature->type = 0;
- Py_IncRef((PyObject*)feature);
- return feature;
-}
-
-
-// -- Python Type -> Screenshot Data
-
-static PyMemberDef python_screenshot_data_members[] = {
- { "buffer", T_OBJECT, offsetof(PyRemminaPluginScreenshotData, buffer), 0, NULL },
- { "width", T_INT, offsetof(PyRemminaPluginScreenshotData, width), 0, NULL },
- { "height", T_INT, offsetof(PyRemminaPluginScreenshotData, height), 0, NULL },
- { "bitsPerPixel", T_INT, offsetof(PyRemminaPluginScreenshotData, bitsPerPixel), 0, NULL },
- { "bytesPerPixel", T_INT, offsetof(PyRemminaPluginScreenshotData, bytesPerPixel), 0, NULL },
- { NULL }
-};
-
-PyObject* python_screenshot_data_new(PyTypeObject* type, PyObject* kws, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- PyRemminaPluginScreenshotData* self;
- self = (PyRemminaPluginScreenshotData*)type->tp_alloc(type, 0);
- if (!self)
- return NULL;
-
- self->buffer = (PyByteArrayObject*)PyObject_New(PyByteArrayObject, &PyByteArray_Type);
- self->height = 0;
- self->width = 0;
- self->bitsPerPixel = 0;
- self->bytesPerPixel = 0;
-
- return (PyObject*)self;
-}
-
-static int python_screenshot_data_init(PyRemminaPluginScreenshotData* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- g_printerr("Not to be initialized within Python!");
- return -1;
-}
-
-static PyTypeObject python_screenshot_data_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "remmina.RemminaScreenshotData",
- .tp_doc = "Remmina Screenshot Data",
- .tp_basicsize = sizeof(PyRemminaPluginScreenshotData),
- .tp_itemsize = 0,
- .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_new = python_screenshot_data_new,
- .tp_init = (initproc)python_screenshot_data_init,
- .tp_members = python_screenshot_data_members
-};
-PyRemminaPluginScreenshotData* remmina_plugin_python_screenshot_data_new(void)
-{
- PyRemminaPluginScreenshotData* data = (PyRemminaPluginScreenshotData*)PyObject_New(PyRemminaPluginScreenshotData, &python_screenshot_data_type);
- data->buffer = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
- Py_IncRef((PyObject*)data->buffer);
- data->height = 0;
- data->width = 0;
- data->bitsPerPixel = 0;
- data->bytesPerPixel = 0;
- return data;
-}
-
-static PyObject* remmina_plugin_python_generic_to_int(PyGeneric* self, PyObject* args);
-static PyObject* remmina_plugin_python_generic_to_bool(PyGeneric* self, PyObject* args);
-static PyObject* remmina_plugin_python_generic_to_string(PyGeneric* self, PyObject* args);
-
-static void remmina_plugin_python_generic_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-static PyMethodDef remmina_plugin_python_generic_methods[] = {
- { "to_int", (PyCFunction)remmina_plugin_python_generic_to_int, METH_NOARGS, "" },
- { "to_bool", (PyCFunction)remmina_plugin_python_generic_to_bool, METH_NOARGS, "" },
- { "to_string", (PyCFunction)remmina_plugin_python_generic_to_string, METH_NOARGS, "" },
- { NULL }
-};
-
-static PyMemberDef remmina_plugin_python_generic_members[] = {
- { "raw", T_OBJECT, offsetof(PyGeneric, raw), 0, "" },
- { NULL }
-};
-
-PyObject* remmina_plugin_python_generic_type_new(PyTypeObject* type, PyObject* kws, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- PyGeneric* self;
- self = (PyGeneric*)type->tp_alloc(type, 0);
- if (!self)
- return NULL;
-
- self->raw = Py_None;
-
- return (PyObject*)self;
-}
-
-static int remmina_plugin_python_generic_init(PyGeneric* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "raw", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &self->raw))
- return -1;
-
- return 0;
-}
-
-static PyTypeObject python_generic_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "remmina.Generic",
- .tp_doc = "",
- .tp_basicsize = sizeof(PyGeneric),
- .tp_itemsize = 0,
- .tp_dealloc = remmina_plugin_python_generic_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_new = remmina_plugin_python_generic_type_new,
- .tp_init = (initproc)remmina_plugin_python_generic_init,
- .tp_members = remmina_plugin_python_generic_members,
- .tp_methods = remmina_plugin_python_generic_methods,
-};
-
-PyGeneric* remmina_plugin_python_generic_new(void)
-{
- PyGeneric* generic = (PyGeneric*)PyObject_New(PyGeneric, &python_generic_type);
- generic->raw = PyLong_FromLongLong(0LL);
- Py_IncRef((PyObject*)generic);
- return generic;
-}
-
-static PyObject* remmina_plugin_python_generic_to_int(PyGeneric* self, PyObject* args)
-{
- SELF_CHECK();
-
- if (self->raw == NULL)
- {
- return Py_None;
- }
- else if (self->type_hint == REMMINA_TYPEHINT_SIGNED)
- {
- return PyLong_FromLongLong((long long)self->raw);
- }
- else if (self->type_hint == REMMINA_TYPEHINT_UNSIGNED)
- {
- return PyLong_FromUnsignedLongLong((unsigned long long)self->raw);
- }
-
- return Py_None;
-}
-static PyObject* remmina_plugin_python_generic_to_bool(PyGeneric* self, PyObject* args)
-{
- SELF_CHECK();
-
- if (self->raw == NULL)
- {
- return Py_None;
- }
- else if (self->type_hint == REMMINA_TYPEHINT_BOOLEAN)
- {
- return PyBool_FromLong((long)self->raw);
- }
-
- return Py_None;
-}
-static PyObject* remmina_plugin_python_generic_to_string(PyGeneric* self, PyObject* args)
-{
- SELF_CHECK();
-
- if (self->raw == NULL)
- {
- return Py_None;
- }
- else if (self->type_hint == REMMINA_TYPEHINT_STRING)
- {
- return PyUnicode_FromString((const char*)self->raw);
- }
-
- return Py_None;
-}
-
-/**
- * Is called from the Python engine when it initializes the 'remmina' module.
- * @details This function is only called by the Python engine!
- */
-PyMODINIT_FUNC remmina_plugin_python_module_initialize(void)
-{
- TRACE_CALL(__func__);
-
- if (PyType_Ready(&python_screenshot_data_type) < 0)
- {
- PyErr_Print();
- return NULL;
- }
-
- if (PyType_Ready(&python_generic_type) < 0)
- {
- PyErr_Print();
- return NULL;
- }
-
- if (PyType_Ready(&python_protocol_setting_type) < 0)
- {
- PyErr_Print();
- return NULL;
- }
-
- if (PyType_Ready(&python_protocol_feature_type) < 0)
- {
- PyErr_Print();
- return NULL;
- }
-
- remmina_plugin_python_protocol_widget_type_ready();
- remmina_plugin_python_remmina_init_types();
-
- PyObject* module = PyModule_Create(&remmina_python_module_type);
- if (!module)
- {
- PyErr_Print();
- return NULL;
- }
-
- PyModule_AddIntConstant(module, "BUTTONS_CLOSE", (long)GTK_BUTTONS_CLOSE);
- PyModule_AddIntConstant(module, "BUTTONS_NONE", (long)GTK_BUTTONS_NONE);
- PyModule_AddIntConstant(module, "BUTTONS_OK", (long)GTK_BUTTONS_OK);
- PyModule_AddIntConstant(module, "BUTTONS_CLOSE", (long)GTK_BUTTONS_CLOSE);
- PyModule_AddIntConstant(module, "BUTTONS_CANCEL", (long)GTK_BUTTONS_CANCEL);
- PyModule_AddIntConstant(module, "BUTTONS_YES_NO", (long)GTK_BUTTONS_YES_NO);
- PyModule_AddIntConstant(module, "BUTTONS_OK_CANCEL", (long)GTK_BUTTONS_OK_CANCEL);
-
- PyModule_AddIntConstant(module, "MESSAGE_INFO", (long)GTK_MESSAGE_INFO);
- PyModule_AddIntConstant(module, "MESSAGE_WARNING", (long)GTK_MESSAGE_WARNING);
- PyModule_AddIntConstant(module, "MESSAGE_QUESTION", (long)GTK_MESSAGE_QUESTION);
- PyModule_AddIntConstant(module, "MESSAGE_ERROR", (long)GTK_MESSAGE_ERROR);
- PyModule_AddIntConstant(module, "MESSAGE_OTHER", (long)GTK_MESSAGE_OTHER);
-
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_SERVER", (long)REMMINA_PROTOCOL_SETTING_TYPE_SERVER);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_PASSWORD", (long)REMMINA_PROTOCOL_SETTING_TYPE_PASSWORD);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_RESOLUTION", (long)REMMINA_PROTOCOL_SETTING_TYPE_RESOLUTION);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_KEYMAP", (long)REMMINA_PROTOCOL_SETTING_TYPE_KEYMAP);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_TEXT", (long)REMMINA_PROTOCOL_SETTING_TYPE_TEXT);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_SELECT", (long)REMMINA_PROTOCOL_SETTING_TYPE_SELECT);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_COMBO", (long)REMMINA_PROTOCOL_SETTING_TYPE_COMBO);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_CHECK", (long)REMMINA_PROTOCOL_SETTING_TYPE_CHECK);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_FILE", (long)REMMINA_PROTOCOL_SETTING_TYPE_FILE);
- PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_FOLDER", (long)REMMINA_PROTOCOL_SETTING_TYPE_FOLDER);
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_MULTIMON", (long)REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON);
-
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_PREF", (long)REMMINA_PROTOCOL_FEATURE_TYPE_PREF);
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_TOOL", (long)REMMINA_PROTOCOL_FEATURE_TYPE_TOOL);
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_UNFOCUS", (long)REMMINA_PROTOCOL_FEATURE_TYPE_UNFOCUS);
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_SCALE", (long)REMMINA_PROTOCOL_FEATURE_TYPE_SCALE);
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_DYNRESUPDATE", (long)REMMINA_PROTOCOL_FEATURE_TYPE_DYNRESUPDATE);
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_GTKSOCKET", (long)REMMINA_PROTOCOL_FEATURE_TYPE_GTKSOCKET);
-
- PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_NONE", (long)REMMINA_PROTOCOL_SSH_SETTING_NONE);
- PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_TUNNEL", (long)REMMINA_PROTOCOL_SSH_SETTING_TUNNEL);
- PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_SSH", (long)REMMINA_PROTOCOL_SSH_SETTING_SSH);
- PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_REVERSE_TUNNEL", (long)REMMINA_PROTOCOL_SSH_SETTING_REVERSE_TUNNEL);
- PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_SFTP", (long)REMMINA_PROTOCOL_SSH_SETTING_SFTP);
-
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_PREF_RADIO", (long)REMMINA_PROTOCOL_FEATURE_PREF_RADIO);
- PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_PREF_CHECK", (long)REMMINA_PROTOCOL_FEATURE_PREF_CHECK);
-
- PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_USERNAME", REMMINA_MESSAGE_PANEL_FLAG_USERNAME);
- PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_USERNAME_READONLY", REMMINA_MESSAGE_PANEL_FLAG_USERNAME_READONLY);
- PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_DOMAIN", REMMINA_MESSAGE_PANEL_FLAG_DOMAIN);
- PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_SAVEPASSWORD", REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD);
-
- if (PyModule_AddObject(module, "Setting", (PyObject*)&python_protocol_setting_type) < 0)
- {
- Py_DECREF(&python_protocol_setting_type);
- Py_DECREF(module);
- PyErr_Print();
- return NULL;
- }
-
- Py_INCREF(&python_protocol_feature_type);
- if (PyModule_AddObject(module, "Feature", (PyObject*)&python_protocol_feature_type) < 0)
- {
- Py_DECREF(&python_protocol_setting_type);
- Py_DECREF(&python_protocol_feature_type);
- Py_DECREF(module);
- PyErr_Print();
- return NULL;
- }
-
- return module;
-}
-
-/**
- * Initializes all globals and registers the 'remmina' module in the Python engine.
- * @details This
- */
-void remmina_plugin_python_module_init(void)
-{
- TRACE_CALL(__func__);
-
- if (PyImport_AppendInittab("remmina", remmina_plugin_python_module_initialize))
- {
- PyErr_Print();
- exit(1);
- }
-
- remmina_plugin_python_entry_init();
- remmina_plugin_python_protocol_init();
- remmina_plugin_python_tool_init();
- remmina_plugin_python_pref_init();
- remmina_plugin_python_secret_init();
- remmina_plugin_python_file_init();
-}
-
-gboolean remmina_plugin_python_check_mandatory_member(PyObject* instance, const gchar* member)
-{
- TRACE_CALL(__func__);
-
- if (PyObject_HasAttrString(instance, member))
- {
- return TRUE;
- }
-
- g_printerr("Missing mandatory member '%s' in Python plugin instance!\n", member);
- return FALSE;
-}
-
-static PyObject* remmina_register_plugin_wrapper(PyObject* self, PyObject* plugin_instance)
-{
- TRACE_CALL(__func__);
-
- if (plugin_instance)
- {
- if (!remmina_plugin_python_check_mandatory_member(plugin_instance, "name")
- || !remmina_plugin_python_check_mandatory_member(plugin_instance, "version"))
- {
- return NULL;
- }
-
- /* Protocol plugin definition and features */
- const gchar* pluginType = PyUnicode_AsUTF8(PyObject_GetAttrString(plugin_instance, "type"));
-
- RemminaPlugin* remmina_plugin = NULL;
-
- PyPlugin* plugin = (PyPlugin*)remmina_plugin_python_malloc(sizeof(PyPlugin));
- plugin->instance = plugin_instance;
- Py_INCREF(plugin_instance);
- plugin->protocol_plugin = NULL;
- plugin->entry_plugin = NULL;
- plugin->file_plugin = NULL;
- plugin->pref_plugin = NULL;
- plugin->secret_plugin = NULL;
- plugin->tool_plugin = NULL;
- g_print("New Python plugin registered: %ld\n", PyObject_Hash(plugin_instance));
-
- if (g_str_equal(pluginType, "protocol"))
- {
- remmina_plugin = remmina_plugin_python_create_protocol_plugin(plugin);
- }
- else if (g_str_equal(pluginType, "entry"))
- {
- remmina_plugin = remmina_plugin_python_create_entry_plugin(plugin);
- }
- else if (g_str_equal(pluginType, "file"))
- {
- remmina_plugin = remmina_plugin_python_create_file_plugin(plugin);
- }
- else if (g_str_equal(pluginType, "tool"))
- {
- remmina_plugin = remmina_plugin_python_create_tool_plugin(plugin);
- }
- else if (g_str_equal(pluginType, "pref"))
- {
- remmina_plugin = remmina_plugin_python_create_pref_plugin(plugin);
- }
- else if (g_str_equal(pluginType, "secret"))
- {
- remmina_plugin = remmina_plugin_python_create_secret_plugin(plugin);
- }
- else
- {
- g_printerr("Unknown plugin type: %s\n", pluginType);
- }
-
- if (remmina_plugin)
- {
- if (remmina_plugin->type == REMMINA_PLUGIN_TYPE_PROTOCOL)
- {
- plugin->gp = remmina_plugin_python_protocol_widget_create();
- }
-
- remmina_plugin_manager_service.register_plugin((RemminaPlugin*)remmina_plugin);
- }
- }
-
- return Py_None;
-}
-
-static PyObject* remmina_file_get_datadir_wrapper(PyObject* self, PyObject* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = Py_None;
- const gchar* datadir = remmina_file_get_datadir();
-
- if (datadir)
- {
- result = PyUnicode_FromFormat("%s", datadir);
- }
-
- remmina_plugin_python_check_error();
- return result;
-}
-
-static PyObject* remmina_file_new_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- RemminaFile* file = remmina_file_new();
- if (file)
- {
- return (PyObject*)remmina_plugin_python_remmina_file_to_python(file);
- }
-
- remmina_plugin_python_check_error();
- return Py_None;
-}
-
-static PyObject* remmina_pref_set_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "key", "value", NULL };
- gchar* key, * value;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &key, &value))
- {
- return Py_None;
- }
-
- if (key)
- {
- remmina_pref_set_value(key, value);
- }
-
- remmina_plugin_python_check_error();
- return Py_None;
-}
-
-static PyObject* remmina_pref_get_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "key", NULL };
- gchar* key;
- PyObject* result = Py_None;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &key))
- {
- return Py_None;
- }
-
- if (key)
- {
- const gchar* value = remmina_pref_get_value(key);
- if (value)
- {
- result = PyUnicode_FromFormat("%s", result);
- }
- }
-
- remmina_plugin_python_check_error();
- return result;
-}
-
-static PyObject* remmina_pref_get_scale_quality_wrapper(PyObject* self, PyObject* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = PyLong_FromLong(remmina_pref_get_scale_quality());
- remmina_plugin_python_check_error();
- return result;
-}
-
-static PyObject* remmina_pref_get_sshtunnel_port_wrapper(PyObject* self, PyObject* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = PyLong_FromLong(remmina_pref_get_sshtunnel_port());
- remmina_plugin_python_check_error();
- return result;
-}
-
-static PyObject* remmina_pref_get_ssh_loglevel_wrapper(PyObject* self, PyObject* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = PyLong_FromLong(remmina_pref_get_ssh_loglevel());
- remmina_plugin_python_check_error();
- return result;
-}
-
-static PyObject* remmina_pref_get_ssh_parseconfig_wrapper(PyObject* self, PyObject* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* result = PyLong_FromLong(remmina_pref_get_ssh_parseconfig());
- remmina_plugin_python_check_error();
- return result;
-}
-
-static PyObject* remmina_pref_keymap_get_keyval_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "keymap", "keyval", NULL };
- gchar* keymap;
- guint keyval;
- PyObject* result = Py_None;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sl", kwlist, &keymap, &keyval))
- {
- return PyLong_FromLong(-1);
- }
-
- if (keymap)
- {
- const guint value = remmina_pref_keymap_get_keyval(keymap, keyval);
- result = PyLong_FromUnsignedLong(value);
- }
-
- remmina_plugin_python_check_error();
- return result;
-}
-
-static PyObject* remmina_plugin_python_log_print_wrapper(PyObject* self, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- gchar* text;
- if (!PyArg_ParseTuple(args, "s", &text) || !text)
- {
- return Py_None;
- }
-
- remmina_log_print(text);
- return Py_None;
-}
-
-static PyObject* remmina_plugin_python_debug_wrapper(PyObject* self, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- gchar* text;
- if (!PyArg_ParseTuple(args, "s", &text) || !text)
- {
- return Py_None;
- }
-
- remmina_plugin_manager_service._remmina_debug("python", "%s", text);
- return Py_None;
-}
-
-static PyObject* remmina_widget_pool_register_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "widget", NULL };
- PyObject* widget;
-
- if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &widget) && widget)
- {
- remmina_widget_pool_register(get_pywidget(widget));
- }
-
- return Py_None;
-}
-
-static PyObject* rcw_open_from_file_full_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "remminafile", "data", "handler", NULL };
- PyObject* pyremminafile;
- PyObject* data;
-
- if (PyArg_ParseTupleAndKeywords(args, kwargs, "OOO", kwlist, &pyremminafile, &data) && pyremminafile && data)
- {
- rcw_open_from_file_full((RemminaFile*)pyremminafile, NULL, (void*)data, NULL);
- }
-
- return Py_None;
-}
-
-static PyObject* remmina_public_get_server_port_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "server", "defaultport", "host", "port", NULL };
- gchar* server;
- gint defaultport;
-
- if (PyArg_ParseTupleAndKeywords(args, kwargs, "slsl", kwlist, &server, &defaultport) && server)
- {
- gchar* host;
- gint port;
- remmina_public_get_server_port(server, defaultport, &host, &port);
-
- PyObject* result = PyList_New(2);
- PyList_Append(result, PyUnicode_FromString(host));
- PyList_Append(result, PyLong_FromLong(port));
- return PyList_AsTuple(result);
- }
-
- return Py_None;
-}
-
-static PyObject* remmina_masterthread_exec_is_main_thread_wrapper(PyObject* self, PyObject* plugin)
-{
- TRACE_CALL(__func__);
-
- return PyBool_FromLong(remmina_masterthread_exec_is_main_thread());
-}
-
-static PyObject* remmina_gtksocket_available_wrapper(PyObject* self, PyObject* plugin)
-{
- TRACE_CALL(__func__);
-
- return PyBool_FromLong(remmina_gtksocket_available());
-}
-
-static PyObject*
-remmina_protocol_widget_get_profile_remote_height_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "widget", NULL };
- PyPlugin* plugin;
-
- if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &plugin) && plugin && plugin->gp)
- {
- remmina_protocol_widget_get_profile_remote_height(plugin->gp->gp);
- }
-
- return Py_None;
-}
-
-static PyObject*
-remmina_protocol_widget_get_profile_remote_width_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "widget", NULL };
- PyPlugin* plugin;
-
- if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &plugin) && plugin && plugin->gp)
- {
- remmina_protocol_widget_get_profile_remote_width(plugin->gp->gp);
- }
-
- return Py_None;
-}
-
-void remmina_plugin_python_to_protocol_setting(RemminaProtocolSetting* dest, PyObject* setting)
-{
- TRACE_CALL(__func__);
-
- PyRemminaProtocolSetting* src = (PyRemminaProtocolSetting*)setting;
- Py_INCREF(setting);
- dest->name = src->name;
- dest->label = src->label;
- dest->compact = src->compact;
- dest->type = src->settingType;
- dest->validator = NULL;
- dest->validator_data = NULL;
- remmina_plugin_python_to_generic(src->opt1, &dest->opt1);
- remmina_plugin_python_to_generic(src->opt2, &dest->opt2);
-}
-
-void remmina_plugin_python_to_protocol_feature(RemminaProtocolFeature* dest, PyObject* feature)
-{
- TRACE_CALL(__func__);
-
- PyRemminaProtocolFeature* src = (PyRemminaProtocolFeature*)feature;
- Py_INCREF(feature);
- dest->id = src->id;
- dest->type = src->type;
- dest->opt1 = src->opt1->raw;
- dest->opt1_type_hint = src->opt1->type_hint;
- dest->opt2 = src->opt2->raw;
- dest->opt2_type_hint = src->opt2->type_hint;
- dest->opt3 = src->opt3->raw;
- dest->opt3_type_hint = src->opt3->type_hint;
-}
-
-PyObject* remmina_plugin_python_show_dialog_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- TRACE_CALL(__func__);
-
- static char* kwlist[] = { "type", "buttons", "message", NULL };
- GtkMessageType msgType;
- GtkButtonsType btnType;
- gchar* message;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "lls", kwlist, &msgType, &btnType, &message))
- {
- return PyLong_FromLong(-1);
- }
-
- remmina_main_show_dialog(msgType, btnType, message);
-
- return Py_None;
-}
-
-PyObject* remmina_plugin_python_get_mainwindow_wrapper(PyObject* self, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- GtkWindow* result = remmina_main_get_window();
-
- if (!result)
- {
- return Py_None;
- }
-
- return (PyObject*)new_pywidget((GObject*)result);
-}
-
-static PyObject* remmina_protocol_plugin_signal_connection_closed_wrapper(PyObject* self, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- PyObject* pygp = NULL;
- if (!PyArg_ParseTuple(args, "O", &pygp) || !pygp)
- {
- g_printerr("Please provide the Remmina protocol widget instance!");
- return Py_None;
- }
-
- remmina_plugin_manager_service.protocol_plugin_signal_connection_closed(((PyRemminaProtocolWidget*)pygp)->gp);
- return Py_None;
-}
-
-static PyObject* remmina_protocol_plugin_init_auth_wrapper(PyObject* module, PyObject* args, PyObject* kwds)
-{
- TRACE_CALL(__func__);
-
- static gchar* keyword_list[] = { "widget", "flags", "title", "default_username", "default_password",
- "default_domain", "password_prompt" };
-
- PyRemminaProtocolWidget* self;
- gint pflags = 0;
- gchar* title, * default_username, * default_password, * default_domain, * password_prompt;
-
- if (PyArg_ParseTupleAndKeywords(args, kwds, "Oisssss", keyword_list, &self, &pflags, &title, &default_username,
- &default_password, &default_domain, &password_prompt))
- {
- if (pflags != 0 && !(pflags & REMMINA_MESSAGE_PANEL_FLAG_USERNAME)
- && !(pflags & REMMINA_MESSAGE_PANEL_FLAG_USERNAME_READONLY)
- && !(pflags & REMMINA_MESSAGE_PANEL_FLAG_DOMAIN)
- && !(pflags & REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD))
- {
- g_printerr("panel_auth(pflags, title, default_username, default_password, default_domain, password_prompt): "
- "%d is not a known value for RemminaMessagePanelFlags!\n", pflags);
- }
- else
- {
- return Py_BuildValue("i", remmina_protocol_widget_panel_auth(self
- ->gp, pflags, title, default_username, default_password, default_domain, password_prompt));
- }
- }
- else
- {
- g_printerr("panel_auth(pflags, title, default_username, default_password, default_domain, password_prompt): Error parsing arguments!\n");
- PyErr_Print();
- }
- return Py_None;
-}
-
-static PyObject* remmina_protocol_plugin_signal_connection_opened_wrapper(PyObject* self, PyObject* args)
-{
- PyObject* pygp = NULL;
- if (!PyArg_ParseTuple(args, "O", &pygp) || !pygp)
- {
- g_printerr("Please provide the Remmina protocol widget instance!");
- return Py_None;
- }
-
- remmina_plugin_manager_service.protocol_plugin_signal_connection_opened(((PyRemminaProtocolWidget*)pygp)->gp);
- return Py_None;
-}
diff --git a/src/remmina_plugin_python_remmina.h b/src/remmina_plugin_python_remmina.h
deleted file mode 100644
index 25869d58a..000000000
--- a/src/remmina_plugin_python_remmina.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2022 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.
- */
-
-/**
- * @file remmina_plugin_python_remmina.h
- *
- * @brief Contains the implementation of the Python module 'remmina', provided to interface with the application from
- * the Python plugin source.
- *
- * @detail In contrast to the wrapper functions that exist in the plugin specialisation files (e.g.
- * remmina_plugin_python_protocol.c or remmina_plugin_python_entry.c), this file contains the API for the
- * communication in the direction, from Python to Remmina. This means, if in the Python plugin a function
- * is called, that is defined in Remmina, C code, at least in this file, is executed.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_protocol_widget.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-/**
- * Initializes the 'remmina' module in the Python engine.
- */
-void remmina_plugin_python_module_init(void);
-
-/**
- * @brief Returns a pointer to the Python instance, mapped to the RemminaProtocolWidget or null if not found.
- *
- * @param gp The widget that is owned by the plugin that should be found.
- *
- * @details Remmina expects this callback function to be part of one plugin, which is the reason no instance information
- * is explicitly passed. To bridge that, this function can be used to retrieve the very plugin instance owning
- * the given RemminaProtocolWidget.
- */
-PyPlugin* remmina_plugin_python_module_get_plugin(RemminaProtocolWidget* gp);
-
-/**
- * @brief Converts the PyObject to RemminaProtocolSetting.
- *
- * @param dest A target for the converted value.
- * @param setting The source value to convert.
- */
-void remmina_plugin_python_to_protocol_setting(RemminaProtocolSetting* dest, PyObject* setting);
-
-/**
- * @brief Converts the PyObject to RemminaProtocolFeature.
- *
- * @param dest A target for the converted value.
- * @param setting The source value to convert.
- */
-void remmina_plugin_python_to_protocol_feature(RemminaProtocolFeature* dest, PyObject* feature);
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_remmina_file.c b/src/remmina_plugin_python_remmina_file.c
deleted file mode 100644
index 1c417129a..000000000
--- a/src/remmina_plugin_python_remmina_file.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2016-2022 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.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N C L U D E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina/remmina_trace_calls.h"
-#include "remmina_file.h"
-#include "remmina_plugin_python_common.h"
-#include "remmina_plugin_python_remmina_file.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// D E C L A R A T I O N S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-static PyObject* file_get_path(PyRemminaFile* self, PyObject* args);
-static PyObject* file_set_setting(PyRemminaFile* self, PyObject* args, PyObject* kwds);
-static PyObject* file_get_setting(PyRemminaFile* self, PyObject* args, PyObject* kwds);
-static PyObject* file_get_secret(PyRemminaFile* self, PyObject* setting);
-static PyObject* file_unsave_passwords(PyRemminaFile* self, PyObject* args);
-
-static void file_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-static PyMethodDef python_remmina_file_type_methods[] = {
- { "get_path", (PyCFunction)file_get_path, METH_NOARGS, "" },
- { "set_setting", (PyCFunction)file_set_setting, METH_VARARGS | METH_KEYWORDS, "Set file setting" },
- { "get_setting", (PyCFunction)file_get_setting, METH_VARARGS | METH_KEYWORDS, "Get file setting" },
- { "get_secret", (PyCFunction)file_get_secret, METH_VARARGS, "Get secret file setting" },
- { "unsave_passwords", (PyCFunction)file_unsave_passwords, METH_NOARGS, "" },
- { NULL }
-};
-
-/**
- * @brief The definition of the Python module 'remmina'.
- */
-static PyTypeObject python_remmina_file_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "remmina.RemminaFile",
- .tp_doc = "",
- .tp_basicsize = sizeof(PyRemminaFile),
- .tp_itemsize = 0,
- .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_methods = python_remmina_file_type_methods,
- .tp_dealloc = file_dealloc
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void remmina_plugin_python_remmina_init_types(void)
-{
- PyType_Ready(&python_remmina_file_type);
-}
-
-PyRemminaFile* remmina_plugin_python_remmina_file_to_python(RemminaFile* file)
-{
- TRACE_CALL(__func__);
-
- PyRemminaFile* result = PyObject_New(PyRemminaFile, &python_remmina_file_type);
- result->file = file;
- Py_INCREF(result);
- return result;
-}
-
-static PyObject* file_get_path(PyRemminaFile* self, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- return Py_BuildValue("s", remmina_file_get_filename(self->file));
-}
-
-static PyObject* file_set_setting(PyRemminaFile* self, PyObject* args, PyObject* kwds)
-{
- TRACE_CALL(__func__);
-
- static char* keyword_list[] = { "key", "value", NULL };
- gchar* key;
- PyObject* value;
-
- if (PyArg_ParseTupleAndKeywords(args, kwds, "s|O", keyword_list, &key, &value))
- {
- if (PyUnicode_Check(value))
- {
- remmina_file_set_string(self->file, key, PyUnicode_AsUTF8(value));
- }
- else if (PyLong_Check(value))
- {
- remmina_file_set_int(self->file, key, PyLong_AsLong(value));
- }
- else
- {
- g_printerr("%s: Not a string or int value\n", PyUnicode_AsUTF8(PyObject_Str(value)));
- }
- return Py_None;
- }
- else
- {
- g_printerr("file.set_setting(key, value): Error parsing arguments!\n");
- PyErr_Print();
- return NULL;
- }
-}
-
-static PyObject* file_get_setting(PyRemminaFile* self, PyObject* args, PyObject* kwds)
-{
- TRACE_CALL(__func__);
-
- static gchar* keyword_list[] = { "key", "default" };
- gchar* key;
- PyObject* def;
-
- if (PyArg_ParseTupleAndKeywords(args, kwds, "sO", keyword_list, &key, &def))
- {
- if (PyUnicode_Check(def))
- {
- return Py_BuildValue("s", remmina_file_get_string(self->file, key));
- }
- else if (PyBool_Check(def))
- {
- return remmina_file_get_int(self->file, key, (gint)PyLong_AsLong(def)) ? Py_True : Py_False;
- }
- else if (PyLong_Check(def))
- {
- return Py_BuildValue("i", remmina_file_get_int(self->file, key, (gint)PyLong_AsLong(def)));
- }
- else
- {
- g_printerr("%s: Not a string or int value\n", PyUnicode_AsUTF8(PyObject_Str(def)));
- }
- return def;
- }
- else
- {
- g_printerr("file.get_setting(key, default): Error parsing arguments!\n");
- PyErr_Print();
- return Py_None;
- }
-}
-
-static PyObject* file_get_secret(PyRemminaFile* self, PyObject* key)
-{
- TRACE_CALL(__func__);
-
- if (key && PyUnicode_Check(key))
- {
- return Py_BuildValue("s", remmina_file_get_secret(self->file, PyUnicode_AsUTF8(key)));
- }
- else
- {
- g_printerr("file.get_secret(key): Error parsing arguments!\n");
- PyErr_Print();
- return NULL;
- }
-}
-
-static PyObject* file_unsave_passwords(PyRemminaFile* self, PyObject* args)
-{
- TRACE_CALL(__func__);
-
- if (self)
- {
- remmina_file_unsave_passwords(self->file);
- return Py_None;
- }
- else
- {
- g_printerr("unsave_passwords(): self is null!\n");
- return NULL;
- }
-}
diff --git a/src/remmina_plugin_python_remmina_file.h b/src/remmina_plugin_python_remmina_file.h
deleted file mode 100644
index a2e7a53d3..000000000
--- a/src/remmina_plugin_python_remmina_file.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2016-2022 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.
- */
-
-
-/**
- * @file remmina_plugin_python_protocol.h
- *
- * @brief Contains the implementation of the Python type remmina.RemminaFile.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Wrapper for a Python object that contains a pointer to an instance of RemminaFile.
- */
-typedef struct
-{
- PyObject_HEAD
- RemminaFile* file;
-} PyRemminaFile;
-
-void remmina_plugin_python_remmina_init_types(void);
-
-/**
- * Converts the instance of RemminaFile to a Python object that can be passed to the Python engine.
- */
-PyRemminaFile* remmina_plugin_python_remmina_file_to_python(RemminaFile* file);
diff --git a/src/remmina_plugin_python_secret.c b/src/remmina_plugin_python_secret.c
deleted file mode 100644
index be659fdbb..000000000
--- a/src/remmina_plugin_python_secret.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N L U C E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-#include "remmina_plugin_python_secret.h"
-#include "remmina_plugin_python_remmina_file.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void remmina_plugin_python_secret_init(void)
-{
- TRACE_CALL(__func__);
-}
-
-gboolean remmina_plugin_python_secret_init_wrapper(RemminaSecretPlugin* instance)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- PyObject* result = CallPythonMethod(plugin->instance, "init", NULL);
- return result == Py_None || result != Py_False;
-}
-
-gboolean remmina_plugin_python_secret_is_service_available_wrapper(RemminaSecretPlugin* instance)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- PyObject* result = CallPythonMethod(plugin->instance, "is_service_available", NULL);
- return result == Py_None || result != Py_False;
-}
-
-void
-remmina_plugin_python_secret_store_password_wrapper(RemminaSecretPlugin* instance, RemminaFile* file, const gchar* key, const gchar* password)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- CallPythonMethod(plugin
- ->instance, "store_password", "Oss", (PyObject*)remmina_plugin_python_remmina_file_to_python(file), key, password);
-}
-
-gchar*
-remmina_plugin_python_secret_get_password_wrapper(RemminaSecretPlugin* instance, RemminaFile* file, const gchar* key)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- PyObject* result = CallPythonMethod(plugin
- ->instance, "get_password", "Os", (PyObject*)remmina_plugin_python_remmina_file_to_python(file), key);
- Py_ssize_t len = PyUnicode_GetLength(result);
- if (len == 0)
- {
- return NULL;
- }
-
- return remmina_plugin_python_copy_string_from_python(result, len);
-}
-
-void
-remmina_plugin_python_secret_delete_password_wrapper(RemminaSecretPlugin* instance, RemminaFile* file, const gchar* key)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- CallPythonMethod(plugin
- ->instance, "delete_password", "Os", (PyObject*)remmina_plugin_python_remmina_file_to_python(file), key);
-}
-
-RemminaPlugin* remmina_plugin_python_create_secret_plugin(PyPlugin* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* instance = plugin->instance;
-
- if (!remmina_plugin_python_check_attribute(instance, ATTR_NAME))
- {
- return NULL;
- }
-
- RemminaSecretPlugin* remmina_plugin = (RemminaSecretPlugin*)remmina_plugin_python_malloc(sizeof(RemminaSecretPlugin));
-
- remmina_plugin->type = REMMINA_PLUGIN_TYPE_SECRET;
- remmina_plugin->domain = GETTEXT_PACKAGE;
- remmina_plugin->name = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_NAME));
- remmina_plugin->version = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_VERSION));
- remmina_plugin->description = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_DESCRIPTION));
- remmina_plugin->init_order = PyLong_AsLong(PyObject_GetAttrString(instance, ATTR_INIT_ORDER));
-
- remmina_plugin->init = remmina_plugin_python_secret_init_wrapper;
- remmina_plugin->is_service_available = remmina_plugin_python_secret_is_service_available_wrapper;
- remmina_plugin->store_password = remmina_plugin_python_secret_store_password_wrapper;
- remmina_plugin->get_password = remmina_plugin_python_secret_get_password_wrapper;
- remmina_plugin->delete_password = remmina_plugin_python_secret_delete_password_wrapper;
-
- plugin->secret_plugin = remmina_plugin;
- plugin->generic_plugin = (RemminaPlugin*)remmina_plugin;
-
- remmina_plugin_python_add_plugin(plugin);
-
- return (RemminaPlugin*)remmina_plugin;
-} \ No newline at end of file
diff --git a/src/remmina_plugin_python_secret.h b/src/remmina_plugin_python_secret.h
deleted file mode 100644
index c627d2a49..000000000
--- a/src/remmina_plugin_python_secret.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_entry.h
- *
- * @brief Contains the specialisation of RemminaPluginEntry plugins in Python.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N L U C E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina/plugin.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-/**
- * Initializes the Python plugin specialisation for secret plugins.
- */
-void remmina_plugin_python_secret_init(void);
-
-/**
- * @brief Creates a new instance of the RemminaPluginSecret, initializes its members and references the wrapper
- * functions.
- * @param instance The instance of the Python plugin.
- * @return Returns a new instance of the RemminaPlugin (must be freed!).
- */
-RemminaPlugin* remmina_plugin_python_create_secret_plugin(PyPlugin* instance);
-
-G_END_DECLS
diff --git a/src/remmina_plugin_python_tool.c b/src/remmina_plugin_python_tool.c
deleted file mode 100644
index a951291f2..000000000
--- a/src/remmina_plugin_python_tool.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N L U C E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina_plugin_python_common.h"
-#include "remmina_plugin_python_tool.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void remmina_plugin_python_tool_init(void)
-{
- TRACE_CALL(__func__);
-}
-
-void remmina_plugin_python_tool_exec_func_wrapper(GtkMenuItem* self, RemminaToolPlugin* instance)
-{
- TRACE_CALL(__func__);
-
- PyPlugin* plugin = remmina_plugin_python_get_plugin(instance->name);
- CallPythonMethod(plugin->instance, "exec_func", NULL);
-}
-
-RemminaPlugin* remmina_plugin_python_create_tool_plugin(PyPlugin* plugin)
-{
- TRACE_CALL(__func__);
-
- PyObject* instance = plugin->instance;
-
- if (!remmina_plugin_python_check_attribute(instance, ATTR_NAME))
- {
- return NULL;
- }
-
- RemminaToolPlugin* remmina_plugin = (RemminaToolPlugin*)remmina_plugin_python_malloc(sizeof(RemminaToolPlugin));
-
- remmina_plugin->type = REMMINA_PLUGIN_TYPE_TOOL;
- remmina_plugin->domain = GETTEXT_PACKAGE;
- remmina_plugin->name = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_NAME));
- remmina_plugin->version = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_VERSION));
- remmina_plugin->description = PyUnicode_AsUTF8(PyObject_GetAttrString(instance, ATTR_DESCRIPTION));
- remmina_plugin->exec_func = remmina_plugin_python_tool_exec_func_wrapper;
-
- plugin->tool_plugin = remmina_plugin;
- plugin->generic_plugin = (RemminaPlugin*)remmina_plugin;
-
- remmina_plugin_python_add_plugin(plugin);
-
- return (RemminaPlugin*)remmina_plugin;
-}
diff --git a/src/remmina_plugin_python_tool.h b/src/remmina_plugin_python_tool.h
deleted file mode 100644
index 08852bdc4..000000000
--- a/src/remmina_plugin_python_tool.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Remmina - The GTK+ Remote Desktop Client
- * Copyright (C) 2014-2021 Antenore Gatta, Giovanni Panozzo, Mathias Winterhalter (ToolsDevler)
- *
- * 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.
- */
-
-/**
- * @file remmina_plugin_python_entry.h
- *
- * @brief Contains the specialisation of RemminaPluginEntry plugins in Python.
- */
-
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// I N L U C E S
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "remmina/plugin.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// A P I
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-G_BEGIN_DECLS
-
-/**
- * Initializes the Python plugin specialisation for tool plugins.
- */
-void remmina_plugin_python_tool_init(void);
-
-/**
- * @brief Creates a new instance of the RemminaPluginTool, initializes its members and references the wrapper
- * functions.
- * @param instance The instance of the Python plugin.
- * @return Returns a new instance of the RemminaPlugin (must be freed!).
- */
-RemminaPlugin* remmina_plugin_python_create_tool_plugin(PyPlugin* instance);
-
-G_END_DECLS
-
diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c
index 9703d4cc5..5db892820 100644
--- a/src/remmina_protocol_widget.c
+++ b/src/remmina_protocol_widget.c
@@ -1372,6 +1372,11 @@ gint remmina_protocol_widget_get_profile_remote_height(RemminaProtocolWidget *gp
return gp->priv->profile_remote_height;
}
+const gchar* remmina_protocol_widget_get_name(RemminaProtocolWidget *gp)
+{
+ TRACE_CALL(__func__);
+ return gp ? gp->plugin ? gp->plugin->name : NULL : NULL;
+}
gint remmina_protocol_widget_get_width(RemminaProtocolWidget *gp)
{
diff --git a/src/remmina_protocol_widget.h b/src/remmina_protocol_widget.h
index e1a8f9987..c356df9c5 100644
--- a/src/remmina_protocol_widget.h
+++ b/src/remmina_protocol_widget.h
@@ -82,6 +82,7 @@ GtkWidget* remmina_protocol_widget_gtkviewport(RemminaProtocolWidget *gp);
GtkWidget *remmina_protocol_widget_new(void);
void remmina_protocol_widget_setup(RemminaProtocolWidget *gp, RemminaFile *remminafile, RemminaConnectionObject *cnnobj);
+const gchar* remmina_protocol_widget_get_name(RemminaProtocolWidget *gp);
gint remmina_protocol_widget_get_width(RemminaProtocolWidget *gp);
void remmina_protocol_widget_set_width(RemminaProtocolWidget *gp, gint width);
gint remmina_protocol_widget_get_height(RemminaProtocolWidget *gp);