diff --git a/.gitignore b/.gitignore
index 31242bd..8f5c56c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/mutter-3.22.3.tar.xz
+SOURCES/mutter-3.26.2.tar.xz
diff --git a/.mutter.metadata b/.mutter.metadata
index 0aaec90..8d83fd2 100644
--- a/.mutter.metadata
+++ b/.mutter.metadata
@@ -1 +1 @@
-90bf3c4a65b474e958a1b13f80c47ebcdb411b42 SOURCES/mutter-3.22.3.tar.xz
+8d9dffa9c1ceaf07761b80662828fb7d60e76dd1 SOURCES/mutter-3.26.2.tar.xz
diff --git a/SOURCES/0001-Revert-backend-x11-Ensure-the-Xkb-group-index-remain.patch b/SOURCES/0001-Revert-backend-x11-Ensure-the-Xkb-group-index-remain.patch
deleted file mode 100644
index ee3b81c..0000000
--- a/SOURCES/0001-Revert-backend-x11-Ensure-the-Xkb-group-index-remain.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 090ac268b91c3b07f90d9d4ebe481bfe649836df Mon Sep 17 00:00:00 2001
-From: Rui Matos <tiagomatos@gmail.com>
-Date: Mon, 13 Jun 2016 19:32:43 +0200
-Subject: [PATCH] Revert "backend-x11: Ensure the Xkb group index remains
- properly set"
-
-This reverts commit 2857fdbdb887fcaa2e2f25d268c34ae039646e78.
----
- src/backends/x11/meta-backend-x11.c | 16 +++-------------
- 1 file changed, 3 insertions(+), 13 deletions(-)
-
-diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
-index a645bbd..dbcd13f 100644
---- a/src/backends/x11/meta-backend-x11.c
-+++ b/src/backends/x11/meta-backend-x11.c
-@@ -82,7 +82,6 @@ struct _MetaBackendX11Private
-   gchar *keymap_layouts;
-   gchar *keymap_variants;
-   gchar *keymap_options;
--  int locked_group;
- };
- typedef struct _MetaBackendX11Private MetaBackendX11Private;
- 
-@@ -298,23 +297,15 @@ handle_host_xevent (MetaBackend *backend,
- 
-   if (event->type == priv->xkb_event_base)
-     {
--      XkbEvent *xkb_ev = (XkbEvent *) event;
-+      XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
- 
--      if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID)
-+      if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
-         {
--          switch (xkb_ev->any.xkb_type)
-+          switch (xkb_ev->xkb_type)
-             {
-             case XkbNewKeyboardNotify:
-             case XkbMapNotify:
-               keymap_changed (backend);
--              break;
--            case XkbStateNotify:
--              if (xkb_ev->state.changed & XkbGroupLockMask)
--                {
--                  if (priv->locked_group != xkb_ev->state.locked_group)
--                    XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, priv->locked_group);
--                }
--              break;
-             default:
-               break;
-             }
-@@ -785,7 +776,6 @@ meta_backend_x11_lock_layout_group (MetaBackend *backend,
-   MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
-   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
- 
--  priv->locked_group = idx;
-   XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx);
- }
- 
--- 
-2.7.4
-
diff --git a/SOURCES/0001-Revert-build-Require-libgudev-232.patch b/SOURCES/0001-Revert-build-Require-libgudev-232.patch
new file mode 100644
index 0000000..ec6bf21
--- /dev/null
+++ b/SOURCES/0001-Revert-build-Require-libgudev-232.patch
@@ -0,0 +1,46 @@
+From 23f4b91105c4fa9fa2231d2e1049728a6383cd65 Mon Sep 17 00:00:00 2001
+From: Olivier Fourdan <ofourdan@redhat.com>
+Date: Fri, 15 Sep 2017 09:39:18 +0200
+Subject: [PATCH] Revert "build: Require libgudev >= 232"
+
+This reverts commit 361bf847af82c7dca097302fe64c575079280c9c.
+---
+ configure.ac                        | 4 ++--
+ src/backends/native/meta-launcher.c | 4 ++++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 805707933..813ca008a 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -225,10 +225,10 @@ AC_MSG_CHECKING([gudev])
+ if test x$with_gudev = xno ; then
+   AC_MSG_RESULT([disabled])
+ else
+-  if $PKG_CONFIG --exists "gudev-1.0 >= 232"; then
++  if $PKG_CONFIG --exists gudev-1.0; then
+     have_gudev=yes
+     AC_MSG_RESULT(yes)
+-    MUTTER_PC_MODULES="$MUTTER_PC_MODULES gudev-1.0 >= 232"
++    MUTTER_PC_MODULES="$MUTTER_PC_MODULES gudev-1.0"
+     AC_DEFINE([HAVE_LIBGUDEV], 1, [Building with gudev for device type detection])
+   else
+     AC_MSG_RESULT(no)
+diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
+index eb35f88be..90b4b98ba 100644
+--- a/src/backends/native/meta-launcher.c
++++ b/src/backends/native/meta-launcher.c
+@@ -49,6 +49,10 @@
+ 
+ #define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
+ 
++G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref)
++G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref)
++G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevEnumerator, g_object_unref)
++
+ struct _MetaLauncher
+ {
+   Login1Session *session_proxy;
+-- 
+2.13.5
+
diff --git a/SOURCES/0001-backends-Monitor-changes-in-active-tools-settings.patch b/SOURCES/0001-backends-Monitor-changes-in-active-tools-settings.patch
new file mode 100644
index 0000000..444e6ff
--- /dev/null
+++ b/SOURCES/0001-backends-Monitor-changes-in-active-tools-settings.patch
@@ -0,0 +1,142 @@
+From 62f0fb12b1fa946779f0efa406159a355811fdc5 Mon Sep 17 00:00:00 2001
+From: Carlos Garnacho <carlosg@gnome.org>
+Date: Mon, 19 Feb 2018 16:50:52 +0100
+Subject: [PATCH] backends: Monitor changes in active tools' settings
+
+So the changes can be instantly applied while the tool is in proximity.
+Before we would just do it on proximity-in, which doesn't provide a
+good look&feel while modifying the tool settings in g-c-c.
+
+https://gitlab.gnome.org/GNOME/mutter/issues/38
+
+Closes: #38
+---
+ src/backends/meta-input-settings.c | 71 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 68 insertions(+), 3 deletions(-)
+
+diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
+index 0658755..ec0fc9f 100644
+--- a/src/backends/meta-input-settings.c
++++ b/src/backends/meta-input-settings.c
+@@ -41,6 +41,16 @@ static GQuark quark_tool_settings = 0;
+ 
+ typedef struct _MetaInputSettingsPrivate MetaInputSettingsPrivate;
+ typedef struct _DeviceMappingInfo DeviceMappingInfo;
++typedef struct _CurrentToolInfo CurrentToolInfo;
++
++struct _CurrentToolInfo
++{
++  MetaInputSettings *input_settings;
++  ClutterInputDevice *device;
++  ClutterInputDeviceTool *tool;
++  GSettings *settings;
++  guint changed_id;
++};
+ 
+ struct _DeviceMappingInfo
+ {
+@@ -68,6 +78,8 @@ struct _MetaInputSettingsPrivate
+ 
+   GHashTable *mappable_devices;
+ 
++  GHashTable *current_tools;
++
+   ClutterVirtualInputDevice *virtual_pad_keyboard;
+ 
+ #ifdef HAVE_LIBWACOM
+@@ -144,6 +156,7 @@ meta_input_settings_dispose (GObject *object)
+   g_clear_object (&priv->keyboard_settings);
+   g_clear_object (&priv->gsd_settings);
+   g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
++  g_clear_pointer (&priv->current_tools, g_hash_table_unref);
+ 
+   if (priv->monitors_changed_id && priv->monitor_manager)
+     {
+@@ -1510,22 +1523,71 @@ meta_input_settings_device_removed (ClutterDeviceManager *device_manager,
+ 
+   priv = meta_input_settings_get_instance_private (input_settings);
+   g_hash_table_remove (priv->mappable_devices, device);
++  g_hash_table_remove (priv->current_tools, device);
+ 
+   if (g_hash_table_remove (priv->two_finger_devices, device) &&
+       g_hash_table_size (priv->two_finger_devices) == 0)
+     apply_device_settings (input_settings, NULL);
+ }
+ 
++static void
++current_tool_changed_cb (GSettings  *settings,
++                         const char *key,
++                         gpointer    user_data)
++{
++  CurrentToolInfo *info = user_data;
++
++  apply_stylus_settings (info->input_settings, info->device, info->tool);
++}
++
++static CurrentToolInfo *
++current_tool_info_new (MetaInputSettings      *input_settings,
++                       ClutterInputDevice     *device,
++                       ClutterInputDeviceTool *tool)
++{
++  CurrentToolInfo *info;
++
++  info = g_new0 (CurrentToolInfo, 1);
++  info->input_settings = input_settings;
++  info->device = device;
++  info->tool = tool;
++  info->settings = lookup_tool_settings (tool, device);
++  info->changed_id =
++    g_signal_connect (info->settings, "changed",
++                      G_CALLBACK (current_tool_changed_cb),
++                      info);
++  return info;
++}
++
++static void
++current_tool_info_free (CurrentToolInfo *info)
++{
++  g_signal_handler_disconnect (info->settings, info->changed_id);
++  g_free (info);
++}
++
+ static void
+ meta_input_settings_tool_changed (ClutterDeviceManager   *device_manager,
+                                   ClutterInputDevice     *device,
+                                   ClutterInputDeviceTool *tool,
+                                   MetaInputSettings      *input_settings)
+ {
+-  if (!tool)
+-    return;
++  MetaInputSettingsPrivate *priv;
+ 
+-  apply_stylus_settings (input_settings, device, tool);
++  priv = meta_input_settings_get_instance_private (input_settings);
++
++  if (tool)
++    {
++      CurrentToolInfo *current_tool;
++
++      current_tool = current_tool_info_new (input_settings, device, tool);
++      g_hash_table_insert (priv->current_tools, device, current_tool);
++      apply_stylus_settings (input_settings, device, tool);
++    }
++  else
++    {
++      g_hash_table_remove (priv->current_tools, device);
++    }
+ }
+ 
+ static void
+@@ -1616,6 +1678,9 @@ meta_input_settings_init (MetaInputSettings *settings)
+   priv->mappable_devices =
+     g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) device_mapping_info_free);
+ 
++  priv->current_tools =
++    g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) current_tool_info_free);
++
+   priv->monitor_manager = g_object_ref (meta_monitor_manager_get ());
+   g_signal_connect (priv->monitor_manager, "monitors-changed-internal",
+                     G_CALLBACK (monitors_changed_cb), settings);
+-- 
+2.16.1
+
diff --git a/SOURCES/0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch b/SOURCES/0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch
new file mode 100644
index 0000000..0a1fc86
--- /dev/null
+++ b/SOURCES/0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch
@@ -0,0 +1,127 @@
+From bc17d94ef058564c1a1adf28a8696164455fea1b Mon Sep 17 00:00:00 2001
+From: Carlos Garnacho <carlosg@gnome.org>
+Date: Tue, 30 Jan 2018 13:07:32 +0100
+Subject: [PATCH] backends/x11: Preserve XI1 XDevice throughout
+ ClutterInputDevice lifetime
+
+Opening and closing the device may result into XI2 grabs being cut short,
+resulting into pad buttons being rendered ineffective, and other possible
+misbehaviors. This is an XInput flaw that fell in the gap between XI1 and
+XI2, and has no easy fix. It pays us for mixing both versions, I guess...
+
+Work this around by keeping the XI1 XDevice attached to the
+ClutterInputDevice, this way it will live long enough that this is not
+a concern.
+
+Investigation of this bug was mostly carried by Peter Hutterer, I'm just
+the executing hand.
+
+https://gitlab.gnome.org/GNOME/mutter/issues/7
+
+Closes: #7
+---
+ src/backends/x11/meta-input-settings-x11.c | 48 ++++++++++++++++++++++++++----
+ 1 file changed, 42 insertions(+), 6 deletions(-)
+
+diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
+index d1ee37a..7a876ef 100644
+--- a/src/backends/x11/meta-input-settings-x11.c
++++ b/src/backends/x11/meta-input-settings-x11.c
+@@ -55,6 +55,46 @@ enum {
+   SCROLL_METHOD_NUM_FIELDS
+ };
+ 
++static void
++device_free_xdevice (gpointer user_data)
++{
++  MetaDisplay *display = meta_get_display ();
++  MetaBackend *backend = meta_get_backend ();
++  Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
++  XDevice *xdev = user_data;
++
++  meta_error_trap_push (display);
++  XCloseDevice (xdisplay, xdev);
++  meta_error_trap_pop (display);
++}
++
++static XDevice *
++device_ensure_xdevice (ClutterInputDevice *device)
++{
++  MetaDisplay *display = meta_get_display ();
++  MetaBackend *backend = meta_get_backend ();
++  Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
++  int device_id = clutter_input_device_get_device_id (device);
++  XDevice *xdev = NULL;
++
++  xdev = g_object_get_data (G_OBJECT (device), "meta-input-settings-xdevice");
++  if (xdev)
++    return xdev;
++
++  meta_error_trap_push (display);
++  xdev = XOpenDevice (xdisplay, device_id);
++  meta_error_trap_pop (display);
++
++  if (xdev)
++    {
++      g_object_set_data_full (G_OBJECT (device),
++                              "meta-input-settings-xdevice",
++                              xdev, (GDestroyNotify) device_free_xdevice);
++    }
++
++  return xdev;
++}
++
+ static void *
+ get_property (ClutterInputDevice *device,
+               const gchar        *property,
+@@ -540,7 +580,6 @@ meta_input_settings_x11_set_tablet_mapping (MetaInputSettings     *settings,
+   MetaDisplay *display = meta_get_display ();
+   MetaBackend *backend = meta_get_backend ();
+   Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+-  int device_id = clutter_input_device_get_device_id (device);
+   XDevice *xdev;
+ 
+   if (!display)
+@@ -548,13 +587,12 @@ meta_input_settings_x11_set_tablet_mapping (MetaInputSettings     *settings,
+ 
+   /* Grab the puke bucket! */
+   meta_error_trap_push (display);
+-  xdev = XOpenDevice (xdisplay, device_id);
++  xdev = device_ensure_xdevice (device);
+   if (xdev)
+     {
+       XSetDeviceMode (xdisplay, xdev,
+                       mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE ?
+                       Absolute : Relative);
+-      XCloseDevice (xdisplay, xdev);
+     }
+ 
+   if (meta_error_trap_pop_with_return (display))
+@@ -737,7 +775,6 @@ meta_input_settings_x11_set_stylus_button_map (MetaInputSettings          *setti
+   MetaDisplay *display = meta_get_display ();
+   MetaBackend *backend = meta_get_backend ();
+   Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+-  int device_id = clutter_input_device_get_device_id (device);
+   XDevice *xdev;
+ 
+   if (!display)
+@@ -745,7 +782,7 @@ meta_input_settings_x11_set_stylus_button_map (MetaInputSettings          *setti
+ 
+   /* Grab the puke bucket! */
+   meta_error_trap_push (display);
+-  xdev = XOpenDevice (xdisplay, device_id);
++  xdev = device_ensure_xdevice (device);
+   if (xdev)
+     {
+       guchar map[3] = {
+@@ -755,7 +792,6 @@ meta_input_settings_x11_set_stylus_button_map (MetaInputSettings          *setti
+       };
+ 
+       XSetDeviceButtonMapping (xdisplay, xdev, map, G_N_ELEMENTS (map));
+-      XCloseDevice (xdisplay, xdev);
+     }
+ 
+   if (meta_error_trap_pop_with_return (display))
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch b/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch
index 059728b..b6f21e1 100644
--- a/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch
+++ b/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch
@@ -1,4 +1,4 @@
-From 10b63b27ba84458884138cecc1b914b4f69bc9b9 Mon Sep 17 00:00:00 2001
+From 647de5a802627809486fe760c657b05297470683 Mon Sep 17 00:00:00 2001
 From: Carlos Garnacho <carlosg@gnome.org>
 Date: Thu, 19 Jan 2017 15:03:41 +0100
 Subject: [PATCH] backends/x11: Support synaptics configuration
@@ -6,11 +6,11 @@ Subject: [PATCH] backends/x11: Support synaptics configuration
 The code is taken mostly as-is from g-s-d, so we can drag the
 dead horse a bit longer.
 ---
- src/backends/x11/meta-input-settings-x11.c | 264 +++++++++++++++++++++++++++++
- 1 file changed, 264 insertions(+)
+ src/backends/x11/meta-input-settings-x11.c | 261 +++++++++++++++++++++++++++++
+ 1 file changed, 261 insertions(+)
 
 diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
-index 8f962b4..75ceb0c 100644
+index 7a876ef..467a9b7 100644
 --- a/src/backends/x11/meta-input-settings-x11.c
 +++ b/src/backends/x11/meta-input-settings-x11.c
 @@ -26,6 +26,7 @@
@@ -21,7 +21,7 @@ index 8f962b4..75ceb0c 100644
  #include <string.h>
  #include <gdk/gdkx.h>
  #include <X11/Xatom.h>
-@@ -118,6 +119,177 @@ change_property (ClutterInputDevice *device,
+@@ -159,6 +160,173 @@ change_property (ClutterInputDevice *device,
    meta_XFree (data_ret);
  }
  
@@ -51,14 +51,14 @@ index 8f962b4..75ceb0c 100644
 +  guchar *tap_action, *buttons;
 +  guint buttons_capacity = 16, n_buttons;
 +
-+  xdevice = XOpenDevice(xdisplay, clutter_input_device_get_device_id (device));
++  xdevice = device_ensure_xdevice (device);
 +  if (!xdevice)
 +    return;
 +
 +  tap_action = get_property (device, "Synaptics Tap Action",
 +                             XA_INTEGER, 8, 7);
 +  if (!tap_action)
-+    goto out;
++    return;
 +
 +  tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0;
 +  tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0;
@@ -93,9 +93,6 @@ index 8f962b4..75ceb0c 100644
 +      g_warning ("Could not set synaptics touchpad left-handed for %s",
 +                 clutter_input_device_get_device_name (device));
 +    }
-+
-+ out:
-+  XCloseDevice (xdisplay, xdevice);
 +}
 +
 +static void
@@ -111,7 +108,7 @@ index 8f962b4..75ceb0c 100644
 +  int i, num_feedbacks, motion_threshold, numerator, denominator;
 +  gfloat motion_acceleration;
 +
-+  xdevice = XOpenDevice(xdisplay, clutter_input_device_get_device_id (device));
++  xdevice = device_ensure_xdevice (device);
 +  if (!xdevice)
 +    return;
 +  /* Get the list of feedbacks for the device */
@@ -193,13 +190,12 @@ index 8f962b4..75ceb0c 100644
 +    }
 +
 +  XFreeFeedbackList (states);
-+  XCloseDevice (xdisplay, xdevice);
 +}
 +
  static void
  meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
                                           ClutterInputDevice       *device,
-@@ -126,6 +298,13 @@ meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
+@@ -167,6 +335,13 @@ meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
    guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
    guchar *available;
  
@@ -213,7 +209,7 @@ index 8f962b4..75ceb0c 100644
    available = get_property (device, "libinput Send Events Modes Available",
                              XA_INTEGER, 8, 2);
    if (!available)
-@@ -178,6 +357,12 @@ meta_input_settings_x11_set_speed (MetaInputSettings  *settings,
+@@ -219,6 +394,12 @@ meta_input_settings_x11_set_speed (MetaInputSettings  *settings,
    Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
    gfloat value = speed;
  
@@ -226,26 +222,27 @@ index 8f962b4..75ceb0c 100644
    change_property (device, "libinput Accel Speed",
                     XInternAtom (xdisplay, "FLOAT", False),
                     32, &value, 1);
-@@ -190,6 +375,18 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings  *settings,
- {
-   guchar value = (enabled) ? 1 : 0;
- 
-+  if (is_device_synaptics (device))
-+    {
-+      GSettings *settings;
+@@ -245,6 +426,19 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings  *settings,
+   else
+     {
+       value = enabled ? 1 : 0;
 +
-+      settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
-+      change_synaptics_tap_left_handed (device,
-+                                        g_settings_get_boolean (settings, "tap-to-click"),
-+                                        enabled);
-+      g_object_unref (settings);
-+      return;
-+    }
++      if (is_device_synaptics (device))
++        {
++          GSettings *settings;
++
++          settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
++          change_synaptics_tap_left_handed (device,
++                                            g_settings_get_boolean (settings, "tap-to-click"),
++                                            enabled);
++          g_object_unref (settings);
++          return;
++        }
 +
-   change_property (device, "libinput Left Handed Enabled",
-                    XA_INTEGER, 8, &value, 1);
- }
-@@ -201,6 +398,20 @@ meta_input_settings_x11_set_tap_enabled (MetaInputSettings  *settings,
+       change_property (device, "libinput Left Handed Enabled",
+                        XA_INTEGER, 8, &value, 1);
+     }
+@@ -268,6 +462,20 @@ meta_input_settings_x11_set_tap_enabled (MetaInputSettings  *settings,
  {
    guchar value = (enabled) ? 1 : 0;
  
@@ -266,7 +263,7 @@ index 8f962b4..75ceb0c 100644
    change_property (device, "libinput Tapping Enabled",
                     XA_INTEGER, 8, &value, 1);
  }
-@@ -212,6 +423,27 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings  *settings,
+@@ -290,6 +498,27 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings  *settings,
  {
    guchar value = (inverted) ? 1 : 0;
  
@@ -294,7 +291,7 @@ index 8f962b4..75ceb0c 100644
    change_property (device, "libinput Natural Scrolling Enabled",
                     XA_INTEGER, 8, &value, 1);
  }
-@@ -225,6 +457,22 @@ meta_input_settings_x11_set_edge_scroll (MetaInputSettings            *settings,
+@@ -303,6 +532,22 @@ meta_input_settings_x11_set_edge_scroll (MetaInputSettings            *settings,
    guchar *current = NULL;
    guchar *available = NULL;
  
@@ -317,7 +314,7 @@ index 8f962b4..75ceb0c 100644
    available = get_property (device, "libinput Scroll Methods Available",
                              XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
    if (!available || !available[SCROLL_METHOD_FIELD_EDGE])
-@@ -254,6 +502,22 @@ meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings            *set
+@@ -332,6 +577,22 @@ meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings            *set
    guchar *current = NULL;
    guchar *available = NULL;
  
@@ -341,5 +338,5 @@ index 8f962b4..75ceb0c 100644
                              XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
    if (!available || !available[SCROLL_METHOD_FIELD_2FG])
 -- 
-2.9.3
+1.8.3.1
 
diff --git a/SOURCES/0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch b/SOURCES/0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch
new file mode 100644
index 0000000..f13f593
--- /dev/null
+++ b/SOURCES/0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch
@@ -0,0 +1,35 @@
+From ac502c921d2e813e6e916a589a07bc58ca4c12e7 Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Fri, 9 Feb 2018 11:53:17 +1000
+Subject: [PATCH] backends/x11: wacom pressure curve is a 32-bit property
+
+The property has been 32 bits since around 2011 and has not changed, mutter
+expects it to be 8 bits. The mismatch causes change_property to never
+actually change the property.
+
+https://gitlab.gnome.org/GNOME/mutter/issues/26
+
+Closes: #26
+---
+ src/backends/x11/meta-input-settings-x11.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
+index 7d1d360a3..9687fb36f 100644
+--- a/src/backends/x11/meta-input-settings-x11.c
++++ b/src/backends/x11/meta-input-settings-x11.c
+@@ -813,9 +813,9 @@ meta_input_settings_x11_set_stylus_pressure (MetaInputSettings      *settings,
+                                              ClutterInputDeviceTool *tool,
+                                              const gint32            pressure[4])
+ {
+-  guchar values[4] = { pressure[0], pressure[1], pressure[2], pressure[3] };
++  guint32 values[4] = { pressure[0], pressure[1], pressure[2], pressure[3] };
+ 
+-  change_property (device, "Wacom Pressurecurve", XA_INTEGER, 8,
++  change_property (device, "Wacom Pressurecurve", XA_INTEGER, 32,
+                    &values, G_N_ELEMENTS (values));
+ }
+ 
+-- 
+2.16.1
+
diff --git a/SOURCES/0001-cally-Fix-translation-to-screen-coordinates.patch b/SOURCES/0001-cally-Fix-translation-to-screen-coordinates.patch
deleted file mode 100644
index 33370b3..0000000
--- a/SOURCES/0001-cally-Fix-translation-to-screen-coordinates.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 59eb6a6ff7d6356213db1ea22616315c215ae4a1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
-Date: Fri, 28 Apr 2017 17:12:40 +0200
-Subject: [PATCH] cally: Fix translation to screen coordinates
-
-Due to an accidental swap of an else statement and a preprocessor #else,
-the output x coordinate is currently only set when not using the X11
-windowing system, whoops.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=781902
----
- clutter/clutter/cally/cally-actor.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/clutter/clutter/cally/cally-actor.c b/clutter/clutter/cally/cally-actor.c
-index fe3e27433..8ff5b09e1 100644
---- a/clutter/clutter/cally/cally-actor.c
-+++ b/clutter/clutter/cally/cally-actor.c
-@@ -780,8 +780,8 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
-         g_warning ("[x11] We were not able to get proper absolute "
-                    "position of the stage");
-     }
--  else
- #else
-+  else
-     {
-       static gboolean yet_warned = FALSE;
- 
--- 
-2.12.2
-
diff --git a/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch b/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch
new file mode 100644
index 0000000..3ae0f20
--- /dev/null
+++ b/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch
@@ -0,0 +1,61 @@
+From 424e37231a0930594d4363477e7515e006b3dac1 Mon Sep 17 00:00:00 2001
+From: Carlos Garnacho <carlosg@gnome.org>
+Date: Tue, 13 Feb 2018 11:44:40 +0100
+Subject: [PATCH] clutter: Extend touchpad device property check for Synaptics
+
+So we reliably get CLUTTER_TOUCHPAD_DEVICE for those. The other heuristics
+to get the device type may fall short.
+---
+ clutter/clutter/x11/clutter-device-manager-xi2.c | 22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c
+index d2610cc..fcba55c 100644
+--- a/clutter/clutter/x11/clutter-device-manager-xi2.c
++++ b/clutter/clutter/x11/clutter-device-manager-xi2.c
+@@ -267,8 +267,9 @@ is_touch_device (XIAnyClassInfo         **classes,
+ }
+ 
+ static gboolean
+-is_touchpad_device (ClutterBackendX11 *backend_x11,
+-                    XIDeviceInfo      *info)
++query_exists_device_property (ClutterBackendX11 *backend_x11,
++                              XIDeviceInfo      *info,
++                              const gchar       *property)
+ {
+   gulong nitems, bytes_after;
+   guint32 *data = NULL;
+@@ -276,7 +277,7 @@ is_touchpad_device (ClutterBackendX11 *backend_x11,
+   Atom type;
+   Atom prop;
+ 
+-  prop = XInternAtom (backend_x11->xdpy, "libinput Tapping Enabled", True);
++  prop = XInternAtom (backend_x11->xdpy, property, True);
+   if (prop == None)
+     return FALSE;
+ 
+@@ -298,6 +299,21 @@ is_touchpad_device (ClutterBackendX11 *backend_x11,
+ }
+ 
+ static gboolean
++is_touchpad_device (ClutterBackendX11 *backend_x11,
++                    XIDeviceInfo      *info)
++{
++  if (query_exists_device_property (backend_x11, info,
++                                    "libinput Tapping Enabled"))
++    return TRUE;
++
++  if (query_exists_device_property (backend_x11, info,
++                                    "Synaptics Off"))
++    return TRUE;
++
++  return FALSE;
++}
++
++static gboolean
+ get_device_ids (ClutterBackendX11  *backend_x11,
+                 XIDeviceInfo       *info,
+                 gchar             **vendor_id,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0001-clutter-clone-Unset-source-when-source-actor-is-dest.patch b/SOURCES/0001-clutter-clone-Unset-source-when-source-actor-is-dest.patch
deleted file mode 100644
index f30481a..0000000
--- a/SOURCES/0001-clutter-clone-Unset-source-when-source-actor-is-dest.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 82eb06def0b02efec2852aced4f0e609abb12557 Mon Sep 17 00:00:00 2001
-From: Rui Matos <tiagomatos@gmail.com>
-Date: Thu, 2 Mar 2017 19:18:43 +0100
-Subject: [PATCH] clutter-clone: Unset source when source actor is destroyed
-
-Otherwise we might be holding on to a source actor that's no longer
-fully functioning and cause crashes if for example we try to paint it.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779483
----
- clutter/clutter/clutter-clone.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/clutter/clutter/clutter-clone.c b/clutter/clutter/clutter-clone.c
-index af03a4e81..f0eea2459 100644
---- a/clutter/clutter/clutter-clone.c
-+++ b/clutter/clutter/clutter-clone.c
-@@ -54,6 +54,7 @@
- struct _ClutterClonePrivate
- {
-   ClutterActor *clone_source;
-+  gulong source_destroy_id;
- };
- 
- G_DEFINE_TYPE_WITH_PRIVATE (ClutterClone, clutter_clone, CLUTTER_TYPE_ACTOR)
-@@ -377,6 +378,13 @@ clutter_clone_new (ClutterActor *source)
- }
- 
- static void
-+on_source_destroyed (ClutterActor *source,
-+                     ClutterClone *self)
-+{
-+  clutter_clone_set_source_internal (self, NULL);
-+}
-+
-+static void
- clutter_clone_set_source_internal (ClutterClone *self,
- 				   ClutterActor *source)
- {
-@@ -387,6 +395,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
- 
-   if (priv->clone_source != NULL)
-     {
-+      g_signal_handler_disconnect (priv->clone_source, priv->source_destroy_id);
-+      priv->source_destroy_id = 0;
-       _clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self));
-       g_object_unref (priv->clone_source);
-       priv->clone_source = NULL;
-@@ -396,6 +406,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
-     {
-       priv->clone_source = g_object_ref (source);
-       _clutter_actor_attach_clone (priv->clone_source, CLUTTER_ACTOR (self));
-+      priv->source_destroy_id = g_signal_connect (priv->clone_source, "destroy",
-+                                                  G_CALLBACK (on_source_destroyed), self);
-     }
- 
-   g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SOURCE]);
--- 
-2.13.0
-
diff --git a/SOURCES/0001-clutter-stage-don-t-use-deprecated-api.patch b/SOURCES/0001-clutter-stage-don-t-use-deprecated-api.patch
new file mode 100644
index 0000000..d3b0103
--- /dev/null
+++ b/SOURCES/0001-clutter-stage-don-t-use-deprecated-api.patch
@@ -0,0 +1,217 @@
+From e69a6ac0e44e8d5fd72d7bc60f118044b0407e8f Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Thu, 9 Nov 2017 16:18:02 -0500
+Subject: [PATCH] 0001-clutter-stage-don-t-use-deprecated-api.patch
+
+---
+ clutter/clutter/clutter-stage.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
+index 02ab07b..e4f9342 100644
+--- a/clutter/clutter/clutter-stage.c
++++ b/clutter/clutter/clutter-stage.c
+@@ -1459,64 +1459,65 @@ _clutter_stage_do_pick_on_view (ClutterStage     *stage,
+   fb_height = view_layout.height * fb_scale;
+   cogl_push_framebuffer (fb);
+ 
+   /* needed for when a context switch happens */
+   _clutter_stage_maybe_setup_viewport (stage, view);
+ 
+   /* FIXME: For some reason leaving the cogl clip stack empty causes the
+    * picking to not work at all, so setting it the whole framebuffer content
+    * for now. */
+   cogl_framebuffer_push_scissor_clip (fb, 0, 0,
+                                       view_layout.width * fb_scale,
+                                       view_layout.height * fb_scale);
+ 
+   _clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y);
+ 
+   if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
+     {
+       CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1",
+                     (int) dirty_x * fb_scale,
+                     (int) dirty_y * fb_scale);
+       cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1);
+     }
+ 
+   viewport_offset_x = x * fb_scale - dirty_x * fb_scale;
+   viewport_offset_y = y * fb_scale - dirty_y * fb_scale;
+   CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f",
+                 priv->viewport[0] * fb_scale - viewport_offset_x,
+                 priv->viewport[1] * fb_scale - viewport_offset_y,
+                 priv->viewport[2] * fb_scale,
+                 priv->viewport[3] * fb_scale);
+-  cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x,
+-                     priv->viewport[1] * fb_scale - viewport_offset_y,
+-                     priv->viewport[2] * fb_scale,
+-                     priv->viewport[3] * fb_scale);
++  cogl_framebuffer_set_viewport (fb,
++                                 priv->viewport[0] * fb_scale - viewport_offset_x,
++                                 priv->viewport[1] * fb_scale - viewport_offset_y,
++                                 priv->viewport[2] * fb_scale,
++                                 priv->viewport[3] * fb_scale);
+ 
+   read_x = dirty_x * fb_scale;
+   read_y = dirty_y * fb_scale;
+ 
+   CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %d",
+                 x, y,
+                 view_layout.width, view_layout.height,
+                 view_layout.x, view_layout.y, fb_scale);
+ 
+   cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255);
+   cogl_clear (&stage_pick_id, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH);
+ 
+   /* Disable dithering (if any) when doing the painting in pick mode */
+   dither_enabled_save = cogl_framebuffer_get_dither_enabled (fb);
+   cogl_framebuffer_set_dither_enabled (fb, FALSE);
+ 
+   /* Render the entire scence in pick mode - just single colored silhouette's
+    * are drawn offscreen (as we never swap buffers)
+   */
+   context->pick_mode = mode;
+   _clutter_stage_paint_view (stage, view, NULL);
+   context->pick_mode = CLUTTER_PICK_NONE;
+ 
+   /* Read the color of the screen co-ords pixel. RGBA_8888_PRE is used
+      even though we don't care about the alpha component because under
+      GLES this is the only format that is guaranteed to work so Cogl
+      will end up having to do a conversion if any other format is
+      used. The format is requested as pre-multiplied because Cogl
+      assumes that all pixels in the framebuffer are premultiplied so
+      it avoids a conversion. */
+@@ -3590,123 +3591,125 @@ calculate_z_translation (float z_near)
+    *  z_2d = --------------------------- + z_near
+    *                 sin (0.5°)
+    */
+ 
+    /* We expect the compiler should boil this down to z_near * CONSTANT
+     * already, but just in case we use precomputed constants
+     */
+ #if 0
+ # define A      tanf (_DEG_TO_RAD (30.f))
+ # define B      sinf (_DEG_TO_RAD (120.f))
+ # define C      cosf (_DEG_TO_RAD (30.5f))
+ # define D      sinf (_DEG_TO_RAD (.5f))
+ #else
+ # define A      0.57735025882720947265625f
+ # define B      0.866025388240814208984375f
+ # define C      0.86162912845611572265625f
+ # define D      0.00872653536498546600341796875f
+ #endif
+ 
+   return z_near
+        * A * B * C
+        / D
+        + z_near;
+ }
+ 
+ void
+ _clutter_stage_maybe_setup_viewport (ClutterStage     *stage,
+                                      ClutterStageView *view)
+ {
+   ClutterStagePrivate *priv = stage->priv;
++  CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
+ 
+   if (clutter_stage_view_is_dirty_viewport (view))
+     {
+       cairo_rectangle_int_t view_layout;
+       ClutterPerspective perspective;
+       float fb_scale;
+       float viewport_offset_x;
+       float viewport_offset_y;
+       float z_2d;
+ 
+       CLUTTER_NOTE (PAINT,
+                     "Setting up the viewport { w:%f, h:%f }",
+                     priv->viewport[2],
+                     priv->viewport[3]);
+ 
+       fb_scale = clutter_stage_view_get_scale (view);
+       clutter_stage_view_get_layout (view, &view_layout);
+ 
+       viewport_offset_x = view_layout.x * fb_scale;
+       viewport_offset_y = view_layout.y * fb_scale;
+-      cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x,
+-                         priv->viewport[1] * fb_scale - viewport_offset_y,
+-                         priv->viewport[2] * fb_scale,
+-                         priv->viewport[3] * fb_scale);
++      cogl_framebuffer_set_viewport (fb,
++                                     priv->viewport[0] * fb_scale - viewport_offset_x,
++                                     priv->viewport[1] * fb_scale - viewport_offset_y,
++                                     priv->viewport[2] * fb_scale,
++                                     priv->viewport[3] * fb_scale);
+ 
+       perspective = priv->perspective;
+ 
+       /* Ideally we want to regenerate the perspective matrix whenever
+        * the size changes but if the user has provided a custom matrix
+        * then we don't want to override it */
+       if (!priv->has_custom_perspective)
+         {
+           perspective.aspect = priv->viewport[2] / priv->viewport[3];
+           z_2d = calculate_z_translation (perspective.z_near);
+ 
+           /* NB: z_2d is only enough room for 85% of the stage_height between
+            * the stage and the z_near plane. For behind the stage plane we
+            * want a more consistent gap of 10 times the stage_height before
+            * hitting the far plane so we calculate that relative to the final
+            * height of the stage plane at the z_2d_distance we got... */
+           perspective.z_far = z_2d +
+             tanf (_DEG_TO_RAD (perspective.fovy / 2.0f)) * z_2d * 20.0f;
+ 
+           clutter_stage_set_perspective_internal (stage, &perspective);
+         }
+       else
+         z_2d = calculate_z_translation (perspective.z_near);
+ 
+       cogl_matrix_init_identity (&priv->view);
+       cogl_matrix_view_2d_in_perspective (&priv->view,
+                                           perspective.fovy,
+                                           perspective.aspect,
+                                           perspective.z_near,
+                                           z_2d,
+                                           priv->viewport[2],
+                                           priv->viewport[3]);
+ 
+       clutter_stage_view_set_dirty_viewport (view, FALSE);
+     }
+ 
+   if (clutter_stage_view_is_dirty_projection (view))
+     {
+-      cogl_set_projection_matrix (&priv->projection);
++      cogl_framebuffer_set_projection_matrix (fb, &priv->projection);
+ 
+       clutter_stage_view_set_dirty_projection (view, FALSE);
+     }
+ }
+ 
+ #undef _DEG_TO_RAD
+ 
+ /**
+  * clutter_stage_ensure_redraw:
+  * @stage: a #ClutterStage
+  *
+  * Ensures that @stage is redrawn
+  *
+  * This function should not be called by applications: it is
+  * used when embedding a #ClutterStage into a toolkit with
+  * another windowing system, like GTK+.
+  *
+  * Since: 1.0
+  */
+ void
+ clutter_stage_ensure_redraw (ClutterStage *stage)
+ {
+   ClutterMasterClock *master_clock;
+   ClutterStagePrivate *priv;
+ 
+   g_return_if_fail (CLUTTER_IS_STAGE (stage));
+ 
+   priv = stage->priv;
+ 
+   if (!priv->relayout_pending && !priv->redraw_pending)
+-- 
+2.14.3
+
diff --git a/SOURCES/0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch b/SOURCES/0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch
new file mode 100644
index 0000000..69ca7a4
--- /dev/null
+++ b/SOURCES/0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch
@@ -0,0 +1,481 @@
+From 1d745a858470b29b44e5b0e308488a477c4526cb Mon Sep 17 00:00:00 2001
+From: Carlos Garnacho <carlosg@gnome.org>
+Date: Thu, 22 Feb 2018 17:48:17 +0100
+Subject: [PATCH 1/2] clutter/x11: Implement missing ClutterInputDevice pad
+ vmethods
+
+Use libwacom to be able to find out modes, groups and button roles on
+pad devices.
+
+https://gitlab.gnome.org/GNOME/mutter/issues/48
+
+Closes: #48
+---
+ clutter/clutter/x11/clutter-device-manager-xi2.c | 11 +++
+ clutter/clutter/x11/clutter-device-manager-xi2.h |  8 ++
+ clutter/clutter/x11/clutter-input-device-xi2.c   | 97 ++++++++++++++++++++++++
+ clutter/clutter/x11/clutter-input-device-xi2.h   | 10 +++
+ clutter/configure.ac                             | 32 +++++++-
+ 5 files changed, 156 insertions(+), 2 deletions(-)
+
+diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c
+index d2610cc..dee2604 100644
+--- a/clutter/clutter/x11/clutter-device-manager-xi2.c
++++ b/clutter/clutter/x11/clutter-device-manager-xi2.c
+@@ -495,11 +495,18 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
+                          "device-node", node_path,
+                          "n-rings", num_rings,
+                          "n-strips", num_strips,
++                         "n-mode-groups", MAX (num_rings, num_strips),
+                          NULL);
+ 
+   translate_device_classes (backend_x11->xdpy, retval,
+                             info->classes,
+                             info->num_classes);
++
++#ifdef HAVE_LIBWACOM
++  if (source == CLUTTER_PAD_DEVICE)
++    clutter_input_device_xi2_ensure_wacom_info (retval, manager_xi2->wacom_db);
++#endif
++
+   g_free (vendor_id);
+   g_free (product_id);
+ 
+@@ -2063,4 +2070,8 @@ clutter_device_manager_xi2_init (ClutterDeviceManagerXI2 *self)
+                                                (GDestroyNotify) g_object_unref);
+   self->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL,
+                                                  (GDestroyNotify) g_object_unref);
++
++#ifdef HAVE_LIBWACOM
++  self->wacom_db = libwacom_database_new ();
++#endif
+ }
+diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.h b/clutter/clutter/x11/clutter-device-manager-xi2.h
+index c8e66f9..be25759 100644
+--- a/clutter/clutter/x11/clutter-device-manager-xi2.h
++++ b/clutter/clutter/x11/clutter-device-manager-xi2.h
+@@ -26,6 +26,10 @@
+ 
+ #include <clutter/clutter-device-manager.h>
+ 
++#ifdef HAVE_LIBWACOM
++#include <libwacom/libwacom.h>
++#endif
++
+ G_BEGIN_DECLS
+ 
+ #define CLUTTER_TYPE_DEVICE_MANAGER_XI2            (_clutter_device_manager_xi2_get_type ())
+@@ -51,6 +55,10 @@ struct _ClutterDeviceManagerXI2
+   GList *slave_devices;
+ 
+   int opcode;
++
++#ifdef HAVE_LIBWACOM
++  WacomDeviceDatabase *wacom_db;
++#endif
+ };
+ 
+ struct _ClutterDeviceManagerXI2Class
+diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
+index 7fb0e05..2d9b6d2 100644
+--- a/clutter/clutter/x11/clutter-input-device-xi2.c
++++ b/clutter/clutter/x11/clutter-input-device-xi2.c
+@@ -45,6 +45,10 @@ struct _ClutterInputDeviceXI2
+ 
+   gint device_id;
+   ClutterInputDeviceTool *current_tool;
++
++#ifdef HAVE_LIBWACOM
++  WacomDevice *wacom_device;
++#endif
+ };
+ 
+ #define N_BUTTONS       5
+@@ -88,15 +92,94 @@ clutter_input_device_xi2_is_grouped (ClutterInputDevice *device,
+ }
+ 
+ static void
++clutter_input_device_xi2_finalize (GObject *object)
++{
++#ifdef HAVE_LIBWACOM
++  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (object);
++
++  if (device_xi2->wacom_device)
++    libwacom_destroy (device_xi2->wacom_device);
++#endif
++
++  G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);
++}
++
++static gint
++clutter_input_device_xi2_get_group_n_modes (ClutterInputDevice *device,
++                                            gint                group)
++{
++#ifdef HAVE_LIBWACOM
++  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
++
++  if (device_xi2->wacom_device)
++    {
++      if (group == 0)
++        {
++          if (libwacom_has_ring (device_xi2->wacom_device))
++            return libwacom_get_ring_num_modes (device_xi2->wacom_device);
++          else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 1)
++            return libwacom_get_strips_num_modes (device_xi2->wacom_device);
++        }
++      else if (group == 1)
++        {
++          if (libwacom_has_ring2 (device_xi2->wacom_device))
++            return libwacom_get_ring2_num_modes (device_xi2->wacom_device);
++          else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 2)
++            return libwacom_get_strips_num_modes (device_xi2->wacom_device);
++        }
++    }
++#endif
++
++  return -1;
++}
++
++#ifdef HAVE_LIBWACOM
++static int
++clutter_input_device_xi2_get_button_group (ClutterInputDevice *device,
++                                           guint               button)
++{
++  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
++
++  if (device_xi2->wacom_device)
++    {
++      if (button >= libwacom_get_num_buttons (device_xi2->wacom_device))
++        return -1;
++
++      return libwacom_get_button_led_group (device_xi2->wacom_device,
++                                            'A' + button);
++    }
++  else
++    return -1;
++}
++#endif
++
++static gboolean
++clutter_input_device_xi2_is_mode_switch_button (ClutterInputDevice *device,
++                                                guint               group,
++                                                guint               button)
++{
++  int button_group = -1;
++
++#ifdef HAVE_LIBWACOM
++  button_group = clutter_input_device_xi2_get_button_group (device, button);
++#endif
++
++  return button_group == (int) group;
++}
++
++static void
+ clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
+ {
+   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+   ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass);
+ 
+   gobject_class->constructed = clutter_input_device_xi2_constructed;
++  gobject_class->finalize = clutter_input_device_xi2_finalize;
+ 
+   device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev;
+   device_class->is_grouped = clutter_input_device_xi2_is_grouped;
++  device_class->get_group_n_modes = clutter_input_device_xi2_get_group_n_modes;
++  device_class->is_mode_switch_button = clutter_input_device_xi2_is_mode_switch_button;
+ }
+ 
+ static void
+@@ -196,3 +279,17 @@ clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device)
+   ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
+   return device_xi2->current_tool;
+ }
++
++#ifdef HAVE_LIBWACOM
++void
++clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice  *device,
++                                            WacomDeviceDatabase *wacom_db)
++{
++  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
++  const gchar *node_path;
++
++  node_path = clutter_input_device_get_device_node (device);
++  device_xi2->wacom_device = libwacom_new_from_path (wacom_db, node_path,
++                                                     WFALLBACK_NONE, NULL);
++}
++#endif
+diff --git a/clutter/clutter/x11/clutter-input-device-xi2.h b/clutter/clutter/x11/clutter-input-device-xi2.h
+index b93684f..e30fb4d 100644
+--- a/clutter/clutter/x11/clutter-input-device-xi2.h
++++ b/clutter/clutter/x11/clutter-input-device-xi2.h
+@@ -27,6 +27,10 @@
+ #include <clutter/clutter-input-device.h>
+ #include <X11/extensions/XInput2.h>
+ 
++#ifdef HAVE_LIBWACOM
++#include <libwacom/libwacom.h>
++#endif
++
+ G_BEGIN_DECLS
+ 
+ #define CLUTTER_TYPE_INPUT_DEVICE_XI2           (_clutter_input_device_xi2_get_type ())
+@@ -45,6 +49,12 @@ void  clutter_input_device_xi2_update_tool      (ClutterInputDevice     *device,
+                                                  ClutterInputDeviceTool *tool);
+ ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device);
+ 
++#ifdef HAVE_LIBWACOM
++void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice  *device,
++                                                 WacomDeviceDatabase *wacom_db);
++
++#endif
++
+ G_END_DECLS
+ 
+ #endif /* __CLUTTER_INPUT_DEVICE_XI2_H__ */
+diff --git a/clutter/configure.ac b/clutter/configure.ac
+index 3c3d0c5..5474fa0 100644
+--- a/clutter/configure.ac
++++ b/clutter/configure.ac
+@@ -121,6 +121,7 @@ m4_define([xcomposite_req_version],     [0.4])
+ m4_define([gdk_req_version],            [3.3.18])
+ m4_define([libinput_req_version],       [1.4.0])
+ m4_define([libudev_req_version],        [136])
++m4_define([libwacom_req_version],       [0.13])
+ 
+ AC_SUBST([GLIB_REQ_VERSION],       [glib_req_version])
+ AC_SUBST([COGL_REQ_VERSION],       [cogl_req_version])
+@@ -133,6 +134,7 @@ AC_SUBST([XCOMPOSITE_REQ_VERSION], [xcomposite_req_version])
+ AC_SUBST([GDK_REQ_VERSION],        [gdk_req_version])
+ AC_SUBST([LIBINPUT_REQ_VERSION],   [libinput_req_version])
+ AC_SUBST([LIBUDEV_REQ_VERSION],    [libudev_req_version])
++AC_SUBST([LIBWACOM_REQ_VERSION],   [libwacom_req_version])
+ 
+ # Checks for typedefs, structures, and compiler characteristics.
+ AM_PATH_GLIB_2_0([glib_req_version],
+@@ -508,6 +510,32 @@ X11_EXTS=${X11_EXTS#* }
+ 
+ AC_CACHE_SAVE
+ 
++dnl === Libwacom support for X11 ===============================================
++AC_ARG_WITH(libwacom,
++  AC_HELP_STRING([--without-libwacom],
++                 [disable the use of libwacom for advanced tablet management]),,
++  with_libwacom=auto)
++
++have_libwacom=no
++AC_MSG_CHECKING([libwacom])
++if test x$with_libwacom = xno ; then
++  AC_MSG_RESULT([disabled])
++else
++  if $PKG_CONFIG --exists libwacom '>=' $LIBWACOM_REQ_VERSION; then
++    have_libwacom=yes
++    AC_MSG_RESULT(yes)
++    PKG_CHECK_MODULES([LIBWACOM], [libwacom])
++    AC_SUBST(LIBWACOM_CFLAGS)
++    AC_SUBST(LIBWACOM_LIBS)
++    AC_DEFINE([HAVE_LIBWACOM], 1, [Building with libwacom for advanced tablet management])
++  else
++    AC_MSG_RESULT(no)
++    if test x$with_libwacom = xyes ; then
++      AC_MSG_ERROR([libwacom forced but not found])
++    fi
++  fi
++fi
++
+ dnl === Enable GDK-Pixbuf in tests ============================================
+ 
+ m4_define([pixbuf_default], [yes])
+@@ -679,8 +707,8 @@ AS_IF([test "x$CLUTTER_BASE_PC_FILES_PRIVATE" = "x" && test "x$BACKEND_PC_FILES_
+ AC_SUBST(CLUTTER_REQUIRES)
+ AC_SUBST(CLUTTER_REQUIRES_PRIVATE)
+ 
+-CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS"
+-CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS"
++CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS $LIBWACOM_CFLAGS"
++CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS $LIBWACOM_LIBS"
+ AC_SUBST(CLUTTER_CFLAGS)
+ AC_SUBST(CLUTTER_LIBS)
+ 
+-- 
+1.8.3.1
+
+
+From f8fa4b8fa13fba9ed484be74fb7fc82499d46261 Mon Sep 17 00:00:00 2001
+From: Carlos Garnacho <carlosg@gnome.org>
+Date: Thu, 22 Feb 2018 17:50:42 +0100
+Subject: [PATCH 2/2] clutter/x11: Communicate proper group/mode on pad events.
+
+So we can trigger actions for the right mode.
+
+https://gitlab.gnome.org/GNOME/mutter/issues/48
+
+Closes: #48
+---
+ clutter/clutter/x11/clutter-device-manager-xi2.c | 15 +++++-
+ clutter/clutter/x11/clutter-input-device-xi2.c   | 61 ++++++++++++++++++++++++
+ clutter/clutter/x11/clutter-input-device-xi2.h   |  9 ++++
+ 3 files changed, 84 insertions(+), 1 deletion(-)
+
+diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c
+index dee2604..d269a38 100644
+--- a/clutter/clutter/x11/clutter-device-manager-xi2.c
++++ b/clutter/clutter/x11/clutter-device-manager-xi2.c
+@@ -1133,7 +1133,7 @@ translate_pad_event (ClutterEvent       *event,
+                      ClutterInputDevice *device)
+ {
+   gdouble value;
+-  guint number;
++  guint number, mode = 0;
+ 
+   if (!translate_pad_axis (device, &xev->valuators,
+                            &event->any.type,
+@@ -1147,15 +1147,21 @@ translate_pad_event (ClutterEvent       *event,
+   if (xev->evtype == XI_Motion)
+     value = -1;
+ 
++#ifdef HAVE_LIBWACOM
++  mode = clutter_input_device_xi2_get_pad_group_mode (device, number);
++#endif
++
+   if (event->any.type == CLUTTER_PAD_RING)
+     {
+       event->pad_ring.ring_number = number;
+       event->pad_ring.angle = value;
++      event->pad_ring.mode = mode;
+     }
+   else
+     {
+       event->pad_strip.strip_number = number;
+       event->pad_strip.value = value;
++      event->pad_strip.mode = mode;
+     }
+ 
+   event->any.time = xev->time;
+@@ -1382,6 +1388,13 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
+ 
+             /* Pad buttons are 0-indexed */
+             event->pad_button.button = xev->detail - 1;
++#ifdef HAVE_LIBWACOM
++            clutter_input_device_xi2_update_pad_state (device,
++                                                       event->pad_button.button,
++                                                       (xi_event->evtype == XI_ButtonPress),
++                                                       &event->pad_button.group,
++                                                       &event->pad_button.mode);
++#endif
+             clutter_event_set_device (event, device);
+             clutter_event_set_source_device (event, source_device);
+ 
+diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
+index 2d9b6d2..f62ba85 100644
+--- a/clutter/clutter/x11/clutter-input-device-xi2.c
++++ b/clutter/clutter/x11/clutter-input-device-xi2.c
+@@ -48,6 +48,7 @@ struct _ClutterInputDeviceXI2
+ 
+ #ifdef HAVE_LIBWACOM
+   WacomDevice *wacom_device;
++  GArray *group_modes;
+ #endif
+ };
+ 
+@@ -68,6 +69,15 @@ clutter_input_device_xi2_constructed (GObject *gobject)
+ 
+   if (G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed)
+     G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed (gobject);
++
++#ifdef HAVE_LIBWACOM
++  if (clutter_input_device_get_device_type (CLUTTER_INPUT_DEVICE (gobject)) == CLUTTER_PAD_DEVICE)
++    {
++      device_xi2->group_modes = g_array_new (FALSE, TRUE, sizeof (guint));
++      g_array_set_size (device_xi2->group_modes,
++                        clutter_input_device_get_n_mode_groups (CLUTTER_INPUT_DEVICE (gobject)));
++    }
++#endif
+ }
+ 
+ static gboolean
+@@ -99,6 +109,8 @@ clutter_input_device_xi2_finalize (GObject *object)
+ 
+   if (device_xi2->wacom_device)
+     libwacom_destroy (device_xi2->wacom_device);
++
++  g_array_unref (device_xi2->group_modes);
+ #endif
+ 
+   G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);
+@@ -292,4 +304,53 @@ clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice  *device,
+   device_xi2->wacom_device = libwacom_new_from_path (wacom_db, node_path,
+                                                      WFALLBACK_NONE, NULL);
+ }
++
++guint
++clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device,
++                                             guint               group)
++{
++  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
++
++  if (group >= device_xi2->group_modes->len)
++    return 0;
++
++  return g_array_index (device_xi2->group_modes, guint, group);
++}
++
++void
++clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
++                                           guint               button,
++                                           guint               state,
++                                           guint              *group,
++                                           guint              *mode)
++{
++  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
++  guint button_group, *group_mode;
++  gboolean is_mode_switch = FALSE;
++
++  button_group = clutter_input_device_xi2_get_button_group (device, button);
++  is_mode_switch = button_group >= 0;
++
++  /* Assign all non-mode-switch buttons to group 0 so far */
++  button_group = MAX (0, button_group);
++
++  if (button_group >= device_xi2->group_modes->len)
++    return;
++
++  group_mode = &g_array_index (device_xi2->group_modes, guint, button_group);
++
++  if (is_mode_switch && state)
++    {
++      guint next, n_modes;
++
++      n_modes = clutter_input_device_get_group_n_modes (device, button_group);
++      next = (*group_mode + 1) % n_modes;
++      *group_mode = next;
++    }
++
++  if (group)
++    *group = button_group;
++  if (mode)
++    *mode = *group_mode;
++}
+ #endif
+diff --git a/clutter/clutter/x11/clutter-input-device-xi2.h b/clutter/clutter/x11/clutter-input-device-xi2.h
+index e30fb4d..2194e1b 100644
+--- a/clutter/clutter/x11/clutter-input-device-xi2.h
++++ b/clutter/clutter/x11/clutter-input-device-xi2.h
+@@ -53,6 +53,15 @@ ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInput
+ void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice  *device,
+                                                  WacomDeviceDatabase *wacom_db);
+ 
++guint clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device,
++                                                   guint               group);
++
++void clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
++                                                guint               button,
++                                                guint               state,
++                                                guint              *group,
++                                                guint              *mode);
++
+ #endif
+ 
+ G_END_DECLS
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0001-cogl-Prefer-swizzling-to-convert-BGRA-buffers.patch b/SOURCES/0001-cogl-Prefer-swizzling-to-convert-BGRA-buffers.patch
deleted file mode 100644
index 5ef1fad..0000000
--- a/SOURCES/0001-cogl-Prefer-swizzling-to-convert-BGRA-buffers.patch
+++ /dev/null
@@ -1,248 +0,0 @@
-From 32faf80489f8ee7b4c973660c286f6d228f8e738 Mon Sep 17 00:00:00 2001
-From: Carlos Garnacho <carlosg@gnome.org>
-Date: Sat, 25 Feb 2017 23:21:06 +0100
-Subject: [PATCH] cogl: Prefer swizzling to convert BGRA buffers
-
-(squashed/rebased for gnome-3-22)
-
-If the GL implementation/hw supports the GL_*_texture_swizzle extension,
-pretend that BGRA textures shall contain RGBA data, and let the flipping
-happen when the texture will be used in the rendering pipeline.
-
-This avoids rather expensive format conversions when forcing BGRA buffers
-into RGBA textures, which happens rather often with WL_SHM_FORMAT_ARGB8888
-buffers (like gtk+ uses) in little-endian machines.
-
-In intel/mesa/wayland, the performance improvement is rather noticeable,
-CPU% as seen by top decreases from 45-50% to 25-30% when running
-gtk+/tests/scrolling-performance with a cairo renderer.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779234
----
- cogl/cogl/cogl-driver.h                         |  7 +++++
- cogl/cogl/driver/gl/cogl-framebuffer-gl.c       |  9 ++++++
- cogl/cogl/driver/gl/cogl-texture-2d-gl.c        | 11 ++++----
- cogl/cogl/driver/gl/gl/cogl-driver-gl.c         | 37 +++++++++++++++++++++----
- cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c | 12 ++++++++
- cogl/cogl/driver/gl/gles/cogl-driver-gles.c     | 26 +++++++++++++----
- cogl/cogl/driver/nop/cogl-driver-nop.c          |  1 +
- 7 files changed, 87 insertions(+), 16 deletions(-)
-
-diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h
-index 648228c..85aa0d8 100644
---- a/cogl/cogl/cogl-driver.h
-+++ b/cogl/cogl/cogl-driver.h
-@@ -55,6 +55,13 @@ struct _CoglDriverVtable
-                           GLenum *out_glintformat,
-                           GLenum *out_glformat,
-                           GLenum *out_gltype);
-+  CoglPixelFormat
-+  (* pixel_format_to_gl_with_target) (CoglContext *context,
-+                                      CoglPixelFormat format,
-+                                      CoglPixelFormat target_format,
-+                                      GLenum *out_glintformat,
-+                                      GLenum *out_glformat,
-+                                      GLenum *out_gltype);
- 
-   CoglBool
-   (* update_features) (CoglContext *context,
-diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
-index 18ba08a..2af36f0 100644
---- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
-+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
-@@ -1418,6 +1418,15 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
-                                                             &gl_format,
-                                                             &gl_type);
- 
-+  /* As we are reading pixels, we want to consider the bitmap according to
-+   * its real pixel format, not the swizzled channels we pretend face to the
-+   * pipeline.
-+   */
-+  if ((format == COGL_PIXEL_FORMAT_BGRA_8888 ||
-+       format == COGL_PIXEL_FORMAT_BGRA_8888_PRE) &&
-+      _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
-+    gl_format = GL_BGRA;
-+
-   /* NB: All offscreen rendering is done upside down so there is no need
-    * to flip in this case... */
-   if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) &&
-diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
-index 1193df4..817dd53 100644
---- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
-+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
-@@ -657,11 +657,12 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
- 
-   upload_format = cogl_bitmap_get_format (upload_bmp);
- 
--  ctx->driver_vtable->pixel_format_to_gl (ctx,
--                                          upload_format,
--                                          NULL, /* internal format */
--                                          &gl_format,
--                                          &gl_type);
-+  ctx->driver_vtable->pixel_format_to_gl_with_target (ctx,
-+                                                      upload_format,
-+                                                      _cogl_texture_get_format (tex),
-+                                                      NULL, /* internal gl format */
-+                                                      &gl_format,
-+                                                      &gl_type);
- 
-   /* If this touches the first pixel then we'll update our copy */
-   if (dst_x == 0 && dst_y == 0 &&
-diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
-index 2b9a49c..178262a 100644
---- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
-+++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
-@@ -96,11 +96,12 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
- }
- 
- static CoglPixelFormat
--_cogl_driver_pixel_format_to_gl (CoglContext *context,
--                                 CoglPixelFormat  format,
--                                 GLenum *out_glintformat,
--                                 GLenum *out_glformat,
--                                 GLenum *out_gltype)
-+_cogl_driver_pixel_format_to_gl_with_target (CoglContext *context,
-+                                             CoglPixelFormat format,
-+                                             CoglPixelFormat target_format,
-+                                             GLenum *out_glintformat,
-+                                             GLenum *out_glformat,
-+                                             GLenum *out_gltype)
- {
-   CoglPixelFormat required_format;
-   GLenum glintformat = 0;
-@@ -174,7 +175,16 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
-     case COGL_PIXEL_FORMAT_BGRA_8888:
-     case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
-       glintformat = GL_RGBA;
--      glformat = GL_BGRA;
-+      /* If the driver has texture_swizzle, pretend internal
-+       * and buffer format are the same here, the pixels
-+       * will be flipped through this extension.
-+       */
-+      if (target_format == format &&
-+          _cogl_has_private_feature
-+          (context, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
-+        glformat = GL_RGBA;
-+      else
-+        glformat = GL_BGRA;
-       gltype = GL_UNSIGNED_BYTE;
-       break;
- 
-@@ -289,6 +299,20 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
-   return required_format;
- }
- 
-+static CoglPixelFormat
-+_cogl_driver_pixel_format_to_gl (CoglContext *context,
-+                                 CoglPixelFormat  format,
-+                                 GLenum *out_glintformat,
-+                                 GLenum *out_glformat,
-+                                 GLenum *out_gltype)
-+{
-+  return _cogl_driver_pixel_format_to_gl_with_target (context,
-+                                                      format, format,
-+                                                      out_glintformat,
-+                                                      out_glformat,
-+                                                      out_gltype);
-+}
-+
- static CoglBool
- _cogl_get_gl_version (CoglContext *ctx,
-                       int *major_out,
-@@ -669,6 +693,7 @@ _cogl_driver_gl =
-   {
-     _cogl_driver_pixel_format_from_gl_internal,
-     _cogl_driver_pixel_format_to_gl,
-+    _cogl_driver_pixel_format_to_gl_with_target,
-     _cogl_driver_update_features,
-     _cogl_offscreen_gl_allocate,
-     _cogl_offscreen_gl_free,
-diff --git a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
-index c76a0cf..d5ee4b4 100644
---- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
-+++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
-@@ -114,6 +114,18 @@ _cogl_texture_driver_gen (CoglContext *ctx,
-                                  red_swizzle) );
-     }
- 
-+  /* If swizzle extension is available, prefer it to flip bgra buffers to rgba */
-+  if ((internal_format == COGL_PIXEL_FORMAT_BGRA_8888 ||
-+       internal_format == COGL_PIXEL_FORMAT_BGRA_8888_PRE) &&
-+      _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
-+    {
-+      static const GLint bgra_swizzle[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
-+
-+      GE( ctx, glTexParameteriv (gl_target,
-+                                 GL_TEXTURE_SWIZZLE_RGBA,
-+                                 bgra_swizzle) );
-+    }
-+
-   return tex;
- }
- 
-diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
-index bf63fcc..521f6ef 100644
---- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
-+++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
-@@ -67,11 +67,12 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
- }
- 
- static CoglPixelFormat
--_cogl_driver_pixel_format_to_gl (CoglContext *context,
--                                 CoglPixelFormat  format,
--                                 GLenum *out_glintformat,
--                                 GLenum *out_glformat,
--                                 GLenum *out_gltype)
-+_cogl_driver_pixel_format_to_gl_with_target (CoglContext *context,
-+                                             CoglPixelFormat format,
-+                                             CoglPixelFormat target_format,
-+                                             GLenum *out_glintformat,
-+                                             GLenum *out_glformat,
-+                                             GLenum *out_gltype)
- {
-   CoglPixelFormat required_format;
-   GLenum glintformat;
-@@ -219,6 +220,20 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
-   return required_format;
- }
- 
-+static CoglPixelFormat
-+_cogl_driver_pixel_format_to_gl (CoglContext *context,
-+                                 CoglPixelFormat  format,
-+                                 GLenum *out_glintformat,
-+                                 GLenum *out_glformat,
-+                                 GLenum *out_gltype)
-+{
-+  return _cogl_driver_pixel_format_to_gl_with_target (context,
-+                                                      format, format,
-+                                                      out_glintformat,
-+                                                      out_glformat,
-+                                                      out_gltype);
-+}
-+
- static CoglBool
- _cogl_get_gl_version (CoglContext *ctx,
-                       int *major_out,
-@@ -457,6 +472,7 @@ _cogl_driver_gles =
-   {
-     _cogl_driver_pixel_format_from_gl_internal,
-     _cogl_driver_pixel_format_to_gl,
-+    _cogl_driver_pixel_format_to_gl_with_target,
-     _cogl_driver_update_features,
-     _cogl_offscreen_gl_allocate,
-     _cogl_offscreen_gl_free,
-diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c
-index d9b1d0f..6e04e71 100644
---- a/cogl/cogl/driver/nop/cogl-driver-nop.c
-+++ b/cogl/cogl/driver/nop/cogl-driver-nop.c
-@@ -61,6 +61,7 @@ _cogl_driver_nop =
-   {
-     NULL, /* pixel_format_from_gl_internal */
-     NULL, /* pixel_format_to_gl */
-+    NULL, /* pixel_format_to_gl_with_target */
-     _cogl_driver_update_features,
-     _cogl_offscreen_nop_allocate,
-     _cogl_offscreen_nop_free,
--- 
-2.9.3
-
diff --git a/SOURCES/0001-display-Check-we-have-a-screen-before-freeing-it.patch b/SOURCES/0001-display-Check-we-have-a-screen-before-freeing-it.patch
deleted file mode 100644
index 5b8c284..0000000
--- a/SOURCES/0001-display-Check-we-have-a-screen-before-freeing-it.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 91dced2ea5e4317c0067df28071c7694fb2f35ac Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
-Date: Fri, 17 Feb 2017 14:24:38 +0100
-Subject: [PATCH] display: Check we have a screen before freeing it
-
-The reason for the display to be closed may be meta_screen_new()
-returning NULL, in which case we don't have a screen to free.
-Avoid a segfault on exit by adding a proper check.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=778831
----
- src/core/display.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/src/core/display.c b/src/core/display.c
-index 42a530f6c..c6248ce34 100644
---- a/src/core/display.c
-+++ b/src/core/display.c
-@@ -1113,7 +1113,9 @@ meta_display_close (MetaDisplay *display,
-   meta_display_free_events_x11 (display);
-   meta_display_free_events (display);
- 
--  meta_screen_free (display->screen, timestamp);
-+  if (display->screen)
-+    meta_screen_free (display->screen, timestamp);
-+  display->screen = NULL;
- 
-   /* Must be after all calls to meta_window_unmanage() since they
-    * unregister windows
--- 
-2.12.0
-
diff --git a/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch b/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch
index 3a6d899..4eeb33e 100644
--- a/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch
+++ b/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch
@@ -1,7 +1,8 @@
-From def9c7e2cb32d8aeb7c48f126a43e2ff97fe14e2 Mon Sep 17 00:00:00 2001
+From 887537360c3c3b0ae5d0ef0222fad4d0a3bc41c9 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
 Date: Thu, 21 Jul 2016 15:43:12 +0200
-Subject: [PATCH] events: Don't move (sloppy) focus while buttons are pressed
+Subject: [PATCH 5/8] events: Don't move (sloppy) focus while buttons are
+ pressed
 
 (https://bugzilla.redhat.com/show_bug.cgi?id=1358535)
 ---
@@ -9,13 +10,14 @@ Subject: [PATCH] events: Don't move (sloppy) focus while buttons are pressed
  1 file changed, 11 insertions(+)
 
 diff --git a/src/x11/events.c b/src/x11/events.c
-index 98f5f03a9..b763af312 100644
+index 49f2569f3..ecb4de53d 100644
 --- a/src/x11/events.c
 +++ b/src/x11/events.c
 @@ -830,6 +830,16 @@ crossing_serial_is_ignored (MetaDisplay  *display,
+   return FALSE;
  }
  
- static gboolean
++static gboolean
 +event_has_button_mask (XIEnterEvent *enter_event)
 +{
 +  int i;
@@ -25,11 +27,10 @@ index 98f5f03a9..b763af312 100644
 +  return FALSE;
 +}
 +
-+static gboolean
+ static gboolean
  handle_input_xevent (MetaDisplay  *display,
                       XIEvent      *input_event,
-                      unsigned long serial)
-@@ -870,6 +880,7 @@ handle_input_xevent (MetaDisplay  *display,
+@@ -871,6 +881,7 @@ handle_input_xevent (MetaDisplay  *display,
         * avoid races.
         */
        if (window && !crossing_serial_is_ignored (display, serial) &&
@@ -38,5 +39,5 @@ index 98f5f03a9..b763af312 100644
            enter_event->mode != XINotifyUngrab &&
            enter_event->detail != XINotifyInferior &&
 -- 
-2.12.0
+2.14.2
 
diff --git a/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch b/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch
new file mode 100644
index 0000000..8fcef03
--- /dev/null
+++ b/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch
@@ -0,0 +1,132 @@
+From 5e3a6efd0e2bbea040e203b996e7d00ab3431cfa Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode@redhat.com>
+Date: Tue, 13 Feb 2018 09:44:50 -0500
+Subject: [PATCH] main: be more aggressive in assuming X11 backend
+
+If the session is started by vncserver right now, the
+XDG_SESSION_TYPE won't be X11.  Ideally that would be
+fixed, but for backward compatibility we should default
+to X11 if the session type isn't set to wayland explicitly.
+---
+ src/core/main.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 079f6a9ef..8e8bc3f77 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -304,108 +304,106 @@ meta_finalize (void)
+ 
+ #ifdef HAVE_WAYLAND
+   if (meta_is_wayland_compositor ())
+     meta_wayland_finalize ();
+ #endif
+ }
+ 
+ static gboolean
+ on_sigterm (gpointer user_data)
+ {
+   meta_quit (EXIT_SUCCESS);
+ 
+   return G_SOURCE_REMOVE;
+ }
+ 
+ #if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND)
+ static gboolean
+ session_type_is_supported (const char *session_type)
+ {
+    return (g_strcmp0 (session_type, "x11") == 0) ||
+           (g_strcmp0 (session_type, "wayland") == 0);
+ }
+ 
+ static char *
+ find_session_type (void)
+ {
+   char **sessions = NULL;
+   char *session_id;
+   char *session_type;
+   const char *session_type_env;
+-  gboolean is_tty = FALSE;
+   int ret, i;
+ 
+   ret = sd_pid_get_session (0, &session_id);
+   if (ret == 0 && session_id != NULL)
+     {
+       ret = sd_session_get_type (session_id, &session_type);
+       free (session_id);
+ 
+       if (ret == 0)
+         {
+           if (session_type_is_supported (session_type))
+             goto out;
+-          else
+-            is_tty = g_strcmp0 (session_type, "tty") == 0;
++
+           free (session_type);
+         }
+     }
+   else if (sd_uid_get_sessions (getuid (), 1, &sessions) > 0)
+     {
+       for (i = 0; sessions[i] != NULL; i++)
+         {
+           ret = sd_session_get_type (sessions[i], &session_type);
+ 
+           if (ret < 0)
+             continue;
+ 
+           if (session_type_is_supported (session_type))
+             {
+               g_strfreev (sessions);
+               goto out;
+             }
+ 
+           free (session_type);
+         }
+     }
+   g_strfreev (sessions);
+ 
+   session_type_env = g_getenv ("XDG_SESSION_TYPE");
+   if (session_type_is_supported (session_type_env))
+     {
+       /* The string should be freeable */
+       session_type = strdup (session_type_env);
+       goto out;
+     }
+ 
+-  /* Legacy support for starting through xinit */
+-  if (is_tty && (g_getenv ("MUTTER_DISPLAY") || g_getenv ("DISPLAY")))
++  /* Legacy support for starting through xinit or vncserver */
++  if (g_getenv ("MUTTER_DISPLAY") || g_getenv ("DISPLAY"))
+     {
+       session_type = strdup ("x11");
+       goto out;
+     }
+ 
+   meta_warning ("Unsupported session type\n");
+   meta_exit (META_EXIT_ERROR);
+ 
+ out:
+   return session_type;
+ }
+ 
+ static gboolean
+ check_for_wayland_session_type (void)
+ {
+   char *session_type;
+   gboolean is_wayland;
+ 
+   session_type = find_session_type ();
+   is_wayland = g_strcmp0 (session_type, "wayland") == 0;
+   free (session_type);
+ 
+   return is_wayland;
+ }
+ #endif
+ 
+ /*
+  * Determine the compositor configuration, i.e. whether to run as a Wayland
+  * compositor, as well as what backend to use.
+  *
+-- 
+2.14.3
+
diff --git a/SOURCES/0001-monitor-config-Consider-external-layout-before-defau.patch b/SOURCES/0001-monitor-config-Consider-external-layout-before-defau.patch
deleted file mode 100644
index 2527d38..0000000
--- a/SOURCES/0001-monitor-config-Consider-external-layout-before-defau.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From d2cc8089a6fd31e302b23ac787d84ff5a3257b6c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
-Date: Thu, 28 Jan 2016 15:26:33 +0100
-Subject: [PATCH] monitor-config: Consider external layout before default
- linear config
-
-In case of no existing configuration, we use a default layout of
-aligning attached displays horizontally. This sidesteps any layout
-configuration that is done externally, for instance via xorg.conf,
-which is not desirable. Instead, base the initial configuration on
-the existing layout if it passes some sanity checks before falling
-back to the default linear config.
----
- src/backends/meta-monitor-config.c | 76 +++++++++++++++++++++++++++++---------
- 1 file changed, 59 insertions(+), 17 deletions(-)
-
-diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c
-index 21e3126f2..492b0ffe1 100644
---- a/src/backends/meta-monitor-config.c
-+++ b/src/backends/meta-monitor-config.c
-@@ -1130,6 +1130,23 @@ init_config_from_preferred_mode (MetaOutputConfig *config,
-   config->is_presentation = FALSE;
- }
- 
-+static void
-+init_config_from_output (MetaOutputConfig *config,
-+                         MetaOutput       *output)
-+{
-+  config->enabled = (output->crtc != NULL);
-+
-+  if (!config->enabled)
-+    return;
-+
-+  config->rect = output->crtc->rect;
-+  config->refresh_rate = output->crtc->current_mode->refresh_rate;
-+  config->transform = output->crtc->transform;
-+  config->is_primary = output->is_primary;
-+  config->is_presentation = output->is_presentation;
-+  config->is_underscanning = output->is_underscanning;
-+}
-+
- /* This function handles configuring the outputs when the driver provides a
-  * suggested layout position for each output. This is done in recent versions
-  * of qxl and allows displays to be aligned on the guest in the same order as
-@@ -1368,6 +1385,45 @@ extend_stored_config (MetaMonitorConfig *self,
-   return FALSE;
- }
- 
-+static gboolean
-+make_initial_config_from_current (MetaMonitorConfig *self,
-+                                  MetaOutput        *outputs,
-+                                  unsigned           n_outputs,
-+                                  int                max_width,
-+                                  int                max_height,
-+                                  MetaConfiguration *config)
-+{
-+  GList *region = NULL;
-+  unsigned i;
-+
-+  g_return_val_if_fail (config != NULL, FALSE);
-+
-+  if (g_hash_table_size (self->configs) > 0)
-+    return FALSE;
-+
-+  g_assert (config->n_outputs == n_outputs);
-+
-+  for (i = 0; i < n_outputs; i++)
-+    {
-+      init_config_from_output (&config->outputs[i], &outputs[i]);
-+
-+      /* Reject the configuration if the suggested positions result in
-+       * overlapping displays */
-+      if (meta_rectangle_overlaps_with_region (region, &config->outputs[i].rect))
-+        {
-+          g_warning ("Overlapping outputs, rejecting suggested configuration");
-+          g_list_free (region);
-+          return FALSE;
-+        }
-+
-+      region = g_list_prepend (region, &config->outputs[i].rect);
-+    }
-+
-+  g_list_free (region);
-+
-+  return TRUE;
-+}
-+
- static MetaConfiguration *
- make_default_config (MetaMonitorConfig *self,
-                      MetaOutput        *outputs,
-@@ -1399,6 +1455,9 @@ make_default_config (MetaMonitorConfig *self,
-       extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
-       goto check_limits;
- 
-+  if (make_initial_config_from_current (self, outputs, n_outputs, max_width, max_height, ret))
-+      goto check_limits;
-+
-   make_linear_config (self, outputs, n_outputs, max_width, max_height, ret);
- 
- check_limits:
-@@ -1500,23 +1559,6 @@ meta_monitor_config_make_default (MetaMonitorConfig  *self,
-     }
- }
- 
--static void
--init_config_from_output (MetaOutputConfig *config,
--                         MetaOutput       *output)
--{
--  config->enabled = (output->crtc != NULL);
--
--  if (!config->enabled)
--    return;
--
--  config->rect = output->crtc->rect;
--  config->refresh_rate = output->crtc->current_mode->refresh_rate;
--  config->transform = output->crtc->transform;
--  config->is_primary = output->is_primary;
--  config->is_presentation = output->is_presentation;
--  config->is_underscanning = output->is_underscanning;
--}
--
- void
- meta_monitor_config_update_current (MetaMonitorConfig  *self,
-                                     MetaMonitorManager *manager)
--- 
-2.12.0
-
diff --git a/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch b/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch
new file mode 100644
index 0000000..3a67aa8
--- /dev/null
+++ b/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch
@@ -0,0 +1,145 @@
+From 679644180338527648d7856640c2021b4f4daf30 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
+Date: Thu, 28 Jan 2016 15:26:33 +0100
+Subject: [PATCH] monitor-manager: Consider external layout before default
+ linear config
+
+In case of no existing configuration, we use a default layout of
+aligning attached displays horizontally. This sidesteps any layout
+configuration that is done externally, for instance via xorg.conf,
+which is not desirable. Instead, base the initial configuration on
+the existing layout if it passes some sanity checks before falling
+back to the default linear config.
+---
+ src/backends/meta-monitor-config-manager.c | 71 ++++++++++++++++++++++++++++++
+ src/backends/meta-monitor-config-manager.h |  1 +
+ src/backends/meta-monitor-manager.c        | 19 ++++++++
+ 3 files changed, 91 insertions(+)
+
+diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
+index cdc9fb775..2fe620767 100644
+--- a/src/backends/meta-monitor-config-manager.c
++++ b/src/backends/meta-monitor-config-manager.c
+@@ -558,6 +558,77 @@ create_preferred_logical_monitor_config (MetaMonitorManager          *monitor_ma
+   return logical_monitor_config;
+ }
+ 
++static MetaLogicalMonitorConfig *
++create_logical_monitor_config_from_output (MetaMonitorManager           *monitor_manager,
++                                           MetaMonitor                  *monitor,
++                                           MetaLogicalMonitorConfig     *primary_logical_monitor_config,
++                                           MetaLogicalMonitorLayoutMode  layout_mode)
++{
++    MetaOutput *output;
++
++    output = meta_monitor_get_main_output (monitor);
++    return create_preferred_logical_monitor_config (monitor_manager,
++                                                    monitor,
++                                                    output->crtc->rect.x,
++                                                    output->crtc->rect.y,
++                                                    primary_logical_monitor_config,
++                                                    layout_mode);
++}
++
++MetaMonitorsConfig *
++meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager)
++{
++  MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
++  GList *logical_monitor_configs;
++  MetaMonitor *primary_monitor;
++  MetaLogicalMonitorLayoutMode layout_mode;
++  MetaLogicalMonitorConfig *primary_logical_monitor_config;
++  GList *monitors;
++  GList *l;
++
++  if (meta_monitor_config_store_get_config_count (config_manager->config_store) > 0)
++    return NULL;
++
++  primary_monitor = find_primary_monitor (monitor_manager);
++  if (!primary_monitor || !meta_monitor_is_active (primary_monitor))
++    return NULL;
++
++  layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
++
++  primary_logical_monitor_config =
++    create_logical_monitor_config_from_output (monitor_manager,
++                                               primary_monitor,
++                                               NULL,
++                                               layout_mode);
++
++  primary_logical_monitor_config->is_primary = TRUE;
++  logical_monitor_configs = g_list_append (NULL,
++                                           primary_logical_monitor_config);
++
++  monitors = meta_monitor_manager_get_monitors (monitor_manager);
++  for (l = monitors; l; l = l->next)
++    {
++      MetaMonitor *monitor = l->data;
++      MetaLogicalMonitorConfig *logical_monitor_config;
++
++      if (monitor == primary_monitor)
++        continue;
++
++      if (!meta_monitor_is_active (monitor))
++        continue;
++
++      logical_monitor_config =
++        create_logical_monitor_config_from_output (monitor_manager,
++                                                   monitor,
++                                                   primary_logical_monitor_config,
++                                                   layout_mode);
++
++      logical_monitor_configs = g_list_append (logical_monitor_configs,
++                                               logical_monitor_config);
++    }
++  return NULL;
++}
++
+ MetaMonitorsConfig *
+ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager)
+ {
+diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
+index b99cdaba2..516909dd7 100644
+--- a/src/backends/meta-monitor-config-manager.h
++++ b/src/backends/meta-monitor-config-manager.h
+@@ -87,6 +87,7 @@ gboolean meta_monitor_config_manager_assign (MetaMonitorManager *manager,
+ 
+ MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager);
+ 
++MetaMonitorsConfig * meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager);
+ MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager);
+ 
+ MetaMonitorsConfig * meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_manager);
+diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
+index f2ad3f3d0..8b548fd68 100644
+--- a/src/backends/meta-monitor-manager.c
++++ b/src/backends/meta-monitor-manager.c
+@@ -553,6 +553,25 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
+       g_clear_object (&config);
+     }
+ 
++  config = meta_monitor_config_manager_create_current (manager->config_manager);
++  if (config)
++    {
++      if (!meta_monitor_manager_apply_monitors_config (manager,
++                                                       config,
++                                                       method,
++                                                       &error))
++        {
++          g_clear_object (&config);
++          g_warning ("Failed to use current monitor configuration: %s",
++                     error->message);
++          g_clear_error (&error);
++        }
++      else
++        {
++          goto done;
++        }
++    }
++
+   config = meta_monitor_config_manager_create_linear (manager->config_manager);
+   if (config)
+     {
+-- 
+2.14.2
+
diff --git a/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch b/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch
index c81b5bb..127f61d 100644
--- a/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch
+++ b/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch
@@ -1,21 +1,21 @@
-From 677c216fbf52e5cbc1d5f0890ebc1ee9216cfd27 Mon Sep 17 00:00:00 2001
+From ed7cad0561b79e68ddd91f0e12042087199676ea Mon Sep 17 00:00:00 2001
 From: Rui Matos <tiagomatos@gmail.com>
 Date: Sun, 25 Oct 2015 16:14:58 +0100
-Subject: [PATCH] monitor-manager-xrandr: Force an update when resuming from
- suspend
+Subject: [PATCH 3/8] monitor-manager-xrandr: Force an update when resuming
+ from suspend
 
 The stack below us isn't as reliable as we'd like and in some cases
 doesn't generate RRScreenChangeNotify events when e.g. resuming a
 laptop on a dock, meaning that we'd miss newly attached outputs.
 ---
- src/backends/x11/meta-monitor-manager-xrandr.c | 157 +++++++++++++++++++------
- 1 file changed, 122 insertions(+), 35 deletions(-)
+ src/backends/x11/meta-monitor-manager-xrandr.c | 188 ++++++++++++++++++-------
+ 1 file changed, 137 insertions(+), 51 deletions(-)
 
 diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
-index 4a27b3a14..aa3ff76f5 100644
+index 8d1bdfb69..d451fcccc 100644
 --- a/src/backends/x11/meta-monitor-manager-xrandr.c
 +++ b/src/backends/x11/meta-monitor-manager-xrandr.c
-@@ -58,6 +58,11 @@ struct _MetaMonitorManagerXrandr
+@@ -61,6 +61,11 @@ struct _MetaMonitorManagerXrandr
    XRRScreenResources *resources;
    int rr_event_base;
    int rr_error_base;
@@ -25,9 +25,9 @@ index 4a27b3a14..aa3ff76f5 100644
 +
 +  gboolean need_hardware_poll;
    gboolean has_randr15;
- };
  
-@@ -763,8 +768,15 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
+   xcb_timestamp_t last_xrandr_set_timestamp;
+@@ -787,8 +792,15 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
    manager->screen_width = WidthOfScreen (screen);
    manager->screen_height = HeightOfScreen (screen);
  
@@ -45,9 +45,9 @@ index 4a27b3a14..aa3ff76f5 100644
    if (!resources)
      return;
  
-@@ -1414,6 +1426,100 @@ meta_monitor_manager_xrandr_init_monitors(MetaMonitorManagerXrandr *manager_xran
+@@ -1910,6 +1922,115 @@ meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager
+   return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
  }
- #endif
  
 +static gboolean
 +is_xvnc (MetaMonitorManager *manager)
@@ -65,25 +65,40 @@ index 4a27b3a14..aa3ff76f5 100644
 +meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
 +{
 +  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
-+  gboolean hotplug;
++  gboolean is_hotplug;
++  gboolean is_our_configuration;
 +  unsigned int timestamp;
 +
-+  meta_monitor_manager_read_current_config (manager);
++  meta_monitor_manager_read_current_state (manager);
 +
 +  timestamp = manager_xrandr->resources->timestamp;
 +  if (is_xvnc (manager))
 +    timestamp += 100;
 +
-+  hotplug = timestamp < manager_xrandr->resources->configTimestamp;
-+  if (hotplug)
++  is_hotplug = (timestamp < manager_xrandr->resources->configTimestamp);
++  is_our_configuration = (manager_xrandr->resources->timestamp ==
++                          manager_xrandr->last_xrandr_set_timestamp);
++  if (is_hotplug)
 +    {
-+      /* This is a hotplug event, so go ahead and build a new configuration. */
 +      meta_monitor_manager_on_hotplug (manager);
 +    }
 +  else
 +    {
-+      /* Something else changed -- tell the world about it. */
-+      meta_monitor_manager_rebuild_derived (manager);
++      MetaMonitorsConfig *config;
++
++      if (is_our_configuration)
++        {
++          MetaMonitorConfigManager *config_manager =
++            meta_monitor_manager_get_config_manager (manager);
++
++          config = meta_monitor_config_manager_get_current (config_manager);
++        }
++      else
++        {
++          config = NULL;
++        }
++
++      meta_monitor_manager_rebuild_derived (manager, config);
 +    }
 +}
 +
@@ -146,7 +161,7 @@ index 4a27b3a14..aa3ff76f5 100644
  static void
  meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
  {
-@@ -1449,6 +1555,15 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
+@@ -1948,6 +2069,15 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
        meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
  #endif
      }
@@ -162,9 +177,9 @@ index 4a27b3a14..aa3ff76f5 100644
  }
  
  static void
-@@ -1460,6 +1575,10 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
-     XRRFreeScreenResources (manager_xrandr->resources);
-   manager_xrandr->resources = NULL;
+@@ -1962,6 +2092,10 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
+   g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
+   g_free (manager_xrandr->supported_scales);
  
 +  if (manager_xrandr->logind_watch_id > 0)
 +    g_bus_unwatch_name (manager_xrandr->logind_watch_id);
@@ -173,8 +188,8 @@ index 4a27b3a14..aa3ff76f5 100644
    G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
  }
  
-@@ -1484,48 +1603,16 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
- #endif
+@@ -1996,64 +2130,16 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
+     g_quark_from_static_string ("-meta-monitor-xrandr-data");
  }
  
 -static gboolean
@@ -194,7 +209,8 @@ index 4a27b3a14..aa3ff76f5 100644
  					   XEvent                   *event)
  {
 -  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
--  gboolean hotplug;
+-  gboolean is_hotplug;
+-  gboolean is_our_configuration;
 -  unsigned int timestamp;
 -
    if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
@@ -202,27 +218,42 @@ index 4a27b3a14..aa3ff76f5 100644
  
    XRRUpdateConfiguration (event);
  
--  meta_monitor_manager_read_current_config (manager);
+-  meta_monitor_manager_read_current_state (manager);
+-
 -
 -  timestamp = manager_xrandr->resources->timestamp;
 -  if (is_xvnc (manager))
 -    timestamp += 100;
 -
--  hotplug = timestamp < manager_xrandr->resources->configTimestamp;
--  if (hotplug)
+-  is_hotplug = (timestamp < manager_xrandr->resources->configTimestamp);
+-  is_our_configuration = (manager_xrandr->resources->timestamp ==
+-                          manager_xrandr->last_xrandr_set_timestamp);
+-  if (is_hotplug)
 -    {
--      /* This is a hotplug event, so go ahead and build a new configuration. */
 -      meta_monitor_manager_on_hotplug (manager);
 -    }
 -  else
 -    {
--      /* Something else changed -- tell the world about it. */
--      meta_monitor_manager_rebuild_derived (manager);
+-      MetaMonitorsConfig *config;
+-
+-      if (is_our_configuration)
+-        {
+-          MetaMonitorConfigManager *config_manager =
+-            meta_monitor_manager_get_config_manager (manager);
+-
+-          config = meta_monitor_config_manager_get_current (config_manager);
+-        }
+-      else
+-        {
+-          config = NULL;
+-        }
+-
+-      meta_monitor_manager_xrandr_rebuild_derived (manager, config);
 -    }
 +  meta_monitor_manager_xrandr_update (manager_xrandr);
  
    return TRUE;
  }
 -- 
-2.12.0
+2.14.2
 
diff --git a/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch b/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch
index f77a18f..73e1cd5 100644
--- a/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch
+++ b/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch
@@ -1,7 +1,8 @@
-From 257c8e8d3b7103973dfdc2665d210c63496be457 Mon Sep 17 00:00:00 2001
+From 73cae2c78af65cdfd6fa0c8257b4d3ae593f9f74 Mon Sep 17 00:00:00 2001
 From: Rui Matos <tiagomatos@gmail.com>
 Date: Tue, 6 Oct 2015 21:16:18 +0200
-Subject: [PATCH] monitor-manager-xrandr: Work around spurious hotplugs on Xvnc
+Subject: [PATCH 2/8] monitor-manager-xrandr: Work around spurious hotplugs on
+ Xvnc
 
 Xvnc turns its outputs off/on on every mode set which makes us believe
 there was an hotplug when there actually wasn't. Work around this by
@@ -9,15 +10,15 @@ requiring new randr configuration timestamps to be ahead of the last
 set timestamp by at least 100 ms for us to consider them an actual
 hotplug.
 ---
- src/backends/x11/meta-monitor-manager-xrandr.c | 19 ++++++++++++++++++-
- 1 file changed, 18 insertions(+), 1 deletion(-)
+ src/backends/x11/meta-monitor-manager-xrandr.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
 
 diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
-index b82120af9..4a27b3a14 100644
+index c369d4960..8d1bdfb69 100644
 --- a/src/backends/x11/meta-monitor-manager-xrandr.c
 +++ b/src/backends/x11/meta-monitor-manager-xrandr.c
-@@ -1484,12 +1484,25 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
- #endif
+@@ -1909,6 +1909,18 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
+     g_quark_from_static_string ("-meta-monitor-xrandr-data");
  }
  
 +static gboolean
@@ -35,26 +36,28 @@ index b82120af9..4a27b3a14 100644
  gboolean
  meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
  					   XEvent                   *event)
- {
+@@ -1916,6 +1928,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
    MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
-   gboolean hotplug;
+   gboolean is_hotplug;
+   gboolean is_our_configuration;
 +  unsigned int timestamp;
  
    if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
      return FALSE;
-@@ -1498,7 +1511,11 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
+@@ -1925,8 +1938,11 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
+   meta_monitor_manager_read_current_state (manager);
  
-   meta_monitor_manager_read_current_config (manager);
  
--  hotplug = manager_xrandr->resources->timestamp < manager_xrandr->resources->configTimestamp;
+-  is_hotplug = (manager_xrandr->resources->timestamp <
+-                manager_xrandr->resources->configTimestamp);
 +  timestamp = manager_xrandr->resources->timestamp;
 +  if (is_xvnc (manager))
 +    timestamp += 100;
 +
-+  hotplug = timestamp < manager_xrandr->resources->configTimestamp;
-   if (hotplug)
-     {
-       /* This is a hotplug event, so go ahead and build a new configuration. */
++  is_hotplug = (timestamp < manager_xrandr->resources->configTimestamp);
+   is_our_configuration = (manager_xrandr->resources->timestamp ==
+                           manager_xrandr->last_xrandr_set_timestamp);
+   if (is_hotplug)
 -- 
-2.12.0
+2.14.2
 
diff --git a/SOURCES/0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch b/SOURCES/0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch
new file mode 100644
index 0000000..094910d
--- /dev/null
+++ b/SOURCES/0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch
@@ -0,0 +1,44 @@
+From 4b2d21ff03ed389138fcb9bca778aec02bafcadb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
+Date: Fri, 2 Feb 2018 14:34:50 +0800
+Subject: [PATCH] renderer/x11: Enable GPU memory purge error extension if
+ available
+
+This was done by the clutter X11 backend before prior to introducing
+MetaRenderer, but during that work, enabling of said extension was lost.
+Let's turn it on again.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=739178
+---
+ src/backends/x11/meta-backend-x11.c  | 2 --
+ src/backends/x11/meta-renderer-x11.c | 1 +
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
+index 233532435..c7602cc70 100644
+--- a/src/backends/x11/meta-backend-x11.c
++++ b/src/backends/x11/meta-backend-x11.c
+@@ -705,8 +705,6 @@ meta_backend_x11_init (MetaBackendX11 *x11)
+    */
+   XInitThreads();
+ 
+-  clutter_x11_request_reset_on_video_memory_purge ();
+-
+   /* We do X11 event retrieval ourselves */
+   clutter_x11_disable_event_retrieval ();
+ }
+diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c
+index 90924e038..003211d85 100644
+--- a/src/backends/x11/meta-renderer-x11.c
++++ b/src/backends/x11/meta-renderer-x11.c
+@@ -73,6 +73,7 @@ meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer)
+   cogl_renderer = cogl_renderer_new ();
+   cogl_renderer_set_custom_winsys (cogl_renderer, get_x11_cogl_winsys_vtable);
+   cogl_xlib_renderer_set_foreign_display (cogl_renderer, xdisplay);
++  cogl_xlib_renderer_request_reset_on_video_memory_purge (cogl_renderer, TRUE);
+ 
+   /* Set up things so that if the INTEL_swap_event extension is not present,
+    * but the driver is known to have good thread support, we use an extra
+-- 
+2.14.3
+
diff --git a/SOURCES/0001-rhel7-Fix-build-for-el7.patch b/SOURCES/0001-rhel7-Fix-build-for-el7.patch
new file mode 100644
index 0000000..5b9ac0f
--- /dev/null
+++ b/SOURCES/0001-rhel7-Fix-build-for-el7.patch
@@ -0,0 +1,898 @@
+From 6be34265a67e9ca1e30fe42993d5743b01d3b010 Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Fri, 15 Sep 2017 08:55:44 +0100
+Subject: [PATCH] rhel7: Fix build for el7
+
+---
+ .../evdev/clutter-virtual-input-device-evdev.c     |   1 +
+ clutter/clutter/evdev/linux/input-event-codes.h    | 838 +++++++++++++++++++++
+ src/backends/native/meta-input-settings-native.c   |   2 +-
+ src/wayland/meta-wayland-tablet-tool.c             |   2 +-
+ 4 files changed, 841 insertions(+), 2 deletions(-)
+ create mode 100644 clutter/clutter/evdev/linux/input-event-codes.h
+
+diff --git a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c b/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c
+index e487708..8443c0a 100644
+--- a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c
++++ b/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c
+@@ -33,6 +33,7 @@
+ #include "evdev/clutter-input-device-evdev.h"
+ #include "evdev/clutter-seat-evdev.h"
+ #include "evdev/clutter-virtual-input-device-evdev.h"
++#include "evdev/linux/input-event-codes.h"
+ 
+ enum
+ {
+diff --git a/clutter/clutter/evdev/linux/input-event-codes.h b/clutter/clutter/evdev/linux/input-event-codes.h
+new file mode 100644
+index 0000000..e2b5c75
+--- /dev/null
++++ b/clutter/clutter/evdev/linux/input-event-codes.h
+@@ -0,0 +1,838 @@
++/*
++ * Input event codes
++ *
++ *    *** IMPORTANT ***
++ * This file is not only included from C-code but also from devicetree source
++ * files. As such this file MUST only contain comments and defines.
++ *
++ * Copyright (c) 1999-2002 Vojtech Pavlik
++ * Copyright (c) 2015 Hans de Goede <hdegoede@redhat.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ */
++#ifndef _INPUT_EVENT_CODES_H
++#define _INPUT_EVENT_CODES_H
++
++/*
++ * Device properties and quirks
++ */
++
++#define INPUT_PROP_POINTER		0x00	/* needs a pointer */
++#define INPUT_PROP_DIRECT		0x01	/* direct input devices */
++#define INPUT_PROP_BUTTONPAD		0x02	/* has button(s) under pad */
++#define INPUT_PROP_SEMI_MT		0x03	/* touch rectangle only */
++#define INPUT_PROP_TOPBUTTONPAD		0x04	/* softbuttons at top of pad */
++#define INPUT_PROP_POINTING_STICK	0x05	/* is a pointing stick */
++#define INPUT_PROP_ACCELEROMETER	0x06	/* has accelerometer */
++
++#define INPUT_PROP_MAX			0x1f
++#define INPUT_PROP_CNT			(INPUT_PROP_MAX + 1)
++
++/*
++ * Event types
++ */
++
++#define EV_SYN			0x00
++#define EV_KEY			0x01
++#define EV_REL			0x02
++#define EV_ABS			0x03
++#define EV_MSC			0x04
++#define EV_SW			0x05
++#define EV_LED			0x11
++#define EV_SND			0x12
++#define EV_REP			0x14
++#define EV_FF			0x15
++#define EV_PWR			0x16
++#define EV_FF_STATUS		0x17
++#define EV_MAX			0x1f
++#define EV_CNT			(EV_MAX+1)
++
++/*
++ * Synchronization events.
++ */
++
++#define SYN_REPORT		0
++#define SYN_CONFIG		1
++#define SYN_MT_REPORT		2
++#define SYN_DROPPED		3
++#define SYN_MAX			0xf
++#define SYN_CNT			(SYN_MAX+1)
++
++/*
++ * Keys and buttons
++ *
++ * Most of the keys/buttons are modeled after USB HUT 1.12
++ * (see http://www.usb.org/developers/hidpage).
++ * Abbreviations in the comments:
++ * AC - Application Control
++ * AL - Application Launch Button
++ * SC - System Control
++ */
++
++#define KEY_RESERVED		0
++#define KEY_ESC			1
++#define KEY_1			2
++#define KEY_2			3
++#define KEY_3			4
++#define KEY_4			5
++#define KEY_5			6
++#define KEY_6			7
++#define KEY_7			8
++#define KEY_8			9
++#define KEY_9			10
++#define KEY_0			11
++#define KEY_MINUS		12
++#define KEY_EQUAL		13
++#define KEY_BACKSPACE		14
++#define KEY_TAB			15
++#define KEY_Q			16
++#define KEY_W			17
++#define KEY_E			18
++#define KEY_R			19
++#define KEY_T			20
++#define KEY_Y			21
++#define KEY_U			22
++#define KEY_I			23
++#define KEY_O			24
++#define KEY_P			25
++#define KEY_LEFTBRACE		26
++#define KEY_RIGHTBRACE		27
++#define KEY_ENTER		28
++#define KEY_LEFTCTRL		29
++#define KEY_A			30
++#define KEY_S			31
++#define KEY_D			32
++#define KEY_F			33
++#define KEY_G			34
++#define KEY_H			35
++#define KEY_J			36
++#define KEY_K			37
++#define KEY_L			38
++#define KEY_SEMICOLON		39
++#define KEY_APOSTROPHE		40
++#define KEY_GRAVE		41
++#define KEY_LEFTSHIFT		42
++#define KEY_BACKSLASH		43
++#define KEY_Z			44
++#define KEY_X			45
++#define KEY_C			46
++#define KEY_V			47
++#define KEY_B			48
++#define KEY_N			49
++#define KEY_M			50
++#define KEY_COMMA		51
++#define KEY_DOT			52
++#define KEY_SLASH		53
++#define KEY_RIGHTSHIFT		54
++#define KEY_KPASTERISK		55
++#define KEY_LEFTALT		56
++#define KEY_SPACE		57
++#define KEY_CAPSLOCK		58
++#define KEY_F1			59
++#define KEY_F2			60
++#define KEY_F3			61
++#define KEY_F4			62
++#define KEY_F5			63
++#define KEY_F6			64
++#define KEY_F7			65
++#define KEY_F8			66
++#define KEY_F9			67
++#define KEY_F10			68
++#define KEY_NUMLOCK		69
++#define KEY_SCROLLLOCK		70
++#define KEY_KP7			71
++#define KEY_KP8			72
++#define KEY_KP9			73
++#define KEY_KPMINUS		74
++#define KEY_KP4			75
++#define KEY_KP5			76
++#define KEY_KP6			77
++#define KEY_KPPLUS		78
++#define KEY_KP1			79
++#define KEY_KP2			80
++#define KEY_KP3			81
++#define KEY_KP0			82
++#define KEY_KPDOT		83
++
++#define KEY_ZENKAKUHANKAKU	85
++#define KEY_102ND		86
++#define KEY_F11			87
++#define KEY_F12			88
++#define KEY_RO			89
++#define KEY_KATAKANA		90
++#define KEY_HIRAGANA		91
++#define KEY_HENKAN		92
++#define KEY_KATAKANAHIRAGANA	93
++#define KEY_MUHENKAN		94
++#define KEY_KPJPCOMMA		95
++#define KEY_KPENTER		96
++#define KEY_RIGHTCTRL		97
++#define KEY_KPSLASH		98
++#define KEY_SYSRQ		99
++#define KEY_RIGHTALT		100
++#define KEY_LINEFEED		101
++#define KEY_HOME		102
++#define KEY_UP			103
++#define KEY_PAGEUP		104
++#define KEY_LEFT		105
++#define KEY_RIGHT		106
++#define KEY_END			107
++#define KEY_DOWN		108
++#define KEY_PAGEDOWN		109
++#define KEY_INSERT		110
++#define KEY_DELETE		111
++#define KEY_MACRO		112
++#define KEY_MUTE		113
++#define KEY_VOLUMEDOWN		114
++#define KEY_VOLUMEUP		115
++#define KEY_POWER		116	/* SC System Power Down */
++#define KEY_KPEQUAL		117
++#define KEY_KPPLUSMINUS		118
++#define KEY_PAUSE		119
++#define KEY_SCALE		120	/* AL Compiz Scale (Expose) */
++
++#define KEY_KPCOMMA		121
++#define KEY_HANGEUL		122
++#define KEY_HANGUEL		KEY_HANGEUL
++#define KEY_HANJA		123
++#define KEY_YEN			124
++#define KEY_LEFTMETA		125
++#define KEY_RIGHTMETA		126
++#define KEY_COMPOSE		127
++
++#define KEY_STOP		128	/* AC Stop */
++#define KEY_AGAIN		129
++#define KEY_PROPS		130	/* AC Properties */
++#define KEY_UNDO		131	/* AC Undo */
++#define KEY_FRONT		132
++#define KEY_COPY		133	/* AC Copy */
++#define KEY_OPEN		134	/* AC Open */
++#define KEY_PASTE		135	/* AC Paste */
++#define KEY_FIND		136	/* AC Search */
++#define KEY_CUT			137	/* AC Cut */
++#define KEY_HELP		138	/* AL Integrated Help Center */
++#define KEY_MENU		139	/* Menu (show menu) */
++#define KEY_CALC		140	/* AL Calculator */
++#define KEY_SETUP		141
++#define KEY_SLEEP		142	/* SC System Sleep */
++#define KEY_WAKEUP		143	/* System Wake Up */
++#define KEY_FILE		144	/* AL Local Machine Browser */
++#define KEY_SENDFILE		145
++#define KEY_DELETEFILE		146
++#define KEY_XFER		147
++#define KEY_PROG1		148
++#define KEY_PROG2		149
++#define KEY_WWW			150	/* AL Internet Browser */
++#define KEY_MSDOS		151
++#define KEY_COFFEE		152	/* AL Terminal Lock/Screensaver */
++#define KEY_SCREENLOCK		KEY_COFFEE
++#define KEY_ROTATE_DISPLAY	153	/* Display orientation for e.g. tablets */
++#define KEY_DIRECTION		KEY_ROTATE_DISPLAY
++#define KEY_CYCLEWINDOWS	154
++#define KEY_MAIL		155
++#define KEY_BOOKMARKS		156	/* AC Bookmarks */
++#define KEY_COMPUTER		157
++#define KEY_BACK		158	/* AC Back */
++#define KEY_FORWARD		159	/* AC Forward */
++#define KEY_CLOSECD		160
++#define KEY_EJECTCD		161
++#define KEY_EJECTCLOSECD	162
++#define KEY_NEXTSONG		163
++#define KEY_PLAYPAUSE		164
++#define KEY_PREVIOUSSONG	165
++#define KEY_STOPCD		166
++#define KEY_RECORD		167
++#define KEY_REWIND		168
++#define KEY_PHONE		169	/* Media Select Telephone */
++#define KEY_ISO			170
++#define KEY_CONFIG		171	/* AL Consumer Control Configuration */
++#define KEY_HOMEPAGE		172	/* AC Home */
++#define KEY_REFRESH		173	/* AC Refresh */
++#define KEY_EXIT		174	/* AC Exit */
++#define KEY_MOVE		175
++#define KEY_EDIT		176
++#define KEY_SCROLLUP		177
++#define KEY_SCROLLDOWN		178
++#define KEY_KPLEFTPAREN		179
++#define KEY_KPRIGHTPAREN	180
++#define KEY_NEW			181	/* AC New */
++#define KEY_REDO		182	/* AC Redo/Repeat */
++
++#define KEY_F13			183
++#define KEY_F14			184
++#define KEY_F15			185
++#define KEY_F16			186
++#define KEY_F17			187
++#define KEY_F18			188
++#define KEY_F19			189
++#define KEY_F20			190
++#define KEY_F21			191
++#define KEY_F22			192
++#define KEY_F23			193
++#define KEY_F24			194
++
++#define KEY_PLAYCD		200
++#define KEY_PAUSECD		201
++#define KEY_PROG3		202
++#define KEY_PROG4		203
++#define KEY_DASHBOARD		204	/* AL Dashboard */
++#define KEY_SUSPEND		205
++#define KEY_CLOSE		206	/* AC Close */
++#define KEY_PLAY		207
++#define KEY_FASTFORWARD		208
++#define KEY_BASSBOOST		209
++#define KEY_PRINT		210	/* AC Print */
++#define KEY_HP			211
++#define KEY_CAMERA		212
++#define KEY_SOUND		213
++#define KEY_QUESTION		214
++#define KEY_EMAIL		215
++#define KEY_CHAT		216
++#define KEY_SEARCH		217
++#define KEY_CONNECT		218
++#define KEY_FINANCE		219	/* AL Checkbook/Finance */
++#define KEY_SPORT		220
++#define KEY_SHOP		221
++#define KEY_ALTERASE		222
++#define KEY_CANCEL		223	/* AC Cancel */
++#define KEY_BRIGHTNESSDOWN	224
++#define KEY_BRIGHTNESSUP	225
++#define KEY_MEDIA		226
++
++#define KEY_SWITCHVIDEOMODE	227	/* Cycle between available video
++					   outputs (Monitor/LCD/TV-out/etc) */
++#define KEY_KBDILLUMTOGGLE	228
++#define KEY_KBDILLUMDOWN	229
++#define KEY_KBDILLUMUP		230
++
++#define KEY_SEND		231	/* AC Send */
++#define KEY_REPLY		232	/* AC Reply */
++#define KEY_FORWARDMAIL		233	/* AC Forward Msg */
++#define KEY_SAVE		234	/* AC Save */
++#define KEY_DOCUMENTS		235
++
++#define KEY_BATTERY		236
++
++#define KEY_BLUETOOTH		237
++#define KEY_WLAN		238
++#define KEY_UWB			239
++
++#define KEY_UNKNOWN		240
++
++#define KEY_VIDEO_NEXT		241	/* drive next video source */
++#define KEY_VIDEO_PREV		242	/* drive previous video source */
++#define KEY_BRIGHTNESS_CYCLE	243	/* brightness up, after max is min */
++#define KEY_BRIGHTNESS_AUTO	244	/* Set Auto Brightness: manual
++					  brightness control is off,
++					  rely on ambient */
++#define KEY_BRIGHTNESS_ZERO	KEY_BRIGHTNESS_AUTO
++#define KEY_DISPLAY_OFF		245	/* display device to off state */
++
++#define KEY_WWAN		246	/* Wireless WAN (LTE, UMTS, GSM, etc.) */
++#define KEY_WIMAX		KEY_WWAN
++#define KEY_RFKILL		247	/* Key that controls all radios */
++
++#define KEY_MICMUTE		248	/* Mute / unmute the microphone */
++
++/* Code 255 is reserved for special needs of AT keyboard driver */
++
++#define BTN_MISC		0x100
++#define BTN_0			0x100
++#define BTN_1			0x101
++#define BTN_2			0x102
++#define BTN_3			0x103
++#define BTN_4			0x104
++#define BTN_5			0x105
++#define BTN_6			0x106
++#define BTN_7			0x107
++#define BTN_8			0x108
++#define BTN_9			0x109
++
++#define BTN_MOUSE		0x110
++#define BTN_LEFT		0x110
++#define BTN_RIGHT		0x111
++#define BTN_MIDDLE		0x112
++#define BTN_SIDE		0x113
++#define BTN_EXTRA		0x114
++#define BTN_FORWARD		0x115
++#define BTN_BACK		0x116
++#define BTN_TASK		0x117
++
++#define BTN_JOYSTICK		0x120
++#define BTN_TRIGGER		0x120
++#define BTN_THUMB		0x121
++#define BTN_THUMB2		0x122
++#define BTN_TOP			0x123
++#define BTN_TOP2		0x124
++#define BTN_PINKIE		0x125
++#define BTN_BASE		0x126
++#define BTN_BASE2		0x127
++#define BTN_BASE3		0x128
++#define BTN_BASE4		0x129
++#define BTN_BASE5		0x12a
++#define BTN_BASE6		0x12b
++#define BTN_DEAD		0x12f
++
++#define BTN_GAMEPAD		0x130
++#define BTN_SOUTH		0x130
++#define BTN_A			BTN_SOUTH
++#define BTN_EAST		0x131
++#define BTN_B			BTN_EAST
++#define BTN_C			0x132
++#define BTN_NORTH		0x133
++#define BTN_X			BTN_NORTH
++#define BTN_WEST		0x134
++#define BTN_Y			BTN_WEST
++#define BTN_Z			0x135
++#define BTN_TL			0x136
++#define BTN_TR			0x137
++#define BTN_TL2			0x138
++#define BTN_TR2			0x139
++#define BTN_SELECT		0x13a
++#define BTN_START		0x13b
++#define BTN_MODE		0x13c
++#define BTN_THUMBL		0x13d
++#define BTN_THUMBR		0x13e
++
++#define BTN_DIGI		0x140
++#define BTN_TOOL_PEN		0x140
++#define BTN_TOOL_RUBBER		0x141
++#define BTN_TOOL_BRUSH		0x142
++#define BTN_TOOL_PENCIL		0x143
++#define BTN_TOOL_AIRBRUSH	0x144
++#define BTN_TOOL_FINGER		0x145
++#define BTN_TOOL_MOUSE		0x146
++#define BTN_TOOL_LENS		0x147
++#define BTN_TOOL_QUINTTAP	0x148	/* Five fingers on trackpad */
++#define BTN_TOUCH		0x14a
++#define BTN_STYLUS		0x14b
++#define BTN_STYLUS2		0x14c
++#define BTN_TOOL_DOUBLETAP	0x14d
++#define BTN_TOOL_TRIPLETAP	0x14e
++#define BTN_TOOL_QUADTAP	0x14f	/* Four fingers on trackpad */
++
++#define BTN_WHEEL		0x150
++#define BTN_GEAR_DOWN		0x150
++#define BTN_GEAR_UP		0x151
++
++#define KEY_OK			0x160
++#define KEY_SELECT		0x161
++#define KEY_GOTO		0x162
++#define KEY_CLEAR		0x163
++#define KEY_POWER2		0x164
++#define KEY_OPTION		0x165
++#define KEY_INFO		0x166	/* AL OEM Features/Tips/Tutorial */
++#define KEY_TIME		0x167
++#define KEY_VENDOR		0x168
++#define KEY_ARCHIVE		0x169
++#define KEY_PROGRAM		0x16a	/* Media Select Program Guide */
++#define KEY_CHANNEL		0x16b
++#define KEY_FAVORITES		0x16c
++#define KEY_EPG			0x16d
++#define KEY_PVR			0x16e	/* Media Select Home */
++#define KEY_MHP			0x16f
++#define KEY_LANGUAGE		0x170
++#define KEY_TITLE		0x171
++#define KEY_SUBTITLE		0x172
++#define KEY_ANGLE		0x173
++#define KEY_ZOOM		0x174
++#define KEY_MODE		0x175
++#define KEY_KEYBOARD		0x176
++#define KEY_SCREEN		0x177
++#define KEY_PC			0x178	/* Media Select Computer */
++#define KEY_TV			0x179	/* Media Select TV */
++#define KEY_TV2			0x17a	/* Media Select Cable */
++#define KEY_VCR			0x17b	/* Media Select VCR */
++#define KEY_VCR2		0x17c	/* VCR Plus */
++#define KEY_SAT			0x17d	/* Media Select Satellite */
++#define KEY_SAT2		0x17e
++#define KEY_CD			0x17f	/* Media Select CD */
++#define KEY_TAPE		0x180	/* Media Select Tape */
++#define KEY_RADIO		0x181
++#define KEY_TUNER		0x182	/* Media Select Tuner */
++#define KEY_PLAYER		0x183
++#define KEY_TEXT		0x184
++#define KEY_DVD			0x185	/* Media Select DVD */
++#define KEY_AUX			0x186
++#define KEY_MP3			0x187
++#define KEY_AUDIO		0x188	/* AL Audio Browser */
++#define KEY_VIDEO		0x189	/* AL Movie Browser */
++#define KEY_DIRECTORY		0x18a
++#define KEY_LIST		0x18b
++#define KEY_MEMO		0x18c	/* Media Select Messages */
++#define KEY_CALENDAR		0x18d
++#define KEY_RED			0x18e
++#define KEY_GREEN		0x18f
++#define KEY_YELLOW		0x190
++#define KEY_BLUE		0x191
++#define KEY_CHANNELUP		0x192	/* Channel Increment */
++#define KEY_CHANNELDOWN		0x193	/* Channel Decrement */
++#define KEY_FIRST		0x194
++#define KEY_LAST		0x195	/* Recall Last */
++#define KEY_AB			0x196
++#define KEY_NEXT		0x197
++#define KEY_RESTART		0x198
++#define KEY_SLOW		0x199
++#define KEY_SHUFFLE		0x19a
++#define KEY_BREAK		0x19b
++#define KEY_PREVIOUS		0x19c
++#define KEY_DIGITS		0x19d
++#define KEY_TEEN		0x19e
++#define KEY_TWEN		0x19f
++#define KEY_VIDEOPHONE		0x1a0	/* Media Select Video Phone */
++#define KEY_GAMES		0x1a1	/* Media Select Games */
++#define KEY_ZOOMIN		0x1a2	/* AC Zoom In */
++#define KEY_ZOOMOUT		0x1a3	/* AC Zoom Out */
++#define KEY_ZOOMRESET		0x1a4	/* AC Zoom */
++#define KEY_WORDPROCESSOR	0x1a5	/* AL Word Processor */
++#define KEY_EDITOR		0x1a6	/* AL Text Editor */
++#define KEY_SPREADSHEET		0x1a7	/* AL Spreadsheet */
++#define KEY_GRAPHICSEDITOR	0x1a8	/* AL Graphics Editor */
++#define KEY_PRESENTATION	0x1a9	/* AL Presentation App */
++#define KEY_DATABASE		0x1aa	/* AL Database App */
++#define KEY_NEWS		0x1ab	/* AL Newsreader */
++#define KEY_VOICEMAIL		0x1ac	/* AL Voicemail */
++#define KEY_ADDRESSBOOK		0x1ad	/* AL Contacts/Address Book */
++#define KEY_MESSENGER		0x1ae	/* AL Instant Messaging */
++#define KEY_DISPLAYTOGGLE	0x1af	/* Turn display (LCD) on and off */
++#define KEY_BRIGHTNESS_TOGGLE	KEY_DISPLAYTOGGLE
++#define KEY_SPELLCHECK		0x1b0   /* AL Spell Check */
++#define KEY_LOGOFF		0x1b1   /* AL Logoff */
++
++#define KEY_DOLLAR		0x1b2
++#define KEY_EURO		0x1b3
++
++#define KEY_FRAMEBACK		0x1b4	/* Consumer - transport controls */
++#define KEY_FRAMEFORWARD	0x1b5
++#define KEY_CONTEXT_MENU	0x1b6	/* GenDesc - system context menu */
++#define KEY_MEDIA_REPEAT	0x1b7	/* Consumer - transport control */
++#define KEY_10CHANNELSUP	0x1b8	/* 10 channels up (10+) */
++#define KEY_10CHANNELSDOWN	0x1b9	/* 10 channels down (10-) */
++#define KEY_IMAGES		0x1ba	/* AL Image Browser */
++
++#define KEY_DEL_EOL		0x1c0
++#define KEY_DEL_EOS		0x1c1
++#define KEY_INS_LINE		0x1c2
++#define KEY_DEL_LINE		0x1c3
++
++#define KEY_FN			0x1d0
++#define KEY_FN_ESC		0x1d1
++#define KEY_FN_F1		0x1d2
++#define KEY_FN_F2		0x1d3
++#define KEY_FN_F3		0x1d4
++#define KEY_FN_F4		0x1d5
++#define KEY_FN_F5		0x1d6
++#define KEY_FN_F6		0x1d7
++#define KEY_FN_F7		0x1d8
++#define KEY_FN_F8		0x1d9
++#define KEY_FN_F9		0x1da
++#define KEY_FN_F10		0x1db
++#define KEY_FN_F11		0x1dc
++#define KEY_FN_F12		0x1dd
++#define KEY_FN_1		0x1de
++#define KEY_FN_2		0x1df
++#define KEY_FN_D		0x1e0
++#define KEY_FN_E		0x1e1
++#define KEY_FN_F		0x1e2
++#define KEY_FN_S		0x1e3
++#define KEY_FN_B		0x1e4
++
++#define KEY_BRL_DOT1		0x1f1
++#define KEY_BRL_DOT2		0x1f2
++#define KEY_BRL_DOT3		0x1f3
++#define KEY_BRL_DOT4		0x1f4
++#define KEY_BRL_DOT5		0x1f5
++#define KEY_BRL_DOT6		0x1f6
++#define KEY_BRL_DOT7		0x1f7
++#define KEY_BRL_DOT8		0x1f8
++#define KEY_BRL_DOT9		0x1f9
++#define KEY_BRL_DOT10		0x1fa
++
++#define KEY_NUMERIC_0		0x200	/* used by phones, remote controls, */
++#define KEY_NUMERIC_1		0x201	/* and other keypads */
++#define KEY_NUMERIC_2		0x202
++#define KEY_NUMERIC_3		0x203
++#define KEY_NUMERIC_4		0x204
++#define KEY_NUMERIC_5		0x205
++#define KEY_NUMERIC_6		0x206
++#define KEY_NUMERIC_7		0x207
++#define KEY_NUMERIC_8		0x208
++#define KEY_NUMERIC_9		0x209
++#define KEY_NUMERIC_STAR	0x20a
++#define KEY_NUMERIC_POUND	0x20b
++#define KEY_NUMERIC_A		0x20c	/* Phone key A - HUT Telephony 0xb9 */
++#define KEY_NUMERIC_B		0x20d
++#define KEY_NUMERIC_C		0x20e
++#define KEY_NUMERIC_D		0x20f
++
++#define KEY_CAMERA_FOCUS	0x210
++#define KEY_WPS_BUTTON		0x211	/* WiFi Protected Setup key */
++
++#define KEY_TOUCHPAD_TOGGLE	0x212	/* Request switch touchpad on or off */
++#define KEY_TOUCHPAD_ON		0x213
++#define KEY_TOUCHPAD_OFF	0x214
++
++#define KEY_CAMERA_ZOOMIN	0x215
++#define KEY_CAMERA_ZOOMOUT	0x216
++#define KEY_CAMERA_UP		0x217
++#define KEY_CAMERA_DOWN		0x218
++#define KEY_CAMERA_LEFT		0x219
++#define KEY_CAMERA_RIGHT	0x21a
++
++#define KEY_ATTENDANT_ON	0x21b
++#define KEY_ATTENDANT_OFF	0x21c
++#define KEY_ATTENDANT_TOGGLE	0x21d	/* Attendant call on or off */
++#define KEY_LIGHTS_TOGGLE	0x21e	/* Reading light on or off */
++
++#define BTN_DPAD_UP		0x220
++#define BTN_DPAD_DOWN		0x221
++#define BTN_DPAD_LEFT		0x222
++#define BTN_DPAD_RIGHT		0x223
++
++#define KEY_ALS_TOGGLE		0x230	/* Ambient light sensor */
++
++#define KEY_BUTTONCONFIG		0x240	/* AL Button Configuration */
++#define KEY_TASKMANAGER		0x241	/* AL Task/Project Manager */
++#define KEY_JOURNAL		0x242	/* AL Log/Journal/Timecard */
++#define KEY_CONTROLPANEL		0x243	/* AL Control Panel */
++#define KEY_APPSELECT		0x244	/* AL Select Task/Application */
++#define KEY_SCREENSAVER		0x245	/* AL Screen Saver */
++#define KEY_VOICECOMMAND		0x246	/* Listening Voice Command */
++
++#define KEY_BRIGHTNESS_MIN		0x250	/* Set Brightness to Minimum */
++#define KEY_BRIGHTNESS_MAX		0x251	/* Set Brightness to Maximum */
++
++#define KEY_KBDINPUTASSIST_PREV		0x260
++#define KEY_KBDINPUTASSIST_NEXT		0x261
++#define KEY_KBDINPUTASSIST_PREVGROUP		0x262
++#define KEY_KBDINPUTASSIST_NEXTGROUP		0x263
++#define KEY_KBDINPUTASSIST_ACCEPT		0x264
++#define KEY_KBDINPUTASSIST_CANCEL		0x265
++
++/* Diagonal movement keys */
++#define KEY_RIGHT_UP			0x266
++#define KEY_RIGHT_DOWN			0x267
++#define KEY_LEFT_UP			0x268
++#define KEY_LEFT_DOWN			0x269
++
++#define KEY_ROOT_MENU			0x26a /* Show Device's Root Menu */
++/* Show Top Menu of the Media (e.g. DVD) */
++#define KEY_MEDIA_TOP_MENU		0x26b
++#define KEY_NUMERIC_11			0x26c
++#define KEY_NUMERIC_12			0x26d
++/*
++ * Toggle Audio Description: refers to an audio service that helps blind and
++ * visually impaired consumers understand the action in a program. Note: in
++ * some countries this is referred to as "Video Description".
++ */
++#define KEY_AUDIO_DESC			0x26e
++#define KEY_3D_MODE			0x26f
++#define KEY_NEXT_FAVORITE		0x270
++#define KEY_STOP_RECORD			0x271
++#define KEY_PAUSE_RECORD		0x272
++#define KEY_VOD				0x273 /* Video on Demand */
++#define KEY_UNMUTE			0x274
++#define KEY_FASTREVERSE			0x275
++#define KEY_SLOWREVERSE			0x276
++/*
++ * Control a data application associated with the currently viewed channel,
++ * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
++ */
++#define KEY_DATA			0x277
++#define KEY_ONSCREEN_KEYBOARD		0x278
++
++#define BTN_TRIGGER_HAPPY		0x2c0
++#define BTN_TRIGGER_HAPPY1		0x2c0
++#define BTN_TRIGGER_HAPPY2		0x2c1
++#define BTN_TRIGGER_HAPPY3		0x2c2
++#define BTN_TRIGGER_HAPPY4		0x2c3
++#define BTN_TRIGGER_HAPPY5		0x2c4
++#define BTN_TRIGGER_HAPPY6		0x2c5
++#define BTN_TRIGGER_HAPPY7		0x2c6
++#define BTN_TRIGGER_HAPPY8		0x2c7
++#define BTN_TRIGGER_HAPPY9		0x2c8
++#define BTN_TRIGGER_HAPPY10		0x2c9
++#define BTN_TRIGGER_HAPPY11		0x2ca
++#define BTN_TRIGGER_HAPPY12		0x2cb
++#define BTN_TRIGGER_HAPPY13		0x2cc
++#define BTN_TRIGGER_HAPPY14		0x2cd
++#define BTN_TRIGGER_HAPPY15		0x2ce
++#define BTN_TRIGGER_HAPPY16		0x2cf
++#define BTN_TRIGGER_HAPPY17		0x2d0
++#define BTN_TRIGGER_HAPPY18		0x2d1
++#define BTN_TRIGGER_HAPPY19		0x2d2
++#define BTN_TRIGGER_HAPPY20		0x2d3
++#define BTN_TRIGGER_HAPPY21		0x2d4
++#define BTN_TRIGGER_HAPPY22		0x2d5
++#define BTN_TRIGGER_HAPPY23		0x2d6
++#define BTN_TRIGGER_HAPPY24		0x2d7
++#define BTN_TRIGGER_HAPPY25		0x2d8
++#define BTN_TRIGGER_HAPPY26		0x2d9
++#define BTN_TRIGGER_HAPPY27		0x2da
++#define BTN_TRIGGER_HAPPY28		0x2db
++#define BTN_TRIGGER_HAPPY29		0x2dc
++#define BTN_TRIGGER_HAPPY30		0x2dd
++#define BTN_TRIGGER_HAPPY31		0x2de
++#define BTN_TRIGGER_HAPPY32		0x2df
++#define BTN_TRIGGER_HAPPY33		0x2e0
++#define BTN_TRIGGER_HAPPY34		0x2e1
++#define BTN_TRIGGER_HAPPY35		0x2e2
++#define BTN_TRIGGER_HAPPY36		0x2e3
++#define BTN_TRIGGER_HAPPY37		0x2e4
++#define BTN_TRIGGER_HAPPY38		0x2e5
++#define BTN_TRIGGER_HAPPY39		0x2e6
++#define BTN_TRIGGER_HAPPY40		0x2e7
++
++/* We avoid low common keys in module aliases so they don't get huge. */
++#define KEY_MIN_INTERESTING	KEY_MUTE
++#define KEY_MAX			0x2ff
++#define KEY_CNT			(KEY_MAX+1)
++
++/*
++ * Relative axes
++ */
++
++#define REL_X			0x00
++#define REL_Y			0x01
++#define REL_Z			0x02
++#define REL_RX			0x03
++#define REL_RY			0x04
++#define REL_RZ			0x05
++#define REL_HWHEEL		0x06
++#define REL_DIAL		0x07
++#define REL_WHEEL		0x08
++#define REL_MISC		0x09
++#define REL_MAX			0x0f
++#define REL_CNT			(REL_MAX+1)
++
++/*
++ * Absolute axes
++ */
++
++#define ABS_X			0x00
++#define ABS_Y			0x01
++#define ABS_Z			0x02
++#define ABS_RX			0x03
++#define ABS_RY			0x04
++#define ABS_RZ			0x05
++#define ABS_THROTTLE		0x06
++#define ABS_RUDDER		0x07
++#define ABS_WHEEL		0x08
++#define ABS_GAS			0x09
++#define ABS_BRAKE		0x0a
++#define ABS_HAT0X		0x10
++#define ABS_HAT0Y		0x11
++#define ABS_HAT1X		0x12
++#define ABS_HAT1Y		0x13
++#define ABS_HAT2X		0x14
++#define ABS_HAT2Y		0x15
++#define ABS_HAT3X		0x16
++#define ABS_HAT3Y		0x17
++#define ABS_PRESSURE		0x18
++#define ABS_DISTANCE		0x19
++#define ABS_TILT_X		0x1a
++#define ABS_TILT_Y		0x1b
++#define ABS_TOOL_WIDTH		0x1c
++
++#define ABS_VOLUME		0x20
++
++#define ABS_MISC		0x28
++
++#define ABS_MT_SLOT		0x2f	/* MT slot being modified */
++#define ABS_MT_TOUCH_MAJOR	0x30	/* Major axis of touching ellipse */
++#define ABS_MT_TOUCH_MINOR	0x31	/* Minor axis (omit if circular) */
++#define ABS_MT_WIDTH_MAJOR	0x32	/* Major axis of approaching ellipse */
++#define ABS_MT_WIDTH_MINOR	0x33	/* Minor axis (omit if circular) */
++#define ABS_MT_ORIENTATION	0x34	/* Ellipse orientation */
++#define ABS_MT_POSITION_X	0x35	/* Center X touch position */
++#define ABS_MT_POSITION_Y	0x36	/* Center Y touch position */
++#define ABS_MT_TOOL_TYPE	0x37	/* Type of touching device */
++#define ABS_MT_BLOB_ID		0x38	/* Group a set of packets as a blob */
++#define ABS_MT_TRACKING_ID	0x39	/* Unique ID of initiated contact */
++#define ABS_MT_PRESSURE		0x3a	/* Pressure on contact area */
++#define ABS_MT_DISTANCE		0x3b	/* Contact hover distance */
++#define ABS_MT_TOOL_X		0x3c	/* Center X tool position */
++#define ABS_MT_TOOL_Y		0x3d	/* Center Y tool position */
++
++
++#define ABS_MAX			0x3f
++#define ABS_CNT			(ABS_MAX+1)
++
++/*
++ * Switch events
++ */
++
++#define SW_LID			0x00  /* set = lid shut */
++#define SW_TABLET_MODE		0x01  /* set = tablet mode */
++#define SW_HEADPHONE_INSERT	0x02  /* set = inserted */
++#define SW_RFKILL_ALL		0x03  /* rfkill master switch, type "any"
++					 set = radio enabled */
++#define SW_RADIO		SW_RFKILL_ALL	/* deprecated */
++#define SW_MICROPHONE_INSERT	0x04  /* set = inserted */
++#define SW_DOCK			0x05  /* set = plugged into dock */
++#define SW_LINEOUT_INSERT	0x06  /* set = inserted */
++#define SW_JACK_PHYSICAL_INSERT 0x07  /* set = mechanical switch set */
++#define SW_VIDEOOUT_INSERT	0x08  /* set = inserted */
++#define SW_CAMERA_LENS_COVER	0x09  /* set = lens covered */
++#define SW_KEYPAD_SLIDE		0x0a  /* set = keypad slide out */
++#define SW_FRONT_PROXIMITY	0x0b  /* set = front proximity sensor active */
++#define SW_ROTATE_LOCK		0x0c  /* set = rotate locked/disabled */
++#define SW_LINEIN_INSERT	0x0d  /* set = inserted */
++#define SW_MUTE_DEVICE		0x0e  /* set = device disabled */
++#define SW_PEN_INSERTED		0x0f  /* set = pen inserted */
++#define SW_MAX			0x0f
++#define SW_CNT			(SW_MAX+1)
++
++/*
++ * Misc events
++ */
++
++#define MSC_SERIAL		0x00
++#define MSC_PULSELED		0x01
++#define MSC_GESTURE		0x02
++#define MSC_RAW			0x03
++#define MSC_SCAN		0x04
++#define MSC_TIMESTAMP		0x05
++#define MSC_MAX			0x07
++#define MSC_CNT			(MSC_MAX+1)
++
++/*
++ * LEDs
++ */
++
++#define LED_NUML		0x00
++#define LED_CAPSL		0x01
++#define LED_SCROLLL		0x02
++#define LED_COMPOSE		0x03
++#define LED_KANA		0x04
++#define LED_SLEEP		0x05
++#define LED_SUSPEND		0x06
++#define LED_MUTE		0x07
++#define LED_MISC		0x08
++#define LED_MAIL		0x09
++#define LED_CHARGING		0x0a
++#define LED_MAX			0x0f
++#define LED_CNT			(LED_MAX+1)
++
++/*
++ * Autorepeat values
++ */
++
++#define REP_DELAY		0x00
++#define REP_PERIOD		0x01
++#define REP_MAX			0x01
++#define REP_CNT			(REP_MAX+1)
++
++/*
++ * Sounds
++ */
++
++#define SND_CLICK		0x00
++#define SND_BELL		0x01
++#define SND_TONE		0x02
++#define SND_MAX			0x07
++#define SND_CNT			(SND_MAX+1)
++
++#endif
+diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c
+index 8a62bb3..8a5ff5b 100644
+--- a/src/backends/native/meta-input-settings-native.c
++++ b/src/backends/native/meta-input-settings-native.c
+@@ -24,7 +24,7 @@
+ #include "config.h"
+ 
+ #include <clutter/evdev/clutter-evdev.h>
+-#include <linux/input-event-codes.h>
++#include <clutter/evdev/linux/input-event-codes.h>
+ #include <libinput.h>
+ 
+ #include "meta-backend-native.h"
+diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c
+index 4b57d41..5675f48 100644
+--- a/src/wayland/meta-wayland-tablet-tool.c
++++ b/src/wayland/meta-wayland-tablet-tool.c
+@@ -41,7 +41,7 @@
+ 
+ #ifdef HAVE_NATIVE_BACKEND
+ #include "backends/native/meta-backend-native.h"
+-#include <linux/input-event-codes.h>
++#include <clutter/evdev/linux/input-event-codes.h>
+ #endif
+ 
+ #define TABLET_AXIS_MAX 65535
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0001-screen-Remove-stray-assert.patch b/SOURCES/0001-screen-Remove-stray-assert.patch
deleted file mode 100644
index 221f9ef..0000000
--- a/SOURCES/0001-screen-Remove-stray-assert.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From fd41db64169f6e0b36d56e054967cb406e32fa74 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
-Date: Mon, 26 Jun 2017 17:56:36 +0200
-Subject: [PATCH] screen: Remove stray assert
-
-When the number of (static) workspaces decreases, we relocate windows
-from extra workspaces before removing them. As removing a non-empty
-workspace is not allowed, we assert that it doesn't contain any windows
-before removing it.
-
-However that assert is
-
- - pointless, because meta_workspace_remove() already asserts that
-   the workspace is empty
-
- - wrong, because even empty workspaces contain windows that are set
-   to show on all workspaces
-
-Simply drop the assert to avoid a crash when trying to remove a workspace
-while on-all-workspaces windows are present.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=784223
----
- src/core/screen.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/src/core/screen.c b/src/core/screen.c
-index d6b5eac53..c6aa9e194 100644
---- a/src/core/screen.c
-+++ b/src/core/screen.c
-@@ -1260,7 +1260,6 @@ update_num_workspaces (MetaScreen *screen,
-     {
-       MetaWorkspace *w = l->data;
- 
--      g_assert (w->windows == NULL);
-       meta_workspace_remove (w);
-     }
- 
--- 
-2.13.0
-
diff --git a/SOURCES/0001-stack-tracker-Keep-override-redirect-windows-on-top.patch b/SOURCES/0001-stack-tracker-Keep-override-redirect-windows-on-top.patch
deleted file mode 100644
index 3ee1d5d..0000000
--- a/SOURCES/0001-stack-tracker-Keep-override-redirect-windows-on-top.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 245a3c2e12b4aad2e752675f82be9517235d5498 Mon Sep 17 00:00:00 2001
-From: Rui Matos <tiagomatos@gmail.com>
-Date: Fri, 19 May 2017 17:11:19 +0200
-Subject: [PATCH] stack-tracker: Keep override redirect windows on top
-
-Since commit 6b5cf2e, we keep override redirect windows on a layer
-above regular windows in the clutter actor scene graph. In the X
-server, and thus for input purposes, these windows might end up being
-stacked below regular windows though, e.g. because a new regular
-window is mapped after an OR window.
-
-Fix this disconnect by re-stacking OR windows on top when syncing the
-window stack with the compositor.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=780485
----
- src/core/stack-tracker.c | 36 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 36 insertions(+)
-
-diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c
-index a76b42cbf..82afd644a 100644
---- a/src/core/stack-tracker.c
-+++ b/src/core/stack-tracker.c
-@@ -168,6 +168,9 @@ struct _MetaStackTracker
-   guint sync_stack_later;
- };
- 
-+static void
-+meta_stack_tracker_keep_override_redirect_on_top (MetaStackTracker *tracker);
-+
- static inline const char *
- get_window_desc (MetaStackTracker *tracker,
-                  guint64           window)
-@@ -835,6 +838,8 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
-       tracker->sync_stack_later = 0;
-     }
- 
-+  meta_stack_tracker_keep_override_redirect_on_top (tracker);
-+
-   meta_stack_tracker_get_stack (tracker, &windows, &n_windows);
- 
-   meta_windows = NULL;
-@@ -1040,6 +1045,37 @@ meta_stack_tracker_lower (MetaStackTracker *tracker,
-   meta_stack_tracker_raise_above (tracker, window, None);
- }
- 
-+static void
-+meta_stack_tracker_keep_override_redirect_on_top (MetaStackTracker *tracker)
-+{
-+  MetaWindow *window;
-+  guint64 *stack;
-+  int n_windows, i;
-+  int topmost_non_or;
-+
-+  meta_stack_tracker_get_stack (tracker, &stack, &n_windows);
-+
-+  for (i = n_windows - 1; i >= 0; i--)
-+    {
-+      window = meta_display_lookup_stack_id (tracker->screen->display, stack[i]);
-+      if (window && window->layer != META_LAYER_OVERRIDE_REDIRECT)
-+        break;
-+    }
-+
-+  topmost_non_or = i;
-+
-+  for (i -= 1; i >= 0; i--)
-+    {
-+      window = meta_display_lookup_stack_id (tracker->screen->display, stack[i]);
-+      if (window && window->layer == META_LAYER_OVERRIDE_REDIRECT)
-+        {
-+          meta_stack_tracker_raise_above (tracker, stack[i], stack[topmost_non_or]);
-+          meta_stack_tracker_get_stack (tracker, &stack, &n_windows);
-+          topmost_non_or -= 1;
-+        }
-+    }
-+}
-+
- void
- meta_stack_tracker_restack_managed (MetaStackTracker *tracker,
-                                     const guint64    *managed,
--- 
-2.13.0
-
diff --git a/SOURCES/0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch b/SOURCES/0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch
new file mode 100644
index 0000000..d90a588
--- /dev/null
+++ b/SOURCES/0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch
@@ -0,0 +1,37 @@
+From 9826eae9f091d461bd117c254ba8e255dd084797 Mon Sep 17 00:00:00 2001
+From: Olivier Fourdan <ofourdan@redhat.com>
+Date: Fri, 2 Feb 2018 16:35:26 +0100
+Subject: [PATCH] wayland: Do not fail on stalled .X11-unix entries
+
+If for whatever reason, there are stalled files in /tmp/.X11-unix/ the
+bind() to the abstract socket will succeed but not the bind() to the
+to the UNIX socket.
+
+This causes gnome-shell/mutter to fail because it cannot start Xwayland
+(while it could actually, by using a different display).
+
+In case of failure to bind to the UNIX socket, try the next display
+instead of failing, to avoid stalled entries in /tmp/.X11-unix.
+
+Closes: https://gitlab.gnome.org/GNOME/mutter/issues/13
+---
+ src/wayland/meta-xwayland.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
+index 50cfc7c57..ce21fe5ee 100644
+--- a/src/wayland/meta-xwayland.c
++++ b/src/wayland/meta-xwayland.c
+@@ -458,7 +458,8 @@ choose_xdisplay (MetaXWaylandManager *manager)
+         {
+           unlink (lock_file);
+           close (manager->abstract_fd);
+-          return FALSE;
++          display++;
++          continue;
+         }
+ 
+       break;
+-- 
+2.14.3
+
diff --git a/SOURCES/0001-wayland-enable-scale-monitor-framebuffer-by-default.patch b/SOURCES/0001-wayland-enable-scale-monitor-framebuffer-by-default.patch
new file mode 100644
index 0000000..46c940b
--- /dev/null
+++ b/SOURCES/0001-wayland-enable-scale-monitor-framebuffer-by-default.patch
@@ -0,0 +1,25 @@
+From 85968e1d0996b7f3a7453076c88ed6d5e0113369 Mon Sep 17 00:00:00 2001
+From: Olivier Fourdan <ofourdan@redhat.com>
+Date: Wed, 20 Sep 2017 12:17:23 +0200
+Subject: [PATCH] wayland: enable scale-monitor-framebuffer by default
+
+---
+ data/org.gnome.mutter.gschema.xml.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in
+index d926312c8..bec5585bd 100644
+--- a/data/org.gnome.mutter.gschema.xml.in
++++ b/data/org.gnome.mutter.gschema.xml.in
+@@ -103,7 +103,7 @@
+     </key>
+ 
+     <key name="experimental-features" type="as">
+-      <default>[]</default>
++      <default>['scale-monitor-framebuffer']</default>
+       <summary>Enable experimental features</summary>
+       <description>
+         To enable experimental features, add the feature keyword to the list.
+-- 
+2.13.5
+
diff --git a/SOURCES/0001-wayland-xdg-shell-Handle-the-wl_output-on-the-set_fu.patch b/SOURCES/0001-wayland-xdg-shell-Handle-the-wl_output-on-the-set_fu.patch
deleted file mode 100644
index 5ef1077..0000000
--- a/SOURCES/0001-wayland-xdg-shell-Handle-the-wl_output-on-the-set_fu.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 4ee272a5a88351a03619deae4e5dd4ab16f32b07 Mon Sep 17 00:00:00 2001
-From: Rui Matos <tiagomatos@gmail.com>
-Date: Wed, 2 Nov 2016 17:55:01 +0100
-Subject: [PATCH] wayland-xdg-shell: Handle the wl_output on the set_fullscreen
- request
-
-This makes us fullscreen wayland windows on the requested monitor.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=772525
----
- src/wayland/meta-wayland-xdg-shell.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c
-index 450acda..e1195c7 100644
---- a/src/wayland/meta-wayland-xdg-shell.c
-+++ b/src/wayland/meta-wayland-xdg-shell.c
-@@ -27,6 +27,7 @@
- 
- #include "core/window-private.h"
- #include "wayland/meta-wayland.h"
-+#include "wayland/meta-wayland-outputs.h"
- #include "wayland/meta-wayland-popup.h"
- #include "wayland/meta-wayland-private.h"
- #include "wayland/meta-wayland-seat.h"
-@@ -363,6 +364,13 @@ xdg_toplevel_set_fullscreen (struct wl_client   *client,
- {
-   MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
- 
-+  if (output_resource)
-+    {
-+      MetaWaylandOutput *output = wl_resource_get_user_data (output_resource);
-+      if (output)
-+        meta_window_move_to_monitor (surface->window, output->monitor_info->number);
-+    }
-+
-   meta_window_make_fullscreen (surface->window);
- }
- 
--- 
-2.9.3
-
diff --git a/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch b/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch
index fad3a5f..f20fc6c 100644
--- a/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch
+++ b/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch
@@ -1,7 +1,7 @@
-From 4cd334074a411f1bdc018f74ef51e9ac8dea9fa0 Mon Sep 17 00:00:00 2001
+From 97f5f9bdc1c5cb1a2e02ec04750b5db9a4b4fdf1 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
 Date: Fri, 12 May 2017 13:40:31 +0200
-Subject: [PATCH] window-actor: Special-case shaped Java windows
+Subject: [PATCH 8/8] window-actor: Special-case shaped Java windows
 
 OpenJDK wrongly assumes that shaping a window implies no shadows.
 They got lucky until commit b975676c changed the fallback case,
@@ -12,13 +12,14 @@ by special-casing shaped Java windows.
  1 file changed, 8 insertions(+)
 
 diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
-index 7595adb66..8768b477c 100644
+index 773e6d09d..ac072997c 100644
 --- a/src/compositor/meta-window-actor.c
 +++ b/src/compositor/meta-window-actor.c
-@@ -842,6 +842,14 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
+@@ -843,6 +843,14 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
+   if (priv->window->has_custom_frame_extents)
      return FALSE;
  
-   /*
++  /*
 +   * OpenJDK wrongly assumes that shaping a window implies no compositor
 +   * shadows; make its compliance tests happy to give it what it wants ...
 +   */
@@ -26,10 +27,9 @@ index 7595adb66..8768b477c 100644
 +      priv->window->shape_region != NULL)
 +    return FALSE;
 +
-+  /*
+   /*
     * Generate shadows for all other windows.
     */
-   return TRUE;
 -- 
-2.12.2
+2.14.2
 
diff --git a/SOURCES/0003-window-wayland-Handle-resizing-when-headless.patch b/SOURCES/0003-window-wayland-Handle-resizing-when-headless.patch
new file mode 100644
index 0000000..32756c0
--- /dev/null
+++ b/SOURCES/0003-window-wayland-Handle-resizing-when-headless.patch
@@ -0,0 +1,50 @@
+From 07e5f7ef29b5567e090221d5da9415e8b84c0ebb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
+Date: Mon, 16 Oct 2017 17:02:51 +0800
+Subject: [PATCH 3/4] window/wayland: Handle resizing when headless
+
+We tried to get the geometry scale, which may depend on the main
+logical monitor assigned to the window. To avoid dereferencing a NULL
+logical monitor when headless, instead assume the geometry scale is 1.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=788764
+---
+ src/wayland/meta-window-wayland.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c
+index ed6e34b43..f3f0e1688 100644
+--- a/src/wayland/meta-window-wayland.c
++++ b/src/wayland/meta-window-wayland.c
+@@ -67,6 +67,8 @@ G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW)
+ static int
+ get_window_geometry_scale_for_logical_monitor (MetaLogicalMonitor *logical_monitor)
+ {
++  g_assert (logical_monitor);
++
+   if (meta_is_stage_views_scaled ())
+     return 1;
+   else
+@@ -79,8 +81,7 @@ meta_window_wayland_manage (MetaWindow *window)
+   MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
+   MetaDisplay *display = window->display;
+ 
+-  wl_window->geometry_scale =
+-    get_window_geometry_scale_for_logical_monitor (window->monitor);
++  wl_window->geometry_scale = meta_window_wayland_get_geometry_scale (window);
+ 
+   meta_display_register_wayland_window (display, window);
+ 
+@@ -634,6 +635,9 @@ should_do_pending_move (MetaWindowWayland *wl_window,
+ int
+ meta_window_wayland_get_geometry_scale (MetaWindow *window)
+ {
++  if (!window->monitor)
++    return 1;
++
+   return get_window_geometry_scale_for_logical_monitor (window->monitor);
+ }
+ 
+-- 
+2.14.2
+
diff --git a/SOURCES/0008-Add-support-for-quad-buffer-stereo.patch b/SOURCES/0008-Add-support-for-quad-buffer-stereo.patch
index 1a44410..82fe332 100644
--- a/SOURCES/0008-Add-support-for-quad-buffer-stereo.patch
+++ b/SOURCES/0008-Add-support-for-quad-buffer-stereo.patch
@@ -1,7 +1,7 @@
-From 1292ea32ce34e804b709af0cdbc9fda87d142e9b Mon Sep 17 00:00:00 2001
+From 7940ea62307044c056c16f1534e3e8e94cc7a352 Mon Sep 17 00:00:00 2001
 From: "Owen W. Taylor" <otaylor@fishsoup.net>
 Date: Thu, 8 May 2014 18:44:15 -0400
-Subject: [PATCH 8/8] Add support for quad-buffer stereo
+Subject: [PATCH 7/8] Add support for quad-buffer stereo
 
 Track the stereo status of windows using the new EXT_stereo_tree
 GLX extension.
@@ -23,7 +23,7 @@ texture_from_pixmap.
  src/compositor/compositor.c                  | 128 ++++++++++++++++++++++
  src/compositor/meta-shaped-texture-private.h |   5 +-
  src/compositor/meta-shaped-texture.c         | 157 ++++++++++++++++++++-------
- src/compositor/meta-surface-actor-wayland.c  |   2 +-
+ src/compositor/meta-surface-actor-wayland.c  |  10 +-
  src/compositor/meta-surface-actor-x11.c      |  56 ++++++++--
  src/compositor/meta-surface-actor-x11.h      |   5 +
  src/compositor/meta-window-actor-private.h   |   5 +
@@ -31,15 +31,16 @@ texture_from_pixmap.
  src/core/main.c                              |   4 +
  src/core/stereo.c                            | 153 ++++++++++++++++++++++++++
  src/core/stereo.h                            |  28 +++++
- 13 files changed, 526 insertions(+), 50 deletions(-)
+ src/wayland/meta-wayland-surface.c           |   2 +-
+ 14 files changed, 535 insertions(+), 51 deletions(-)
  create mode 100644 src/core/stereo.c
  create mode 100644 src/core/stereo.h
 
 diff --git a/src/Makefile.am b/src/Makefile.am
-index da4e3df..aea37da 100644
+index 6aef50de8..8c680602c 100644
 --- a/src/Makefile.am
 +++ b/src/Makefile.am
-@@ -233,6 +233,8 @@ libmutter_la_SOURCES =				\
+@@ -281,6 +281,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES =	\
  	core/stack.h				\
  	core/stack-tracker.c			\
  	core/stack-tracker.h			\
@@ -49,7 +50,7 @@ index da4e3df..aea37da 100644
  	meta/util.h				\
  	core/util-private.h			\
 diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
-index 4629fa5..27813ba 100644
+index ba58bf175..1c257b5ee 100644
 --- a/src/compositor/compositor-private.h
 +++ b/src/compositor/compositor-private.h
 @@ -21,6 +21,10 @@ struct _MetaCompositor
@@ -63,7 +64,7 @@ index 4629fa5..27813ba 100644
    guint           server_time_is_monotonic_time : 1;
    guint           no_mipmaps  : 1;
  
-@@ -59,6 +63,11 @@ void     meta_end_modal_for_plugin   (MetaCompositor   *compositor,
+@@ -61,6 +65,11 @@ void     meta_end_modal_for_plugin   (MetaCompositor   *compositor,
  gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
                                                        gint64       monotonic_time);
  
@@ -76,7 +77,7 @@ index 4629fa5..27813ba 100644
                                     MetaWindow     *window);
  
 diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
-index f001dfd..f8198d5 100644
+index 17e8a55dd..a1bf1a8f8 100644
 --- a/src/compositor/compositor.c
 +++ b/src/compositor/compositor.c
 @@ -70,6 +70,8 @@
@@ -86,9 +87,9 @@ index f001dfd..f8198d5 100644
 +#include "stack-tracker.h"
 +#include "stereo.h"
  #include "util-private.h"
+ #include "backends/meta-dnd-private.h"
  #include "frame.h"
- #include <X11/extensions/shape.h>
-@@ -477,6 +479,97 @@ redirect_windows (MetaScreen *screen)
+@@ -482,6 +484,97 @@ redirect_windows (MetaScreen *screen)
      }
  }
  
@@ -125,7 +126,7 @@ index f001dfd..f8198d5 100644
 +  extensions_string = query_extensions_string (xdisplay,
 +                                               meta_screen_get_screen_number (screen));
 +
-+  return strstr (extensions_string, "EXT_stereo_tree") != 0;
++  return extensions_string && strstr (extensions_string, "EXT_stereo_tree") != 0;
 +}
 +
 +#include <GL/gl.h>
@@ -186,7 +187,7 @@ index f001dfd..f8198d5 100644
  void
  meta_compositor_manage (MetaCompositor *compositor)
  {
-@@ -485,6 +578,8 @@ meta_compositor_manage (MetaCompositor *compositor)
+@@ -490,6 +583,8 @@ meta_compositor_manage (MetaCompositor *compositor)
    MetaScreen *screen = display->screen;
    MetaBackend *backend = meta_get_backend ();
  
@@ -195,7 +196,7 @@ index f001dfd..f8198d5 100644
    meta_screen_set_cm_selection (display->screen);
  
    compositor->stage = meta_backend_get_stage (backend);
-@@ -749,6 +844,23 @@ meta_compositor_process_event (MetaCompositor *compositor,
+@@ -757,6 +852,23 @@ meta_compositor_process_event (MetaCompositor *compositor,
        if (window)
          process_damage (compositor, (XDamageNotifyEvent *) event, window);
      }
@@ -219,7 +220,7 @@ index f001dfd..f8198d5 100644
  
    if (compositor->have_x11_sync_object)
      meta_sync_ring_handle_event (event);
-@@ -923,6 +1035,7 @@ meta_compositor_sync_stack (MetaCompositor  *compositor,
+@@ -957,6 +1069,7 @@ meta_compositor_sync_stack (MetaCompositor  *compositor,
  			    GList	    *stack)
  {
    GList *old_stack;
@@ -227,7 +228,7 @@ index f001dfd..f8198d5 100644
  
    /* This is painful because hidden windows that we are in the process
     * of animating out of existence. They'll be at the bottom of the
-@@ -998,12 +1111,16 @@ meta_compositor_sync_stack (MetaCompositor  *compositor,
+@@ -1032,6 +1145,8 @@ meta_compositor_sync_stack (MetaCompositor  *compositor,
         * near the front of the other.)
         */
        compositor->windows = g_list_prepend (compositor->windows, actor);
@@ -236,15 +237,16 @@ index f001dfd..f8198d5 100644
  
        stack = g_list_remove (stack, window);
        old_stack = g_list_remove (old_stack, actor);
-     }
+@@ -1039,6 +1154,8 @@ meta_compositor_sync_stack (MetaCompositor  *compositor,
  
    sync_actor_stacking (compositor);
-+
+ 
 +  meta_stereo_set_have_stereo_windows (stereo_window_count > 0);
++
+   compositor->top_window_actor = get_top_visible_window_actor (compositor);
  }
  
- void
-@@ -1193,6 +1310,17 @@ meta_compositor_new (MetaDisplay *display)
+@@ -1237,6 +1354,17 @@ meta_compositor_new (MetaDisplay *display)
                                             meta_post_paint_func,
                                             compositor,
                                             NULL);
@@ -263,7 +265,7 @@ index f001dfd..f8198d5 100644
  }
  
 diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
-index 1a841de..79912e7 100644
+index 5b3f283c2..189a95312 100644
 --- a/src/compositor/meta-shaped-texture-private.h
 +++ b/src/compositor/meta-shaped-texture-private.h
 @@ -30,8 +30,9 @@
@@ -275,11 +277,11 @@ index 1a841de..79912e7 100644
 +void meta_shaped_texture_set_textures (MetaShapedTexture *stex,
 +                                       CoglTexture       *texture,
 +                                       CoglTexture       *texture_right);
- void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
-                                             guint              fallback_width,
-                                             guint              fallback_height);
+ void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
+                                             gboolean           is_y_inverted);
+ void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
 diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
-index 5b2630b..830aa67 100644
+index 98346c6ae..b89de03a3 100644
 --- a/src/compositor/meta-shaped-texture.c
 +++ b/src/compositor/meta-shaped-texture.c
 @@ -74,8 +74,10 @@ static guint signals[LAST_SIGNAL];
@@ -291,9 +293,9 @@ index 5b2630b..830aa67 100644
    CoglTexture *texture;
 +  CoglTexture *texture_right;
    CoglTexture *mask_texture;
+   CoglSnippet *snippet;
  
-   /* The region containing only fully opaque pixels */
-@@ -122,8 +124,10 @@ meta_shaped_texture_init (MetaShapedTexture *self)
+@@ -129,8 +131,10 @@ meta_shaped_texture_init (MetaShapedTexture *self)
    priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
  
    priv->paint_tower = meta_texture_tower_new ();
@@ -303,8 +305,8 @@ index 5b2630b..830aa67 100644
 +  priv->texture_right = NULL;
    priv->mask_texture = NULL;
    priv->create_mipmaps = TRUE;
- }
-@@ -173,11 +177,11 @@ meta_shaped_texture_dispose (GObject *object)
+   priv->is_y_inverted = TRUE;
+@@ -191,11 +195,11 @@ meta_shaped_texture_dispose (GObject *object)
    MetaShapedTexture *self = (MetaShapedTexture *) object;
    MetaShapedTexturePrivate *priv = self->priv;
  
@@ -319,7 +321,7 @@ index 5b2630b..830aa67 100644
    g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
  
    meta_shaped_texture_set_mask_texture (self, NULL);
-@@ -271,8 +275,9 @@ paint_clipped_rectangle (CoglFramebuffer       *fb,
+@@ -326,8 +330,9 @@ paint_clipped_rectangle (CoglFramebuffer       *fb,
  }
  
  static void
@@ -331,7 +333,7 @@ index 5b2630b..830aa67 100644
  {
    MetaShapedTexturePrivate *priv;
    guint width, height;
-@@ -283,8 +288,11 @@ set_cogl_texture (MetaShapedTexture *stex,
+@@ -338,8 +343,11 @@ set_cogl_texture (MetaShapedTexture *stex,
  
    if (priv->texture)
      cogl_object_unref (priv->texture);
@@ -343,7 +345,7 @@ index 5b2630b..830aa67 100644
  
    if (cogl_tex != NULL)
      {
-@@ -298,6 +306,9 @@ set_cogl_texture (MetaShapedTexture *stex,
+@@ -353,6 +361,9 @@ set_cogl_texture (MetaShapedTexture *stex,
        height = 0;
      }
  
@@ -353,7 +355,7 @@ index 5b2630b..830aa67 100644
    if (priv->tex_width != width ||
        priv->tex_height != height)
      {
-@@ -313,52 +324,41 @@ set_cogl_texture (MetaShapedTexture *stex,
+@@ -368,52 +379,41 @@ set_cogl_texture (MetaShapedTexture *stex,
     * previous buffer. We only queue a redraw in response to surface
     * damage. */
  
@@ -425,7 +427,7 @@ index 5b2630b..830aa67 100644
    tex_width = priv->tex_width;
    tex_height = priv->tex_height;
  
-@@ -519,6 +519,76 @@ meta_shaped_texture_paint (ClutterActor *actor)
+@@ -574,6 +574,76 @@ meta_shaped_texture_paint (ClutterActor *actor)
  }
  
  static void
@@ -502,7 +504,7 @@ index 5b2630b..830aa67 100644
  meta_shaped_texture_get_preferred_width (ClutterActor *self,
                                           gfloat        for_height,
                                           gfloat       *min_width_p,
-@@ -637,6 +707,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
+@@ -692,6 +762,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
        priv->create_mipmaps = create_mipmaps;
        base_texture = create_mipmaps ? priv->texture : NULL;
        meta_texture_tower_set_base_texture (priv->paint_tower, base_texture);
@@ -515,7 +517,7 @@ index 5b2630b..830aa67 100644
      }
  }
  
-@@ -702,6 +778,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
+@@ -757,6 +833,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
      return FALSE;
  
    meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
@@ -524,7 +526,7 @@ index 5b2630b..830aa67 100644
  
    unobscured_region = effective_unobscured_region (stex);
    if (unobscured_region)
-@@ -734,17 +812,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
+@@ -789,17 +867,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
  }
  
  /**
@@ -548,20 +550,35 @@ index 5b2630b..830aa67 100644
  
  /**
 diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
-index 33036d8..f38c7d3 100644
+index 551322573..6ca68eb64 100644
 --- a/src/compositor/meta-surface-actor-wayland.c
 +++ b/src/compositor/meta-surface-actor-wayland.c
-@@ -477,7 +477,7 @@ meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
-                                         CoglTexture *texture)
- {
-   MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
--  meta_shaped_texture_set_texture (stex, texture);
-+  meta_shaped_texture_set_textures (stex, texture, NULL);
+@@ -403,7 +403,7 @@ meta_surface_actor_wayland_dispose (GObject *object)
+   MetaShapedTexture *stex =
+     meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
+ 
+-  meta_shaped_texture_set_texture (stex, NULL);
++  meta_shaped_texture_set_textures (stex, NULL, NULL);
+   if (priv->surface)
+     {
+       g_object_remove_weak_pointer (G_OBJECT (priv->surface),
+@@ -462,6 +462,14 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
+   return META_SURFACE_ACTOR (self);
  }
  
++void
++meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
++                                        CoglTexture *texture)
++{
++  MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
++  meta_shaped_texture_set_textures (stex, texture, NULL);
++}
++
  MetaWaylandSurface *
+ meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self)
+ {
 diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c
-index d32aeb6..52db380 100644
+index d32aeb68a..52db3808e 100644
 --- a/src/compositor/meta-surface-actor-x11.c
 +++ b/src/compositor/meta-surface-actor-x11.c
 @@ -31,6 +31,7 @@
@@ -699,7 +716,7 @@ index d32aeb6..52db380 100644
 +  return priv->stereo;
 +}
 diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h
-index 0e692ee..4b2eccc 100644
+index 0e692ee0f..4b2ecccb1 100644
 --- a/src/compositor/meta-surface-actor-x11.h
 +++ b/src/compositor/meta-surface-actor-x11.h
 @@ -64,6 +64,11 @@ MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window);
@@ -715,7 +732,7 @@ index 0e692ee..4b2eccc 100644
  
  #endif /* __META_SURFACE_ACTOR_X11_H__ */
 diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
-index 72dcd14..035d756 100644
+index 72dcd1451..035d756b2 100644
 --- a/src/compositor/meta-window-actor-private.h
 +++ b/src/compositor/meta-window-actor-private.h
 @@ -59,4 +59,9 @@ void meta_window_actor_effect_completed (MetaWindowActor  *actor,
@@ -729,10 +746,10 @@ index 72dcd14..035d756 100644
 +
  #endif /* META_WINDOW_ACTOR_PRIVATE_H */
 diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
-index 9395caa..f763964 100644
+index 1184cd422..773e6d09d 100644
 --- a/src/compositor/meta-window-actor.c
 +++ b/src/compositor/meta-window-actor.c
-@@ -2146,3 +2146,25 @@ meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
+@@ -2150,3 +2150,25 @@ meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
  
    meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
  }
@@ -759,7 +776,7 @@ index 9395caa..f763964 100644
 +    return FALSE;
 +}
 diff --git a/src/core/main.c b/src/core/main.c
-index 25586be..23d9d6d 100644
+index dc1f1c4f6..2c1160711 100644
 --- a/src/core/main.c
 +++ b/src/core/main.c
 @@ -47,6 +47,7 @@
@@ -770,9 +787,9 @@ index 25586be..23d9d6d 100644
  #include <meta/errors.h>
  #include "ui.h"
  #include <meta/prefs.h>
-@@ -490,6 +491,9 @@ meta_init (void)
+@@ -566,6 +567,9 @@ meta_init (void)
  
-   meta_init_backend (backend_type);
+   meta_init_backend (backend_gtype);
  
 +  if (!meta_is_wayland_compositor ())
 +    meta_stereo_init ();
@@ -782,7 +799,7 @@ index 25586be..23d9d6d 100644
  #ifdef HAVE_WAYLAND
 diff --git a/src/core/stereo.c b/src/core/stereo.c
 new file mode 100644
-index 0000000..5a232b6
+index 000000000..5a232b67c
 --- /dev/null
 +++ b/src/core/stereo.c
 @@ -0,0 +1,153 @@
@@ -941,7 +958,7 @@ index 0000000..5a232b6
 +}
 diff --git a/src/core/stereo.h b/src/core/stereo.h
 new file mode 100644
-index 0000000..ccd1d70
+index 000000000..ccd1d702a
 --- /dev/null
 +++ b/src/core/stereo.h
 @@ -0,0 +1,28 @@
@@ -973,6 +990,19 @@ index 0000000..ccd1d70
 +void     meta_stereo_finish_restart          (void);
 +
 +#endif
+diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
+index 6f9df37da..d353ae5d0 100644
+--- a/src/wayland/meta-wayland-surface.c
++++ b/src/wayland/meta-wayland-surface.c
+@@ -789,7 +789,7 @@ apply_pending_state (MetaWaylandSurface      *surface,
+               snippet = meta_wayland_buffer_create_snippet (pending->buffer);
+               is_y_inverted = meta_wayland_buffer_is_y_inverted (pending->buffer);
+ 
+-              meta_shaped_texture_set_texture (stex, texture);
++              meta_shaped_texture_set_textures (stex, texture, NULL);
+               meta_shaped_texture_set_snippet (stex, snippet);
+               meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted);
+               g_clear_pointer (&snippet, cogl_object_unref);
 -- 
-2.9.3
+2.14.2
 
diff --git a/SOURCES/Enable-threeaded-swap-wait.patch b/SOURCES/Enable-threeaded-swap-wait.patch
deleted file mode 100644
index 5e27d79..0000000
--- a/SOURCES/Enable-threeaded-swap-wait.patch
+++ /dev/null
@@ -1,887 +0,0 @@
-From 4d1005e3b86050f8b5bab41baf08704117f89b21 Mon Sep 17 00:00:00 2001
-From: "Owen W. Taylor" <otaylor@fishsoup.net>
-Date: Thu, 11 Feb 2016 15:06:23 -0500
-Subject: [PATCH 1/7] CoglGPUInfo - fix check for NVIDIA
-
-NVIDIA drivers have a vendor of "NVIDIA Corporation" not "NVIDIA".
-Check for both in case older drivers did use "NVIDIA"
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779039
----
- cogl/cogl/cogl-gpu-info.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/cogl/cogl/cogl-gpu-info.c b/cogl/cogl/cogl-gpu-info.c
-index 845382881..23a846616 100644
---- a/cogl/cogl/cogl-gpu-info.c
-+++ b/cogl/cogl/cogl-gpu-info.c
-@@ -169,7 +169,8 @@ check_qualcomm_vendor (const CoglGpuInfoStrings *strings)
- static CoglBool
- check_nvidia_vendor (const CoglGpuInfoStrings *strings)
- {
--  if (strcmp (strings->vendor_string, "NVIDIA") != 0)
-+  if (strcmp (strings->vendor_string, "NVIDIA") != 0 &&
-+      strcmp (strings->vendor_string, "NVIDIA Corporation") != 0)
-     return FALSE;
- 
-   return TRUE;
--- 
-2.12.0
-
-
-From 62a66bddf3aba14e65ab913746237d3d19a502dd Mon Sep 17 00:00:00 2001
-From: "Owen W. Taylor" <otaylor@fishsoup.net>
-Date: Thu, 11 Feb 2016 16:33:03 -0500
-Subject: [PATCH 2/7] CoglWinsysGLX: factor out some duplicated code
-
-Add a helper function for repeated calls to clock_gettime(CLOCK_MONOTONIC)
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779039
----
- cogl/cogl/winsys/cogl-winsys-glx.c | 24 ++++++++++++------------
- 1 file changed, 12 insertions(+), 12 deletions(-)
-
-diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
-index c50db3a04..379658e8a 100644
---- a/cogl/cogl/winsys/cogl-winsys-glx.c
-+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
-@@ -192,6 +192,15 @@ find_onscreen_for_xid (CoglContext *context, uint32_t xid)
-   return NULL;
- }
- 
-+static int64_t
-+get_monotonic_time_ns (void)
-+{
-+  struct timespec ts;
-+
-+  clock_gettime (CLOCK_MONOTONIC, &ts);
-+  return ts.tv_sec * G_GINT64_CONSTANT (1000000000) + ts.tv_nsec;
-+}
-+
- static void
- ensure_ust_type (CoglRenderer *renderer,
-                  GLXDrawable drawable)
-@@ -202,7 +211,6 @@ ensure_ust_type (CoglRenderer *renderer,
-   int64_t msc;
-   int64_t sbc;
-   struct timeval tv;
--  struct timespec ts;
-   int64_t current_system_time;
-   int64_t current_monotonic_time;
- 
-@@ -232,9 +240,7 @@ ensure_ust_type (CoglRenderer *renderer,
- 
-   /* This is the time source that the newer (fixed) linux drm
-    * drivers use (Linux >= 3.8) */
--  clock_gettime (CLOCK_MONOTONIC, &ts);
--  current_monotonic_time = (ts.tv_sec * G_GINT64_CONSTANT (1000000)) +
--    (ts.tv_nsec / G_GINT64_CONSTANT (1000));
-+  current_monotonic_time = get_monotonic_time_ns () / 1000;
- 
-   if (current_monotonic_time > ust - 1000000 &&
-       current_monotonic_time < ust + 1000000)
-@@ -310,10 +316,7 @@ _cogl_winsys_get_clock_time (CoglContext *context)
-       }
-     case COGL_GLX_UST_IS_MONOTONIC_TIME:
-       {
--        struct timespec ts;
--
--        clock_gettime (CLOCK_MONOTONIC, &ts);
--        return ts.tv_sec * G_GINT64_CONSTANT (1000000000) + ts.tv_nsec;
-+        return get_monotonic_time_ns ();
-       }
-     }
- 
-@@ -1682,16 +1685,13 @@ _cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen)
-       else
-         {
-           uint32_t current_count;
--          struct timespec ts;
- 
-           glx_renderer->glXGetVideoSync (&current_count);
-           glx_renderer->glXWaitVideoSync (2,
-                                           (current_count + 1) % 2,
-                                           &current_count);
- 
--          clock_gettime (CLOCK_MONOTONIC, &ts);
--          info->presentation_time =
--            ts.tv_sec * G_GINT64_CONSTANT (1000000000) + ts.tv_nsec;
-+          info->presentation_time = get_monotonic_time_ns ();
-         }
-     }
- }
--- 
-2.12.0
-
-
-From 69e156c91c663e6f41759eec9f7c729a67da7dc5 Mon Sep 17 00:00:00 2001
-From: "Owen W. Taylor" <otaylor@fishsoup.net>
-Date: Thu, 11 Feb 2016 17:04:08 -0500
-Subject: [PATCH 3/7] Usability of SGI_video_sync is per-display not
- per-renderer
-
-As previously commented in the code, SGI_video_sync is per-display, rather
-than per-renderer. The is_direct flag for the renderer was tested before
-it was initialized (per-display) and that resulted in SGI_video_sync
-never being used.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779039
----
- cogl/cogl/cogl-glx-display-private.h  |  3 ++
- cogl/cogl/cogl-glx-renderer-private.h |  2 --
- cogl/cogl/winsys/cogl-winsys-glx.c    | 52 +++++++++++++++++++----------------
- 3 files changed, 31 insertions(+), 26 deletions(-)
-
-diff --git a/cogl/cogl/cogl-glx-display-private.h b/cogl/cogl/cogl-glx-display-private.h
-index 133c1188c..1d1afc0cf 100644
---- a/cogl/cogl/cogl-glx-display-private.h
-+++ b/cogl/cogl/cogl-glx-display-private.h
-@@ -51,6 +51,9 @@ typedef struct _CoglGLXDisplay
- 
-   CoglBool found_fbconfig;
-   CoglBool fbconfig_has_rgba_visual;
-+  CoglBool is_direct;
-+  CoglBool have_vblank_counter;
-+  CoglBool can_vblank_wait;
-   GLXFBConfig fbconfig;
- 
-   /* Single context for all wins */
-diff --git a/cogl/cogl/cogl-glx-renderer-private.h b/cogl/cogl/cogl-glx-renderer-private.h
-index cb8ff97f8..061f2ccb5 100644
---- a/cogl/cogl/cogl-glx-renderer-private.h
-+++ b/cogl/cogl/cogl-glx-renderer-private.h
-@@ -43,8 +43,6 @@ typedef struct _CoglGLXRenderer
-   int glx_error_base;
-   int glx_event_base;
- 
--  CoglBool is_direct;
--
-   /* Vblank stuff */
-   int dri_fd;
- 
-diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
-index 379658e8a..5a2700176 100644
---- a/cogl/cogl/winsys/cogl-winsys-glx.c
-+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
-@@ -715,23 +715,25 @@ update_base_winsys_features (CoglRenderer *renderer)
- 
-   g_strfreev (split_extensions);
- 
--  /* Note: the GLX_SGI_video_sync spec explicitly states this extension
--   * only works for direct contexts. */
--  if (!glx_renderer->is_direct)
--    {
--      glx_renderer->glXGetVideoSync = NULL;
--      glx_renderer->glXWaitVideoSync = NULL;
--      COGL_FLAGS_SET (glx_renderer->base_winsys_features,
--                      COGL_WINSYS_FEATURE_VBLANK_COUNTER,
--                      FALSE);
--    }
-+  /* The GLX_SGI_video_sync spec explicitly states this extension
-+   * only works for direct contexts; we don't know per-renderer
-+   * if the context is direct or not, so we turn off the feature
-+   * flag; we still use the extension within this file looking
-+   * instead at glx_display->have_vblank_counter.
-+   */
-+  COGL_FLAGS_SET (glx_renderer->base_winsys_features,
-+                  COGL_WINSYS_FEATURE_VBLANK_COUNTER,
-+                  FALSE);
-+
- 
-   COGL_FLAGS_SET (glx_renderer->base_winsys_features,
-                   COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
-                   TRUE);
- 
--  if (glx_renderer->glXWaitVideoSync ||
--      glx_renderer->glXWaitForMsc)
-+  /* Because of the direct-context dependency, the VBLANK_WAIT feature
-+   * doesn't reflect the presence of GLX_SGI_video_sync.
-+   */
-+  if (glx_renderer->glXWaitForMsc)
-     COGL_FLAGS_SET (glx_renderer->base_winsys_features,
-                     COGL_WINSYS_FEATURE_VBLANK_WAIT,
-                     TRUE);
-@@ -864,7 +866,7 @@ update_winsys_features (CoglContext *context, CoglError **error)
-    * by the SwapInterval so we have to throttle swap_region requests
-    * manually... */
-   if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION) &&
--      _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT))
-+      (glx_display->have_vblank_counter || glx_display->can_vblank_wait))
-     COGL_FLAGS_SET (context->winsys_features,
-                     COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
- 
-@@ -1142,11 +1144,13 @@ create_context (CoglDisplay *display, CoglError **error)
-       return FALSE;
-     }
- 
--  glx_renderer->is_direct =
-+  glx_display->is_direct =
-     glx_renderer->glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context);
-+  glx_display->have_vblank_counter = glx_display->is_direct && glx_renderer->glXWaitVideoSync;
-+  glx_display->can_vblank_wait = glx_renderer->glXWaitForMsc || glx_display->have_vblank_counter;
- 
-   COGL_NOTE (WINSYS, "Setting %s context",
--             glx_renderer->is_direct ? "direct" : "indirect");
-+             glx_display->is_direct ? "direct" : "indirect");
- 
-   /* XXX: GLX doesn't let us make a context current without a window
-    * so we create a dummy window that we can use while no CoglOnscreen
-@@ -1658,12 +1662,13 @@ _cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen)
-   CoglContext *ctx = framebuffer->context;
-   CoglGLXRenderer *glx_renderer;
-   CoglXlibRenderer *xlib_renderer;
-+  CoglGLXDisplay *glx_display;
- 
-   glx_renderer = ctx->display->renderer->winsys;
-   xlib_renderer = _cogl_xlib_renderer_get_data (ctx->display->renderer);
-+  glx_display = ctx->display->winsys;
- 
--  if (glx_renderer->glXWaitForMsc ||
--      glx_renderer->glXGetVideoSync)
-+  if (glx_display->can_vblank_wait)
-     {
-       CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
- 
-@@ -1759,6 +1764,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
-   CoglXlibRenderer *xlib_renderer =
-     _cogl_xlib_renderer_get_data (context->display->renderer);
-   CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
-+  CoglGLXDisplay *glx_display = context->display->winsys;
-   CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
-   CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
-   GLXDrawable drawable =
-@@ -1815,9 +1821,8 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
- 
-   if (framebuffer->config.swap_throttled)
-     {
--      have_counter =
--        _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_COUNTER);
--      can_wait = _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT);
-+      have_counter = glx_display->have_vblank_counter;
-+      can_wait = glx_display->can_vblank_wait;
-     }
-   else
-     {
-@@ -1974,6 +1979,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
-   CoglXlibRenderer *xlib_renderer =
-     _cogl_xlib_renderer_get_data (context->display->renderer);
-   CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
-+  CoglGLXDisplay *glx_display = context->display->winsys;
-   CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
-   CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
-   CoglBool have_counter;
-@@ -1993,8 +1999,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
-     {
-       uint32_t end_frame_vsync_counter = 0;
- 
--      have_counter =
--        _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_COUNTER);
-+      have_counter = glx_display->have_vblank_counter;
- 
-       /* If the swap_region API is also being used then we need to track
-        * the vsync counter for each swap request so we can manually
-@@ -2004,8 +2009,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
- 
-       if (!glx_renderer->glXSwapInterval)
-         {
--          CoglBool can_wait =
--            _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT);
-+          CoglBool can_wait = glx_display->can_vblank_wait;
- 
-           /* If we are going to wait for VBLANK manually, we not only
-            * need to flush out pending drawing to the GPU before we
--- 
-2.12.0
-
-
-From 55b8900c1d66a4568ff261a0498d12ca857d2431 Mon Sep 17 00:00:00 2001
-From: "Owen W. Taylor" <otaylor@fishsoup.net>
-Date: Thu, 11 Feb 2016 17:12:09 -0500
-Subject: [PATCH 4/7] Fix the get_clock_time() without GLX_OML_sync_control
-
-When we don't have GLX_OML_sync_control, we still can set the
-frame presentation time, but we always use the system monotonic time,
-so return that from get_clock_time().
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779039
----
- cogl/cogl/winsys/cogl-winsys-glx.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
-index 5a2700176..7ad1a3fdf 100644
---- a/cogl/cogl/winsys/cogl-winsys-glx.c
-+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
-@@ -296,6 +296,9 @@ _cogl_winsys_get_clock_time (CoglContext *context)
- {
-   CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
- 
-+  if (!glx_renderer->glXWaitForMsc)
-+    return get_monotonic_time_ns ();
-+
-   /* We don't call ensure_ust_type() because we don't have a drawable
-    * to work with. cogl_get_clock_time() is documented to only work
-    * once a valid, non-zero, timestamp has been retrieved from Cogl.
--- 
-2.12.0
-
-
-From cb784a7be6c72453bc441f03ced27a531ee687d5 Mon Sep 17 00:00:00 2001
-From: "Owen W. Taylor" <otaylor@fishsoup.net>
-Date: Thu, 11 Feb 2016 17:15:13 -0500
-Subject: [PATCH 5/7] For NVIDIA proprietary drivers, implement sync events
- with a thread
-
-It's a good guess that the buffer swap will occur at the next vblank,
-so use glXWaitVideoSync in a separate thread to deliver a sync event
-rather than just letting the client block when frame drawing, which
-can signficantly change app logic as compared to the INTEL_swap_event
-case.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779039
----
- cogl/cogl/cogl-private.h           |   3 +
- cogl/cogl/winsys/cogl-winsys-glx.c | 294 +++++++++++++++++++++++++++++++++++--
- 2 files changed, 286 insertions(+), 11 deletions(-)
-
-diff --git a/cogl/cogl/cogl-private.h b/cogl/cogl/cogl-private.h
-index 333955c65..e5dc9feda 100644
---- a/cogl/cogl/cogl-private.h
-+++ b/cogl/cogl/cogl-private.h
-@@ -77,6 +77,9 @@ typedef enum
-   COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE,
-   COGL_PRIVATE_FEATURE_GL_EMBEDDED,
-   COGL_PRIVATE_FEATURE_GL_WEB,
-+  /* This is currently only implemented for GLX, but isn't actually
-+   * that winsys dependent */
-+  COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT,
- 
-   COGL_N_PRIVATE_FEATURES
- } CoglPrivateFeature;
-diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
-index 7ad1a3fdf..1418d1501 100644
---- a/cogl/cogl/winsys/cogl-winsys-glx.c
-+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
-@@ -65,12 +65,16 @@
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/time.h>
-+#include <errno.h>
- #include <fcntl.h>
- #include <time.h>
-+#include <unistd.h>
- 
- #include <GL/glx.h>
- #include <X11/Xlib.h>
- 
-+#include <glib.h>
-+
- /* This is a relatively new extension */
- #ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
- #define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
-@@ -100,6 +104,14 @@ typedef struct _CoglOnscreenGLX
-   CoglBool pending_sync_notify;
-   CoglBool pending_complete_notify;
-   CoglBool pending_resize_notify;
-+
-+  GThread *swap_wait_thread;
-+  GQueue *swap_wait_queue;
-+  GCond swap_wait_cond;
-+  GMutex swap_wait_mutex;
-+  int swap_wait_pipe[2];
-+  GLXContext swap_wait_context;
-+  CoglBool closing_down;
- } CoglOnscreenGLX;
- 
- typedef struct _CoglPixmapTextureEyeGLX
-@@ -885,6 +897,28 @@ update_winsys_features (CoglContext *context, CoglError **error)
-                       COGL_FEATURE_ID_PRESENTATION_TIME,
-                       TRUE);
-     }
-+  else
-+    {
-+      CoglGpuInfo *info = &context->gpu;
-+      if (glx_display->have_vblank_counter &&
-+	  info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
-+        {
-+          COGL_FLAGS_SET (context->winsys_features,
-+                          COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT, TRUE);
-+          COGL_FLAGS_SET (context->winsys_features,
-+                          COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE);
-+          /* TODO: remove this deprecated feature */
-+          COGL_FLAGS_SET (context->features,
-+                          COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
-+                          TRUE);
-+          COGL_FLAGS_SET (context->features,
-+                          COGL_FEATURE_ID_PRESENTATION_TIME,
-+                          TRUE);
-+          COGL_FLAGS_SET (context->private_features,
-+                          COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT,
-+                          TRUE);
-+        }
-+    }
- 
-   /* We'll manually handle queueing dirty events in response to
-    * Expose events from X */
-@@ -1481,7 +1515,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
-     }
- 
- #ifdef GLX_INTEL_swap_event
--  if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT))
-+  if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT) &&
-+      !_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT))
-     {
-       GLXDrawable drawable =
-         glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin;
-@@ -1524,6 +1559,31 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
-       xlib_onscreen->output = NULL;
-     }
- 
-+  if (glx_onscreen->swap_wait_thread)
-+    {
-+      g_mutex_lock (&glx_onscreen->swap_wait_mutex);
-+      glx_onscreen->closing_down = TRUE;
-+      g_cond_signal (&glx_onscreen->swap_wait_cond);
-+      g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
-+      g_thread_join (glx_onscreen->swap_wait_thread);
-+      glx_onscreen->swap_wait_thread = NULL;
-+
-+      g_cond_clear (&glx_onscreen->swap_wait_cond);
-+      g_mutex_clear (&glx_onscreen->swap_wait_mutex);
-+
-+      g_queue_free (glx_onscreen->swap_wait_queue);
-+      glx_onscreen->swap_wait_queue = NULL;
-+
-+      _cogl_poll_renderer_remove_fd (context->display->renderer,
-+                                     glx_onscreen->swap_wait_pipe[0]);
-+      
-+      close (glx_onscreen->swap_wait_pipe[0]);
-+      close (glx_onscreen->swap_wait_pipe[1]);
-+
-+      glx_renderer->glXDestroyContext (xlib_renderer->xdpy,
-+                                       glx_onscreen->swap_wait_context);
-+    }
-+
-   _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state);
- 
-   drawable =
-@@ -1757,6 +1817,199 @@ set_frame_info_output (CoglOnscreen *onscreen,
-     }
- }
- 
-+static gpointer
-+threaded_swap_wait (gpointer data)
-+{
-+  CoglOnscreen *onscreen = data;
-+
-+  CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
-+
-+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-+  CoglContext *context = framebuffer->context;
-+  CoglDisplay *display = context->display;
-+  CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (display->renderer);
-+  CoglGLXDisplay *glx_display = display->winsys;
-+  CoglGLXRenderer *glx_renderer = display->renderer->winsys;
-+  GLXDrawable dummy_drawable;
-+
-+  if (glx_display->dummy_glxwin)
-+    dummy_drawable = glx_display->dummy_glxwin;
-+  else
-+    dummy_drawable = glx_display->dummy_xwin;
-+
-+  glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
-+                                       dummy_drawable,
-+                                       dummy_drawable,
-+                                       glx_onscreen->swap_wait_context);
-+
-+  g_mutex_lock (&glx_onscreen->swap_wait_mutex);
-+
-+  while (TRUE)
-+    {
-+      gpointer queue_element;
-+      uint32_t vblank_counter;
-+
-+      while (!glx_onscreen->closing_down && glx_onscreen->swap_wait_queue->length == 0)
-+         g_cond_wait (&glx_onscreen->swap_wait_cond, &glx_onscreen->swap_wait_mutex);
-+
-+      if (glx_onscreen->closing_down)
-+         break;
-+
-+      queue_element = g_queue_pop_tail (glx_onscreen->swap_wait_queue);
-+      vblank_counter = GPOINTER_TO_UINT(queue_element);
-+
-+      g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
-+      glx_renderer->glXWaitVideoSync (2,
-+                                      (vblank_counter + 1) % 2,
-+                                      &vblank_counter);
-+      g_mutex_lock (&glx_onscreen->swap_wait_mutex);
-+
-+      if (!glx_onscreen->closing_down)
-+         {
-+           int bytes_written = 0;
-+
-+           union {
-+             char bytes[8];
-+             int64_t presentation_time;
-+           } u;
-+
-+           u.presentation_time = get_monotonic_time_ns ();
-+
-+           while (bytes_written < 8)
-+             {
-+               int res = write (glx_onscreen->swap_wait_pipe[1], u.bytes + bytes_written, 8 - bytes_written);
-+               if (res == -1)
-+                 {
-+                   if (errno != EINTR)
-+                     g_error ("Error writing to swap notification pipe: %s\n",
-+                              g_strerror (errno));
-+                 }
-+               else
-+                 {
-+                   bytes_written += res;
-+                 }
-+             }
-+         }
-+    }
-+
-+  g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
-+
-+  glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
-+                                       None,
-+                                       None,
-+                                       NULL);
-+
-+  return NULL;
-+}
-+
-+static int64_t
-+threaded_swap_wait_pipe_prepare (void *user_data)
-+{
-+  return -1;
-+}
-+
-+static void
-+threaded_swap_wait_pipe_dispatch (void *user_data, int revents)
-+{
-+  CoglOnscreen *onscreen = user_data;
-+  CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
-+
-+  CoglFrameInfo *info;
-+
-+  if ((revents & COGL_POLL_FD_EVENT_IN))
-+    {
-+      int bytes_read = 0;
-+
-+      union {
-+         char bytes[8];
-+         int64_t presentation_time;
-+      } u;
-+
-+      while (bytes_read < 8)
-+         {
-+           int res = read (glx_onscreen->swap_wait_pipe[0], u.bytes + bytes_read, 8 - bytes_read);
-+           if (res == -1)
-+             {
-+               if (errno != EINTR)
-+                 g_error ("Error reading from swap notification pipe: %s\n",
-+                          g_strerror (errno));
-+             }
-+           else
-+             {
-+               bytes_read += res;
-+             }
-+         }
-+
-+      set_sync_pending (onscreen);
-+      set_complete_pending (onscreen);
-+
-+      info = g_queue_peek_head (&onscreen->pending_frame_infos);
-+      info->presentation_time = u.presentation_time;
-+    }
-+}
-+
-+static void
-+start_threaded_swap_wait (CoglOnscreen *onscreen,
-+                           uint32_t      vblank_counter)
-+{
-+  CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
-+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-+  CoglContext *context = framebuffer->context;
-+
-+  if (glx_onscreen->swap_wait_thread == NULL)
-+    {
-+      CoglDisplay *display = context->display;
-+      CoglGLXRenderer *glx_renderer = display->renderer->winsys;
-+      CoglGLXDisplay *glx_display = display->winsys;
-+      CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
-+      CoglXlibRenderer *xlib_renderer =
-+        _cogl_xlib_renderer_get_data (display->renderer);
-+
-+      GLXDrawable drawable =
-+        glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin;
-+      int i;
-+
-+      ensure_ust_type (display->renderer, drawable);
-+      
-+      if ((pipe (glx_onscreen->swap_wait_pipe) == -1))
-+        g_error ("Couldn't create pipe for swap notification: %s\n",
-+                 g_strerror (errno));
-+
-+      for (i = 0; i < 2; i++)
-+	{
-+	  if (fcntl(glx_onscreen->swap_wait_pipe[i], F_SETFD,
-+		    fcntl(glx_onscreen->swap_wait_pipe[i], F_GETFD, 0) | FD_CLOEXEC) == -1)
-+	    g_error ("Couldn't set swap notification pipe CLOEXEC: %s\n",
-+		     g_strerror (errno));
-+	}
-+
-+      _cogl_poll_renderer_add_fd (display->renderer,
-+                                  glx_onscreen->swap_wait_pipe[0],
-+                                  COGL_POLL_FD_EVENT_IN,
-+                                  threaded_swap_wait_pipe_prepare,
-+                                  threaded_swap_wait_pipe_dispatch,
-+                                  onscreen);
-+
-+      glx_onscreen->swap_wait_queue = g_queue_new ();
-+      g_mutex_init (&glx_onscreen->swap_wait_mutex);
-+      g_cond_init (&glx_onscreen->swap_wait_cond);
-+      glx_onscreen->swap_wait_context =
-+         glx_renderer->glXCreateNewContext (xlib_renderer->xdpy,
-+                                            glx_display->fbconfig,
-+                                            GLX_RGBA_TYPE,
-+                                            glx_display->glx_context,
-+                                            True);
-+      glx_onscreen->swap_wait_thread = g_thread_new ("cogl_glx_swap_wait",
-+                                                     threaded_swap_wait,
-+                                                     onscreen);
-+    }
-+
-+  g_mutex_lock (&glx_onscreen->swap_wait_mutex);
-+  g_queue_push_head (glx_onscreen->swap_wait_queue, GUINT_TO_POINTER(vblank_counter));
-+  g_cond_signal (&glx_onscreen->swap_wait_cond);
-+  g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
-+}
-+
- static void
- _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
-                                    const int *user_rectangles,
-@@ -2000,19 +2253,38 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
- 
-   if (framebuffer->config.swap_throttled)
-     {
--      uint32_t end_frame_vsync_counter = 0;
--
-       have_counter = glx_display->have_vblank_counter;
- 
--      /* If the swap_region API is also being used then we need to track
--       * the vsync counter for each swap request so we can manually
--       * throttle swap_region requests. */
--      if (have_counter)
--        end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context);
--
--      if (!glx_renderer->glXSwapInterval)
-+      if (glx_renderer->glXSwapInterval)
-         {
--          CoglBool can_wait = glx_display->can_vblank_wait;
-+          if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT))
-+            {
-+	      /* If we didn't wait for the GPU here, then it's easy to get the case
-+	       * where there is a VBlank between the point where we get the vsync counter
-+	       * and the point where the GPU is ready to actually perform the glXSwapBuffers(),
-+	       * and the swap wait terminates at the first VBlank rather than the one
-+	       * where the swap buffers happens. Calling glFinish() here makes this a
-+	       * rare race since the GPU is already ready to swap when we call glXSwapBuffers().
-+	       * The glFinish() also prevents any serious damage if the rare race happens,
-+	       * since it will wait for the preceding glXSwapBuffers() and prevent us from
-+	       * getting premanently ahead. (For NVIDIA drivers, glFinish() after glXSwapBuffers()
-+	       * waits for the buffer swap to happen.)
-+	       */
-+              _cogl_winsys_wait_for_gpu (onscreen);
-+              start_threaded_swap_wait (onscreen, _cogl_winsys_get_vsync_counter (context));
-+            }
-+        }
-+      else
-+        {
-+          CoglBool can_wait = have_counter || glx_display->can_vblank_wait;
-+
-+          uint32_t end_frame_vsync_counter = 0;
-+
-+          /* If the swap_region API is also being used then we need to track
-+           * the vsync counter for each swap request so we can manually
-+           * throttle swap_region requests. */
-+          if (have_counter)
-+            end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context);
- 
-           /* If we are going to wait for VBLANK manually, we not only
-            * need to flush out pending drawing to the GPU before we
--- 
-2.12.0
-
-
-From fb0978b4ea33c88e7a42d4f478d60ef86e271414 Mon Sep 17 00:00:00 2001
-From: "Owen W. Taylor" <otaylor@fishsoup.net>
-Date: Wed, 29 Jun 2016 13:52:59 -0400
-Subject: [PATCH 6/7] Add cogl_xlib_renderer_set_threaded_swap_wait_enabled()
-
-Because the threaded-swap-wait functionality requires XInitThreads(),
-and because it isn't clear that it is a win for all applications,
-add a API function to conditionally enable it.
-
-Fix the cogl-crate example not to just have a hard-coded dependency
-on libX11.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779039
----
- cogl/cogl/cogl-renderer-private.h  |  1 +
- cogl/cogl/cogl-renderer.c          | 11 +++++++++++
- cogl/cogl/cogl-xlib-renderer.h     | 30 ++++++++++++++++++++++++++++++
- cogl/cogl/winsys/cogl-winsys-glx.c |  1 +
- 4 files changed, 43 insertions(+)
-
-diff --git a/cogl/cogl/cogl-renderer-private.h b/cogl/cogl/cogl-renderer-private.h
-index 8627b6cc6..33ed0ceac 100644
---- a/cogl/cogl/cogl-renderer-private.h
-+++ b/cogl/cogl/cogl-renderer-private.h
-@@ -69,6 +69,7 @@ struct _CoglRenderer
-   Display *foreign_xdpy;
-   CoglBool xlib_enable_event_retrieval;
-   CoglBool xlib_want_reset_on_video_memory_purge;
-+  CoglBool xlib_enable_threaded_swap_wait;
- #endif
- 
-   CoglDriver driver;
-diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c
-index 51a04ffdd..e6575d808 100644
---- a/cogl/cogl/cogl-renderer.c
-+++ b/cogl/cogl/cogl-renderer.c
-@@ -285,6 +285,17 @@ cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer,
- 
-   renderer->xlib_want_reset_on_video_memory_purge = enable;
- }
-+
-+void
-+cogl_xlib_renderer_set_threaded_swap_wait_enabled (CoglRenderer *renderer,
-+						   CoglBool 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_threaded_swap_wait = enable;
-+}
- #endif /* COGL_HAS_XLIB_SUPPORT */
- 
- CoglBool
-diff --git a/cogl/cogl/cogl-xlib-renderer.h b/cogl/cogl/cogl-xlib-renderer.h
-index f3c1d7c09..3c0db189b 100644
---- a/cogl/cogl/cogl-xlib-renderer.h
-+++ b/cogl/cogl/cogl-xlib-renderer.h
-@@ -168,6 +168,36 @@ cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer,
-                                                 CoglBool enable);
- 
- /**
-+ * cogl_xlib_renderer_set_threaded_swap_wait_enabled:
-+ * @renderer: a #CoglRenderer
-+ * @enable: The new value
-+ *
-+ * Sets whether Cogl is allowed to use a separate threaded to wait for the
-+ * completion of glXSwapBuffers() and call the frame callback for the
-+ * corresponding #CoglOnscreen. This is a way of emulating the
-+ * INTEL_swap_event extension, and will only ever be used if
-+ * INTEL_swap_event is not present; it will also only be used for
-+ * specific white-listed drivers that are known to work correctly with
-+ * multiple contexts sharing state between threads.
-+ *
-+ * The advantage of enabling this is that it will allow your main loop
-+ * to do other work while waiting for the system to be ready to draw
-+ * the next frame, instead of blocking in glXSwapBuffers(). A disadvantage
-+ * is that the driver will be prevented from buffering up multiple frames
-+ * even if it thinks that it would be advantageous. In general, this
-+ * will work best for something like a system compositor that is doing
-+ * simple drawing but handling lots of other complex tasks.
-+ * 
-+ * If you enable this, you must call XInitThreads() before any other
-+ * X11 calls in your program. (See the documentation for XInitThreads())
-+ *
-+ * Stability: unstable
-+ */
-+void
-+cogl_xlib_renderer_set_threaded_swap_wait_enabled (CoglRenderer *renderer,
-+						   CoglBool enable);
-+
-+/**
-  * cogl_xlib_renderer_get_display: (skip)
-  */
- Display *
-diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
-index 1418d1501..74b0895d1 100644
---- a/cogl/cogl/winsys/cogl-winsys-glx.c
-+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
-@@ -901,6 +901,7 @@ update_winsys_features (CoglContext *context, CoglError **error)
-     {
-       CoglGpuInfo *info = &context->gpu;
-       if (glx_display->have_vblank_counter &&
-+	  context->display->renderer->xlib_enable_threaded_swap_wait &&
- 	  info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
-         {
-           COGL_FLAGS_SET (context->winsys_features,
--- 
-2.12.0
-
-
-From 9505ce8cce4fe14443b5c9868e4e7301268a8d23 Mon Sep 17 00:00:00 2001
-From: "Owen W. Taylor" <otaylor@fishsoup.net>
-Date: Tue, 21 Feb 2017 13:51:16 -0500
-Subject: [PATCH 7/7] Call cogl_xlib_renderer_set_threaded_swap_wait_enabled()
-
-Set up things so that if the INTEL_swap_event extension is not present,
-but the driver is known to have good thread support, we use an extra
-thread and call glXWaitVideoSync() in the thread. This allows idles
-to work properly, even when Mutter is constantly redrawing new frames;
-otherwise, without INTEL_swap_event, we'll just block in glXSwapBuffers().
-
-https://bugzilla.gnome.org/show_bug.cgi?id=779039
----
- src/backends/x11/meta-backend-x11.c  | 6 ++++++
- src/backends/x11/meta-renderer-x11.c | 8 ++++++++
- 2 files changed, 14 insertions(+)
-
-diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
-index a0b196efe..413b0622a 100644
---- a/src/backends/x11/meta-backend-x11.c
-+++ b/src/backends/x11/meta-backend-x11.c
-@@ -913,6 +913,12 @@ meta_backend_x11_init (MetaBackendX11 *x11)
- {
-   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
- 
-+  /* XInitThreads() is needed to use the "threaded swap wait" functionality
-+   * in Cogl - see meta_renderer_x11_create_cogl_renderer(). We call it here
-+   * to hopefully call it before any other use of XLib.
-+   */
-+  XInitThreads();
-+
-   clutter_x11_request_reset_on_video_memory_purge ();
- 
-   /* We do X11 event retrieval ourselves */
-diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c
-index c0405bedc..9a86f493a 100644
---- a/src/backends/x11/meta-renderer-x11.c
-+++ b/src/backends/x11/meta-renderer-x11.c
-@@ -65,6 +65,14 @@ meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer)
-   cogl_renderer_set_custom_winsys (cogl_renderer, get_x11_cogl_winsys_vtable);
-   cogl_xlib_renderer_set_foreign_display (cogl_renderer, xdisplay);
- 
-+  /* Set up things so that if the INTEL_swap_event extension is not present,
-+   * but the driver is known to have good thread support, we use an extra
-+   * thread and call glXWaitVideoSync() in the thread. This allows idles
-+   * to work properly, even when Mutter is constantly redrawing new frames;
-+   * otherwise, without INTEL_swap_event, we'll just block in glXSwapBuffers().
-+   */
-+  cogl_xlib_renderer_set_threaded_swap_wait_enabled (cogl_renderer, TRUE);
-+
-   return cogl_renderer;
- }
- 
--- 
-2.12.0
-
diff --git a/SOURCES/add-support-for-plain-old-x-device-configuration.patch b/SOURCES/add-support-for-plain-old-x-device-configuration.patch
index 39ec339..3198a09 100644
--- a/SOURCES/add-support-for-plain-old-x-device-configuration.patch
+++ b/SOURCES/add-support-for-plain-old-x-device-configuration.patch
@@ -1,4 +1,4 @@
-From e9cd700f11565fd1723828a5cf77f994c8494ddd Mon Sep 17 00:00:00 2001
+From 81986e9b3c16efa170b2bb4fe2af05a30b9386b3 Mon Sep 17 00:00:00 2001
 From: Rui Matos <tiagomatos@gmail.com>
 Date: Mon, 9 Oct 2017 18:37:11 +0200
 Subject: [PATCH 1/4] backends/x11: Fix a small memory leak
@@ -9,10 +9,10 @@ Introduced in "backends/x11: Support synaptics configuration".
  1 file changed, 1 insertion(+)
 
 diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
-index 75ceb0c93..cfdd2ffef 100644
+index 467a9b7..27995c8 100644
 --- a/src/backends/x11/meta-input-settings-x11.c
 +++ b/src/backends/x11/meta-input-settings-x11.c
-@@ -181,6 +181,7 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
+@@ -222,6 +222,7 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
    buttons[0] = left_handed ? 3 : 1;
    buttons[2] = left_handed ? 1 : 3;
    XSetDeviceButtonMapping (xdisplay, xdevice, buttons, n_buttons);
@@ -21,9 +21,10 @@ index 75ceb0c93..cfdd2ffef 100644
    if (display && meta_error_trap_pop_with_return (display))
      {
 -- 
-2.13.5
+1.8.3.1
 
-From 1df0d3b1a0d85c3a565ce6dde4faedf7c1f57930 Mon Sep 17 00:00:00 2001
+
+From c3f4dc97cdb4f1b63e43e38daf02e676d207ad37 Mon Sep 17 00:00:00 2001
 From: Rui Matos <tiagomatos@gmail.com>
 Date: Mon, 9 Oct 2017 18:39:52 +0200
 Subject: [PATCH 2/4] backends/x11: Add a synaptics check for two finger scroll
@@ -38,10 +39,10 @@ isn't.
  1 file changed, 11 insertions(+)
 
 diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
-index cfdd2ffef..8aa8a497b 100644
+index 27995c8..4c2709c 100644
 --- a/src/backends/x11/meta-input-settings-x11.c
 +++ b/src/backends/x11/meta-input-settings-x11.c
-@@ -546,6 +546,17 @@ meta_input_settings_x11_has_two_finger_scroll (MetaInputSettings  *settings,
+@@ -621,6 +621,17 @@ meta_input_settings_x11_has_two_finger_scroll (MetaInputSettings  *settings,
    guchar *available = NULL;
    gboolean has_two_finger = TRUE;
  
@@ -60,9 +61,10 @@ index cfdd2ffef..8aa8a497b 100644
                              XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
    if (!available || !available[SCROLL_METHOD_FIELD_2FG])
 -- 
-2.13.5
+1.8.3.1
+
 
-From 05b6600752ee85e0c48d4055b3ca1c2d010d2851 Mon Sep 17 00:00:00 2001
+From fd94f5fd842f0f0f9e4a28e69716a30669e2e848 Mon Sep 17 00:00:00 2001
 From: Rui Matos <tiagomatos@gmail.com>
 Date: Mon, 9 Oct 2017 18:55:56 +0200
 Subject: [PATCH 3/4] backends/x11: Add disable while typing support for
@@ -71,11 +73,11 @@ Subject: [PATCH 3/4] backends/x11: Add disable while typing support for
 This is basically a copy of the old g-s-d mouse plugin code to manage
 syndaemon when the synaptics driver is being used.
 ---
- src/backends/x11/meta-input-settings-x11.c | 107 +++++++++++++++++++++++++++++
- 1 file changed, 107 insertions(+)
+ src/backends/x11/meta-input-settings-x11.c | 112 +++++++++++++++++++++++++++++
+ 1 file changed, 112 insertions(+)
 
 diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
-index 8aa8a497b..d38e1b454 100644
+index 4c2709c..9a85f94 100644
 --- a/src/backends/x11/meta-input-settings-x11.c
 +++ b/src/backends/x11/meta-input-settings-x11.c
 @@ -35,6 +35,9 @@
@@ -87,8 +89,8 @@ index 8aa8a497b..d38e1b454 100644
 +#endif
  
  #include <meta/errors.h>
- 
-@@ -43,6 +46,8 @@ typedef struct _MetaInputSettingsX11Private
+ #include "backends/meta-logical-monitor.h"
+@@ -44,6 +47,8 @@ typedef struct _MetaInputSettingsX11Private
  #ifdef HAVE_LIBGUDEV
    GUdevClient *udev_client;
  #endif
@@ -97,8 +99,8 @@ index 8aa8a497b..d38e1b454 100644
  } MetaInputSettingsX11Private;
  
  G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettingsX11, meta_input_settings_x11,
-@@ -291,6 +296,107 @@ change_synaptics_speed (ClutterInputDevice *device,
-   XCloseDevice (xdisplay, xdevice);
+@@ -328,6 +333,107 @@ change_synaptics_speed (ClutterInputDevice *device,
+   XFreeFeedbackList (states);
  }
  
 +/* Ensure that syndaemon dies together with us, to avoid running several of
@@ -205,18 +207,24 @@ index 8aa8a497b..d38e1b454 100644
  static void
  meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
                                           ClutterInputDevice       *device,
-@@ -303,6 +409,7 @@ meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
-     {
-       values[0] = mode != G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED;
-       change_property (device, "Synaptics Off", XA_INTEGER, 8, &values, 1);
-+      set_synaptics_disable_w_typing (settings, mode == G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED);
-       return;
-     }
+@@ -452,6 +558,12 @@ meta_input_settings_x11_set_disable_while_typing (MetaInputSettings  *settings,
+ {
+   guchar value = (enabled) ? 1 : 0;
  
++  if (is_device_synaptics (device))
++    {
++      set_synaptics_disable_w_typing (settings, enabled);
++      return;
++    }
++
+   change_property (device, "libinput Disable While Typing Enabled",
+                    XA_INTEGER, 8, &value, 1);
+ }
 -- 
-2.13.5
+1.8.3.1
+
 
-From 94aa02bfe8364c9be9ca0251f66e8f91c38d1bdd Mon Sep 17 00:00:00 2001
+From f5f9195fe23c0af8a498a13ca6bc5521a0c9e6ce Mon Sep 17 00:00:00 2001
 From: Rui Matos <tiagomatos@gmail.com>
 Date: Tue, 10 Oct 2017 19:07:27 +0200
 Subject: [PATCH 4/4] backends/x11: Support plain old X device configuration
@@ -224,14 +232,14 @@ Subject: [PATCH 4/4] backends/x11: Support plain old X device configuration
 We re-use part of the code added to support synaptics and add a few
 bits specific for xorg-x11-drv-evdev devices.
 ---
- src/backends/x11/meta-input-settings-x11.c | 97 +++++++++++++++++++++++-------
- 1 file changed, 74 insertions(+), 23 deletions(-)
+ src/backends/x11/meta-input-settings-x11.c | 96 +++++++++++++++++++++++-------
+ 1 file changed, 74 insertions(+), 22 deletions(-)
 
 diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
-index d38e1b454..63a8fe79e 100644
+index 9a85f94..cb4eb00 100644
 --- a/src/backends/x11/meta-input-settings-x11.c
 +++ b/src/backends/x11/meta-input-settings-x11.c
-@@ -138,35 +138,35 @@ is_device_synaptics (ClutterInputDevice *device)
+@@ -179,35 +179,35 @@ is_device_synaptics (ClutterInputDevice *device)
    return TRUE;
  }
  
@@ -264,14 +272,14 @@ index d38e1b454..63a8fe79e 100644
 +  guchar *buttons;
    guint buttons_capacity = 16, n_buttons;
  
-   xdevice = XOpenDevice(xdisplay, clutter_input_device_get_device_id (device));
+   xdevice = device_ensure_xdevice (device);
    if (!xdevice)
      return;
  
 -  tap_action = get_property (device, "Synaptics Tap Action",
 -                             XA_INTEGER, 8, 7);
 -  if (!tap_action)
--    goto out;
+-    return;
 -
 -  tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0;
 -  tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0;
@@ -284,7 +292,7 @@ index d38e1b454..63a8fe79e 100644
    if (display)
      meta_error_trap_push (display);
    buttons = g_new (guchar, buttons_capacity);
-@@ -190,17 +190,39 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
+@@ -231,14 +231,37 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
  
    if (display && meta_error_trap_pop_with_return (display))
      {
@@ -292,9 +300,6 @@ index d38e1b454..63a8fe79e 100644
 +      g_warning ("Could not set left-handed for %s",
                   clutter_input_device_get_device_name (device));
      }
- 
-- out:
-   XCloseDevice (xdisplay, xdevice);
  }
  
  static void
@@ -328,8 +333,8 @@ index d38e1b454..63a8fe79e 100644
  {
    MetaDisplay *display = meta_get_display ();
    MetaBackend *backend = meta_get_backend ();
-@@ -296,6 +318,23 @@ change_synaptics_speed (ClutterInputDevice *device,
-   XCloseDevice (xdisplay, xdevice);
+@@ -333,6 +356,23 @@ change_synaptics_speed (ClutterInputDevice *device,
+   XFreeFeedbackList (states);
  }
  
 +static void
@@ -352,7 +357,7 @@ index d38e1b454..63a8fe79e 100644
  /* Ensure that syndaemon dies together with us, to avoid running several of
   * them */
  static void
-@@ -465,9 +504,10 @@ meta_input_settings_x11_set_speed (MetaInputSettings  *settings,
+@@ -501,9 +541,10 @@ meta_input_settings_x11_set_speed (MetaInputSettings  *settings,
    Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
    gfloat value = speed;
  
@@ -365,19 +370,19 @@ index d38e1b454..63a8fe79e 100644
        return;
      }
  
-@@ -494,6 +534,11 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings  *settings,
-       g_object_unref (settings);
-       return;
-     }
-+  else if (!is_device_libinput (device))
-+    {
-+      change_x_device_left_handed (device, enabled);
-+      return;
-+    }
+@@ -545,6 +586,11 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings  *settings,
+           g_object_unref (settings);
+           return;
+         }
++      else if (!is_device_libinput (device))
++        {
++          change_x_device_left_handed (device, enabled);
++          return;
++        }
  
-   change_property (device, "libinput Left Handed Enabled",
-                    XA_INTEGER, 8, &value, 1);
-@@ -678,6 +723,12 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings  *settings,
+       change_property (device, "libinput Left Handed Enabled",
+                        XA_INTEGER, 8, &value, 1);
+@@ -758,6 +804,12 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings  *settings,
                                             ClutterInputDevice *device,
                                             guint               button)
  {
@@ -391,5 +396,5 @@ index d38e1b454..63a8fe79e 100644
                     XA_INTEGER, 32, &button, 1);
  }
 -- 
-2.13.5
+1.8.3.1
 
diff --git a/SOURCES/deal-more-gracefully-with-oversized-windows.patch b/SOURCES/deal-more-gracefully-with-oversized-windows.patch
index b91bd6f..477aded 100644
--- a/SOURCES/deal-more-gracefully-with-oversized-windows.patch
+++ b/SOURCES/deal-more-gracefully-with-oversized-windows.patch
@@ -1,7 +1,7 @@
-From 196f9e68c5c95989225870a8554eac7f61e974f2 Mon Sep 17 00:00:00 2001
+From 547af942e6a0586208dbc3f158a7ec2c14611ff8 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
 Date: Wed, 12 Mar 2014 02:04:13 +0100
-Subject: [PATCH] constraints: Enforce X11 size limits
+Subject: [PATCH 1/8] constraints: Enforce X11 size limits
 
 X11 limits windows to a maximum of 32767x32767, enforce that restriction
 to keep insanely huge windows from crashing the WM.
@@ -10,10 +10,10 @@ to keep insanely huge windows from crashing the WM.
  1 file changed, 42 insertions(+)
 
 diff --git a/src/core/constraints.c b/src/core/constraints.c
-index e7dcacd84..67b52c994 100644
+index f5360ef9d..3b6203d6b 100644
 --- a/src/core/constraints.c
 +++ b/src/core/constraints.c
-@@ -103,6 +103,7 @@ typedef enum
+@@ -106,6 +106,7 @@ typedef enum
    PRIORITY_TITLEBAR_VISIBLE = 4,
    PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA = 4,
    PRIORITY_CUSTOM_RULE = 4,
@@ -21,7 +21,7 @@ index e7dcacd84..67b52c994 100644
    PRIORITY_MAXIMUM = 4 /* Dummy value used for loop end = max(all priorities) */
  } ConstraintPriority;
  
-@@ -193,6 +194,10 @@ static gboolean constrain_partially_onscreen (MetaWindow         *window,
+@@ -196,6 +197,10 @@ static gboolean constrain_partially_onscreen (MetaWindow         *window,
                                                ConstraintInfo     *info,
                                                ConstraintPriority  priority,
                                                gboolean            check_only);
@@ -32,7 +32,7 @@ index e7dcacd84..67b52c994 100644
  
  static void setup_constraint_info        (ConstraintInfo      *info,
                                            MetaWindow          *window,
-@@ -228,6 +233,7 @@ static const Constraint all_constraints[] = {
+@@ -231,6 +236,7 @@ static const Constraint all_constraints[] = {
    {constrain_fully_onscreen,     "constrain_fully_onscreen"},
    {constrain_titlebar_visible,   "constrain_titlebar_visible"},
    {constrain_partially_onscreen, "constrain_partially_onscreen"},
@@ -40,7 +40,7 @@ index e7dcacd84..67b52c994 100644
    {NULL,                         NULL}
  };
  
-@@ -1659,3 +1665,39 @@ constrain_partially_onscreen (MetaWindow         *window,
+@@ -1674,3 +1680,39 @@ constrain_partially_onscreen (MetaWindow         *window,
  
    return retval;
  }
@@ -81,5 +81,5 @@ index e7dcacd84..67b52c994 100644
 +  return TRUE;
 +}
 -- 
-2.12.0
+2.14.2
 
diff --git a/SOURCES/fall-back-to-xorg-on-hybrid-gpus.patch b/SOURCES/fall-back-to-xorg-on-hybrid-gpus.patch
deleted file mode 100644
index 0e26bc3..0000000
--- a/SOURCES/fall-back-to-xorg-on-hybrid-gpus.patch
+++ /dev/null
@@ -1,596 +0,0 @@
-From 5bea406b353f39867eb86307b1c8b4093f22968e Mon Sep 17 00:00:00 2001
-From: Ray Strode <rstrode@redhat.com>
-Date: Tue, 18 Oct 2016 16:40:14 -0400
-Subject: [PATCH 1/4] native: only match drm subsystem devices
-
-Despite g_udev_client_new taking a list of subsystems, it doesn't
-implicitly filter results to those subsystems.
-
-This commit explicitly adds a subsystem match to make sure sound cards
-don't end up in the resulting list of video cards.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=771442
----
- src/backends/native/meta-launcher.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
-index ea28e5a..03a928a 100644
---- a/src/backends/native/meta-launcher.c
-+++ b/src/backends/native/meta-launcher.c
-@@ -268,60 +268,65 @@ sync_active (MetaLauncher *self)
-   self->session_active = active;
- 
-   if (active)
-     session_unpause ();
-   else
-     session_pause ();
- }
- 
- static void
- on_active_changed (Login1Session *session,
-                    GParamSpec    *pspec,
-                    gpointer       user_data)
- {
-   MetaLauncher *self = user_data;
-   sync_active (self);
- }
- 
- static gchar *
- get_primary_gpu_path (const gchar *seat_name)
- {
-   const gchar *subsystems[] = {"drm", NULL};
-   gchar *path = NULL;
-   GList *devices, *tmp;
- 
-   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
-   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
- 
-   g_udev_enumerator_add_match_name (enumerator, "card*");
-   g_udev_enumerator_add_match_tag (enumerator, "seat");
- 
-+  /* We need to explicitly match the subsystem for now.
-+   * https://bugzilla.gnome.org/show_bug.cgi?id=773224
-+   */
-+  g_udev_enumerator_add_match_subsystem (enumerator, "drm");
-+
-   devices = g_udev_enumerator_execute (enumerator);
-   if (!devices)
-     goto out;
- 
-   for (tmp = devices; tmp != NULL; tmp = tmp->next)
-     {
-       g_autoptr (GUdevDevice) platform_device = NULL;
-       g_autoptr (GUdevDevice) pci_device = NULL;
-       GUdevDevice *dev = tmp->data;
-       gint boot_vga;
-       const gchar *device_seat;
- 
-       /* filter out devices that are not character device, like card0-VGA-1 */
-       if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
-         continue;
- 
-       device_seat = g_udev_device_get_property (dev, "ID_SEAT");
-       if (!device_seat)
-         {
-           /* when ID_SEAT is not set, it means seat0 */
-           device_seat = "seat0";
-         }
-       else if (g_strcmp0 (device_seat, "seat0") != 0)
-         {
-           /* if the device has been explicitly assigned other seat
-            * than seat0, it is probably the right device to use */
-           path = g_strdup (g_udev_device_get_device_file (dev));
-           break;
-         }
- 
--- 
-2.10.1
-
-
-From d9dc6ac094080a4190508297e8244a8905a8dcb4 Mon Sep 17 00:00:00 2001
-From: Ray Strode <rstrode@redhat.com>
-Date: Wed, 19 Oct 2016 10:41:14 -0400
-Subject: [PATCH 2/4] native: shore up matching of card device
-
-Right now we accept any character device that matches the glob card*.
-
-That's fine, but we can be a little more specific by checking that
-the devtype is what we expect.
-
-This commit does that.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=771442
----
- src/backends/native/meta-launcher.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
-index 03a928a..765e5ef 100644
---- a/src/backends/native/meta-launcher.c
-+++ b/src/backends/native/meta-launcher.c
-@@ -20,60 +20,62 @@
- #include "config.h"
- 
- #include "meta-launcher.h"
- 
- #include <gio/gunixfdlist.h>
- 
- #include <clutter/clutter.h>
- #include <clutter/egl/clutter-egl.h>
- #include <clutter/evdev/clutter-evdev.h>
- 
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <malloc.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- 
- #include <systemd/sd-login.h>
- #include <gudev/gudev.h>
- 
- #include "dbus-utils.h"
- #include "meta-dbus-login1.h"
- 
- #include "backends/meta-backend-private.h"
- #include "meta-cursor-renderer-native.h"
- #include "meta-idle-monitor-native.h"
- #include "meta-renderer-native.h"
- 
-+#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
-+
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref)
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref)
- G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevEnumerator, g_object_unref)
- 
- struct _MetaLauncher
- {
-   Login1Session *session_proxy;
-   Login1Seat *seat_proxy;
- 
-   gboolean session_active;
- 
-   int kms_fd;
- };
- 
- static Login1Session *
- get_session_proxy (GCancellable *cancellable,
-                    GError      **error)
- {
-   g_autofree char *proxy_path = NULL;
-   g_autofree char *session_id = NULL;
-   Login1Session *session_proxy;
- 
-   if (sd_pid_get_session (getpid (), &session_id) < 0)
-     {
-       g_set_error (error,
-                    G_IO_ERROR,
-                    G_IO_ERROR_NOT_FOUND,
-                    "Could not get session ID: %m");
-       return NULL;
-     }
-@@ -283,66 +285,71 @@ on_active_changed (Login1Session *session,
- }
- 
- static gchar *
- get_primary_gpu_path (const gchar *seat_name)
- {
-   const gchar *subsystems[] = {"drm", NULL};
-   gchar *path = NULL;
-   GList *devices, *tmp;
- 
-   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
-   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
- 
-   g_udev_enumerator_add_match_name (enumerator, "card*");
-   g_udev_enumerator_add_match_tag (enumerator, "seat");
- 
-   /* We need to explicitly match the subsystem for now.
-    * https://bugzilla.gnome.org/show_bug.cgi?id=773224
-    */
-   g_udev_enumerator_add_match_subsystem (enumerator, "drm");
- 
-   devices = g_udev_enumerator_execute (enumerator);
-   if (!devices)
-     goto out;
- 
-   for (tmp = devices; tmp != NULL; tmp = tmp->next)
-     {
-       g_autoptr (GUdevDevice) platform_device = NULL;
-       g_autoptr (GUdevDevice) pci_device = NULL;
-       GUdevDevice *dev = tmp->data;
-       gint boot_vga;
-+      const gchar *device_type;
-       const gchar *device_seat;
- 
-       /* filter out devices that are not character device, like card0-VGA-1 */
-       if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
-         continue;
- 
-+      device_type = g_udev_device_get_property (dev, "DEVTYPE");
-+      if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
-+        continue;
-+
-       device_seat = g_udev_device_get_property (dev, "ID_SEAT");
-       if (!device_seat)
-         {
-           /* when ID_SEAT is not set, it means seat0 */
-           device_seat = "seat0";
-         }
-       else if (g_strcmp0 (device_seat, "seat0") != 0)
-         {
-           /* if the device has been explicitly assigned other seat
-            * than seat0, it is probably the right device to use */
-           path = g_strdup (g_udev_device_get_device_file (dev));
-           break;
-         }
- 
-       /* skip devices that do not belong to our seat */
-       if (g_strcmp0 (seat_name, device_seat))
-         continue;
- 
-       platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL);
-       if (platform_device != NULL)
-         {
-           path = g_strdup (g_udev_device_get_device_file (dev));
-           break;
-         }
- 
-       pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
-       if (pci_device != NULL)
-         {
-           /* get value of boot_vga attribute or 0 if the device has no boot_vga */
-           boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
--- 
-2.10.1
-
-
-From 54ceafff8c8b0b02cd9124eae56a05da4f117033 Mon Sep 17 00:00:00 2001
-From: Ray Strode <rstrode@redhat.com>
-Date: Tue, 18 Oct 2016 16:43:04 -0400
-Subject: [PATCH 3/4] native: fail on systems with connectors spread across
- multiple gpus
-
-We don't support using more than one GPU for output yet, so we should fail
-if we encounter that situation, so GDM will fall back to X.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=771442
----
- src/backends/native/meta-launcher.c | 63 ++++++++++++++++++++++++++++++++++++-
- 1 file changed, 62 insertions(+), 1 deletion(-)
-
-diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
-index 765e5ef..a2885a1 100644
---- a/src/backends/native/meta-launcher.c
-+++ b/src/backends/native/meta-launcher.c
-@@ -257,141 +257,202 @@ on_evdev_device_close (int      fd,
- 
- out:
-   close (fd);
- }
- 
- static void
- sync_active (MetaLauncher *self)
- {
-   gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy));
- 
-   if (active == self->session_active)
-     return;
- 
-   self->session_active = active;
- 
-   if (active)
-     session_unpause ();
-   else
-     session_pause ();
- }
- 
- static void
- on_active_changed (Login1Session *session,
-                    GParamSpec    *pspec,
-                    gpointer       user_data)
- {
-   MetaLauncher *self = user_data;
-   sync_active (self);
- }
- 
-+static guint
-+count_devices_with_connectors (const gchar *seat_name,
-+                               GList       *devices)
-+{
-+  g_autoptr (GHashTable) cards = NULL;
-+  GList *tmp;
-+
-+  cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
-+  for (tmp = devices; tmp != NULL; tmp = tmp->next)
-+    {
-+      GUdevDevice *device = tmp->data;
-+      g_autoptr (GUdevDevice) parent_device = NULL;
-+      const gchar *parent_device_type = NULL;
-+      const gchar *card_seat;
-+
-+      /* filter out the real card devices, we only care about the connectors */
-+      if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE)
-+        continue;
-+
-+      /* only connectors have a modes attribute */
-+      if (!g_udev_device_has_sysfs_attr (device, "modes"))
-+        continue;
-+
-+      parent_device = g_udev_device_get_parent (device);
-+
-+      if (g_udev_device_get_device_type (parent_device) == G_UDEV_DEVICE_TYPE_CHAR)
-+        parent_device_type = g_udev_device_get_property (parent_device, "DEVTYPE");
-+
-+      if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
-+        continue;
-+
-+      card_seat = g_udev_device_get_property (parent_device, "ID_SEAT");
-+
-+      if (!card_seat)
-+        card_seat = "seat0";
-+
-+      if (g_strcmp0 (seat_name, card_seat) != 0)
-+        continue;
-+
-+      g_hash_table_insert (cards,
-+                           (gpointer) g_udev_device_get_name (parent_device),
-+                           g_steal_pointer (&parent_device));
-+    }
-+
-+  return g_hash_table_size (cards);
-+}
-+
- static gchar *
- get_primary_gpu_path (const gchar *seat_name)
- {
-   const gchar *subsystems[] = {"drm", NULL};
-   gchar *path = NULL;
-   GList *devices, *tmp;
- 
-   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
-   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
- 
-   g_udev_enumerator_add_match_name (enumerator, "card*");
-   g_udev_enumerator_add_match_tag (enumerator, "seat");
- 
-   /* We need to explicitly match the subsystem for now.
-    * https://bugzilla.gnome.org/show_bug.cgi?id=773224
-    */
-   g_udev_enumerator_add_match_subsystem (enumerator, "drm");
- 
-   devices = g_udev_enumerator_execute (enumerator);
-   if (!devices)
-     goto out;
- 
-+  /* For now, fail on systems where some of the connectors
-+   * are connected to secondary gpus.
-+   *
-+   * https://bugzilla.gnome.org/show_bug.cgi?id=771442
-+   */
-+  if (g_getenv ("MUTTER_ALLOW_HYBRID_GPUS") == NULL)
-+    {
-+      guint num_devices;
-+
-+      num_devices = count_devices_with_connectors (seat_name, devices);
-+      if (num_devices != 1)
-+        goto out;
-+    }
-+
-   for (tmp = devices; tmp != NULL; tmp = tmp->next)
-     {
-       g_autoptr (GUdevDevice) platform_device = NULL;
-       g_autoptr (GUdevDevice) pci_device = NULL;
-       GUdevDevice *dev = tmp->data;
-       gint boot_vga;
-       const gchar *device_type;
-       const gchar *device_seat;
- 
-       /* filter out devices that are not character device, like card0-VGA-1 */
-       if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
-         continue;
- 
-       device_type = g_udev_device_get_property (dev, "DEVTYPE");
-       if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
-         continue;
- 
-       device_seat = g_udev_device_get_property (dev, "ID_SEAT");
-       if (!device_seat)
-         {
-           /* when ID_SEAT is not set, it means seat0 */
-           device_seat = "seat0";
-         }
-       else if (g_strcmp0 (device_seat, "seat0") != 0)
-         {
-           /* if the device has been explicitly assigned other seat
-            * than seat0, it is probably the right device to use */
-           path = g_strdup (g_udev_device_get_device_file (dev));
-           break;
-         }
- 
-       /* skip devices that do not belong to our seat */
-       if (g_strcmp0 (seat_name, device_seat))
-         continue;
- 
-       platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL);
-       if (platform_device != NULL)
-         {
-           path = g_strdup (g_udev_device_get_device_file (dev));
-           break;
-         }
- 
-       pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
-       if (pci_device != NULL)
-         {
-           /* get value of boot_vga attribute or 0 if the device has no boot_vga */
-           boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
-           if (boot_vga == 1)
-             {
-               /* found the boot_vga device */
-               path = g_strdup (g_udev_device_get_device_file (dev));
-               break;
-             }
-         }
-     }
- 
-+out:
-   g_list_free_full (devices, g_object_unref);
- 
--out:
-   return path;
- }
- 
- static gboolean
- get_kms_fd (Login1Session *session_proxy,
-             const gchar   *seat_id,
-             int           *fd_out,
-             GError       **error)
- {
-   int major, minor;
-   int fd;
- 
-   g_autofree gchar *path = get_primary_gpu_path (seat_id);
-   if (!path)
-     {
-       g_set_error (error,
-                    G_IO_ERROR,
-                    G_IO_ERROR_NOT_FOUND,
-                    "could not find drm kms device");
-       return FALSE;
-     }
- 
-   if (!get_device_info_from_path (path, &major, &minor))
-     {
-       g_set_error (error,
-                    G_IO_ERROR,
-                    G_IO_ERROR_NOT_FOUND,
-                    "Could not get device info for path %s: %m", path);
-       return FALSE;
-     }
--- 
-2.10.1
-
-
-From 0d87baa029329c409646e04bcf40bea5da67b5f7 Mon Sep 17 00:00:00 2001
-From: Ray Strode <rstrode@redhat.com>
-Date: Wed, 19 Oct 2016 14:27:24 -0400
-Subject: [PATCH 4/4] native: don't call steal_pointer prematurely
-
-commit e2bfaf07514ed633f8721b5f521577685b6cccc0 does this:
-
-g_hash_table_insert (cards,
-                     g_udev_device_get_name (parent_device),
-                     g_steal_pointer (&parent_device));
-
-The problem is the g_steal_pointer call may happen before the
-g_udev_device_get_name call leading to a crash.
-
-This commit does the get_name call on an earlier line
-
-https://bugzilla.gnome.org/show_bug.cgi?id=771442
----
- src/backends/native/meta-launcher.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
-index a2885a1..ddb7080 100644
---- a/src/backends/native/meta-launcher.c
-+++ b/src/backends/native/meta-launcher.c
-@@ -270,88 +270,90 @@ sync_active (MetaLauncher *self)
-   self->session_active = active;
- 
-   if (active)
-     session_unpause ();
-   else
-     session_pause ();
- }
- 
- static void
- on_active_changed (Login1Session *session,
-                    GParamSpec    *pspec,
-                    gpointer       user_data)
- {
-   MetaLauncher *self = user_data;
-   sync_active (self);
- }
- 
- static guint
- count_devices_with_connectors (const gchar *seat_name,
-                                GList       *devices)
- {
-   g_autoptr (GHashTable) cards = NULL;
-   GList *tmp;
- 
-   cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
-   for (tmp = devices; tmp != NULL; tmp = tmp->next)
-     {
-       GUdevDevice *device = tmp->data;
-       g_autoptr (GUdevDevice) parent_device = NULL;
-       const gchar *parent_device_type = NULL;
-+      const gchar *parent_device_name = NULL;
-       const gchar *card_seat;
- 
-       /* filter out the real card devices, we only care about the connectors */
-       if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE)
-         continue;
- 
-       /* only connectors have a modes attribute */
-       if (!g_udev_device_has_sysfs_attr (device, "modes"))
-         continue;
- 
-       parent_device = g_udev_device_get_parent (device);
- 
-       if (g_udev_device_get_device_type (parent_device) == G_UDEV_DEVICE_TYPE_CHAR)
-         parent_device_type = g_udev_device_get_property (parent_device, "DEVTYPE");
- 
-       if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
-         continue;
- 
-       card_seat = g_udev_device_get_property (parent_device, "ID_SEAT");
- 
-       if (!card_seat)
-         card_seat = "seat0";
- 
-       if (g_strcmp0 (seat_name, card_seat) != 0)
-         continue;
- 
-+      parent_device_name = g_udev_device_get_name (parent_device);
-       g_hash_table_insert (cards,
--                           (gpointer) g_udev_device_get_name (parent_device),
-+                           (gpointer) parent_device_name ,
-                            g_steal_pointer (&parent_device));
-     }
- 
-   return g_hash_table_size (cards);
- }
- 
- static gchar *
- get_primary_gpu_path (const gchar *seat_name)
- {
-   const gchar *subsystems[] = {"drm", NULL};
-   gchar *path = NULL;
-   GList *devices, *tmp;
- 
-   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
-   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
- 
-   g_udev_enumerator_add_match_name (enumerator, "card*");
-   g_udev_enumerator_add_match_tag (enumerator, "seat");
- 
-   /* We need to explicitly match the subsystem for now.
-    * https://bugzilla.gnome.org/show_bug.cgi?id=773224
-    */
-   g_udev_enumerator_add_match_subsystem (enumerator, "drm");
- 
-   devices = g_udev_enumerator_execute (enumerator);
-   if (!devices)
-     goto out;
- 
-   /* For now, fail on systems where some of the connectors
-    * are connected to secondary gpus.
--- 
-2.10.1
-
diff --git a/SOURCES/fix-session-save-crash.patch b/SOURCES/fix-session-save-crash.patch
new file mode 100644
index 0000000..99534ae
--- /dev/null
+++ b/SOURCES/fix-session-save-crash.patch
@@ -0,0 +1,92 @@
+From 0c9cb02111908409285991e4b0f44a4fdcf91eed Mon Sep 17 00:00:00 2001
+From: Olivier Fourdan <ofourdan@redhat.com>
+Date: Tue, 23 Jan 2018 11:43:09 +0100
+Subject: [PATCH 1/2] session: use initial workspace if no workspace set
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Having “on_all_workspaces_requested” FALSE on a window does not imply a
+workspace is set.
+
+If the X11 window is placed on a secondary monitor while workspaces
+applies on primary monitor only  (“workspaces-only-on-primary” set) then
+“on_all_workspaces_requested” is FALSE while “on_all_workspaces“ is TRUE
+and the associated workspace is NULL, leading to a crash when saving the
+gnome-shell/mutter session.
+
+So if no workspace is set, use the “initial_workspace” instead to avoid
+a NULL pointer dereference.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=792818
+---
+ src/x11/session.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/x11/session.c b/src/x11/session.c
+index af64270a6..8b2a89f1c 100644
+--- a/src/x11/session.c
++++ b/src/x11/session.c
+@@ -950,7 +950,10 @@ save_state (void)
+               fputs ("    <sticky/>\n", outfile);
+             } else {
+               int n;
+-              n = meta_workspace_index (window->workspace);
++              if (window->workspace)
++                n = meta_workspace_index (window->workspace);
++              else
++                n = window->initial_workspace;
+               fprintf (outfile,
+                        "    <workspace index=\"%d\"/>\n", n);
+             }
+-- 
+2.14.3
+
+
+From e2269448dcebd24f23bb8872590204819abc3ac0 Mon Sep 17 00:00:00 2001
+From: Olivier Fourdan <ofourdan@redhat.com>
+Date: Mon, 29 Jan 2018 16:58:46 +0100
+Subject: [PATCH 2/2] =?UTF-8?q?x11/window:=20Mark=20restored=20workspace?=
+ =?UTF-8?q?=20as=20=E2=80=9Cset=E2=80=9D?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When a window's workspace is not NULL, on_all_workspace should be FALSE.
+Similarly, when on_all_workspace is TRUE, the window workspace should be
+NULL.
+
+This is an assumption in multiple places in the code, including when
+setting the workspace state, the window is either added or removed from
+all workspaces only if the window's workspace is NULL.
+
+This rule is initially enforced at creation in _meta_window_shared_new()
+when a initial workspace is set. However, when the initial workspace is
+set from the session info, the initial workspace is not marked as “set”
+which leads to an assertion failure when unmanaging windows, because the
+window is not removed from all the workspaces.
+
+When applying the session info to a window, mark the workspace as “set”.
+
+https://gitlab.gnome.org/GNOME/mutter/issues/4
+
+Closes: #4
+---
+ src/x11/window-x11.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
+index 36a5e70a3..9c8ef5d75 100644
+--- a/src/x11/window-x11.c
++++ b/src/x11/window-x11.c
+@@ -466,6 +466,7 @@ meta_window_apply_session_info (MetaWindow *window,
+           MetaWorkspace *workspace = spaces->data;
+ 
+           meta_window_change_workspace (window, workspace);
++          window->initial_workspace_set = TRUE;
+ 
+           meta_topic (META_DEBUG_SM,
+                       "Restoring saved window %s to workspace %d\n",
+-- 
+2.14.3
+
diff --git a/SOURCES/mutter-3.26.0-hybrid-gpus.patch b/SOURCES/mutter-3.26.0-hybrid-gpus.patch
new file mode 100644
index 0000000..e0c314a
--- /dev/null
+++ b/SOURCES/mutter-3.26.0-hybrid-gpus.patch
@@ -0,0 +1,12 @@
+diff -up mutter-3.26.0/src/backends/native/meta-launcher.c.hybrid mutter-3.26.0/src/backends/native/meta-launcher.c
+--- mutter-3.26.0/src/backends/native/meta-launcher.c.hybrid	2017-09-18 15:55:56.673262947 +0100
++++ mutter-3.26.0/src/backends/native/meta-launcher.c	2017-09-18 15:56:21.383167768 +0100
+@@ -363,7 +363,7 @@ get_primary_gpu_path (const gchar *seat_
+       guint num_devices;
+ 
+       num_devices = count_devices_with_connectors (seat_name, devices);
+-      if (num_devices != 1)
++      if (num_devices > 1)
+         goto out;
+     }
+ 
diff --git a/SOURCES/remember-saved-multi-monitor-configuration.patch b/SOURCES/remember-saved-multi-monitor-configuration.patch
new file mode 100644
index 0000000..f658b0d
--- /dev/null
+++ b/SOURCES/remember-saved-multi-monitor-configuration.patch
@@ -0,0 +1,160 @@
+From 702f204a281c6525da6bfcd2286d70b1ab6eab13 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
+Date: Fri, 3 Nov 2017 15:58:02 +0800
+Subject: [PATCH 1/4] monitor-config-manager: Don't include closed laptop panel
+ in config key
+
+When deriving the list of disabled monitors when creating new monitors
+configs, don't include the laptop panel if the lid is currently closed,
+as we consider the laptop panel nonexistent when the laptop lid is
+closed when it comes to configuration.
+
+The laptop panel connector(s) will either way be appropriately disabled
+anyway, as the field listing disabled monitors in the configuration do
+not affect actual CRTC/connector assignments.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=788915
+---
+ src/backends/meta-monitor-config-manager.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
+index 2fe620767..2a7287778 100644
+--- a/src/backends/meta-monitor-config-manager.c
++++ b/src/backends/meta-monitor-config-manager.c
+@@ -1308,6 +1308,10 @@ meta_monitors_config_new (MetaMonitorManager           *monitor_manager,
+       MetaMonitor *monitor = l->data;
+       MetaMonitorSpec *monitor_spec;
+ 
++      if (meta_monitor_manager_is_lid_closed (monitor_manager) &&
++          meta_monitor_is_laptop_panel (monitor))
++        continue;
++
+       monitor_spec = meta_monitor_get_spec (monitor);
+       if (meta_logical_monitor_configs_have_monitor (logical_monitor_configs,
+                                                      monitor_spec))
+-- 
+2.14.2
+
+From 584e2b93d9f28557cfe8a6ff720b4c3e45c458ab Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
+Date: Fri, 3 Nov 2017 16:03:23 +0800
+Subject: [PATCH 2/4] monitor-manager: Compare keys when checking whether a
+ config is complete
+
+We only counted configured monitors and whether the config was
+applicable (could be assigned), howeverwe didn't include disabled
+monitors when comparing. This could caused incorrect configurations to
+be applied when trying to use the previous configuration.
+
+One scenario where this happened was one a system with one laptop
+screen and one external monitor that was hot plugged some point after
+start up. When the laptop lid was closed, the 'previous configuration'
+being the configuration where only the laptop panel was enabled, passed
+'is-complete' check as the number of configured monitors were correct,
+and the configuration was applicable.
+
+Avoid this issue by simply comparing the configuration key of the
+previous configuration and the configuration key of the current state.
+This correctly identifies a laptop panel with the lid closed as
+inaccessible, thus doesn't incorrectly revert to the previous
+configuration.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=788915
+---
+ src/backends/meta-monitor-config-manager.c |  7 +++---
+ src/backends/meta-monitor-config-manager.h |  2 ++
+ src/backends/meta-monitor-manager.c        | 36 +++++++++---------------------
+ 3 files changed, 16 insertions(+), 29 deletions(-)
+
+diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
+index 2a7287778..bdf863055 100644
+--- a/src/backends/meta-monitor-config-manager.c
++++ b/src/backends/meta-monitor-config-manager.c
+@@ -326,8 +326,8 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager,
+   return TRUE;
+ }
+ 
+-static MetaMonitorsConfigKey *
+-create_key_for_current_state (MetaMonitorManager *monitor_manager)
++MetaMonitorsConfigKey *
++meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager)
+ {
+   MetaMonitorsConfigKey *config_key;
+   GList *l;
+@@ -369,7 +369,8 @@ meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager
+   MetaMonitorsConfig *config;
+   GError *error = NULL;
+ 
+-  config_key = create_key_for_current_state (monitor_manager);
++  config_key =
++    meta_create_monitors_config_key_for_current_state (monitor_manager);
+   if (!config_key)
+     return NULL;
+ 
+diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
+index 516909dd7..c36df38e6 100644
+--- a/src/backends/meta-monitor-config-manager.h
++++ b/src/backends/meta-monitor-config-manager.h
+@@ -136,6 +136,8 @@ void meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor
+ 
+ void meta_monitor_config_free (MetaMonitorConfig *monitor_config);
+ 
++MetaMonitorsConfigKey * meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager);
++
+ gboolean meta_logical_monitor_configs_have_monitor (GList           *logical_monitor_configs,
+                                                     MetaMonitorSpec *monitor_spec);
+ 
+diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
+index 8b548fd68..eb3612cf0 100644
+--- a/src/backends/meta-monitor-manager.c
++++ b/src/backends/meta-monitor-manager.c
+@@ -1551,35 +1551,19 @@ static gboolean
+ meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
+                                          MetaMonitorsConfig *config)
+ {
+-  GList *l;
+-  unsigned int configured_monitor_count = 0;
+-  unsigned int expected_monitor_count = 0;
+-
+-  for (l = config->logical_monitor_configs; l; l = l->next)
+-    {
+-      MetaLogicalMonitorConfig *logical_monitor_config = l->data;
+-      GList *k;
++  MetaMonitorsConfigKey *current_state_key;
++  gboolean is_config_complete;
+ 
+-      for (k = logical_monitor_config->monitor_configs; k; k = k->next)
+-        configured_monitor_count++;
+-    }
+-
+-  for (l = manager->monitors; l; l = l->next)
+-    {
+-      MetaMonitor *monitor = l->data;
++  current_state_key =
++    meta_create_monitors_config_key_for_current_state (manager);
++  if (!current_state_key)
++    return FALSE;
+ 
+-      if (meta_monitor_is_laptop_panel (monitor))
+-        {
+-          if (!meta_monitor_manager_is_lid_closed (manager))
+-            expected_monitor_count++;
+-        }
+-      else
+-        {
+-          expected_monitor_count++;
+-        }
+-    }
++  is_config_complete = meta_monitors_config_key_equal (current_state_key,
++                                                       config->key);
++  meta_monitors_config_key_free (current_state_key);
+ 
+-  if (configured_monitor_count != expected_monitor_count)
++  if (!is_config_complete)
+     return FALSE;
+ 
+   return meta_monitor_manager_is_config_applicable (manager, config, NULL);
+-- 
+2.14.2
+
diff --git a/SOURCES/support-headless-mode.patch b/SOURCES/support-headless-mode.patch
deleted file mode 100644
index 57245e4..0000000
--- a/SOURCES/support-headless-mode.patch
+++ /dev/null
@@ -1,481 +0,0 @@
-From 0826616da1dacf29e3e08dae6d2ffe4116e5bdff Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
-Date: Thu, 16 Jul 2015 15:07:38 +0200
-Subject: [PATCH 1/2] barrier: Guard against X errors
-
----
- src/backends/x11/meta-barrier-x11.c | 22 +++++++++++++++-------
- 1 file changed, 15 insertions(+), 7 deletions(-)
-
-diff --git a/src/backends/x11/meta-barrier-x11.c b/src/backends/x11/meta-barrier-x11.c
-index 054e5cdc6..1fc3fd8cc 100644
---- a/src/backends/x11/meta-barrier-x11.c
-+++ b/src/backends/x11/meta-barrier-x11.c
-@@ -38,6 +38,7 @@
- #include <X11/extensions/XInput2.h>
- #include <X11/extensions/Xfixes.h>
- #include <meta/barrier.h>
-+#include <meta/errors.h>
- #include "backends/x11/meta-barrier-x11.h"
- #include "display-private.h"
- 
-@@ -107,6 +108,7 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier)
-   MetaDisplay *display = barrier->priv->display;
-   Display *dpy;
-   Window root;
-+  PointerBarrier xbarrier;
-   unsigned int allowed_motion_dirs;
- 
-   if (display == NULL)
-@@ -119,18 +121,24 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier)
-   priv = meta_barrier_impl_x11_get_instance_private (self);
-   priv->barrier = barrier;
- 
-+  meta_error_trap_push (display);
-   dpy = display->xdisplay;
-   root = DefaultRootWindow (dpy);
- 
-   allowed_motion_dirs =
-     meta_border_get_allows_directions (&barrier->priv->border);
--  priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
--                                               barrier->priv->border.line.a.x,
--                                               barrier->priv->border.line.a.y,
--                                               barrier->priv->border.line.b.x,
--                                               barrier->priv->border.line.b.y,
--                                               allowed_motion_dirs,
--                                               0, NULL);
-+  xbarrier = XFixesCreatePointerBarrier (dpy, root,
-+                                         barrier->priv->border.line.a.x,
-+                                         barrier->priv->border.line.a.y,
-+                                         barrier->priv->border.line.b.x,
-+                                         barrier->priv->border.line.b.y,
-+                                         allowed_motion_dirs,
-+                                         0, NULL);
-+
-+  if (meta_error_trap_pop_with_return (display) != Success)
-+    return NULL;
-+
-+  priv->xbarrier = xbarrier;
- 
-   g_hash_table_insert (display->xids, &priv->xbarrier, barrier);
- 
--- 
-2.12.0
-
-
-From 2da829399dc79b5c51ca55ab6e633c4a4769c15a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
-Date: Thu, 16 Jul 2015 15:12:55 +0200
-Subject: [PATCH 2/2] Do not crash when starting up with no monitor connected
-
-Some parts of Mutter currently assume there's always a monitor connected
-to the screen. This assumption can be incorrect - e.g. a desktop
-computer can be powered on and a monitor only plugged in after the
-desktop session - or the GDM login - has already been reached.
-
-Fix the various places that assume so, making the code robust to the
-above use case.
-
-Based on an initial patch by Cosimo Cecchi.
----
- src/backends/x11/meta-monitor-manager-xrandr.c |  4 +-
- src/compositor/meta-window-actor.c             |  2 +-
- src/core/constraints.c                         | 71 +++++++++++++++-----------
- src/core/place.c                               |  4 ++
- src/core/screen.c                              | 10 +++-
- src/core/window.c                              | 57 ++++++++++++++-------
- src/core/workspace.c                           |  3 ++
- src/x11/window-x11.c                           |  3 +-
- 8 files changed, 100 insertions(+), 54 deletions(-)
-
-diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
-index b0a77dadb..b82120af9 100644
---- a/src/backends/x11/meta-monitor-manager-xrandr.c
-+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
-@@ -1141,7 +1141,9 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
-       crtc->current_mode = NULL;
-     }
- 
--  g_assert (width > 0 && height > 0);
-+  if (width == 0 || height == 0)
-+    return;
-+
-   /* The 'physical size' of an X screen is meaningless if that screen
-    * can consist of many monitors. So just pick a size that make the
-    * dpi 96.
-diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
-index 9395caac5..fb29ca1c9 100644
---- a/src/compositor/meta-window-actor.c
-+++ b/src/compositor/meta-window-actor.c
-@@ -959,7 +959,7 @@ queue_send_frame_messages_timeout (MetaWindowActor *self)
-   outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
-   for (i = 0; i < n_outputs; i++)
-     {
--      if (outputs[i].winsys_id == window->monitor->winsys_id && outputs[i].crtc)
-+      if (window->monitor && outputs[i].winsys_id == window->monitor->winsys_id && outputs[i].crtc)
-         {
-           refresh_rate = outputs[i].crtc->current_mode->refresh_rate;
-           break;
-diff --git a/src/core/constraints.c b/src/core/constraints.c
-index 67b52c994..3d1701e88 100644
---- a/src/core/constraints.c
-+++ b/src/core/constraints.c
-@@ -29,6 +29,7 @@
- #include <meta/prefs.h>
- 
- #include <stdlib.h>
-+#include <string.h>
- #include <math.h>
- 
- #if 0
-@@ -337,6 +338,8 @@ setup_constraint_info (ConstraintInfo      *info,
-   const MetaMonitorInfo *monitor_info;
-   MetaWorkspace *cur_workspace;
- 
-+  memset (info, 0, sizeof (ConstraintInfo));
-+
-   info->orig    = *orig;
-   info->current = *new;
- 
-@@ -382,40 +385,43 @@ setup_constraint_info (ConstraintInfo      *info,
-   if (!info->is_user_action)
-     info->fixed_directions = FIXED_DIRECTION_NONE;
- 
-+  cur_workspace = window->screen->active_workspace;
-   monitor_info =
-     meta_screen_get_monitor_for_rect (window->screen, &info->current);
--  meta_window_get_work_area_for_monitor (window,
--                                         monitor_info->number,
--                                         &info->work_area_monitor);
- 
--  if (!window->fullscreen || window->fullscreen_monitors[0] == -1)
-+  if (monitor_info)
-     {
--      info->entire_monitor = monitor_info->rect;
--    }
--  else
--    {
--      int i = 0;
--      long monitor;
-+      meta_window_get_work_area_for_monitor (window,
-+                                             monitor_info->number,
-+                                             &info->work_area_monitor);
- 
--      monitor = window->fullscreen_monitors[i];
--      info->entire_monitor =
--        window->screen->monitor_infos[monitor].rect;
--      for (i = 1; i <= 3; i++)
-+      if (!window->fullscreen || window->fullscreen_monitors[0] == -1)
-+        {
-+          info->entire_monitor = monitor_info->rect;
-+        }
-+      else
-         {
-+          int i = 0;
-+          long monitor;
-+
-           monitor = window->fullscreen_monitors[i];
--          meta_rectangle_union (&info->entire_monitor,
--                                &window->screen->monitor_infos[monitor].rect,
--                                &info->entire_monitor);
-+          info->entire_monitor =
-+            window->screen->monitor_infos[monitor].rect;
-+          for (i = 1; i <= 3; i++)
-+            {
-+              monitor = window->fullscreen_monitors[i];
-+              meta_rectangle_union (&info->entire_monitor,
-+                                    &window->screen->monitor_infos[monitor].rect,
-+                                    &info->entire_monitor);
-+            }
-         }
-+      info->usable_screen_region  =
-+        meta_workspace_get_onscreen_region (cur_workspace);
-+      info->usable_monitor_region =
-+        meta_workspace_get_onmonitor_region (cur_workspace,
-+                                             monitor_info->number);
-     }
- 
--  cur_workspace = window->screen->active_workspace;
--  info->usable_screen_region   =
--    meta_workspace_get_onscreen_region (cur_workspace);
--  info->usable_monitor_region =
--    meta_workspace_get_onmonitor_region (cur_workspace,
--                                         monitor_info->number);
--
-   /* Log all this information for debugging */
-   meta_topic (META_DEBUG_GEOMETRY,
-               "Setting up constraint info:\n"
-@@ -489,14 +495,17 @@ place_window_if_needed(MetaWindow     *window,
-        */
-       monitor_info =
-         meta_screen_get_monitor_for_rect (window->screen, &placed_rect);
--      info->entire_monitor = monitor_info->rect;
--      meta_window_get_work_area_for_monitor (window,
--                                             monitor_info->number,
--                                             &info->work_area_monitor);
-       cur_workspace = window->screen->active_workspace;
--      info->usable_monitor_region =
--        meta_workspace_get_onmonitor_region (cur_workspace,
--                                             monitor_info->number);
-+      if (monitor_info)
-+        {
-+          info->entire_monitor = monitor_info->rect;
-+          meta_window_get_work_area_for_monitor (window,
-+                                                 monitor_info->number,
-+                                                 &info->work_area_monitor);
-+          info->usable_monitor_region =
-+            meta_workspace_get_onmonitor_region (cur_workspace,
-+                                                 monitor_info->number);
-+        }
- 
-       info->current.x = placed_rect.x;
-       info->current.y = placed_rect.y;
-diff --git a/src/core/place.c b/src/core/place.c
-index db71b83ce..0f046f046 100644
---- a/src/core/place.c
-+++ b/src/core/place.c
-@@ -811,6 +811,8 @@ meta_window_place (MetaWindow        *window,
- 
-       /* Warning, this function is a round trip! */
-       xi = meta_screen_get_current_monitor_info (window->screen);
-+      if (!xi)
-+        goto done;
- 
-       w = xi->rect.width;
-       h = xi->rect.height;
-@@ -856,6 +858,8 @@ meta_window_place (MetaWindow        *window,
- 
-   /* Warning, this is a round trip! */
-   xi = meta_screen_get_current_monitor_info (window->screen);
-+  if (!xi)
-+    goto done;
- 
-   /* Maximize windows if they are too big for their work area (bit of
-    * a hack here). Assume undecorated windows probably don't intend to
-diff --git a/src/core/screen.c b/src/core/screen.c
-index b8ac22f76..54a0b0aba 100644
---- a/src/core/screen.c
-+++ b/src/core/screen.c
-@@ -381,7 +381,10 @@ meta_screen_monitor_index_to_xinerama_index (MetaScreen *screen,
- 
-   meta_screen_ensure_xinerama_indices (screen);
- 
--  return screen->monitor_infos[index].xinerama_index;
-+  if (index >= 0 && index < screen->n_monitor_infos)
-+    return screen->monitor_infos[index].xinerama_index;
-+
-+  return -1;
- }
- 
- int
-@@ -1395,6 +1398,9 @@ meta_screen_get_monitor_for_rect (MetaScreen    *screen,
-   int i;
-   int best_monitor, monitor_score, rect_area;
- 
-+  if (screen->n_monitor_infos == 0)
-+    return NULL;
-+
-   if (screen->n_monitor_infos == 1)
-     return &screen->monitor_infos[0];
- 
-@@ -1448,7 +1454,7 @@ meta_screen_get_monitor_index_for_rect (MetaScreen    *screen,
-                                         MetaRectangle *rect)
- {
-   const MetaMonitorInfo *monitor = meta_screen_get_monitor_for_rect (screen, rect);
--  return monitor->number;
-+  return monitor ? monitor->number : -1;
- }
- 
- const MetaMonitorInfo *
-diff --git a/src/core/window.c b/src/core/window.c
-index e3e15cf26..9745b42e0 100644
---- a/src/core/window.c
-+++ b/src/core/window.c
-@@ -1029,7 +1029,8 @@ _meta_window_shared_new (MetaDisplay         *display,
- 
-   window->monitor = meta_screen_calculate_monitor_for_window (window->screen,
-                                                               window);
--  window->preferred_output_winsys_id = window->monitor->winsys_id;
-+  window->preferred_output_winsys_id = window->monitor ? window->monitor->winsys_id
-+                                                       : -1;
- 
-   window->tile_match = NULL;
- 
-@@ -2280,7 +2281,10 @@ meta_window_show (MetaWindow *window)
-       if (meta_prefs_get_auto_maximize() && window->showing_for_first_time && window->has_maximize_func)
-         {
-           MetaRectangle work_area;
--          meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
-+          if (window->monitor)
-+            meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
-+          else
-+            meta_window_get_work_area_current_monitor (window, &work_area);
-           /* Automaximize windows that map with a size > MAX_UNMAXIMIZED_WINDOW_AREA of the work area */
-           if (window->rect.width * window->rect.height > work_area.width * work_area.height * MAX_UNMAXIMIZED_WINDOW_AREA)
-             {
-@@ -2677,7 +2681,7 @@ meta_window_maximize_internal (MetaWindow        *window,
-   meta_window_recalc_features (window);
-   set_net_wm_state (window);
- 
--  if (window->monitor->in_fullscreen)
-+  if (window->monitor && window->monitor->in_fullscreen)
-     meta_screen_queue_check_fullscreen (window->screen);
- 
-   g_object_freeze_notify (G_OBJECT (window));
-@@ -2863,6 +2867,9 @@ meta_window_is_monitor_sized (MetaWindow *window)
-   if (meta_window_is_screen_sized (window))
-     return TRUE;
- 
-+  if (!window->monitor)
-+    return FALSE;
-+
-   if (window->override_redirect)
-     {
-       MetaRectangle window_rect, monitor_rect;
-@@ -2886,7 +2893,7 @@ meta_window_is_monitor_sized (MetaWindow *window)
- gboolean
- meta_window_is_on_primary_monitor (MetaWindow *window)
- {
--  return window->monitor->is_primary;
-+  return window->monitor ? window->monitor->is_primary : FALSE;
- }
- 
- /**
-@@ -3027,7 +3034,10 @@ meta_window_unmaximize (MetaWindow        *window,
-       MetaRectangle work_area;
-       MetaRectangle old_frame_rect, old_buffer_rect;
- 
--      meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
-+      if (window->monitor)
-+        meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
-+      else
-+        meta_window_get_work_area_current_monitor (window, &work_area);
-       meta_window_get_frame_rect (window, &old_frame_rect);
-       meta_window_get_buffer_rect (window, &old_buffer_rect);
- 
-@@ -3123,7 +3133,7 @@ meta_window_unmaximize (MetaWindow        *window,
- 
-       meta_window_recalc_features (window);
-       set_net_wm_state (window);
--      if (!window->monitor->in_fullscreen)
-+      if (window->monitor && !window->monitor->in_fullscreen)
-         meta_screen_queue_check_fullscreen (window->screen);
-     }
- 
-@@ -3522,7 +3532,7 @@ maybe_move_attached_dialog (MetaWindow *window,
- int
- meta_window_get_monitor (MetaWindow *window)
- {
--  return window->monitor->number;
-+  return window->monitor ? window->monitor->number : -1;
- }
- 
- static MetaMonitorInfo *
-@@ -3549,14 +3559,15 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
- {
-   const MetaMonitorInfo *old, *new;
- 
--  if (window->override_redirect || window->type == META_WINDOW_DESKTOP)
-+  old = window->monitor;
-+
-+  if (!old || window->screen->n_monitor_infos == 0 ||
-+      window->override_redirect || window->type == META_WINDOW_DESKTOP)
-     {
-       meta_window_update_monitor (window, FALSE);
-       return;
-     }
- 
--  old = window->monitor;
--
-   /* Try the preferred output first */
-   new = find_monitor_by_winsys_id (window, window->preferred_output_winsys_id);
- 
-@@ -3643,7 +3654,7 @@ meta_window_move_resize_internal (MetaWindow          *window,
-    */
- 
-   gboolean did_placement;
--  guint old_output_winsys_id;
-+  guint old_output_winsys_id, new_output_winsys_id;
-   MetaRectangle unconstrained_rect;
-   MetaRectangle constrained_rect;
-   MetaMoveResizeResultFlags result = 0;
-@@ -3737,13 +3748,15 @@ meta_window_move_resize_internal (MetaWindow          *window,
-                                               did_placement);
-     }
- 
--  old_output_winsys_id = window->monitor->winsys_id;
-+  old_output_winsys_id = window->monitor ? window->monitor->winsys_id : -1;
- 
-   meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION);
- 
--  if (old_output_winsys_id != window->monitor->winsys_id &&
-+  new_output_winsys_id = window->monitor ? window->monitor->winsys_id : -1;
-+
-+  if (old_output_winsys_id != new_output_winsys_id &&
-       flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_USER_ACTION)
--    window->preferred_output_winsys_id = window->monitor->winsys_id;
-+    window->preferred_output_winsys_id = new_output_winsys_id;
- 
-   if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
-     {
-@@ -3849,7 +3862,7 @@ meta_window_move_to_monitor (MetaWindow  *window,
- {
-   MetaRectangle old_area, new_area;
- 
--  if (monitor == window->monitor->number)
-+  if (!window->monitor || monitor == window->monitor->number)
-     return;
- 
-   meta_window_get_work_area_for_monitor (window,
-@@ -6104,9 +6117,17 @@ void
- meta_window_get_work_area_current_monitor (MetaWindow    *window,
-                                            MetaRectangle *area)
- {
--  meta_window_get_work_area_for_monitor (window,
--                                         window->monitor->number,
--                                         area);
-+  if (window->monitor)
-+    {
-+      meta_window_get_work_area_for_monitor (window,
-+                                             window->monitor->number,
-+                                             area);
-+    }
-+  else if (area)
-+    {
-+      MetaRectangle empty = { 0, 0, 0, 0 };
-+      *area = empty;
-+    }
- }
- 
- /**
-diff --git a/src/core/workspace.c b/src/core/workspace.c
-index cfac7dc48..a73ac6bb7 100644
---- a/src/core/workspace.c
-+++ b/src/core/workspace.c
-@@ -765,6 +765,9 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
-   g_assert (workspace->screen_edges == NULL);
-   g_assert (workspace->monitor_edges == NULL);
- 
-+  if (workspace->screen->n_monitor_infos == 0)
-+    return;
-+
-   /* STEP 1: Get the list of struts */
- 
-   workspace->all_struts = copy_strut_list (workspace->builtin_struts);
-diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
-index 376d73c78..9b102e589 100644
---- a/src/x11/window-x11.c
-+++ b/src/x11/window-x11.c
-@@ -2032,7 +2032,8 @@ meta_window_move_resize_request (MetaWindow *window,
-       rect.width = width;
-       rect.height = height;
- 
--      meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect);
-+      if (window->monitor)
-+        meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect);
- 
-       /* Workaround braindead legacy apps that don't know how to
-        * fullscreen themselves properly - don't get fooled by
--- 
-2.12.0
-
diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec
index 6e09914..af086a5 100644
--- a/SPECS/mutter.spec
+++ b/SPECS/mutter.spec
@@ -1,66 +1,74 @@
 %global gtk3_version 3.19.8
+%global glib_version 2.53.2
 %global gsettings_desktop_schemas_version 3.21.4
 %global json_glib_version 0.12.0
+%global libinput_version 1.4
+%global wayland_protocols_version 1.9.0
+
+%ifarch s390 s390x
+%global disable_wayland --disable-wayland-egl-server --disable-wayland --disable-native-backend
+%endif
 
 Name:          mutter
-Version:       3.22.3
-Release:       12%{?dist}
+Version:       3.26.2
+Release:       13%{?dist}
 Summary:       Window and compositing manager based on Clutter
 
 License:       GPLv2+
 #VCS:          git:git://git.gnome.org/mutter
 URL:           http://www.gnome.org
-Source0:       http://download.gnome.org/sources/%{name}/3.22/%{name}-%{version}.tar.xz
-
-# https://bugzilla.gnome.org/show_bug.cgi?id=771442
-Patch0:        fall-back-to-xorg-on-hybrid-gpus.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1331382
-Patch1:        0001-Revert-backend-x11-Ensure-the-Xkb-group-index-remain.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1390607
-Patch2:        0001-wayland-xdg-shell-Handle-the-wl_output-on-the-set_fu.patch
-
-Patch3:         startup-notification.patch
-
-Patch4:        deal-more-gracefully-with-oversized-windows.patch
-Patch5:        support-headless-mode.patch
-
-Patch6:        0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch
-Patch7:        0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch
-Patch8:        0001-monitor-config-Consider-external-layout-before-defau.patch
-
-Patch9:       Enable-threeaded-swap-wait.patch
+Source0:       http://download.gnome.org/sources/%{name}/3.26/%{name}-%{version}.tar.xz
 
-Patch10:       0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch
-Patch11:       0001-backends-x11-Support-synaptics-configuration.patch
+Patch0:  startup-notification.patch
 
-Patch12:       0001-display-Check-we-have-a-screen-before-freeing-it.patch
+Patch1:  deal-more-gracefully-with-oversized-windows.patch
 
-Patch13:       0001-cogl-Prefer-swizzling-to-convert-BGRA-buffers.patch
+Patch2:  0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch
+Patch3:  0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch
+Patch4:  0001-monitor-manager-Consider-external-layout-before-defa.patch
 
-Patch14:       0001-cally-Fix-translation-to-screen-coordinates.patch
+Patch5:  0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch
+Patch6:  0001-backends-x11-Support-synaptics-configuration.patch
 
-Patch15:       0001-window-actor-Special-case-shaped-Java-windows.patch
+Patch7:  0001-window-actor-Special-case-shaped-Java-windows.patch
 
-Patch16:       0001-clutter-clone-Unset-source-when-source-actor-is-dest.patch
+Patch8:  0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch
+Patch9:  0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch
+Patch10: 0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch
 
-Patch17:       0001-stack-tracker-Keep-override-redirect-windows-on-top.patch
-
-Patch18:       0001-screen-Remove-stray-assert.patch
+Patch11:  0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch
+Patch12:  0001-backends-Monitor-changes-in-active-tools-settings.patch
+Patch13:  0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch
 
 # http://bugzilla.gnome.org/show_bug.cgi?id=733277
 Patch20: 0008-Add-support-for-quad-buffer-stereo.patch
 Patch21: 0001-build-Lower-automake-requirement.patch
 
-Patch22: add-support-for-plain-old-x-device-configuration.patch
+# el7 patches
+Patch100: 0001-Revert-build-Require-libgudev-232.patch
+Patch101: 0001-rhel7-Fix-build-for-el7.patch
+Patch102: mutter-3.26.0-hybrid-gpus.patch
+Patch103: 0001-wayland-enable-scale-monitor-framebuffer-by-default.patch
+Patch104: add-support-for-plain-old-x-device-configuration.patch
+Patch105: remember-saved-multi-monitor-configuration.patch
+Patch106: 0003-window-wayland-Handle-resizing-when-headless.patch
+Patch107: fix-session-save-crash.patch
+Patch108: 0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch
+Patch109: 0001-main-be-more-aggressive-in-assuming-X11-backend.patch
+
+Patch500: 0001-clutter-stage-don-t-use-deprecated-api.patch
+
 
 BuildRequires: chrpath
 BuildRequires: pango-devel
 BuildRequires: startup-notification-devel
 BuildRequires: gnome-desktop3-devel
+BuildRequires: glib2-devel >= %{glib_version}
 BuildRequires: gtk3-devel >= %{gtk3_version}
 BuildRequires: pkgconfig
 BuildRequires: gobject-introspection-devel >= 1.41.0
 BuildRequires: libSM-devel
+BuildRequires: libwacom-devel
 BuildRequires: libX11-devel
 BuildRequires: libXdamage-devel
 BuildRequires: libXext-devel
@@ -74,6 +82,9 @@ BuildRequires: libxcb-devel
 BuildRequires: libxkbcommon-devel
 BuildRequires: libxkbcommon-x11-devel
 BuildRequires: libxkbfile-devel
+BuildRequires: libXtst-devel
+BuildRequires: mesa-libEGL-devel
+BuildRequires: mesa-libGLES-devel
 BuildRequires: mesa-libGL-devel
 BuildRequires: mesa-libgbm-devel
 BuildRequires: pam-devel
@@ -82,13 +93,22 @@ BuildRequires: xkeyboard-config-devel
 BuildRequires: zenity
 BuildRequires: desktop-file-utils
 # Bootstrap requirements
-BuildRequires: gtk-doc gnome-common gettext-devel
+BuildRequires: gtk-doc gnome-common gettext-devel git
 BuildRequires: libcanberra-devel
 BuildRequires: gsettings-desktop-schemas-devel >= %{gsettings_desktop_schemas_version}
 BuildRequires: automake, autoconf, libtool
+BuildRequires: pkgconfig(gudev-1.0)
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(gbm)
+BuildRequires: pkgconfig(wayland-server)
 
 BuildRequires: json-glib-devel >= %{json_glib_version}
 BuildRequires: libgudev1-devel
+%ifnarch s390 s390x
+BuildRequires: libwayland-server-devel
+BuildRequires: libinput-devel >= %{libinput_version}
+BuildRequires: wayland-protocols-devel >= %{wayland_protocols_version}
+%endif
 
 Obsoletes: mutter-wayland < 3.13.0
 Obsoletes: mutter-wayland-devel < 3.13.0
@@ -106,6 +126,10 @@ Requires: zenity
 
 Requires:      json-glib%{?_isa} >= %{json_glib_version}
 
+%ifnarch s390 s390x
+Requires:      libinput%{?_isa} >= %{libinput_version}
+%endif
+
 %description
 Mutter is a window and compositing manager that displays and manages
 your desktop via OpenGL. Mutter combines a sophisticated display engine
@@ -127,36 +151,12 @@ Header files and libraries for developing Mutter plugins. Also includes
 utilities for testing Metacity/Mutter themes.
 
 %prep
-%setup -q
-%patch0 -p1
-%patch1 -p1
-%patch2 -p1
-%patch3 -p1
-%patch4 -p1 -b .deal-with-oversized-windows
-%patch5 -p1 -b .support-headless-mode
-%patch6 -p1 -b .workaround-xvnc-spurious-hotplugs
-%patch7 -p1 -b .force-randr-update-on-resume
-%patch8 -p1 -b .support-external-monitor-layout
-%patch9 -p1 -b .threaded-swap-wait
-%patch10 -p1 -b .dont-move-sloppy-focus-with-button-pressed
-%patch11 -p1 -b .synaptics-touchpad-configuration
-%patch12 -p1 -b .fix-segfault-on-early-exit
-%patch13 -p1 -b .bgra-buffer-swizzling
-%patch14 -p1 -b .fix-cally-screen-coordinates
-%patch15 -p1 -b .special-case-shaped-java-windows
-%patch16 -p1 -b .unset-source-when-actor-is-destroyed
-%patch17 -p1 -b .keep-OR-windows-on-top
-%patch18 -p1 -b .drop-stray-assert
-
-%patch20 -p1 -b .quad-buffer-stereo
-%patch21 -p1 -b .lower-automake-requirement
-
-%patch22 -p1 -b .add-support-for-plain-old-x-device-configuration
+%autosetup -S git
 
 %build
-autoreconf
+autoreconf -f -i
 (if ! test -x configure; then NOCONFIGURE=1 ./autogen.sh; fi;
- %configure --disable-static --enable-compile-warnings=maximum --disable-wayland-egl-server)
+ %configure --disable-static %{?disable_wayland} --enable-compile-warnings=maximum --with-libwacom)
 
 SHOULD_HAVE_DEFINED="HAVE_SM HAVE_RANDR HAVE_STARTUP_NOTIFICATION"
 
@@ -215,9 +215,69 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
 %{_libdir}/pkgconfig/*
 
 %changelog
-* Tue Oct 10 2017 Rui Matos <rmatos@redhat.com> - 3.22.3-12
+* Fri Feb 23 2018 Carlos Garnacho <cgarnach@redhat.com> - 3.26.2-13
+- Fix pad ring/strip modes
+  Resolves: #1543633
+
+* Mon Feb 19 2018 Carlos Garnacho <cgarnach@redhat.com> - 3.26.2-12
+- Apply settings on current stylus tools instantly
+  Resolves: #1543693
+
+* Wed Feb 14 2018 Jonas Ådahl <jadahl@redhat.com> - 3.26.2-11
+- Fix GPU memory purge error handling
+  Resolves: #1542375
+
+* Tue Feb 13 2018 Carlos Garnacho <cgarnach@redhat.com> - 3.26.2-10
+- Detect CLUTTER_TOUCHPAD_DEVICE on all Synaptics devices
+  Resolves: #1499788
+- Fix tablet pressure curve configuration not being applied
+  Resolves: #1543693
+
+* Tue Feb 13 2018 Ray Strode <rstrode@redhat.com> - 3.26.2-9
+- Fix VNC sessions
+  Resolves: #1543073
+
+* Wed Feb 07 2018 Carlos Garnacho <cgarnach@redhat.com> - 3.26.2-8
+- Avoid XCloseDevice on active XI2 devices
+  Resolves: #1540790
+
+* Wed Feb 07 2018 Florian Müllner <fmuellner@redhat.com> - 3.26.2-7
+- Fix crash during session saving
+  Resolves: #1535080
+- Fix XWayland prevented from starting
+  Resolves: #1540986
+
+* Wed Nov 29 2017 Rui Matos <rmatos@redhat.com> - 3.26.2-6
+- Fix a crash resizing windows while headless
+  Resolves: #1516408
+
+* Wed Nov 29 2017 Rui Matos <rmatos@redhat.com> - 3.26.2-5
+- Fix for certain multi-monitor configurations not being remembered
+  Resolves: #1516404
+
+* Wed Nov 08 2017 Ray Strode <rstrode@redhat.com> - 3.26.2-4
+- Fix crash with screen recorder
+  Resolves: #1508903
+
+* Tue Nov  7 2017 Rui Matos <rmatos@redhat.com> - 3.26.2-3
+- Fix external monitor layout patch to avoid a crash
+- Resolves: #1481386
+
+* Mon Nov  6 2017 Rui Matos <rmatos@redhat.com> - 3.26.2-2
+- Fix stereo patch to fail gracefully on Xwayland
+- Resolves: #1481386
+
+* Fri Nov 03 2017 Kalev Lember <klember@redhat.com> - 3.26.2-1
+- Update to 3.26.2
+- Resolves: #1481386
+
+* Thu Oct 26 2017 Rui Matos <rmatos@redhat.com> - 3.26.1-2
 - Add support for plain old X device configuration
-- Resolves: #1515138
+  Resolves: #1478397
+
+* Fri Oct 06 2017 Florian Müllner <fmuellner@redhat.com> - 3.26.1-1
+- Update to 3.26.1
+  Resolves: #1481386
 
 * Mon Jun 26 2017 Florian Müllner <fmuellner@redhat.com> - 3.24.3-11
 - Prevent crash when removing workspace with on-all-workspaces windows