changeset 21800:73aab5bdd830

Allow loading python scripts at runtime. Things can go wrong if a script starts its own mainloop, or blocks on something. For now, a script can check for a positive return value from 'gobject.main_depth()' to determine that it's being loaded at runtime, and not start its own mainloop.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sun, 09 Dec 2007 00:56:29 +0000
parents f14da598bffe
children 3265e4619117
files configure.ac finch/libgnt/Makefile.am finch/libgnt/configure.ac finch/libgnt/gntwm.c
diffstat 4 files changed, 114 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Fri Dec 07 22:14:23 2007 +0000
+++ b/configure.ac	Sun Dec 09 00:56:29 2007 +0000
@@ -1336,6 +1336,34 @@
 
 AM_CONDITIONAL(ENABLE_DBUS, test "x$enable_dbus" = "xyes")
 
+dnl Check for Python headers (currently useful only for libgnt)
+dnl (Thanks to XChat)
+AC_PATH_PROG(pythonpath, python)
+if test "_$pythonpath" != _ ; then
+	AC_MSG_CHECKING(for Python compile flags)
+	PY_PREFIX=`$pythonpath -c 'import sys ; print sys.prefix'`
+	PY_EXEC_PREFIX=`$pythonpath -c 'import sys ; print sys.exec_prefix'`
+	changequote(<<, >>)dnl
+	PY_VERSION=`$pythonpath -c 'import sys ; print sys.version[0:3]'`
+	PY_MAJOR=`$pythonpath -c 'import sys ; print sys.version[0:2]'`
+	changequote([, ])dnl
+	if test -f $PY_PREFIX/include/python$PY_VERSION/Python.h -a "$PY_MAJOR" = "2."; then
+		AC_CHECK_LIB(pthread, pthread_create, )
+		AC_CHECK_LIB(util, openpty, )
+		AC_CHECK_LIB(db, dbopen, )
+		PY_LIBS="-lpython$PY_VERSION -L$PY_EXEC_PREFIX/lib/python$PY_VERSION/config"
+		PY_CFLAGS="-I$PY_PREFIX/include/python$PY_VERSION"
+		AC_DEFINE(USE_PYTHON, [1], [Define if python headers are available.])
+		AC_MSG_RESULT(ok)
+	else
+		AC_MSG_RESULT([Can't find Python.h])
+		PY_LIBS=""
+		PY_CFLAGS=""
+	fi
+fi
+AC_SUBST(PY_CFLAGS)
+AC_SUBST(PY_LIBS)
+
 dnl #######################################################################
 dnl # Check for Mono support
 dnl #######################################################################
--- a/finch/libgnt/Makefile.am	Fri Dec 07 22:14:23 2007 +0000
+++ b/finch/libgnt/Makefile.am	Sun Dec 09 00:56:29 2007 +0000
@@ -84,10 +84,12 @@
 libgnt_la_LIBADD = \
 	$(GLIB_LIBS) \
 	$(GNT_LIBS) \
-	$(LIBXML_LIBS)
+	$(LIBXML_LIBS) \
+	$(PY_LIBS)
 
 AM_CPPFLAGS = \
 	$(GLIB_CFLAGS) \
 	$(GNT_CFLAGS) \
 	$(DEBUG_CFLAGS) \
-	$(LIBXML_CFLAGS)
+	$(LIBXML_CFLAGS) \
+	$(PY_CFLAGS)
--- a/finch/libgnt/configure.ac	Fri Dec 07 22:14:23 2007 +0000
+++ b/finch/libgnt/configure.ac	Sun Dec 09 00:56:29 2007 +0000
@@ -302,6 +302,34 @@
 *** You need ncursesw or ncurses and its header files.])
 fi
 
+dnl Check for Python headers (currently useful only for libgnt)
+dnl (Thanks to XChat)
+AC_PATH_PROG(pythonpath, python)
+if test "_$pythonpath" != _ ; then
+	AC_MSG_CHECKING(for Python compile flags)
+	PY_PREFIX=`$pythonpath -c 'import sys ; print sys.prefix'`
+	PY_EXEC_PREFIX=`$pythonpath -c 'import sys ; print sys.exec_prefix'`
+	changequote(<<, >>)dnl
+	PY_VERSION=`$pythonpath -c 'import sys ; print sys.version[0:3]'`
+	PY_MAJOR=`$pythonpath -c 'import sys ; print sys.version[0:2]'`
+	changequote([, ])dnl
+	if test -f $PY_PREFIX/include/python$PY_VERSION/Python.h -a "$PY_MAJOR" = "2."; then
+		AC_CHECK_LIB(pthread, pthread_create, )
+		AC_CHECK_LIB(util, openpty, )
+		AC_CHECK_LIB(db, dbopen, )
+		PY_LIBS="-lpython$PY_VERSION -L$PY_EXEC_PREFIX/lib/python$PY_VERSION/config"
+		PY_CFLAGS="-I$PY_PREFIX/include/python$PY_VERSION"
+		AC_DEFINE(USE_PYTHON, [1], [Define if python headers are available.])
+		AC_MSG_RESULT(ok)
+	else
+		AC_MSG_RESULT([Can't find Python.h])
+		PY_LIBS=""
+		PY_CFLAGS=""
+	fi
+fi
+AC_SUBST(PY_CFLAGS)
+AC_SUBST(PY_LIBS)
+
 dnl Check for libxml
 have_libxml=yes
 PKG_CHECK_MODULES(LIBXML, [libxml-2.0], , [
--- a/finch/libgnt/gntwm.c	Fri Dec 07 22:14:23 2007 +0000
+++ b/finch/libgnt/gntwm.c	Sun Dec 09 00:56:29 2007 +0000
@@ -20,12 +20,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include "config.h"
+
+#ifdef USE_PYTHON
+#include <Python.h>
+#else
 #define _GNU_SOURCE
 #if (defined(__APPLE__) || defined(__unix__)) && !defined(__FreeBSD__)
 #define _XOPEN_SOURCE_EXTENDED
 #endif
-
-#include "config.h"
+#endif
 
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -1198,12 +1202,50 @@
 	return ignore_keys ? !(ignore_keys = FALSE) : FALSE;
 }
 
+#ifdef USE_PYTHON
+static void
+python_script_selected(GntFileSel *fs, const char *path, const char *f, gpointer n)
+{
+	char *dir = g_path_get_dirname(path);
+	FILE *file = fopen(path, "r");
+	PyObject *pp = PySys_GetObject("path"), *dirobj = PyString_FromString(dir);
+
+	PyList_Insert(pp, 0, dirobj);
+	Py_DECREF(dirobj);
+	PyRun_SimpleFile(file, path);
+	fclose(file);
+
+	if (PyErr_Occurred()) {
+		PyErr_Print();
+	}
+	g_free(dir);
+
+	gnt_widget_destroy(GNT_WIDGET(fs));
+}
+
+static gboolean
+run_python(GntBindable *bindable, GList *n)
+{
+	GntWidget *window = gnt_file_sel_new();
+	GntFileSel *sel = GNT_FILE_SEL(window);
+
+	g_object_set(G_OBJECT(window), "vertical", TRUE, NULL);
+	gnt_box_add_widget(GNT_BOX(window), gnt_label_new("Please select the python script you want to run."));
+	gnt_box_set_title(GNT_BOX(window), "Select Python Script...");
+
+	g_signal_connect(G_OBJECT(sel), "file_selected", G_CALLBACK(python_script_selected), NULL);
+	g_signal_connect_swapped(G_OBJECT(sel->cancel), "activate", G_CALLBACK(gnt_widget_destroy), sel);
+	gnt_widget_show(window);
+	return TRUE;
+}
+#endif  /* USE_PYTHON */
+
 static gboolean
 help_for_bindable(GntWM *wm, GntBindable *bindable)
 {
 	gboolean ret = TRUE;
 	GntBindableClass *klass = GNT_BINDABLE_GET_CLASS(bindable);
- 
+
 	if (klass->help_window) {
 		gnt_wm_raise_window(wm, GNT_WIDGET(klass->help_window));
 	} else {
@@ -1271,6 +1313,9 @@
 		g_object_unref(wm->workspaces->data);
 		wm->workspaces = g_list_delete_link(wm->workspaces, wm->workspaces);
 	}
+#ifdef USE_PYTHON
+	Py_Finalize();
+#endif
 }
 
 static void
@@ -1441,6 +1486,12 @@
 				GNT_KEY_CTRL_G, NULL);
 	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "ignore-keys-end", ignore_keys_end, 
 				"\033" GNT_KEY_CTRL_G, NULL);
+#ifdef USE_PYTHON
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "run-python", run_python,
+				GNT_KEY_F3, NULL);
+	Py_SetProgramName("gnt");
+	Py_Initialize();
+#endif
 
 	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));