commit:     2c00b2f8422f0ea593daa6792c3ec6caf83210ef
Author:     Pacho Ramos <pacho <AT> gentoo <DOT> org>
AuthorDate: Sat Oct  3 09:02:56 2015 +0000
Commit:     Pacho Ramos <pacho <AT> gentoo <DOT> org>
CommitDate: Sat Oct  3 09:02:56 2015 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2c00b2f8

x11-wm/mutter: Apply some upstream fixes from 3.16 branch and also stop 
crashing when keymap cannot be get on a first try (from master)

Package-Manager: portage-2.2.22

 .../mutter-3.16.3-GL_EXT_x11_sync_object.patch     | 840 +++++++++++++++++++++
 .../mutter/files/mutter-3.16.3-crash-border.patch  |  32 +
 .../files/mutter-3.16.3-fallback-keymap.patch      |  28 +
 x11-wm/mutter/files/mutter-3.16.3-fix-race.patch   | 114 +++
 x11-wm/mutter/files/mutter-3.16.3-fix-return.patch |  32 +
 x11-wm/mutter/files/mutter-3.16.3-flickering.patch | 114 +++
 x11-wm/mutter/mutter-3.16.3-r1.ebuild              | 114 +++
 7 files changed, 1274 insertions(+)

diff --git a/x11-wm/mutter/files/mutter-3.16.3-GL_EXT_x11_sync_object.patch 
b/x11-wm/mutter/files/mutter-3.16.3-GL_EXT_x11_sync_object.patch
new file mode 100644
index 0000000..401c175
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.16.3-GL_EXT_x11_sync_object.patch
@@ -0,0 +1,840 @@
+From 9cc80497a262edafc58062fd860ef7a9dcab688c Mon Sep 17 00:00:00 2001
+From: Rui Matos <[email protected]>
+Date: Fri, 18 Apr 2014 20:21:20 +0200
+Subject: compositor: Add support for GL_EXT_x11_sync_object
+
+If GL advertises this extension we'll use it to synchronize X with GL
+rendering instead of relying on the XSync() behavior with open source
+drivers.
+
+Some driver bugs were uncovered while working on this so if we have
+had to reboot the ring a few times, something is probably wrong and
+we're likely to just make things worse by continuing to try.  Let's
+err on the side of caution, disable ourselves and fallback to the
+XSync() path in the compositor.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=728464
+
+diff --git a/configure.ac b/configure.ac
+index 01d75cb..6eea6b2 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -332,6 +332,11 @@ fi
+ 
+ GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
+ 
++AC_CHECK_DECL([GL_EXT_x11_sync_object],
++              [],
++              [AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, 
please update your GL headers])],
++              [#include <GL/glx.h>])
++
+ #### Warnings (last since -Werror can disturb other tests)
+ 
+ # Stay command-line compatible with the gnome-common configure option. Here
+diff --git a/src/Makefile.am b/src/Makefile.am
+index baadb41..a4e07a9 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -139,6 +139,8 @@ libmutter_la_SOURCES =                             \
+       compositor/meta-surface-actor.h         \
+       compositor/meta-surface-actor-x11.c     \
+       compositor/meta-surface-actor-x11.h     \
++      compositor/meta-sync-ring.c             \
++      compositor/meta-sync-ring.h             \
+       compositor/meta-texture-rectangle.c     \
+       compositor/meta-texture-rectangle.h     \
+       compositor/meta-texture-tower.c         \
+diff --git a/src/backends/x11/meta-backend-x11.c 
b/src/backends/x11/meta-backend-x11.c
+index 3ff8431..ac38ffc 100644
+--- a/src/backends/x11/meta-backend-x11.c
++++ b/src/backends/x11/meta-backend-x11.c
+@@ -45,6 +45,7 @@
+ #include <meta/util.h>
+ #include "display-private.h"
+ #include "compositor/compositor-private.h"
++#include "compositor/meta-sync-ring.h"
+ 
+ struct _MetaBackendX11Private
+ {
+@@ -255,6 +256,8 @@ handle_host_xevent (MetaBackend *backend,
+         MetaCompositor *compositor = display->compositor;
+         if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
+           bypass_clutter = TRUE;
++        if (compositor->have_x11_sync_object)
++          meta_sync_ring_handle_event (event);
+       }
+   }
+ 
+diff --git a/src/compositor/compositor-private.h 
b/src/compositor/compositor-private.h
+index 80fb4e2..9e3e73d 100644
+--- a/src/compositor/compositor-private.h
++++ b/src/compositor/compositor-private.h
+@@ -15,7 +15,8 @@ struct _MetaCompositor
+ {
+   MetaDisplay    *display;
+ 
+-  guint           repaint_func_id;
++  guint           pre_paint_func_id;
++  guint           post_paint_func_id;
+ 
+   gint64          server_time_query_time;
+   gint64          server_time_offset;
+@@ -40,6 +41,7 @@ struct _MetaCompositor
+   MetaPluginManager *plugin_mgr;
+ 
+   gboolean frame_has_updated_xsurfaces;
++  gboolean have_x11_sync_object;
+ };
+ 
+ /* Wait 2ms after vblank before starting to draw next frame */
+diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
+index 250d489..554faa1 100644
+--- a/src/compositor/compositor.c
++++ b/src/compositor/compositor.c
+@@ -79,6 +79,7 @@
+ #include "frame.h"
+ #include <X11/extensions/shape.h>
+ #include <X11/extensions/Xcomposite.h>
++#include "meta-sync-ring.h"
+ 
+ #include "backends/x11/meta-backend-x11.h"
+ 
+@@ -125,7 +126,11 @@ meta_switch_workspace_completed (MetaCompositor 
*compositor)
+ void
+ meta_compositor_destroy (MetaCompositor *compositor)
+ {
+-  clutter_threads_remove_repaint_func (compositor->repaint_func_id);
++  clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
++  clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
++
++  if (compositor->have_x11_sync_object)
++    meta_sync_ring_destroy ();
+ }
+ 
+ static void
+@@ -468,13 +473,11 @@ meta_compositor_manage (MetaCompositor *compositor)
+   MetaDisplay *display = compositor->display;
+   Display *xdisplay = display->xdisplay;
+   MetaScreen *screen = display->screen;
++  MetaBackend *backend = meta_get_backend ();
+ 
+   meta_screen_set_cm_selection (display->screen);
+ 
+-  {
+-    MetaBackend *backend = meta_get_backend ();
+-    compositor->stage = meta_backend_get_stage (backend);
+-  }
++  compositor->stage = meta_backend_get_stage (backend);
+ 
+   /* We use connect_after() here to accomodate code in GNOME Shell that,
+    * when benchmarking drawing performance, connects to ::after-paint
+@@ -510,7 +513,7 @@ meta_compositor_manage (MetaCompositor *compositor)
+ 
+       compositor->output = screen->composite_overlay_window;
+ 
+-      xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend 
()));
++      xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
+ 
+       XReparentWindow (xdisplay, xwin, compositor->output, 0, 0);
+ 
+@@ -530,6 +533,9 @@ meta_compositor_manage (MetaCompositor *compositor)
+        * contents until we show the stage.
+        */
+       XMapWindow (xdisplay, compositor->output);
++
++      compositor->have_x11_sync_object =
++        meta_sync_ring_init (meta_backend_x11_get_xdisplay (META_BACKEND_X11 
(backend)));
+     }
+ 
+   redirect_windows (display->screen);
+@@ -1044,11 +1050,12 @@ frame_callback (CoglOnscreen  *onscreen,
+     }
+ }
+ 
+-static void
+-pre_paint_windows (MetaCompositor *compositor)
++static gboolean
++meta_pre_paint_func (gpointer data)
+ {
+   GList *l;
+   MetaWindowActor *top_window;
++  MetaCompositor *compositor = data;
+ 
+   if (compositor->onscreen == NULL)
+     {
+@@ -1060,7 +1067,7 @@ pre_paint_windows (MetaCompositor *compositor)
+     }
+ 
+   if (compositor->windows == NULL)
+-    return;
++    return TRUE;
+ 
+   top_window = g_list_last (compositor->windows)->data;
+ 
+@@ -1077,10 +1084,12 @@ pre_paint_windows (MetaCompositor *compositor)
+     {
+       /* We need to make sure that any X drawing that happens before
+        * the XDamageSubtract() for each window above is visible to
+-       * subsequent GL rendering; the only standardized way to do this
+-       * is EXT_x11_sync_object, which isn't yet widely available. For
+-       * now, we count on details of Xorg and the open source drivers,
+-       * and hope for the best otherwise.
++       * subsequent GL rendering; the standardized way to do this is
++       * GL_EXT_X11_sync_object. Since this isn't implemented yet in
++       * mesa, we also have a path that relies on the implementation
++       * of the open source drivers.
++       *
++       * Anything else, we just hope for the best.
+        *
+        * Xorg and open source driver specifics:
+        *
+@@ -1095,17 +1104,28 @@ pre_paint_windows (MetaCompositor *compositor)
+        * round trip request at this point is sufficient to flush the
+        * GLX buffers.
+        */
+-      XSync (compositor->display->xdisplay, False);
+-
+-      compositor->frame_has_updated_xsurfaces = FALSE;
++      if (compositor->have_x11_sync_object)
++        compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
++      else
++        XSync (compositor->display->xdisplay, False);
+     }
++
++  return TRUE;
+ }
+ 
+ static gboolean
+-meta_repaint_func (gpointer data)
++meta_post_paint_func (gpointer data)
+ {
+   MetaCompositor *compositor = data;
+-  pre_paint_windows (compositor);
++
++  if (compositor->frame_has_updated_xsurfaces)
++    {
++      if (compositor->have_x11_sync_object)
++        compositor->have_x11_sync_object = meta_sync_ring_after_frame ();
++
++      compositor->frame_has_updated_xsurfaces = FALSE;
++    }
++
+   return TRUE;
+ }
+ 
+@@ -1140,10 +1160,16 @@ meta_compositor_new (MetaDisplay *display)
+                     G_CALLBACK (on_shadow_factory_changed),
+                     compositor);
+ 
+-  compositor->repaint_func_id = clutter_threads_add_repaint_func 
(meta_repaint_func,
+-                                                                  compositor,
+-                                                                  NULL);
+-
++  compositor->pre_paint_func_id =
++    clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
++                                           meta_pre_paint_func,
++                                           compositor,
++                                           NULL);
++  compositor->post_paint_func_id =
++    clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
++                                           meta_post_paint_func,
++                                           compositor,
++                                           NULL);
+   return compositor;
+ }
+ 
+diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
+new file mode 100644
+index 0000000..4ee61f8
+--- /dev/null
++++ b/src/compositor/meta-sync-ring.c
+@@ -0,0 +1,566 @@
++/*
++ * This is based on an original C++ implementation for compiz that
++ * carries the following copyright notice:
++ *
++ *
++ * Copyright © 2011 NVIDIA Corporation
++ *
++ * Permission to use, copy, modify, distribute, and sell this software
++ * and its documentation for any purpose is hereby granted without
++ * fee, provided that the above copyright notice appear in all copies
++ * and that both that copyright notice and this permission notice
++ * appear in supporting documentation, and that the name of NVIDIA
++ * Corporation not be used in advertising or publicity pertaining to
++ * distribution of the software without specific, written prior
++ * permission.  NVIDIA Corporation makes no representations about the
++ * suitability of this software for any purpose. It is provided "as
++ * is" without express or implied warranty.
++ *
++ * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
++ * FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
++ * SOFTWARE.
++ *
++ * Authors: James Jones <[email protected]>
++ */
++
++#include <string.h>
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <X11/extensions/sync.h>
++
++#include <cogl/cogl.h>
++#include <clutter/clutter.h>
++
++#include <meta/util.h>
++
++#include "meta-sync-ring.h"
++
++/* Theory of operation:
++ *
++ * We use a ring of NUM_SYNCS fence objects. On each frame we advance
++ * to the next fence in the ring. For each fence we do:
++ *
++ * 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
++ * 2. NUM_SYNCS / 2 frames later, fence should be triggered
++ * 3. fence is XSyncResetFence()'d
++ * 4. NUM_SYNCS / 2 frames later, fence should be reset
++ * 5. go back to 1 and re-use fence
++ *
++ * glClientWaitSync() and XAlarms are used in steps 2 and 4,
++ * respectively, to double-check the expectections.
++ */
++
++#define NUM_SYNCS 10
++#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
++#define MAX_REBOOT_ATTEMPTS 2
++
++typedef enum
++{
++  META_SYNC_STATE_READY,
++  META_SYNC_STATE_WAITING,
++  META_SYNC_STATE_DONE,
++  META_SYNC_STATE_RESET_PENDING,
++} MetaSyncState;
++
++typedef struct
++{
++  Display *xdisplay;
++
++  XSyncFence xfence;
++  GLsync glsync;
++
++  XSyncCounter xcounter;
++  XSyncAlarm xalarm;
++  XSyncValue next_counter_value;
++
++  MetaSyncState state;
++} MetaSync;
++
++typedef struct
++{
++  Display *xdisplay;
++  int xsync_event_base;
++  int xsync_error_base;
++
++  GHashTable *alarm_to_sync;
++
++  MetaSync *syncs_array[NUM_SYNCS];
++  guint current_sync_idx;
++  MetaSync *current_sync;
++  guint warmup_syncs;
++
++  guint reboots;
++} MetaSyncRing;
++
++static MetaSyncRing meta_sync_ring = { 0 };
++
++static XSyncValue SYNC_VALUE_ZERO;
++static XSyncValue SYNC_VALUE_ONE;
++
++static const char*      (*meta_gl_get_string) (GLenum name);
++static void             (*meta_gl_get_integerv) (GLenum  pname,
++                                                 GLint  *params);
++static const char*      (*meta_gl_get_stringi) (GLenum name,
++                                                GLuint index);
++static void             (*meta_gl_delete_sync) (GLsync sync);
++static GLenum           (*meta_gl_client_wait_sync) (GLsync sync,
++                                                     GLbitfield flags,
++                                                     GLuint64 timeout);
++static void             (*meta_gl_wait_sync) (GLsync sync,
++                                              GLbitfield flags,
++                                              GLuint64 timeout);
++static GLsync           (*meta_gl_import_sync) (GLenum external_sync_type,
++                                                GLintptr external_sync,
++                                                GLbitfield flags);
++
++static MetaSyncRing *
++meta_sync_ring_get (void)
++{
++  if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
++    return NULL;
++
++  return &meta_sync_ring;
++}
++
++static gboolean
++load_gl_symbol (const char  *name,
++                void       **func)
++{
++  *func = cogl_get_proc_address (name);
++  if (!*func)
++    {
++      meta_verbose ("MetaSyncRing: failed to resolve required GL symbol 
\"%s\"\n", name);
++      return FALSE;
++    }
++  return TRUE;
++}
++
++static gboolean
++check_gl_extensions (void)
++{
++  ClutterBackend *backend;
++  CoglContext *cogl_context;
++  CoglDisplay *cogl_display;
++  CoglRenderer *cogl_renderer;
++
++  backend = clutter_get_default_backend ();
++  cogl_context = clutter_backend_get_cogl_context (backend);
++  cogl_display = cogl_context_get_display (cogl_context);
++  cogl_renderer = cogl_display_get_renderer (cogl_display);
++
++  switch (cogl_renderer_get_driver (cogl_renderer))
++    {
++    case COGL_DRIVER_GL3:
++      {
++        int num_extensions, i;
++        gboolean arb_sync = FALSE;
++        gboolean x11_sync_object = FALSE;
++
++        meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
++
++        for (i = 0; i < num_extensions; ++i)
++          {
++            const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
++
++            if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
++              arb_sync = TRUE;
++            else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
++              x11_sync_object = TRUE;
++          }
++
++        return arb_sync && x11_sync_object;
++      }
++    case COGL_DRIVER_GL:
++      {
++        const char *extensions = meta_gl_get_string (GL_EXTENSIONS);
++        return (extensions != NULL &&
++                strstr (extensions, "GL_ARB_sync") != NULL &&
++                strstr (extensions, "GL_EXT_x11_sync_object") != NULL);
++      }
++    default:
++      break;
++    }
++
++  return FALSE;
++}
++
++static gboolean
++load_required_symbols (void)
++{
++  static gboolean success = FALSE;
++
++  if (success)
++    return TRUE;
++
++  /* We don't link against libGL directly because cogl may want to
++   * use something else. This assumes that cogl has been initialized
++   * and dynamically loaded libGL at this point.
++   */
++
++  if (!load_gl_symbol ("glGetString", (void **) &meta_gl_get_string))
++    goto out;
++  if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
++    goto out;
++  if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
++    goto out;
++
++  if (!check_gl_extensions ())
++    {
++      meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n");
++      goto out;
++    }
++
++  if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
++    goto out;
++  if (!load_gl_symbol ("glClientWaitSync", (void **) 
&meta_gl_client_wait_sync))
++    goto out;
++  if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
++    goto out;
++  if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
++    goto out;
++
++  success = TRUE;
++ out:
++  return success;
++}
++
++static void
++meta_sync_insert (MetaSync *self)
++{
++  g_return_if_fail (self->state == META_SYNC_STATE_READY);
++
++  XSyncTriggerFence (self->xdisplay, self->xfence);
++  XFlush (self->xdisplay);
++
++  meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED);
++
++  self->state = META_SYNC_STATE_WAITING;
++}
++
++static GLenum
++meta_sync_check_update_finished (MetaSync *self,
++                                 GLuint64  timeout)
++{
++  GLenum status = GL_WAIT_FAILED;
++
++  switch (self->state)
++    {
++    case META_SYNC_STATE_DONE:
++      status = GL_ALREADY_SIGNALED;
++      break;
++    case META_SYNC_STATE_WAITING:
++      status = meta_gl_client_wait_sync (self->glsync, 0, timeout);
++      if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
++        self->state = META_SYNC_STATE_DONE;
++      break;
++    default:
++      break;
++    }
++
++  g_warn_if_fail (status != GL_WAIT_FAILED);
++
++  return status;
++}
++
++static void
++meta_sync_reset (MetaSync *self)
++{
++  XSyncAlarmAttributes attrs;
++  int overflow;
++
++  g_return_if_fail (self->state == META_SYNC_STATE_DONE);
++
++  XSyncResetFence (self->xdisplay, self->xfence);
++
++  attrs.trigger.wait_value = self->next_counter_value;
++
++  XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
++  XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
++
++  XSyncValueAdd (&self->next_counter_value,
++                 self->next_counter_value,
++                 SYNC_VALUE_ONE,
++                 &overflow);
++
++  self->state = META_SYNC_STATE_RESET_PENDING;
++}
++
++static void
++meta_sync_handle_event (MetaSync              *self,
++                        XSyncAlarmNotifyEvent *event)
++{
++  g_return_if_fail (event->alarm == self->xalarm);
++  g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
++
++  self->state = META_SYNC_STATE_READY;
++}
++
++static MetaSync *
++meta_sync_new (Display *xdisplay)
++{
++  MetaSync *self;
++  XSyncAlarmAttributes attrs;
++
++  self = g_malloc0 (sizeof (MetaSync));
++
++  self->xdisplay = xdisplay;
++
++  self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), 
FALSE);
++  self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
++
++  self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
++
++  attrs.trigger.counter = self->xcounter;
++  attrs.trigger.value_type = XSyncAbsolute;
++  attrs.trigger.wait_value = SYNC_VALUE_ONE;
++  attrs.trigger.test_type = XSyncPositiveTransition;
++  attrs.events = TRUE;
++  self->xalarm = XSyncCreateAlarm (xdisplay,
++                                   XSyncCACounter |
++                                   XSyncCAValueType |
++                                   XSyncCAValue |
++                                   XSyncCATestType |
++                                   XSyncCAEvents,
++                                   &attrs);
++
++  XSyncIntToValue (&self->next_counter_value, 1);
++
++  self->state = META_SYNC_STATE_READY;
++
++  return self;
++}
++
++static Bool
++alarm_event_predicate (Display  *dpy,
++                       XEvent   *event,
++                       XPointer  data)
++{
++  MetaSyncRing *ring = meta_sync_ring_get ();
++
++  if (!ring)
++    return False;
++
++  if (event->type == ring->xsync_event_base + XSyncAlarmNotify)
++    {
++      if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) 
event)->alarm)
++        return True;
++    }
++  return False;
++}
++
++static void
++meta_sync_free (MetaSync *self)
++{
++  /* When our assumptions don't hold, something has gone wrong but we
++   * don't know what, so we reboot the ring. While doing that, we
++   * trigger fences before deleting them to try to get ourselves out
++   * of a potentially stuck GPU state.
++   */
++  switch (self->state)
++    {
++    case META_SYNC_STATE_WAITING:
++    case META_SYNC_STATE_DONE:
++      /* nothing to do */
++      break;
++    case META_SYNC_STATE_RESET_PENDING:
++      {
++        XEvent event;
++        XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) 
self);
++        meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
++      }
++      /* fall through */
++    case META_SYNC_STATE_READY:
++      XSyncTriggerFence (self->xdisplay, self->xfence);
++      XFlush (self->xdisplay);
++      break;
++    default:
++      break;
++    }
++
++  meta_gl_delete_sync (self->glsync);
++  XSyncDestroyFence (self->xdisplay, self->xfence);
++  XSyncDestroyCounter (self->xdisplay, self->xcounter);
++  XSyncDestroyAlarm (self->xdisplay, self->xalarm);
++
++  g_free (self);
++}
++
++gboolean
++meta_sync_ring_init (Display *xdisplay)
++{
++  gint major, minor;
++  guint i;
++  MetaSyncRing *ring = meta_sync_ring_get ();
++
++  if (!ring)
++    return FALSE;
++
++  g_return_val_if_fail (xdisplay != NULL, FALSE);
++  g_return_val_if_fail (ring->xdisplay == NULL, FALSE);
++
++  if (!load_required_symbols ())
++    return FALSE;
++
++  if (!XSyncQueryExtension (xdisplay, &ring->xsync_event_base, 
&ring->xsync_error_base) ||
++      !XSyncInitialize (xdisplay, &major, &minor))
++    return FALSE;
++
++  XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
++  XSyncIntToValue (&SYNC_VALUE_ONE, 1);
++
++  ring->xdisplay = xdisplay;
++
++  ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
++
++  for (i = 0; i < NUM_SYNCS; ++i)
++    {
++      MetaSync *sync = meta_sync_new (ring->xdisplay);
++      ring->syncs_array[i] = sync;
++      g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, 
sync);
++    }
++
++  ring->current_sync_idx = 0;
++  ring->current_sync = ring->syncs_array[0];
++  ring->warmup_syncs = 0;
++
++  return TRUE;
++}
++
++void
++meta_sync_ring_destroy (void)
++{
++  guint i;
++  MetaSyncRing *ring = meta_sync_ring_get ();
++
++  if (!ring)
++    return;
++
++  g_return_if_fail (ring->xdisplay != NULL);
++
++  ring->current_sync_idx = 0;
++  ring->current_sync = NULL;
++  ring->warmup_syncs = 0;
++
++  for (i = 0; i < NUM_SYNCS; ++i)
++    meta_sync_free (ring->syncs_array[i]);
++
++  g_hash_table_destroy (ring->alarm_to_sync);
++
++  ring->xsync_event_base = 0;
++  ring->xsync_error_base = 0;
++  ring->xdisplay = NULL;
++}
++
++static gboolean
++meta_sync_ring_reboot (Display *xdisplay)
++{
++  MetaSyncRing *ring = meta_sync_ring_get ();
++
++  if (!ring)
++    return FALSE;
++
++  meta_sync_ring_destroy ();
++
++  ring->reboots += 1;
++
++  if (!meta_sync_ring_get ())
++    {
++      meta_warning ("MetaSyncRing: Too many reboots -- disabling\n");
++      return FALSE;
++    }
++
++  return meta_sync_ring_init (xdisplay);
++}
++
++gboolean
++meta_sync_ring_after_frame (void)
++{
++  MetaSyncRing *ring = meta_sync_ring_get ();
++
++  if (!ring)
++    return FALSE;
++
++  g_return_if_fail (ring->xdisplay != NULL);
++
++  if (ring->warmup_syncs >= NUM_SYNCS / 2)
++    {
++      guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS 
/ 2)) % NUM_SYNCS;
++      MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
++
++      GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
++      if (status == GL_TIMEOUT_EXPIRED)
++        {
++          meta_warning ("MetaSyncRing: We should never wait for a sync -- add 
more syncs?\n");
++          status = meta_sync_check_update_finished (sync_to_reset, 
MAX_SYNC_WAIT_TIME);
++        }
++
++      if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
++        {
++          meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n");
++          return meta_sync_ring_reboot (ring->xdisplay);
++        }
++
++      meta_sync_reset (sync_to_reset);
++    }
++  else
++    {
++      ring->warmup_syncs += 1;
++    }
++
++  ring->current_sync_idx += 1;
++  ring->current_sync_idx %= NUM_SYNCS;
++
++  ring->current_sync = ring->syncs_array[ring->current_sync_idx];
++
++  return TRUE;
++}
++
++gboolean
++meta_sync_ring_insert_wait (void)
++{
++  MetaSyncRing *ring = meta_sync_ring_get ();
++
++  if (!ring)
++    return FALSE;
++
++  g_return_if_fail (ring->xdisplay != NULL);
++
++  if (ring->current_sync->state != META_SYNC_STATE_READY)
++    {
++      meta_warning ("MetaSyncRing: Sync object is not ready -- were events 
handled properly?\n");
++      if (!meta_sync_ring_reboot (ring->xdisplay))
++        return FALSE;
++    }
++
++  meta_sync_insert (ring->current_sync);
++
++  return TRUE;
++}
++
++void
++meta_sync_ring_handle_event (XEvent *xevent)
++{
++  XSyncAlarmNotifyEvent *event;
++  MetaSync *sync;
++  MetaSyncRing *ring = meta_sync_ring_get ();
++
++  if (!ring)
++    return;
++
++  g_return_if_fail (ring->xdisplay != NULL);
++
++  if (xevent->type != (ring->xsync_event_base + XSyncAlarmNotify))
++    return;
++
++  event = (XSyncAlarmNotifyEvent *) xevent;
++
++  sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
++  if (sync)
++    meta_sync_handle_event (sync, event);
++}
+diff --git a/src/compositor/meta-sync-ring.h b/src/compositor/meta-sync-ring.h
+new file mode 100644
+index 0000000..6dca8ef
+--- /dev/null
++++ b/src/compositor/meta-sync-ring.h
+@@ -0,0 +1,14 @@
++#ifndef _META_SYNC_RING_H_
++#define _META_SYNC_RING_H_
++
++#include <glib.h>
++
++#include <X11/Xlib.h>
++
++gboolean meta_sync_ring_init (Display *dpy);
++void meta_sync_ring_destroy (void);
++gboolean meta_sync_ring_after_frame (void);
++gboolean meta_sync_ring_insert_wait (void);
++void meta_sync_ring_handle_event (XEvent *event);
++
++#endif  /* _META_SYNC_RING_H_ */
+-- 
+cgit v0.10.2
+

diff --git a/x11-wm/mutter/files/mutter-3.16.3-crash-border.patch 
b/x11-wm/mutter/files/mutter-3.16.3-crash-border.patch
new file mode 100644
index 0000000..9cbd0d0
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.16.3-crash-border.patch
@@ -0,0 +1,32 @@
+From f60c33b5afc4b1dff0b31f17d7ae222db8aa789f Mon Sep 17 00:00:00 2001
+From: Marek Chalupa <[email protected]>
+Date: Fri, 3 Jul 2015 11:28:00 +0200
+Subject: frames: handle META_FRAME_CONTROL_NONE on left click
+
+We can get this operation in some cases, for example when
+we're trying to resize window that cannot be resized.
+This can occur with maximized windows that have a border
+(without border we couldn't resize them by mouse in maximized state).
+In this case we reached abort() beacuse we did not handle this op.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=751884
+
+diff --git a/src/ui/frames.c b/src/ui/frames.c
+index 362d7b6..a2f7f45 100644
+--- a/src/ui/frames.c
++++ b/src/ui/frames.c
+@@ -1053,6 +1053,11 @@ meta_frame_left_click_event (MetaUIFrame *frame,
+       }
+ 
+       return TRUE;
++    case META_FRAME_CONTROL_NONE:
++      /* We can get this for example when trying to resize window
++       * that cannot be resized (e. g. it is maximized and the theme
++       * currently used has borders for maximized windows), see #751884 */
++      return FALSE;
+     default:
+       g_assert_not_reached ();
+     }
+-- 
+cgit v0.10.2
+

diff --git a/x11-wm/mutter/files/mutter-3.16.3-fallback-keymap.patch 
b/x11-wm/mutter/files/mutter-3.16.3-fallback-keymap.patch
new file mode 100644
index 0000000..f77234b
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.16.3-fallback-keymap.patch
@@ -0,0 +1,28 @@
+From 9abc0712836c9e56ed08796645874cc0d10b1826 Mon Sep 17 00:00:00 2001
+From: Rui Matos <[email protected]>
+Date: Mon, 21 Sep 2015 17:25:40 +0200
+Subject: backend-x11: Fallback to a default keymap if getting it from X fails
+
+This shouldn't fail but apparently sometimes it does and in that case
+having a possibly wrong idea of the keymap is still better than
+crashing.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=754979
+
+diff --git a/src/backends/x11/meta-backend-x11.c 
b/src/backends/x11/meta-backend-x11.c
+index 7ad28fd..dbcd13f 100644
+--- a/src/backends/x11/meta-backend-x11.c
++++ b/src/backends/x11/meta-backend-x11.c
+@@ -760,6 +760,9 @@ meta_backend_x11_get_keymap (MetaBackend *backend)
+                                                      priv->xcb,
+                                                      
xkb_x11_get_core_keyboard_device_id (priv->xcb),
+                                                      
XKB_KEYMAP_COMPILE_NO_FLAGS);
++      if (priv->keymap == NULL)
++        priv->keymap = xkb_keymap_new_from_names (context, NULL, 
XKB_KEYMAP_COMPILE_NO_FLAGS);
++
+       xkb_context_unref (context);
+     }
+ 
+-- 
+cgit v0.10.2
+

diff --git a/x11-wm/mutter/files/mutter-3.16.3-fix-race.patch 
b/x11-wm/mutter/files/mutter-3.16.3-fix-race.patch
new file mode 100644
index 0000000..a0b493b
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.16.3-fix-race.patch
@@ -0,0 +1,114 @@
+From c77e482b60bea40a422691b16af02a429d9c2edc Mon Sep 17 00:00:00 2001
+From: Aaron Plattner <[email protected]>
+Date: Mon, 3 Aug 2015 21:15:15 -0700
+Subject: compositor: Fix GL_EXT_x11_sync_object race condition
+
+The compositor maintains a ring of shared fences with the X server in order to
+properly synchronize rendering between the X server and the compositor's GPU
+channel.  When all of the fences have been used, the compositor needs to reset
+one so that it can be reused.  It does this by first waiting on the CPU for the
+fence to become triggered, and then sending a request to the X server to reset
+the fence.
+
+If the compositor's GPU channel is busy processing other work (e.g. the desktop
+switcher animation), then the X server may process the reset request before the
+GPU has consumed the fence.  This causes the GPU channel to hang.
+
+Fix the problem by having the compositor's GPU channel trigger its own fence
+after waiting for the X server's fence.  Wait for that fence on the CPU before
+sending the reset request to the X server.  This ensures that the GPU has
+consumed the X11 fence before the server resets it.
+
+Signed-off-by: Aaron Plattner <[email protected]>
+
+https://bugzilla.gnome.org/show_bug.cgi?id=728464
+
+diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
+index 4ee61f8..44b1c41 100644
+--- a/src/compositor/meta-sync-ring.c
++++ b/src/compositor/meta-sync-ring.c
+@@ -73,7 +73,8 @@ typedef struct
+   Display *xdisplay;
+ 
+   XSyncFence xfence;
+-  GLsync glsync;
++  GLsync gl_x11_sync;
++  GLsync gpu_fence;
+ 
+   XSyncCounter xcounter;
+   XSyncAlarm xalarm;
+@@ -118,6 +119,8 @@ static void             (*meta_gl_wait_sync) (GLsync sync,
+ static GLsync           (*meta_gl_import_sync) (GLenum external_sync_type,
+                                                 GLintptr external_sync,
+                                                 GLbitfield flags);
++static GLsync           (*meta_gl_fence_sync) (GLenum condition,
++                                               GLbitfield flags);
+ 
+ static MetaSyncRing *
+ meta_sync_ring_get (void)
+@@ -224,6 +227,8 @@ load_required_symbols (void)
+     goto out;
+   if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
+     goto out;
++  if (!load_gl_symbol ("glFenceSync", (void **) &meta_gl_fence_sync))
++    goto out;
+ 
+   success = TRUE;
+  out:
+@@ -238,7 +243,8 @@ meta_sync_insert (MetaSync *self)
+   XSyncTriggerFence (self->xdisplay, self->xfence);
+   XFlush (self->xdisplay);
+ 
+-  meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED);
++  meta_gl_wait_sync (self->gl_x11_sync, 0, GL_TIMEOUT_IGNORED);
++  self->gpu_fence = meta_gl_fence_sync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ 
+   self->state = META_SYNC_STATE_WAITING;
+ }
+@@ -255,9 +261,13 @@ meta_sync_check_update_finished (MetaSync *self,
+       status = GL_ALREADY_SIGNALED;
+       break;
+     case META_SYNC_STATE_WAITING:
+-      status = meta_gl_client_wait_sync (self->glsync, 0, timeout);
++      status = meta_gl_client_wait_sync (self->gpu_fence, 0, timeout);
+       if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
+-        self->state = META_SYNC_STATE_DONE;
++        {
++          self->state = META_SYNC_STATE_DONE;
++          meta_gl_delete_sync (self->gpu_fence);
++          self->gpu_fence = 0;
++        }
+       break;
+     default:
+       break;
+@@ -312,7 +322,8 @@ meta_sync_new (Display *xdisplay)
+   self->xdisplay = xdisplay;
+ 
+   self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), 
FALSE);
+-  self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
++  self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, 
self->xfence, 0);
++  self->gpu_fence = 0;
+ 
+   self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
+ 
+@@ -365,6 +376,8 @@ meta_sync_free (MetaSync *self)
+   switch (self->state)
+     {
+     case META_SYNC_STATE_WAITING:
++      meta_gl_delete_sync (self->gpu_fence);
++      break;
+     case META_SYNC_STATE_DONE:
+       /* nothing to do */
+       break;
+@@ -383,7 +396,7 @@ meta_sync_free (MetaSync *self)
+       break;
+     }
+ 
+-  meta_gl_delete_sync (self->glsync);
++  meta_gl_delete_sync (self->gl_x11_sync);
+   XSyncDestroyFence (self->xdisplay, self->xfence);
+   XSyncDestroyCounter (self->xdisplay, self->xcounter);
+   XSyncDestroyAlarm (self->xdisplay, self->xalarm);
+-- 
+cgit v0.10.2
+

diff --git a/x11-wm/mutter/files/mutter-3.16.3-fix-return.patch 
b/x11-wm/mutter/files/mutter-3.16.3-fix-return.patch
new file mode 100644
index 0000000..2898d52
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.16.3-fix-return.patch
@@ -0,0 +1,32 @@
+From a54b1261d3ec5ccf7a8262c88557b6b952bc8a2e Mon Sep 17 00:00:00 2001
+From: Ting-Wei Lan <[email protected]>
+Date: Sat, 8 Aug 2015 20:12:09 +0800
+Subject: build: Fix return value in meta-sync-ring.c
+
+https://bugzilla.gnome.org/show_bug.cgi?id=753380
+
+diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
+index 44b1c41..217ebe5 100644
+--- a/src/compositor/meta-sync-ring.c
++++ b/src/compositor/meta-sync-ring.c
+@@ -499,7 +499,7 @@ meta_sync_ring_after_frame (void)
+   if (!ring)
+     return FALSE;
+ 
+-  g_return_if_fail (ring->xdisplay != NULL);
++  g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
+ 
+   if (ring->warmup_syncs >= NUM_SYNCS / 2)
+     {
+@@ -542,7 +542,7 @@ meta_sync_ring_insert_wait (void)
+   if (!ring)
+     return FALSE;
+ 
+-  g_return_if_fail (ring->xdisplay != NULL);
++  g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
+ 
+   if (ring->current_sync->state != META_SYNC_STATE_READY)
+     {
+-- 
+cgit v0.10.2
+

diff --git a/x11-wm/mutter/files/mutter-3.16.3-flickering.patch 
b/x11-wm/mutter/files/mutter-3.16.3-flickering.patch
new file mode 100644
index 0000000..6267a4e
--- /dev/null
+++ b/x11-wm/mutter/files/mutter-3.16.3-flickering.patch
@@ -0,0 +1,114 @@
+From 916070cc7218cc80f4565ea265b0dd6e5e93cb98 Mon Sep 17 00:00:00 2001
+From: Rui Matos <[email protected]>
+Date: Wed, 12 Aug 2015 15:26:34 +0200
+Subject: compositor: Handle fences in the frontend X connection
+
+Since mutter has two X connections and does damage handling on the
+frontend while fence triggering is done on the backend, we have a race
+between XDamageSubtract() and XSyncFenceTrigger() causing missed
+redraws in the GL_EXT_X11_sync_object path.
+
+If the fence trigger gets processed first by the server, any client
+drawing that happens between that and the damage subtract being
+processed and is completely contained in the last damage event box
+that mutter got, won't be included in the current frame nor will it
+cause a new damage event.
+
+A simple fix for this would be XSync()ing on the frontend connection
+after doing all the damage subtracts but that would add a round trip
+on every frame again which defeats the asynchronous design of X
+fences.
+
+Instead, if we move fence handling to the frontend we automatically
+get the right ordering between damage subtracts and fence triggers.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=728464
+
+diff --git a/src/backends/x11/meta-backend-x11.c 
b/src/backends/x11/meta-backend-x11.c
+index ac38ffc..3ff8431 100644
+--- a/src/backends/x11/meta-backend-x11.c
++++ b/src/backends/x11/meta-backend-x11.c
+@@ -45,7 +45,6 @@
+ #include <meta/util.h>
+ #include "display-private.h"
+ #include "compositor/compositor-private.h"
+-#include "compositor/meta-sync-ring.h"
+ 
+ struct _MetaBackendX11Private
+ {
+@@ -256,8 +255,6 @@ handle_host_xevent (MetaBackend *backend,
+         MetaCompositor *compositor = display->compositor;
+         if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
+           bypass_clutter = TRUE;
+-        if (compositor->have_x11_sync_object)
+-          meta_sync_ring_handle_event (event);
+       }
+   }
+ 
+diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
+index 554faa1..2e182c2 100644
+--- a/src/compositor/compositor.c
++++ b/src/compositor/compositor.c
+@@ -534,8 +534,7 @@ meta_compositor_manage (MetaCompositor *compositor)
+        */
+       XMapWindow (xdisplay, compositor->output);
+ 
+-      compositor->have_x11_sync_object =
+-        meta_sync_ring_init (meta_backend_x11_get_xdisplay (META_BACKEND_X11 
(backend)));
++      compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay);
+     }
+ 
+   redirect_windows (display->screen);
+@@ -737,6 +736,9 @@ meta_compositor_process_event (MetaCompositor *compositor,
+         process_damage (compositor, (XDamageNotifyEvent *) event, window);
+     }
+ 
++  if (compositor->have_x11_sync_object)
++    meta_sync_ring_handle_event (event);
++
+   /* Clutter needs to know about MapNotify events otherwise it will
+      think the stage is invisible */
+   if (!meta_is_wayland_compositor () && event->type == MapNotify)
+diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
+index 217ebe5..336ccd4 100644
+--- a/src/compositor/meta-sync-ring.c
++++ b/src/compositor/meta-sync-ring.c
+@@ -322,7 +322,7 @@ meta_sync_new (Display *xdisplay)
+   self->xdisplay = xdisplay;
+ 
+   self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), 
FALSE);
+-  self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, 
self->xfence, 0);
++  self->gl_x11_sync = 0;
+   self->gpu_fence = 0;
+ 
+   self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
+@@ -347,6 +347,13 @@ meta_sync_new (Display *xdisplay)
+   return self;
+ }
+ 
++static void
++meta_sync_import (MetaSync *self)
++{
++  g_return_if_fail (self->gl_x11_sync == 0);
++  self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, 
self->xfence, 0);
++}
++
+ static Bool
+ alarm_event_predicate (Display  *dpy,
+                        XEvent   *event,
+@@ -437,6 +444,12 @@ meta_sync_ring_init (Display *xdisplay)
+       ring->syncs_array[i] = sync;
+       g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, 
sync);
+     }
++  /* Since the connection we create the X fences on isn't the same as
++   * the one used for the GLX context, we need to XSync() here to
++   * ensure glImportSync() succeeds. */
++  XSync (xdisplay, False);
++  for (i = 0; i < NUM_SYNCS; ++i)
++    meta_sync_import (ring->syncs_array[i]);
+ 
+   ring->current_sync_idx = 0;
+   ring->current_sync = ring->syncs_array[0];
+-- 
+cgit v0.10.2
+

diff --git a/x11-wm/mutter/mutter-3.16.3-r1.ebuild 
b/x11-wm/mutter/mutter-3.16.3-r1.ebuild
new file mode 100644
index 0000000..98cc39c
--- /dev/null
+++ b/x11-wm/mutter/mutter-3.16.3-r1.ebuild
@@ -0,0 +1,114 @@
+# Copyright 1999-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+EAPI="5"
+GCONF_DEBUG="yes"
+
+inherit autotools eutils gnome2
+
+DESCRIPTION="GNOME 3 compositing window manager based on Clutter"
+HOMEPAGE="https://git.gnome.org/browse/mutter/";
+
+LICENSE="GPL-2+"
+SLOT="0"
+IUSE="+introspection +kms test wayland"
+KEYWORDS="~alpha ~amd64 ~arm ~ia64 ~ppc ~ppc64 ~sparc ~x86"
+
+# libXi-1.7.4 or newer needed per:
+# https://bugzilla.gnome.org/show_bug.cgi?id=738944
+COMMON_DEPEND="
+       >=x11-libs/pango-1.2[X,introspection?]
+       >=x11-libs/cairo-1.10[X]
+       >=x11-libs/gtk+-3.9.11:3[X,introspection?]
+       >=dev-libs/glib-2.36.0:2[dbus]
+       >=media-libs/clutter-1.21.3:1.0[introspection?]
+       >=media-libs/cogl-1.17.1:1.0=[introspection?]
+       >=media-libs/libcanberra-0.26[gtk3]
+       >=x11-libs/startup-notification-0.7
+       >=x11-libs/libXcomposite-0.2
+       >=gnome-base/gsettings-desktop-schemas-3.15.92[introspection?]
+       gnome-base/gnome-desktop:3=
+       >sys-power/upower-0.99:=
+
+       x11-libs/libICE
+       x11-libs/libSM
+       x11-libs/libX11
+       >=x11-libs/libXcomposite-0.2
+       x11-libs/libXcursor
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       >=x11-libs/libXi-1.7.4
+       x11-libs/libXinerama
+       x11-libs/libXrandr
+       x11-libs/libXrender
+       x11-libs/libxcb
+       x11-libs/libxkbfile
+       >=x11-libs/libxkbcommon-0.4.3[X]
+       x11-misc/xkeyboard-config
+
+       gnome-extra/zenity
+
+       introspection? ( >=dev-libs/gobject-introspection-1.42:= )
+       kms? (
+               dev-libs/libinput
+               >=media-libs/clutter-1.20[egl]
+               media-libs/cogl:1.0=[kms]
+               >=media-libs/mesa-10.3[gbm]
+               sys-apps/systemd
+               virtual/libgudev
+               x11-libs/libdrm:= )
+       wayland? (
+               >=dev-libs/wayland-1.6.90
+               >=media-libs/clutter-1.20[wayland]
+               x11-base/xorg-server[wayland] )
+"
+DEPEND="${COMMON_DEPEND}
+       >=dev-util/gtk-doc-am-1.15
+       >=dev-util/intltool-0.41
+       sys-devel/gettext
+       virtual/pkgconfig
+       x11-proto/xextproto
+       x11-proto/xineramaproto
+       x11-proto/xproto
+       test? ( app-text/docbook-xml-dtd:4.5 )
+"
+RDEPEND="${COMMON_DEPEND}
+       !x11-misc/expocity
+"
+
+src_prepare() {
+       # Fallback to a default keymap if getting it from X fails (from 
'master')
+       epatch "${FILESDIR}"/${PN}-3.16.3-fallback-keymap.patch
+       
+       # frames: handle META_FRAME_CONTROL_NONE on left click (from '3.16')
+       epatch "${FILESDIR}"/${P}-crash-border.patch
+       
+       # compositor: Add support for GL_EXT_x11_sync_object (from '3.16')
+       epatch "${FILESDIR}"/${P}-GL_EXT_x11_sync_object.patch
+       
+       # compositor: Fix GL_EXT_x11_sync_object race condition (from '3.16')
+       epatch "${FILESDIR}"/${P}-fix-race.patch
+       
+       # build: Fix return value in meta-sync-ring.c (from '3.16')
+       epatch "${FILESDIR}"/${P}-fix-return.patch
+       
+       # compositor: Handle fences in the frontend X connection (from '3.16')
+       epatch "${FILESDIR}"/${P}-flickering.patch
+
+       eautoreconf
+       gnome2_src_prepare
+}
+
+src_configure() {
+       gnome2_src_configure \
+               --disable-static \
+               --enable-sm \
+               --enable-startup-notification \
+               --enable-verbose-mode \
+               --with-libcanberra \
+               $(use_enable introspection) \
+               $(use_enable kms native-backend) \
+               $(use_enable wayland)
+}

Reply via email to