/* * Copyright (C) 2006-2015 Juan Pablo Ugarte. * * 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. * * Authors: * Juan Pablo Ugarte */ #include #include #include #include #if PY_MAJOR_VERSION >= 3 #define WCHAR(str) L##str #define PY_STRING(str) WCHAR(str) #define STRING_FROM_PYSTR(pstr) PyUnicode_AsUTF8 (pstr) #else /* include bytesobject.h to map PyBytes_* to PyString_* */ #include #define PY_STRING(str) str #define STRING_FROM_PYSTR(pstr) PyBytes_AsString (pstr) #endif static void python_init (void) { if (Py_IsInitialized ()) return; Py_InitializeEx (0); /* if argc is 0 an empty string is prepended to sys.path */ PySys_SetArgvEx (0, NULL, 0); } static void glade_python_init_pygobject_check (gint req_major, gint req_minor, gint req_micro) { PyObject *gi, *gobject; /* import gobject */ pygobject_init (req_major, req_minor, req_micro); if (PyErr_Occurred ()) { g_warning ("Error initializing Python interpreter: could not " "import pygobject"); return; } gi = PyImport_ImportModule ("gi"); if (gi == NULL) { g_warning ("Error initializing Python interpreter: could not " "import gi"); return; } gobject = PyImport_ImportModule ("gi.repository.GObject"); if (gobject == NULL) { g_warning ("Error initializing Python interpreter: could not " "import gobject"); return; } } static gboolean glade_python_setup () { GString *command; const gchar *module_path; const GList *paths; Py_SetProgramName (PY_STRING (PACKAGE_NAME)); /* Initialize the Python interpreter */ python_init (); /* Check and init pygobject */ PyErr_Clear (); glade_python_init_pygobject_check (PYGOBJECT_REQUIRED_MAJOR, PYGOBJECT_REQUIRED_MINOR, PYGOBJECT_REQUIRED_MICRO); if (PyErr_Occurred ()) { PyObject *ptype, *pvalue, *ptraceback, *pstr; char *pvalue_char = ""; PyErr_Fetch (&ptype, &pvalue, &ptraceback); PyErr_NormalizeException (&ptype, &pvalue, &ptraceback); if ((pstr = PyObject_Str (pvalue))) pvalue_char = STRING_FROM_PYSTR (pstr); g_warning ("Unable to load pygobject module >= %d.%d.%d, " "please make sure it is in python's path (sys.path). " "(use PYTHONPATH env variable to specify non default paths)\n%s", PYGOBJECT_REQUIRED_MAJOR, PYGOBJECT_REQUIRED_MINOR, PYGOBJECT_REQUIRED_MICRO, pvalue_char); Py_DecRef (ptype); Py_DecRef (pvalue); Py_DecRef (ptraceback); Py_DecRef (pstr); PyErr_Clear (); Py_Finalize (); return TRUE; } pyg_disable_warning_redirections (); /* Generate system path array */ command = g_string_new ("import sys; sys.path+=["); /* GLADE_ENV_MODULE_PATH has priority */ module_path = g_getenv (GLADE_ENV_MODULE_PATH); if (module_path) g_string_append_printf (command, "'%s', ", module_path); /* Append modules directory */ g_string_append_printf (command, "'%s'", glade_app_get_modules_dir ()); /* Append extra paths (declared in the Preferences) */ for (paths = glade_catalog_get_extra_paths (); paths; paths = g_list_next (paths)) g_string_append_printf (command, ", '%s'", (gchar *) paths->data); /* Close python statement */ g_string_append (command, "];\n"); /* Make sure we load Gtk 3 */ g_string_append (command, "import gi; gi.require_version('Gtk', '3.0');\n"); /* Finally run statement in vm */ PyRun_SimpleString (command->str); g_string_free (command, TRUE); return FALSE; } void glade_python_init (const gchar *name) { static gsize init = 0; gchar *import_sentence; if (g_once_init_enter (&init)) { if (glade_python_setup ()) return; g_once_init_leave (&init, TRUE); } /* Yeah, we use the catalog name as the library */ import_sentence = g_strdup_printf ("import %s;", name); /* Importing the module will create all the GTypes so that glade can use them at runtime */ PyRun_SimpleString (import_sentence); g_free (import_sentence); }