summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2011-12-16 18:50:49 +0000
committerNeil Roberts <neil@linux.intel.com>2012-01-05 13:40:24 +0000
commit181b875a3d73860b5568768658d82b7dd7492107 (patch)
treee9c2d30a10bf2483a030866181db7adbf90b9196
parent74974752955b8ba0e3e4e5df89ed937bb7397beb (diff)
downloadcogl-181b875a3d73860b5568768658d82b7dd7492107.tar.gz
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>
-rw-r--r--cogl/cogl-renderer-private.h1
-rw-r--r--cogl/cogl-renderer.c19
-rw-r--r--cogl/cogl-xlib-renderer-private.h15
-rw-r--r--cogl/cogl-xlib-renderer.c45
-rw-r--r--cogl/cogl-xlib-renderer.h27
-rw-r--r--cogl/winsys/cogl-winsys-egl-x11.c25
-rw-r--r--cogl/winsys/cogl-winsys-glx.c24
7 files changed, 156 insertions, 0 deletions
diff --git a/cogl/cogl-renderer-private.h b/cogl/cogl-renderer-private.h
index 2f7aaf10..47c0667e 100644
--- a/cogl/cogl-renderer-private.h
+++ b/cogl/cogl-renderer-private.h
@@ -46,6 +46,7 @@ struct _CoglRenderer
CoglWinsysID winsys_id_override;
#ifdef COGL_HAS_XLIB_SUPPORT
Display *foreign_xdpy;
+ gboolean xlib_enable_event_retrieval;
#endif
CoglDriver driver;
diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c
index fe4e2251..1a01b594 100644
--- a/cogl/cogl-renderer.c
+++ b/cogl/cogl-renderer.c
@@ -169,6 +169,10 @@ cogl_renderer_new (void)
renderer->connected = FALSE;
renderer->event_filters = NULL;
+#ifdef COGL_HAS_XLIB_SUPPORT
+ renderer->xlib_enable_event_retrieval = TRUE;
+#endif
+
return _cogl_renderer_object_new (renderer);
}
@@ -183,6 +187,10 @@ cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer,
_COGL_RETURN_IF_FAIL (!renderer->connected);
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 *
@@ -192,6 +200,17 @@ cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer)
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 */
gboolean
diff --git a/cogl/cogl-xlib-renderer-private.h b/cogl/cogl-xlib-renderer-private.h
index bad70bab..d0715c19 100644
--- a/cogl/cogl-xlib-renderer-private.h
+++ b/cogl/cogl-xlib-renderer-private.h
@@ -27,6 +27,7 @@
#include "cogl-object-private.h"
#include "cogl-xlib-private.h"
#include "cogl-x11-renderer-private.h"
+#include "cogl-context.h"
typedef struct _CoglXlibRenderer
{
@@ -37,6 +38,9 @@ typedef struct _CoglXlibRenderer
/* Current top of the XError trap state stack. The actual memory for
these is expected to be allocated on the stack by the caller */
CoglXlibTrapState *trap_state;
+
+ /* A poll FD for handling event retrieval within Cogl */
+ CoglPollFD poll_fd;
} CoglXlibRenderer;
gboolean
@@ -77,4 +81,15 @@ _cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer,
CoglXlibRenderer *
_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 */
diff --git a/cogl/cogl-xlib-renderer.c b/cogl/cogl-xlib-renderer.c
index 3a96b517..1bbbe140 100644
--- a/cogl/cogl-xlib-renderer.c
+++ b/cogl/cogl-xlib-renderer.c
@@ -213,6 +213,9 @@ _cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error)
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);
return TRUE;
@@ -267,3 +270,45 @@ cogl_xlib_renderer_remove_filter (CoglRenderer *renderer,
(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);
+ }
+}
diff --git a/cogl/cogl-xlib-renderer.h b/cogl/cogl-xlib-renderer.h
index 0afd568f..8c8b7522 100644
--- a/cogl/cogl-xlib-renderer.h
+++ b/cogl/cogl-xlib-renderer.h
@@ -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
* 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
cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer,
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
Display *
cogl_xlib_renderer_get_display (CoglRenderer *renderer);
diff --git a/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/winsys/cogl-winsys-egl-x11.c
index 3506ba96..e4fc6de8 100644
--- a/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/winsys/cogl-winsys-egl-x11.c
@@ -564,6 +564,28 @@ _cogl_winsys_xlib_get_visual_info (void)
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
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.poll_get_info = _cogl_winsys_poll_get_info;
+ vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
+
#ifdef EGL_KHR_image_pixmap
/* X11 tfp support... */
/* XXX: instead of having a rather monolithic winsys vtable we could
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
index 66252de2..8779af69 100644
--- a/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/winsys/cogl-winsys-glx.c
@@ -2051,6 +2051,27 @@ _cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
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 =
{
@@ -2082,6 +2103,9 @@ static CoglWinsysVtable _cogl_winsys_vtable =
_cogl_winsys_onscreen_remove_swap_buffers_callback,
.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... */
/* XXX: instead of having a rather monolithic winsys vtable we could
* perhaps look for a way to separate these... */