[sabayon] Add a C wrapper to capture CreateNotify events
- From: Federico Mena Quintero <federico src gnome org>
- To: svn-commits-list gnome org
- Subject: [sabayon] Add a C wrapper to capture CreateNotify events
- Date: Wed, 29 Jul 2009 01:01:45 +0000 (UTC)
commit 4c10b58050c0aa086dbc65b096f1a1c94a730bd9
Author: Federico Mena Quintero <federico novell com>
Date: Tue Jul 28 14:35:39 2009 -0500
Add a C wrapper to capture CreateNotify events
Pygtk doesn't bind gdk_window_add_filter() and GdkFilterFunc correctly (bgo#156948).
So, we will need custom binding code to extract just CreateNotify events
with an event filter (GDK doesn't report those events, either, so we need an event filter).
Signed-off-by: Federico Mena Quintero <federico novell com>
lib/xlib.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 104 insertions(+), 6 deletions(-)
---
diff --git a/lib/xlib.c b/lib/xlib.c
index d841903..f62baa9 100644
--- a/lib/xlib.c
+++ b/lib/xlib.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2009 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -15,9 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
-
+ *
* Authors:
* Mark McLoughlin <markmc redhat com>
+ * Federico Mena-Quintero <federico novell com>
*/
#include <config.h>
@@ -28,6 +30,9 @@
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
+
+/* Bindings to do Xlib hackery */
+
static PyObject *
xlib_send_key_event (PyObject *self,
PyObject *args)
@@ -246,13 +251,106 @@ xlib_send_crossing_event (PyObject *self,
return Py_None;
}
+
+/* Bindings to do Gdk hackery, usually where features are not bound (or not
+ * properly bound) by Pygtk itself.
+ */
+
+struct create_window_closure {
+ GdkWindow *gdk_parent_window;
+ PyObject *pyfunc;
+ PyObject *pydata;
+};
+
+static int
+window_filter_func_marshal_cb(GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ struct create_window_closure *closure;
+ PyObject *ret;
+ XEvent *xev;
+
+ closure = data;
+
+ xev = (XEvent *) xevent;
+
+ if (xev->type != CreateNotify)
+ return GDK_FILTER_CONTINUE;
+
+ if (closure->pydata)
+ ret = PyEval_CallFunction (closure->pyfunc, "(iO)", (int) xev->xcreatewindow.window, closure->pydata);
+ else
+ ret = PyEval_CallFunction (closure->pyfunc, "(i)", (int) xev->xcreatewindow.window);
+
+ if (ret == NULL)
+ PyErr_Print ();
+ else
+ Py_DECREF (ret);
+
+ return GDK_FILTER_REMOVE; /* GDK doesn't process CreateNotify events */
+}
+
+/* Called as
+ * xlib.window_capture_create_notify (gdkwindow, callback, user_data)
+ *
+ * The callback is
+ * def callback (xid, user_data):
+ */
+static PyObject*
+xlib_window_capture_create_notify (PyGObject *self, PyObject *args)
+{
+ PyGObject *pygdkwindow;
+ PyObject *pyfunc, *pydata;
+ GdkWindow *gdkwindow;
+ struct create_window_closure *closure;
+
+ if (!PyArg_ParseTuple (args, "OOO:xlib.window_capture_create_notify", &pygdkwindow, &pyfunc, &pydata))
+ return NULL;
+
+ if (!PyCallable_Check (pyfunc))
+ {
+ PyErr_SetString (PyExc_TypeError, "func must be a callable object");
+ return NULL;
+ }
+
+ if (!GDK_IS_WINDOW (pygdkwindow->obj))
+ {
+ PyErr_SetString (PyExc_TypeError, "window should be a GdkWindow");
+ return NULL;
+ }
+
+ gdkwindow = GDK_WINDOW (pygdkwindow->obj);
+
+ closure = g_new (struct create_window_closure, 1);
+ closure->gdk_parent_window = gdkwindow;
+
+ closure->pyfunc = pyfunc;
+ closure->pydata = pydata;
+ Py_INCREF (closure->pyfunc);
+ Py_INCREF (closure->pydata);
+
+ /* FIXME: weakref the gdk_parent_window; destroy our closure when the window is destroyed */
+
+ gdk_window_add_filter (gdkwindow,
+ (GdkFilterFunc) window_filter_func_marshal_cb,
+ closure);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* Registration */
+
static struct PyMethodDef xlib_methods[] =
{
- { "send_key_event", xlib_send_key_event, METH_VARARGS },
- { "send_button_event", xlib_send_button_event, METH_VARARGS },
- { "send_motion_event", xlib_send_motion_event, METH_VARARGS },
- { "send_crossing_event", xlib_send_crossing_event, METH_VARARGS },
- { NULL, NULL, 0 }
+ { "send_key_event", xlib_send_key_event, METH_VARARGS },
+ { "send_button_event", xlib_send_button_event, METH_VARARGS },
+ { "send_motion_event", xlib_send_motion_event, METH_VARARGS },
+ { "send_crossing_event", xlib_send_crossing_event, METH_VARARGS },
+ { "window_capture_create_notify", xlib_window_capture_create_notify, METH_VARARGS },
+ { NULL, NULL, 0 }
};
void initxlib (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]