diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 17:06:32 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 17:06:32 +0000 |
commit | 2dad5357405ad33cfa792f04b3ab62a5d188841e (patch) | |
tree | b8f8893942060fe3cfb04ac374cda96fdfc8f453 /plugins/python_wrapper/python_wrapper_common.h | |
parent | Initial commit. (diff) | |
download | remmina-2dad5357405ad33cfa792f04b3ab62a5d188841e.tar.xz remmina-2dad5357405ad33cfa792f04b3ab62a5d188841e.zip |
Adding upstream version 1.4.34+dfsg.upstream/1.4.34+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/python_wrapper/python_wrapper_common.h')
-rw-r--r-- | plugins/python_wrapper/python_wrapper_common.h | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/plugins/python_wrapper/python_wrapper_common.h b/plugins/python_wrapper/python_wrapper_common.h new file mode 100644 index 0000000..8c7a167 --- /dev/null +++ b/plugins/python_wrapper/python_wrapper_common.h @@ -0,0 +1,295 @@ +/* + * Remmina - The GTK+ Remote Desktop Client + * Copyright (C) 2014-2023 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 python_wrapper_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 "common/remmina_plugin.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, ...) \ + python_wrapper_last_result_set(PyObject_CallMethod(instance, name, params, ##__VA_ARGS__)); \ + python_wrapper_log_method_call(instance, name); \ + python_wrapper_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__); \ + python_wrapper_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* python_wrapper_generic_new(void); + +/** + * Registers the given plugin if no other plugin with the same name has been already registered. + */ +void python_wrapper_add_plugin(PyPlugin* plugin); + +/** + * Sets the pointer to the plugin service of Remmina. + */ +void python_wrapper_set_service(RemminaPluginService* service); + +/** + * Gets the pointer to the plugin service of Remmina. + */ +RemminaPluginService* python_wrapper_get_service(void); + +/** + * Extracts data from a PyObject instance to a generic pointer and returns a type hint if it could be determined. + */ +RemminaTypeHint python_wrapper_to_generic(PyObject* field, gpointer* target); + +/** + * Gets the result of the last python method call. + */ +PyObject* python_wrapper_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* python_wrapper_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 python_wrapper_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 python_wrapper_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 python_wrapper_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 python_wrapper_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* python_wrapper_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* python_wrapper_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* 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 + * @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 |