debian/changelog | 12 ++ debian/patches/xmir.patch | 248 +++++++++++++++++++++++++++++++--------------- 2 files changed, 180 insertions(+), 80 deletions(-)
New commits: commit 858b1addb8c1a46c427a6199d7f631ef79af651e Author: Robert Ancell <robert.anc...@canonical.com> Date: Thu Jul 21 15:17:26 2016 +0200 Update xmir.patch diff --git a/debian/changelog b/debian/changelog index ff9b686..70d2704 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +xorg-server (2:1.18.4-1ubuntu3) yakkety; urgency=medium + + * debian/patches/xmir.patch: + - Fix bottom/right edge corruption. (LP: #1510849) + - Fix key repeat. (LP: #1591356) + - Don't delete outputs without replacing them. (LP: #1504422) (LP: #1602561) + - Xmir -debug: Log WM types by name and number. + - Implement fake GLX frame notification/timing. + - Improve focus tracking. + + -- Robert Ancell <robert.anc...@canonical.com> Thu, 21 Jul 2016 11:42:03 +0200 + xorg-server (2:1.18.4-1ubuntu2) yakkety; urgency=medium * debian/control, debian/rules: diff --git a/debian/patches/xmir.patch b/debian/patches/xmir.patch index e7ff8d7..d4eccf3 100644 --- a/debian/patches/xmir.patch +++ b/debian/patches/xmir.patch @@ -1,4 +1,4 @@ -From eb0fb72f618ea17a90d6c535d38e12b5f95fcec8 Mon Sep 17 00:00:00 2001 +From c93f490c0c560c82ffc2dd3b6095f6e390b0fb81 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 | 551 +++++++++++++++ - 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 | 1622 +++++++++++++++++++++++++++++++++++++++++++ - hw/xmir/xmir.h | 227 ++++++ - 18 files changed, 7803 insertions(+), 2 deletions(-) + hw/xmir/xmir-dri2.c | 551 ++++++++++++++ + hw/xmir/xmir-glamor.c | 1160 +++++++++++++++++++++++++++++ + hw/xmir/xmir-input.c | 595 +++++++++++++++ + hw/xmir/xmir-output.c | 428 +++++++++++ + hw/xmir/xmir-thread-proxy.c | 115 +++ + hw/xmir/xmir.c | 1719 +++++++++++++++++++++++++++++++++++++++++++ + hw/xmir/xmir.h | 230 ++++++ + 18 files changed, 7891 insertions(+), 2 deletions(-) create mode 100644 hw/xmir/.gitignore create mode 100644 hw/xmir/Makefile.am create mode 100644 hw/xmir/dri2/Makefile.am @@ -48,10 +48,10 @@ Contributions from: create mode 100644 hw/xmir/xmir.h diff --git a/configure.ac b/configure.ac -index 77cf234..8bf62a0 100644 +index 868e859..dac8887 100644 --- a/configure.ac +++ b/configure.ac -@@ -628,6 +628,7 @@ AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server +@@ -638,6 +638,7 @@ AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server 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 +59,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 +@@ -756,6 +757,7 @@ case $host_os in XVFB=no XNEST=no XWAYLAND=no @@ -67,7 +67,7 @@ index 77cf234..8bf62a0 100644 COMPOSITE=no DGA=no -@@ -2482,6 +2484,27 @@ if test "x$XWAYLAND" = xyes; then +@@ -2492,6 +2494,27 @@ if test "x$XWAYLAND" = xyes; then [${WAYLAND_PREFIX}/bin$PATH_SEPARATOR$PATH]) fi @@ -95,7 +95,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 +@@ -2640,6 +2663,8 @@ hw/kdrive/fbdev/Makefile hw/kdrive/linux/Makefile hw/kdrive/src/Makefile hw/xwayland/Makefile @@ -4972,10 +4972,10 @@ index 0000000..7ad0245 +} diff --git a/hw/xmir/xmir-input.c b/hw/xmir/xmir-input.c new file mode 100644 -index 0000000..14c4709 +index 0000000..e62e16c --- /dev/null +++ b/hw/xmir/xmir-input.c -@@ -0,0 +1,592 @@ +@@ -0,0 +1,595 @@ +/* + * Copyright © 2015 Canonical Ltd + * @@ -5354,15 +5354,18 @@ 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); ++ if (action == mir_keyboard_action_down || ++ action == mir_keyboard_action_repeat) { ++ QueueKeyboardEvents(xmir_input->keyboard, KeyPress, code); ++ } ++ if (action == mir_keyboard_action_up || ++ action == mir_keyboard_action_repeat) { ++ QueueKeyboardEvents(xmir_input->keyboard, KeyRelease, code); ++ } + break; + } + case mir_input_event_type_touch: { @@ -5570,10 +5573,10 @@ index 0000000..14c4709 +} diff --git a/hw/xmir/xmir-output.c b/hw/xmir/xmir-output.c new file mode 100644 -index 0000000..f538749 +index 0000000..1927215 --- /dev/null +++ b/hw/xmir/xmir-output.c -@@ -0,0 +1,449 @@ +@@ -0,0 +1,428 @@ +/* + * Copyright © 2015 Canonical Ltd + * @@ -5793,9 +5796,6 @@ index 0000000..f538749 + MirDisplayOutput **mir_output; + struct xmir_output *xmir_output; + -+ if (xmir_screen->windowed) -+ return; -+ + new_config = mir_connection_create_display_config(xmir_screen->conn); + if (new_config->num_outputs != xmir_screen->display->num_outputs) + FatalError("Number of outputs changed on update.\n"); @@ -5878,20 +5878,6 @@ index 0000000..f538749 + if (xmir_screen->rootless) + 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)) { -+ struct xmir_output *xmir_output = xorg_list_first_entry(&xmir_screen->output_list, typeof(*xmir_output), link); -+ -+ RRCrtcDestroy(xmir_output->randr_crtc); -+ RROutputDestroy(xmir_output->randr_output); -+ xmir_output_destroy(xmir_output); -+ } -+ } -+ + XMIR_DEBUG(("Output resized %ix%i with rotation %i\n", + width, height, xmir_window->orientation)); + @@ -5924,16 +5910,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; @@ -6025,10 +6007,10 @@ index 0000000..f538749 +} diff --git a/hw/xmir/xmir-thread-proxy.c b/hw/xmir/xmir-thread-proxy.c new file mode 100644 -index 0000000..dbb187f +index 0000000..bfe64f0 --- /dev/null +++ b/hw/xmir/xmir-thread-proxy.c -@@ -0,0 +1,109 @@ +@@ -0,0 +1,115 @@ +/* + * Copyright © 2012-2015 Canonical Ltd + * @@ -6127,23 +6109,29 @@ 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); + } +} ++ ++void ++xmir_process_from_eventloop(void) ++{ ++ xmir_process_from_eventloop_except(NULL); ++} diff --git a/hw/xmir/xmir.c b/hw/xmir/xmir.c new file mode 100644 -index 0000000..ee5fff5 +index 0000000..b0fedfc --- /dev/null +++ b/hw/xmir/xmir.c -@@ -0,0 +1,1622 @@ +@@ -0,0 +1,1719 @@ +/* + * Copyright © 2015 Canonical Ltd + * @@ -6210,19 +6198,21 @@ index 0000000..ee5fff5 + 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; + @@ -6230,6 +6220,12 @@ index 0000000..ee5fff5 + +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 */ @@ -6450,6 +6446,31 @@ index 0000000..ee5fff5 + return 0; +} + ++enum XWMHints_flag { ++ InputHint = 1 ++ /* There are more but not yet required */ ++}; ++ ++struct XWMHints { ++ CARD32 flags; ++ CARD32 input; ++ /* There are more but not yet required */ ++}; ++ ++static struct 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 (struct XWMHints*)&p->data; ++ p = p->next; ++ } ++ } ++ return NULL; ++} ++ +static void +damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) +{ @@ -6522,9 +6543,14 @@ index 0000000..ee5fff5 + 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 @@ -6559,11 +6585,21 @@ index 0000000..ee5fff5 + } +} + ++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; + @@ -6620,14 +6656,12 @@ index 0000000..ee5fff5 + 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: @@ -6671,6 +6705,9 @@ index 0000000..ee5fff5 + 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}; @@ -6688,9 +6725,6 @@ index 0000000..ee5fff5 + */ + } + -+ 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); +} @@ -6698,11 +6732,15 @@ index 0000000..ee5fff5 +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 @@ -6756,6 +6794,8 @@ index 0000000..ee5fff5 + 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; ++ struct XWMHints *wm_hints = NULL; + char wm_name[1024]; + + screen->RealizeWindow = xmir_screen->RealizeWindow; @@ -6789,6 +6829,14 @@ index 0000000..ee5fff5 + (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%x,input=0x%x}\n", ++ wm_hints->flags, wm_hints->input)); ++ } else { ++ XMIR_DEBUG(("\tWM_HINTS=<none>\n")); ++ } ++ + if (!window->viewable) { + return ret; + } else if (xmir_screen->rootless) { @@ -6922,6 +6970,17 @@ index 0000000..ee5fff5 + } + 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)); @@ -7000,16 +7059,23 @@ index 0000000..ee5fff5 + 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) { -+ Window id = (state == mir_surface_focused) ? -+ xmir_window->window->drawable.id : None; -+ SetInputFocus(serverClient, keyboard, id, RevertToParent, CurrentTime, -+ False); ++ const struct XWMHints *hints = ++ xmir_get_window_prop_hints(xmir_window->window); ++ if (!hints || !((hints->flags & InputHint) && !hints->input)) { ++ Window id = (state == mir_surface_focused) ? ++ xmir_window->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 @@ -7237,8 +7303,7 @@ index 0000000..ee5fff5 + 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); +} @@ -7272,6 +7337,9 @@ index 0000000..ee5fff5 + 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); + @@ -7319,6 +7387,8 @@ index 0000000..ee5fff5 + struct xmir_output *xmir_output, *next_xmir_output; + Bool ret; + ++ xmir_screen->closing = TRUE; ++ + if (xmir_screen->glamor && xmir_screen->gbm) + DRI2CloseScreen(screen); + @@ -7723,6 +7793,21 @@ index 0000000..ee5fff5 + xmir_screen->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = xmir_close_screen; + ++ { ++ int v; ++ XMIR_DEBUG(("XMir initialized with %hd visuals:\n", ++ pScreen->numVisuals)); ++ for (v = 0; v < pScreen->numVisuals; ++v) { ++ VisualPtr visual = pScreen->visuals + v; ++ XMIR_DEBUG(("\tVisual id 0x%x: %lx %lx %lx, %hd planes\n", ++ (int)visual->vid, ++ (long)visual->redMask, ++ (long)visual->greenMask, ++ (long)visual->blueMask, ++ visual->nplanes)); ++ } ++ } ++ + return ret; +} + @@ -7768,10 +7853,10 @@ index 0000000..ee5fff5 +} diff --git a/hw/xmir/xmir.h b/hw/xmir/xmir.h new file mode 100644 -index 0000000..310e6b9 +index 0000000..a62a66f --- /dev/null +++ b/hw/xmir/xmir.h -@@ -0,0 +1,227 @@ +@@ -0,0 +1,230 @@ +/* + * Copyright © 2015 Canonical Ltd + * @@ -7827,7 +7912,7 @@ index 0000000..310e6b9 +struct xmir_screen { + ScreenPtr screen; + -+ int depth, rootless, windowed, doubled; ++ int depth, rootless, doubled; + enum {glamor_off=0, glamor_dri, glamor_egl, glamor_egl_sync} glamor; + + CreateScreenResourcesProcPtr CreateScreenResources; @@ -7864,6 +7949,8 @@ index 0000000..310e6b9 + MirPixelFormat depth24_pixel_format, depth32_pixel_format; + Bool flatten; + Bool neverclose; ++ Bool destroying_root; ++ Bool closing; + const char *title; + MirSurface *neverclosed; + struct xorg_list flattened_list; @@ -7989,6 +8076,7 @@ index 0000000..310e6b9 +void xmir_post_to_eventloop(xmir_event_callback *cb, + struct xmir_screen*, struct xmir_window*, void*); +void xmir_process_from_eventloop(void); ++void xmir_process_from_eventloop_except(const struct xmir_window*); + +/* xmir-input.c */ +void xmir_surface_handle_event(MirSurface *surface, MirEvent const* ev, void *context);