|
Packit |
1e8aac |
/*
|
|
Packit |
1e8aac |
* Copyright (C) 2006-2015 Juan Pablo Ugarte.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
1e8aac |
* it under the terms of the GNU General Public License as
|
|
Packit |
1e8aac |
* published by the Free Software Foundation; either version 2 of the
|
|
Packit |
1e8aac |
* License, or (at your option) any later version.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
1e8aac |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
1e8aac |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
1e8aac |
* GNU General Public License for more details.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* You should have received a copy of the GNU General Public License
|
|
Packit |
1e8aac |
* along with this program; if not, write to the Free Software
|
|
Packit |
1e8aac |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Authors:
|
|
Packit |
1e8aac |
* Juan Pablo Ugarte <juanpablougarte@gmail.com>
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <config.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <Python.h>
|
|
Packit |
1e8aac |
#include <pygobject.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <gladeui/glade.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#if PY_MAJOR_VERSION >= 3
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define WCHAR(str) L##str
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define PY_STRING(str) WCHAR(str)
|
|
Packit |
1e8aac |
#define STRING_FROM_PYSTR(pstr) PyUnicode_AsUTF8 (pstr)
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#else
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* include bytesobject.h to map PyBytes_* to PyString_* */
|
|
Packit |
1e8aac |
#include <bytesobject.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define PY_STRING(str) str
|
|
Packit |
1e8aac |
#define STRING_FROM_PYSTR(pstr) PyBytes_AsString (pstr)
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#endif
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
python_init (void)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (Py_IsInitialized ())
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
Py_InitializeEx (0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* if argc is 0 an empty string is prepended to sys.path */
|
|
Packit |
1e8aac |
PySys_SetArgvEx (0, NULL, 0);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_python_init_pygobject_check (gint req_major, gint req_minor, gint req_micro)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
PyObject *gi, *gobject;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* import gobject */
|
|
Packit |
1e8aac |
pygobject_init (req_major, req_minor, req_micro);
|
|
Packit |
1e8aac |
if (PyErr_Occurred ())
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning ("Error initializing Python interpreter: could not "
|
|
Packit |
1e8aac |
"import pygobject");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gi = PyImport_ImportModule ("gi");
|
|
Packit |
1e8aac |
if (gi == NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning ("Error initializing Python interpreter: could not "
|
|
Packit |
1e8aac |
"import gi");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gobject = PyImport_ImportModule ("gi.repository.GObject");
|
|
Packit |
1e8aac |
if (gobject == NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning ("Error initializing Python interpreter: could not "
|
|
Packit |
1e8aac |
"import gobject");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_python_setup ()
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GString *command;
|
|
Packit |
1e8aac |
const gchar *module_path;
|
|
Packit |
1e8aac |
const GList *paths;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
Py_SetProgramName (PY_STRING (PACKAGE_NAME));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Initialize the Python interpreter */
|
|
Packit |
1e8aac |
python_init ();
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Check and init pygobject */
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
PyErr_Clear ();
|
|
Packit |
1e8aac |
glade_python_init_pygobject_check (PYGOBJECT_REQUIRED_MAJOR,
|
|
Packit |
1e8aac |
PYGOBJECT_REQUIRED_MINOR,
|
|
Packit |
1e8aac |
PYGOBJECT_REQUIRED_MICRO);
|
|
Packit |
1e8aac |
if (PyErr_Occurred ())
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
PyObject *ptype, *pvalue, *ptraceback, *pstr;
|
|
Packit |
1e8aac |
char *pvalue_char = "";
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
PyErr_Fetch (&ptype, &pvalue, &ptraceback);
|
|
Packit |
1e8aac |
PyErr_NormalizeException (&ptype, &pvalue, &ptraceback);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((pstr = PyObject_Str (pvalue)))
|
|
Packit |
1e8aac |
pvalue_char = STRING_FROM_PYSTR (pstr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_warning ("Unable to load pygobject module >= %d.%d.%d, "
|
|
Packit |
1e8aac |
"please make sure it is in python's path (sys.path). "
|
|
Packit |
1e8aac |
"(use PYTHONPATH env variable to specify non default paths)\n%s",
|
|
Packit |
1e8aac |
PYGOBJECT_REQUIRED_MAJOR, PYGOBJECT_REQUIRED_MINOR,
|
|
Packit |
1e8aac |
PYGOBJECT_REQUIRED_MICRO, pvalue_char);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
Py_DecRef (ptype);
|
|
Packit |
1e8aac |
Py_DecRef (pvalue);
|
|
Packit |
1e8aac |
Py_DecRef (ptraceback);
|
|
Packit |
1e8aac |
Py_DecRef (pstr);
|
|
Packit |
1e8aac |
PyErr_Clear ();
|
|
Packit |
1e8aac |
Py_Finalize ();
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
pyg_disable_warning_redirections ();
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Generate system path array */
|
|
Packit |
1e8aac |
command = g_string_new ("import sys; sys.path+=[");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* GLADE_ENV_MODULE_PATH has priority */
|
|
Packit |
1e8aac |
module_path = g_getenv (GLADE_ENV_MODULE_PATH);
|
|
Packit |
1e8aac |
if (module_path)
|
|
Packit |
1e8aac |
g_string_append_printf (command, "'%s', ", module_path);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Append modules directory */
|
|
Packit |
1e8aac |
g_string_append_printf (command, "'%s'", glade_app_get_modules_dir ());
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Append extra paths (declared in the Preferences) */
|
|
Packit |
1e8aac |
for (paths = glade_catalog_get_extra_paths (); paths; paths = g_list_next (paths))
|
|
Packit |
1e8aac |
g_string_append_printf (command, ", '%s'", (gchar *) paths->data);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Close python statement */
|
|
Packit |
1e8aac |
g_string_append (command, "];\n");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Make sure we load Gtk 3 */
|
|
Packit |
1e8aac |
g_string_append (command, "import gi; gi.require_version('Gtk', '3.0');\n");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Finally run statement in vm */
|
|
Packit |
1e8aac |
PyRun_SimpleString (command->str);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_string_free (command, TRUE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_python_init (const gchar *name)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
static gsize init = 0;
|
|
Packit |
1e8aac |
gchar *import_sentence;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_once_init_enter (&init))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (glade_python_setup ())
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_once_init_leave (&init, TRUE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Yeah, we use the catalog name as the library */
|
|
Packit |
1e8aac |
import_sentence = g_strdup_printf ("import %s;", name);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Importing the module will create all the GTypes so that glade can use them at runtime */
|
|
Packit |
1e8aac |
PyRun_SimpleString (import_sentence);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (import_sentence);
|
|
Packit |
1e8aac |
}
|