I had sent a patch earlier that did this and works fine, but unfortunately
it seems as if some of my submissions are disappearing into a black hole.
Latest patch attached,
-- Elliot
? autom4te.cache
? obj
? t.py
Index: configure.in
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/configure.in,v
retrieving revision 1.46
diff -u -r1.46 configure.in
--- configure.in 2001/10/08 19:46:55 1.46
+++ configure.in 2001/10/10 14:59:14
@@ -46,7 +46,7 @@
AC_MSG_RESULT(no)
fi
-AM_PATH_GLIB_2_0(1.3.9,,[AC_MSG_ERROR(maybe you want the gtk-gnome-1-2
branch?)],gobject)
+AM_PATH_GLIB_2_0(1.3.9,,[AC_MSG_ERROR(maybe you want the gtk-gnome-1-2
+branch?)],gobject $extra_mods)
PKG_CHECK_MODULES(PANGO, pango >= 0.20,,[AC_MSG_ERROR(maybe you want the
gtk-gnome-1-2 branch?)])
AC_SUBST(PANGO_CFLAGS)
AC_SUBST(PANGO_LIBS)
Index: gobjectmodule.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobjectmodule.c,v
retrieving revision 1.63
diff -u -r1.63 gobjectmodule.c
--- gobjectmodule.c 2001/10/05 19:28:33 1.63
+++ gobjectmodule.c 2001/10/10 14:59:14
@@ -1,4 +1,6 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
+#include "config.h"
+
#define _INSIDE_PYGOBJECT_
#include "pygobject.h"
@@ -10,6 +12,8 @@
staticforward PyTypeObject PyGObject_Type;
static void pygobject_dealloc(PyGObject *self);
static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
+static void pyg_block_threads(void);
+static void pyg_unblock_threads(void);
static void
object_free(PyObject *op)
@@ -50,7 +54,7 @@
char buf[80];
const gchar *name = g_type_name(self->type);
- g_snprintf(buf, sizeof(buf), "<GType %s>",
+ g_snprintf(buf, sizeof(buf), "<GType %s (%u)>",
name?name:"invalid", self->type);
return PyString_FromString(buf);
}
@@ -221,9 +225,9 @@
{
PyObject *obj = (PyObject *)user_data;
- /* PyGTK_BLOCK_THREADS */
+ pyg_block_threads();
Py_DECREF(obj);
- /* PyGTK_UNBLOCK_THREADS */
+ pyg_unblock_threads();
}
static void
@@ -487,8 +491,8 @@
PyGBoxed *self;
PyTypeObject *tp;
- g_return_if_fail(boxed_type != 0);
- g_return_if_fail(!copy_boxed || (copy_boxed && own_ref));
+ g_return_val_if_fail(boxed_type != 0, NULL);
+ g_return_val_if_fail(!copy_boxed || (copy_boxed && own_ref), NULL);
if (!boxed) {
Py_INCREF(Py_None);
@@ -639,6 +643,24 @@
Py_DECREF(gtype);
}
+ if(PyType_Check(obj)) {
+ PyTypeObject *tobj = (PyTypeObject *)obj;
+ if(tobj == &PyFloat_Type)
+ return G_TYPE_DOUBLE;
+ else if(tobj == &PyInt_Type)
+ return G_TYPE_INT;
+ else if(tobj == &PyLong_Type)
+ return G_TYPE_LONG;
+ else if(tobj == &PyString_Type)
+ return G_TYPE_STRING;
+ else if(tobj == &PyBaseObject_Type)
+ return PY_TYPE_OBJECT;
+ else if(tobj == &PyCObject_Type)
+ return G_TYPE_POINTER;
+ else if(tobj == Py_None->ob_type)
+ return G_TYPE_NONE;
+ }
+
PyErr_Clear();
PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
return 0;
@@ -891,15 +913,16 @@
PyObject *swap_data; /* other object for gtk_signal_connect_object */
};
-/* XXXX - must handle multithreadedness here */
static void
pyg_closure_destroy(gpointer data, GClosure *closure)
{
PyGClosure *pc = (PyGClosure *)closure;
+ pyg_block_threads();
Py_DECREF(pc->callback);
Py_XDECREF(pc->extra_args);
Py_XDECREF(pc->swap_data);
+ pyg_unblock_threads();
}
/* XXXX - need to handle python thread context stuff */
@@ -915,6 +938,7 @@
PyObject *params, *ret;
guint i;
+ pyg_block_threads();
/* construct Python tuple for the parameter values */
params = PyTuple_New(n_param_values);
for (i = 0; i < n_param_values; i++) {
@@ -929,7 +953,7 @@
/* error condition */
if (!item) {
Py_DECREF(params);
- /* XXXX - clean up if threading was used */
+ pyg_unblock_threads();
return;
}
PyTuple_SetItem(params, i, item);
@@ -946,13 +970,13 @@
/* XXXX - do fatal exceptions thing here */
PyErr_Print();
PyErr_Clear();
- /* XXXX - clean up if threading was used */
+ pyg_unblock_threads();
return;
}
if (return_value)
pyg_value_from_pyobject(return_value, ret);
Py_DECREF(ret);
- /* XXXX - clean up if threading was used */
+ pyg_unblock_threads();
}
static GClosure *
@@ -966,10 +990,11 @@
g_closure_set_marshal(closure, pyg_closure_marshal);
Py_INCREF(callback);
((PyGClosure *)closure)->callback = callback;
- if (extra_args) {
+ if (extra_args && extra_args != Py_None) {
if (!PyTuple_Check(extra_args)) {
PyObject *tmp = PyTuple_New(1);
PySequence_SetItem(tmp, 0, extra_args);
+ Py_INCREF(extra_args);
extra_args = tmp;
} else {
Py_INCREF(extra_args);
@@ -978,7 +1003,7 @@
}
if (swap_data) {
Py_INCREF(swap_data);
- ((PyGClosure *)closure)->swap_data;
+ ((PyGClosure *)closure)->swap_data = swap_data;
closure->derivative_flag = TRUE;
}
return closure;
@@ -1013,6 +1038,7 @@
g_return_if_fail(invocation_hint != NULL);
+ pyg_block_threads();
/* get the object passed as the first argument to the closure */
object = g_value_get_object(¶m_values[0]);
g_return_if_fail(object != NULL && G_IS_OBJECT(object));
@@ -1036,6 +1062,7 @@
if (!method) {
PyErr_Clear();
Py_DECREF(object_wrapper);
+ pyg_unblock_threads();
return;
}
Py_DECREF(object_wrapper);
@@ -1048,7 +1075,7 @@
/* error condition */
if (!item) {
Py_DECREF(params);
- /* XXXX - clean up if threading was used */
+ pyg_unblock_threads();
return;
}
PyTuple_SetItem(params, i - 1, item);
@@ -1059,15 +1086,15 @@
/* XXXX - do fatal exceptions thing here */
PyErr_Print();
PyErr_Clear();
- /* XXXX - clean up if threading was used */
Py_DECREF(method);
+ pyg_unblock_threads();
return;
}
Py_DECREF(method);
if (return_value)
pyg_value_from_pyobject(return_value, ret);
Py_DECREF(ret);
- /* XXXX - clean up if threading was used */
+ pyg_unblock_threads();
}
static GClosure *
@@ -1112,7 +1139,9 @@
PyObject_GC_UnTrack((PyObject *)self);
if (self->inst_dict)
- Py_DECREF(self->inst_dict);
+ {
+ Py_DECREF(self->inst_dict);
+ }
self->inst_dict = NULL;
/* the following causes problems with subclassed types */
@@ -1330,7 +1359,7 @@
PyErr_SetString(PyExc_TypeError, "second argument must be callable");
return NULL;
}
- if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
+ if (!g_signal_parse_name(name, pyg_type_from_object((PyObject *)self),
&sigid, &detail, TRUE)) {
PyErr_SetString(PyExc_TypeError, "unknown signal name");
return NULL;
@@ -1553,13 +1582,16 @@
return NULL;
}
}
- if (query.return_type != G_TYPE_NONE)
+ if (query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_INVALID)
g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
+ pyg_unblock_threads();
g_signal_emitv(params, signal_id, detail, &ret);
+ pyg_block_threads();
for (i = 0; i < query.n_params + 1; i++)
g_value_unset(¶ms[i]);
g_free(params);
- if (query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE != G_TYPE_NONE) {
+ if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE
+ && (query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_INVALID) {
py_ret = pyg_value_as_pyobject(&ret);
g_value_unset(&ret);
} else {
@@ -2263,7 +2295,6 @@
g_type_class_unref(fclass);
}
-
/* ----------------- gobject module initialisation -------------- */
static struct _PyGObject_Functions functions = {
@@ -2288,8 +2319,55 @@
pyg_enum_add_constants,
pyg_flags_add_constants,
+ pyg_block_threads,
+ pyg_unblock_threads,
+ NULL, /* gdk_threads_enter */
+ NULL /* gdk_threads_leave */
};
+
+#ifdef ENABLE_PYGTK_THREADING
+static GStaticPrivate pythreadstate_key = G_STATIC_PRIVATE_INIT;
+static GStaticPrivate counter_key = G_STATIC_PRIVATE_INIT;
+# define INITIAL_LOCK_COUNT 1
+#endif
+
+static void
+pyg_block_threads(void)
+{
+#ifdef ENABLE_PYGTK_THREADING
+ gint counter = GPOINTER_TO_INT(g_static_private_get(&counter_key));
+ g_assert(functions.block_threads == pyg_block_threads);
+ if (counter == INITIAL_LOCK_COUNT) {
+ PyThreadState *_save;
+ _save = g_static_private_get(&pythreadstate_key);
+ if(functions.gdk_threads_leave)
+ functions.gdk_threads_leave();
+ Py_BLOCK_THREADS;
+ }
+ counter--;
+ g_static_private_set(&counter_key, GINT_TO_POINTER(counter), NULL);
+#endif
+}
+
+static void
+pyg_unblock_threads(void)
+{
+#ifdef ENABLE_PYGTK_THREADING
+ gint counter = GPOINTER_TO_INT(g_static_private_get(&counter_key));
+ g_assert(functions.unblock_threads == pyg_unblock_threads);
+ counter++;
+ if (counter == INITIAL_LOCK_COUNT) {
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS;
+ if(functions.gdk_threads_enter)
+ functions.gdk_threads_enter();
+ g_static_private_set(&pythreadstate_key, _save, NULL);
+ }
+ g_static_private_set(&counter_key, GINT_TO_POINTER(counter), NULL);
+#endif
+}
+
DL_EXPORT(void)
initgobject(void)
{
@@ -2301,6 +2379,12 @@
m = Py_InitModule("gobject", pygobject_functions);
d = PyModule_GetDict(m);
+ /* initialise gthread if appropriate ... */
+#ifdef ENABLE_PYGTK_THREADING
+ /* it is required that this function be called to enable the thread
+ * safety functions */
+ g_thread_init(NULL);
+#endif
g_type_init();
PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject",
Index: pango.override
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/pango.override,v
retrieving revision 1.6
diff -u -r1.6 pango.override
--- pango.override 2001/10/08 09:01:36 1.6
+++ pango.override 2001/10/10 14:59:14
@@ -1,8 +1,10 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
+#include "config.h"
#define NO_IMPORT_PYGOBJECT
#include <pygobject.h>
+#define PANGO_ENABLE_BACKEND 1
#include <pango/pango.h>
%%
Index: pygobject.h
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/pygobject.h,v
retrieving revision 1.18
diff -u -r1.18 pygobject.h
--- pygobject.h 2001/09/28 23:43:46 1.18
+++ pygobject.h 2001/10/10 14:59:14
@@ -61,6 +61,10 @@
const gchar *strip_prefix);
void (* flags_add_constants)(PyObject *module, GType flags_type,
const gchar *strip_prefix);
+ void (* block_threads)(void);
+ void (* unblock_threads)(void);
+ void (* gdk_threads_enter)(void);
+ void (* gdk_threads_leave)(void);
};
#ifndef _INSIDE_PYGOBJECT_
@@ -89,6 +93,8 @@
#define pyg_boxed_new (_PyGObject_API->boxed_new)
#define pyg_enum_add_constants (_PyGObject_API->enum_add_constants)
#define pyg_flags_add_constants (_PyGObject_API->flags_add_constants)
+#define pyg_block_threads (_PyGObject_API->block_threads)
+#define pyg_unblock_threads (_PyGObject_API->unblock_threads)
#define init_pygobject() { \
PyObject *gobject = PyImport_ImportModule("gobject"); \
Index: codegen/codegen.py
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/codegen/codegen.py,v
retrieving revision 1.32
diff -u -r1.32 codegen.py
--- codegen/codegen.py 2001/10/08 09:01:37 1.32
+++ codegen/codegen.py 2001/10/10 14:59:15
@@ -781,6 +781,7 @@
def write_source(parser, overrides, prefix, fp=FileOutput(sys.stdout)):
fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
+ fp.write('#include "config.h"\n')
fp.write('#include <Python.h>\n\n\n')
fp.write(overrides.get_headers())
fp.resetline()
Index: gtk/gdk.override
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/gdk.override,v
retrieving revision 1.8
diff -u -r1.8 gdk.override
--- gtk/gdk.override 2001/10/08 09:01:38 1.8
+++ gtk/gdk.override 2001/10/10 14:59:15
@@ -1,6 +1,7 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
+#include "config.h"
#define NO_IMPORT_PYGOBJECT
#include "pygobject.h"
#include <gtk/gtk.h>
Index: gtk/gtk.defs
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/gtk.defs,v
retrieving revision 1.71
diff -u -r1.71 gtk.defs
--- gtk/gtk.defs 2001/10/09 04:05:33 1.71
+++ gtk/gtk.defs 2001/10/10 14:59:15
@@ -4193,8 +4193,6 @@
(return-type "GtkShadowType")
)
-
-
;; From /opt/gtk2/include/gtk-2.0/gtk/gtkgamma.h
(define-function gtk_gamma_curve_get_type
@@ -13226,8 +13224,12 @@
'("GtkTreeIter*" "iter")
)
)
-
+(define-method clear
+ (of-object "GtkTreeStore")
+ (c-name "gtk_tree_store_clear")
+ (return-type "none")
+)
;; From /opt/gtk2/include/gtk-2.0/gtk/gtktreeview.h
@@ -13977,9 +13979,6 @@
;; From /opt/gtk2/include/gtk-2.0/gtk/gtktypeutils.h
-
-
-
;; From /opt/gtk2/include/gtk-2.0/gtk/gtkvbbox.h
Index: gtk/gtk.override
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/gtk.override,v
retrieving revision 1.65
diff -u -r1.65 gtk.override
--- gtk/gtk.override 2001/10/08 09:01:38 1.65
+++ gtk/gtk.override 2001/10/10 14:59:15
@@ -1,6 +1,7 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
+#include "config.h"
#define NO_IMPORT_PYGOBJECT
#include "pygobject.h"
#include <gtk/gtk.h>
@@ -1324,6 +1325,45 @@
}
}
%%
+override gtk_tree_selection_selected_foreach
+static PyObject *
+_wrap_gtk_tree_selection_selected_foreach(PyGObject *self, PyObject *args)
+{
+ PyObject *pyfunc, *pyarg = NULL;
+ PyGtkCustomNotify cunote;
+
+ if(!PyArg_ParseTuple(args, "O|O:GtkTreeSelection.selected_foreach", &pyfunc,
+&pyarg))
+ return NULL;
+
+ cunote.func = pyfunc;
+ cunote.data = pyarg;
+ pygtk_unblock_threads();
+ gtk_tree_selection_selected_foreach(GTK_TREE_SELECTION(self->obj),
+pygtk_tree_foreach_marshal, &cunote);
+ pygtk_block_threads();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+%%
+override gtk_tree_selection_set_select_function
+static PyObject *
+_wrap_gtk_tree_selection_set_select_function(PyGObject *self, PyObject *args)
+{
+ PyObject *pyfunc, *pyarg = NULL;
+ PyGtkCustomNotify *cunote;
+
+ if(!PyArg_ParseTuple(args, "O|O:GtkTreeSelection.set_select_function", &pyfunc,
+&pyarg))
+ return NULL;
+
+ cunote = g_new0(PyGtkCustomNotify, 1);
+ Py_XINCREF(cunote->func = pyfunc);
+ Py_XINCREF(cunote->data = pyarg);
+ gtk_tree_selection_set_select_function(GTK_TREE_SELECTION(self->obj),
+pygtk_tree_selection_marshal, cunote,
+ pygtk_custom_destroy_notify);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+%%
override gtk_tree_selection_get_selected
static PyObject *
_wrap_gtk_tree_selection_get_selected(PyGObject *self, PyObject *args)
@@ -3937,6 +3977,24 @@
gtk_object_sink(GTK_OBJECT(self->obj));
pygobject_register_wrapper((PyObject *)self);
return 0;
+}
+%%
+override gtk_dialog_run
+
+static PyObject *
+_wrap_gtk_dialog_run(PyGObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { NULL };
+ gint retval;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, ":GtkDialog.run", kwlist))
+ return NULL;
+
+ pyg_unblock_threads();
+ retval = gtk_dialog_run(GTK_DIALOG(self->obj));
+ pyg_block_threads();
+
+ return PyInt_FromLong(retval);
}
%%
override gtk_message_dialog_new kwargs
Index: gtk/gtkgl.override
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/gtkgl.override,v
retrieving revision 1.2
diff -u -r1.2 gtkgl.override
--- gtk/gtkgl.override 2000/06/26 14:14:48 1.2
+++ gtk/gtkgl.override 2001/10/10 14:59:15
@@ -1,6 +1,7 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
+#include "config.h"
#define NO_IMPORT_PYGTK
#include "pygtk.h"
Index: gtk/gtkmodule.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/gtkmodule.c,v
retrieving revision 1.22
diff -u -r1.22 gtkmodule.c
--- gtk/gtkmodule.c 2001/09/27 16:22:45 1.22
+++ gtk/gtkmodule.c 2001/10/10 14:59:15
@@ -20,9 +20,6 @@
VERSION,
FALSE,
- pygtk_block_threads,
- pygtk_unblock_threads,
-
pygtk_destroy_notify,
&PyGdkAtom_Type, PyGdkAtom_New,
@@ -35,17 +32,12 @@
PyObject *av;
int argc, i;
char **argv;
+ GSList *stock_ids, *cur;
+ char buf[128];
/* initialise gobject */
init_pygobject();
- /* initialise gthread if appropriate ... */
-#ifdef ENABLE_PYGTK_THREADING
- /* it is required that this function be called to enable the thread
- * safety functions */
- g_thread_init(NULL);
-#endif
-
/* set the default python encoding to utf-8 */
PyUnicode_SetDefaultEncoding("utf-8");
@@ -83,6 +75,37 @@
PyDict_SetItemString(d, "_PyGtk_API",
PyCObject_FromVoidPtr(&functions, NULL));
+ stock_ids = gtk_stock_list_ids();
+ strcpy(buf, "STOCK_");
+ for(cur = stock_ids; cur; cur = stock_ids)
+ {
+ char *ctmp;
+ PyObject *obj;
+ int i;
+
+ ctmp = cur->data;
+ if(strncmp(ctmp, "gtk-", 4))
+ continue;
+ ctmp += 4;
+
+ strcpy(buf + sizeof("STOCK"), ctmp);
+ ctmp = buf + sizeof("STOCK");
+ for(i = 0; ctmp[i]; i++)
+ {
+ if(ctmp[i] == '-')
+ ctmp[i] = '_';
+ else if(ctmp[i] >= 'a' && ctmp[i] <= 'z')
+ ctmp[i] -= 'a'-'A';
+ }
+
+ obj = PyString_FromString(cur->data);
+ PyDict_SetItemString(d, buf, obj);
+ Py_DECREF(obj);
+ g_free(cur->data);
+ stock_ids = cur->next;
+ g_slist_free_1(cur);
+ }
+
/* namespace all the gdk stuff in gtk.gdk ... */
m = Py_InitModule("gtk.gdk", pygdk_functions);
d = PyModule_GetDict(m);
@@ -93,4 +116,6 @@
if (PyErr_Occurred())
Py_FatalError("can't initialise module _gtk");
+ _PyGObject_API->gdk_threads_enter = gdk_threads_enter;
+ _PyGObject_API->gdk_threads_leave = gdk_threads_leave;
}
Index: gtk/gtkobject-support.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/gtkobject-support.c,v
retrieving revision 1.12
diff -u -r1.12 gtkobject-support.c
--- gtk/gtkobject-support.c 2001/06/25 03:27:27 1.12
+++ gtk/gtkobject-support.c 2001/10/10 14:59:15
@@ -5,68 +5,6 @@
#include "pygtk-private.h"
-/* ----------------- Thread stuff -------------------- */
-/* The threading hacks are based on ones supplied by Duncan Grisby
- * of AT&T Labs Cambridge. Since then they have been modified a bit. */
-
-/* The threading code has been enhanced to be a little better with multiple
- * threads accessing GTK+. Here are some notes on the changes by
- * Paul Fisher:
- *
- * If threading is enabled, we create a recursive version of Python's
- * global interpreter mutex using TSD. This scheme makes it possible,
- * although rather hackish, for any thread to make a call into PyGTK,
- * as long as the GDK lock is held (that is, Python code is wrapped
- * around a threads_{enter,leave} pair).
- *
- * A viable alternative would be to wrap each and every GTK call, at
- * the Python/C level, with Py_{BEGIN,END}_ALLOW_THREADS. However,
- * given the nature of Python threading, this option is not
- * particularly appealing.
- */
-
-
-#ifdef ENABLE_PYGTK_THREADING
-static GStaticPrivate pythreadstate_key = G_STATIC_PRIVATE_INIT;
-static GStaticPrivate counter_key = G_STATIC_PRIVATE_INIT;
-
-/* The global Python lock will be grabbed by Python when entering a
- * Python/C function; thus, the initial lock count will always be one.
- */
-# define INITIAL_LOCK_COUNT 1
-# define PyGTK_BLOCK_THREADS \
- { \
- gint counter = GPOINTER_TO_INT(g_static_private_get(&counter_key)); \
- if (counter == -INITIAL_LOCK_COUNT) { \
- PyThreadState *_save; \
- _save = g_static_private_get(&pythreadstate_key); \
- Py_BLOCK_THREADS; \
- } \
- counter++; \
- g_static_private_set(&counter_key, GINT_TO_POINTER(counter), NULL); \
- }
-
-# define PyGTK_UNBLOCK_THREADS \
- { \
- gint counter = GPOINTER_TO_INT(g_static_private_get(&counter_key)); \
- counter--; \
- if (counter == -INITIAL_LOCK_COUNT) { \
- PyThreadState *_save; \
- Py_UNBLOCK_THREADS; \
- g_static_private_set(&pythreadstate_key, _save, NULL); \
- } \
- g_static_private_set(&counter_key, GINT_TO_POINTER(counter), NULL); \
- }
-
-
-#else /* !WITH_THREADS */
-# define PyGTK_BLOCK_THREADS
-# define PyGTK_UNBLOCK_THREADS
-#endif
-
-void pygtk_block_threads(void) { PyGTK_BLOCK_THREADS }
-void pygtk_unblock_threads(void) { PyGTK_UNBLOCK_THREADS }
-
/* ------------------- object support */
void
@@ -74,19 +12,30 @@
{
PyObject *obj = (PyObject *)user_data;
- PyGTK_BLOCK_THREADS
+ pyg_block_threads();
Py_DECREF(obj);
- PyGTK_UNBLOCK_THREADS
+ pyg_unblock_threads();
}
+void
+pygtk_custom_destroy_notify(gpointer user_data)
+{
+ PyGtkCustomNotify *cunote = user_data;
+ pyg_block_threads();
+ Py_XDECREF(cunote->func);
+ Py_XDECREF(cunote->data);
+ pyg_unblock_threads();
+ g_free(cunote);
+}
+
/* used for timeout and idle functions */
void
pygtk_handler_marshal(gpointer a, PyObject *func, int nargs, GtkArg *args)
{
PyObject *ret;
- PyGTK_BLOCK_THREADS
+ pyg_block_threads();
if (PyTuple_Check(func))
ret = PyObject_CallObject(PyTuple_GetItem(func, 0),
@@ -101,7 +50,7 @@
PyErr_Clear();
}
*GTK_RETLOC_BOOL(args[0]) = FALSE;
- PyGTK_UNBLOCK_THREADS
+ pyg_unblock_threads();
return;
}
if (ret == Py_None || (PyInt_Check(ret) && PyInt_AsLong(ret) == 0))
@@ -109,7 +58,7 @@
else
*GTK_RETLOC_BOOL(args[0]) = TRUE;
Py_DECREF(ret);
- PyGTK_UNBLOCK_THREADS
+ pyg_unblock_threads();
}
/* callback for input handlers */
@@ -118,7 +67,7 @@
{
PyObject *tuple, *ret;
- PyGTK_BLOCK_THREADS
+ pyg_block_threads();
tuple = Py_BuildValue("(ii)", GTK_VALUE_INT(args[0]),
GTK_VALUE_FLAGS(args[1]));
ret = PyObject_CallObject(func, tuple);
@@ -132,8 +81,67 @@
}
} else
Py_DECREF(ret);
- PyGTK_UNBLOCK_THREADS
+ pyg_unblock_threads();
+}
+
+void
+pygtk_tree_foreach_marshal(GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ PyGtkCustomNotify *cunote = data;
+ PyObject *pypath, *retobj;
+
+ g_assert(cunote->func);
+
+ pyg_block_threads();
+
+ pypath = pygtk_tree_path_to_pyobject(path);
+ if(cunote->data)
+ retobj = PyEval_CallFunction(cunote->func, "(OO)", pypath, cunote->data);
+ else
+ retobj = PyEval_CallFunction(cunote->func, "(O)", pypath);
+ Py_DECREF(pypath);
+ Py_XDECREF(retobj);
+
+ pyg_unblock_threads();
}
+gboolean
+pygtk_tree_selection_marshal(GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gpointer data)
+{
+ gboolean retval = FALSE;
+ PyGtkCustomNotify *cunote = data;
+ PyObject *pypath, *retobj;
+
+ g_assert(cunote->func);
+
+ pyg_block_threads();
+
+ pypath = pygtk_tree_path_to_pyobject(path);
+ if(cunote->data)
+ retobj = PyEval_CallFunction(cunote->func, "(OO)", pypath, cunote->data);
+ else
+ retobj = PyEval_CallFunction(cunote->func, "(O)", pypath);
+ Py_DECREF(pypath);
+ if(retobj)
+ {
+ if(retobj == Py_None);
+ else if(PyInt_Check(retobj))
+ retval = PyInt_AsLong(retobj) && TRUE;
+ else if(PyLong_Check(retobj))
+ retval = PyLong_AsLongLong(retobj) && TRUE;
+ else if(PyString_Check(retobj))
+ retval = PyString_GET_SIZE(retobj) && TRUE;
+
+ Py_DECREF(retobj);
+ }
+ pyg_unblock_threads();
+ return retval;
+}
Index: gtk/libglade.override
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/libglade.override,v
retrieving revision 1.9
diff -u -r1.9 libglade.override
--- gtk/libglade.override 2001/10/08 09:01:38 1.9
+++ gtk/libglade.override 2001/10/10 14:59:15
@@ -1,6 +1,7 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
%%
headers
+#include "config.h"
#define NO_IMPORT_PYGOBJECT
#include <pygobject.h>
#include <glade/glade.h>
Index: gtk/pygtk-private.h
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/pygtk-private.h,v
retrieving revision 1.18
diff -u -r1.18 pygtk-private.h
--- gtk/pygtk-private.h 2001/09/27 16:22:45 1.18
+++ gtk/pygtk-private.h 2001/10/10 14:59:15
@@ -22,10 +22,6 @@
/* constructors for PyObject wrappers ... */
PyObject *PyGdkAtom_New(GdkAtom atom);
-/* miscelaneous functions */
-void pygtk_block_threads(void);
-void pygtk_unblock_threads(void);
-
void pygtk_destroy_notify(gpointer data);
void pygtk_handler_marshal(gpointer a, PyObject *func, int nargs,GtkArg *args);
@@ -36,5 +32,20 @@
GtkTreePath *pygtk_tree_path_from_pyobject(PyObject *object);
static gboolean PyGtk_FatalExceptions = FALSE;
+
+typedef struct {
+ PyObject *func, *data;
+} PyGtkCustomNotify;
+
+void pygtk_custom_destroy_notify(gpointer user_data);
+
+gboolean pygtk_tree_selection_marshal(GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gpointer data);
+void pygtk_tree_foreach_marshal(GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data);
#endif
Index: gtk/pygtk.h
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gtk/pygtk.h,v
retrieving revision 1.20
diff -u -r1.20 pygtk.h
--- gtk/pygtk.h 2001/09/28 23:43:47 1.20
+++ gtk/pygtk.h 2001/10/10 14:59:15
@@ -11,9 +11,6 @@
char *pygtkVersion;
gboolean fatalExceptions;
- void (* block_threads)(void);
- void (* unblock_threads)(void);
-
GtkDestroyNotify destroy_notify;
PyTypeObject *gdkAtom_type;
@@ -30,6 +27,9 @@
/* routines to get the C object value out of the PyObject wrapper */
#define PyGdkAtom_Get(v) (((PyGdkAtom_Object *)(v))->atom)
+#define pygtk_block_threads pyg_block_threads
+#define pygtk_unblock_threads pyg_unblock_threads
+
/* this section is dependent on whether we are being included from gtkmodule.c
* or not. A similar source level interface should be provided in both
* instances. */
@@ -53,8 +53,6 @@
#define PyGdkAtom_New (_PyGtk_API->gdkAtom_new)
/* miscelaneous other functions */
-#define pygtk_block_threads (_PyGtk_API->block_threads)
-#define pygtk_unblock_threads (_PyGtk_API->unblock_threads)
#define pygtk_destroy_notify (_PyGtk_API->destroy_notify)
/* some variables */