debian/changelog          |    8 
 debian/patches/xmir.patch |  477 +++++++++++++++++++++++++++++++---------------
 2 files changed, 330 insertions(+), 155 deletions(-)

New commits:
commit d4889a21e47bc45b56e7f65feda63090fad3336f
Author: Timo Aaltonen <tjaal...@debian.org>
Date:   Wed Sep 14 18:03:32 2016 +0300

    close the microrelease bug

diff --git a/debian/changelog b/debian/changelog
index d59d35d..2e0673d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,6 @@
 xorg-server (2:1.18.4-0ubuntu0.1) xenial; urgency=medium
 
-  * New upstream bugfix release.
+  * New upstream bugfix release. (LP: #1619142)
   * randr-adjust-masters-last-set-time.diff,
     randr-do-not-check-the-screen-size.diff:
     Fix issues changing display mode on prime setups. (LP: #1586260)

commit 5d680c9cc48b471551ab89c43eb69ccefca83769
Author: Timo Aaltonen <tjaal...@debian.org>
Date:   Wed Sep 14 15:41:04 2016 +0300

    add new xmir patch based on yakkety

diff --git a/debian/changelog b/debian/changelog
index b50d00e..d59d35d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -7,6 +7,12 @@ xorg-server (2:1.18.4-0ubuntu0.1) xenial; urgency=medium
   * os-treat-ssh-as-a-non-local-client.diff: Dropped, upstream.
   * drm_device_keep_trying.patch: Dropped, shouldn't be needed anymore,
     and causes issues on non-x86 archs. (LP: #1581076)
+  * debian/patches/xmir.patch: backport XMir fixes from Ubuntu "Yakkety Yak"
+    - fix button/menu focus failures (lp: #1590553)
+    - ignore 'unnkown 11 event' (lp: #1617925)
+    - don't call epoxy every frame (lp: #1617932)
+    - fix unclickable parts of the screen after rotation (lp: #1613708)
+    - fix key repeat issues (lp: #1591356)
 
  -- Timo Aaltonen <tjaal...@debian.org>  Thu, 01 Sep 2016 10:28:26 +0300
 
diff --git a/debian/patches/xmir.patch b/debian/patches/xmir.patch
index 3af0c45..c51aac0 100644
--- a/debian/patches/xmir.patch
+++ b/debian/patches/xmir.patch
@@ -1,4 +1,4 @@
-From d1786a76da403e240abd98f65c95a2d0a242b495 Mon Sep 17 00:00:00 2001
+From 8467ede06b3b40fae1d362d73cfa313737e0defc Mon Sep 17 00:00:00 2001
 From: Robert Ancell <robert.anc...@canonical.com>
 Date: Fri, 29 Apr 2016 14:57:53 +0200
 Subject: [PATCH xserver 1/3] XMir DDX
@@ -16,20 +16,20 @@ Contributions from:
  hw/xmir/.gitignore          |    1 +
  hw/xmir/Makefile.am         |   61 ++
  hw/xmir/dri2/Makefile.am    |   14 +
- hw/xmir/dri2/dri2.c         | 1398 ++++++++++++++++++++++++++++++++++++++
- hw/xmir/dri2/dri2.h         |  364 ++++++++++
- hw/xmir/dri2/dri2ext.c      |  683 +++++++++++++++++++
+ hw/xmir/dri2/dri2.c         | 1398 ++++++++++++++++++++++++++++++++++
+ hw/xmir/dri2/dri2.h         |  364 +++++++++
+ hw/xmir/dri2/dri2ext.c      |  683 +++++++++++++++++
  hw/xmir/dri2/dri2int.h      |   26 +
  hw/xmir/xmir-cursor.c       |  210 ++++++
- hw/xmir/xmir-cvt.c          |  304 +++++++++
- hw/xmir/xmir-dri2.c         |  545 +++++++++++++++
- hw/xmir/xmir-glamor.c       | 1160 ++++++++++++++++++++++++++++++++
- hw/xmir/xmir-input.c        |  592 ++++++++++++++++
- hw/xmir/xmir-output.c       |  449 +++++++++++++
- hw/xmir/xmir-thread-proxy.c |  109 +++
- hw/xmir/xmir.c              | 1571 +++++++++++++++++++++++++++++++++++++++++++
- hw/xmir/xmir.h              |  226 +++++++
- 18 files changed, 7745 insertions(+), 2 deletions(-)
+ hw/xmir/xmir-cvt.c          |  304 ++++++++
+ hw/xmir/xmir-dri2.c         |  551 ++++++++++++++
+ hw/xmir/xmir-glamor.c       | 1164 +++++++++++++++++++++++++++++
+ hw/xmir/xmir-input.c        |  611 +++++++++++++++
+ hw/xmir/xmir-output.c       |  476 ++++++++++++
+ hw/xmir/xmir-thread-proxy.c |  115 +++
+ hw/xmir/xmir.c              | 1729 +++++++++++++++++++++++++++++++++++++++++++
+ hw/xmir/xmir.h              |  232 ++++++
+ 18 files changed, 7971 insertions(+), 2 deletions(-)
  create mode 100644 hw/xmir/.gitignore
  create mode 100644 hw/xmir/Makefile.am
  create mode 100644 hw/xmir/dri2/Makefile.am
@@ -47,11 +47,9 @@ Contributions from:
  create mode 100644 hw/xmir/xmir.c
  create mode 100644 hw/xmir/xmir.h
 
-diff --git a/configure.ac b/configure.ac
-index 77cf234..8bf62a0 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -628,6 +628,7 @@ AC_ARG_ENABLE(xvfb,              
AS_HELP_STRING([--enable-xvfb], [Build Xvfb server
+@@ -633,6 +633,7 @@
  AC_ARG_ENABLE(xnest,                AS_HELP_STRING([--enable-xnest], [Build 
Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
  AC_ARG_ENABLE(xquartz,        AS_HELP_STRING([--enable-xquartz], [Build 
Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
  AC_ARG_ENABLE(xwayland,       AS_HELP_STRING([--enable-xwayland], [Build 
Xwayland server (default: auto)]), [XWAYLAND=$enableval], [XWAYLAND=auto])
@@ -59,7 +57,7 @@ index 77cf234..8bf62a0 100644
  AC_ARG_ENABLE(standalone-xpbproxy, 
AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in 
addition to the one integrated into Xquartz as a separate thread) (default: 
no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
  AC_ARG_ENABLE(xwin,                 AS_HELP_STRING([--enable-xwin], [Build 
XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
  AC_ARG_ENABLE(glamor,         AS_HELP_STRING([--enable-glamor], [Build glamor 
dix module (default: no)]), [GLAMOR=$enableval], [GLAMOR=no])
-@@ -746,6 +747,7 @@ case $host_os in
+@@ -751,6 +752,7 @@
                        XVFB=no
                        XNEST=no
                        XWAYLAND=no
@@ -67,7 +65,7 @@ index 77cf234..8bf62a0 100644
  
                        COMPOSITE=no
                        DGA=no
-@@ -2482,6 +2484,27 @@ if test "x$XWAYLAND" = xyes; then
+@@ -2503,6 +2505,27 @@
                     [${WAYLAND_PREFIX}/bin$PATH_SEPARATOR$PATH])
  fi
  
@@ -95,7 +93,7 @@ index 77cf234..8bf62a0 100644
  
  dnl and the rest of these are generic, so they're in config.h
  dnl 
-@@ -2630,6 +2653,8 @@ hw/kdrive/fbdev/Makefile
+@@ -2651,6 +2674,8 @@
  hw/kdrive/linux/Makefile
  hw/kdrive/src/Makefile
  hw/xwayland/Makefile
@@ -104,11 +102,9 @@ index 77cf234..8bf62a0 100644
  test/Makefile
  test/xi1/Makefile
  test/xi2/Makefile
-diff --git a/hw/Makefile.am b/hw/Makefile.am
-index 19895dc..b7b958c 100644
 --- a/hw/Makefile.am
 +++ b/hw/Makefile.am
-@@ -30,6 +30,10 @@ if XWAYLAND
+@@ -30,6 +30,10 @@
  XWAYLAND_SUBDIRS = xwayland
  endif
  
@@ -119,7 +115,7 @@ index 19895dc..b7b958c 100644
  SUBDIRS =                     \
        $(XORG_SUBDIRS)         \
        $(XWIN_SUBDIRS)         \
-@@ -38,9 +42,10 @@ SUBDIRS =                   \
+@@ -38,9 +42,10 @@
        $(DMX_SUBDIRS)          \
        $(KDRIVE_SUBDIRS)       \
        $(XQUARTZ_SUBDIRS)      \
@@ -132,16 +128,10 @@ index 19895dc..b7b958c 100644
  
  relink:
        $(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; 
done
-diff --git a/hw/xmir/.gitignore b/hw/xmir/.gitignore
-new file mode 100644
-index 0000000..b6a16d4
 --- /dev/null
 +++ b/hw/xmir/.gitignore
 @@ -0,0 +1 @@
 +Xmir
-diff --git a/hw/xmir/Makefile.am b/hw/xmir/Makefile.am
-new file mode 100644
-index 0000000..be5225e
 --- /dev/null
 +++ b/hw/xmir/Makefile.am
 @@ -0,0 +1,61 @@
@@ -206,9 +196,6 @@ index 0000000..be5225e
 +
 +relink:
 +      $(AM_V_at)rm -f Xmir$(EXEEXT) && $(MAKE) Xmir$(EXEEXT)
-diff --git a/hw/xmir/dri2/Makefile.am b/hw/xmir/dri2/Makefile.am
-new file mode 100644
-index 0000000..696240c
 --- /dev/null
 +++ b/hw/xmir/dri2/Makefile.am
 @@ -0,0 +1,14 @@
@@ -226,9 +213,6 @@ index 0000000..696240c
 +      dri2ext.c \
 +      dri2int.h
 +
-diff --git a/hw/xmir/dri2/dri2.c b/hw/xmir/dri2/dri2.c
-new file mode 100644
-index 0000000..6aa19ba
 --- /dev/null
 +++ b/hw/xmir/dri2/dri2.c
 @@ -0,0 +1,1398 @@
@@ -1630,9 +1614,6 @@ index 0000000..6aa19ba
 +    *is_param_recognized = FALSE;
 +    return Success;
 +}
-diff --git a/hw/xmir/dri2/dri2.h b/hw/xmir/dri2/dri2.h
-new file mode 100644
-index 0000000..318898b
 --- /dev/null
 +++ b/hw/xmir/dri2/dri2.h
 @@ -0,0 +1,364 @@
@@ -2000,9 +1981,6 @@ index 0000000..318898b
 +extern Bool noDRI2Extension;
 +
 +#endif
-diff --git a/hw/xmir/dri2/dri2ext.c b/hw/xmir/dri2/dri2ext.c
-new file mode 100644
-index 0000000..befbb82
 --- /dev/null
 +++ b/hw/xmir/dri2/dri2ext.c
 @@ -0,0 +1,683 @@
@@ -2689,9 +2667,6 @@ index 0000000..befbb82
 +
 +    DRI2ModuleSetup();
 +}
-diff --git a/hw/xmir/dri2/dri2int.h b/hw/xmir/dri2/dri2int.h
-new file mode 100644
-index 0000000..7f53eba
 --- /dev/null
 +++ b/hw/xmir/dri2/dri2int.h
 @@ -0,0 +1,26 @@
@@ -2721,9 +2696,6 @@ index 0000000..7f53eba
 + */
 +
 +extern Bool DRI2ModuleSetup(void);
-diff --git a/hw/xmir/xmir-cursor.c b/hw/xmir/xmir-cursor.c
-new file mode 100644
-index 0000000..81873a4
 --- /dev/null
 +++ b/hw/xmir/xmir-cursor.c
 @@ -0,0 +1,210 @@
@@ -2937,9 +2909,6 @@ index 0000000..81873a4
 +                               &xmir_pointer_sprite_funcs,
 +                               &xmir_pointer_screen_funcs, TRUE);
 +}
-diff --git a/hw/xmir/xmir-cvt.c b/hw/xmir/xmir-cvt.c
-new file mode 100644
-index 0000000..6070d77
 --- /dev/null
 +++ b/hw/xmir/xmir-cvt.c
 @@ -0,0 +1,304 @@
@@ -3247,12 +3216,9 @@ index 0000000..6070d77
 +
 +    return RRModeGet(&modeinfo, name);
 +}
-diff --git a/hw/xmir/xmir-dri2.c b/hw/xmir/xmir-dri2.c
-new file mode 100644
-index 0000000..b24d4b9
 --- /dev/null
 +++ b/hw/xmir/xmir-dri2.c
-@@ -0,0 +1,545 @@
+@@ -0,0 +1,551 @@
 +/*
 + * Copyright © 2015 Canonical Ltd
 + *
@@ -3744,10 +3710,16 @@ index 0000000..b24d4b9
 +
 +static int xmir_dri_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
 +{
-+    /* TODO: Implement this?
-+     * At least doing nothing like this is enough to shut up Chromium
-+     * error messages.
-+     */
++    /* TODO: Implement this properly after Mir implements it. */
++    const uint64_t now_us = GetTimeInMicros();
++    const uint64_t fake_frame_rate_hz = 60;
++    const uint64_t fake_frame_time_us = 1000000 / fake_frame_rate_hz;
++    const uint64_t fake_msc = now_us / fake_frame_time_us;
++    const uint64_t fake_ust = fake_msc * fake_frame_time_us;
++    if (ust)
++        *(uint64_t*)ust = fake_ust;
++    if (msc)
++        *(uint64_t*)msc = fake_msc;
 +    return Success;
 +}
 +
@@ -3798,12 +3770,9 @@ index 0000000..b24d4b9
 +    ret = DRI2ScreenInit(xmir_screen->screen, &xmir_screen->dri2);
 +    return ret;
 +}
-diff --git a/hw/xmir/xmir-glamor.c b/hw/xmir/xmir-glamor.c
-new file mode 100644
-index 0000000..7ad0245
 --- /dev/null
 +++ b/hw/xmir/xmir-glamor.c
-@@ -0,0 +1,1160 @@
+@@ -0,0 +1,1164 @@
 +/*
 + * Copyright © 2015 Canonical Ltd
 + *
@@ -4163,7 +4132,8 @@ index 0000000..7ad0245
 +    struct xmir_screen *xmir_screen = xmir_screen_get(src->pScreen);
 +    DebugF("Box: (%i,%i)->(%i,%i)\n", ext->x1, ext->y1, ext->x2, ext->y2);
 +
-+    if (epoxy_has_gl_extension("GL_EXT_framebuffer_blit") && 
!xmir_screen->doubled && !orientation) {
++    if (xmir_screen->glamor_has_GL_EXT_framebuffer_blit &&
++        !xmir_screen->doubled && !orientation) {
 +        glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 
src_pixmap_priv->fbo->fb);
 +
 +        glBlitFramebuffer(ext->x1, ext->y2, ext->x2, ext->y1,
@@ -4642,6 +4612,9 @@ index 0000000..7ad0245
 +        return FALSE;
 +    }
 +
++    xmir_screen->glamor_has_GL_EXT_framebuffer_blit =
++        epoxy_has_gl_extension("GL_EXT_framebuffer_blit");
++
 +    if (!xmir_screen->gbm && xmir_screen->glamor != glamor_egl_sync) {
 +        xmir_screen->swap_context = 
eglCreateContext(xmir_screen->egl_display, egl_config, EGL_NO_CONTEXT, 
gles2_attribs);
 +        if (!xmir_screen->swap_context) {
@@ -4964,12 +4937,9 @@ index 0000000..7ad0245
 +
 +    return TRUE;
 +}
-diff --git a/hw/xmir/xmir-input.c b/hw/xmir/xmir-input.c
-new file mode 100644
-index 0000000..14c4709
 --- /dev/null
 +++ b/hw/xmir/xmir-input.c
-@@ -0,0 +1,592 @@
+@@ -0,0 +1,609 @@
 +/*
 + * Copyright © 2015 Canonical Ltd
 + *
@@ -5014,7 +4984,7 @@ index 0000000..14c4709
 +xmir_pointer_proc(DeviceIntPtr device, int what)
 +{
 +#define NBUTTONS 10
-+#define NAXES 2
++#define NAXES 4
 +    BYTE map[NBUTTONS + 1];
 +    int i = 0;
 +    Atom btn_labels[NBUTTONS] = { 0 };
@@ -5038,8 +5008,10 @@ index 0000000..14c4709
 +
 +        axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
 +        axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
++        axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
++        axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
 +
-+        if (!InitValuatorClassDeviceStruct(device, 2, btn_labels,
++        if (!InitValuatorClassDeviceStruct(device, NAXES, btn_labels,
 +                                           GetMotionHistorySize(), Absolute))
 +            return BadValue;
 +
@@ -5048,6 +5020,13 @@ index 0000000..14c4709
 +                               0, 0xFFFF, 10000, 0, 10000, Absolute);
 +        InitValuatorAxisStruct(device, 1, axes_labels[1],
 +                               0, 0xFFFF, 10000, 0, 10000, Absolute);
++        InitValuatorAxisStruct(device, 2, axes_labels[2],
++                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, 
Relative);
++        InitValuatorAxisStruct(device, 3, axes_labels[3],
++                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, 
Relative);
++
++        SetScrollValuator(device, 2, SCROLL_TYPE_HORIZONTAL, 1.0, 
SCROLL_FLAG_NONE);
++        SetScrollValuator(device, 3, SCROLL_TYPE_VERTICAL, 1.0, 
SCROLL_FLAG_PREFERRED);
 +
 +        if (!InitPtrFeedbackClassDeviceStruct(device, xmir_pointer_control))
 +            return BadValue;
@@ -5192,7 +5171,7 @@ index 0000000..14c4709
 +{
 +    int sx = mir_pointer_event_axis_value(pev, mir_pointer_axis_x);
 +    int sy = mir_pointer_event_axis_value(pev, mir_pointer_axis_y);
-+    int vscroll = 0;
++    float vscroll, hscroll;
 +    ValuatorMask mask;
 +
 +    pointer_ensure_focus(xmir_input, xmir_window, xmir_input->pointer, sx, 
sy);
@@ -5202,17 +5181,17 @@ index 0000000..14c4709
 +    valuator_mask_zero(&mask);
 +    valuator_mask_set(&mask, 0, sx);
 +    valuator_mask_set(&mask, 1, sy);
-+
 +    QueuePointerEvents(xmir_input->pointer, MotionNotify, 0,
 +                       POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
 +
-+    /* Mouse wheel: Moving the wheel is a press+release of button 4/5 */
 +    vscroll = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll);
-+    if (vscroll) {
-+        int button = vscroll < 0 ? 5 : 4;
++    hscroll = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll);
++    if (vscroll || hscroll) {
 +        valuator_mask_zero(&mask);
-+        QueuePointerEvents(xmir_input->pointer, ButtonPress, button, 0, 
&mask);
-+        QueuePointerEvents(xmir_input->pointer, ButtonRelease, button, 0, 
&mask);
++        valuator_mask_set_double(&mask, 3, -vscroll);
++        valuator_mask_set_double(&mask, 2, hscroll);
++        QueuePointerEvents(xmir_input->pointer, MotionNotify, 0,
++                           POINTER_RELATIVE, &mask);
 +    }
 +}
 +
@@ -5348,15 +5327,23 @@ index 0000000..14c4709
 +{
 +    switch (mir_input_event_get_type(ev)) {
 +    case mir_input_event_type_key: {
-+        MirKeyboardEvent const *kev;
-+        MirKeyboardAction action;
++        MirKeyboardEvent const *kev = mir_input_event_get_keyboard_event(ev);
++        MirKeyboardAction action = mir_keyboard_event_action(kev);
++        int code = mir_keyboard_event_scan_code(kev) + 8;
 +
-+        kev = mir_input_event_get_keyboard_event(ev);
-+        action = mir_keyboard_event_action(kev);
-+
-+        QueueKeyboardEvents(xmir_input->keyboard,
-+                            action == mir_keyboard_action_up ? KeyRelease : 
KeyPress,
-+                            mir_keyboard_event_scan_code(kev) + 8);
++        /*
++         * Note: mir_keyboard_action_repeat must KeyRelease then KeyPress
++         * because it is already preceded by mir_keyboard_action_down and will
++         * be followed by mir_keyboard_action_up.
++         */
++        if (action == mir_keyboard_action_up ||
++            action == mir_keyboard_action_repeat) {
++            QueueKeyboardEvents(xmir_input->keyboard, KeyRelease, code);
++        }
++        if (action == mir_keyboard_action_down ||
++            action == mir_keyboard_action_repeat) {
++            QueueKeyboardEvents(xmir_input->keyboard, KeyPress, code);
++        }
 +        break;
 +    }
 +    case mir_input_event_type_touch: {
@@ -5562,12 +5549,9 @@ index 0000000..14c4709
 +
 +    mieqFini();
 +}
-diff --git a/hw/xmir/xmir-output.c b/hw/xmir/xmir-output.c
-new file mode 100644
-index 0000000..f538749
 --- /dev/null
 +++ b/hw/xmir/xmir-output.c
-@@ -0,0 +1,449 @@
+@@ -0,0 +1,476 @@
 +/*
 + * Copyright © 2015 Canonical Ltd
 + *
@@ -5692,8 +5676,8 @@ index 0000000..f538749
 +        /* Odd resolutions like 1366x768 don't show correctly otherwise */
 +        randr_mode->mode.width = mode->horizontal_resolution;
 +        randr_mode->mode.height = mode->vertical_resolution;
-+        sprintf(randr_mode->name, "%dx%d@%.1fHz",
-+                randr_mode->mode.width, randr_mode->mode.height, 
mode->refresh_rate);
++        sprintf(randr_mode->name, "%dx%d",
++                randr_mode->mode.width, randr_mode->mode.height);
 +
 +        RROutputSetPhysicalSize(xmir_output->randr_output, 
mir_output->physical_width_mm, mir_output->physical_height_mm);
 +        RROutputSetModes(xmir_output->randr_output, &randr_mode, 1, 1);
@@ -5714,6 +5698,33 @@ index 0000000..f538749
 +}
 +
 +static void
++xmir_screen_update_windowed_output(struct xmir_screen *xmir_screen)
++{
++    struct xmir_output *xmir_output = xmir_screen->windowed;
++    RRModePtr randr_mode;
++
++    RROutputSetConnection(xmir_output->randr_output, RR_Connected);
++    RROutputSetSubpixelOrder(xmir_output->randr_output, SubPixelUnknown);
++
++    xmir_output->width = xmir_screen->screen->width;
++    xmir_output->height = xmir_screen->screen->height;
++    xmir_output->x = 0;
++    xmir_output->y = 0;
++
++    randr_mode = xmir_cvt(xmir_output->width, xmir_output->height, 60, 0, 0);
++    randr_mode->mode.width = xmir_output->width;
++    randr_mode->mode.height = xmir_output->height;
++    sprintf(randr_mode->name, "%dx%d",
++            randr_mode->mode.width, randr_mode->mode.height);
++
++    RROutputSetPhysicalSize(xmir_output->randr_output, 0, 0);
++    RROutputSetModes(xmir_output->randr_output, &randr_mode, 1, 1);
++    RRCrtcNotify(xmir_output->randr_crtc, randr_mode,
++                 xmir_output->x, xmir_output->y,
++                 RR_Rotate_0, NULL, 1, &xmir_output->randr_output);
++}
++
++static void
 +xmir_output_screen_resized(struct xmir_screen *xmir_screen)
 +{
 +    ScreenPtr screen = xmir_screen->screen;
@@ -5736,15 +5747,15 @@ index 0000000..f538749
 +    update_desktop_dimensions();
 +}
 +
-+static void
-+xmir_output_create(struct xmir_screen *xmir_screen, MirDisplayOutput 
*mir_output, const char *name)
++static struct xmir_output*
++xmir_output_create(struct xmir_screen *xmir_screen, const char *name)
 +{
 +    struct xmir_output *xmir_output;
 +
 +    xmir_output = calloc(sizeof *xmir_output, 1);
 +    if (xmir_output == NULL) {
 +        FatalError("No memory for creating output\n");
-+        return;
++        return NULL;
 +    }
 +
 +    xmir_output->xmir_screen = xmir_screen;
@@ -5754,8 +5765,7 @@ index 0000000..f538749
 +    RRCrtcGammaSetSize(xmir_output->randr_crtc, 256);
 +    RROutputSetCrtcs(xmir_output->randr_output, &xmir_output->randr_crtc, 1);
 +    xorg_list_append(&xmir_output->link, &xmir_screen->output_list);
-+    if (mir_output)
-+        xmir_output_update(xmir_output, mir_output);
++    return xmir_output;
 +}
 +
 +void
@@ -5873,8 +5883,6 @@ index 0000000..f538749
 +        return;
 +
 +    if (!xmir_screen->windowed) {
-+        xmir_screen->windowed = 1;
-+
 +        XMIR_DEBUG(("Root resized, removing all outputs and inserting fake 
output\n"));
 +
 +        while (!xorg_list_is_empty(&xmir_screen->output_list)) {
@@ -5884,6 +5892,8 @@ index 0000000..f538749
 +            RROutputDestroy(xmir_output->randr_output);
 +            xmir_output_destroy(xmir_output);
 +        }
++
++        xmir_screen->windowed = xmir_output_create(xmir_screen, "Windowed");
 +    }
 +
 +    XMIR_DEBUG(("Output resized %ix%i with rotation %i\n",
@@ -5918,16 +5928,12 @@ index 0000000..f538749
 +        int y;
 +        for (y = copy_box.y1; y < copy_box.y2; ++y) {
 +            memcpy(dst, src, line_len);
-+            /* Bother filling the edges?
 +            memset(dst+line_len, 0, dst_stride-line_len);
-+            */
 +            src += src_stride;
 +            dst += dst_stride;
 +        }
-+        /* Bother filling the edges?
 +        if (y < window_height)
 +            memset(dst, 0, (window_height - y) * dst_stride);
-+        */
 +    }
 +
 +    screen->width = window_width;
@@ -5937,7 +5943,7 @@ index 0000000..f538749
 +
 +    screen->SetScreenPixmap(pixmap);
 +
-+    SetRootClip(screen, TRUE);
++    SetRootClip(screen, ROOT_CLIP_FULL);
 +
 +    box.x1 = box.y1 = 0;
 +    box.x2 = window_width;
@@ -5957,6 +5963,7 @@ index 0000000..f538749
 +        miPointerSetScreen(pDev, 0, x, y);
 +    }
 +
++    xmir_screen_update_windowed_output(xmir_screen);
 +    if (ConnectionInfo)
 +        RRScreenSizeNotify(xmir_screen->screen);
 +    update_desktop_dimensions();
@@ -5996,6 +6003,7 @@ index 0000000..f538749
 +    for (i = 0; i < display_config->num_outputs; i++) {
 +        char name[32];
 +        MirDisplayOutput *mir_output = &display_config->outputs[i];
++        struct xmir_output *xmir_output;
 +        const char* output_type_str = xmir_get_output_type_str(mir_output);
 +        int type_count = i;
 +
@@ -6003,7 +6011,10 @@ index 0000000..f538749
 +            type_count = output_type_count[mir_output->type]++;
 +
 +        snprintf(name, sizeof name, "%s-%d", output_type_str, type_count);
-+        xmir_output_create(xmir_screen, mir_output, name);
++        xmir_output = xmir_output_create(xmir_screen, name);
++        if (!xmir_output)
++            return FALSE;
++        xmir_output_update(xmir_output, mir_output);
 +    }
 +
 +    RRScreenSetSizeRange(xmir_screen->screen, 320, 200, INT16_MAX, INT16_MAX);
@@ -6017,12 +6028,9 @@ index 0000000..f538749
 +
 +    return TRUE;
 +}
-diff --git a/hw/xmir/xmir-thread-proxy.c b/hw/xmir/xmir-thread-proxy.c
-new file mode 100644
-index 0000000..dbb187f
 --- /dev/null
 +++ b/hw/xmir/xmir-thread-proxy.c
-@@ -0,0 +1,109 @@
+@@ -0,0 +1,115 @@
 +/*
 + * Copyright © 2012-2015 Canonical Ltd
 + *
@@ -6121,23 +6129,26 @@ index 0000000..dbb187f
 +}
 +
 +void
-+xmir_process_from_eventloop(void)
++xmir_process_from_eventloop_except(const struct xmir_window *w)
 +{
 +    for (;;) {
 +        struct message msg;
 +        ssize_t got = read(pipefds[0], &msg, sizeof msg);
 +        if (got < 0)
 +            return;
-+        if (got == sizeof(msg))
++        if (got == sizeof(msg) && w != msg.xmir_window)
 +            msg.callback(msg.xmir_screen, msg.xmir_window, msg.arg);
 +    }
 +}
-diff --git a/hw/xmir/xmir.c b/hw/xmir/xmir.c
-new file mode 100644
-index 0000000..34f78c9
++
++void
++xmir_process_from_eventloop(void)
++{
++    xmir_process_from_eventloop_except(NULL);
++}
 --- /dev/null
 +++ b/hw/xmir/xmir.c
-@@ -0,0 +1,1571 @@
+@@ -0,0 +1,1729 @@
 +/*
 + * Copyright © 2015 Canonical Ltd
 + *
@@ -6204,19 +6215,21 @@ index 0000000..34f78c9
 +    Atom _NET_WM_WINDOW_TYPE_COMBO;
 +    Atom _NET_WM_WINDOW_TYPE_DND;
 +    Atom _NET_WM_WINDOW_TYPE_NORMAL;
++    Atom _MIR_WM_PERSISTENT_ID;
 +} known_atom;
 +
-+static Atom get_atom(const char *name, Atom *cache)
++static Atom get_atom(const char *name, Atom *cache, Bool create)
 +{
 +    if (!*cache) {
-+        *cache = MakeAtom(name, strlen(name), False);
++        *cache = MakeAtom(name, strlen(name), create);
 +        if (*cache)
 +            XMIR_DEBUG(("Atom %s = %lu\n", name, (unsigned long)*cache));
 +    }
 +    return *cache;
 +}
 +
-+#define GET_ATOM(_a) get_atom(#_a, &known_atom._a)
++#define GET_ATOM(_a)  get_atom(#_a, &known_atom._a, False)
++#define MAKE_ATOM(_a) get_atom(#_a, &known_atom._a, True)
 +
 +extern __GLXprovider __glXDRI2Provider;
 +
@@ -6224,6 +6237,12 @@ index 0000000..34f78c9
 +
 +static const char get_title_from_top_window[] = "@";
 +
++struct xmir_swap {
++    int server_generation;
++    struct xmir_screen *xmir_screen;
++    struct xmir_window *xmir_window;
++};
++
 +static void xmir_handle_buffer_received(MirBufferStream *stream, void *ctx);
 +
 +/* Required by GLX module */
@@ -6273,9 +6292,7 @@ index 0000000..34f78c9
 +{
 +    ErrorF("-rootless              Run rootless\n");
 +    ErrorF("  -flatten             Flatten rootless X windows into a single 
surface\n");
-+    ErrorF("                       (Unity8 requires -flatten; LP: 
#1497085)\n");
 +    ErrorF("    -neverclose        Never close the flattened rootless 
window\n");
-+    ErrorF("                       (ugly workaround for Unity8 bug LP: 
#1501346)\n");
 +    ErrorF("-title <name>          Set window title (@ = automatic)\n");
 +    ErrorF("-sw                    disable glamor rendering\n");
 +    ErrorF("-egl                   force use of EGL calls, disables DRI2 
pass-through\n");
@@ -6444,6 +6461,38 @@ index 0000000..34f78c9
 +    return 0;
 +}
 +
++enum XWMHints_flag {
++    InputHint = 1
++    /* There are more but not yet required */
++};
++
++typedef struct {
++    long flags;     /* marks which fields in this structure are defined */
++    Bool input;     /* does this application rely on the window manager to
++                       get keyboard input? */
++    int initial_state;      /* see below */
++    Pixmap icon_pixmap;     /* pixmap to be used as icon */
++    Window icon_window;     /* window to be used as icon */
++    int icon_x, icon_y;     /* initial position of icon */
++    Pixmap icon_mask;       /* icon mask bitmap */
++    XID window_group;       /* id of related window group */
++    /* this structure may be extended in the future */
++} XWMHints;
++
++static XWMHints*
++xmir_get_window_prop_hints(WindowPtr window)
++{
++    if (window->optional) {
++        PropertyPtr p = window->optional->userProps;
++        while (p) {
++            if (p->propertyName == XA_WM_HINTS)
++                return (XWMHints*)p->data;
++            p = p->next;
++        }
++    }
++    return NULL;
++}
++
 +static void
 +damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
 +{
@@ -6516,9 +6565,14 @@ index 0000000..34f78c9
 +    line_len = (x2 - x1) * bpp;
 +    for (y = y1; y < y2; ++y) {
 +        memcpy(dst, src, line_len);
++        if (x2 < region.width)
++            memset(dst+x2*bpp, 0, (region.width - x2)*bpp);
 +        src += src_stride;
 +        dst += region.stride;
 +    }
++
++    if (y2 < region.height)
++        memset(dst, 0, (region.height - y2)*region.stride);
 +}
 +
 +static void
@@ -6553,11 +6607,21 @@ index 0000000..34f78c9
 +    }
 +}
 +
++static void
++xmir_swap(struct xmir_screen *xmir_screen, struct xmir_window *xmir_win)
++{
++    MirBufferStream *stream = 
mir_surface_get_buffer_stream(xmir_win->surface);
++    struct xmir_swap *swap = calloc(sizeof(struct xmir_swap), 1);
++    swap->server_generation = serverGeneration;
++    swap->xmir_screen = xmir_screen;
++    swap->xmir_window = xmir_win;
++    mir_buffer_stream_swap_buffers(stream, xmir_handle_buffer_received, swap);
++}
++
 +void xmir_repaint(struct xmir_window *xmir_win)
 +{
 +    struct xmir_screen *xmir_screen = 
xmir_screen_get(xmir_win->window->drawable.pScreen);
 +    RegionPtr dirty = &xmir_win->region;
-+    MirBufferStream *stream = 
mir_surface_get_buffer_stream(xmir_win->surface);
 +    char wm_name[256];
 +    WindowPtr named = NULL;
 +
@@ -6614,14 +6678,12 @@ index 0000000..34f78c9
 +    case glamor_off:
 +        xmir_sw_copy(xmir_screen, xmir_win, dirty);
 +        xmir_win->has_free_buffer = FALSE;
-+        mir_buffer_stream_swap_buffers(stream, xmir_handle_buffer_received,
-+                                       xmir_win);
++        xmir_swap(xmir_screen, xmir_win);
 +        break;
 +    case glamor_dri:
 +        xmir_glamor_copy(xmir_screen, xmir_win, dirty);
 +        xmir_win->has_free_buffer = FALSE;
-+        mir_buffer_stream_swap_buffers(stream, xmir_handle_buffer_received,
-+                                       xmir_win);
++        xmir_swap(xmir_screen, xmir_win);
 +        break;
 +    case glamor_egl:
 +    case glamor_egl_sync:
@@ -6665,6 +6727,9 @@ index 0000000..34f78c9
 +    xclient_lagging = buf_width != xmir_win->window->drawable.width ||
 +                      buf_height != xmir_win->window->drawable.height;
 +
++    if (xserver_lagging || !xorg_list_is_empty(&xmir_win->link_damage))
++        xmir_repaint(xmir_win);
++
 +    if (xclient_lagging) {
 +        if (xmir_screen->rootless) {
 +            XID vlist[2] = {buf_width, buf_height};
@@ -6682,9 +6747,6 @@ index 0000000..34f78c9
 +         */
 +    }
 +
-+    if (xserver_lagging || !xorg_list_is_empty(&xmir_win->link_damage))
-+        xmir_repaint(xmir_win);
-+
 +    if (xserver_lagging)
 +        DamageDamageRegion(&xmir_win->window->drawable, &xmir_win->region);
 +}
@@ -6692,11 +6754,15 @@ index 0000000..34f78c9
 +static void
 +xmir_handle_buffer_received(MirBufferStream *stream, void *ctx)
 +{
-+    struct xmir_window *xmir_win = ctx;
-+    struct xmir_screen *xmir_screen = 
xmir_screen_get(xmir_win->window->drawable.pScreen);
++    struct xmir_swap *swap = ctx;
++    struct xmir_screen *xmir_screen = swap->xmir_screen;
 +
-+    xmir_post_to_eventloop(xmir_handle_buffer_available, xmir_screen,
-+                           xmir_win, 0);
++    if (swap->server_generation == serverGeneration && !xmir_screen->closing) 
{
++        xmir_post_to_eventloop(xmir_handle_buffer_available, xmir_screen,
++                               swap->xmir_window, 0);
++    }
++
++    free(swap);
 +}
 +
 +static Bool
@@ -6750,6 +6816,8 @@ index 0000000..34f78c9
 +    int mir_height = window->drawable.height / (1 + xmir_screen->doubled);
 +    MirSurfaceSpec* spec = NULL;
 +    WindowPtr wm_transient_for = NULL, positioning_parent = NULL;
++    MirPersistentId *persistent_id = NULL;
++    XWMHints *wm_hints = NULL;
 +    char wm_name[1024];
 +
 +    screen->RealizeWindow = xmir_screen->RealizeWindow;
@@ -6768,17 +6836,28 @@ index 0000000..34f78c9
 +    wm_type = xmir_get_window_prop_atom(window, 
GET_ATOM(_NET_WM_WINDOW_TYPE));
 +    wm_transient_for = xmir_get_window_prop_window(window, 
XA_WM_TRANSIENT_FOR);
 +
-+    XMIR_DEBUG(("Realize %swindow %p \"%s\": %dx%d %+d%+d parent=%p\n"
++    XMIR_DEBUG(("Realize %swindow %p id=0x%x \"%s\": %dx%d %+d%+d parent=%p\n"
 +           "\tdepth=%d redir=%u type=%hu class=%u visibility=%u viewable=%u\n"
-+           "\toverride=%d _NET_WM_WINDOW_TYPE=%lu WM_TRANSIENT_FOR=%p\n",
++           "\toverride=%d _NET_WM_WINDOW_TYPE=%lu(%s)\n"
++           "\tWM_TRANSIENT_FOR=%p\n",
 +           window == screen->root ? "ROOT " : "",
-+           window, wm_name, mir_width, mir_height,
++           window, (int)window->drawable.id, wm_name, mir_width, mir_height,
 +           window->drawable.x, window->drawable.y,
 +           window->parent,
 +           window->drawable.depth,
 +           window->redirectDraw, window->drawable.type,
 +           window->drawable.class, window->visibility, window->viewable,
-+           window->overrideRedirect, (unsigned long)wm_type, 
wm_transient_for));
++           window->overrideRedirect,
++           (unsigned long)wm_type, NameForAtom(wm_type)?:"",
++           wm_transient_for));
++
++    wm_hints = xmir_get_window_prop_hints(window);
++    if (wm_hints) {
++        XMIR_DEBUG(("\tWM_HINTS={flags=0x%lx,input=%s}\n",
++                    wm_hints->flags, wm_hints->input?"True":"False"));
++    } else {
++        XMIR_DEBUG(("\tWM_HINTS=<none>\n"));
++    }
 +
 +    if (!window->viewable) {
 +        return ret;
@@ -6913,6 +6992,17 @@ index 0000000..34f78c9
 +    }
 +    mir_surface_spec_release(spec);
 +
++    persistent_id =
++        mir_surface_request_persistent_id_sync(xmir_window->surface);
++    if (mir_persistent_id_is_valid(persistent_id)) {
++        const char *str = mir_persistent_id_as_string(persistent_id);
++        dixChangeWindowProperty(serverClient, window,
++                                MAKE_ATOM(_MIR_WM_PERSISTENT_ID),
++                                XA_STRING, 8, PropModeReplace,
++                                strlen(str), (void*)str, FALSE);
++    }
++    mir_persistent_id_release(persistent_id);
++
 +    xmir_window->has_free_buffer = TRUE;
 +    if (!mir_surface_is_valid(xmir_window->surface)) {
 +        ErrorF("failed to create a surface: %s\n", 
mir_surface_get_error_message(xmir_window->surface));
@@ -6970,6 +7060,66 @@ index 0000000..34f78c9
 +    }
 +}
 +
++static Window
++xmir_get_current_input_focus(DeviceIntPtr kbd)
++{
++    Window id = None;
++    FocusClassPtr focus = kbd->focus;
++    if (focus->win == NoneWin)
++        id = None;
++    else if (focus->win == PointerRootWin)
++        id = PointerRoot;
++    else
++        id = focus->win->drawable.id;
++    return id;
++}
++
++static void
++xmir_handle_focus_event(struct xmir_window *xmir_window,
++                        MirSurfaceFocusState state)
++{
++    struct xmir_screen *xmir_screen = xmir_window->xmir_screen;
++    DeviceIntPtr keyboard = inputInfo.keyboard; 
/*PickKeyboard(serverClient);*/
++
++    if (xmir_screen->destroying_root)
++        return;
++
++    if (xmir_window->surface) {  /* It's a real Mir window */
++        xmir_screen->last_focus = (state == mir_surface_focused) ?
++                                  xmir_window->window : NULL;
++    }
++
++    if (xmir_screen->rootless) {
++        WindowPtr window = xmir_window->window;
++        const XWMHints *hints = xmir_get_window_prop_hints(window);
++        Bool refuse_focus = window->overrideRedirect ||
++            (hints && (hints->flags & InputHint) && !hints->input);
++        if (!refuse_focus) {
++            Window id = (state == mir_surface_focused) ?
++                        window->drawable.id : None;
++            SetInputFocus(serverClient, keyboard, id, RevertToParent,
++                          CurrentTime, False);
++        }
++    } else if (!strcmp(xmir_screen->title, get_title_from_top_window)) {
++        /*
++         * So as to not break default behaviour, we only hack focus within
++         * the root window when in Unity8 invasive mode (-title @).
++         */
++        Window id = None;
++        if (state == mir_surface_focused) {
++            id = xmir_screen->saved_focus;
++            if (id == None)
++                id = PointerRoot;
++        } else {
++            xmir_screen->saved_focus = xmir_get_current_input_focus(keyboard);
++            id = None;
++        }
++        SetInputFocus(serverClient, keyboard, id, RevertToNone, CurrentTime,
++                      False);
++    }
++    /* else normal root window mode -- Xmir does not interfere in focus */
++}
++
 +void
 +xmir_handle_surface_event(struct xmir_window *xmir_window, MirSurfaceAttrib 
attr, int val)
 +{
@@ -6985,10 +7135,7 @@ index 0000000..34f78c9
 +        break;
 +    case mir_surface_attrib_focus:
 +        XMIR_DEBUG(("Focus: %s\n", xmir_surface_focus_str(val)));
-+        if (xmir_window->surface) {  /* It's a real Mir window */
-+            xmir_window->xmir_screen->last_focus =
-+                (val == mir_surface_focused) ? xmir_window->window : NULL;
-+        }
++        xmir_handle_focus_event(xmir_window, (MirSurfaceFocusState)val);
 +        break;
 +    case mir_surface_attrib_dpi:
 +        XMIR_DEBUG(("DPI: %i\n", val));
@@ -7180,8 +7327,7 @@ index 0000000..34f78c9
 +        xmir_window->surface = NULL;
 +    }
 +
-+    /* drain all events from input and damage to prevent a race condition 
after mir_surface_release_sync */
-+    xmir_process_from_eventloop();
++    xmir_process_from_eventloop_except(xmir_window);
 +
 +    RegionUninit(&xmir_window->region);
 +}
@@ -7215,6 +7361,9 @@ index 0000000..34f78c9
 +    struct xmir_screen *xmir_screen = xmir_screen_get(screen);
 +    Bool ret;
 +
++    if (!window->parent)
++        xmir_screen->destroying_root = TRUE;
++
 +    xmir_unmap_input(xmir_screen, window);
 +    xmir_unmap_surface(xmir_screen, window, TRUE);
 +
@@ -7262,6 +7411,8 @@ index 0000000..34f78c9
 +    struct xmir_output *xmir_output, *next_xmir_output;
 +    Bool ret;
 +
++    xmir_screen->closing = TRUE;
++
 +    if (xmir_screen->glamor && xmir_screen->gbm)
 +        DRI2CloseScreen(screen);
 +
@@ -7571,11 +7722,14 @@ index 0000000..34f78c9
 +        return FALSE;
 +    }
 +
-+    /* Core DPI cannot report correct values (it's one value, we have 
multiple displays)
-+     * Use the value from the -dpi commandline if set, or 96 otherwise.
++    /*
++     * Core DPI cannot report correct values (it's one value and we might have
++     * multiple displays). Use the value from the -dpi command line if set, or
++     * 96 otherwise.
 +     *
-+     * This matches the behaviour of all the desktop Xorg drivers. Clients 
which
-+     * care can use the XRANDR extension to get correct per-output DPI 
information.
++     * This matches the behaviour of all the desktop Xorg drivers. Clients
++     * which care can use the XRandR extension to get correct per-output DPI
++     * information.
 +     */
 +    xmir_screen->dpi = monitorResolution > 0 ? monitorResolution : 96;
 +
@@ -7666,6 +7820,21 @@ index 0000000..34f78c9
 +    xmir_screen->CloseScreen = pScreen->CloseScreen;

Reply via email to