summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>1999-08-08 14:51:50 +0000
committerJames Henstridge <jamesh@src.gnome.org>1999-08-08 14:51:50 +0000
commite36ac1a21a255fc4655834e1d0272fdad4a89f51 (patch)
tree1929d375ab325a162385804f0dd3fde839c5c27d
parent14d3f7b03cb3df32ba92e9b8f24475a421888c47 (diff)
downloadpygtk-e36ac1a21a255fc4655834e1d0272fdad4a89f51.tar.gz
updated news file.
1999-08-08 James Henstridge <james@daa.com.au> * NEWS: updated news file. * configure.in: increased version number to 0.6.2. * gdkimlibmodule.c (_wrap_gdk_imlib_image_get_array): make sure that the image data is not freed while the returned array is in use, so that we don't get into an inconsistent state. * gtk.py: added gdkrgb functions to this file. * gtkmodule.c: added the gdkrgb functions for drawing rgb and greyscale images. (gdk_draw_array): a new function that will draw a numpy array to a drawable with gdkrgb. It is written so that it can handle slicing on the first two axes -- it does not handle non contiguous data on the third axis.
-rw-r--r--ChangeLog19
-rw-r--r--NEWS18
-rw-r--r--configure.in2
-rw-r--r--gdkimlibmodule.c11
-rw-r--r--gtk.py52
-rw-r--r--gtkmodule.c164
6 files changed, 259 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 18d7235f..2ce25846 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+1999-08-08 James Henstridge <james@daa.com.au>
+
+ * NEWS: updated news file.
+
+ * configure.in: increased version number to 0.6.2.
+
+ * gdkimlibmodule.c (_wrap_gdk_imlib_image_get_array): make sure that
+ the image data is not freed while the returned array is in use, so
+ that we don't get into an inconsistent state.
+
+ * gtk.py: added gdkrgb functions to this file.
+
+ * gtkmodule.c: added the gdkrgb functions for drawing rgb and greyscale
+ images.
+ (gdk_draw_array): a new function that will draw a numpy array to a
+ drawable with gdkrgb. It is written so that it can handle slicing
+ on the first two axes -- it does not handle non contiguous data on
+ the third axis.
+
1999-08-04 Matt Wilson <msw@redhat.com>
* GdkImlib.py (create_image_from_xpm): new wrapper for creating
diff --git a/NEWS b/NEWS
index 76895a68..ebbe3522 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,21 @@
+pygtk-0.6.2:
+ - Alright, threading should work correctly with multiple threads
+ accessing GTK (assuming they use threads_enter/leave). Thanks go
+ to Matt Wilson and Paul Fisher for this code.
+ - A pygtk.h header file is now installed that should make it easier
+ to write extensions to pygtk.
+ - There is now optional support for the gtkglarea widget and the
+ libglade library now.
+ - There is support for gdkrgb functions for rendering rgb and greyscale
+ image data to a drawable.
+ - Optional support for numpy arrays. You can create a GdkImlibImage
+ from a numpy array, and manipulate an image's data as an array.
+ Also there is a gdk_draw_array wrapper that uses gdkrgb to render
+ an array to a drawable. The code for the imlib stuff is based on
+ stuff submitted by Travis Oliphant.
+ - The GdkWindow type now has some methods for manipulating properties,
+ and has an xid attribute for getting the X window ID of the window.
+
pygtk-0.6.1: 22-May-1999
- Fixed a few bugs to do with the threading patches I applied in the
last release. Threading should now work correctly.
diff --git a/configure.in b/configure.in
index 47818b00..c1288396 100644
--- a/configure.in
+++ b/configure.in
@@ -2,7 +2,7 @@ AC_INIT
dnl for gnome-python:
-AM_INIT_AUTOMAKE(pygtk, 0.6.1)
+AM_INIT_AUTOMAKE(pygtk, 0.6.2)
AM_PATH_PYTHON
AM_INIT_PYEXEC_MOD
diff --git a/gdkimlibmodule.c b/gdkimlibmodule.c
index 7a341078..3a8f73da 100644
--- a/gdkimlibmodule.c
+++ b/gdkimlibmodule.c
@@ -797,12 +797,11 @@ static PyObject *_wrap_gdk_imlib_image_get_array(PyObject *self, PyObject *args)
(char *)obj->rgb_data);
if (ap_data == NULL)
return NULL;
- /* this is necessary if you want to manipulate the rgb data after
- * destroying the image. It causes a reference imbalance, and
- * I don't see when you would want to do this (you can always copy
- * the array).
- */
- /* Py_INCREF(image); */
+ /* this makes sure the GdkImlibImage is not freed while someone has a
+ * reference to the new array. */
+ Py_INCREF(image);
+ ap_data->base = image;
+
return PyArray_Return(ap_data);
}
#endif
diff --git a/gtk.py b/gtk.py
index 304ab0f5..bf042419 100644
--- a/gtk.py
+++ b/gtk.py
@@ -1977,6 +1977,29 @@ class GtkDrawingArea(GtkWidget):
def draw_lines(self, gc, points):
if not self.__win: self.__cache_win()
_gtk.gdk_draw_lines(self.__win, gc, points)
+ # these are the gdkrgb functions
+ def draw_rgb_image(self, gc, x, y, width, height,
+ dither, buffer, rowstride):
+ if not self.__win: self.__cache_win()
+ _gtk.gdk_draw_rgb_image(self.__win, gc, x, y, width, height,
+ dither, buffer, rowstride)
+ def draw_rgb_32_image(self, gc, x, y, width, height,
+ dither, buffer, rowstride):
+ if not self.__win: self.__cache_win()
+ _gtk.gdk_draw_rgb_32_image(self.__win, gc, x, y, width, height,
+ dither, buffer, rowstride)
+ def draw_gray_image(self, gc, x, y, width, height,
+ dither, buffer, rowstride):
+ if not self.__win: self.__cache_win()
+ _gtk.gdk_draw_gray_image(self.__win, gc, x, y, width, height,
+ dither, buffer, rowstride)
+
+ # see the comment for draw_array closer to the bottom of this file.
+ if hasattr(_gtk, "gdk_draw_array"):
+ def draw_array(self, gc, x, y, dither, array):
+ if not self.__win: self.__cache_win()
+ _gtk.gdk_draw_array(self.__win, gc, x, y, dither,array)
+
class GtkCurve(GtkDrawingArea):
get_type = _gtk.gtk_curve_get_type
@@ -2642,6 +2665,29 @@ def draw_segments(drawable, gc, segs):
def draw_lines(drawable, gc, points):
_gtk.gdk_draw_lines(drawable, gc, points)
+# these are the gdkrgb functions
+def draw_rgb_image(drawable, gc, x, y, width, height,
+ dither, buffer, rowstride):
+ _gtk.gdk_draw_rgb_image(drawable, gc, x, y, width, height,
+ dither, buffer, rowstride)
+def draw_rgb_32_image(drawable, gc, x, y, width, height,
+ dither, buffer, rowstride):
+ _gtk.gdk_draw_rgb_32_image(drawable, gc, x, y, width, height,
+ dither, buffer, rowstride)
+def draw_gray_image(drawable, gc, x, y, width, height,
+ dither, buffer, rowstride):
+ _gtk.gdk_draw_gray_image(drawable, gc, x, y, width, height,
+ dither, buffer, rowstride)
+
+# this function renders an unsigned byte (type code 'b') numpy array to a
+# drawable. If it is a MxN or MxNx1 array, it is assumed to be a grey image.
+# If it is a MxNx3 or MxNx4 array, it is assumed to be an rgb image.
+# It should accept images that have been sliced along their first two axes,
+# if you want to only draw part of the image.
+if hasattr(_gtk, "gdk_draw_array"):
+ def draw_array(drawable, gc, x, y, dither, array):
+ _gtk.gdk_draw_array(drawable, gc, x, y, dither, array)
+
# screen size
def screen_width():
@@ -2663,6 +2709,12 @@ def threads_leave():
def gdk_flush():
_gtk.gdk_flush()
+# these actually push/pop a visual/colormap pair.
+def push_rgb_visual():
+ _gtk.gtk_rgb_push_visual()
+def pop_visual():
+ _gtk.gtk_pop_visual()
+
# these are prefixed with underscores, since they are low level, and
# would break if pygtk was ported to windows.
def _window_foreign_new(xid):
diff --git a/gtkmodule.c b/gtkmodule.c
index adaaba5b..cd310c33 100644
--- a/gtkmodule.c
+++ b/gtkmodule.c
@@ -20,6 +20,10 @@
#include <Python.h>
#include <sysmodule.h>
+#ifdef HAVE_NUMPY
+#include <arrayobject.h>
+#endif
+
#include <gtk/gtk.h>
#define WITH_XSTUFF
@@ -5821,6 +5825,154 @@ static PyObject *_wrap_gdk_threads_leave(PyObject *self, PyObject *args) {
return Py_None;
}
+/* gdkrgb stuff -- will be needed when gdk_pixbuf stuff is added */
+
+static PyObject *_wrap_gtk_rgb_push_visual(PyObject *self, PyObject *args) {
+ if (!PyArg_ParseTuple(args, ":gtk_rgb_push_visual"))
+ return NULL;
+ gtk_widget_push_colormap(gdk_rgb_get_cmap());
+ gtk_widget_push_visual(gdk_rgb_get_visual());
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *_wrap_gtk_pop_visual(PyObject *self, PyObject *args) {
+ if (!PyArg_ParseTuple(args, ":gtk_pop_visual"))
+ return NULL;
+ gtk_widget_pop_colormap();
+ gtk_widget_pop_visual();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *_wrap_gdk_draw_rgb_image(PyObject *self, PyObject *args) {
+ PyObject *drawable, *gc, *py_dith;
+ gint x, y, width, height, rowstride = -1, len;
+ GdkRgbDither dith;
+ guchar *rgb_buf;
+
+ if (!PyArg_ParseTuple(args, "O!O!iiiiOs#|i:gdk_draw_rgb_image",
+ &PyGdkWindow_Type, &drawable, &PyGdkGC_Type, &gc,
+ &x, &y, &width, &height, &py_dith, &rgb_buf, &len,
+ &rowstride))
+ return NULL;
+ if (PyGtkEnum_get_value(GTK_TYPE_GDK_RGB_DITHER, py_dith, (gint *)&dith))
+ return NULL;
+ if (rowstride == -1)
+ rowstride = width * 3;
+ gdk_draw_rgb_image(PyGdkWindow_Get(drawable), PyGdkGC_Get(gc), x, y,
+ width, height, dith, rgb_buf, rowstride);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *_wrap_gdk_draw_rgb_32_image(PyObject *self, PyObject *args) {
+ PyObject *drawable, *gc, *py_dith;
+ gint x, y, width, height, rowstride = -1, len;
+ GdkRgbDither dith;
+ guchar *rgb_buf;
+
+ if (!PyArg_ParseTuple(args, "O!O!iiiiOs#|i:gdk_draw_rgb_32_image",
+ &PyGdkWindow_Type, &drawable, &PyGdkGC_Type, &gc,
+ &x, &y, &width, &height, &py_dith, &rgb_buf, &len,
+ &rowstride))
+ return NULL;
+ if (PyGtkEnum_get_value(GTK_TYPE_GDK_RGB_DITHER, py_dith, (gint *)&dith))
+ return NULL;
+ if (rowstride == -1)
+ rowstride = width * 4;
+ gdk_draw_rgb_32_image(PyGdkWindow_Get(drawable), PyGdkGC_Get(gc), x, y,
+ width, height, dith, rgb_buf, rowstride);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *_wrap_gdk_draw_gray_image(PyObject *self, PyObject *args) {
+ PyObject *drawable, *gc, *py_dith;
+ gint x, y, width, height, rowstride = -1, len;
+ GdkRgbDither dith;
+ guchar *buf;
+
+ if (!PyArg_ParseTuple(args, "O!O!iiiiOs#|i:gdk_draw_gray_image",
+ &PyGdkWindow_Type, &drawable, &PyGdkGC_Type, &gc,
+ &x, &y, &width, &height, &py_dith, &buf, &len,
+ &rowstride))
+ return NULL;
+ if (PyGtkEnum_get_value(GTK_TYPE_GDK_RGB_DITHER, py_dith, (gint *)&dith))
+ return NULL;
+ if (rowstride == -1)
+ rowstride = width;
+ gdk_draw_gray_image(PyGdkWindow_Get(drawable), PyGdkGC_Get(gc), x, y,
+ width, height, dith, buf, rowstride);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef HAVE_NUMPY
+/* this function renders an array to a drawable. If it is a MxN or MxNx1
+ * array, it is considered to be a grey image. If it is an MxNx3 or MxNx4
+ * array, it is considered to be an rgb image. The second two axes of the
+ * array must be contiguous (ie. array->strides[1] == 1,3 or 4,
+ * array->strides[2] == 1). The array->strides[0] is used to deduce the
+ * rowstride value for the data. This allows you to draw a slice of the image
+ * data. */
+static PyObject *_wrap_gdk_draw_array(PyObject *self, PyObject *args) {
+ PyObject *drawable, *gc, *py_dith;
+ PyArrayObject *array;
+ gint x, y, width, height, rowstride = -1, len;
+ GdkRgbDither dith;
+ guchar *buf;
+
+ if (!PyArg_ParseTuple(args, "O!O!iiOO!:gdk_draw_array",
+ &PyGdkWindow_Type, &drawable, &PyGdkGC_Type, &gc,
+ &x, &y, &py_dith, &PyArray_Type, &array))
+ return NULL;
+ if (PyGtkEnum_get_value(GTK_TYPE_GDK_RGB_DITHER, py_dith, (gint *)&dith))
+ return NULL;
+ if (array->descr->type_num != PyArray_UBYTE) {
+ PyErr_SetString(PyExc_TypeError, "array data must be unsigned bytes");
+ return NULL;
+ }
+ if (array->nd < 2) {
+ PyErr_SetString(PyExc_TypeError, "array must have at least 2 axes");
+ return NULL;
+ }
+ width = array->dimensions[1];
+ height = array->dimensions[0];
+ buf = (guchar *)array->data;
+ rowstride = array->strides[0];
+ if (array->nd == 2 || array->nd == 3 && array->dimensions[2] == 1) {
+ /* grey image */
+ if (array->strides[1] != 1) {
+ PyErr_SetString(PyExc_TypeError, "second axis must be contiguous");
+ return NULL;
+ }
+ gdk_draw_gray_image(PyGdkWindow_Get(drawable), PyGdkGC_Get(gc), x, y,
+ width, height, dith, buf, rowstride);
+ } else if (array->nd == 3 && array->dimensions[2] == 3) {
+ if (array->strides[1] != 3) {
+ PyErr_SetString(PyExc_TypeError, "second axis must be contiguous");
+ return NULL;
+ }
+ gdk_draw_rgb_image(PyGdkWindow_Get(drawable), PyGdkGC_Get(gc), x, y,
+ width, height, dith, buf, rowstride);
+ } else if (array->nd == 3 && array->dimensions[2] == 4) {
+ if (array->strides[1] != 4) {
+ PyErr_SetString(PyExc_TypeError, "second axis must be contiguous");
+ return NULL;
+ }
+ gdk_draw_rgb_32_image(PyGdkWindow_Get(drawable), PyGdkGC_Get(gc), x, y,
+ width, height, dith, buf, rowstride);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "array must be MxN or MxNxP where P is 1, 3 or 4");
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
static PyMethodDef _gtkmoduleMethods[] = {
{ "gtk_signal_connect", _wrap_gtk_signal_connect, 1 },
{ "gtk_signal_connect_after", _wrap_gtk_signal_connect_after, 1 },
@@ -5950,6 +6102,14 @@ static PyMethodDef _gtkmoduleMethods[] = {
{ "gdk_window_foreign_new", _wrap_gdk_window_foreign_new, 1 },
{ "gdk_get_root_win", _wrap_gdk_get_root_win, 1 },
#endif
+ { "gtk_rgb_push_visual", _wrap_gtk_rgb_push_visual, 1 },
+ { "gtk_pop_visual", _wrap_gtk_pop_visual, 1 },
+ { "gdk_draw_rgb_image", _wrap_gdk_draw_rgb_image, 1 },
+ { "gdk_draw_rgb_32_image", _wrap_gdk_draw_rgb_32_image, 1 },
+ { "gdk_draw_gray_image", _wrap_gdk_draw_gray_image, 1 },
+#ifdef HAVE_NUMPY
+ { "gdk_draw_array", _wrap_gdk_draw_array, 1 },
+#endif
{ NULL, NULL }
};
@@ -5995,6 +6155,10 @@ void init_gtk() {
m = Py_InitModule("_gtk", _gtkmoduleMethods);
d = PyModule_GetDict(m);
+#ifdef HAVE_NUMPY
+ import_array();
+#endif
+
/* initialise the boxed_funcs hash_table */
boxed_funcs = g_hash_table_new(g_direct_hash, g_direct_equal);