From 0beb52ed27725588789f4bbefb34f46e31652791 Mon Sep 17 00:00:00 2001 From: Antenore Gatta Date: Fri, 22 Sep 2023 12:01:04 +0000 Subject: Automatic doc build by remmina-ci --- public/python__wrapper__remmina_8c_source.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/python__wrapper__remmina_8c_source.html b/public/python__wrapper__remmina_8c_source.html index 838258c56..7d0d01fce 100644 --- a/public/python__wrapper__remmina_8c_source.html +++ b/public/python__wrapper__remmina_8c_source.html @@ -86,7 +86,7 @@ $(document).ready(function(){initNavTree('python__wrapper__remmina_8c_source.htm
python_wrapper_remmina.c
-Go to the documentation of this file.
1 /*
2  * Remmina - The GTK+ Remote Desktop Client
3  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  * In addition, as a special exception, the copyright holders give
21  * permission to link the code of portions of this program with the
22  * OpenSSL library under certain conditions as described in each
23  * individual source file, and distribute linked combinations
24  * including the two.
25  * You must obey the GNU General Public License in all respects
26  * for all of the code used other than OpenSSL. * If you modify
27  * file(s) with this exception, you may extend this exception to your
28  * version of the file(s), but you are not obligated to do so. * If you
29  * do not wish to do so, delete this exception statement from your
30  * version. * If you delete this exception statement from all source
31  * files in the program, then also delete it here.
32  */
33 
35 // I N C L U D E S
37 
38 #include "python_wrapper_common.h"
39 #include "remmina/plugin.h"
40 #include "remmina/types.h"
41 
42 #include "python_wrapper_remmina.h"
44 
45 #include "python_wrapper_entry.h"
46 #include "python_wrapper_file.h"
48 #include "python_wrapper_tool.h"
49 #include "python_wrapper_secret.h"
50 #include "python_wrapper_pref.h"
51 
53 
54 #include <string.h>
55 
57 // D E C L A R A T I O N S
59 
60 
64 gboolean python_wrapper_check_mandatory_member(PyObject* instance, const gchar* member);
65 
66 static PyObject* python_wrapper_debug_wrapper(PyObject* self, PyObject* msg);
67 static PyObject* remmina_register_plugin_wrapper(PyObject* self, PyObject* plugin);
68 static PyObject* remmina_file_get_datadir_wrapper(PyObject* self, PyObject* plugin);
69 static PyObject* remmina_file_new_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
70 static PyObject* remmina_pref_set_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
71 static PyObject* remmina_pref_get_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
72 static PyObject* remmina_pref_get_scale_quality_wrapper(PyObject* self, PyObject* plugin);
73 static PyObject* remmina_pref_get_sshtunnel_port_wrapper(PyObject* self, PyObject* plugin);
74 static PyObject* remmina_pref_get_ssh_loglevel_wrapper(PyObject* self, PyObject* plugin);
75 static PyObject* remmina_pref_get_ssh_parseconfig_wrapper(PyObject* self, PyObject* plugin);
76 static PyObject* remmina_pref_keymap_get_keyval_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
77 static PyObject* python_wrapper_log_print_wrapper(PyObject* self, PyObject* arg);
78 static PyObject* remmina_widget_pool_register_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
79 static PyObject* rcw_open_from_file_full_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
80 static PyObject* remmina_public_get_server_port_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
81 static PyObject* remmina_masterthread_exec_is_main_thread_wrapper(PyObject* self, PyObject* plugin);
82 static PyObject* remmina_gtksocket_available_wrapper(PyObject* self, PyObject* plugin);
83 static PyObject*
84 remmina_protocol_widget_get_profile_remote_height_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
85 static PyObject*
86 remmina_protocol_widget_get_profile_remote_width_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
87 static PyObject* python_wrapper_show_dialog_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
88 static PyObject* python_wrapper_get_mainwindow_wrapper(PyObject* self, PyObject* args);
89 static PyObject* remmina_protocol_plugin_signal_connection_opened_wrapper(PyObject* self, PyObject* args);
90 static PyObject* remmina_protocol_plugin_signal_connection_closed_wrapper(PyObject* self, PyObject* args);
91 static PyObject* remmina_protocol_plugin_init_auth_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
92 
97 static PyMethodDef remmina_python_module_type_methods[] = {
102  { "register_plugin", remmina_register_plugin_wrapper, METH_O, NULL },
103 
107  { "log_print", python_wrapper_log_print_wrapper, METH_VARARGS, NULL },
108 
112  { "debug", python_wrapper_debug_wrapper, METH_VARARGS, NULL },
113 
117  { "show_dialog", (PyCFunction)python_wrapper_show_dialog_wrapper, METH_VARARGS | METH_KEYWORDS,
118  NULL },
119 
123  { "get_main_window", python_wrapper_get_mainwindow_wrapper, METH_NOARGS, NULL },
124 
128  { "get_datadir", remmina_file_get_datadir_wrapper, METH_VARARGS, NULL },
129 
133  { "file_new", (PyCFunction)remmina_file_new_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
134 
138  { "pref_set_value", (PyCFunction)remmina_pref_set_value_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
139 
143  { "pref_get_value", (PyCFunction)remmina_pref_get_value_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
144 
148  { "pref_get_scale_quality", remmina_pref_get_scale_quality_wrapper, METH_VARARGS, NULL },
149 
153  { "pref_get_sshtunnel_port", remmina_pref_get_sshtunnel_port_wrapper, METH_VARARGS, NULL },
154 
158  { "pref_get_ssh_loglevel", remmina_pref_get_ssh_loglevel_wrapper, METH_VARARGS, NULL },
159 
163  { "pref_get_ssh_parseconfig", remmina_pref_get_ssh_parseconfig_wrapper, METH_VARARGS, NULL },
164 
168  { "pref_keymap_get_keyval", (PyCFunction)remmina_pref_keymap_get_keyval_wrapper, METH_VARARGS | METH_KEYWORDS,
169  NULL },
170 
174  { "widget_pool_register", (PyCFunction)remmina_widget_pool_register_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
175 
179  { "rcw_open_from_file_full", (PyCFunction)rcw_open_from_file_full_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
180 
184  { "public_get_server_port", (PyCFunction)remmina_public_get_server_port_wrapper, METH_VARARGS | METH_KEYWORDS,
185  NULL },
186 
190  { "masterthread_exec_is_main_thread", remmina_masterthread_exec_is_main_thread_wrapper, METH_VARARGS, NULL },
191 
195  { "gtksocket_available", remmina_gtksocket_available_wrapper, METH_VARARGS, NULL },
196 
200  { "protocol_widget_get_profile_remote_width",
201  (PyCFunction)remmina_protocol_widget_get_profile_remote_width_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
202 
206  { "protocol_widget_get_profile_remote_height",
207  (PyCFunction)remmina_protocol_widget_get_profile_remote_height_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
208  { "protocol_plugin_signal_connection_opened", (PyCFunction)remmina_protocol_plugin_signal_connection_opened_wrapper,
209  METH_VARARGS, NULL },
210 
211  { "protocol_plugin_signal_connection_closed", (PyCFunction)remmina_protocol_plugin_signal_connection_closed_wrapper,
212  METH_VARARGS, NULL },
213 
214  { "protocol_plugin_init_auth", (PyCFunction)remmina_protocol_plugin_init_auth_wrapper, METH_VARARGS | METH_KEYWORDS,
215  NULL },
216 
217  /* Sentinel */
218  { NULL }
219 };
220 
224 typedef struct
225 {
226  PyObject_HEAD
228  gchar* name;
229  gchar* label;
230  gboolean compact;
231  PyObject* opt1;
232  PyObject* opt2;
234 
238 static PyModuleDef remmina_python_module_type = {
239  PyModuleDef_HEAD_INIT,
240  .m_name = "remmina",
241  .m_doc = "Remmina API.",
242  .m_size = -1,
244 };
245 
246 // -- Python Object -> Setting
247 
252 static PyObject* python_protocol_setting_new(PyTypeObject* type, PyObject* args, PyObject* kwargs)
253 {
254  TRACE_CALL(__func__);
255 
256  PyRemminaProtocolSetting* self = (PyRemminaProtocolSetting*)type->tp_alloc(type, 0);
257 
258  if (!self)
259  {
260  return NULL;
261  }
262 
263  self->name = "";
264  self->label = "";
265  self->compact = FALSE;
266  self->opt1 = NULL;
267  self->opt2 = NULL;
268  self->settingType = 0;
269 
270  return (PyObject*)self;
271 }
272 
277 static int python_protocol_setting_init(PyRemminaProtocolSetting* self, PyObject* args, PyObject* kwargs)
278 {
279  TRACE_CALL(__func__);
280 
281  static gchar* kwlist[] = { "type", "name", "label", "compact", "opt1", "opt2", NULL };
282  PyObject* name;
283  PyObject* label;
284 
285  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|lOOpOO", kwlist,
286  &self->settingType, &name, &label, &self->compact, &self->opt1, &self->opt2))
287  {
288  return -1;
289  }
290 
291  Py_ssize_t len = PyUnicode_GetLength(label);
292  if (len == 0)
293  {
294  self->label = "";
295  }
296  else
297  {
298  self->label = python_wrapper_copy_string_from_python(label, len);
299  if (!self->label)
300  {
301  g_printerr("Unable to extract label during initialization of Python settings module!\n");
303  }
304  }
305 
306  len = PyUnicode_GetLength(name);
307  if (len == 0)
308  {
309  self->name = "";
310  }
311  else
312  {
313  self->name = python_wrapper_copy_string_from_python(label, len);
314  if (!self->name)
315  {
316  g_printerr("Unable to extract name during initialization of Python settings module!\n");
318  }
319  }
320 
321  return 0;
322 }
323 
324 static PyMemberDef python_protocol_setting_type_members[] = {
325  { "settingType", offsetof(PyRemminaProtocolSetting, settingType), T_INT, 0, NULL },
326  { "name", offsetof(PyRemminaProtocolSetting, name), T_STRING, 0, NULL },
327  { "label", offsetof(PyRemminaProtocolSetting, label), T_STRING, 0, NULL },
328  { "compact", offsetof(PyRemminaProtocolSetting, compact), T_BOOL, 0, NULL },
329  { "opt1", offsetof(PyRemminaProtocolSetting, opt1), T_OBJECT, 0, NULL },
330  { "opt2", offsetof(PyRemminaProtocolSetting, opt2), T_OBJECT, 0, NULL },
331  { NULL }
332 };
333 
334 static PyTypeObject python_protocol_setting_type = {
335  PyVarObject_HEAD_INIT(NULL, 0)
336  .tp_name = "remmina.Setting",
337  .tp_doc = "Remmina Setting information",
338  .tp_basicsize = sizeof(PyRemminaProtocolSetting),
339  .tp_itemsize = 0,
340  .tp_flags = Py_TPFLAGS_DEFAULT,
341  .tp_new = python_protocol_setting_new,
342  .tp_init = (initproc)python_protocol_setting_init,
344 };
345 
346 // -- Python Type -> Feature
347 
348 
349 static PyMemberDef python_protocol_feature_members[] = {
350  { "type", T_INT, offsetof(PyRemminaProtocolFeature, type), 0, NULL },
351  { "id", T_INT, offsetof(PyRemminaProtocolFeature, id), 0, NULL },
352  { "opt1", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt1), 0, NULL },
353  { "opt2", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt2), 0, NULL },
354  { "opt3", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt3), 0, NULL },
355  { NULL }
356 };
357 
358 PyObject* python_protocol_feature_new(PyTypeObject* type, PyObject* kws, PyObject* args)
359 {
360  TRACE_CALL(__func__);
361 
363  self = (PyRemminaProtocolFeature*)type->tp_alloc(type, 0);
364  if (!self)
365  return NULL;
366 
367  self->id = 0;
368  self->type = 0;
369  self->opt1 = (PyGeneric*)Py_None;
370  self->opt1->raw = NULL;
371  self->opt1->type_hint = REMMINA_TYPEHINT_UNDEFINED;
372  self->opt2 = (PyGeneric*)Py_None;
373  self->opt2->raw = NULL;
374  self->opt2->type_hint = REMMINA_TYPEHINT_UNDEFINED;
375  self->opt3 = (PyGeneric*)Py_None;
376  self->opt3->raw = NULL;
377  self->opt3->type_hint = REMMINA_TYPEHINT_UNDEFINED;
378 
379  return (PyObject*)self;
380 }
381 
382 static int python_protocol_feature_init(PyRemminaProtocolFeature* self, PyObject* args, PyObject* kwargs)
383 {
384  TRACE_CALL(__func__);
385 
386  static char* kwlist[] = { "type", "id", "opt1", "opt2", "opt3", NULL };
387 
388  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|llOOO", kwlist, &self->type, &self->id, &self->opt1, &self
389  ->opt2, &self->opt3))
390  return -1;
391 
392  return 0;
393 }
394 
395 static PyTypeObject python_protocol_feature_type = {
396  PyVarObject_HEAD_INIT(NULL, 0)
397  .tp_name = "remmina.ProtocolFeature",
398  .tp_doc = "Remmina Setting information",
399  .tp_basicsize = sizeof(PyRemminaProtocolFeature),
400  .tp_itemsize = 0,
401  .tp_flags = Py_TPFLAGS_DEFAULT,
402  .tp_new = python_protocol_feature_new,
403  .tp_init = (initproc)python_protocol_feature_init,
404  .tp_members = python_protocol_feature_members
405 };
406 
408 {
410  feature->id = 0;
411  feature->opt1 = python_wrapper_generic_new();
412  feature->opt1->raw = NULL;
414  feature->opt2 = python_wrapper_generic_new();
415  feature->opt2->raw = NULL;
417  feature->opt3 = python_wrapper_generic_new();
418  feature->opt3->raw = NULL;
420  feature->type = 0;
421  Py_IncRef((PyObject*)feature);
422  return feature;
423 }
424 
425 
426 // -- Python Type -> Screenshot Data
427 
428 static PyMemberDef python_screenshot_data_members[] = {
429  { "buffer", T_OBJECT, offsetof(PyRemminaPluginScreenshotData, buffer), 0, NULL },
430  { "width", T_INT, offsetof(PyRemminaPluginScreenshotData, width), 0, NULL },
431  { "height", T_INT, offsetof(PyRemminaPluginScreenshotData, height), 0, NULL },
432  { "bitsPerPixel", T_INT, offsetof(PyRemminaPluginScreenshotData, bitsPerPixel), 0, NULL },
433  { "bytesPerPixel", T_INT, offsetof(PyRemminaPluginScreenshotData, bytesPerPixel), 0, NULL },
434  { NULL }
435 };
436 
437 PyObject* python_screenshot_data_new(PyTypeObject* type, PyObject* kws, PyObject* args)
438 {
439  TRACE_CALL(__func__);
440 
442  self = (PyRemminaPluginScreenshotData*)type->tp_alloc(type, 0);
443  if (!self)
444  return NULL;
445 
446  self->buffer = (PyByteArrayObject*)PyObject_New(PyByteArrayObject, &PyByteArray_Type);
447  self->height = 0;
448  self->width = 0;
449  self->bitsPerPixel = 0;
450  self->bytesPerPixel = 0;
451 
452  return (PyObject*)self;
453 }
454 
455 static int python_screenshot_data_init(PyRemminaPluginScreenshotData* self, PyObject* args, PyObject* kwargs)
456 {
457  TRACE_CALL(__func__);
458 
459  g_printerr("Not to be initialized within Python!");
460  return -1;
461 }
462 
463 static PyTypeObject python_screenshot_data_type = {
464  PyVarObject_HEAD_INIT(NULL, 0)
465  .tp_name = "remmina.RemminaScreenshotData",
466  .tp_doc = "Remmina Screenshot Data",
467  .tp_basicsize = sizeof(PyRemminaPluginScreenshotData),
468  .tp_itemsize = 0,
469  .tp_flags = Py_TPFLAGS_DEFAULT,
470  .tp_new = python_screenshot_data_new,
471  .tp_init = (initproc)python_screenshot_data_init,
472  .tp_members = python_screenshot_data_members
473 };
475 {
477  data->buffer = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
478  Py_IncRef((PyObject*)data->buffer);
479  data->height = 0;
480  data->width = 0;
481  data->bitsPerPixel = 0;
482  data->bytesPerPixel = 0;
483  return data;
484 }
485 
486 static PyObject* python_wrapper_generic_to_int(PyGeneric* self, PyObject* args);
487 static PyObject* python_wrapper_generic_to_bool(PyGeneric* self, PyObject* args);
488 static PyObject* python_wrapper_generic_to_string(PyGeneric* self, PyObject* args);
489 
490 static void python_wrapper_generic_dealloc(PyObject* self)
491 {
492  PyObject_Del(self);
493 }
494 
495 static PyMethodDef python_wrapper_generic_methods[] = {
496  { "to_int", (PyCFunction)python_wrapper_generic_to_int, METH_NOARGS, "" },
497  { "to_bool", (PyCFunction)python_wrapper_generic_to_bool, METH_NOARGS, "" },
498  { "to_string", (PyCFunction)python_wrapper_generic_to_string, METH_NOARGS, "" },
499  { NULL }
500 };
501 
502 static PyMemberDef python_wrapper_generic_members[] = {
503  { "raw", T_OBJECT, offsetof(PyGeneric, raw), 0, "" },
504  { NULL }
505 };
506 
507 PyObject* python_wrapper_generic_type_new(PyTypeObject* type, PyObject* kws, PyObject* args)
508 {
509  TRACE_CALL(__func__);
510 
511  PyGeneric* self;
512  self = (PyGeneric*)type->tp_alloc(type, 0);
513  if (!self)
514  return NULL;
515 
516  self->raw = Py_None;
517 
518  return (PyObject*)self;
519 }
520 
521 static int python_wrapper_generic_init(PyGeneric* self, PyObject* args, PyObject* kwargs)
522 {
523  TRACE_CALL(__func__);
524 
525  static char* kwlist[] = { "raw", NULL };
526 
527  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &self->raw))
528  return -1;
529 
530  return 0;
531 }
532 
533 static PyTypeObject python_generic_type = {
534  PyVarObject_HEAD_INIT(NULL, 0)
535  .tp_name = "remmina.Generic",
536  .tp_doc = "",
537  .tp_basicsize = sizeof(PyGeneric),
538  .tp_itemsize = 0,
539  .tp_dealloc = python_wrapper_generic_dealloc,
540  .tp_flags = Py_TPFLAGS_DEFAULT,
542  .tp_init = (initproc)python_wrapper_generic_init,
543  .tp_members = python_wrapper_generic_members,
544  .tp_methods = python_wrapper_generic_methods,
545 };
546 
548 {
549  PyGeneric* generic = (PyGeneric*)PyObject_New(PyGeneric, &python_generic_type);
550  generic->raw = PyLong_FromLongLong(0LL);
551  Py_IncRef((PyObject*)generic);
552  return generic;
553 }
554 
555 static PyObject* python_wrapper_generic_to_int(PyGeneric* self, PyObject* args)
556 {
557  SELF_CHECK();
558 
559  if (self->raw == NULL)
560  {
561  return Py_None;
562  }
563  else if (self->type_hint == REMMINA_TYPEHINT_SIGNED)
564  {
565  return PyLong_FromLongLong((long long)self->raw);
566  }
567  else if (self->type_hint == REMMINA_TYPEHINT_UNSIGNED)
568  {
569  return PyLong_FromUnsignedLongLong((unsigned long long)self->raw);
570  }
571 
572  return Py_None;
573 }
574 static PyObject* python_wrapper_generic_to_bool(PyGeneric* self, PyObject* args)
575 {
576  SELF_CHECK();
577 
578  if (self->raw == NULL)
579  {
580  return Py_None;
581  }
582  else if (self->type_hint == REMMINA_TYPEHINT_BOOLEAN)
583  {
584  return PyBool_FromLong((long)self->raw);
585  }
586 
587  return Py_None;
588 }
589 static PyObject* python_wrapper_generic_to_string(PyGeneric* self, PyObject* args)
590 {
591  SELF_CHECK();
592 
593  if (self->raw == NULL)
594  {
595  return Py_None;
596  }
597  else if (self->type_hint == REMMINA_TYPEHINT_STRING)
598  {
599  return PyUnicode_FromString((const char*)self->raw);
600  }
601 
602  return Py_None;
603 }
604 
610 {
611  TRACE_CALL(__func__);
612 
613  if (PyType_Ready(&python_screenshot_data_type) < 0)
614  {
615  PyErr_Print();
616  return NULL;
617  }
618 
619  if (PyType_Ready(&python_generic_type) < 0)
620  {
621  PyErr_Print();
622  return NULL;
623  }
624 
625  if (PyType_Ready(&python_protocol_setting_type) < 0)
626  {
627  PyErr_Print();
628  return NULL;
629  }
630 
631  if (PyType_Ready(&python_protocol_feature_type) < 0)
632  {
633  PyErr_Print();
634  return NULL;
635  }
636 
639 
640  PyObject* module = PyModule_Create(&remmina_python_module_type);
641  if (!module)
642  {
643  PyErr_Print();
644  return NULL;
645  }
646 
647  PyModule_AddIntConstant(module, "BUTTONS_CLOSE", (long)GTK_BUTTONS_CLOSE);
648  PyModule_AddIntConstant(module, "BUTTONS_NONE", (long)GTK_BUTTONS_NONE);
649  PyModule_AddIntConstant(module, "BUTTONS_OK", (long)GTK_BUTTONS_OK);
650  PyModule_AddIntConstant(module, "BUTTONS_CLOSE", (long)GTK_BUTTONS_CLOSE);
651  PyModule_AddIntConstant(module, "BUTTONS_CANCEL", (long)GTK_BUTTONS_CANCEL);
652  PyModule_AddIntConstant(module, "BUTTONS_YES_NO", (long)GTK_BUTTONS_YES_NO);
653  PyModule_AddIntConstant(module, "BUTTONS_OK_CANCEL", (long)GTK_BUTTONS_OK_CANCEL);
654 
655  PyModule_AddIntConstant(module, "MESSAGE_INFO", (long)GTK_MESSAGE_INFO);
656  PyModule_AddIntConstant(module, "MESSAGE_WARNING", (long)GTK_MESSAGE_WARNING);
657  PyModule_AddIntConstant(module, "MESSAGE_QUESTION", (long)GTK_MESSAGE_QUESTION);
658  PyModule_AddIntConstant(module, "MESSAGE_ERROR", (long)GTK_MESSAGE_ERROR);
659  PyModule_AddIntConstant(module, "MESSAGE_OTHER", (long)GTK_MESSAGE_OTHER);
660 
661  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_SERVER", (long)REMMINA_PROTOCOL_SETTING_TYPE_SERVER);
662  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_PASSWORD", (long)REMMINA_PROTOCOL_SETTING_TYPE_PASSWORD);
663  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_RESOLUTION", (long)REMMINA_PROTOCOL_SETTING_TYPE_RESOLUTION);
664  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_ASSISTANCE", (long)REMMINA_PROTOCOL_SETTING_TYPE_ASSISTANCE);
665  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_KEYMAP", (long)REMMINA_PROTOCOL_SETTING_TYPE_KEYMAP);
666  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_TEXT", (long)REMMINA_PROTOCOL_SETTING_TYPE_TEXT);
667  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_SELECT", (long)REMMINA_PROTOCOL_SETTING_TYPE_SELECT);
668  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_COMBO", (long)REMMINA_PROTOCOL_SETTING_TYPE_COMBO);
669  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_CHECK", (long)REMMINA_PROTOCOL_SETTING_TYPE_CHECK);
670  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_FILE", (long)REMMINA_PROTOCOL_SETTING_TYPE_FILE);
671  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_FOLDER", (long)REMMINA_PROTOCOL_SETTING_TYPE_FOLDER);
672  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_MULTIMON", (long)REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON);
673 
674  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_PREF", (long)REMMINA_PROTOCOL_FEATURE_TYPE_PREF);
675  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_TOOL", (long)REMMINA_PROTOCOL_FEATURE_TYPE_TOOL);
676  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_UNFOCUS", (long)REMMINA_PROTOCOL_FEATURE_TYPE_UNFOCUS);
677  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_SCALE", (long)REMMINA_PROTOCOL_FEATURE_TYPE_SCALE);
678  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_DYNRESUPDATE", (long)REMMINA_PROTOCOL_FEATURE_TYPE_DYNRESUPDATE);
679  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_GTKSOCKET", (long)REMMINA_PROTOCOL_FEATURE_TYPE_GTKSOCKET);
680 
681  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_NONE", (long)REMMINA_PROTOCOL_SSH_SETTING_NONE);
682  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_TUNNEL", (long)REMMINA_PROTOCOL_SSH_SETTING_TUNNEL);
683  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_SSH", (long)REMMINA_PROTOCOL_SSH_SETTING_SSH);
684  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_REVERSE_TUNNEL", (long)REMMINA_PROTOCOL_SSH_SETTING_REVERSE_TUNNEL);
685  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_SFTP", (long)REMMINA_PROTOCOL_SSH_SETTING_SFTP);
686 
687  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_PREF_RADIO", (long)REMMINA_PROTOCOL_FEATURE_PREF_RADIO);
688  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_PREF_CHECK", (long)REMMINA_PROTOCOL_FEATURE_PREF_CHECK);
689 
690  PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_USERNAME", REMMINA_MESSAGE_PANEL_FLAG_USERNAME);
691  PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_USERNAME_READONLY", REMMINA_MESSAGE_PANEL_FLAG_USERNAME_READONLY);
692  PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_DOMAIN", REMMINA_MESSAGE_PANEL_FLAG_DOMAIN);
693  PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_SAVEPASSWORD", REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD);
694 
695  if (PyModule_AddObject(module, "Setting", (PyObject*)&python_protocol_setting_type) < 0)
696  {
697  Py_DECREF(&python_protocol_setting_type);
698  Py_DECREF(module);
699  PyErr_Print();
700  return NULL;
701  }
702 
703  Py_INCREF(&python_protocol_feature_type);
704  if (PyModule_AddObject(module, "Feature", (PyObject*)&python_protocol_feature_type) < 0)
705  {
706  Py_DECREF(&python_protocol_setting_type);
707  Py_DECREF(&python_protocol_feature_type);
708  Py_DECREF(module);
709  PyErr_Print();
710  return NULL;
711  }
712 
713  return module;
714 }
715 
721 {
722  TRACE_CALL(__func__);
723 
724  if (PyImport_AppendInittab("remmina", python_wrapper_module_initialize))
725  {
726  PyErr_Print();
727  exit(1);
728  }
729 
736 }
737 
738 gboolean python_wrapper_check_mandatory_member(PyObject* instance, const gchar* member)
739 {
740  TRACE_CALL(__func__);
741 
742  if (PyObject_HasAttrString(instance, member))
743  {
744  return TRUE;
745  }
746 
747  g_printerr("Missing mandatory member '%s' in Python plugin instance!\n", member);
748  return FALSE;
749 }
750 
751 static PyObject* remmina_register_plugin_wrapper(PyObject* self, PyObject* plugin_instance)
752 {
753  TRACE_CALL(__func__);
754 
755  if (plugin_instance)
756  {
757  if (!python_wrapper_check_mandatory_member(plugin_instance, "name")
758  || !python_wrapper_check_mandatory_member(plugin_instance, "version"))
759  {
760  return NULL;
761  }
762 
763  /* Protocol plugin definition and features */
764  const gchar* pluginType = PyUnicode_AsUTF8(PyObject_GetAttrString(plugin_instance, "type"));
765 
767 
768  PyPlugin* plugin = (PyPlugin*)python_wrapper_malloc(sizeof(PyPlugin));
769  plugin->instance = plugin_instance;
770  Py_INCREF(plugin_instance);
771  plugin->protocol_plugin = NULL;
772  plugin->entry_plugin = NULL;
773  plugin->file_plugin = NULL;
774  plugin->pref_plugin = NULL;
775  plugin->secret_plugin = NULL;
776  plugin->tool_plugin = NULL;
777  g_print("New Python plugin registered: %ld\n", PyObject_Hash(plugin_instance));
778 
779  if (g_str_equal(pluginType, "protocol"))
780  {
781  remmina_plugin = python_wrapper_create_protocol_plugin(plugin);
782  }
783  else if (g_str_equal(pluginType, "entry"))
784  {
785  remmina_plugin = python_wrapper_create_entry_plugin(plugin);
786  }
787  else if (g_str_equal(pluginType, "file"))
788  {
789  remmina_plugin = python_wrapper_create_file_plugin(plugin);
790  }
791  else if (g_str_equal(pluginType, "tool"))
792  {
793  remmina_plugin = python_wrapper_create_tool_plugin(plugin);
794  }
795  else if (g_str_equal(pluginType, "pref"))
796  {
797  remmina_plugin = python_wrapper_create_pref_plugin(plugin);
798  }
799  else if (g_str_equal(pluginType, "secret"))
800  {
801  remmina_plugin = python_wrapper_create_secret_plugin(plugin);
802  }
803  else
804  {
805  g_printerr("Unknown plugin type: %s\n", pluginType);
806  }
807 
808  if (remmina_plugin)
809  {
810  if (remmina_plugin->type == REMMINA_PLUGIN_TYPE_PROTOCOL)
811  {
813  }
814 
815  if (python_wrapper_get_service()->register_plugin((RemminaPlugin*)remmina_plugin)) {
816  g_print("%s: Successfully reigstered!\n", remmina_plugin->name);
817  } else {
818  g_print("%s: Failed to reigster!\n", remmina_plugin->name);
819  }
820  }
821  }
822 
823  PyErr_Clear();
824  return Py_None;
825 }
826 
827 static PyObject* remmina_file_get_datadir_wrapper(PyObject* self, PyObject* plugin)
828 {
829  TRACE_CALL(__func__);
830 
831  PyObject* result = Py_None;
832  const gchar* datadir = python_wrapper_get_service()->file_get_user_datadir();
833 
834  if (datadir)
835  {
836  result = PyUnicode_FromFormat("%s", datadir);
837  }
838 
840  return result;
841 }
842 
843 static PyObject* remmina_file_new_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
844 {
845  TRACE_CALL(__func__);
846 
848  if (file)
849  {
850  return (PyObject*)python_wrapper_remmina_file_to_python(file);
851  }
852 
854  return Py_None;
855 }
856 
857 static PyObject* remmina_pref_set_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
858 {
859  TRACE_CALL(__func__);
860 
861  static char* kwlist[] = { "key", "value", NULL };
862  gchar* key, * value;
863 
864  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &key, &value))
865  {
866  return Py_None;
867  }
868 
869  if (key)
870  {
872  }
873 
875  return Py_None;
876 }
877 
878 static PyObject* remmina_pref_get_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
879 {
880  TRACE_CALL(__func__);
881 
882  static char* kwlist[] = { "key", NULL };
883  gchar* key;
884  PyObject* result = Py_None;
885 
886  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &key))
887  {
888  return Py_None;
889  }
890 
891  if (key)
892  {
893  const gchar* value = python_wrapper_get_service()->pref_get_value(key);
894  if (value)
895  {
896  result = PyUnicode_FromFormat("%s", result);
897  }
898  }
899 
901  return result;
902 }
903 
904 static PyObject* remmina_pref_get_scale_quality_wrapper(PyObject* self, PyObject* plugin)
905 {
906  TRACE_CALL(__func__);
907 
908  PyObject* result = PyLong_FromLong(python_wrapper_get_service()->pref_get_scale_quality());
910  return result;
911 }
912 
913 static PyObject* remmina_pref_get_sshtunnel_port_wrapper(PyObject* self, PyObject* plugin)
914 {
915  TRACE_CALL(__func__);
916 
917  PyObject* result = PyLong_FromLong(python_wrapper_get_service()->pref_get_sshtunnel_port());
919  return result;
920 }
921 
922 static PyObject* remmina_pref_get_ssh_loglevel_wrapper(PyObject* self, PyObject* plugin)
923 {
924  TRACE_CALL(__func__);
925 
926  PyObject* result = PyLong_FromLong(python_wrapper_get_service()->pref_get_ssh_loglevel());
928  return result;
929 }
930 
931 static PyObject* remmina_pref_get_ssh_parseconfig_wrapper(PyObject* self, PyObject* plugin)
932 {
933  TRACE_CALL(__func__);
934 
935  PyObject* result = PyLong_FromLong(python_wrapper_get_service()->pref_get_ssh_parseconfig());
937  return result;
938 }
939 
940 static PyObject* remmina_pref_keymap_get_keyval_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
941 {
942  TRACE_CALL(__func__);
943 
944  static char* kwlist[] = { "keymap", "keyval", NULL };
945  gchar* keymap;
946  guint keyval;
947  PyObject* result = Py_None;
948 
949  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sl", kwlist, &keymap, &keyval))
950  {
951  return PyLong_FromLong(-1);
952  }
953 
954  if (keymap)
955  {
956  const guint value = python_wrapper_get_service()->pref_keymap_get_keyval(keymap, keyval);
957  result = PyLong_FromUnsignedLong(value);
958  }
959 
961  return result;
962 }
963 
964 static PyObject* python_wrapper_log_print_wrapper(PyObject* self, PyObject* args)
965 {
966  TRACE_CALL(__func__);
967 
968  gchar* text;
969  if (!PyArg_ParseTuple(args, "s", &text) || !text)
970  {
971  return Py_None;
972  }
973 
975  return Py_None;
976 }
977 
978 static PyObject* python_wrapper_debug_wrapper(PyObject* self, PyObject* args)
979 {
980  TRACE_CALL(__func__);
981 
982  gchar* text;
983  if (!PyArg_ParseTuple(args, "s", &text) || !text)
984  {
985  return Py_None;
986  }
987 
988  python_wrapper_get_service()->_remmina_debug("python", "%s", text);
989  return Py_None;
990 }
991 
992 static PyObject* remmina_widget_pool_register_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
993 {
994  TRACE_CALL(__func__);
995 
996  static char* kwlist[] = { "widget", NULL };
997  PyObject* widget;
998 
999  if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &widget) && widget)
1000  {
1002  }
1003 
1004  return Py_None;
1005 }
1006 
1007 static PyObject* rcw_open_from_file_full_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1008 {
1009  TRACE_CALL(__func__);
1010 
1011  static char* kwlist[] = { "remminafile", "data", "handler", NULL };
1012  PyObject* pyremminafile;
1013  PyObject* data;
1014 
1015  if (PyArg_ParseTupleAndKeywords(args, kwargs, "OOO", kwlist, &pyremminafile, &data) && pyremminafile && data)
1016  {
1017  python_wrapper_get_service()->rcw_open_from_file_full((RemminaFile*)pyremminafile, NULL, (void*)data, NULL);
1018  }
1019 
1020  return Py_None;
1021 }
1022 
1023 static PyObject* remmina_public_get_server_port_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1024 {
1025  TRACE_CALL(__func__);
1026 
1027  static char* kwlist[] = { "server", "defaultport", NULL };
1028  gchar* server;
1029  gint defaultport;
1030 
1031  if (PyArg_ParseTupleAndKeywords(args, kwargs, "sl", kwlist, &server, &defaultport) && server)
1032  {
1033  gchar* host;
1034  gint port;
1035  python_wrapper_get_service()->get_server_port(server, defaultport, &host, &port);
1036 
1037  PyObject* result = PyList_New(2);
1038  PyList_SetItem(result, 0, PyUnicode_FromString(host));
1039  PyList_SetItem(result, 1, PyLong_FromLong(port));
1040 
1041  return PyList_AsTuple(result);
1042  }
1043 
1044  return Py_None;
1045 }
1046 
1047 static PyObject* remmina_masterthread_exec_is_main_thread_wrapper(PyObject* self, PyObject* plugin)
1048 {
1049  TRACE_CALL(__func__);
1050 
1051  return PyBool_FromLong(python_wrapper_get_service()->is_main_thread());
1052 }
1053 
1054 static PyObject* remmina_gtksocket_available_wrapper(PyObject* self, PyObject* plugin)
1055 {
1056  TRACE_CALL(__func__);
1057 
1058  return PyBool_FromLong(python_wrapper_get_service()->gtksocket_available());
1059 }
1060 
1061 static PyObject*
1062 remmina_protocol_widget_get_profile_remote_height_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1063 {
1064  TRACE_CALL(__func__);
1065 
1066  static char* kwlist[] = { "widget", NULL };
1067  PyPlugin* plugin;
1068 
1069  if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &plugin) && plugin && plugin->gp)
1070  {
1072  }
1073 
1074  return Py_None;
1075 }
1076 
1077 static PyObject*
1078 remmina_protocol_widget_get_profile_remote_width_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1079 {
1080  TRACE_CALL(__func__);
1081 
1082  static char* kwlist[] = { "widget", NULL };
1083  PyPlugin* plugin;
1084 
1085  if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &plugin) && plugin && plugin->gp)
1086  {
1088  }
1089 
1090  return Py_None;
1091 }
1092 
1094 {
1095  TRACE_CALL(__func__);
1096 
1098  Py_INCREF(setting);
1099  dest->name = src->name;
1100  dest->label = src->label;
1101  dest->compact = src->compact;
1102  dest->type = src->settingType;
1103  dest->validator = NULL;
1104  dest->validator_data = NULL;
1105  python_wrapper_to_generic(src->opt1, &dest->opt1);
1106  python_wrapper_to_generic(src->opt2, &dest->opt2);
1107 }
1108 
1110 {
1111  TRACE_CALL(__func__);
1112 
1114  Py_INCREF(feature);
1115  dest->id = src->id;
1116  dest->type = src->type;
1117  dest->opt1 = src->opt1->raw;
1118  dest->opt1_type_hint = src->opt1->type_hint;
1119  dest->opt2 = src->opt2->raw;
1120  dest->opt2_type_hint = src->opt2->type_hint;
1121  dest->opt3 = src->opt3->raw;
1122  dest->opt3_type_hint = src->opt3->type_hint;
1123 }
1124 
1125 PyObject* python_wrapper_show_dialog_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1126 {
1127  TRACE_CALL(__func__);
1128 
1129  static char* kwlist[] = { "type", "buttons", "message", NULL };
1130  GtkMessageType msgType;
1131  GtkButtonsType btnType;
1132  gchar* message;
1133 
1134  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "lls", kwlist, &msgType, &btnType, &message))
1135  {
1136  return PyLong_FromLong(-1);
1137  }
1138 
1139  python_wrapper_get_service()->show_dialog(msgType, btnType, message);
1140 
1141  return Py_None;
1142 }
1143 
1144 PyObject* python_wrapper_get_mainwindow_wrapper(PyObject* self, PyObject* args)
1145 {
1146  TRACE_CALL(__func__);
1147 
1148  GtkWindow* result = python_wrapper_get_service()->get_window();
1149 
1150  if (!result)
1151  {
1152  return Py_None;
1153  }
1154 
1155  return (PyObject*)new_pywidget((GObject*)result);
1156 }
1157 
1158 static PyObject* remmina_protocol_plugin_signal_connection_closed_wrapper(PyObject* self, PyObject* args)
1159 {
1160  TRACE_CALL(__func__);
1161 
1162  PyObject* pygp = NULL;
1163  if (!PyArg_ParseTuple(args, "O", &pygp) || !pygp)
1164  {
1165  g_printerr("Please provide the Remmina protocol widget instance!");
1166  return Py_None;
1167  }
1168 
1170  return Py_None;
1171 }
1172 
1173 static PyObject* remmina_protocol_plugin_init_auth_wrapper(PyObject* module, PyObject* args, PyObject* kwds)
1174 {
1175  TRACE_CALL(__func__);
1176 
1177  static gchar* keyword_list[] = { "widget", "flags", "title", "default_username", "default_password",
1178  "default_domain", "password_prompt" };
1179 
1181  gint pflags = 0;
1182  gchar* title, * default_username, * default_password, * default_domain, * password_prompt;
1183 
1184  if (PyArg_ParseTupleAndKeywords(args, kwds, "Oisssss", keyword_list, &self, &pflags, &title, &default_username,
1185  &default_password, &default_domain, &password_prompt))
1186  {
1187  if (pflags != 0 && !(pflags & REMMINA_MESSAGE_PANEL_FLAG_USERNAME)
1189  && !(pflags & REMMINA_MESSAGE_PANEL_FLAG_DOMAIN)
1191  {
1192  g_printerr("panel_auth(pflags, title, default_username, default_password, default_domain, password_prompt): "
1193  "%d is not a known value for RemminaMessagePanelFlags!\n", pflags);
1194  }
1195  else
1196  {
1197  return Py_BuildValue("i", python_wrapper_get_service()->protocol_widget_panel_auth(self
1198  ->gp, pflags, title, default_username, default_password, default_domain, password_prompt));
1199  }
1200  }
1201  else
1202  {
1203  g_printerr("panel_auth(pflags, title, default_username, default_password, default_domain, password_prompt): Error parsing arguments!\n");
1204  PyErr_Print();
1205  }
1206  return Py_None;
1207 }
1208 
1209 static PyObject* remmina_protocol_plugin_signal_connection_opened_wrapper(PyObject* self, PyObject* args)
1210 {
1211  PyObject* pygp = NULL;
1212  if (!PyArg_ParseTuple(args, "O", &pygp) || !pygp)
1213  {
1214  g_printerr("Please provide the Remmina protocol widget instance!");
1215  return Py_None;
1216  }
1217 
1219  return Py_None;
1220 }
static PyObject * remmina_register_plugin_wrapper(PyObject *self, PyObject *plugin)
+Go to the documentation of this file.
1 /*
2  * Remmina - The GTK+ Remote Desktop Client
3  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  * In addition, as a special exception, the copyright holders give
21  * permission to link the code of portions of this program with the
22  * OpenSSL library under certain conditions as described in each
23  * individual source file, and distribute linked combinations
24  * including the two.
25  * You must obey the GNU General Public License in all respects
26  * for all of the code used other than OpenSSL. * If you modify
27  * file(s) with this exception, you may extend this exception to your
28  * version of the file(s), but you are not obligated to do so. * If you
29  * do not wish to do so, delete this exception statement from your
30  * version. * If you delete this exception statement from all source
31  * files in the program, then also delete it here.
32  */
33 
35 // I N C L U D E S
37 
38 #include "python_wrapper_common.h"
39 #include "remmina/plugin.h"
40 #include "remmina/types.h"
41 
42 #include "python_wrapper_remmina.h"
44 
45 #include "python_wrapper_entry.h"
46 #include "python_wrapper_file.h"
48 #include "python_wrapper_tool.h"
49 #include "python_wrapper_secret.h"
50 #include "python_wrapper_pref.h"
51 
53 
54 #include <string.h>
55 
57 // D E C L A R A T I O N S
59 
60 
64 gboolean python_wrapper_check_mandatory_member(PyObject* instance, const gchar* member);
65 
66 static PyObject* python_wrapper_debug_wrapper(PyObject* self, PyObject* msg);
67 static PyObject* remmina_register_plugin_wrapper(PyObject* self, PyObject* plugin);
68 static PyObject* remmina_file_get_datadir_wrapper(PyObject* self, PyObject* plugin);
69 static PyObject* remmina_file_new_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
70 static PyObject* remmina_pref_set_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
71 static PyObject* remmina_pref_get_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
72 static PyObject* remmina_pref_get_scale_quality_wrapper(PyObject* self, PyObject* plugin);
73 static PyObject* remmina_pref_get_sshtunnel_port_wrapper(PyObject* self, PyObject* plugin);
74 static PyObject* remmina_pref_get_ssh_loglevel_wrapper(PyObject* self, PyObject* plugin);
75 static PyObject* remmina_pref_get_ssh_parseconfig_wrapper(PyObject* self, PyObject* plugin);
76 static PyObject* remmina_pref_keymap_get_keyval_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
77 static PyObject* python_wrapper_log_print_wrapper(PyObject* self, PyObject* arg);
78 static PyObject* remmina_widget_pool_register_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
79 static PyObject* rcw_open_from_file_full_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
80 static PyObject* remmina_public_get_server_port_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
81 static PyObject* remmina_masterthread_exec_is_main_thread_wrapper(PyObject* self, PyObject* plugin);
82 static PyObject* remmina_gtksocket_available_wrapper(PyObject* self, PyObject* plugin);
83 static PyObject*
84 remmina_protocol_widget_get_profile_remote_height_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
85 static PyObject*
86 remmina_protocol_widget_get_profile_remote_width_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
87 static PyObject* python_wrapper_show_dialog_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
88 static PyObject* python_wrapper_get_mainwindow_wrapper(PyObject* self, PyObject* args);
89 static PyObject* remmina_protocol_plugin_signal_connection_opened_wrapper(PyObject* self, PyObject* args);
90 static PyObject* remmina_protocol_plugin_signal_connection_closed_wrapper(PyObject* self, PyObject* args);
91 static PyObject* remmina_protocol_plugin_init_auth_wrapper(PyObject* self, PyObject* args, PyObject* kwargs);
92 
97 static PyMethodDef remmina_python_module_type_methods[] = {
102  { "register_plugin", remmina_register_plugin_wrapper, METH_O, NULL },
103 
107  { "log_print", python_wrapper_log_print_wrapper, METH_VARARGS, NULL },
108 
112  { "debug", python_wrapper_debug_wrapper, METH_VARARGS, NULL },
113 
117  { "show_dialog", (PyCFunction)python_wrapper_show_dialog_wrapper, METH_VARARGS | METH_KEYWORDS,
118  NULL },
119 
123  { "get_main_window", python_wrapper_get_mainwindow_wrapper, METH_NOARGS, NULL },
124 
128  { "get_datadir", remmina_file_get_datadir_wrapper, METH_VARARGS, NULL },
129 
133  { "file_new", (PyCFunction)remmina_file_new_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
134 
138  { "pref_set_value", (PyCFunction)remmina_pref_set_value_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
139 
143  { "pref_get_value", (PyCFunction)remmina_pref_get_value_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
144 
148  { "pref_get_scale_quality", remmina_pref_get_scale_quality_wrapper, METH_VARARGS, NULL },
149 
153  { "pref_get_sshtunnel_port", remmina_pref_get_sshtunnel_port_wrapper, METH_VARARGS, NULL },
154 
158  { "pref_get_ssh_loglevel", remmina_pref_get_ssh_loglevel_wrapper, METH_VARARGS, NULL },
159 
163  { "pref_get_ssh_parseconfig", remmina_pref_get_ssh_parseconfig_wrapper, METH_VARARGS, NULL },
164 
168  { "pref_keymap_get_keyval", (PyCFunction)remmina_pref_keymap_get_keyval_wrapper, METH_VARARGS | METH_KEYWORDS,
169  NULL },
170 
174  { "widget_pool_register", (PyCFunction)remmina_widget_pool_register_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
175 
179  { "rcw_open_from_file_full", (PyCFunction)rcw_open_from_file_full_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
180 
184  { "public_get_server_port", (PyCFunction)remmina_public_get_server_port_wrapper, METH_VARARGS | METH_KEYWORDS,
185  NULL },
186 
190  { "masterthread_exec_is_main_thread", remmina_masterthread_exec_is_main_thread_wrapper, METH_VARARGS, NULL },
191 
195  { "gtksocket_available", remmina_gtksocket_available_wrapper, METH_VARARGS, NULL },
196 
200  { "protocol_widget_get_profile_remote_width",
201  (PyCFunction)remmina_protocol_widget_get_profile_remote_width_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
202 
206  { "protocol_widget_get_profile_remote_height",
207  (PyCFunction)remmina_protocol_widget_get_profile_remote_height_wrapper, METH_VARARGS | METH_KEYWORDS, NULL },
208  { "protocol_plugin_signal_connection_opened", (PyCFunction)remmina_protocol_plugin_signal_connection_opened_wrapper,
209  METH_VARARGS, NULL },
210 
211  { "protocol_plugin_signal_connection_closed", (PyCFunction)remmina_protocol_plugin_signal_connection_closed_wrapper,
212  METH_VARARGS, NULL },
213 
214  { "protocol_plugin_init_auth", (PyCFunction)remmina_protocol_plugin_init_auth_wrapper, METH_VARARGS | METH_KEYWORDS,
215  NULL },
216 
217  /* Sentinel */
218  { NULL }
219 };
220 
224 typedef struct
225 {
226  PyObject_HEAD
228  gchar* name;
229  gchar* label;
230  gboolean compact;
231  PyObject* opt1;
232  PyObject* opt2;
234 
238 static PyModuleDef remmina_python_module_type = {
239  PyModuleDef_HEAD_INIT,
240  .m_name = "remmina",
241  .m_doc = "Remmina API.",
242  .m_size = -1,
244 };
245 
246 // -- Python Object -> Setting
247 
252 static PyObject* python_protocol_setting_new(PyTypeObject* type, PyObject* args, PyObject* kwargs)
253 {
254  TRACE_CALL(__func__);
255 
256  PyRemminaProtocolSetting* self = (PyRemminaProtocolSetting*)type->tp_alloc(type, 0);
257 
258  if (!self)
259  {
260  return NULL;
261  }
262 
263  self->name = "";
264  self->label = "";
265  self->compact = FALSE;
266  self->opt1 = NULL;
267  self->opt2 = NULL;
268  self->settingType = 0;
269 
270  return (PyObject*)self;
271 }
272 
277 static int python_protocol_setting_init(PyRemminaProtocolSetting* self, PyObject* args, PyObject* kwargs)
278 {
279  TRACE_CALL(__func__);
280 
281  static gchar* kwlist[] = { "type", "name", "label", "compact", "opt1", "opt2", NULL };
282  PyObject* name;
283  PyObject* label;
284 
285  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|lOOpOO", kwlist,
286  &self->settingType, &name, &label, &self->compact, &self->opt1, &self->opt2))
287  {
288  return -1;
289  }
290 
291  Py_ssize_t len = PyUnicode_GetLength(label);
292  if (len == 0)
293  {
294  self->label = "";
295  }
296  else
297  {
298  self->label = python_wrapper_copy_string_from_python(label, len);
299  if (!self->label)
300  {
301  g_printerr("Unable to extract label during initialization of Python settings module!\n");
303  }
304  }
305 
306  len = PyUnicode_GetLength(name);
307  if (len == 0)
308  {
309  self->name = "";
310  }
311  else
312  {
313  self->name = python_wrapper_copy_string_from_python(label, len);
314  if (!self->name)
315  {
316  g_printerr("Unable to extract name during initialization of Python settings module!\n");
318  }
319  }
320 
321  return 0;
322 }
323 
324 static PyMemberDef python_protocol_setting_type_members[] = {
325  { "settingType", offsetof(PyRemminaProtocolSetting, settingType), T_INT, 0, NULL },
326  { "name", offsetof(PyRemminaProtocolSetting, name), T_STRING, 0, NULL },
327  { "label", offsetof(PyRemminaProtocolSetting, label), T_STRING, 0, NULL },
328  { "compact", offsetof(PyRemminaProtocolSetting, compact), T_BOOL, 0, NULL },
329  { "opt1", offsetof(PyRemminaProtocolSetting, opt1), T_OBJECT, 0, NULL },
330  { "opt2", offsetof(PyRemminaProtocolSetting, opt2), T_OBJECT, 0, NULL },
331  { NULL }
332 };
333 
334 static PyTypeObject python_protocol_setting_type = {
335  PyVarObject_HEAD_INIT(NULL, 0)
336  .tp_name = "remmina.Setting",
337  .tp_doc = "Remmina Setting information",
338  .tp_basicsize = sizeof(PyRemminaProtocolSetting),
339  .tp_itemsize = 0,
340  .tp_flags = Py_TPFLAGS_DEFAULT,
341  .tp_new = python_protocol_setting_new,
342  .tp_init = (initproc)python_protocol_setting_init,
344 };
345 
346 // -- Python Type -> Feature
347 
348 
349 static PyMemberDef python_protocol_feature_members[] = {
350  { "type", T_INT, offsetof(PyRemminaProtocolFeature, type), 0, NULL },
351  { "id", T_INT, offsetof(PyRemminaProtocolFeature, id), 0, NULL },
352  { "opt1", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt1), 0, NULL },
353  { "opt2", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt2), 0, NULL },
354  { "opt3", T_OBJECT, offsetof(PyRemminaProtocolFeature, opt3), 0, NULL },
355  { NULL }
356 };
357 
358 PyObject* python_protocol_feature_new(PyTypeObject* type, PyObject* kws, PyObject* args)
359 {
360  TRACE_CALL(__func__);
361 
363  self = (PyRemminaProtocolFeature*)type->tp_alloc(type, 0);
364  if (!self)
365  return NULL;
366 
367  self->id = 0;
368  self->type = 0;
369  self->opt1 = (PyGeneric*)Py_None;
370  self->opt1->raw = NULL;
371  self->opt1->type_hint = REMMINA_TYPEHINT_UNDEFINED;
372  self->opt2 = (PyGeneric*)Py_None;
373  self->opt2->raw = NULL;
374  self->opt2->type_hint = REMMINA_TYPEHINT_UNDEFINED;
375  self->opt3 = (PyGeneric*)Py_None;
376  self->opt3->raw = NULL;
377  self->opt3->type_hint = REMMINA_TYPEHINT_UNDEFINED;
378 
379  return (PyObject*)self;
380 }
381 
382 static int python_protocol_feature_init(PyRemminaProtocolFeature* self, PyObject* args, PyObject* kwargs)
383 {
384  TRACE_CALL(__func__);
385 
386  static char* kwlist[] = { "type", "id", "opt1", "opt2", "opt3", NULL };
387 
388  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|llOOO", kwlist, &self->type, &self->id, &self->opt1, &self
389  ->opt2, &self->opt3))
390  return -1;
391 
392  return 0;
393 }
394 
395 static PyTypeObject python_protocol_feature_type = {
396  PyVarObject_HEAD_INIT(NULL, 0)
397  .tp_name = "remmina.ProtocolFeature",
398  .tp_doc = "Remmina Setting information",
399  .tp_basicsize = sizeof(PyRemminaProtocolFeature),
400  .tp_itemsize = 0,
401  .tp_flags = Py_TPFLAGS_DEFAULT,
402  .tp_new = python_protocol_feature_new,
403  .tp_init = (initproc)python_protocol_feature_init,
404  .tp_members = python_protocol_feature_members
405 };
406 
408 {
410  feature->id = 0;
411  feature->opt1 = python_wrapper_generic_new();
412  feature->opt1->raw = NULL;
414  feature->opt2 = python_wrapper_generic_new();
415  feature->opt2->raw = NULL;
417  feature->opt3 = python_wrapper_generic_new();
418  feature->opt3->raw = NULL;
420  feature->type = 0;
421  Py_IncRef((PyObject*)feature);
422  return feature;
423 }
424 
425 
426 // -- Python Type -> Screenshot Data
427 
428 static PyMemberDef python_screenshot_data_members[] = {
429  { "buffer", T_OBJECT, offsetof(PyRemminaPluginScreenshotData, buffer), 0, NULL },
430  { "width", T_INT, offsetof(PyRemminaPluginScreenshotData, width), 0, NULL },
431  { "height", T_INT, offsetof(PyRemminaPluginScreenshotData, height), 0, NULL },
432  { "bitsPerPixel", T_INT, offsetof(PyRemminaPluginScreenshotData, bitsPerPixel), 0, NULL },
433  { "bytesPerPixel", T_INT, offsetof(PyRemminaPluginScreenshotData, bytesPerPixel), 0, NULL },
434  { NULL }
435 };
436 
437 PyObject* python_screenshot_data_new(PyTypeObject* type, PyObject* kws, PyObject* args)
438 {
439  TRACE_CALL(__func__);
440 
442  self = (PyRemminaPluginScreenshotData*)type->tp_alloc(type, 0);
443  if (!self)
444  return NULL;
445 
446  self->buffer = (PyByteArrayObject*)PyObject_New(PyByteArrayObject, &PyByteArray_Type);
447  self->height = 0;
448  self->width = 0;
449  self->bitsPerPixel = 0;
450  self->bytesPerPixel = 0;
451 
452  return (PyObject*)self;
453 }
454 
455 static int python_screenshot_data_init(PyRemminaPluginScreenshotData* self, PyObject* args, PyObject* kwargs)
456 {
457  TRACE_CALL(__func__);
458 
459  g_printerr("Not to be initialized within Python!");
460  return -1;
461 }
462 
463 static PyTypeObject python_screenshot_data_type = {
464  PyVarObject_HEAD_INIT(NULL, 0)
465  .tp_name = "remmina.RemminaScreenshotData",
466  .tp_doc = "Remmina Screenshot Data",
467  .tp_basicsize = sizeof(PyRemminaPluginScreenshotData),
468  .tp_itemsize = 0,
469  .tp_flags = Py_TPFLAGS_DEFAULT,
470  .tp_new = python_screenshot_data_new,
471  .tp_init = (initproc)python_screenshot_data_init,
472  .tp_members = python_screenshot_data_members
473 };
475 {
477  data->buffer = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
478  Py_IncRef((PyObject*)data->buffer);
479  data->height = 0;
480  data->width = 0;
481  data->bitsPerPixel = 0;
482  data->bytesPerPixel = 0;
483  return data;
484 }
485 
486 static PyObject* python_wrapper_generic_to_int(PyGeneric* self, PyObject* args);
487 static PyObject* python_wrapper_generic_to_bool(PyGeneric* self, PyObject* args);
488 static PyObject* python_wrapper_generic_to_string(PyGeneric* self, PyObject* args);
489 
490 static void python_wrapper_generic_dealloc(PyObject* self)
491 {
492  PyObject_Del(self);
493 }
494 
495 static PyMethodDef python_wrapper_generic_methods[] = {
496  { "to_int", (PyCFunction)python_wrapper_generic_to_int, METH_NOARGS, "" },
497  { "to_bool", (PyCFunction)python_wrapper_generic_to_bool, METH_NOARGS, "" },
498  { "to_string", (PyCFunction)python_wrapper_generic_to_string, METH_NOARGS, "" },
499  { NULL }
500 };
501 
502 static PyMemberDef python_wrapper_generic_members[] = {
503  { "raw", T_OBJECT, offsetof(PyGeneric, raw), 0, "" },
504  { NULL }
505 };
506 
507 PyObject* python_wrapper_generic_type_new(PyTypeObject* type, PyObject* kws, PyObject* args)
508 {
509  TRACE_CALL(__func__);
510 
511  PyGeneric* self;
512  self = (PyGeneric*)type->tp_alloc(type, 0);
513  if (!self)
514  return NULL;
515 
516  self->raw = Py_None;
517 
518  return (PyObject*)self;
519 }
520 
521 static int python_wrapper_generic_init(PyGeneric* self, PyObject* args, PyObject* kwargs)
522 {
523  TRACE_CALL(__func__);
524 
525  static char* kwlist[] = { "raw", NULL };
526 
527  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &self->raw))
528  return -1;
529 
530  return 0;
531 }
532 
533 static PyTypeObject python_generic_type = {
534  PyVarObject_HEAD_INIT(NULL, 0)
535  .tp_name = "remmina.Generic",
536  .tp_doc = "",
537  .tp_basicsize = sizeof(PyGeneric),
538  .tp_itemsize = 0,
539  .tp_dealloc = python_wrapper_generic_dealloc,
540  .tp_flags = Py_TPFLAGS_DEFAULT,
542  .tp_init = (initproc)python_wrapper_generic_init,
543  .tp_members = python_wrapper_generic_members,
544  .tp_methods = python_wrapper_generic_methods,
545 };
546 
548 {
549  PyGeneric* generic = (PyGeneric*)PyObject_New(PyGeneric, &python_generic_type);
550  generic->raw = PyLong_FromLongLong(0LL);
551  Py_IncRef((PyObject*)generic);
552  return generic;
553 }
554 
555 static PyObject* python_wrapper_generic_to_int(PyGeneric* self, PyObject* args)
556 {
557  SELF_CHECK();
558 
559  if (self->raw == NULL)
560  {
561  return Py_None;
562  }
563  else if (self->type_hint == REMMINA_TYPEHINT_SIGNED)
564  {
565  return PyLong_FromLongLong((long long)self->raw);
566  }
567  else if (self->type_hint == REMMINA_TYPEHINT_UNSIGNED)
568  {
569  return PyLong_FromUnsignedLongLong((unsigned long long)self->raw);
570  }
571 
572  return Py_None;
573 }
574 static PyObject* python_wrapper_generic_to_bool(PyGeneric* self, PyObject* args)
575 {
576  SELF_CHECK();
577 
578  if (self->raw == NULL)
579  {
580  return Py_None;
581  }
582  else if (self->type_hint == REMMINA_TYPEHINT_BOOLEAN)
583  {
584  return PyBool_FromLong((long)self->raw);
585  }
586 
587  return Py_None;
588 }
589 static PyObject* python_wrapper_generic_to_string(PyGeneric* self, PyObject* args)
590 {
591  SELF_CHECK();
592 
593  if (self->raw == NULL)
594  {
595  return Py_None;
596  }
597  else if (self->type_hint == REMMINA_TYPEHINT_STRING)
598  {
599  return PyUnicode_FromString((const char*)self->raw);
600  }
601 
602  return Py_None;
603 }
604 
610 {
611  TRACE_CALL(__func__);
612 
613  if (PyType_Ready(&python_screenshot_data_type) < 0)
614  {
615  PyErr_Print();
616  return NULL;
617  }
618 
619  if (PyType_Ready(&python_generic_type) < 0)
620  {
621  PyErr_Print();
622  return NULL;
623  }
624 
625  if (PyType_Ready(&python_protocol_setting_type) < 0)
626  {
627  PyErr_Print();
628  return NULL;
629  }
630 
631  if (PyType_Ready(&python_protocol_feature_type) < 0)
632  {
633  PyErr_Print();
634  return NULL;
635  }
636 
639 
640  PyObject* module = PyModule_Create(&remmina_python_module_type);
641  if (!module)
642  {
643  PyErr_Print();
644  return NULL;
645  }
646 
647  PyModule_AddIntConstant(module, "BUTTONS_CLOSE", (long)GTK_BUTTONS_CLOSE);
648  PyModule_AddIntConstant(module, "BUTTONS_NONE", (long)GTK_BUTTONS_NONE);
649  PyModule_AddIntConstant(module, "BUTTONS_OK", (long)GTK_BUTTONS_OK);
650  PyModule_AddIntConstant(module, "BUTTONS_CLOSE", (long)GTK_BUTTONS_CLOSE);
651  PyModule_AddIntConstant(module, "BUTTONS_CANCEL", (long)GTK_BUTTONS_CANCEL);
652  PyModule_AddIntConstant(module, "BUTTONS_YES_NO", (long)GTK_BUTTONS_YES_NO);
653  PyModule_AddIntConstant(module, "BUTTONS_OK_CANCEL", (long)GTK_BUTTONS_OK_CANCEL);
654 
655  PyModule_AddIntConstant(module, "MESSAGE_INFO", (long)GTK_MESSAGE_INFO);
656  PyModule_AddIntConstant(module, "MESSAGE_WARNING", (long)GTK_MESSAGE_WARNING);
657  PyModule_AddIntConstant(module, "MESSAGE_QUESTION", (long)GTK_MESSAGE_QUESTION);
658  PyModule_AddIntConstant(module, "MESSAGE_ERROR", (long)GTK_MESSAGE_ERROR);
659  PyModule_AddIntConstant(module, "MESSAGE_OTHER", (long)GTK_MESSAGE_OTHER);
660 
661  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_SERVER", (long)REMMINA_PROTOCOL_SETTING_TYPE_SERVER);
662  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_PASSWORD", (long)REMMINA_PROTOCOL_SETTING_TYPE_PASSWORD);
663  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_RESOLUTION", (long)REMMINA_PROTOCOL_SETTING_TYPE_RESOLUTION);
664  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_ASSISTANCE", (long)REMMINA_PROTOCOL_SETTING_TYPE_ASSISTANCE);
665  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_KEYMAP", (long)REMMINA_PROTOCOL_SETTING_TYPE_KEYMAP);
666  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_TEXT", (long)REMMINA_PROTOCOL_SETTING_TYPE_TEXT);
667  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_SELECT", (long)REMMINA_PROTOCOL_SETTING_TYPE_SELECT);
668  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_COMBO", (long)REMMINA_PROTOCOL_SETTING_TYPE_COMBO);
669  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_CHECK", (long)REMMINA_PROTOCOL_SETTING_TYPE_CHECK);
670  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_FILE", (long)REMMINA_PROTOCOL_SETTING_TYPE_FILE);
671  PyModule_AddIntConstant(module, "PROTOCOL_SETTING_TYPE_FOLDER", (long)REMMINA_PROTOCOL_SETTING_TYPE_FOLDER);
672  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_MULTIMON", (long)REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON);
673 
674  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_PREF", (long)REMMINA_PROTOCOL_FEATURE_TYPE_PREF);
675  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_TOOL", (long)REMMINA_PROTOCOL_FEATURE_TYPE_TOOL);
676  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_UNFOCUS", (long)REMMINA_PROTOCOL_FEATURE_TYPE_UNFOCUS);
677  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_SCALE", (long)REMMINA_PROTOCOL_FEATURE_TYPE_SCALE);
678  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_DYNRESUPDATE", (long)REMMINA_PROTOCOL_FEATURE_TYPE_DYNRESUPDATE);
679  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_TYPE_GTKSOCKET", (long)REMMINA_PROTOCOL_FEATURE_TYPE_GTKSOCKET);
680 
681  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_NONE", (long)REMMINA_PROTOCOL_SSH_SETTING_NONE);
682  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_TUNNEL", (long)REMMINA_PROTOCOL_SSH_SETTING_TUNNEL);
683  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_SSH", (long)REMMINA_PROTOCOL_SSH_SETTING_SSH);
684  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_REVERSE_TUNNEL", (long)REMMINA_PROTOCOL_SSH_SETTING_REVERSE_TUNNEL);
685  PyModule_AddIntConstant(module, "PROTOCOL_SSH_SETTING_SFTP", (long)REMMINA_PROTOCOL_SSH_SETTING_SFTP);
686 
687  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_PREF_RADIO", (long)REMMINA_PROTOCOL_FEATURE_PREF_RADIO);
688  PyModule_AddIntConstant(module, "PROTOCOL_FEATURE_PREF_CHECK", (long)REMMINA_PROTOCOL_FEATURE_PREF_CHECK);
689 
690  PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_USERNAME", REMMINA_MESSAGE_PANEL_FLAG_USERNAME);
691  PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_USERNAME_READONLY", REMMINA_MESSAGE_PANEL_FLAG_USERNAME_READONLY);
692  PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_DOMAIN", REMMINA_MESSAGE_PANEL_FLAG_DOMAIN);
693  PyModule_AddIntConstant(module, "MESSAGE_PANEL_FLAG_SAVEPASSWORD", REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD);
694 
695  if (PyModule_AddObject(module, "Setting", (PyObject*)&python_protocol_setting_type) < 0)
696  {
697  Py_DECREF(&python_protocol_setting_type);
698  Py_DECREF(module);
699  PyErr_Print();
700  return NULL;
701  }
702 
703  Py_INCREF(&python_protocol_feature_type);
704  if (PyModule_AddObject(module, "Feature", (PyObject*)&python_protocol_feature_type) < 0)
705  {
706  Py_DECREF(&python_protocol_setting_type);
707  Py_DECREF(&python_protocol_feature_type);
708  Py_DECREF(module);
709  PyErr_Print();
710  return NULL;
711  }
712 
713  return module;
714 }
715 
721 {
722  TRACE_CALL(__func__);
723 
724  if (PyImport_AppendInittab("remmina", python_wrapper_module_initialize))
725  {
726  PyErr_Print();
727  exit(1);
728  }
729 
736 }
737 
738 gboolean python_wrapper_check_mandatory_member(PyObject* instance, const gchar* member)
739 {
740  TRACE_CALL(__func__);
741 
742  if (PyObject_HasAttrString(instance, member))
743  {
744  return TRUE;
745  }
746 
747  g_printerr("Missing mandatory member '%s' in Python plugin instance!\n", member);
748  return FALSE;
749 }
750 
751 static PyObject* remmina_register_plugin_wrapper(PyObject* self, PyObject* plugin_instance)
752 {
753  TRACE_CALL(__func__);
754 
755  if (plugin_instance)
756  {
757  if (!python_wrapper_check_mandatory_member(plugin_instance, "name")
758  || !python_wrapper_check_mandatory_member(plugin_instance, "version"))
759  {
760  return NULL;
761  }
762 
763  /* Protocol plugin definition and features */
764  const gchar* pluginType = PyUnicode_AsUTF8(PyObject_GetAttrString(plugin_instance, "type"));
765 
767 
768  PyPlugin* plugin = (PyPlugin*)python_wrapper_malloc(sizeof(PyPlugin));
769  plugin->instance = plugin_instance;
770  Py_INCREF(plugin_instance);
771  plugin->protocol_plugin = NULL;
772  plugin->entry_plugin = NULL;
773  plugin->file_plugin = NULL;
774  plugin->pref_plugin = NULL;
775  plugin->secret_plugin = NULL;
776  plugin->tool_plugin = NULL;
777  g_print("New Python plugin registered: %ld\n", PyObject_Hash(plugin_instance));
778 
779  if (g_str_equal(pluginType, "protocol"))
780  {
781  remmina_plugin = python_wrapper_create_protocol_plugin(plugin);
782  }
783  else if (g_str_equal(pluginType, "entry"))
784  {
785  remmina_plugin = python_wrapper_create_entry_plugin(plugin);
786  }
787  else if (g_str_equal(pluginType, "file"))
788  {
789  remmina_plugin = python_wrapper_create_file_plugin(plugin);
790  }
791  else if (g_str_equal(pluginType, "tool"))
792  {
793  remmina_plugin = python_wrapper_create_tool_plugin(plugin);
794  }
795  else if (g_str_equal(pluginType, "pref"))
796  {
797  remmina_plugin = python_wrapper_create_pref_plugin(plugin);
798  }
799  else if (g_str_equal(pluginType, "secret"))
800  {
801  remmina_plugin = python_wrapper_create_secret_plugin(plugin);
802  }
803  else
804  {
805  g_printerr("Unknown plugin type: %s\n", pluginType);
806  }
807 
808  if (remmina_plugin)
809  {
810  if (remmina_plugin->type == REMMINA_PLUGIN_TYPE_PROTOCOL)
811  {
813  }
814 
815  if (python_wrapper_get_service()->register_plugin((RemminaPlugin*)remmina_plugin)) {
816  g_print("%s: Successfully reigstered!\n", remmina_plugin->name);
817  } else {
818  g_print("%s: Failed to reigster!\n", remmina_plugin->name);
819  }
820  }
821  }
822 
823  PyErr_Clear();
824  return Py_None;
825 }
826 
827 static PyObject* remmina_file_get_datadir_wrapper(PyObject* self, PyObject* plugin)
828 {
829  TRACE_CALL(__func__);
830 
831  PyObject* result = Py_None;
832  const gchar* datadir = python_wrapper_get_service()->file_get_user_datadir();
833 
834  if (datadir)
835  {
836  result = PyUnicode_FromFormat("%s", datadir);
837  }
838 
840  return result;
841 }
842 
843 static PyObject* remmina_file_new_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
844 {
845  TRACE_CALL(__func__);
846 
848  if (file)
849  {
850  return (PyObject*)python_wrapper_remmina_file_to_python(file);
851  }
852 
854  return Py_None;
855 }
856 
857 static PyObject* remmina_pref_set_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
858 {
859  TRACE_CALL(__func__);
860 
861  static char* kwlist[] = { "key", "value", NULL };
862  gchar* key, * value;
863 
864  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &key, &value))
865  {
866  return Py_None;
867  }
868 
869  if (key)
870  {
872  }
873 
875  return Py_None;
876 }
877 
878 static PyObject* remmina_pref_get_value_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
879 {
880  TRACE_CALL(__func__);
881 
882  static char* kwlist[] = { "key", NULL };
883  gchar* key;
884  PyObject* result = Py_None;
885 
886  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &key))
887  {
888  return Py_None;
889  }
890 
891  if (key)
892  {
893  const gchar* value = python_wrapper_get_service()->pref_get_value(key);
894  if (value)
895  {
896  result = PyUnicode_FromFormat("%s", value);
897  }
898  }
899 
901  return result;
902 }
903 
904 static PyObject* remmina_pref_get_scale_quality_wrapper(PyObject* self, PyObject* plugin)
905 {
906  TRACE_CALL(__func__);
907 
908  PyObject* result = PyLong_FromLong(python_wrapper_get_service()->pref_get_scale_quality());
910  return result;
911 }
912 
913 static PyObject* remmina_pref_get_sshtunnel_port_wrapper(PyObject* self, PyObject* plugin)
914 {
915  TRACE_CALL(__func__);
916 
917  PyObject* result = PyLong_FromLong(python_wrapper_get_service()->pref_get_sshtunnel_port());
919  return result;
920 }
921 
922 static PyObject* remmina_pref_get_ssh_loglevel_wrapper(PyObject* self, PyObject* plugin)
923 {
924  TRACE_CALL(__func__);
925 
926  PyObject* result = PyLong_FromLong(python_wrapper_get_service()->pref_get_ssh_loglevel());
928  return result;
929 }
930 
931 static PyObject* remmina_pref_get_ssh_parseconfig_wrapper(PyObject* self, PyObject* plugin)
932 {
933  TRACE_CALL(__func__);
934 
935  PyObject* result = PyLong_FromLong(python_wrapper_get_service()->pref_get_ssh_parseconfig());
937  return result;
938 }
939 
940 static PyObject* remmina_pref_keymap_get_keyval_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
941 {
942  TRACE_CALL(__func__);
943 
944  static char* kwlist[] = { "keymap", "keyval", NULL };
945  gchar* keymap;
946  guint keyval;
947  PyObject* result = Py_None;
948 
949  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sl", kwlist, &keymap, &keyval))
950  {
951  return PyLong_FromLong(-1);
952  }
953 
954  if (keymap)
955  {
956  const guint value = python_wrapper_get_service()->pref_keymap_get_keyval(keymap, keyval);
957  result = PyLong_FromUnsignedLong(value);
958  }
959 
961  return result;
962 }
963 
964 static PyObject* python_wrapper_log_print_wrapper(PyObject* self, PyObject* args)
965 {
966  TRACE_CALL(__func__);
967 
968  gchar* text;
969  if (!PyArg_ParseTuple(args, "s", &text) || !text)
970  {
971  return Py_None;
972  }
973 
975  return Py_None;
976 }
977 
978 static PyObject* python_wrapper_debug_wrapper(PyObject* self, PyObject* args)
979 {
980  TRACE_CALL(__func__);
981 
982  gchar* text;
983  if (!PyArg_ParseTuple(args, "s", &text) || !text)
984  {
985  return Py_None;
986  }
987 
988  python_wrapper_get_service()->_remmina_debug("python", "%s", text);
989  return Py_None;
990 }
991 
992 static PyObject* remmina_widget_pool_register_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
993 {
994  TRACE_CALL(__func__);
995 
996  static char* kwlist[] = { "widget", NULL };
997  PyObject* widget;
998 
999  if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &widget) && widget)
1000  {
1002  }
1003 
1004  return Py_None;
1005 }
1006 
1007 static PyObject* rcw_open_from_file_full_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1008 {
1009  TRACE_CALL(__func__);
1010 
1011  static char* kwlist[] = { "remminafile", "data", "handler", NULL };
1012  PyObject* pyremminafile;
1013  PyObject* data;
1014 
1015  if (PyArg_ParseTupleAndKeywords(args, kwargs, "OOO", kwlist, &pyremminafile, &data) && pyremminafile && data)
1016  {
1017  python_wrapper_get_service()->rcw_open_from_file_full((RemminaFile*)pyremminafile, NULL, (void*)data, NULL);
1018  }
1019 
1020  return Py_None;
1021 }
1022 
1023 static PyObject* remmina_public_get_server_port_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1024 {
1025  TRACE_CALL(__func__);
1026 
1027  static char* kwlist[] = { "server", "defaultport", NULL };
1028  gchar* server;
1029  gint defaultport;
1030 
1031  if (PyArg_ParseTupleAndKeywords(args, kwargs, "sl", kwlist, &server, &defaultport) && server)
1032  {
1033  gchar* host;
1034  gint port;
1035  python_wrapper_get_service()->get_server_port(server, defaultport, &host, &port);
1036 
1037  PyObject* result = PyList_New(2);
1038  PyList_SetItem(result, 0, PyUnicode_FromString(host));
1039  PyList_SetItem(result, 1, PyLong_FromLong(port));
1040 
1041  return PyList_AsTuple(result);
1042  }
1043 
1044  return Py_None;
1045 }
1046 
1047 static PyObject* remmina_masterthread_exec_is_main_thread_wrapper(PyObject* self, PyObject* plugin)
1048 {
1049  TRACE_CALL(__func__);
1050 
1051  return PyBool_FromLong(python_wrapper_get_service()->is_main_thread());
1052 }
1053 
1054 static PyObject* remmina_gtksocket_available_wrapper(PyObject* self, PyObject* plugin)
1055 {
1056  TRACE_CALL(__func__);
1057 
1058  return PyBool_FromLong(python_wrapper_get_service()->gtksocket_available());
1059 }
1060 
1061 static PyObject*
1062 remmina_protocol_widget_get_profile_remote_height_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1063 {
1064  TRACE_CALL(__func__);
1065 
1066  static char* kwlist[] = { "widget", NULL };
1067  PyPlugin* plugin;
1068 
1069  if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &plugin) && plugin && plugin->gp)
1070  {
1072  }
1073 
1074  return Py_None;
1075 }
1076 
1077 static PyObject*
1078 remmina_protocol_widget_get_profile_remote_width_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1079 {
1080  TRACE_CALL(__func__);
1081 
1082  static char* kwlist[] = { "widget", NULL };
1083  PyPlugin* plugin;
1084 
1085  if (PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &plugin) && plugin && plugin->gp)
1086  {
1088  }
1089 
1090  return Py_None;
1091 }
1092 
1094 {
1095  TRACE_CALL(__func__);
1096 
1098  Py_INCREF(setting);
1099  dest->name = src->name;
1100  dest->label = src->label;
1101  dest->compact = src->compact;
1102  dest->type = src->settingType;
1103  dest->validator = NULL;
1104  dest->validator_data = NULL;
1105  python_wrapper_to_generic(src->opt1, &dest->opt1);
1106  python_wrapper_to_generic(src->opt2, &dest->opt2);
1107 }
1108 
1110 {
1111  TRACE_CALL(__func__);
1112 
1114  Py_INCREF(feature);
1115  dest->id = src->id;
1116  dest->type = src->type;
1117  dest->opt1 = src->opt1->raw;
1118  dest->opt1_type_hint = src->opt1->type_hint;
1119  dest->opt2 = src->opt2->raw;
1120  dest->opt2_type_hint = src->opt2->type_hint;
1121  dest->opt3 = src->opt3->raw;
1122  dest->opt3_type_hint = src->opt3->type_hint;
1123 }
1124 
1125 PyObject* python_wrapper_show_dialog_wrapper(PyObject* self, PyObject* args, PyObject* kwargs)
1126 {
1127  TRACE_CALL(__func__);
1128 
1129  static char* kwlist[] = { "type", "buttons", "message", NULL };
1130  GtkMessageType msgType;
1131  GtkButtonsType btnType;
1132  gchar* message;
1133 
1134  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "lls", kwlist, &msgType, &btnType, &message))
1135  {
1136  return PyLong_FromLong(-1);
1137  }
1138 
1139  python_wrapper_get_service()->show_dialog(msgType, btnType, message);
1140 
1141  return Py_None;
1142 }
1143 
1144 PyObject* python_wrapper_get_mainwindow_wrapper(PyObject* self, PyObject* args)
1145 {
1146  TRACE_CALL(__func__);
1147 
1148  GtkWindow* result = python_wrapper_get_service()->get_window();
1149 
1150  if (!result)
1151  {
1152  return Py_None;
1153  }
1154 
1155  return (PyObject*)new_pywidget((GObject*)result);
1156 }
1157 
1158 static PyObject* remmina_protocol_plugin_signal_connection_closed_wrapper(PyObject* self, PyObject* args)
1159 {
1160  TRACE_CALL(__func__);
1161 
1162  PyObject* pygp = NULL;
1163  if (!PyArg_ParseTuple(args, "O", &pygp) || !pygp)
1164  {
1165  g_printerr("Please provide the Remmina protocol widget instance!");
1166  return Py_None;
1167  }
1168 
1170  return Py_None;
1171 }
1172 
1173 static PyObject* remmina_protocol_plugin_init_auth_wrapper(PyObject* module, PyObject* args, PyObject* kwds)
1174 {
1175  TRACE_CALL(__func__);
1176 
1177  static gchar* keyword_list[] = { "widget", "flags", "title", "default_username", "default_password",
1178  "default_domain", "password_prompt" };
1179 
1181  gint pflags = 0;
1182  gchar* title, * default_username, * default_password, * default_domain, * password_prompt;
1183 
1184  if (PyArg_ParseTupleAndKeywords(args, kwds, "Oisssss", keyword_list, &self, &pflags, &title, &default_username,
1185  &default_password, &default_domain, &password_prompt))
1186  {
1187  if (pflags != 0 && !(pflags & REMMINA_MESSAGE_PANEL_FLAG_USERNAME)
1189  && !(pflags & REMMINA_MESSAGE_PANEL_FLAG_DOMAIN)
1191  {
1192  g_printerr("panel_auth(pflags, title, default_username, default_password, default_domain, password_prompt): "
1193  "%d is not a known value for RemminaMessagePanelFlags!\n", pflags);
1194  }
1195  else
1196  {
1197  return Py_BuildValue("i", python_wrapper_get_service()->protocol_widget_panel_auth(self
1198  ->gp, pflags, title, default_username, default_password, default_domain, password_prompt));
1199  }
1200  }
1201  else
1202  {
1203  g_printerr("panel_auth(pflags, title, default_username, default_password, default_domain, password_prompt): Error parsing arguments!\n");
1204  PyErr_Print();
1205  }
1206  return Py_None;
1207 }
1208 
1209 static PyObject* remmina_protocol_plugin_signal_connection_opened_wrapper(PyObject* self, PyObject* args)
1210 {
1211  PyObject* pygp = NULL;
1212  if (!PyArg_ParseTuple(args, "O", &pygp) || !pygp)
1213  {
1214  g_printerr("Please provide the Remmina protocol widget instance!");
1215  return Py_None;
1216  }
1217 
1219  return Py_None;
1220 }
static PyObject * remmina_register_plugin_wrapper(PyObject *self, PyObject *plugin)
static PyObject * remmina_file_new_wrapper(PyObject *self, PyObject *args, PyObject *kwargs)
-- cgit v1.2.3