#ifdef COGL_HAS_X11_SUPPORT
guint32 foreign_xid;
+ CoglOnscreenX11MaskCallback foreign_update_mask_callback;
+ void *foreign_update_mask_data;
#endif
gboolean swap_throttled;
#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
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
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
#include <X11/Xlib.h>
+
+#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
#endif
typedef struct _CoglRendererEGL
_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
{
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),
#include <errno.h>
#endif
+#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
+
typedef struct _CoglContextGLX
{
GLXDrawable current_drawable;
_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
{
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),
#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)
{
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
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)
}
}
+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)
{
* 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
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);