Add a vtable of indirection to the winsys code
authorRobert Bragg <robert@linux.intel.com>
Fri, 25 Feb 2011 11:29:08 +0000 (11:29 +0000)
committerRobert Bragg <robert@linux.intel.com>
Thu, 5 May 2011 13:46:01 +0000 (14:46 +0100)
So that we can dynamically select what winsys backend to use at runtime
we need to have some indirection to how code accesses the winsys instead
of simply calling _cogl_winsys* functions that would collide if we
wanted to compile more than one backend into Cogl.

12 files changed:
clutter/cogl/cogl/cogl-clutter.c
clutter/cogl/cogl/cogl-context-private.h
clutter/cogl/cogl/cogl-context.c
clutter/cogl/cogl/cogl-display.c
clutter/cogl/cogl/cogl-framebuffer.c
clutter/cogl/cogl/cogl-renderer-private.h
clutter/cogl/cogl/cogl-renderer.c
clutter/cogl/cogl/cogl.c
clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
clutter/cogl/cogl/winsys/cogl-winsys-egl.c
clutter/cogl/cogl/winsys/cogl-winsys-glx.c
clutter/cogl/cogl/winsys/cogl-winsys-private.h

index facdeb3..49821ac 100644 (file)
@@ -68,6 +68,12 @@ cogl_onscreen_clutter_backend_set_size (int width, int height)
 XVisualInfo *
 cogl_clutter_winsys_xlib_get_visual_info (void)
 {
-  return _cogl_winsys_xlib_get_visual_info ();
+  const CoglWinsysVtable *winsys;
+
+  _COGL_GET_CONTEXT (ctx, NULL);
+
+  winsys = _cogl_context_get_winsys (ctx);
+
+  return winsys->xlib_get_visual_info ();
 }
 #endif
index 9093b44..2f1642c 100644 (file)
@@ -268,6 +268,9 @@ struct _CoglContext
 CoglContext *
 _cogl_context_get_default ();
 
+const CoglWinsysVtable *
+_cogl_context_get_winsys (CoglContext *context);
+
 /* Obtains the context and returns retval if NULL */
 #define _COGL_GET_CONTEXT(ctxvar, retval) \
 CoglContext *ctxvar = _cogl_context_get_default (); \
index e1b18f6..d8dc5c6 100644 (file)
@@ -33,6 +33,8 @@
 #include "cogl-profile.h"
 #include "cogl-util.h"
 #include "cogl-context-private.h"
+#include "cogl-display-private.h"
+#include "cogl-renderer-private.h"
 #include "cogl-journal-private.h"
 #include "cogl-texture-private.h"
 #include "cogl-pipeline-private.h"
@@ -83,6 +85,12 @@ _cogl_init_feature_overrides (CoglContext *ctx)
                             COGL_FEATURE_TEXTURE_NPOT_REPEAT);
 }
 
+const CoglWinsysVtable *
+_cogl_context_get_winsys (CoglContext *context)
+{
+  return context->display->renderer->winsys_vtable;
+}
+
 /* For reference: There was some deliberation over whether to have a
  * constructor that could throw an exception but looking at standard
  * practices with several high level OO languages including python, C++,
@@ -99,6 +107,7 @@ cogl_context_new (CoglDisplay *display,
   CoglContext *context;
   GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
   unsigned long enable_flags = 0;
+  const CoglWinsysVtable *winsys;
   int i;
 
 #ifdef CLUTTER_ENABLE_PROFILE
@@ -155,7 +164,8 @@ cogl_context_new (CoglDisplay *display,
 
 #ifdef COGL_HAS_FULL_WINSYS
   context->stub_winsys = FALSE;
-  if (!_cogl_winsys_context_init (context, error))
+  winsys = _cogl_context_get_winsys (context);
+  if (!winsys->context_init (context, error))
     {
       cogl_object_unref (display);
       g_free (context);
@@ -365,7 +375,9 @@ cogl_context_new (CoglDisplay *display,
 static void
 _cogl_context_free (CoglContext *context)
 {
-  _cogl_winsys_context_deinit (context);
+  const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
+
+  winsys->context_deinit (context);
 
   _cogl_destroy_texture_units ();
 
@@ -480,7 +492,8 @@ cogl_set_default_context (CoglContext *context)
 EGLDisplay
 cogl_context_egl_get_egl_display (CoglContext *context)
 {
-  return _cogl_winsys_context_egl_get_egl_display (context);
+  const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
+  return winsys->context_egl_get_egl_display (context);
 }
 #endif
 
index a09de18..bb792b7 100644 (file)
@@ -32,6 +32,7 @@
 #include "cogl-object.h"
 
 #include "cogl-display-private.h"
+#include "cogl-renderer-private.h"
 #include "cogl-winsys-private.h"
 
 static void _cogl_display_free (CoglDisplay *display);
@@ -93,15 +94,26 @@ cogl_display_new (CoglRenderer *renderer,
   return _cogl_display_object_new (display);
 }
 
+static const CoglWinsysVtable *
+_cogl_display_get_winsys (CoglDisplay *display)
+{
+  return display->renderer->winsys_vtable;
+}
+
 gboolean
 cogl_display_setup (CoglDisplay *display,
                     GError **error)
 {
+#ifdef COGL_HAS_FULL_WINSYS
+  const CoglWinsysVtable *winsys;
+#endif
+
   if (display->setup)
     return TRUE;
 
 #ifdef COGL_HAS_FULL_WINSYS
-  if (!_cogl_winsys_display_setup (display, error))
+  winsys = _cogl_display_get_winsys (display);
+  if (!winsys->display_setup (display, error))
     return FALSE;
 #endif
 
index 8f0769d..9712fe7 100644 (file)
@@ -29,6 +29,8 @@
 #include "cogl-debug.h"
 #include "cogl-internal.h"
 #include "cogl-context-private.h"
+#include "cogl-display-private.h"
+#include "cogl-renderer-private.h"
 #include "cogl-handle.h"
 #include "cogl-object-private.h"
 #include "cogl-util.h"
@@ -231,6 +233,12 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
   cogl_object_unref (ctx);
 }
 
+static const CoglWinsysVtable *
+_cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer)
+{
+  return framebuffer->context->display->renderer->winsys_vtable;
+}
+
 /* This version of cogl_clear can be used internally as an alternative
  * to avoid flushing the journal or the framebuffer state. This is
  * needed when doing operations that may be called whiling flushing
@@ -1012,6 +1020,7 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
                            GError **error)
 {
   CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
 
   if (framebuffer->allocated)
     return TRUE;
@@ -1021,7 +1030,7 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
   g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN,
                         TRUE);
 
-  if (!_cogl_winsys_onscreen_init (onscreen, error))
+  if (!winsys->onscreen_init (onscreen, error))
     return FALSE;
 
   framebuffer->allocated = TRUE;
@@ -1032,10 +1041,14 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
 static void
 _cogl_onscreen_free (CoglOnscreen *onscreen)
 {
-  _cogl_winsys_onscreen_deinit (onscreen);
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+
+  winsys->onscreen_deinit (onscreen);
+  g_return_if_fail (onscreen->winsys == NULL);
 
   /* Chain up to parent */
-  _cogl_framebuffer_free (COGL_FRAMEBUFFER (onscreen));
+  _cogl_framebuffer_free (framebuffer);
 
   g_free (onscreen);
 }
@@ -1350,7 +1363,9 @@ bind_gl_framebuffer (CoglContext *ctx,
   else
     {
 #ifdef COGL_HAS_FULL_WINSYS
-      _cogl_winsys_onscreen_bind (COGL_ONSCREEN (framebuffer));
+      const CoglWinsysVtable *winsys =
+        _cogl_framebuffer_get_winsys (framebuffer);
+      winsys->onscreen_bind (COGL_ONSCREEN (framebuffer));
 #endif
       GE (glBindFramebuffer (target, 0));
     }
@@ -1582,7 +1597,11 @@ cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer)
   /* FIXME: we shouldn't need to flush *all* journals here! */
   cogl_flush ();
   if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
-    _cogl_winsys_onscreen_swap_buffers (COGL_ONSCREEN (framebuffer));
+    {
+      const CoglWinsysVtable *winsys =
+        _cogl_framebuffer_get_winsys (framebuffer);
+      winsys->onscreen_swap_buffers (COGL_ONSCREEN (framebuffer));
+    }
 }
 
 void
@@ -1593,9 +1612,13 @@ cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
   /* FIXME: we shouldn't need to flush *all* journals here! */
   cogl_flush ();
   if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
-    _cogl_winsys_onscreen_swap_region (COGL_ONSCREEN (framebuffer),
-                                       rectangles,
-                                       n_rectangles);
+    {
+      const CoglWinsysVtable *winsys =
+        _cogl_framebuffer_get_winsys (framebuffer);
+      winsys->onscreen_swap_region (COGL_ONSCREEN (framebuffer),
+                                    rectangles,
+                                    n_rectangles);
+    }
 }
 
 #ifdef COGL_HAS_X11_SUPPORT
@@ -1609,15 +1632,20 @@ cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen,
 guint32
 cogl_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
 {
-  return _cogl_winsys_onscreen_x11_get_window_xid (onscreen);
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+
+  return winsys->onscreen_x11_get_window_xid (onscreen);
 }
 
 guint32
 cogl_onscreen_x11_get_visual_xid (CoglOnscreen *onscreen)
 {
-  guint32 id;
-  XVisualInfo *visinfo = _cogl_winsys_xlib_get_visual_info ();
-  id = (guint32)visinfo->visualid;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+  XVisualInfo *visinfo = winsys->xlib_get_visual_info ();
+  guint32 id = (guint32)visinfo->visualid;
+
   XFree (visinfo);
   return id;
 }
@@ -1629,13 +1657,14 @@ cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer,
                                             void *user_data)
 {
   CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
 
   /* Should this just be cogl_onscreen API instead? */
   g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0);
 
-  return _cogl_winsys_onscreen_add_swap_buffers_callback (onscreen,
-                                                          callback,
-                                                          user_data);
+  return winsys->onscreen_add_swap_buffers_callback (onscreen,
+                                                     callback,
+                                                     user_data);
 }
 
 void
@@ -1643,15 +1672,21 @@ cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
                                                unsigned int id)
 {
   CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
 
-  _cogl_winsys_onscreen_remove_swap_buffers_callback (onscreen, id);
+  winsys->onscreen_remove_swap_buffers_callback (onscreen, id);
 }
 
 void
 cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
                                   gboolean throttled)
 {
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   onscreen->swap_throttled = throttled;
-  if (COGL_FRAMEBUFFER (onscreen)->allocated)
-    _cogl_winsys_onscreen_update_swap_throttled (onscreen);
+  if (framebuffer->allocated)
+    {
+      const CoglWinsysVtable *winsys =
+        _cogl_framebuffer_get_winsys (framebuffer);
+      winsys->onscreen_update_swap_throttled (onscreen);
+    }
 }
index 6600825..8b9ebe7 100644 (file)
@@ -25,6 +25,7 @@
 #define __COGL_RENDERER_PRIVATE_H
 
 #include "cogl-object-private.h"
+#include "cogl-winsys-private.h"
 
 #ifdef COGL_HAS_XLIB_SUPPORT
 #include <X11/Xlib.h>
@@ -34,6 +35,7 @@ struct _CoglRenderer
 {
   CoglObject _parent;
   gboolean connected;
+  const CoglWinsysVtable *winsys_vtable;
 #ifdef COGL_HAS_XLIB_SUPPORT
   Display *foreign_xdpy;
 #endif
index 548c2f0..613b163 100644 (file)
 #include "cogl-display-private.h"
 #include "cogl-winsys-private.h"
 
+#ifdef COGL_HAS_FULL_WINSYS
+
+#ifdef COGL_HAS_GLX_SUPPORT
+extern const CoglWinsysVtable *_cogl_winsys_glx_get_vtable (void);
+#endif
+#ifdef COGL_HAS_EGL_SUPPORT
+extern const CoglWinsysVtable *_cogl_winsys_egl_get_vtable (void);
+#endif
+
+typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void);
+
+static CoglWinsysVtableGetter _cogl_winsys_vtable_getters[] =
+{
+#ifdef COGL_HAS_GLX_SUPPORT
+  _cogl_winsys_glx_get_vtable,
+#endif
+#ifdef COGL_HAS_EGL_SUPPORT
+  _cogl_winsys_egl_get_vtable
+#endif
+};
+
+#endif /* COGL_HAS_FULL_WINSYS */
+
 static void _cogl_renderer_free (CoglRenderer *renderer);
 
 COGL_OBJECT_DEFINE (Renderer, renderer);
@@ -53,6 +76,12 @@ cogl_renderer_error_quark (void)
   return g_quark_from_static_string ("cogl-renderer-error-quark");
 }
 
+static const CoglWinsysVtable *
+_cogl_renderer_get_winsys (CoglRenderer *renderer)
+{
+  return renderer->winsys_vtable;
+}
+
 static void
 native_filter_closure_free (CoglNativeFilterClosure *closure)
 {
@@ -63,7 +92,8 @@ static void
 _cogl_renderer_free (CoglRenderer *renderer)
 {
 #ifdef COGL_HAS_FULL_WINSYS
-  _cogl_winsys_renderer_disconnect (renderer);
+  const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer);
+  winsys->renderer_disconnect (renderer);
 #endif
 
   g_slist_foreach (renderer->event_filters,
@@ -114,8 +144,9 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer,
 {
 #ifdef COGL_HAS_FULL_WINSYS
   CoglDisplay *display;
+  const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer);
 
-  if (!_cogl_winsys_renderer_connect (renderer, error))
+  if (!winsys->renderer_connect (renderer, error))
     return FALSE;
 
   display = cogl_display_new (renderer, onscreen_template);
@@ -135,16 +166,51 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer,
 gboolean
 cogl_renderer_connect (CoglRenderer *renderer, GError **error)
 {
+#ifdef COGL_HAS_FULL_WINSYS
+  int i;
+#endif
+  GString *error_message;
+
   if (renderer->connected)
     return TRUE;
 
 #ifdef COGL_HAS_FULL_WINSYS
-  if (!_cogl_winsys_renderer_connect (renderer, error))
-    return FALSE;
-#endif
+  error_message = g_string_new ("");
+  for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++)
+    {
+      const CoglWinsysVtable *winsys = _cogl_winsys_vtable_getters[i]();
+      GError *tmp_error = NULL;
+      if (!winsys->renderer_connect (renderer, &tmp_error))
+        {
+          g_string_append_c (error_message, '\n');
+          g_string_append (error_message, tmp_error->message);
+          g_error_free (tmp_error);
+        }
+      else
+        {
+          renderer->winsys_vtable = winsys;
+          renderer->connected = TRUE;
+          g_string_free (error_message, TRUE);
+          return TRUE;
+        }
+    }
 
+  if (!renderer->connected)
+    {
+      renderer->winsys_vtable = NULL;
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_INIT,
+                   "Failed to connected to any renderer: %s",
+                   error_message->str);
+      g_string_free (error_message, TRUE);
+      return FALSE;
+    }
+
+  return TRUE;
+#else
   renderer->connected = TRUE;
   return TRUE;
+#endif
 }
 
 CoglFilterReturn
index 4dbe4ae..69ed652 100644 (file)
@@ -93,8 +93,17 @@ cogl_get_proc_address (const char* name)
 {
   void *address;
   static GModule *module = NULL;
+#ifdef COGL_HAS_FULL_WINSYS
+  const CoglWinsysVtable *winsys;
 
+  _COGL_GET_CONTEXT (ctx, NULL);
+
+  winsys = _cogl_context_get_winsys (ctx);
+
+  address = winsys->get_proc_address (name);
+#else
   address = _cogl_winsys_get_proc_address (name);
+#endif
   if (address)
     return address;
 
index c59d760..01657d1 100644 (file)
@@ -42,6 +42,8 @@
 #include "cogl-texture-2d-private.h"
 #include "cogl-texture-rectangle-private.h"
 #include "cogl-context-private.h"
+#include "cogl-display-private.h"
+#include "cogl-renderer-private.h"
 #include "cogl-handle.h"
 #include "cogl-winsys-private.h"
 #include "cogl-pipeline-opengl-private.h"
@@ -101,12 +103,23 @@ cogl_damage_rectangle_is_whole (const CoglDamageRectangle *damage_rect,
           && damage_rect->x2 == width && damage_rect->y2 == height);
 }
 
+static const CoglWinsysVtable *
+_cogl_texture_pixmap_x11_get_winsys (CoglTexturePixmapX11 *tex_pixmap)
+{
+  /* FIXME: A CoglContext should be reachable from a CoglTexture
+   * pointer */
+  _COGL_GET_CONTEXT (ctx, NULL);
+
+  return ctx->display->renderer->winsys_vtable;
+}
+
 static void
 process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
                       XDamageNotifyEvent *damage_event)
 {
   Display *display;
   enum { DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode;
+  const CoglWinsysVtable *winsys;
 
   _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
 
@@ -195,7 +208,8 @@ process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
   /* If we're using the texture from pixmap extension then there's no
      point in getting the region and we can just mark that the texture
      needs updating */
-  _cogl_winsys_texture_pixmap_x11_damage_notify (tex_pixmap);
+  winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
+  winsys->texture_pixmap_x11_damage_notify (tex_pixmap);
 }
 
 static CoglFilterReturn
@@ -254,6 +268,7 @@ cogl_texture_pixmap_x11_new (guint32 pixmap,
   CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
   XWindowAttributes window_attributes;
   int damage_base;
+  const CoglWinsysVtable *winsys;
 
   _COGL_GET_CONTEXT (ctxt, COGL_INVALID_HANDLE);
 
@@ -307,7 +322,9 @@ cogl_texture_pixmap_x11_new (guint32 pixmap,
   tex_pixmap->damage_rect.y1 = 0;
   tex_pixmap->damage_rect.y2 = tex_pixmap->height;
 
-  _cogl_winsys_texture_pixmap_x11_create (tex_pixmap);
+  winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
+  if (winsys->texture_pixmap_x11_create)
+    winsys->texture_pixmap_x11_create (tex_pixmap);
 
   return _cogl_texture_pixmap_x11_handle_new (tex_pixmap);
 }
@@ -390,6 +407,7 @@ cogl_texture_pixmap_x11_update_area (CoglHandle handle,
                                      int height)
 {
   CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle);
+  const CoglWinsysVtable *winsys;
 
   if (!cogl_is_texture_pixmap_x11 (handle))
     return;
@@ -398,7 +416,8 @@ cogl_texture_pixmap_x11_update_area (CoglHandle handle,
      texture because we can't determine which will be needed until we
      actually render something */
 
-  _cogl_winsys_texture_pixmap_x11_damage_notify (tex_pixmap);
+  winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
+  winsys->texture_pixmap_x11_damage_notify (tex_pixmap);
 
   cogl_damage_rectangle_union (&tex_pixmap->damage_rect,
                                x, y, width, height);
@@ -617,7 +636,10 @@ _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
 {
   if (tex_pixmap->winsys)
     {
-      if (_cogl_winsys_texture_pixmap_x11_update (tex_pixmap, needs_mipmap))
+      const CoglWinsysVtable *winsys =
+        _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
+
+      if (winsys->texture_pixmap_x11_update (tex_pixmap, needs_mipmap))
         {
           _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE);
           return;
@@ -649,7 +671,11 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
   for (i = 0; i < 2; i++)
     {
       if (tex_pixmap->use_winsys_texture)
-        tex = _cogl_winsys_texture_pixmap_x11_get_texture (tex_pixmap);
+        {
+          const CoglWinsysVtable *winsys =
+            _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
+          tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap);
+        }
       else
         tex = tex_pixmap->tex;
 
@@ -912,7 +938,11 @@ _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
     cogl_handle_unref (tex_pixmap->tex);
 
   if (tex_pixmap->winsys)
-    _cogl_winsys_texture_pixmap_x11_free (tex_pixmap);
+    {
+      const CoglWinsysVtable *winsys =
+        _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
+      winsys->texture_pixmap_x11_free (tex_pixmap);
+    }
 
   /* Chain up */
   _cogl_texture_free (COGL_TEXTURE (tex_pixmap));
index 44583af..46f5842 100644 (file)
@@ -168,7 +168,7 @@ static const CoglFeatureData winsys_feature_data[] =
 #include "cogl-winsys-egl-feature-functions.h"
   };
 
-CoglFuncPtr
+static CoglFuncPtr
 _cogl_winsys_get_proc_address (const char *name)
 {
   return (CoglFuncPtr) eglGetProcAddress (name);
@@ -237,7 +237,21 @@ event_filter_cb (void *event, void *data)
 }
 #endif /* COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT */
 
-gboolean
+static void
+_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
+{
+  CoglRendererEGL *egl_renderer = renderer->winsys;
+
+#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
+  _cogl_renderer_xlib_disconnect (renderer);
+#endif
+
+  eglTerminate (egl_renderer->edpy);
+
+  g_slice_free (CoglRendererEGL, egl_renderer);
+}
+
+static gboolean
 _cogl_winsys_renderer_connect (CoglRenderer *renderer,
                                GError **error)
 {
@@ -285,21 +299,7 @@ error:
   return FALSE;
 }
 
-void
-_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
-{
-  CoglRendererEGL *egl_renderer = renderer->winsys;
-
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-  _cogl_renderer_xlib_disconnect (renderer);
-#endif
-
-  eglTerminate (egl_renderer->edpy);
-
-  g_slice_free (CoglRendererEGL, egl_renderer);
-}
-
-void
+static void
 update_winsys_features (CoglContext *context)
 {
   CoglDisplayEGL *egl_display = context->display->winsys;
@@ -675,7 +675,20 @@ create_context (CoglDisplay *display, GError **error)
   return status;
 }
 
-gboolean
+static void
+_cogl_winsys_display_destroy (CoglDisplay *display)
+{
+  CoglDisplayEGL *egl_display = display->winsys;
+
+  g_return_if_fail (egl_display != NULL);
+
+  cleanup_context (display);
+
+  g_slice_free (CoglDisplayEGL, display->winsys);
+  display->winsys = NULL;
+}
+
+static gboolean
 _cogl_winsys_display_setup (CoglDisplay *display,
                             GError **error)
 {
@@ -698,20 +711,7 @@ error:
   return FALSE;
 }
 
-void
-_cogl_winsys_display_destroy (CoglDisplay *display)
-{
-  CoglDisplayEGL *egl_display = display->winsys;
-
-  g_return_if_fail (egl_display != NULL);
-
-  cleanup_context (display);
-
-  g_slice_free (CoglDisplayEGL, display->winsys);
-  display->winsys = NULL;
-}
-
-gboolean
+static gboolean
 _cogl_winsys_context_init (CoglContext *context, GError **error)
 {
   context->winsys = g_new0 (CoglContextEGL, 1);
@@ -726,7 +726,7 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
   return TRUE;
 }
 
-void
+static void
 _cogl_winsys_context_deinit (CoglContext *context)
 {
 #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
@@ -737,7 +737,7 @@ _cogl_winsys_context_deinit (CoglContext *context)
   g_free (context->winsys);
 }
 
-gboolean
+static gboolean
 _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
                             GError **error)
 {
@@ -896,7 +896,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
   return TRUE;
 }
 
-void
+static void
 _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
@@ -941,7 +941,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
 #endif
 }
 
-void
+static void
 _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
 {
   CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
@@ -982,7 +982,7 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
     eglSwapInterval (egl_renderer->edpy, 0);
 }
 
-void
+static void
 _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
                                    int *rectangles,
                                    int n_rectangles)
@@ -998,14 +998,14 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
     g_warning ("Error reported by eglSwapBuffersRegion");
 }
 
-guint32
+static guint32
 _cogl_winsys_get_vsync_counter (void)
 {
   /* Unsupported feature */
   return 0;
 }
 
-void
+static void
 _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
 {
   CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
@@ -1015,14 +1015,14 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
   eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface);
 }
 
-guint32
+static guint32
 _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
 {
   CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
   return xlib_onscreen->xwin;
 }
 
-unsigned int
+static unsigned int
 _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
                                                  CoglSwapBuffersNotify callback,
                                                  void *user_data)
@@ -1031,14 +1031,14 @@ _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
   return 0;
 }
 
-void
+static void
 _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
                                                     unsigned int id)
 {
   /* Unsupported feature */
 }
 
-void
+static void
 _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
 {
   CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
@@ -1054,7 +1054,7 @@ _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
 
 #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
 /* XXX: This is a particularly hacky _cogl_winsys interface... */
-XVisualInfo *
+static XVisualInfo *
 _cogl_winsys_xlib_get_visual_info (void)
 {
   CoglDisplayEGL *egl_display;
@@ -1072,7 +1072,7 @@ _cogl_winsys_xlib_get_visual_info (void)
 }
 #endif
 
-EGLDisplay
+static EGLDisplay
 _cogl_winsys_context_egl_get_egl_display (CoglContext *context)
 {
   CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
@@ -1080,37 +1080,47 @@ _cogl_winsys_context_egl_get_egl_display (CoglContext *context)
   return egl_renderer->edpy;
 }
 
-#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
-gboolean
-_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
-{
-  /* Unsupported feature */
-  tex_pixmap->winsys = NULL;
-  return FALSE;
-}
-
-void
-_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
-{
-  /* Unsupported feature */
-}
-
-gboolean
-_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
-                                        gboolean needs_mipmap)
-{
-  /* Unsupported feature */
-}
-
-void
-_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
-{
-  /* Unsupported feature */
-}
+static CoglWinsysVtable _cogl_winsys_vtable =
+  {
+    .get_proc_address = _cogl_winsys_get_proc_address,
+    .renderer_connect = _cogl_winsys_renderer_connect,
+    .renderer_disconnect = _cogl_winsys_renderer_disconnect,
+    .display_setup = _cogl_winsys_display_setup,
+    .display_destroy = _cogl_winsys_display_destroy,
+    .context_init = _cogl_winsys_context_init,
+    .context_deinit = _cogl_winsys_context_deinit,
+    .context_egl_get_egl_display =
+      _cogl_winsys_context_egl_get_egl_display,
+#ifdef COGL_HAS_XLIB_SUPPORT
+    .xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info,
+#endif
+    .onscreen_init = _cogl_winsys_onscreen_init,
+    .onscreen_deinit = _cogl_winsys_onscreen_deinit,
+    .onscreen_bind = _cogl_winsys_onscreen_bind,
+    .onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers,
+    .onscreen_swap_region = _cogl_winsys_onscreen_swap_region,
+    .onscreen_update_swap_throttled =
+      _cogl_winsys_onscreen_update_swap_throttled,
+    .onscreen_x11_get_window_xid =
+      _cogl_winsys_onscreen_x11_get_window_xid,
+    .onscreen_add_swap_buffers_callback =
+      _cogl_winsys_onscreen_add_swap_buffers_callback,
+    .onscreen_remove_swap_buffers_callback =
+      _cogl_winsys_onscreen_remove_swap_buffers_callback,
+    .get_vsync_counter = _cogl_winsys_get_vsync_counter
+  };
 
-CoglHandle
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
+/* XXX: we use a function because no doubt someone will complain
+ * about using c99 member initializers because they aren't portable
+ * to windows. We want to avoid having to rigidly follow the real
+ * order of members since some members are #ifdefd and we'd have
+ * to mirror the #ifdefing to add padding etc. For any winsys that
+ * can assume the platform has a sane compiler then we can just use
+ * c99 initializers for insane platforms they can initialize
+ * the members by name in a function.
+ */
+const CoglWinsysVtable *
+_cogl_winsys_egl_get_vtable (void)
 {
-  /* Unsupported feature */
+  return &_cogl_winsys_vtable;
 }
-#endif
index 7668a5f..26ad6e6 100644 (file)
@@ -277,7 +277,15 @@ glx_event_filter_cb (void *native_event, void *data)
   return COGL_FILTER_CONTINUE;
 }
 
-gboolean
+static void
+_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
+{
+  _cogl_renderer_xlib_disconnect (renderer);
+
+  g_slice_free (CoglRendererGLX, renderer->winsys);
+}
+
+static gboolean
 _cogl_winsys_renderer_connect (CoglRenderer *renderer,
                                GError **error)
 {
@@ -325,15 +333,7 @@ error:
   return FALSE;
 }
 
-void
-_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
-{
-  _cogl_renderer_xlib_disconnect (renderer);
-
-  g_slice_free (CoglRendererGLX, renderer->winsys);
-}
-
-void
+static void
 update_winsys_features (CoglContext *context)
 {
   CoglDisplayGLX *glx_display = context->display->winsys;
@@ -625,32 +625,7 @@ create_context (CoglDisplay *display, GError **error)
   return TRUE;
 }
 
-gboolean
-_cogl_winsys_display_setup (CoglDisplay *display,
-                            GError **error)
-{
-  CoglDisplayGLX *glx_display;
-  int i;
-
-  g_return_val_if_fail (display->winsys == NULL, FALSE);
-
-  glx_display = g_slice_new0 (CoglDisplayGLX);
-  display->winsys = glx_display;
-
-  if (!create_context (display, error))
-    goto error;
-
-  for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++)
-    glx_display->glx_cached_configs[i].depth = -1;
-
-  return TRUE;
-
-error:
-  _cogl_winsys_display_destroy (display);
-  return FALSE;
-}
-
-void
+static void
 _cogl_winsys_display_destroy (CoglDisplay *display)
 {
   CoglDisplayGLX *glx_display = display->winsys;
@@ -682,7 +657,32 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
   display->winsys = NULL;
 }
 
-gboolean
+static gboolean
+_cogl_winsys_display_setup (CoglDisplay *display,
+                            GError **error)
+{
+  CoglDisplayGLX *glx_display;
+  int i;
+
+  g_return_val_if_fail (display->winsys == NULL, FALSE);
+
+  glx_display = g_slice_new0 (CoglDisplayGLX);
+  display->winsys = glx_display;
+
+  if (!create_context (display, error))
+    goto error;
+
+  for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++)
+    glx_display->glx_cached_configs[i].depth = -1;
+
+  return TRUE;
+
+error:
+  _cogl_winsys_display_destroy (display);
+  return FALSE;
+}
+
+static gboolean
 _cogl_winsys_context_init (CoglContext *context, GError **error)
 {
   context->winsys = g_new0 (CoglContextGLX, 1);
@@ -695,7 +695,7 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
   return TRUE;
 }
 
-void
+static void
 _cogl_winsys_context_deinit (CoglContext *context)
 {
   cogl_renderer_remove_native_filter (context->display->renderer,
@@ -704,7 +704,7 @@ _cogl_winsys_context_deinit (CoglContext *context)
   g_free (context->winsys);
 }
 
-gboolean
+static gboolean
 _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
                             GError **error)
 {
@@ -859,7 +859,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
   return TRUE;
 }
 
-void
+static void
 _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
@@ -890,7 +890,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
   _cogl_xlib_untrap_errors (&old_state);
 }
 
-void
+static void
 _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
 {
   CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
@@ -1002,7 +1002,7 @@ drm_wait_vblank (int fd, drm_wait_vblank_t *vbl)
 }
 #endif /* HAVE_DRM */
 
-void
+static void
 _cogl_winsys_wait_for_vblank (void)
 {
   CoglRendererGLX *glx_renderer;
@@ -1034,7 +1034,22 @@ _cogl_winsys_wait_for_vblank (void)
 #endif /* HAVE_DRM */
 }
 
-void
+static guint32
+_cogl_winsys_get_vsync_counter (void)
+{
+  guint32 video_sync_count;
+  CoglRendererGLX *glx_renderer;
+
+  _COGL_GET_CONTEXT (ctx, 0);
+
+  glx_renderer = ctx->display->renderer->winsys;
+
+  glx_renderer->pf_glXGetVideoSync (&video_sync_count);
+
+  return video_sync_count;
+}
+
+static void
 _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
                                    int *rectangles,
                                    int n_rectangles)
@@ -1167,22 +1182,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
     glx_onscreen->last_swap_vsync_counter = end_frame_vsync_counter;
 }
 
-guint32
-_cogl_winsys_get_vsync_counter (void)
-{
-  guint32 video_sync_count;
-  CoglRendererGLX *glx_renderer;
-
-  _COGL_GET_CONTEXT (ctx, 0);
-
-  glx_renderer = ctx->display->renderer->winsys;
-
-  glx_renderer->pf_glXGetVideoSync (&video_sync_count);
-
-  return video_sync_count;
-}
-
-void
+static void
 _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
@@ -1259,14 +1259,14 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
     glx_onscreen->last_swap_vsync_counter = _cogl_winsys_get_vsync_counter ();
 }
 
-guint32
+static guint32
 _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
 {
   CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
   return xlib_onscreen->xwin;
 }
 
-unsigned int
+static unsigned int
 _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
                                                  CoglSwapBuffersNotify callback,
                                                  void *user_data)
@@ -1285,7 +1285,7 @@ _cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
   return entry->id;
 }
 
-void
+static void
 _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
                                                     unsigned int id)
 {
@@ -1305,7 +1305,7 @@ _cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
     }
 }
 
-void
+static void
 _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
 {
   CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
@@ -1323,7 +1323,7 @@ _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
 }
 
 /* XXX: This is a particularly hacky _cogl_winsys interface... */
-XVisualInfo *
+static XVisualInfo *
 _cogl_winsys_xlib_get_visual_info (void)
 {
   CoglDisplayGLX *glx_display;
@@ -1616,7 +1616,7 @@ try_create_glx_pixmap (CoglContext *context,
   return TRUE;
 }
 
-gboolean
+static gboolean
 _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
 {
   CoglTexturePixmapGLX *glx_tex_pixmap;
@@ -1697,7 +1697,7 @@ free_glx_pixmap (CoglContext *context,
   glx_tex_pixmap->pixmap_bound = FALSE;
 }
 
-void
+static void
 _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
 {
   CoglTexturePixmapGLX *glx_tex_pixmap;
@@ -1720,7 +1720,7 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
   g_free (glx_tex_pixmap);
 }
 
-gboolean
+static gboolean
 _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
                                         gboolean needs_mipmap)
 {
@@ -1861,7 +1861,7 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
   return TRUE;
 }
 
-void
+static void
 _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
 {
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
@@ -1869,10 +1869,66 @@ _cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap)
   glx_tex_pixmap->bind_tex_image_queued = TRUE;
 }
 
-CoglHandle
+static CoglHandle
 _cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
 {
   CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
 
   return glx_tex_pixmap->glx_tex;
 }
+
+
+static CoglWinsysVtable _cogl_winsys_vtable =
+  {
+    .get_proc_address = _cogl_winsys_get_proc_address,
+    .renderer_connect = _cogl_winsys_renderer_connect,
+    .renderer_disconnect = _cogl_winsys_renderer_disconnect,
+    .display_setup = _cogl_winsys_display_setup,
+    .display_destroy = _cogl_winsys_display_destroy,
+    .context_init = _cogl_winsys_context_init,
+    .context_deinit = _cogl_winsys_context_deinit,
+    .xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info,
+    .onscreen_init = _cogl_winsys_onscreen_init,
+    .onscreen_deinit = _cogl_winsys_onscreen_deinit,
+    .onscreen_bind = _cogl_winsys_onscreen_bind,
+    .onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers,
+    .onscreen_swap_region = _cogl_winsys_onscreen_swap_region,
+    .onscreen_update_swap_throttled =
+      _cogl_winsys_onscreen_update_swap_throttled,
+    .onscreen_x11_get_window_xid =
+      _cogl_winsys_onscreen_x11_get_window_xid,
+    .onscreen_add_swap_buffers_callback =
+      _cogl_winsys_onscreen_add_swap_buffers_callback,
+    .onscreen_remove_swap_buffers_callback =
+      _cogl_winsys_onscreen_remove_swap_buffers_callback,
+    .get_vsync_counter = _cogl_winsys_get_vsync_counter,
+
+    /* X11 tfp support... */
+    /* XXX: instead of having a rather monolithic winsys vtable we could
+     * perhaps look for a way to separate these... */
+    .texture_pixmap_x11_create =
+      _cogl_winsys_texture_pixmap_x11_create,
+    .texture_pixmap_x11_free =
+      _cogl_winsys_texture_pixmap_x11_free,
+    .texture_pixmap_x11_update =
+      _cogl_winsys_texture_pixmap_x11_update,
+    .texture_pixmap_x11_damage_notify =
+      _cogl_winsys_texture_pixmap_x11_damage_notify,
+    .texture_pixmap_x11_get_texture =
+      _cogl_winsys_texture_pixmap_x11_get_texture,
+  };
+
+/* XXX: we use a function because no doubt someone will complain
+ * about using c99 member initializers because they aren't portable
+ * to windows. We want to avoid having to rigidly follow the real
+ * order of members since some members are #ifdefd and we'd have
+ * to mirror the #ifdefing to add padding etc. For any winsys that
+ * can assume the platform has a sane compiler then we can just use
+ * c99 initializers for insane platforms they can initialize
+ * the members by name in a function.
+ */
+const CoglWinsysVtable *
+_cogl_winsys_glx_get_vtable (void)
+{
+  return &_cogl_winsys_vtable;
+}
index 150f2dc..a610848 100644 (file)
@@ -31,6 +31,7 @@
 
 #ifdef COGL_HAS_XLIB_SUPPORT
 #include <X11/Xutil.h>
+#include "cogl-texture-pixmap-x11-private.h"
 #endif
 
 GQuark
@@ -51,95 +52,94 @@ typedef enum
   COGL_WINSYS_RECTANGLE_STATE_ENABLE
 } CoglWinsysRectangleState;
 
-CoglFuncPtr
-_cogl_winsys_get_proc_address (const char *name);
+typedef struct _CoglWinsysVtable
+{
+  CoglFuncPtr
+  (*get_proc_address) (const char *name);
 
-gboolean
-_cogl_winsys_renderer_connect (CoglRenderer *renderer,
-                               GError **error);
+  gboolean
+  (*renderer_connect) (CoglRenderer *renderer, GError **error);
 
-void
-_cogl_winsys_renderer_disconnect (CoglRenderer *renderer);
+  void
+  (*renderer_disconnect) (CoglRenderer *renderer);
 
-gboolean
-_cogl_winsys_display_setup (CoglDisplay *display,
-                            GError **error);
+  gboolean
+  (*display_setup) (CoglDisplay *display, GError **error);
 
-void
-_cogl_winsys_display_destroy (CoglDisplay *display);
+  void
+  (*display_destroy) (CoglDisplay *display);
 
-gboolean
-_cogl_winsys_context_init (CoglContext *context, GError **error);
+  gboolean
+  (*context_init) (CoglContext *context, GError **error);
 
-void
-_cogl_winsys_context_deinit (CoglContext *context);
+  void
+  (*context_deinit) (CoglContext *context);
 
 #ifdef COGL_HAS_EGL_SUPPORT
-EGLDisplay
-_cogl_winsys_context_egl_get_egl_display (CoglContext *context);
+  EGLDisplay
+  (*context_egl_get_egl_display) (CoglContext *context);
 #endif
 
-gboolean
-_cogl_winsys_has_feature (CoglWinsysFeature feature);
+  gboolean
+  (*has_feature) (CoglWinsysFeature feature);
 
 #ifdef COGL_HAS_XLIB_SUPPORT
-XVisualInfo *
-_cogl_winsys_xlib_get_visual_info (void);
+  XVisualInfo *
+  (*xlib_get_visual_info) (void);
 #endif
 
-gboolean
-_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
-                            GError **error);
+  gboolean
+  (*onscreen_init) (CoglOnscreen *onscreen, GError **error);
 
-void
-_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen);
+  void
+  (*onscreen_deinit) (CoglOnscreen *onscreen);
 
-void
-_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen);
+  void
+  (*onscreen_bind) (CoglOnscreen *onscreen);
 
-void
-_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen);
+  void
+  (*onscreen_swap_buffers) (CoglOnscreen *onscreen);
 
-void
-_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
-                                   int *rectangles,
-                                   int n_rectangles);
+  void
+  (*onscreen_swap_region) (CoglOnscreen *onscreen,
+                           int *rectangles,
+                           int n_rectangles);
 
-void
-_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen);
+  void
+  (*onscreen_update_swap_throttled) (CoglOnscreen *onscreen);
 
-guint32
-_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen);
+  guint32
+  (*onscreen_x11_get_window_xid) (CoglOnscreen *onscreen);
 
-guint32
-_cogl_winsys_get_vsync_counter (void);
+  unsigned int
+  (*onscreen_add_swap_buffers_callback) (CoglOnscreen *onscreen,
+                                         CoglSwapBuffersNotify callback,
+                                         void *user_data);
 
-unsigned int
-_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
-                                                 CoglSwapBuffersNotify callback,
-                                                 void *user_data);
+  void
+  (*onscreen_remove_swap_buffers_callback) (CoglOnscreen *onscreen,
+                                            unsigned int id);
 
-void
-_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
-                                                    unsigned int id);
+  guint32
+  (*get_vsync_counter) (void);
 
 #ifdef COGL_HAS_XLIB_SUPPORT
-gboolean
-_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap);
+  gboolean
+  (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap);
+  void
+  (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap);
 
-void
-_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap);
+  gboolean
+  (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap,
+                                gboolean needs_mipmap);
 
-gboolean
-_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
-                                        gboolean needs_mipmap);
+  void
+  (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap);
 
-void
-_cogl_winsys_texture_pixmap_x11_damage_notify (
-                                            CoglTexturePixmapX11 *tex_pixmap);
-
-CoglHandle
-_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap);
+  CoglHandle
+  (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap);
 #endif
 
+} CoglWinsysVtable;
+
 #endif /* __COGL_WINSYS_PRIVATE_H */