[clutter] Adds a way for Cogl to control event_mask of foreign wins
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter] Adds a way for Cogl to control event_mask of foreign wins
- Date: Thu, 5 May 2011 14:23:59 +0000 (UTC)
commit 4d3bf09e60af216774d5b1ec118f420ee0b7137b
Author: Robert Bragg <robert linux intel com>
Date: Wed May 4 17:02:04 2011 +0100
Adds a way for Cogl to control event_mask of foreign wins
This extends cogl_onscreen_x11_set_foreign_xid to take a callback to a
function that details the event mask the Cogl requires the application
to select on foreign windows. This is required because Cogl, for
example, needs to track size changes of a window and may also in the
future want other notifications such as map/unmap.
Most applications wont need to use the foreign xwindow apis, but those
that do are required to pass a valid callback and update the event mask
of their window according to Cogl's requirements.
clutter/cogl/cogl/cogl-framebuffer-private.h | 2 +
clutter/cogl/cogl/cogl-framebuffer.c | 10 ++++-
clutter/cogl/cogl/cogl-framebuffer.h | 58 +++++++++++++++++++++++++-
clutter/cogl/cogl/winsys/cogl-winsys-egl.c | 11 ++++-
clutter/cogl/cogl/winsys/cogl-winsys-glx.c | 11 ++++-
clutter/cogl/examples/x11-foreign.c | 22 +++++++++-
clutter/glx/clutter-stage-glx.c | 9 +++-
clutter/x11/clutter-stage-x11.c | 29 ++++++++-----
clutter/x11/clutter-stage-x11.h | 17 ++++++++
9 files changed, 151 insertions(+), 18 deletions(-)
---
diff --git a/clutter/cogl/cogl/cogl-framebuffer-private.h b/clutter/cogl/cogl/cogl-framebuffer-private.h
index 278cd15..f48938f 100644
--- a/clutter/cogl/cogl/cogl-framebuffer-private.h
+++ b/clutter/cogl/cogl/cogl-framebuffer-private.h
@@ -118,6 +118,8 @@ struct _CoglOnscreen
#ifdef COGL_HAS_X11_SUPPORT
guint32 foreign_xid;
+ CoglOnscreenX11MaskCallback foreign_update_mask_callback;
+ void *foreign_update_mask_data;
#endif
gboolean swap_throttled;
diff --git a/clutter/cogl/cogl/cogl-framebuffer.c b/clutter/cogl/cogl/cogl-framebuffer.c
index 071b9ec..daf817a 100644
--- a/clutter/cogl/cogl/cogl-framebuffer.c
+++ b/clutter/cogl/cogl/cogl-framebuffer.c
@@ -1624,9 +1624,17 @@ cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
#ifdef COGL_HAS_X11_SUPPORT
void
cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen,
- guint32 xid)
+ guint32 xid,
+ CoglOnscreenX11MaskCallback update,
+ void *user_data)
{
+ /* We don't wan't applications to get away with being lazy here and not
+ * passing an update callback... */
+ g_return_if_fail (update);
+
onscreen->foreign_xid = xid;
+ onscreen->foreign_update_mask_callback = update;
+ onscreen->foreign_update_mask_data = user_data;
}
guint32
diff --git a/clutter/cogl/cogl/cogl-framebuffer.h b/clutter/cogl/cogl/cogl-framebuffer.h
index 3f4ecb8..b685031 100644
--- a/clutter/cogl/cogl/cogl-framebuffer.h
+++ b/clutter/cogl/cogl/cogl-framebuffer.h
@@ -86,11 +86,67 @@ CoglOnscreen *
cogl_onscreen_new (CoglContext *context, int width, int height);
#ifdef COGL_HAS_X11
+typedef void (*CoglOnscreenX11MaskCallback) (CoglOnscreen *onscreen,
+ guint32 event_mask,
+ void *user_data);
+
+/**
+ * cogl_onscreen_x11_set_foreign_window_xid:
+ * @onscreen: The unallocated framebuffer to associated with an X
+ * window.
+ * @xid: The XID of an existing X window
+ * @update: A callback that notifies of updates to what Cogl requires
+ * to be in the core X protocol event mask.
+ *
+ * Ideally we would recommend that you let Cogl be responsible for
+ * creating any X window required to back an onscreen framebuffer but
+ * if you really need to target a window created manually this
+ * function can be called before @onscreen has been allocated to set a
+ * foreign XID for your existing X window.
+ *
+ * Since Cogl needs, for example, to track changes to the size of an X
+ * window it requires that certain events be selected for via the core
+ * X protocol. This requirement may also be changed asynchronously so
+ * you must pass in an @update callback to inform you of Cogl's
+ * required event mask.
+ *
+ * For example if you are using Xlib you could use this API roughly
+ * as follows:
+ * [{
+ * static void
+ * my_update_cogl_x11_event_mask (CoglOnscreen *onscreen,
+ * guint32 event_mask,
+ * void *user_data)
+ * {
+ * XSetWindowAttributes attrs;
+ * MyData *data = user_data;
+ * attrs.event_mask = event_mask | data->my_event_mask;
+ * XChangeWindowAttributes (data->xdpy,
+ * data->xwin,
+ * CWEventMask,
+ * &attrs);
+ * }
+ *
+ * {
+ * *snip*
+ * cogl_onscreen_x11_set_foreign_window_xid (onscreen,
+ * data->xwin,
+ * my_update_cogl_x11_event_mask,
+ * data);
+ * *snip*
+ * }
+ * }]
+ *
+ * Since: 2.0
+ * Stability: Unstable
+ */
#define cogl_onscreen_x11_set_foreign_window_xid \
cogl_onscreen_x11_set_foreign_window_xid_EXP
void
cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen,
- guint32 xid);
+ guint32 xid,
+ CoglOnscreenX11MaskCallback update,
+ void *user_data);
#define cogl_onscreen_x11_get_window_xid cogl_onscreen_x11_get_window_xid_EXP
guint32
diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-egl.c b/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
index 0ffd48b..22fd611 100644
--- a/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
+++ b/clutter/cogl/cogl/winsys/cogl-winsys-egl.c
@@ -68,6 +68,8 @@
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
#include <X11/Xlib.h>
+
+#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
#endif
typedef struct _CoglRendererEGL
@@ -922,6 +924,11 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
_cogl_framebuffer_winsys_update_size (framebuffer,
attr.width, attr.height);
+
+ /* Make sure the app selects for the events we require... */
+ onscreen->foreign_update_mask_callback (onscreen,
+ COGL_ONSCREEN_X11_EVENT_MASK,
+ onscreen->foreign_update_mask_data);
}
else
{
@@ -957,7 +964,9 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
DefaultRootWindow (xlib_renderer->xdpy),
xvisinfo->visual,
AllocNone);
- mask = CWBorderPixel | CWColormap;
+ attr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
+
+ mask = CWBorderPixel | CWColormap | CWEventMask;
xwin = XCreateWindow (xlib_renderer->xdpy,
DefaultRootWindow (xlib_renderer->xdpy),
diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-glx.c b/clutter/cogl/cogl/winsys/cogl-winsys-glx.c
index 47a207f..5948dde 100644
--- a/clutter/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/clutter/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -64,6 +64,8 @@ typedef CoglFuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName);
#include <errno.h>
#endif
+#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
+
typedef struct _CoglContextGLX
{
GLXDrawable current_drawable;
@@ -756,6 +758,11 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
_cogl_framebuffer_winsys_update_size (framebuffer,
attr.width, attr.height);
+
+ /* Make sure the app selects for the events we require... */
+ onscreen->foreign_update_mask_callback (onscreen,
+ COGL_ONSCREEN_X11_EVENT_MASK,
+ onscreen->foreign_update_mask_data);
}
else
{
@@ -792,7 +799,9 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
DefaultRootWindow (xlib_renderer->xdpy),
xvisinfo->visual,
AllocNone);
- mask = CWBorderPixel | CWColormap;
+ xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
+
+ mask = CWBorderPixel | CWColormap | CWEventMask;
xwin = XCreateWindow (xlib_renderer->xdpy,
DefaultRootWindow (xlib_renderer->xdpy),
diff --git a/clutter/cogl/examples/x11-foreign.c b/clutter/cogl/examples/x11-foreign.c
index d82e838..7012562 100644
--- a/clutter/cogl/examples/x11-foreign.c
+++ b/clutter/cogl/examples/x11-foreign.c
@@ -5,6 +5,24 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+static void
+update_cogl_x11_event_mask (CoglOnscreen *onscreen,
+ guint32 event_mask,
+ void *user_data)
+{
+ XDisplay *xdpy = user_data;
+ XSetWindowAttributes attrs;
+ guint32 xwin;
+
+ attrs.event_mask = event_mask;
+ xwin = cogl_onscreen_x11_get_window_xid (onscreen);
+
+ XChangeWindowAttributes (xdpy,
+ (Window)xwin,
+ CWEventMask,
+ &attrs);
+}
+
int
main (int argc, char **argv)
{
@@ -110,7 +128,9 @@ main (int argc, char **argv)
XFree (xvisinfo);
- cogl_onscreen_x11_set_foreign_window_xid (onscreen, xwin);
+ cogl_onscreen_x11_set_foreign_window_xid (onscreen, xwin,
+ update_cogl_x11_event_mask,
+ xdpy);
fb = COGL_FRAMEBUFFER (onscreen);
/* Eventually there will be an implicit allocate on first use so this
diff --git a/clutter/glx/clutter-stage-glx.c b/clutter/glx/clutter-stage-glx.c
index 0c0ab01..8a7a414 100644
--- a/clutter/glx/clutter-stage-glx.c
+++ b/clutter/glx/clutter-stage-glx.c
@@ -121,8 +121,13 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
stage_glx->onscreen = cogl_onscreen_new (backend->cogl_context,
width, height);
if (stage_x11->xwin != None)
- cogl_onscreen_x11_set_foreign_window_xid (stage_glx->onscreen,
- stage_x11->xwin);
+ {
+ cogl_onscreen_x11_set_foreign_window_xid (
+ stage_glx->onscreen,
+ stage_x11->xwin,
+ _clutter_stage_x11_update_foreign_event_mask,
+ stage_x11);
+ }
clutter_vblank = _clutter_backend_glx_get_vblank ();
if (clutter_vblank && strcmp (clutter_vblank, "none") == 0)
diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c
index d0553b0..ab877b9 100644
--- a/clutter/x11/clutter-stage-x11.c
+++ b/clutter/x11/clutter-stage-x11.c
@@ -387,6 +387,23 @@ clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
}
}
+void
+_clutter_stage_x11_update_foreign_event_mask (CoglOnscreen *onscreen,
+ guint32 event_mask,
+ void *user_data)
+{
+ ClutterStageX11 *stage_x11 = user_data;
+ ClutterBackendX11 *backend_x11 = stage_x11->backend;
+ XSetWindowAttributes attrs;
+
+ attrs.event_mask = event_mask | CLUTTER_STAGE_X11_EVENT_MASK;
+
+ XChangeWindowAttributes (backend_x11->xdpy,
+ stage_x11->xwin,
+ CWEventMask,
+ &attrs);
+}
+
static gboolean
clutter_stage_x11_realize (ClutterStageWindow *stage_window)
{
@@ -412,17 +429,7 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
* because key events are broken with that extension, and will
* be fixed by XI2
*/
- event_flags = StructureNotifyMask
- | FocusChangeMask
- | ExposureMask
- | PropertyChangeMask
- | EnterWindowMask
- | LeaveWindowMask
- | KeyPressMask
- | KeyReleaseMask
- | ButtonPressMask
- | ButtonReleaseMask
- | PointerMotionMask;
+ event_flags = CLUTTER_STAGE_X11_EVENT_MASK;
/* we unconditionally select input events even with event retrieval
* disabled because we need to guarantee that the Clutter internal
diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h
index 71732f5..a070c58 100644
--- a/clutter/x11/clutter-stage-x11.h
+++ b/clutter/x11/clutter-stage-x11.h
@@ -78,8 +78,25 @@ struct _ClutterStageX11Class
GObjectClass parent_class;
};
+#define CLUTTER_STAGE_X11_EVENT_MASK \
+ StructureNotifyMask | \
+ FocusChangeMask | \
+ ExposureMask | \
+ PropertyChangeMask | \
+ EnterWindowMask | \
+ LeaveWindowMask | \
+ KeyPressMask | \
+ KeyReleaseMask | \
+ ButtonPressMask | \
+ ButtonReleaseMask | \
+ PointerMotionMask;
+
GType _clutter_stage_x11_get_type (void) G_GNUC_CONST;
+void _clutter_stage_x11_update_foreign_event_mask (CoglOnscreen *onscreen,
+ guint32 event_mask,
+ void *user_data);
+
/* Private to subclasses */
void _clutter_stage_x11_set_user_time (ClutterStageX11 *stage_x11,
guint32 user_time);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]