diff options
author | ToolsDevler <info@toolsdevler.net> | 2020-08-30 21:57:40 +0300 |
---|---|---|
committer | ToolsDevler <info@toolsdevler.net> | 2020-12-31 03:03:24 +0300 |
commit | 3b9043d6ed81d3afb451f2c07377e5741a6c0340 (patch) | |
tree | 6f0063a14d182fcd6fae7f1c8220221eb91f5ce0 | |
parent | 5ca2d4ac2aec8b6ce216444c0b0d91fce4c9cf5c (diff) |
WIP: Re-develop tool_hello_plugin in python
-rw-r--r-- | plugins/tool_hello_world_python/toolsdevler.py | 49 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/include/remmina/types.h | 2 | ||||
-rw-r--r-- | src/remmina_plugin_manager.c | 3 | ||||
-rw-r--r-- | src/remmina_plugin_python.c | 35 | ||||
-rw-r--r-- | src/remmina_plugin_python.h | 2 | ||||
-rw-r--r-- | src/remmina_plugin_python_module.c | 59 | ||||
-rw-r--r-- | src/remmina_plugin_python_plugin.c | 179 | ||||
-rw-r--r-- | src/remmina_plugin_python_plugin.h | 2 |
9 files changed, 306 insertions, 27 deletions
diff --git a/plugins/tool_hello_world_python/toolsdevler.py b/plugins/tool_hello_world_python/toolsdevler.py new file mode 100644 index 000000000..d1f3c1041 --- /dev/null +++ b/plugins/tool_hello_world_python/toolsdevler.py @@ -0,0 +1,49 @@ +import sys + +if not hasattr(sys, 'argv'): + sys.argv = [''] + +import remmina + +class HelloPlugin(remmina.Plugin): + def __init__(self): + self.type = remmina.PLUGIN_TYPE_PROTOCOL + self.name = "Hello" + self.description = "Just a Plugin saying hello :)" + self.version = "1.0" + self.appicon = "" + self.service = None + self.protocol_setting = None + + def init(self, service): + self.service = service + service.log_printf("[%s]: Plugin init\n" % self.name) + + def open_connection(self): + service.log_printf("[%s]: Plugin open connection\n" % self.name) + + + def close_connection(self): + service.log_printf("[%s]: Plugin close connection\n" % self.name) + + def query_feature(self): + pass + + def call_feature(self): + pass + + def send_keystrokes(self): + pass + + def get_plugin_screenshot(self): + pass + +print("import gi") +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk + +window = Gtk.Window(title="Hello World") +window.show() +window.connect("destroy", Gtk.main_quit) +Gtk.main() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 44d271912..26bb83846 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,6 +81,8 @@ list(APPEND REMMINA_SRCS "remmina_plugin_native.h" "remmina_plugin_python.c" "remmina_plugin_python.h" + "remmina_plugin_python_plugin.c" + "remmina_plugin_python_plugin.h" "remmina_plugin_python_module.c" "remmina_plugin_python_module.h" "remmina_ext_exec.c" diff --git a/src/include/remmina/types.h b/src/include/remmina/types.h index db5f8bfab..13ae7f9f9 100644 --- a/src/include/remmina/types.h +++ b/src/include/remmina/types.h @@ -36,6 +36,8 @@ #pragma once +#include <glib.h> + G_BEGIN_DECLS typedef struct _RemminaFile RemminaFile; diff --git a/src/remmina_plugin_manager.c b/src/remmina_plugin_manager.c index 63ab2f2db..1f3731ec9 100644 --- a/src/remmina_plugin_manager.c +++ b/src/remmina_plugin_manager.c @@ -304,7 +304,8 @@ void remmina_plugin_manager_init() GSList *sple; remmina_plugin_table = g_ptr_array_new(); - + remmina_plugin_python_init(); + if (!g_module_supported()) { g_print("Dynamic loading of plugins is not supported on this platform!\n"); return; diff --git a/src/remmina_plugin_python.c b/src/remmina_plugin_python.c index 874ec8807..d2db79696 100644 --- a/src/remmina_plugin_python.c +++ b/src/remmina_plugin_python.c @@ -2,7 +2,6 @@ #include <gtk/gtk.h> -#include "remmina_plugin_python.h" #include "remmina/remmina_trace_calls.h" @@ -10,18 +9,42 @@ #include <Python.h> #include "structmember.h" +#include "remmina_plugin_python.h" #include "remmina_plugin_python_module.h" +#include "remmina_plugin_python_plugin.h" -gboolean -remmina_plugin_python_load(RemminaPluginService* service, const char* name) { +void remmina_plugin_python_init(void) { TRACE_CALL(__FUNC__); - // Initialize Python environment + PyTypeObject* plugin_object = remmina_plugin_python_plugin_create(); + remmina_plugin_python_module_register_object(plugin_object); remmina_plugin_python_module_init(); + Py_Initialize(); PyRun_SimpleString("import sys"); - PyRun_SimpleString("sys.path.append(" REMMINA_RUNTIME_PLUGINDIR ")"); + PyRun_SimpleString("sys.path.append('" REMMINA_RUNTIME_PLUGINDIR "')"); +} - return FALSE; +static char* basename(const char* path) { + return "toolsdevler"; +} + +gboolean +remmina_plugin_python_load(RemminaPluginService* service, const char* name) { + TRACE_CALL(__FUNC__); + PyObject *plugin_name, *plugin_file; + PyObject *pArgs, *pValue; + int i; + + plugin_name = PyUnicode_DecodeFSDefault(basename(name)); + plugin_file = PyImport_Import(plugin_name); + if (plugin_file != NULL) { + return TRUE; + } else { + PyErr_Print(); + g_print("Failed to load \"%s\"\n", name); + return FALSE; + } + return TRUE; } diff --git a/src/remmina_plugin_python.h b/src/remmina_plugin_python.h index 4d1db6079..307588904 100644 --- a/src/remmina_plugin_python.h +++ b/src/remmina_plugin_python.h @@ -36,7 +36,7 @@ #pragma once -#include "remmina_plugin_manager.h" +#include "remmina/plugin.h" G_BEGIN_DECLS diff --git a/src/remmina_plugin_python_module.c b/src/remmina_plugin_python_module.c index acbc1e895..17d896d91 100644 --- a/src/remmina_plugin_python_module.c +++ b/src/remmina_plugin_python_module.c @@ -26,38 +26,63 @@ static PyModuleDef remmina_python_module_type = { */ PyMODINIT_FUNC remmina_plugin_python_module_initialize(void); -void remmina_plugin_python_module_init() { - PyTypeObject *builtin; - PyMethodDef* method; - gint i; - +void remmina_plugin_python_module_init(void) { + if (PyImport_AppendInittab("remmina", remmina_plugin_python_module_initialize)) return FALSE; - for (i = 0; i < remmina_python_module_object_table->len; i++) { - builtin = (PyTypeObject*)g_ptr_array_index(remmina_python_module_object_table, i); - PyType_Ready(builtin); - } - - remmina_python_module_type.m_methods = (PyMethodDef*)malloc((sizeof(PyMethodDef) * remmina_python_module_member_table->len) + 1); - - for (i = 0; i < remmina_python_module_member_table->len; i++) { - method = (PyMethodDef*)g_ptr_array_index(remmina_python_module_member_table, i); - remmina_python_module_type.m_methods[i] = *method; - } - } void remmina_plugin_python_module_register_member(PyMemberDef* member) { + if (!remmina_python_module_member_table) + remmina_python_module_member_table = g_ptr_array_new(); g_ptr_array_add(remmina_python_module_member_table, member); } void remmina_plugin_python_module_register_object(PyTypeObject* object) { + if (!remmina_python_module_object_table) + remmina_python_module_object_table = g_ptr_array_new(); g_ptr_array_add(remmina_python_module_object_table, object); } PyMODINIT_FUNC remmina_plugin_python_module_initialize(void) { PyObject* module_instance = NULL; + PyTypeObject* builtin; + PyMethodDef* method; + gint i; + + if (remmina_python_module_member_table) { + remmina_python_module_type.m_methods = (PyMethodDef*)malloc((sizeof(PyMethodDef) * remmina_python_module_member_table->len) + 1); + for (i = 0; i < remmina_python_module_member_table->len; i++) { + method = (PyMethodDef*)g_ptr_array_index(remmina_python_module_member_table, i); + remmina_python_module_type.m_methods[i] = *method; + } + } + + if (remmina_python_module_object_table) { + for (i = 0; i < remmina_python_module_object_table->len; i++) { + builtin = (PyTypeObject*)g_ptr_array_index(remmina_python_module_object_table, i); + if (builtin) { + PyType_Ready(builtin); + } + } + } + + module_instance = PyModule_Create(&remmina_python_module_type); + + if (remmina_python_module_object_table) { + for (i = 0; i < remmina_python_module_object_table->len; i++) { + builtin = (PyTypeObject*)g_ptr_array_index(remmina_python_module_object_table, i); + if (builtin) { + Py_INCREF(builtin); + if (PyModule_AddObject(module_instance, "Plugin", (PyObject*)builtin)) { + printf("%s: Error initializing\n", builtin->tp_name); + Py_INCREF(builtin); + } + } + } + } + // TODO: Initialize Remmina module for Python return module_instance; } diff --git a/src/remmina_plugin_python_plugin.c b/src/remmina_plugin_python_plugin.c index d3c6212be..edf833e87 100644 --- a/src/remmina_plugin_python_plugin.c +++ b/src/remmina_plugin_python_plugin.c @@ -1,5 +1,182 @@ -#include "remmina_plugin_python_plugin.h" +#include "config.h" #define PY_SSIZE_T_CLEAN #include <Python.h> #include "structmember.h" + +#include <glib.h> +#include <gtk/gtk.h> +#include "remmina/plugin.h" +#include "remmina_plugin_python_plugin.h" + +static const gchar* STR_REMMINA_PLUGIN_TYPE_PROTOCOL = "remmina.plugin_type.protocol"; +static const gchar* STR_REMMINA_PLUGIN_TYPE_ENTRY = "remmina.plugin_type.entry"; +static const gchar* STR_REMMINA_PLUGIN_TYPE_FILE = "remmina.plugin_type.file"; +static const gchar* STR_REMMINA_PLUGIN_TYPE_TOOL = "remmina.plugin_type.tool"; +static const gchar* STR_REMMINA_PLUGIN_TYPE_PREF = "remmina.plugin_type.pref"; +static const gchar* STR_REMMINA_PLUGIN_TYPE_SECRET = "remmina.plugin_type.secret"; + + +static int +remmina_remmina_plugin_init(RemminaPluginPython *self, PyObject *args, PyObject *kwds); + +static PyObject * +remmina_remmina_plugin_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + +static PyMemberDef RemminaPluginPython_members[] = { + {"name", T_OBJECT_EX, offsetof(RemminaPluginPython, name), 0, + "plugin name"}, + {"description", T_OBJECT_EX, offsetof(RemminaPluginPython, description), 0, + "plugin description"}, + {"version", T_OBJECT_EX, offsetof(RemminaPluginPython, version), 0, + "plugin version"}, + {"appicon", T_OBJECT_EX, offsetof(RemminaPluginPython, appicon), 0, + "plugin app-icon name"}, + {NULL} /* Sentinel */ +}; + + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *description; + PyObject *version; + PyObject *appicon; + RemminaPlugin* remmina_plugin; +} RemminaPluginPython; + +typedef struct { + PyObject * type; + PyObject * name; + PyObject * description; + PyObject * domain; + PyObject * version; + + PyObject * icon_name; + PyObject * icon_name_ssh; + PyObject * basic_settings; + PyObject * advanced_settings; + PyObject * ssh_setting; + PyObject * features; + + PyMethodDef m_mehods[] = { + {"init", METH_VARARGS, NULL }, + {"open_connection", METH_VARARGS, NULL }, + {"close_connection", METH_VARARGS, NULL }, + {"query_feature", METH_VARARGS, NULL }, + {"call_feature", METH_VARARGS, NULL }, + {"send_keystrokes", METH_VARARGS, NULL }, + {"get_plugin_screenshot", METH_VARARGS, NULL }}; +} RemminaProtocolPluginPython; + +static PyTypeObject RemminaPluginPythonType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "remmina.Plugin", + .tp_doc = "Custom objects", + .tp_basicsize = sizeof(RemminaPluginPython), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_members = RemminaPluginPython_members, + .tp_new = remmina_remmina_plugin_new, + .tp_init = remmina_remmina_plugin_init +}; + +static void +RemminaPluginPython_dealloc(RemminaPluginPython *self){ + Py_XDECREF(self->name); + Py_XDECREF(self->description); + Py_XDECREF(self->version); + Py_XDECREF(self->appicon); + Py_TYPE(self)->tp_free((PyObject *) self); +} + +PyTypeObject* remmina_plugin_python_plugin_create(void) { return &RemminaPluginPythonType; } + +static PyObject * +remmina_remmina_plugin_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + RemminaPluginPython *self; + + self = (RemminaPluginPython *)type->tp_alloc(type, 0); + if (!self) + return NULL; + + self->name = PyUnicode_FromString(""); + if (!self->name) { + Py_DECREF(self); + return NULL; + } + + self->description = PyUnicode_FromString(""); + if (!self->description) { + Py_DECREF(self); + return NULL; + } + + self->version = PyUnicode_FromString(""); + if (!self->version) { + Py_DECREF(self); + return NULL; + } + + self->appicon = PyUnicode_FromString(""); + if (!self->appicon) { + Py_DECREF(self); + return NULL; + } + + return (PyObject *)self; +} + +static int +remmina_remmina_plugin_init(RemminaPluginPython *self, PyObject *args, PyObject *kwds) +{ + static char* kwlist[] = { "name", "description", "version", "appicon", NULL }; + PyObject *name = NULL; + PyObject *description = NULL; + PyObject *version = NULL; + PyObject *appicon = NULL; + PyObject *tmp; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO", kwlist, &name, &description, &version, &appicon)) + return -1; + + if (name) { + tmp = self->name; + Py_INCREF(name); + self->name = name; + Py_XDECREF(tmp); + } + if (description) { + tmp = self->description; + Py_INCREF(description); + self->description = description; + Py_XDECREF(tmp); + } + if (version) { + tmp = self->version; + Py_INCREF(version); + self->version = version; + Py_XDECREF(tmp); + } + if (appicon) { + tmp = self->appicon; + Py_INCREF(appicon); + self->appicon = appicon; + Py_XDECREF(tmp); + } + + const char *name_str; + const char *description_str; + const char *version_str; + const char *appicon_str; + + if (PyArg_ParseTuple(args, "ssss", &name_str, &version_str, &appicon_str, &description_str)) + printf("Initialied plugin: %s\nVersion: %s\nApp-Icon: %s\nDescription: %s\n", name_str, version_str, appicon_str, description_str); + + self->remmina_plugin = (RemminaPlugin*)malloc(sizeof(*self->remmina_plugin)); + self->remmina_plugin->name = name_str; + self->remmina_plugin->type = REMMINA_PLUGIN_TYPE_PROTOCOL; + + return 0; +}
\ No newline at end of file diff --git a/src/remmina_plugin_python_plugin.h b/src/remmina_plugin_python_plugin.h index f4fd46a36..dd202be66 100644 --- a/src/remmina_plugin_python_plugin.h +++ b/src/remmina_plugin_python_plugin.h @@ -36,4 +36,4 @@ #pragma once - +PyTypeObject* remmina_plugin_python_plugin_create(void); |