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.
This commit is contained in:
parent
50d688399b
commit
4d3bf09e60
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user