mirror of
https://github.com/brl/mutter.git
synced 2025-02-18 06:04:10 +00:00
xlib: Internally retrieve XEvents
Previously we relied on the application to send all X events through Cogl using cogl_xlib_renderer_handle_event. This breaks the abstraction that an application shouldn't need to know what winsys Cogl is using. Now that we have main loop integreation in Cogl, the Xlib-based winsys's can report that Cogl needs to block on the file descriptor of the X connection and it can manually handle the events. The event retrieval can be disabled by an application if it calls the new cogl_xlib_renderer_set_event_retrieval_enabled() function. The event retrieval will also automatically be disabled if the application sets a foreign display. Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
parent
7497475295
commit
181b875a3d
@ -46,6 +46,7 @@ struct _CoglRenderer
|
|||||||
CoglWinsysID winsys_id_override;
|
CoglWinsysID winsys_id_override;
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
Display *foreign_xdpy;
|
Display *foreign_xdpy;
|
||||||
|
gboolean xlib_enable_event_retrieval;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CoglDriver driver;
|
CoglDriver driver;
|
||||||
|
@ -169,6 +169,10 @@ cogl_renderer_new (void)
|
|||||||
renderer->connected = FALSE;
|
renderer->connected = FALSE;
|
||||||
renderer->event_filters = NULL;
|
renderer->event_filters = NULL;
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
|
renderer->xlib_enable_event_retrieval = TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
return _cogl_renderer_object_new (renderer);
|
return _cogl_renderer_object_new (renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +187,10 @@ cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer,
|
|||||||
_COGL_RETURN_IF_FAIL (!renderer->connected);
|
_COGL_RETURN_IF_FAIL (!renderer->connected);
|
||||||
|
|
||||||
renderer->foreign_xdpy = xdisplay;
|
renderer->foreign_xdpy = xdisplay;
|
||||||
|
|
||||||
|
/* If the application is using a foreign display then we can assume
|
||||||
|
it will also do its own event retrieval */
|
||||||
|
cogl_xlib_renderer_set_event_retrieval_enabled (renderer, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Display *
|
Display *
|
||||||
@ -192,6 +200,17 @@ cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer)
|
|||||||
|
|
||||||
return renderer->foreign_xdpy;
|
return renderer->foreign_xdpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer,
|
||||||
|
gboolean enable)
|
||||||
|
{
|
||||||
|
_COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer));
|
||||||
|
/* NB: Renderers are considered immutable once connected */
|
||||||
|
_COGL_RETURN_IF_FAIL (!renderer->connected);
|
||||||
|
|
||||||
|
renderer->xlib_enable_event_retrieval = enable;
|
||||||
|
}
|
||||||
#endif /* COGL_HAS_XLIB_SUPPORT */
|
#endif /* COGL_HAS_XLIB_SUPPORT */
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "cogl-object-private.h"
|
#include "cogl-object-private.h"
|
||||||
#include "cogl-xlib-private.h"
|
#include "cogl-xlib-private.h"
|
||||||
#include "cogl-x11-renderer-private.h"
|
#include "cogl-x11-renderer-private.h"
|
||||||
|
#include "cogl-context.h"
|
||||||
|
|
||||||
typedef struct _CoglXlibRenderer
|
typedef struct _CoglXlibRenderer
|
||||||
{
|
{
|
||||||
@ -37,6 +38,9 @@ typedef struct _CoglXlibRenderer
|
|||||||
/* Current top of the XError trap state stack. The actual memory for
|
/* Current top of the XError trap state stack. The actual memory for
|
||||||
these is expected to be allocated on the stack by the caller */
|
these is expected to be allocated on the stack by the caller */
|
||||||
CoglXlibTrapState *trap_state;
|
CoglXlibTrapState *trap_state;
|
||||||
|
|
||||||
|
/* A poll FD for handling event retrieval within Cogl */
|
||||||
|
CoglPollFD poll_fd;
|
||||||
} CoglXlibRenderer;
|
} CoglXlibRenderer;
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -77,4 +81,15 @@ _cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer,
|
|||||||
CoglXlibRenderer *
|
CoglXlibRenderer *
|
||||||
_cogl_xlib_renderer_get_data (CoglRenderer *renderer);
|
_cogl_xlib_renderer_get_data (CoglRenderer *renderer);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_xlib_renderer_poll_get_info (CoglRenderer *renderer,
|
||||||
|
CoglPollFD **poll_fds,
|
||||||
|
int *n_poll_fds,
|
||||||
|
gint64 *timeout);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_xlib_renderer_poll_dispatch (CoglRenderer *renderer,
|
||||||
|
const CoglPollFD *poll_fds,
|
||||||
|
int n_poll_fds);
|
||||||
|
|
||||||
#endif /* __COGL_RENDERER_XLIB_PRIVATE_H */
|
#endif /* __COGL_RENDERER_XLIB_PRIVATE_H */
|
||||||
|
@ -213,6 +213,9 @@ _cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error)
|
|||||||
|
|
||||||
xlib_renderer->trap_state = NULL;
|
xlib_renderer->trap_state = NULL;
|
||||||
|
|
||||||
|
xlib_renderer->poll_fd.fd = ConnectionNumber (xlib_renderer->xdpy);
|
||||||
|
xlib_renderer->poll_fd.events = COGL_POLL_FD_EVENT_IN;
|
||||||
|
|
||||||
register_xlib_renderer (renderer);
|
register_xlib_renderer (renderer);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -267,3 +270,45 @@ cogl_xlib_renderer_remove_filter (CoglRenderer *renderer,
|
|||||||
(CoglNativeFilterFunc)func, data);
|
(CoglNativeFilterFunc)func, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_xlib_renderer_poll_get_info (CoglRenderer *renderer,
|
||||||
|
CoglPollFD **poll_fds,
|
||||||
|
int *n_poll_fds,
|
||||||
|
gint64 *timeout)
|
||||||
|
{
|
||||||
|
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
|
||||||
|
|
||||||
|
if (renderer->xlib_enable_event_retrieval)
|
||||||
|
{
|
||||||
|
*n_poll_fds = 1;
|
||||||
|
*poll_fds = &xlib_renderer->poll_fd;
|
||||||
|
if (XPending (xlib_renderer->xdpy))
|
||||||
|
*timeout = 0;
|
||||||
|
else
|
||||||
|
*timeout = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*n_poll_fds = 0;
|
||||||
|
*poll_fds = NULL;
|
||||||
|
*timeout = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_xlib_renderer_poll_dispatch (CoglRenderer *renderer,
|
||||||
|
const CoglPollFD *poll_fds,
|
||||||
|
int n_poll_fds)
|
||||||
|
{
|
||||||
|
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
|
||||||
|
|
||||||
|
if (renderer->xlib_enable_event_retrieval)
|
||||||
|
while (XPending (xlib_renderer->xdpy))
|
||||||
|
{
|
||||||
|
XEvent xevent;
|
||||||
|
|
||||||
|
XNextEvent (xlib_renderer->xdpy, &xevent);
|
||||||
|
|
||||||
|
cogl_xlib_renderer_handle_event (renderer, &xevent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -112,11 +112,38 @@ cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer);
|
|||||||
*
|
*
|
||||||
* Sets a foreign Xlib display that Cogl will use for and Xlib based winsys
|
* Sets a foreign Xlib display that Cogl will use for and Xlib based winsys
|
||||||
* backend.
|
* backend.
|
||||||
|
*
|
||||||
|
* Note that calling this function will automatically call
|
||||||
|
* cogl_xlib_renderer_set_event_retrieval_enabled() to disable Cogl's
|
||||||
|
* event retrieval. Cogl still needs to see all of the X events so the
|
||||||
|
* application should also use cogl_xlib_renderer_handle_event() if it
|
||||||
|
* uses this function.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer,
|
cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer,
|
||||||
Display *display);
|
Display *display);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_xlib_renderer_set_event_retrieval_enabled:
|
||||||
|
* @renderer: A #CoglRenderer
|
||||||
|
* @enable: The new value
|
||||||
|
*
|
||||||
|
* Sets whether Cogl should automatically retrieve events from the X
|
||||||
|
* display. This defaults to %TRUE unless
|
||||||
|
* cogl_xlib_renderer_set_foreign_display() is called. It can be set
|
||||||
|
* to %FALSE if the application wants to handle its own event
|
||||||
|
* retrieval. Note that Cogl still needs to see all of the X events to
|
||||||
|
* function properly so the application should call
|
||||||
|
* cogl_xlib_renderer_handle_event() for each event if it disables
|
||||||
|
* automatic event retrieval.
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer,
|
||||||
|
gboolean enable);
|
||||||
|
|
||||||
#define cogl_xlib_renderer_get_display cogl_xlib_renderer_get_display_EXP
|
#define cogl_xlib_renderer_get_display cogl_xlib_renderer_get_display_EXP
|
||||||
Display *
|
Display *
|
||||||
cogl_xlib_renderer_get_display (CoglRenderer *renderer);
|
cogl_xlib_renderer_get_display (CoglRenderer *renderer);
|
||||||
|
@ -564,6 +564,28 @@ _cogl_winsys_xlib_get_visual_info (void)
|
|||||||
return get_visual_info (ctx->display, egl_display->egl_config);
|
return get_visual_info (ctx->display, egl_display->egl_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_poll_get_info (CoglContext *context,
|
||||||
|
CoglPollFD **poll_fds,
|
||||||
|
int *n_poll_fds,
|
||||||
|
gint64 *timeout)
|
||||||
|
{
|
||||||
|
_cogl_xlib_renderer_poll_get_info (context->display->renderer,
|
||||||
|
poll_fds,
|
||||||
|
n_poll_fds,
|
||||||
|
timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_poll_dispatch (CoglContext *context,
|
||||||
|
const CoglPollFD *poll_fds,
|
||||||
|
int n_poll_fds)
|
||||||
|
{
|
||||||
|
_cogl_xlib_renderer_poll_dispatch (context->display->renderer,
|
||||||
|
poll_fds,
|
||||||
|
n_poll_fds);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef EGL_KHR_image_pixmap
|
#ifdef EGL_KHR_image_pixmap
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -710,6 +732,9 @@ _cogl_winsys_egl_xlib_get_vtable (void)
|
|||||||
|
|
||||||
vtable.xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info;
|
vtable.xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info;
|
||||||
|
|
||||||
|
vtable.poll_get_info = _cogl_winsys_poll_get_info;
|
||||||
|
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
||||||
|
|
||||||
#ifdef EGL_KHR_image_pixmap
|
#ifdef EGL_KHR_image_pixmap
|
||||||
/* X11 tfp support... */
|
/* X11 tfp support... */
|
||||||
/* XXX: instead of having a rather monolithic winsys vtable we could
|
/* XXX: instead of having a rather monolithic winsys vtable we could
|
||||||
|
@ -2051,6 +2051,27 @@ _cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
|
|||||||
return glx_tex_pixmap->glx_tex;
|
return glx_tex_pixmap->glx_tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_poll_get_info (CoglContext *context,
|
||||||
|
CoglPollFD **poll_fds,
|
||||||
|
int *n_poll_fds,
|
||||||
|
gint64 *timeout)
|
||||||
|
{
|
||||||
|
_cogl_xlib_renderer_poll_get_info (context->display->renderer,
|
||||||
|
poll_fds,
|
||||||
|
n_poll_fds,
|
||||||
|
timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_poll_dispatch (CoglContext *context,
|
||||||
|
const CoglPollFD *poll_fds,
|
||||||
|
int n_poll_fds)
|
||||||
|
{
|
||||||
|
_cogl_xlib_renderer_poll_dispatch (context->display->renderer,
|
||||||
|
poll_fds,
|
||||||
|
n_poll_fds);
|
||||||
|
}
|
||||||
|
|
||||||
static CoglWinsysVtable _cogl_winsys_vtable =
|
static CoglWinsysVtable _cogl_winsys_vtable =
|
||||||
{
|
{
|
||||||
@ -2082,6 +2103,9 @@ static CoglWinsysVtable _cogl_winsys_vtable =
|
|||||||
_cogl_winsys_onscreen_remove_swap_buffers_callback,
|
_cogl_winsys_onscreen_remove_swap_buffers_callback,
|
||||||
.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility,
|
.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility,
|
||||||
|
|
||||||
|
.poll_get_info = _cogl_winsys_poll_get_info,
|
||||||
|
.poll_dispatch = _cogl_winsys_poll_dispatch,
|
||||||
|
|
||||||
/* X11 tfp support... */
|
/* X11 tfp support... */
|
||||||
/* XXX: instead of having a rather monolithic winsys vtable we could
|
/* XXX: instead of having a rather monolithic winsys vtable we could
|
||||||
* perhaps look for a way to separate these... */
|
* perhaps look for a way to separate these... */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user