From 1095c262502332bc570a9b288b01da51c1fa10ec Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Fri, 6 Jun 2014 17:54:22 -0700 Subject: [PATCH 01/40] config: show default path in help for --with-xkb-bin-directory Now shows: --with-xkb-bin-directory=DIR Directory containing xkbcomp program (default: ${bindir}) Signed-off-by: Alan Coopersmith Reviewed-by: Peter Hutterer Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0a6e77255..dabebb9b8 100644 --- a/configure.ac +++ b/configure.ac @@ -1424,7 +1424,7 @@ AC_DEFINE(SHAPE, 1, [Support SHAPE extension]) AC_DEFINE_DIR(XKB_BASE_DIRECTORY, XKBPATH, [Path to XKB data]) AC_ARG_WITH(xkb-bin-directory, - AS_HELP_STRING([--with-xkb-bin-directory=DIR], [Directory containing xkbcomp program]), + AS_HELP_STRING([--with-xkb-bin-directory=DIR], [Directory containing xkbcomp program (default: ${bindir})]), [XKB_BIN_DIRECTORY="$withval"], [XKB_BIN_DIRECTORY="$bindir"]) From 3778fab34bc00334edec4f845d0c6d43440f265a Mon Sep 17 00:00:00 2001 From: Markus Wick Date: Wed, 14 May 2014 23:08:17 +0200 Subject: [PATCH 02/40] glamor: Fix no-mipmap allocations With GL_TEXTURE_MIN_FILTER, we configure not to use mipmaps, but there's no real way until GL_ARB_texture_storage to dictate whether memory should be allocated for mipmap levels or not. GL_TEXTURE_MAX_LEVEL is a stronger hint to the driver than the filtering that we really don't want mipmap allocations. Stops VARM wasting warnings from the nvidia driver. Signed-off-by: Markus Wick Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_fbo.c | 1 + glamor/glamor_font.c | 1 + glamor/glamor_pixmap.c | 1 + 3 files changed, 3 insertions(+) diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index 552168381..090dfd8e7 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -347,6 +347,7 @@ _glamor_create_tex(glamor_screen_private *glamor_priv, glamor_make_current(glamor_priv); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c index f747d59a1..57c607dc2 100644 --- a/glamor/glamor_font.c +++ b/glamor/glamor_font.c @@ -95,6 +95,7 @@ glamor_font_get(ScreenPtr screen, FontPtr font) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 54b414bc2..789d3772e 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -717,6 +717,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex, } glBindTexture(GL_TEXTURE_2D, *tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); From 8da1e4e2bf28c3610cdbe1770a57be89578d37f5 Mon Sep 17 00:00:00 2001 From: Markus Wick Date: Wed, 14 May 2014 23:08:18 +0200 Subject: [PATCH 03/40] glamor: Choose max fbo size by texture + viewport size The max size of renderbuffers and texture often match by accident, but as we always use textures, we should check for the right flag. Also check for viewport size as this may be lower and we want to render to almost every pixmap. Signed-off-by: Markus Wick Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- glamor/glamor.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 08f6ba174..c398807f1 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -316,6 +316,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) { glamor_screen_private *glamor_priv; int gl_version; + int max_viewport_size; #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); @@ -406,7 +407,9 @@ glamor_init(ScreenPtr screen, unsigned int flags) epoxy_has_gl_extension("GL_ARB_map_buffer_range"); glamor_priv->has_buffer_storage = epoxy_has_gl_extension("GL_ARB_buffer_storage"); - glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size); + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &max_viewport_size); + glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size); #ifdef MAX_FBO_SIZE glamor_priv->max_fbo_size = MAX_FBO_SIZE; #endif From a11bbd875f3f90a3d02d727778cb1d3524cf59fd Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 30 May 2014 10:39:30 -0700 Subject: [PATCH 04/40] glamor: Don't leak a prepare_access_gc() in putimage fallbacks. It turns out putimage doesn't use the GC tile or stipple anyway, so there's no need to do this. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_image.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c index 4791d089f..b38b41212 100644 --- a/glamor/glamor_image.c +++ b/glamor/glamor_image.c @@ -88,8 +88,7 @@ static void glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && - glamor_prepare_access_gc(gc)) + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); glamor_finish_access(drawable); } From 382ff4a306b97b0ddcdac03ce8611b026ca5323b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Jun 2014 15:50:48 -0700 Subject: [PATCH 05/40] present: Remove executing vblank from window list. Bug# 79709. Once the vblank is actually getting executed, it's lifetime is no longer tied to the window, and so it shouldn't be controlled by window destruction. In particular, if the vblank is queued for flip, it will get stored in the flip_pending field, and will be correctly destroyed when the flip completes. Signed-off-by: Keith Packard --- present/present.c | 1 + 1 file changed, 1 insertion(+) diff --git a/present/present.c b/present/present.c index 1bf3a5865..165860af8 100644 --- a/present/present.c +++ b/present/present.c @@ -578,6 +578,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) } xorg_list_del(&vblank->event_queue); + xorg_list_del(&vblank->window_list); vblank->queued = FALSE; if (vblank->pixmap && vblank->window) { From d90b5f83010248be65b2039b0b2d0b9e6a4e93cf Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 30 May 2014 09:56:37 +1000 Subject: [PATCH 06/40] dix: fix up coordinate scaling when external monitors are present The goal of all this is to get an x/y motion reflecting the motion on the device, i.e. a circle on the device is a circle on the screen. This is currently done by scaling the y coordinate depending on the screen ratio vs device ratio. Depending on that ratio the movement on the y axis may be accelerated (ratio < 1) or slowed (ratio > 1). This leads to the weird effect that changing the screen ratio by plugging a new monitor changes the speed of the touchpad. Use a different algorithm: calculate the physical movement on the device, map that to the same-ish distance on the screen, then convert that back into a device-specific vector. This way we get the same mapping regardless of the current screen dimensions. Since the pointer accel code doesn't take device resolution into account, make sure we apply our crazy mapping before we accelerate. This way we accelerate resolution-independent. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- dix/getevents.c | 80 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index ffa89fad2..d68fa96d7 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -770,27 +770,65 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl } +/* FIXME: relative events from devices with absolute axis ranges is + fundamentally broken. We map the device coordinate range into the screen + range, but don't really account for device resolution in that. + + what we do here is a hack to make touchpads usable. for a given relative + motion vector in device coordinates: + 1. calculate physical movement on the device in metres + 2. calculate pixel vector that is the same physical movement on the + screen (times some magic number to provide sensible base speed) + 3. calculate what percentage this vector is of the current screen + width/height + 4. calculate equivalent vector in % on the device's min/max axis range + 5. Use that device vector as the actual motion vector + + e.g. 10/50mm on the device, 10/50mm on the screen are 30/100 pixels, + 30/100 pixels are 1/3% of the width, 1/3% of the device is a vector of + 20/80 -> use 20/80 as dx/dy. + + dx/dy is then applied to the current position in device coordinates, + mapped to screen coordinates and thus the movement on the screen reflects + the motion direction on the device. + */ static void scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask) { - double y; + double x, y; ValuatorClassPtr v = dev->valuator; int xrange = v->axes[0].max_value - v->axes[0].min_value + 1; int yrange = v->axes[1].max_value - v->axes[1].min_value + 1; - double screen_ratio = 1.0 * screenInfo.width/screenInfo.height; - double device_ratio = 1.0 * xrange/yrange; - double resolution_ratio = 1.0; - double ratio; + /* Assume 100 units/m for devices without resolution */ + int xres = 100000, yres = 100000; - if (!valuator_mask_fetch_double(mask, 1, &y)) - return; + /* If we have multiple screens with different dpi, it gets complicated: + we have to map which screen we're on and then take the dpi of that + screen to be somewhat accurate. */ + const ScreenPtr s = screenInfo.screens[0]; + const double screen_res = 1000.0 * s->width/s->mmWidth; /* units/m */ - if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0) - resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution; + /* some magic multiplier, so unaccelerated movement of x mm on the + device reflects x * magic mm on the screen */ + const double magic = 4; - ratio = device_ratio/resolution_ratio/screen_ratio; - valuator_mask_set_double(mask, 1, y / ratio); + if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0) { + xres = v->axes[0].resolution; + yres = v->axes[1].resolution; + } + + if (valuator_mask_isset(mask, 0)) { + x = valuator_mask_get_double(mask, 0); + x = magic * x/xres * screen_res/screenInfo.width * xrange; + valuator_mask_set_double(mask, 0, x); + } + + if (valuator_mask_isset(mask, 1)) { + y = valuator_mask_get_double(mask, 1); + y = magic * y/yres * screen_res/screenInfo.height * yrange; + valuator_mask_set_double(mask, 1, y); + } } /** @@ -804,15 +842,6 @@ moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask) { int i; Bool clip_xy = IsMaster(dev) || !IsFloating(dev); - ValuatorClassPtr v = dev->valuator; - - /* for abs devices in relative mode, we've just scaled wrong, since we - mapped the device's shape into the screen shape. Undo this. */ - if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 && - v->axes[0].min_value < v->axes[0].max_value && - v->axes[1].min_value < v->axes[1].max_value) { - scale_for_device_resolution(dev, mask); - } /* calc other axes, clip, drop back into valuators */ for (i = 0; i < valuator_mask_size(mask); i++) { @@ -1441,10 +1470,21 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, set_raw_valuators(raw, &mask, raw->valuators.data); } else { + ValuatorClassPtr v = pDev->valuator; + transformRelative(pDev, &mask); + /* for abs devices in relative mode, we've just scaled wrong, since we + mapped the device's shape into the screen shape. Undo this. */ + if (v && v->numAxes > 1 && + v->axes[0].min_value < v->axes[0].max_value && + v->axes[1].min_value < v->axes[1].max_value) { + scale_for_device_resolution(pDev, &mask); + } + if (flags & POINTER_ACCELERATE) accelPointer(pDev, &mask, ms); + if ((flags & POINTER_NORAW) == 0 && raw) set_raw_valuators(raw, &mask, raw->valuators.data); From 334faabe682a422075ba214501c7554dd5ee5563 Mon Sep 17 00:00:00 2001 From: Frank Binns Date: Tue, 10 Jun 2014 13:43:31 +0100 Subject: [PATCH 07/40] present: restore screen pixmap when aborting a flip If a 2D application is started on top of a fullscreen 3D application, which is flipping, then we need to stop flipping and restore the root window, and possibly the flip window, to using the screen pixmap. Normally this would be done as part of an unflip. However, in the case that there is a pending flip there is no mechanism to abort so the unflip is deferred until the pending flip completes. This provides a window of opportunity for the 2D application to draw to the wrong pixmap. Restore the screen pixmap at the point a pending flip is marked as aborted, thus avoiding this issue. Reviewed-by: Keith Packard Signed-off-by: Frank Binns Signed-off-by: Keith Packard --- present/present.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/present/present.c b/present/present.c index 165860af8..271c251a9 100644 --- a/present/present.c +++ b/present/present.c @@ -382,6 +382,24 @@ present_set_tree_pixmap(WindowPtr window, PixmapPtr pixmap) TraverseTree(window, present_set_tree_pixmap_visit, &visit); } +static void +present_set_abort_flip(ScreenPtr screen) +{ + present_screen_priv_ptr screen_priv = present_screen_priv(screen); + + /* Switch back to using the screen pixmap now to avoid + * 2D applications drawing to the wrong pixmap. + */ + + if (screen_priv->flip_window) + present_set_tree_pixmap(screen_priv->flip_window, + (*screen->GetScreenPixmap)(screen)); + + present_set_tree_pixmap(screen->root, (*screen->GetScreenPixmap)(screen)); + + screen_priv->flip_pending->abort_flip = TRUE; +} + static void present_unflip(ScreenPtr screen) { @@ -511,7 +529,7 @@ present_check_flip_window (WindowPtr window) if (flip_pending->window == window) { if (!present_check_flip(flip_pending->crtc, window, flip_pending->pixmap, flip_pending->sync_flip, NULL, 0, 0)) - flip_pending->abort_flip = TRUE; + present_set_abort_flip(screen); } } else { /* @@ -634,7 +652,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) /* Check pending flip */ if (window == screen_priv->flip_pending->window) - screen_priv->flip_pending->abort_flip = TRUE; + present_set_abort_flip(screen); } else if (!screen_priv->unflip_event_id) { /* Check current flip @@ -916,7 +934,7 @@ present_flip_destroy(ScreenPtr screen) /* Do the actual cleanup once the flip has been performed by the hardware */ if (screen_priv->flip_pending) - screen_priv->flip_pending->abort_flip = TRUE; + present_set_abort_flip(screen); } void From adb7bc3386559dfee34b359dadcbb6796bc416e7 Mon Sep 17 00:00:00 2001 From: Dinar Valeev Date: Mon, 24 Feb 2014 11:36:54 +0100 Subject: [PATCH 08/40] arch: Fix image and bitmap byte order for ppc64le So far PPC was big endian for sure. For ppc64le this is no longer true. Signed-off-by: Egbert Eich Reviewed-by: Mark Kettenis Signed-off-by: Keith Packard --- include/servermd.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/servermd.h b/include/servermd.h index 081123be9..e41331463 100644 --- a/include/servermd.h +++ b/include/servermd.h @@ -114,8 +114,13 @@ SOFTWARE. #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) -#define IMAGE_BYTE_ORDER MSBFirst -#define BITMAP_BIT_ORDER MSBFirst +#if defined(__LITTLE_ENDIAN__) +#define IMAGE_BYTE_ORDER LSBFirst +#define BITMAP_BIT_ORDER LSBFirst +#else +#define IMAGE_BYTE_ORDER MSBFirst +#define BITMAP_BIT_ORDER MSBFirst +#endif #define GLYPHPADBYTES 4 #endif /* PowerPC */ From ce581ac3fa80c4c52d87bd54fa92bc566b7d6adc Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Wed, 18 Jun 2014 22:22:09 -0400 Subject: [PATCH 09/40] present: fix bad logic in cancelling scheduled operations. If we present several pixmaps in advance for different msc, the later one shouldn't cancel the previous ones. This reverts a change made by commit e6f5d9d7b7efdacea0f22f1808efca849bcede4c Without this fix, vblank_mode=0 glxgears doesn't update with the present fallback. Signed-off-by: Axel Davy Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- present/present.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/present/present.c b/present/present.c index 271c251a9..3aea0d7c6 100644 --- a/present/present.c +++ b/present/present.c @@ -771,7 +771,7 @@ present_pixmap(WindowPtr window, if (!vblank->queued) continue; - if (vblank->crtc != target_crtc || vblank->target_msc > target_msc) + if (vblank->crtc != target_crtc || vblank->target_msc != target_msc) continue; DebugPresent(("\tx %lld %p %8lld: %08lx -> %08lx (crtc %p)\n", From 0d9ad781807022d78239327ed508758a3f88b090 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 16 Jun 2014 08:06:53 +0100 Subject: [PATCH 10/40] glamor: Fix GLES2 non-VBO temporary memory allocation. We'd get a request for like 16 bytes, claim to have allocated GLAMOR_VBO_SIZE, and then not reallocate when something a request bigger than 16 came along. The intent was to always allocate at least GLAMOR_VBO_SIZE. Fixes segfaults with Xephyr -glamor_gles2 and running gnome-terminal. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- glamor/glamor_vbo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor_vbo.c b/glamor/glamor_vbo.c index c6785594b..e90610102 100644 --- a/glamor/glamor_vbo.c +++ b/glamor/glamor_vbo.c @@ -119,7 +119,7 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset) if (glamor_priv->vbo_size < size) { glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size); free(glamor_priv->vb); - glamor_priv->vb = XNFalloc(size); + glamor_priv->vb = XNFalloc(glamor_priv->vbo_size); } *vbo_offset = NULL; /* We point to the start of glamor_priv->vb every time, and From 4d92fab39c4225e89f2d157a1f559cb0618a6eaa Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 18 Jun 2014 11:14:43 +0100 Subject: [PATCH 11/40] dri2: Use the PrimeScreen when creating/reusing buffers This fixes a segfault when we attempt to call ds->ReuseBufferNotify() passing a Prime DRI2BufferPtr to the master backend. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80001 Signed-off-by: Chris Wilson Reviewed-by: Dave Airlie Signed-off-by: Keith Packard --- hw/xfree86/dri2/dri2.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 6dd77963c..5705baa16 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -415,18 +415,14 @@ DRI2DrawableGone(void *p, XID id) } static DRI2BufferPtr -create_buffer(DrawablePtr pDraw, +create_buffer(DRI2ScreenPtr ds, DrawablePtr pDraw, unsigned int attachment, unsigned int format) { - ScreenPtr primeScreen; - DRI2DrawablePtr pPriv; - DRI2ScreenPtr ds; DRI2BufferPtr buffer; - pPriv = DRI2GetDrawable(pDraw); - primeScreen = GetScreenPrime(pDraw->pScreen, pPriv->prime_id); - ds = DRI2GetScreenPrime(pDraw->pScreen, pPriv->prime_id); if (ds->CreateBuffer2) - buffer = (*ds->CreateBuffer2)(primeScreen, pDraw, attachment, format); + buffer = (*ds->CreateBuffer2)(GetScreenPrime(pDraw->pScreen, + DRI2GetDrawable(pDraw)->prime_id), + pDraw, attachment, format); else buffer = (*ds->CreateBuffer)(pDraw, attachment, format); return buffer; @@ -475,7 +471,7 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds, if ((old_buf < 0) || attachment == DRI2BufferFrontLeft || !dimensions_match || (pPriv->buffers[old_buf]->format != format)) { - *buffer = create_buffer (pDraw, attachment, format); + *buffer = create_buffer(ds, pDraw, attachment, format); return TRUE; } @@ -538,7 +534,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, return NULL; } - ds = DRI2GetScreen(pDraw->pScreen); + ds = DRI2GetScreenPrime(pDraw->pScreen, pPriv->prime_id); dimensions_match = (pDraw->width == pPriv->width) && (pDraw->height == pPriv->height); From 18744907d0766b1b57be12df5adafd0f93221006 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 10 Jun 2014 07:45:05 +0100 Subject: [PATCH 12/40] dri2: Invalidate DRI2Buffers upon SetWindowPixmap updates When transitioning to a redirected or unredirected Window, the Composite layer modifies the Window's Pixmap. However, the DRI2Buffer for the Drawable is still pointing to the backing bo of the old Pixmap with the result that rendering goes astray. This now also effects DRI2 Drawables that are touched by PresentPixmap. v2: Fixup the function name after rebasing Signed-off-by: Chris Wilson Cc: Reinis Danne Reviewed-by: Dave Airlie Cc: Keith Packard Signed-off-by: Keith Packard --- hw/xfree86/dri2/dri2.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 5705baa16..6459f11b1 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -130,6 +130,7 @@ typedef struct _DRI2Screen { HandleExposuresProcPtr HandleExposures; ConfigNotifyProcPtr ConfigNotify; + SetWindowPixmapProcPtr SetWindowPixmap; DRI2CreateBuffer2ProcPtr CreateBuffer2; DRI2DestroyBuffer2ProcPtr DestroyBuffer2; DRI2CopyRegion2ProcPtr CopyRegion2; @@ -1378,6 +1379,21 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw, return Success; } +static void +DRI2SetWindowPixmap(WindowPtr pWin, PixmapPtr pPix) +{ + DrawablePtr pDraw = (DrawablePtr) pWin; + ScreenPtr pScreen = pDraw->pScreen; + DRI2ScreenPtr ds = DRI2GetScreen(pScreen); + + pScreen->SetWindowPixmap = ds->SetWindowPixmap; + (*pScreen->SetWindowPixmap) (pWin, pPix); + ds->SetWindowPixmap = pScreen->SetWindowPixmap; + pScreen->SetWindowPixmap = DRI2SetWindowPixmap; + + DRI2InvalidateDrawableAll(pDraw); +} + #define MAX_PRIME DRI2DriverPrimeMask static int get_prime_id(void) @@ -1524,6 +1540,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) ds->ConfigNotify = pScreen->ConfigNotify; pScreen->ConfigNotify = DRI2ConfigNotify; + ds->SetWindowPixmap = pScreen->SetWindowPixmap; + pScreen->SetWindowPixmap = DRI2SetWindowPixmap; + xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n"); for (i = 0; i < sizeof(driverTypeNames) / sizeof(driverTypeNames[0]); i++) { if (i < ds->numDrivers && ds->driverNames[i]) { @@ -1548,6 +1567,7 @@ DRI2CloseScreen(ScreenPtr pScreen) DRI2ScreenPtr ds = DRI2GetScreen(pScreen); pScreen->ConfigNotify = ds->ConfigNotify; + pScreen->SetWindowPixmap = ds->SetWindowPixmap; if (ds->prime_id) prime_id_allocate_bitmask &= ~(1 << ds->prime_id); From fd16555c2fc606fc43236050deba558c20e184e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 24 Jun 2014 16:09:19 +0900 Subject: [PATCH 13/40] Revert "glamor: Fix coordinates handling for composite source/mask pictures" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4e9aabb6fc15d8052934f20c6a07801c197ec36a. It broke kwin decorations with XRender compositing. Signed-off-by: Michel Dänzer Reviewed-by: Eric Anholt Signed-off-by: Keith Packard --- glamor/glamor_render.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 5a7a23880..14ab738eb 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1450,8 +1450,8 @@ glamor_composite_clipped_region(CARD8 op, || source_pixmap->drawable.height != height)))) { temp_src = glamor_convert_gradient_picture(screen, source, - x_source, - y_source, + extent->x1 + x_source - x_dest, + extent->y1 + y_source - y_dest, width, height); if (!temp_src) { temp_src = source; @@ -1459,8 +1459,8 @@ glamor_composite_clipped_region(CARD8 op, } temp_src_priv = glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable)); - x_temp_src = 0; - y_temp_src = 0; + x_temp_src = -extent->x1 + x_dest; + y_temp_src = -extent->y1 + y_dest; } if (mask @@ -1474,8 +1474,8 @@ glamor_composite_clipped_region(CARD8 op, * to do reduce one convertion. */ temp_mask = glamor_convert_gradient_picture(screen, mask, - x_mask, - y_mask, + extent->x1 + x_mask - x_dest, + extent->y1 + y_mask - y_dest, width, height); if (!temp_mask) { temp_mask = mask; @@ -1483,8 +1483,8 @@ glamor_composite_clipped_region(CARD8 op, } temp_mask_priv = glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable)); - x_temp_mask = 0; - y_temp_mask = 0; + x_temp_mask = -extent->x1 + x_dest; + y_temp_mask = -extent->y1 + y_dest; } /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. From 2f113d68f6c1572576bc57ecca12e44cc9e438eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 16 Jun 2014 11:34:55 -0700 Subject: [PATCH 14/40] xwayland: Add glamor and DRI3 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Axel Davy Signed-off-by: Kristian Høgsberg Signed-off-by: Keith Packard --- configure.ac | 6 +- hw/xwayland/Makefile.am | 31 +- hw/xwayland/drm.xml | 182 +++++++++++ hw/xwayland/xwayland-glamor.c | 570 ++++++++++++++++++++++++++++++++++ hw/xwayland/xwayland.c | 38 ++- hw/xwayland/xwayland.h | 17 + 6 files changed, 837 insertions(+), 7 deletions(-) create mode 100644 hw/xwayland/drm.xml create mode 100644 hw/xwayland/xwayland-glamor.c diff --git a/configure.ac b/configure.ac index dabebb9b8..2daa6beec 100644 --- a/configure.ac +++ b/configure.ac @@ -810,7 +810,7 @@ LIBDMX="dmx >= 1.0.99.1" LIBDRI="dri >= 7.8.0" LIBDRM="libdrm >= 2.3.0" LIBEGL="egl" -LIBGBM="gbm >= 9" +LIBGBM="gbm >= 10.2.0" LIBGL="gl >= 7.1.0" LIBXEXT="xext >= 1.0.99.4" LIBXFONT="xfont >= 1.4.2" @@ -2459,6 +2459,10 @@ if test "x$XWAYLAND" = xyes; then XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS" AC_SUBST([XWAYLAND_LIBS]) AC_SUBST([XWAYLAND_SYS_LIBS]) + + WAYLAND_PREFIX=`$PKG_CONFIG --variable=prefix wayland-client` + AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner],, + [${WAYLAND_PREFIX}/bin$PATH_SEPARATOR$PATH]) fi diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am index 36e6127df..dc16b8bbe 100644 --- a/hw/xwayland/Makefile.am +++ b/hw/xwayland/Makefile.am @@ -1,10 +1,13 @@ bin_PROGRAMS = Xwayland Xwayland_CFLAGS = \ + -I$(top_srcdir)/glamor \ -I$(top_srcdir)/dri3 \ -DHAVE_DIX_CONFIG_H \ $(XWAYLANDMODULES_CFLAGS) \ - $(DIX_CFLAGS) + $(DIX_CFLAGS) \ + $(GLAMOR_CFLAGS) \ + $(GBM_CFLAGS) Xwayland_SOURCES = \ xwayland.c \ @@ -19,6 +22,7 @@ Xwayland_SOURCES = \ $(top_srcdir)/mi/miinitext.c Xwayland_LDADD = \ + $(glamor_lib) \ $(XWAYLAND_LIBS) \ $(XWAYLAND_SYS_LIBS) \ $(XSERVER_SYS_LIBS) @@ -26,5 +30,30 @@ Xwayland_DEPENDENCIES = $(XWAYLAND_LIBS) Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) +if GLAMOR_EGL +Xwayland_SOURCES += xwayland-glamor.c + +nodist_Xwayland_SOURCES = \ + drm-client-protocol.h \ + drm-protocol.c + +CLEANFILES = $(nodist_Xwayland_SOURCES) + +EXTRA_DIST = drm.xml + +xwayland-glamor.c : $(nodist_Xwayland_SOURCES) + +glamor_lib = $(top_builddir)/glamor/libglamor.la + +Xwayland_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) -lEGL -lGL +endif + + relink: $(AM_V_at)rm -f Xwayland$(EXEEXT) && $(MAKE) Xwayland$(EXEEXT) + +%-protocol.c : %.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ + +%-client-protocol.h : %.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@ diff --git a/hw/xwayland/drm.xml b/hw/xwayland/drm.xml new file mode 100644 index 000000000..8a3ad69b2 --- /dev/null +++ b/hw/xwayland/drm.xml @@ -0,0 +1,182 @@ + + + + + Copyright © 2008-2011 Kristian Høgsberg + Copyright © 2010-2011 Intel Corporation + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that\n the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bitmask of capabilities. + + + + + + + + + + diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c new file mode 100644 index 000000000..4be883fa3 --- /dev/null +++ b/hw/xwayland/xwayland-glamor.c @@ -0,0 +1,570 @@ +/* + * Copyright © 2011-2014 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "xwayland.h" + +#include +#include +#include + +#define MESA_EGL_NO_X11_HEADERS +#include +#include +#include + +#include +#include +#include +#include "drm-client-protocol.h" + +struct xwl_pixmap { + struct wl_buffer *buffer; + struct gbm_bo *bo; + void *image; + unsigned int texture; +}; + +static void +xwl_glamor_egl_make_current(struct glamor_context *glamor_ctx) +{ + eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (!eglMakeCurrent(glamor_ctx->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, + glamor_ctx->ctx)) + FatalError("Failed to make EGL context current\n"); +} + +static uint32_t +drm_format_for_depth(int depth) +{ + switch (depth) { + case 15: + return WL_DRM_FORMAT_XRGB1555; + case 16: + return WL_DRM_FORMAT_RGB565; + case 24: + return WL_DRM_FORMAT_XRGB8888; + default: + ErrorF("unexpected depth: %d\n", depth); + case 32: + return WL_DRM_FORMAT_ARGB8888; + } +} + +static uint32_t +gbm_format_for_depth(int depth) +{ + switch (depth) { + case 16: + return GBM_FORMAT_RGB565; + case 24: + return GBM_FORMAT_XRGB8888; + default: + ErrorF("unexpected depth: %d\n", depth); + case 32: + return GBM_FORMAT_ARGB8888; + } +} + +void +glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + + glamor_ctx->ctx = xwl_screen->egl_context; + glamor_ctx->display = xwl_screen->egl_display; + + glamor_ctx->make_current = xwl_glamor_egl_make_current; + + xwl_screen->glamor_ctx = glamor_ctx; +} + +static PixmapPtr +xwl_glamor_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth) +{ + PixmapPtr pixmap; + struct xwl_pixmap *xwl_pixmap; + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + + xwl_pixmap = malloc(sizeof *xwl_pixmap); + if (xwl_pixmap == NULL) + return NULL; + + pixmap = glamor_create_pixmap(screen, + gbm_bo_get_width(bo), + gbm_bo_get_height(bo), + depth, + GLAMOR_CREATE_PIXMAP_NO_TEXTURE); + if (pixmap == NULL) { + free(xwl_pixmap); + return NULL; + } + + if (lastGLContext != xwl_screen->glamor_ctx) { + lastGLContext = xwl_screen->glamor_ctx; + xwl_glamor_egl_make_current(xwl_screen->glamor_ctx); + } + + xwl_pixmap->bo = bo; + xwl_pixmap->buffer = NULL; + xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display, + xwl_screen->egl_context, + EGL_NATIVE_PIXMAP_KHR, + xwl_pixmap->bo, NULL); + + glGenTextures(1, &xwl_pixmap->texture); + glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image); + glBindTexture(GL_TEXTURE_2D, 0); + + xwl_pixmap_set_private(pixmap, xwl_pixmap); + + glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture); + glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); + + return pixmap; +} + +struct wl_buffer * +xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); + struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); + int prime_fd; + + if (xwl_pixmap->buffer) + return xwl_pixmap->buffer; + + prime_fd = gbm_bo_get_fd(xwl_pixmap->bo); + if (prime_fd == -1) + return NULL; + + xwl_pixmap->buffer = + wl_drm_create_prime_buffer(xwl_screen->drm, prime_fd, + pixmap->drawable.width, + pixmap->drawable.height, + drm_format_for_depth(pixmap->drawable.depth), + 0, gbm_bo_get_stride(xwl_pixmap->bo), + 0, 0, + 0, 0); + + close(prime_fd); + + return xwl_pixmap->buffer; +} + +static PixmapPtr +xwl_glamor_create_pixmap(ScreenPtr screen, + int width, int height, int depth, unsigned int hint) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + struct gbm_bo *bo; + + if (width > 0 && height > 0 && depth >= 15 && + (hint == 0 || + hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP || + hint == CREATE_PIXMAP_USAGE_SHARED)) { + bo = gbm_bo_create(xwl_screen->gbm, width, height, + gbm_format_for_depth(depth), + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + + if (bo) + return xwl_glamor_create_pixmap_for_bo(screen, bo, depth); + } + + return glamor_create_pixmap(screen, width, height, depth, hint); +} + +static Bool +xwl_glamor_destroy_pixmap(PixmapPtr pixmap) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); + struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); + + if (xwl_pixmap && pixmap->refcnt == 1) { + if (xwl_pixmap->buffer) + wl_buffer_destroy(xwl_pixmap->buffer); + + eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image); + gbm_bo_destroy(xwl_pixmap->bo); + free(xwl_pixmap); + } + + return glamor_destroy_pixmap(pixmap); +} + +static Bool +xwl_glamor_create_screen_resources(ScreenPtr screen) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + int ret; + + screen->CreateScreenResources = xwl_screen->CreateScreenResources; + ret = (*screen->CreateScreenResources) (screen); + xwl_screen->CreateScreenResources = screen->CreateScreenResources; + screen->CreateScreenResources = xwl_glamor_create_screen_resources; + + if (!ret) + return ret; + + if (xwl_screen->rootless) + screen->devPrivate = + fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0); + else { + screen->devPrivate = + xwl_glamor_create_pixmap(screen, screen->width, screen->height, + screen->rootDepth, + CREATE_PIXMAP_USAGE_BACKING_PIXMAP); + if (screen->devPrivate) + glamor_set_screen_pixmap(screen->devPrivate, NULL); + } + + return screen->devPrivate != NULL; +} + +static char +is_fd_render_node(int fd) +{ + struct stat render; + + if (fstat(fd, &render)) + return 0; + if (!S_ISCHR(render.st_mode)) + return 0; + if (render.st_rdev & 0x80) + return 1; + + return 0; +} + +static void +xwl_drm_init_egl(struct xwl_screen *xwl_screen) +{ + EGLint major, minor; + const char *version; + + if (xwl_screen->egl_display) + return; + + xwl_screen->expecting_event--; + + xwl_screen->gbm = gbm_create_device(xwl_screen->drm_fd); + if (xwl_screen->gbm == NULL) { + ErrorF("couldn't get display device\n"); + return; + } + + xwl_screen->egl_display = eglGetDisplay(xwl_screen->gbm); + if (xwl_screen->egl_display == EGL_NO_DISPLAY) { + ErrorF("eglGetDisplay() failed\n"); + return; + } + + eglBindAPI(EGL_OPENGL_API); + if (!eglInitialize(xwl_screen->egl_display, &major, &minor)) { + ErrorF("eglInitialize() failed\n"); + return; + } + + version = eglQueryString(xwl_screen->egl_display, EGL_VERSION); + ErrorF("glamor: EGL version %s:\n", version); + + xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display, + NULL, EGL_NO_CONTEXT, NULL); + if (xwl_screen->egl_context == EGL_NO_CONTEXT) { + ErrorF("Failed to create EGL context\n"); + return; + } + + if (!eglMakeCurrent(xwl_screen->egl_display, + EGL_NO_SURFACE, EGL_NO_SURFACE, + xwl_screen->egl_context)) { + ErrorF("Failed to make EGL context current\n"); + return; + } + + if (!epoxy_has_gl_extension("GL_OES_EGL_image")) { + ErrorF("GL_OES_EGL_image no available"); + return; + } + + return; +} + +static void +xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device) +{ + struct xwl_screen *xwl_screen = data; + drm_magic_t magic; + + xwl_screen->device_name = strdup(device); + if (!xwl_screen->device_name) + return; + + xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC); + if (xwl_screen->drm_fd == -1) { + ErrorF("wayland-egl: could not open %s (%s)", + xwl_screen->device_name, strerror(errno)); + return; + } + + if (is_fd_render_node(xwl_screen->drm_fd)) { + xwl_screen->fd_render_node = 1; + xwl_drm_init_egl(xwl_screen); + } else { + drmGetMagic(xwl_screen->drm_fd, &magic); + wl_drm_authenticate(xwl_screen->drm, magic); + } +} + +static void +xwl_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format) +{ + struct xwl_screen *xwl_screen = data; + + switch (format) { + case WL_DRM_FORMAT_ARGB8888: + xwl_screen->formats |= XWL_FORMAT_ARGB8888; + break; + case WL_DRM_FORMAT_XRGB8888: + xwl_screen->formats |= XWL_FORMAT_XRGB8888; + break; + case WL_DRM_FORMAT_RGB565: + xwl_screen->formats |= XWL_FORMAT_RGB565; + break; + } +} + +static void +xwl_drm_handle_authenticated(void *data, struct wl_drm *drm) +{ + struct xwl_screen *xwl_screen = data; + + if (!xwl_screen->egl_display) + xwl_drm_init_egl(xwl_screen); +} + +static void +xwl_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value) +{ + struct xwl_screen *xwl_screen = data; + + xwl_screen->capabilities = value; +} + +static const struct wl_drm_listener xwl_drm_listener = { + xwl_drm_handle_device, + xwl_drm_handle_format, + xwl_drm_handle_authenticated, + xwl_drm_handle_capabilities +}; + +Bool +xwl_screen_init_glamor(struct xwl_screen *xwl_screen, + uint32_t id, uint32_t version) +{ + if (version < 2) + return FALSE; + + xwl_screen->drm = + wl_registry_bind(xwl_screen->registry, id, &wl_drm_interface, 2); + wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen); + xwl_screen->expecting_event++; + + return TRUE; +} + +void +glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap) +{ + glamor_destroy_textured_pixmap(pixmap); +} + +int +glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, + PixmapPtr pixmap, + unsigned int tex, + Bool want_name, CARD16 *stride, CARD32 *size) +{ + return 0; +} + +unsigned int +glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h) +{ + return 0; +} + +struct xwl_auth_state { + int fd; + ClientPtr client; +}; + +static void +sync_callback(void *data, struct wl_callback *callback, uint32_t serial) +{ + struct xwl_auth_state *state = data; + + dri3_send_open_reply(state->client, state->fd); + AttendClient(state->client); + free(state); + wl_callback_destroy(callback); +} + +static const struct wl_callback_listener sync_listener = { + sync_callback +}; + +static int +xwl_dri3_open_client(ClientPtr client, + ScreenPtr screen, + RRProviderPtr provider, + int *pfd) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + struct xwl_auth_state *state; + struct wl_callback *callback; + drm_magic_t magic; + int fd; + + fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC); + if (fd < 0) + return BadAlloc; + if (xwl_screen->fd_render_node) { + *pfd = fd; + return Success; + } + + state = malloc(sizeof *state); + if (state == NULL) { + close(fd); + return BadAlloc; + } + + state->client = client; + state->fd = fd; + + if (drmGetMagic(state->fd, &magic) < 0) { + close(state->fd); + free(state); + return BadMatch; + } + + wl_drm_authenticate(xwl_screen->drm, magic); + callback = wl_display_sync(xwl_screen->display); + wl_callback_add_listener(callback, &sync_listener, state); + + IgnoreClient(client); + + return Success; +} + +static PixmapPtr +xwl_dri3_pixmap_from_fd(ScreenPtr screen, int fd, + CARD16 width, CARD16 height, CARD16 stride, + CARD8 depth, CARD8 bpp) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + struct gbm_import_fd_data data; + struct gbm_bo *bo; + PixmapPtr pixmap; + + if (width == 0 || height == 0 || + depth < 15 || bpp != BitsPerPixel(depth) || stride < width * bpp / 8) + return NULL; + + data.fd = fd; + data.width = width; + data.height = height; + data.stride = stride; + data.format = gbm_format_for_depth(depth); + bo = gbm_bo_import(xwl_screen->gbm, GBM_BO_IMPORT_FD, &data, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + if (bo == NULL) + return NULL; + + pixmap = xwl_glamor_create_pixmap_for_bo(screen, bo, depth); + if (pixmap == NULL) { + gbm_bo_destroy(bo); + return NULL; + } + + return pixmap; +} + +static int +xwl_dri3_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, + CARD16 *stride, CARD32 *size) +{ + struct xwl_pixmap *xwl_pixmap; + + xwl_pixmap = xwl_pixmap_get(pixmap); + + *stride = gbm_bo_get_stride(xwl_pixmap->bo); + *size = pixmap->drawable.width * *stride; + + return gbm_bo_get_fd(xwl_pixmap->bo); +} + +static dri3_screen_info_rec xwl_dri3_info = { + .version = 1, + .open = NULL, + .pixmap_from_fd = xwl_dri3_pixmap_from_fd, + .fd_from_pixmap = xwl_dri3_fd_from_pixmap, + .open_client = xwl_dri3_open_client, +}; + +Bool +xwl_glamor_init(struct xwl_screen *xwl_screen) +{ + ScreenPtr screen = xwl_screen->screen; + + if (xwl_screen->egl_context == EGL_NO_CONTEXT) { + ErrorF("Disabling glamor and dri3, EGL setup failed\n"); + return FALSE; + } + + if (!glamor_init(xwl_screen->screen, + GLAMOR_INVERTED_Y_AXIS | + GLAMOR_USE_EGL_SCREEN | + GLAMOR_USE_SCREEN | + GLAMOR_USE_PICTURE_SCREEN)) { + ErrorF("Failed to initialize glamor\n"); + return FALSE; + } + + if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) { + ErrorF("Failed to initialize dri3\n"); + return FALSE; + } + + xwl_screen->CreateScreenResources = screen->CreateScreenResources; + screen->CreateScreenResources = xwl_glamor_create_screen_resources; + screen->CreatePixmap = xwl_glamor_create_pixmap; + screen->DestroyPixmap = xwl_glamor_destroy_pixmap; + + return TRUE; +} diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index b966e5070..17b7bf7fd 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -337,7 +337,13 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen) pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window); - buffer = xwl_shm_pixmap_get_wl_buffer(pixmap); +#if GLAMOR_HAS_GBM + if (xwl_screen->glamor) + buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap); +#endif + if (!xwl_screen->glamor) + buffer = xwl_shm_pixmap_get_wl_buffer(pixmap); + wl_surface_attach(xwl_window->surface, buffer, 0, 0); for (i = 0; i < count; i++) { box = &RegionRects(region)[i]; @@ -373,6 +379,12 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id, xwl_output_create(xwl_screen, id); xwl_screen->expecting_event++; } +#ifdef GLAMOR_HAS_GBM + else if (xwl_screen->glamor && + strcmp(interface, "wl_drm") == 0 && version >= 2) { + xwl_screen_init_glamor(xwl_screen, id, version); + } +#endif } static void @@ -495,6 +507,10 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen); xwl_screen->screen = pScreen; +#ifdef GLAMOR_HAS_GBM + xwl_screen->glamor = 1; +#endif + for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-rootless") == 0) { xwl_screen->rootless = 1; @@ -514,6 +530,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) atoi(argv[i + 1]); i++; } + else if (strcmp(argv[i], "-shm") == 0) { + xwl_screen->glamor = 0; + } } if (xwl_screen->listen_fd_count > 0) { @@ -591,10 +610,19 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) if (!xwl_screen_init_cursor(xwl_screen)) return FALSE; - xwl_screen->CreateScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = xwl_shm_create_screen_resources; - pScreen->CreatePixmap = xwl_shm_create_pixmap; - pScreen->DestroyPixmap = xwl_shm_destroy_pixmap; +#ifdef GLAMOR_HAS_GBM + if (xwl_screen->glamor && !xwl_glamor_init(xwl_screen)) { + ErrorF("Failed to initialize glamor, falling back to sw\n"); + xwl_screen->glamor = 0; + } +#endif + + if (!xwl_screen->glamor) { + xwl_screen->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = xwl_shm_create_screen_resources; + pScreen->CreatePixmap = xwl_shm_create_pixmap; + pScreen->DestroyPixmap = xwl_shm_destroy_pixmap; + } xwl_screen->RealizeWindow = pScreen->RealizeWindow; pScreen->RealizeWindow = xwl_realize_window; diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 8157e71ff..fc6855044 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -55,6 +55,7 @@ struct xwl_screen { int listen_fds[5]; int listen_fd_count; int rootless; + int glamor; CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; @@ -83,6 +84,16 @@ struct xwl_screen { #define XWL_FORMAT_RGB565 (1 << 2) int prepare_read; + + char *device_name; + int drm_fd; + int fd_render_node; + struct wl_drm *drm; + uint32_t formats; + uint32_t capabilities; + void *egl_display, *egl_context; + struct gbm_device *gbm; + struct glamor_context *glamor_ctx; }; struct xwl_window { @@ -161,4 +172,10 @@ Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap); struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap); +Bool xwl_glamor_init(struct xwl_screen *xwl_screen); + +Bool xwl_screen_init_glamor(struct xwl_screen *xwl_screen, + uint32_t id, uint32_t version); +struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap); + #endif From a3b44ad8db1fa2f3b81c1ff9498f31c5323edd37 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 25 Jun 2014 16:03:29 +0200 Subject: [PATCH 15/40] exa: Fix a warning when enabling DEBUG_TRACE_FALL The format string wants a picture and a character, but the argument list contains only a character, causing GCC to complain. Add the missing argument. Signed-off-by: Thierry Reding Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- exa/exa_unaccel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index 58262e0b2..b0c6344a5 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -685,7 +685,7 @@ ExaCheckAddTraps(PicturePtr pPicture, EXA_PRE_FALLBACK(pScreen); - EXA_FALLBACK(("to pict %p (%c)\n", + EXA_FALLBACK(("to pict %p (%c)\n", pPicture, exaDrawableLocation(pPicture->pDrawable))); exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); swap(pExaScr, ps, AddTraps); From a5499870e2f88822f52b1b54cad0db69856597c0 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Sun, 6 Apr 2014 04:47:15 -0500 Subject: [PATCH 16/40] hw/xwin: link dynamically and export symbols With my patch to fix shared libXfont to work correctly on Cygwin/Win32, there is no need for -static anymore. But, XWin.exe must export its symbols in order for them to override libXfont's stubs. Signed-off-by: Yaakov Selkowitz Reviewed-by: Jon TURNEY --- hw/xwin/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am index cf42cfd2d..4ee963227 100644 --- a/hw/xwin/Makefile.am +++ b/hw/xwin/Makefile.am @@ -155,7 +155,7 @@ XWIN_LIBS += $(top_builddir)/pseudoramiX/libPseudoramiX.la \ $(top_builddir)/Xi/libXistubs.la XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(XSERVER_LIBS) XWin_LDADD = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS) -XWin_LDFLAGS = -mwindows -static -Wl,--disable-stdcall-fixup +XWin_LDFLAGS = -mwindows -Wl,--disable-stdcall-fixup $(LD_EXPORT_SYMBOLS_FLAG) .rc.o: From 10d2805dbc6b96a159b8c5acedcd53f34df362bf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 26 Jun 2014 14:12:24 -0700 Subject: [PATCH 17/40] fb: Don't free NULL pixmap in fbCloseScreen. Bug #80313 We fixed fbCloseScreen to use the FreePixmap function so that the private counts would be updated correctly during CloseScreen. Xvfb calls FreePixmap and sets devPrivate to NULL before fbCloseScreen is called; not checking devPrivate before calling would result in a NULL pointer dereference. Signed-off-by: Keith Packard Reviewed-by: Julien Cristau --- fb/fbscreen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fb/fbscreen.c b/fb/fbscreen.c index 1f9108945..0d4d87f8b 100644 --- a/fb/fbscreen.c +++ b/fb/fbscreen.c @@ -37,7 +37,8 @@ fbCloseScreen(ScreenPtr pScreen) free(depths[d].vids); free(depths); free(pScreen->visuals); - FreePixmap((PixmapPtr)pScreen->devPrivate); + if (pScreen->devPrivate) + FreePixmap((PixmapPtr)pScreen->devPrivate); return TRUE; } From a61ca6f006d70343c88fe45206fae0669d1e8971 Mon Sep 17 00:00:00 2001 From: Tomasz Borowik Date: Thu, 3 Jul 2014 13:04:44 -0700 Subject: [PATCH 18/40] glamor: Fix stack corruption in glamor_init glGet on GL_MAX_VIEWPORT_DIMS returns two values Reviewed-by: Markus Wick Signed-off-by: Keith Packard --- glamor/glamor.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index c398807f1..358890375 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -316,7 +316,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) { glamor_screen_private *glamor_priv; int gl_version; - int max_viewport_size; + int max_viewport_size[2]; #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); @@ -408,8 +408,9 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->has_buffer_storage = epoxy_has_gl_extension("GL_ARB_buffer_storage"); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size); - glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &max_viewport_size); - glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size); + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size); + glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[0]); + glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[1]); #ifdef MAX_FBO_SIZE glamor_priv->max_fbo_size = MAX_FBO_SIZE; #endif From 5a4e15c3f6fb8d674879e54458328e9f595d9451 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 14 Feb 2014 15:45:33 +0100 Subject: [PATCH 19/40] xfree86: Make driver matching consistent Most of the driver enumeration functions take an array and a maximum number of entries that they are allowed to fill in. Upon success, they return the number of entries filled in. This allows them to be easily used to consecutively. One exception is the xf86MatchDriverFromFiles() function, which doesn't return a value, so callers have to manually search the array for the first empty entry. This commit modifies the xf86MatchDriverFromFiles() to behave the same way as others, which makes it easier to deal with. Reviewed-by: Aaron Plattner Tested-By: Aaron Plattner Tested-by: Rob Clark (on arm / platform device) Signed-off-by: Thierry Reding Signed-off-by: Keith Packard --- hw/xfree86/common/xf86AutoConfig.c | 2 +- hw/xfree86/common/xf86pciBus.c | 24 ++++++++++-------------- hw/xfree86/common/xf86pciBus.h | 5 +++-- hw/xfree86/common/xf86platformBus.c | 7 ++----- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 4eb86de22..2b53b908a 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -265,7 +265,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches) #endif #ifdef XSERVER_LIBPCIACCESS if (i < (nmatches - 1)) - i = xf86PciMatchDriver(matches, nmatches); + i += xf86PciMatchDriver(&matches[i], nmatches - i); #endif #if defined(__linux__) diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 0f76a03ee..c06b04033 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -1320,8 +1320,9 @@ xchomp(char *line) * don't export their PCI ID's properly. If distros don't end up using this * feature it can and should be removed because the symbol-based resolution * scheme should be the primary one */ -void -xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_chip) +int +xf86MatchDriverFromFiles(uint16_t match_vendor, uint16_t match_chip, + char *matches[], int nmatches) { DIR *idsdir; FILE *fp; @@ -1331,11 +1332,11 @@ xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_c ssize_t read; char path_name[256], vendor_str[5], chip_str[5]; uint16_t vendor, chip; - int i, j; + int i = 0, j; idsdir = opendir(PCI_TXT_IDS_PATH); if (!idsdir) - return; + return 0; xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", @@ -1386,10 +1387,6 @@ xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_c } } if (vendor == match_vendor && chip == match_chip) { - i = 0; - while (matches[i]) { - i++; - } matches[i] = (char *) malloc(sizeof(char) * strlen(direntry->d_name) - 3); @@ -1412,6 +1409,7 @@ xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_c } xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name); + i++; } } else { @@ -1425,6 +1423,7 @@ xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_c end: free(line); closedir(idsdir); + return i; } #endif /* __linux__ */ @@ -1435,7 +1434,7 @@ xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_c int xf86PciMatchDriver(char *matches[], int nmatches) { - int i; + int i = 0; struct pci_device *info = NULL; struct pci_device_iterator *iter; @@ -1450,13 +1449,10 @@ xf86PciMatchDriver(char *matches[], int nmatches) pci_iterator_destroy(iter); #ifdef __linux__ if (info) - xf86MatchDriverFromFiles(matches, info->vendor_id, info->device_id); + i += xf86MatchDriverFromFiles(info->vendor_id, info->device_id, + matches, nmatches); #endif - for (i = 0; (i < nmatches) && (matches[i]); i++) { - /* find end of matches list */ - } - if ((info != NULL) && (i < nmatches)) { i += xf86VideoPtrToDriverList(info, &(matches[i]), nmatches - i); } diff --git a/hw/xfree86/common/xf86pciBus.h b/hw/xfree86/common/xf86pciBus.h index b497a7f2d..45b5a0fee 100644 --- a/hw/xfree86/common/xf86pciBus.h +++ b/hw/xfree86/common/xf86pciBus.h @@ -47,8 +47,9 @@ void xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo, ((x)->func == (y)->func) && \ ((x)->dev == (y)->dev)) -void -xf86MatchDriverFromFiles(char **matches, uint16_t match_vendor, uint16_t match_chip); +int +xf86MatchDriverFromFiles(uint16_t match_vendor, uint16_t match_chip, + char *matches[], int nmatches); int xf86VideoPtrToDriverList(struct pci_device *dev, char *returnList[], int returnListMax); diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index dd118a285..672e2e519 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -221,13 +221,10 @@ xf86PlatformMatchDriver(char *matches[], int nmatches) info = xf86_platform_devices[i].pdev; #ifdef __linux__ if (info) - xf86MatchDriverFromFiles(matches, info->vendor_id, info->device_id); + j += xf86MatchDriverFromFiles(info->vendor_id, info->device_id, + &matches[j], nmatches - j); #endif - for (j = 0; (j < nmatches) && (matches[j]); j++) { - /* find end of matches list */ - } - if ((info != NULL) && (j < nmatches)) { j += xf86VideoPtrToDriverList(info, &(matches[j]), nmatches - j); } From 856bb80cea695106a8f6767d00918b38795b51c6 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 12 Feb 2014 16:43:29 +0100 Subject: [PATCH 20/40] xfree86: Store kernel driver name in platform device attribute When opening a DRM device, query the version and store the driver name as a new attribute for future reference. Reviewed-by: Aaron Plattner Tested-By: Aaron Plattner Signed-off-by: Thierry Reding Reviewed-by: Rob Clark Tested-by: Rob Clark Signed-off-by: Keith Packard --- hw/xfree86/os-support/linux/lnx_platform.c | 12 ++++++++++++ include/hotplug.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c index 308275ab4..0aaedab21 100644 --- a/hw/xfree86/os-support/linux/lnx_platform.c +++ b/hw/xfree86/os-support/linux/lnx_platform.c @@ -24,6 +24,7 @@ static Bool get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) { drmSetVersion sv; + drmVersionPtr v; char *buf; int major, minor, fd; int err = 0; @@ -74,6 +75,17 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) xf86_add_platform_device_attrib(delayed_index, ODEV_ATTRIB_BUSID, buf); drmFreeBusid(buf); + + v = drmGetVersion(fd); + if (!v) { + xf86Msg(X_ERROR, "%s: failed to query DRM version\n", path); + goto out; + } + + xf86_add_platform_device_attrib(delayed_index, ODEV_ATTRIB_DRIVER, + v->name); + drmFreeVersion(v); + out: if (!server_fd) close(fd); diff --git a/include/hotplug.h b/include/hotplug.h index cefc164ae..c4268a0c4 100644 --- a/include/hotplug.h +++ b/include/hotplug.h @@ -87,6 +87,8 @@ config_odev_free_attributes(struct OdevAttributes *attribs); #define ODEV_ATTRIB_MAJOR 5 /* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */ #define ODEV_ATTRIB_MINOR 6 +/* kernel driver name */ +#define ODEV_ATTRIB_DRIVER 4 typedef void (*config_odev_probe_proc_ptr)(struct OdevAttributes *attribs); void config_odev_probe(config_odev_probe_proc_ptr probe_callback); From a270bb18baa6e3b45fa4a105a8d2be51ac5270bc Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Feb 2014 13:42:05 +0100 Subject: [PATCH 21/40] xfree86: Introduce OutputClass configuration The OutputClass section provides a way to match output devices to a set of given attributes and configure them. For now, only matching by kernel driver name is supported. This can be used to determine what DDX module to load for non-PCI output devices. DDX modules can ship an xorg.conf.d snippet (e.g. in /usr/share/X11/xorg.conf.d) that looks like this: Section "OutputClass" Identifer "NVIDIA Tegra open-source driver" MatchDriver "tegra" Driver "opentegra" EndSection This will cause any device that's driven by the kernel driver named "tegra" to use the "opentegra" DDX module. See the OUTPUTCLASS section in xorg.conf(5) for more details. Reviewed-by: Aaron Plattner Tested-By: Aaron Plattner Signed-off-by: Thierry Reding Tested-by: Rob Clark Signed-off-by: Keith Packard --- hw/xfree86/man/xorg.conf.man | 77 +++++++++++++++ hw/xfree86/parser/Makefile.am | 1 + hw/xfree86/parser/OutputClass.c | 167 ++++++++++++++++++++++++++++++++ hw/xfree86/parser/configProcs.h | 5 + hw/xfree86/parser/read.c | 6 ++ hw/xfree86/parser/write.c | 2 + hw/xfree86/parser/xf86Parser.h | 9 ++ 7 files changed, 267 insertions(+) create mode 100644 hw/xfree86/parser/OutputClass.c diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man index cadd87b7b..bc33df197 100644 --- a/hw/xfree86/man/xorg.conf.man +++ b/hw/xfree86/man/xorg.conf.man @@ -171,6 +171,7 @@ The section names are: .BR "Extensions " "Extension enabling" .BR "InputDevice " "Input device description" .BR "InputClass " "Input class description" +.BR "OutputClass " "Output class description" .BR "Device " "Graphics device description" .BR "VideoAdaptor " "Xv video adaptor description" .BR "Monitor " "Monitor description" @@ -1190,6 +1191,82 @@ entries. This optional entry specifies that the device should be ignored entirely, and not added to the server. This can be useful when the device is handled by another program and no X events should be generated. +.SH "OUTPUTCLASS SECTION" +The config file may have multiple +.B OutputClass +sections. +These sections are optional and are used to provide configuration for a +class of output devices as they are automatically added. +An output device can match more than one +.B OutputClass +section. +Each class can override settings from a previous class, so it is best to +arrange the sections with the most generic matches first. +.PP +.B OutputClass +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qOutputClass\*q" +.BI " Identifier \*q" name \*q +.I " entries" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +The +.B Identifier +entry is required in all +.B OutputClass +sections. +All other entries are optional. +.PP +The +.B Identifier +entry specifies the unique name for this output class. +The +.B Driver +entry specifies the name of the driver to use for this output device. +After all classes have been examined, the +.RI \*q outputdriver \*q +module from the first +.B Driver +entry will be enabled when using the loadable server. +.PP +When an output device is automatically added, its characteristics are +checked against all +.B OutputClass +sections. +Each section can contain optional entries to narrow the match of the class. +If none of the optional entries appear, the +.B OutputClass +section is generic and will match any output device. +If more than one of these entries appear, they all must match for the +configuration to apply. +.PP +The following list of tokens can be matched against attributes of the device. +An entry can be constructed to match attributes from different devices by +separating arguments with a '|' character. +.PP +For example: +.PP +.RS 4 +.nf +.B "Section \*qOutputClass\*q" +.B " Identifier \*qMy Class\*q" +.B " # kernel driver must be either foo or bar +.B " MatchDriver \*qfoo|bar\*q +.I " ..." +.B "EndSection" +.fi +.RE +.TP 7 +.BI "MatchDriver \*q" matchdriver \*q +Check the case-sensitive string +.RI \*q matchdriver \*q +against the kernel driver of the device. .SH "DEVICE SECTION" The config file may have multiple .B Device diff --git a/hw/xfree86/parser/Makefile.am b/hw/xfree86/parser/Makefile.am index 3bf62e8af..4d0bb4fd8 100644 --- a/hw/xfree86/parser/Makefile.am +++ b/hw/xfree86/parser/Makefile.am @@ -14,6 +14,7 @@ INTERNAL_SOURCES= \ Flags.c \ Input.c \ InputClass.c \ + OutputClass.c \ Layout.c \ Module.c \ Video.c \ diff --git a/hw/xfree86/parser/OutputClass.c b/hw/xfree86/parser/OutputClass.c new file mode 100644 index 000000000..7e9a8ac1a --- /dev/null +++ b/hw/xfree86/parser/OutputClass.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include "os.h" +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +static +xf86ConfigSymTabRec OutputClassTab[] = { + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {DRIVER, "driver"}, + {MATCH_DRIVER, "matchdriver"}, + {-1, ""}, +}; + +#define CLEANUP xf86freeOutputClassList + +#define TOKEN_SEP "|" + +static void +add_group_entry(struct xorg_list *head, char **values) +{ + xf86MatchGroup *group; + + group = malloc(sizeof(*group)); + if (group) { + group->values = values; + xorg_list_add(&group->entry, head); + } +} + +XF86ConfOutputClassPtr +xf86parseOutputClassSection(void) +{ + int has_ident = FALSE; + int token; + + parsePrologue(XF86ConfOutputClassPtr, XF86ConfOutputClassRec) + + /* Initialize MatchGroup lists */ + xorg_list_init(&ptr->match_driver); + + while ((token = xf86getToken(OutputClassTab)) != ENDSECTION) { + switch (token) { + case COMMENT: + ptr->comment = xf86addComment(ptr->comment, xf86_lex_val.str); + break; + case IDENTIFIER: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error(MULTIPLE_MSG, "Identifier"); + ptr->identifier = xf86_lex_val.str; + has_ident = TRUE; + break; + case DRIVER: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "Driver"); + else + ptr->driver = xf86_lex_val.str; + break; + case MATCH_DRIVER: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchDriver"); + add_group_entry(&ptr->match_driver, + xstrtokenize(xf86_lex_val.str, TOKEN_SEP)); + free(xf86_lex_val.str); + break; + case EOF_TOKEN: + Error(UNEXPECTED_EOF_MSG); + break; + default: + Error(INVALID_KEYWORD_MSG, xf86tokenString()); + break; + } + } + + if (!has_ident) + Error(NO_IDENT_MSG); + +#ifdef DEBUG + printf("OutputClass section parsed\n"); +#endif + + return ptr; +} +void +xf86printOutputClassSection(FILE * cf, XF86ConfOutputClassPtr ptr) +{ + const xf86MatchGroup *group; + char *const *cur; + + while (ptr) { + fprintf(cf, "Section \"OutputClass\"\n"); + if (ptr->comment) + fprintf(cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf(cf, "\tIdentifier \"%s\"\n", ptr->identifier); + if (ptr->driver) + fprintf(cf, "\tDriver \"%s\"\n", ptr->driver); + + xorg_list_for_each_entry(group, &ptr->match_driver, entry) { + fprintf(cf, "\tMatchDriver \""); + for (cur = group->values; *cur; cur++) + fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, + *cur); + fprintf(cf, "\"\n"); + } + + fprintf(cf, "EndSection\n\n"); + ptr = ptr->list.next; + } +} + +void +xf86freeOutputClassList(XF86ConfOutputClassPtr ptr) +{ + XF86ConfOutputClassPtr prev; + + while (ptr) { + xf86MatchGroup *group, *next; + char **list; + + TestFree(ptr->identifier); + TestFree(ptr->comment); + TestFree(ptr->driver); + + xorg_list_for_each_entry_safe(group, next, &ptr->match_driver, entry) { + xorg_list_del(&group->entry); + for (list = group->values; *list; list++) + free(*list); + free(group); + } + + prev = ptr; + ptr = ptr->list.next; + free(prev); + } +} diff --git a/hw/xfree86/parser/configProcs.h b/hw/xfree86/parser/configProcs.h index 60509dcd8..774e2a2da 100644 --- a/hw/xfree86/parser/configProcs.h +++ b/hw/xfree86/parser/configProcs.h @@ -57,6 +57,11 @@ XF86ConfInputClassPtr xf86parseInputClassSection(void); void xf86printInputClassSection(FILE * f, XF86ConfInputClassPtr ptr); void xf86freeInputClassList(XF86ConfInputClassPtr ptr); +/* OutputClass.c */ +XF86ConfOutputClassPtr xf86parseOutputClassSection(void); +void xf86printOutputClassSection(FILE * f, XF86ConfOutputClassPtr ptr); +void xf86freeOutputClassList(XF86ConfOutputClassPtr ptr); + /* Layout.c */ XF86ConfLayoutPtr xf86parseLayoutSection(void); void xf86printLayoutSection(FILE * cf, XF86ConfLayoutPtr ptr); diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c index 2478b074b..22f6e6af4 100644 --- a/hw/xfree86/parser/read.c +++ b/hw/xfree86/parser/read.c @@ -165,6 +165,12 @@ xf86readConfigFile(void) HANDLE_LIST(conf_inputclass_lst, xf86parseInputClassSection, XF86ConfInputClassPtr); } + else if (xf86nameCompare(xf86_lex_val.str, "outputclass") == 0) { + free(xf86_lex_val.str); + xf86_lex_val.str = NULL; + HANDLE_LIST(conf_outputclass_lst, xf86parseOutputClassSection, + XF86ConfOutputClassPtr); + } else if (xf86nameCompare(xf86_lex_val.str, "module") == 0) { free(xf86_lex_val.str); xf86_lex_val.str = NULL; diff --git a/hw/xfree86/parser/write.c b/hw/xfree86/parser/write.c index 26739b933..472b27ba1 100644 --- a/hw/xfree86/parser/write.c +++ b/hw/xfree86/parser/write.c @@ -114,6 +114,8 @@ doWriteConfigFile(const char *filename, XF86ConfigPtr cptr) xf86printInputClassSection(cf, cptr->conf_inputclass_lst); + xf86printOutputClassSection(cf, cptr->conf_outputclass_lst); + xf86printVideoAdaptorSection(cf, cptr->conf_videoadaptor_lst); xf86printModesSection(cf, cptr->conf_modes_lst); diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h index c95423a1f..3fa5b716d 100644 --- a/hw/xfree86/parser/xf86Parser.h +++ b/hw/xfree86/parser/xf86Parser.h @@ -327,6 +327,14 @@ typedef struct { char *comment; } XF86ConfInputClassRec, *XF86ConfInputClassPtr; +typedef struct { + GenericListRec list; + char *identifier; + char *driver; + struct xorg_list match_driver; + char *comment; +} XF86ConfOutputClassRec, *XF86ConfOutputClassPtr; + /* Values for adj_where */ #define CONF_ADJ_OBSOLETE -1 #define CONF_ADJ_ABSOLUTE 0 @@ -411,6 +419,7 @@ typedef struct { XF86ConfScreenPtr conf_screen_lst; XF86ConfInputPtr conf_input_lst; XF86ConfInputClassPtr conf_inputclass_lst; + XF86ConfOutputClassPtr conf_outputclass_lst; XF86ConfLayoutPtr conf_layout_lst; XF86ConfVendorPtr conf_vendor_lst; XF86ConfDRIPtr conf_dri; From eeefecd9df88920d4dca4100a84a135f7f53dd82 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Feb 2014 13:54:23 +0100 Subject: [PATCH 22/40] xfree86: Support driver loading via OutputClass Use the OutputClass configuration to determine what drivers to autoload for a given device. Reviewed-by: Aaron Plattner Tested-By: Aaron Plattner Signed-off-by: Thierry Reding Tested-by: Rob Clark Signed-off-by: Keith Packard --- hw/xfree86/common/xf86platformBus.c | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index 672e2e519..eb1a3fb5d 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -47,6 +47,7 @@ #include "xf86Bus.h" #include "Pci.h" #include "xf86platformBus.h" +#include "xf86Config.h" #include "randrstr.h" int platformSlotClaimed; @@ -199,6 +200,81 @@ xf86_check_platform_slot(const struct xf86_platform_device *pd) return TRUE; } +static Bool +MatchToken(const char *value, struct xorg_list *patterns, + int (*compare)(const char *, const char *)) +{ + const xf86MatchGroup *group; + + /* If there are no patterns, accept the match */ + if (xorg_list_is_empty(patterns)) + return TRUE; + + /* If there are patterns but no attribute, reject the match */ + if (!value) + return FALSE; + + /* + * Otherwise, iterate the list of patterns ensuring each entry has a + * match. Each list entry is a separate Match line of the same type. + */ + xorg_list_for_each_entry(group, patterns, entry) { + Bool match = FALSE; + char *const *cur; + + for (cur = group->values; *cur; cur++) { + if ((*compare)(value, *cur) == 0) { + match = TRUE; + break; + } + } + + if (!match) + return FALSE; + } + + /* All the entries in the list matched the attribute */ + return TRUE; +} + +static Bool +OutputClassMatches(const XF86ConfOutputClassPtr oclass, int index) +{ + char *driver = xf86_get_platform_attrib(index, ODEV_ATTRIB_DRIVER); + + if (!MatchToken(driver, &oclass->match_driver, strcmp)) + return FALSE; + + return TRUE; +} + +static int +xf86OutputClassDriverList(int index, char *matches[], int nmatches) +{ + XF86ConfOutputClassPtr cl; + int i = 0; + + if (nmatches == 0) + return 0; + + for (cl = xf86configptr->conf_outputclass_lst; cl; cl = cl->list.next) { + if (OutputClassMatches(cl, index)) { + char *path = xf86_get_platform_attrib(index, ODEV_ATTRIB_PATH); + + xf86Msg(X_INFO, "Applying OutputClass \"%s\" to %s\n", + cl->identifier, path); + xf86Msg(X_NONE, "\tloading driver: %s\n", cl->driver); + + matches[i++] = xstrdup(cl->driver); + } + + if (i >= nmatches) + break; + } + + return i; +} + /** * @return The numbers of found devices that match with the current system * drivers. @@ -218,6 +294,8 @@ xf86PlatformMatchDriver(char *matches[], int nmatches) else if (!xf86IsPrimaryPlatform(&xf86_platform_devices[i]) && (pass == 0)) continue; + j += xf86OutputClassDriverList(i, &matches[j], nmatches - j); + info = xf86_platform_devices[i].pdev; #ifdef __linux__ if (info) From b6cc489838dca0bcec7e9dbb4663b871e8cb7bc8 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Feb 2014 21:09:49 +0100 Subject: [PATCH 23/40] xfree86: Make error message more readable While at it also replace a tab by four spaces for consistency. Reviewed-by: Aaron Plattner Tested-By: Aaron Plattner Signed-off-by: Thierry Reding Reviewed-by: Rob Clark Tested-by: Rob Clark Signed-off-by: Keith Packard --- hw/xfree86/os-support/linux/lnx_platform.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c index 0aaedab21..d660761c5 100644 --- a/hw/xfree86/os-support/linux/lnx_platform.c +++ b/hw/xfree86/os-support/linux/lnx_platform.c @@ -58,8 +58,9 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) err = drmSetInterfaceVersion(fd, &sv); if (err) { - ErrorF("setversion 1.4 failed: %s\n", strerror(-err)); - goto out; + xf86Msg(X_ERROR, "%s: failed to set DRM interface version 1.4: %s\n", + path, strerror(-err)); + goto out; } /* for a delayed probe we've already added the device */ From 9308eafb7d303739b81634ed2ee0da88554fd429 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 7 Jul 2014 16:28:26 -0700 Subject: [PATCH 24/40] Update to version 1.15.99.904 One more RC to get the non-PCI patches tested before release Signed-off-by: Keith Packard --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 2daa6beec..c214638d3 100644 --- a/configure.ac +++ b/configure.ac @@ -26,9 +26,9 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.15.99.903, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2014-06-04" -RELEASE_NAME="Strawberry Shortcake" +AC_INIT([xorg-server], 1.15.99.904, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2014-07-07" +RELEASE_NAME="Netarts Bay Oysters" AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) From daa1a9d22db8e83d1933d8403acf72626199ee2a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 7 Jul 2014 08:27:44 +1000 Subject: [PATCH 25/40] os: prevent negative array index access (#80890) If an empty string is provided to LogMessageVerbSigSafe, the length of the printed string is 0. Read-only access only and the only effect it had was adding a linebreak or not. X.Org Bug 80890 Signed-off-by: Peter Hutterer --- os/log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/log.c b/os/log.c index a368569d0..2a721b948 100644 --- a/os/log.c +++ b/os/log.c @@ -697,7 +697,7 @@ LogVMessageVerbSigSafe(MessageType type, int verb, const char *format, va_list a if (sizeof(buf) - len == 1) buf[len - 1] = '\n'; - newline = (buf[len - 1] == '\n'); + newline = (len > 0 && buf[len - 1] == '\n'); LogSWrite(verb, buf, len, newline); } From 578b9283bcc129d0a35fabe2637c7622085ef1e8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 Jul 2014 10:39:50 +1000 Subject: [PATCH 26/40] xfree86: don't force the screensaver off on DPMS unblank, merely suggest it Commit 41d4beb2616ceb3f1a1b8694733e85bae70de59a added symmetry to the screensaver/DPMS invocations so that one (en|dis)ables the other. Having dependencies between DPMS and the screensaver is subject to further arguments, but in this particular case using SCREENSAVER_FORCER is detrimental. SCREENSAVER_FORCER(ScreenSaverReset) resets the idle time for all devices on DPMS unblank. It prevents at least one use-case that GNOME tries to implement: GNOME displays a notification before suspending. If the display is currently blanked, GNOME lights it up to display the message. With the original patch in place DPMS unblank also resets the device idle times, thus restarting the timeout ad infinitum. Switch this to a more suggestive SCREENSAVER_OFF(ScreenSaverReset). This keeps the symmetry in blanking mode (DPMS and screensaver turn each other on/off as expected) but does not reset the idle time on the devices. https://bugzilla.gnome.org/show_bug.cgi?id=731241 Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede Reviewed-By: Egbert Eich --- hw/xfree86/common/xf86DPMS.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/common/xf86DPMS.c b/hw/xfree86/common/xf86DPMS.c index 14d1f4545..2b5a3ed1e 100644 --- a/hw/xfree86/common/xf86DPMS.c +++ b/hw/xfree86/common/xf86DPMS.c @@ -166,7 +166,7 @@ DPMSSet(ClientPtr client, int level) return rc; } } else if (!xf86IsUnblank(screenIsSaved)) { - rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, ScreenSaverReset); + rc = dixSaveScreens(client, SCREEN_SAVER_OFF, ScreenSaverReset); if (rc != Success) return rc; } From acc0b5edd1dc560b5c39dc44872b46581ec23903 Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Fri, 11 Jul 2014 15:56:35 -0700 Subject: [PATCH 27/40] xfree86: Only support one sysconfigdir When the X server is compiled with --prefix set to something other than /usr, then it ends up with a nonstandard sysconfigdir in its .pc file. This causes various other components to install their xorg.conf.d snippets there. However, the X server first looks for /usr/share/X11/xorg.conf.d before looking in sysconfigdir. That means that if the system administrator installed anything that created that path, the user's custom sysconfigdir is not searched. Rather than doing that, just look in the configured sysconfdir and nowhere else. Signed-off-by: Aaron Plattner Reviewed-by: Julien Cristau Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- hw/xfree86/common/xf86Config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 481674de2..779ba6f7c 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -103,7 +103,7 @@ "/etc/X11/%X," "%C/X11/%X" #endif #ifndef SYS_CONFIGDIRPATH -#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X" +#define SYS_CONFIGDIRPATH "%D/X11/%X" #endif #ifndef PROJECTROOT #define PROJECTROOT "/usr/X11R6" From 9a19bf06b5b409fa0d5b5932e29cd4c5545052c5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 14 Jul 2014 15:05:58 +1000 Subject: [PATCH 28/40] Revert "dix: fix up coordinate scaling when external monitors are present" This reverts commit d90b5f83010248be65b2039b0b2d0b9e6a4e93cf. Reverting for two reasons: * the scaling does not work on devices that don't advertise resolution, and the default resolution used (100 units/mm) is higher than most devices, resulting in a significant slowdown of the touchpads. * the scaling is still affected by resolution changing. The patch worked before acceleration but since it maps into resolution-dependent dx/dy coordinates the acceleration may distort the movement after the fact. So the same input data generates different movements depending on the resolution. This can't easily be fixed for all affected devices as synaptics has its own velocity calculation method whereas wacom doesn't. So anything in the server won't work for both at the same time. Revert this for now, until a more integrated solution can be implemented. --- dix/getevents.c | 80 +++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 60 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index d68fa96d7..ffa89fad2 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -770,65 +770,27 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl } -/* FIXME: relative events from devices with absolute axis ranges is - fundamentally broken. We map the device coordinate range into the screen - range, but don't really account for device resolution in that. - - what we do here is a hack to make touchpads usable. for a given relative - motion vector in device coordinates: - 1. calculate physical movement on the device in metres - 2. calculate pixel vector that is the same physical movement on the - screen (times some magic number to provide sensible base speed) - 3. calculate what percentage this vector is of the current screen - width/height - 4. calculate equivalent vector in % on the device's min/max axis range - 5. Use that device vector as the actual motion vector - - e.g. 10/50mm on the device, 10/50mm on the screen are 30/100 pixels, - 30/100 pixels are 1/3% of the width, 1/3% of the device is a vector of - 20/80 -> use 20/80 as dx/dy. - - dx/dy is then applied to the current position in device coordinates, - mapped to screen coordinates and thus the movement on the screen reflects - the motion direction on the device. - */ static void scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask) { - double x, y; + double y; ValuatorClassPtr v = dev->valuator; int xrange = v->axes[0].max_value - v->axes[0].min_value + 1; int yrange = v->axes[1].max_value - v->axes[1].min_value + 1; - /* Assume 100 units/m for devices without resolution */ - int xres = 100000, yres = 100000; + double screen_ratio = 1.0 * screenInfo.width/screenInfo.height; + double device_ratio = 1.0 * xrange/yrange; + double resolution_ratio = 1.0; + double ratio; - /* If we have multiple screens with different dpi, it gets complicated: - we have to map which screen we're on and then take the dpi of that - screen to be somewhat accurate. */ - const ScreenPtr s = screenInfo.screens[0]; - const double screen_res = 1000.0 * s->width/s->mmWidth; /* units/m */ + if (!valuator_mask_fetch_double(mask, 1, &y)) + return; - /* some magic multiplier, so unaccelerated movement of x mm on the - device reflects x * magic mm on the screen */ - const double magic = 4; + if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0) + resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution; - if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0) { - xres = v->axes[0].resolution; - yres = v->axes[1].resolution; - } - - if (valuator_mask_isset(mask, 0)) { - x = valuator_mask_get_double(mask, 0); - x = magic * x/xres * screen_res/screenInfo.width * xrange; - valuator_mask_set_double(mask, 0, x); - } - - if (valuator_mask_isset(mask, 1)) { - y = valuator_mask_get_double(mask, 1); - y = magic * y/yres * screen_res/screenInfo.height * yrange; - valuator_mask_set_double(mask, 1, y); - } + ratio = device_ratio/resolution_ratio/screen_ratio; + valuator_mask_set_double(mask, 1, y / ratio); } /** @@ -842,6 +804,15 @@ moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask) { int i; Bool clip_xy = IsMaster(dev) || !IsFloating(dev); + ValuatorClassPtr v = dev->valuator; + + /* for abs devices in relative mode, we've just scaled wrong, since we + mapped the device's shape into the screen shape. Undo this. */ + if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 && + v->axes[0].min_value < v->axes[0].max_value && + v->axes[1].min_value < v->axes[1].max_value) { + scale_for_device_resolution(dev, mask); + } /* calc other axes, clip, drop back into valuators */ for (i = 0; i < valuator_mask_size(mask); i++) { @@ -1470,21 +1441,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, set_raw_valuators(raw, &mask, raw->valuators.data); } else { - ValuatorClassPtr v = pDev->valuator; - transformRelative(pDev, &mask); - /* for abs devices in relative mode, we've just scaled wrong, since we - mapped the device's shape into the screen shape. Undo this. */ - if (v && v->numAxes > 1 && - v->axes[0].min_value < v->axes[0].max_value && - v->axes[1].min_value < v->axes[1].max_value) { - scale_for_device_resolution(pDev, &mask); - } - if (flags & POINTER_ACCELERATE) accelPointer(pDev, &mask, ms); - if ((flags & POINTER_NORAW) == 0 && raw) set_raw_valuators(raw, &mask, raw->valuators.data); From 25eca7ce35973577c8d85704c270f7fb53e6732e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 14 Jul 2014 14:01:46 +0200 Subject: [PATCH 29/40] Fix ODEV_ATTRIB_DRIVER overlapping with ODEV_ATTRIB_FD Looks like the value of ODEV_ATTRIB_DRIVER was not updated when the patch adding it got rebased on top of a newer server version. This fixes the xserver crashing when systemd-logind integration is used. https://bugzilla.redhat.com/show_bug.cgi?id=1118540 Signed-off-by: Hans de Goede Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- include/hotplug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hotplug.h b/include/hotplug.h index c4268a0c4..b2c0d78a5 100644 --- a/include/hotplug.h +++ b/include/hotplug.h @@ -88,7 +88,7 @@ config_odev_free_attributes(struct OdevAttributes *attribs); /* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */ #define ODEV_ATTRIB_MINOR 6 /* kernel driver name */ -#define ODEV_ATTRIB_DRIVER 4 +#define ODEV_ATTRIB_DRIVER 7 typedef void (*config_odev_probe_proc_ptr)(struct OdevAttributes *attribs); void config_odev_probe(config_odev_probe_proc_ptr probe_callback); From 4dbb641bb2d4037f107b58b31e80963dc8b72c0e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 14 Jul 2014 14:01:47 +0200 Subject: [PATCH 30/40] config_odev_add_attribute*: Check for right attribute type Don't allow setting string attributes to integers and vice versa. Signed-off-by: Hans de Goede Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- config/config.c | 32 ++++++++++++++++++++++++++++++++ include/hotplug.h | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/config/config.c b/config/config.c index 551451623..a26d835e1 100644 --- a/config/config.c +++ b/config/config.c @@ -172,12 +172,38 @@ config_odev_find_or_add_attribute(struct OdevAttributes *attribs, int attrib) return oa; } +static int config_odev_get_attribute_type(int attrib) +{ + switch (attrib) { + case ODEV_ATTRIB_PATH: + case ODEV_ATTRIB_SYSPATH: + case ODEV_ATTRIB_BUSID: + return ODEV_ATTRIB_STRING; + case ODEV_ATTRIB_FD: + case ODEV_ATTRIB_MAJOR: + case ODEV_ATTRIB_MINOR: + return ODEV_ATTRIB_INT; + case ODEV_ATTRIB_DRIVER: + return ODEV_ATTRIB_STRING; + default: + LogMessage(X_ERROR, "Error %s called for unknown attribute %d\n", + __func__, attrib); + return ODEV_ATTRIB_UNKNOWN; + } +} + Bool config_odev_add_attribute(struct OdevAttributes *attribs, int attrib, const char *attrib_name) { struct OdevAttribute *oa; + if (config_odev_get_attribute_type(attrib) != ODEV_ATTRIB_STRING) { + LogMessage(X_ERROR, "Error %s called for non string attrib %d\n", + __func__, attrib); + return FALSE; + } + oa = config_odev_find_or_add_attribute(attribs, attrib); free(oa->attrib_name); oa->attrib_name = XNFstrdup(attrib_name); @@ -191,6 +217,12 @@ config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib, { struct OdevAttribute *oa; + if (config_odev_get_attribute_type(attrib) != ODEV_ATTRIB_INT) { + LogMessage(X_ERROR, "Error %s called for non integer attrib %d\n", + __func__, attrib); + return FALSE; + } + oa = config_odev_find_or_add_attribute(attribs, attrib); oa->attrib_value = attrib_value; oa->attrib_type = ODEV_ATTRIB_INT; diff --git a/include/hotplug.h b/include/hotplug.h index b2c0d78a5..4c2fa970c 100644 --- a/include/hotplug.h +++ b/include/hotplug.h @@ -32,7 +32,7 @@ extern _X_EXPORT void config_pre_init(void); extern _X_EXPORT void config_init(void); extern _X_EXPORT void config_fini(void); -enum { ODEV_ATTRIB_STRING, ODEV_ATTRIB_INT }; +enum { ODEV_ATTRIB_UNKNOWN = -1, ODEV_ATTRIB_STRING = 0, ODEV_ATTRIB_INT }; struct OdevAttribute { struct xorg_list member; From 8b36e1ec8dd9f53e9f4e10422c2100844e9e549c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 17 Jul 2014 00:03:33 -0700 Subject: [PATCH 31/40] Update to version 1.16.0 Signed-off-by: Keith Packard --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index c214638d3..1c327fd59 100644 --- a/configure.ac +++ b/configure.ac @@ -26,9 +26,9 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.15.99.904, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2014-07-07" -RELEASE_NAME="Netarts Bay Oysters" +AC_INIT([xorg-server], 1.16.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2014-07-16" +RELEASE_NAME="Marionberry Pie" AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) From 5eb77697ea35e7dc8cb8af2c3b5d8ffdba0fb632 Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Mon, 10 Mar 2014 18:31:33 -0400 Subject: [PATCH 32/40] Avoid starting a comment with */* Even though -Wcomment doesn't mind it (in gcc or clang), the appearance of */* confuses the syntax highlighter of some editors (eg. vim), and causes warnings in MSVC. Signed-off-by: Peter Harris Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- include/callback.h | 18 +++++------ include/colormap.h | 16 +++++----- include/cursor.h | 4 +-- include/dix.h | 69 ++++++++++++++++++----------------------- include/dixfont.h | 10 +++--- include/dixgrabs.h | 4 +-- include/gc.h | 4 +-- include/gcstruct.h | 36 ++++++++++----------- include/input.h | 8 ++--- include/os.h | 52 +++++++++++++++---------------- include/pixmap.h | 14 ++++----- include/property.h | 34 ++++++++++---------- include/resource.h | 74 ++++++++++++++++++++++---------------------- include/scrnintstr.h | 26 ++++++++-------- include/window.h | 20 ++++++------ include/xkbsrv.h | 18 +++++------ mi/mi.h | 74 ++++++++++++++++++++++---------------------- os/access.c | 6 ++-- 18 files changed, 239 insertions(+), 248 deletions(-) diff --git a/include/callback.h b/include/callback.h index df638c0d4..fe7015ee7 100644 --- a/include/callback.h +++ b/include/callback.h @@ -64,16 +64,16 @@ typedef struct _CallbackList *CallbackListPtr; /* also in misc.h */ typedef void (*CallbackProcPtr) (CallbackListPtr *, void *, void *); -extern _X_EXPORT Bool AddCallback(CallbackListPtr * /*pcbl */ , - CallbackProcPtr /*callback */ , - void */*data */ ); +extern _X_EXPORT Bool AddCallback(CallbackListPtr *pcbl, + CallbackProcPtr callback, + void *data); -extern _X_EXPORT Bool DeleteCallback(CallbackListPtr * /*pcbl */ , - CallbackProcPtr /*callback */ , - void */*data */ ); +extern _X_EXPORT Bool DeleteCallback(CallbackListPtr *pcbl, + CallbackProcPtr callback, + void *data); -extern _X_EXPORT void _CallCallbacks(CallbackListPtr * /*pcbl */ , - void */*call_data */ ); +extern _X_EXPORT void _CallCallbacks(CallbackListPtr *pcbl, + void *call_data); static inline void CallCallbacks(CallbackListPtr *pcbl, void *call_data) @@ -83,7 +83,7 @@ CallCallbacks(CallbackListPtr *pcbl, void *call_data) _CallCallbacks(pcbl, call_data); } -extern _X_EXPORT void DeleteCallbackList(CallbackListPtr * /*pcbl */ ); +extern _X_EXPORT void DeleteCallbackList(CallbackListPtr *pcbl); extern _X_EXPORT void InitCallbackManager(void); extern _X_EXPORT void DeleteCallbackManager(void); diff --git a/include/colormap.h b/include/colormap.h index 22229ca84..b89bbe114 100644 --- a/include/colormap.h +++ b/include/colormap.h @@ -82,14 +82,14 @@ extern _X_EXPORT int CreateColormap(Colormap /*mid */ , int /*alloc */ , int /*client */ ); -extern _X_EXPORT int FreeColormap(void */*pmap */ , - XID /*mid */ ); +extern _X_EXPORT int FreeColormap(void *pmap, + XID mid); -extern _X_EXPORT int TellLostMap(WindowPtr /*pwin */ , - void */* Colormap *pmid */ ); +extern _X_EXPORT int TellLostMap(WindowPtr pwin, + void *value); -extern _X_EXPORT int TellGainedMap(WindowPtr /*pwin */ , - void */* Colormap *pmid */ ); +extern _X_EXPORT int TellGainedMap(WindowPtr pwin, + void *value); extern _X_EXPORT int CopyColormapAndFree(Colormap /*mid */ , ColormapPtr /*pSrc */ , @@ -126,8 +126,8 @@ extern _X_EXPORT int QueryColors(ColormapPtr /*pmap */ , xrgb * /*prgbList */ , ClientPtr client); -extern _X_EXPORT int FreeClientPixels(void */*pcr */ , - XID /*fakeid */ ); +extern _X_EXPORT int FreeClientPixels(void *pcr, + XID fakeid); extern _X_EXPORT int AllocColorCells(int /*client */ , ColormapPtr /*pmap */ , diff --git a/include/cursor.h b/include/cursor.h index 9da08affd..1e483ac40 100644 --- a/include/cursor.h +++ b/include/cursor.h @@ -68,8 +68,8 @@ extern _X_EXPORT DevScreenPrivateKeyRec cursorScreenDevPriv; extern _X_EXPORT CursorPtr rootCursor; -extern _X_EXPORT int FreeCursor(void */*pCurs */ , - XID /*cid */ ); +extern _X_EXPORT int FreeCursor(void *pCurs, + XID cid); extern _X_EXPORT CursorPtr RefCursor(CursorPtr /* cursor */); extern _X_EXPORT CursorPtr UnrefCursor(CursorPtr /* cursor */); diff --git a/include/dix.h b/include/dix.h index f42e23655..61ecc8df2 100644 --- a/include/dix.h +++ b/include/dix.h @@ -147,14 +147,14 @@ extern _X_EXPORT void UpdateCurrentTime(void); extern _X_EXPORT void UpdateCurrentTimeIf(void); -extern _X_EXPORT int dixDestroyPixmap(void */*value */ , - XID /*pid */ ); +extern _X_EXPORT int dixDestroyPixmap(void *value, + XID pid); -extern _X_EXPORT void InitClient(ClientPtr /*client */ , - int /*i */ , - void */*ospriv */ ); +extern _X_EXPORT void InitClient(ClientPtr client, + int i, + void *ospriv); -extern _X_EXPORT ClientPtr NextAvailableClient(void */*ospriv */ ); +extern _X_EXPORT ClientPtr NextAvailableClient(void *ospriv); extern _X_EXPORT void SendErrorToClient(ClientPtr /*client */ , unsigned int /*majorCode */ , @@ -203,11 +203,11 @@ extern _X_EXPORT int AlterSaveSetForClient(ClientPtr /*client */ , extern _X_EXPORT void DeleteWindowFromAnySaveSet(WindowPtr /*pWin */ ); -extern _X_EXPORT void BlockHandler(void */*pTimeout */ , - void */*pReadmask */ ); +extern _X_EXPORT void BlockHandler(void *pTimeout, + void *pReadmask); -extern _X_EXPORT void WakeupHandler(int /*result */ , - void */*pReadmask */ ); +extern _X_EXPORT void WakeupHandler(int result, + void *pReadmask); void EnableLimitedSchedulingLatency(void); @@ -215,21 +215,17 @@ void void DisableLimitedSchedulingLatency(void); -typedef void (*WakeupHandlerProcPtr) (void */* blockData */ , - int /* result */ , - void */* pReadmask */ ); +typedef void (*WakeupHandlerProcPtr) (void *blockData, + int result, + void *pReadmask); -extern _X_EXPORT Bool RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr - /*blockHandler */ , - WakeupHandlerProcPtr - /*wakeupHandler */ , - void */*blockData */ ); +extern _X_EXPORT Bool RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler, + WakeupHandlerProcPtr wakeupHandler, + void *blockData); -extern _X_EXPORT void RemoveBlockAndWakeupHandlers(BlockHandlerProcPtr - /*blockHandler */ , - WakeupHandlerProcPtr - /*wakeupHandler */ , - void */*blockData */ ); +extern _X_EXPORT void RemoveBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler, + WakeupHandlerProcPtr wakeupHandler, + void *blockData); extern _X_EXPORT void InitBlockAndWakeupHandlers(void); @@ -237,22 +233,17 @@ extern _X_EXPORT void ProcessWorkQueue(void); extern _X_EXPORT void ProcessWorkQueueZombies(void); -extern _X_EXPORT Bool QueueWorkProc(Bool (* /*function */ )( - ClientPtr - /*clientUnused */ - , - void * - /*closure */ ), - ClientPtr /*client */ , - void */*closure */ - ); +extern _X_EXPORT Bool QueueWorkProc(Bool (*function)(ClientPtr clientUnused, + void *closure), + ClientPtr client, + void *closure); -typedef Bool (*ClientSleepProcPtr) (ClientPtr /*client */ , - void */*closure */ ); +typedef Bool (*ClientSleepProcPtr) (ClientPtr client, + void *closure); -extern _X_EXPORT Bool ClientSleep(ClientPtr /*client */ , - ClientSleepProcPtr /* function */ , - void */*closure */ ); +extern _X_EXPORT Bool ClientSleep(ClientPtr client, + ClientSleepProcPtr function, + void *closure); #ifndef ___CLIENTSIGNAL_DEFINED___ #define ___CLIENTSIGNAL_DEFINED___ @@ -444,8 +435,8 @@ extern void RecalculateDeliverableEvents(WindowPtr /* pWin */ ); extern _X_EXPORT int -OtherClientGone(void */* value */ , - XID /* id */ ); +OtherClientGone(void *value, + XID id); extern void DoFocusEvents(DeviceIntPtr /* dev */ , diff --git a/include/dixfont.h b/include/dixfont.h index 40d80c141..48c630539 100644 --- a/include/dixfont.h +++ b/include/dixfont.h @@ -40,9 +40,9 @@ extern _X_EXPORT void QueueFontWakeup(FontPathElementPtr /*fpe */ ); extern _X_EXPORT void RemoveFontWakeup(FontPathElementPtr /*fpe */ ); -extern _X_EXPORT void FontWakeup(void */*data */ , - int /*count */ , - void */*LastSelectMask */ ); +extern _X_EXPORT void FontWakeup(void *data, + int count, + void *LastSelectMask); extern _X_EXPORT int OpenFont(ClientPtr /*client */ , XID /*fid */ , @@ -50,8 +50,8 @@ extern _X_EXPORT int OpenFont(ClientPtr /*client */ , unsigned /*lenfname */ , const char * /*pfontname */ ); -extern _X_EXPORT int CloseFont(void */*pfont */ , - XID /*fid */ ); +extern _X_EXPORT int CloseFont(void *pfont, + XID fid); typedef struct _xQueryFontReply *xQueryFontReplyPtr; diff --git a/include/dixgrabs.h b/include/dixgrabs.h index d78d8127b..3bd80132b 100644 --- a/include/dixgrabs.h +++ b/include/dixgrabs.h @@ -47,8 +47,8 @@ extern GrabPtr CreateGrab(int /* client */ , WindowPtr /* confineTo */ , CursorPtr /* cursor */ ); -extern _X_EXPORT int DeletePassiveGrab(void */* value */ , - XID /* id */ ); +extern _X_EXPORT int DeletePassiveGrab(void *value, + XID id); extern _X_EXPORT Bool GrabMatchesSecond(GrabPtr /* pFirstGrab */ , GrabPtr /* pSecondGrab */ , diff --git a/include/gc.h b/include/gc.h index ecaa257bb..eb0a5835e 100644 --- a/include/gc.h +++ b/include/gc.h @@ -112,8 +112,8 @@ extern _X_EXPORT int CopyGC(GCPtr /*pgcSrc */ , GCPtr /*pgcDst */ , BITS32 /*mask */ ); -extern _X_EXPORT int FreeGC(void */*pGC */ , - XID /*gid */ ); +extern _X_EXPORT int FreeGC(void *pGC, + XID gid); extern _X_EXPORT void FreeGCperDepth(int /*screenNum */ ); diff --git a/include/gcstruct.h b/include/gcstruct.h index c830ccde7..6358b8cb7 100644 --- a/include/gcstruct.h +++ b/include/gcstruct.h @@ -76,10 +76,10 @@ typedef struct _GCFuncs { void (*DestroyGC) (GCPtr /*pGC */ ); - void (*ChangeClip) (GCPtr /*pGC */ , - int /*type */ , - void */*pvalue */ , - int /*nrects */ ); + void (*ChangeClip) (GCPtr pGC, + int type, + void *pvalue, + int nrects); void (*DestroyClip) (GCPtr /*pGC */ ); @@ -210,21 +210,21 @@ typedef struct _GCOps { int /*count */ , unsigned short * /*chars */ ); - void (*ImageGlyphBlt) (DrawablePtr /*pDrawable */ , - GCPtr /*pGC */ , - int /*x */ , - int /*y */ , - unsigned int /*nglyph */ , - CharInfoPtr * /*ppci */ , - void */*pglyphBase */ ); + void (*ImageGlyphBlt) (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + void *pglyphBase); - void (*PolyGlyphBlt) (DrawablePtr /*pDrawable */ , - GCPtr /*pGC */ , - int /*x */ , - int /*y */ , - unsigned int /*nglyph */ , - CharInfoPtr * /*ppci */ , - void */*pglyphBase */ ); + void (*PolyGlyphBlt) (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + void *pglyphBase); void (*PushPixels) (GCPtr /*pGC */ , PixmapPtr /*pBitMap */ , diff --git a/include/input.h b/include/input.h index cbf949b53..1b2102fc1 100644 --- a/include/input.h +++ b/include/input.h @@ -314,10 +314,10 @@ extern _X_EXPORT Bool InitTouchClassDeviceStruct(DeviceIntPtr /*device */ , unsigned int /*mode */ , unsigned int /*numAxes */ ); -typedef void (*BellProcPtr) (int /*percent */ , - DeviceIntPtr /*device */ , - void */*ctrl */ , - int); +typedef void (*BellProcPtr) (int percent, + DeviceIntPtr device, + void *ctrl, + int feedbackClass); typedef void (*KbdCtrlProcPtr) (DeviceIntPtr /*device */ , KeybdCtrl * /*ctrl */ ); diff --git a/include/os.h b/include/os.h index d26e399b6..0cbb9288e 100644 --- a/include/os.h +++ b/include/os.h @@ -139,8 +139,8 @@ extern _X_EXPORT const char *ClientAuthorized(ClientPtr /*client */ , unsigned int /*string_n */ , char * /*auth_string */ ); -extern _X_EXPORT Bool EstablishNewConnections(ClientPtr /*clientUnused */ , - void */*closure */ ); +extern _X_EXPORT Bool EstablishNewConnections(ClientPtr clientUnused, + void *closure); extern _X_EXPORT void CheckConnections(void); @@ -173,14 +173,14 @@ extern _X_EXPORT Bool AddClientOnOpenFD(int /* fd */ ); extern _X_EXPORT CARD32 GetTimeInMillis(void); extern _X_EXPORT CARD64 GetTimeInMicros(void); -extern _X_EXPORT void AdjustWaitForDelay(void */*waitTime */ , - unsigned long /*newdelay */ ); +extern _X_EXPORT void AdjustWaitForDelay(void *waitTime, + unsigned long newdelay); typedef struct _OsTimerRec *OsTimerPtr; -typedef CARD32 (*OsTimerCallback) (OsTimerPtr /* timer */ , - CARD32 /* time */ , - void */* arg */ ); +typedef CARD32 (*OsTimerCallback) (OsTimerPtr timer, + CARD32 time, + void *arg); extern _X_EXPORT void TimerInit(void); @@ -189,11 +189,11 @@ extern _X_EXPORT Bool TimerForce(OsTimerPtr /* timer */ ); #define TimerAbsolute (1<<0) #define TimerForceOld (1<<1) -extern _X_EXPORT OsTimerPtr TimerSet(OsTimerPtr /* timer */ , - int /* flags */ , - CARD32 /* millis */ , - OsTimerCallback /* func */ , - void */* arg */ ); +extern _X_EXPORT OsTimerPtr TimerSet(OsTimerPtr timer, + int flags, + CARD32 millis, + OsTimerCallback func, + void *arg); extern _X_EXPORT void TimerCheck(void); extern _X_EXPORT void TimerCancel(OsTimerPtr /* pTimer */ ); @@ -210,9 +210,9 @@ extern _X_EXPORT void UseMsg(void); extern _X_EXPORT void ProcessCommandLine(int /*argc */ , char * /*argv */ []); -extern _X_EXPORT int set_font_authorizations(char ** /* authorizations */ , - int * /*authlen */ , - void */* client */ ); +extern _X_EXPORT int set_font_authorizations(char **authorizations, + int *authlen, + void *client); #ifndef _HAVE_XALLOC_DECLS #define _HAVE_XALLOC_DECLS @@ -391,18 +391,18 @@ AddHost(ClientPtr /*client */ , const void * /*pAddr */ ); extern _X_EXPORT Bool -ForEachHostInFamily(int /*family */ , - Bool (* /*func */ )( - unsigned char * /* addr */ , - short /* len */ , - void */* closure */ ), - void */*closure */ ); +ForEachHostInFamily(int family, + Bool (*func)( + unsigned char *addr, + short len, + void *closure), + void *closure); extern _X_EXPORT int -RemoveHost(ClientPtr /*client */ , - int /*family */ , - unsigned /*length */ , - void */*pAddr */ ); +RemoveHost(ClientPtr client, + int family, + unsigned length, + void *pAddr); extern _X_EXPORT int GetHosts(void ** /*data */ , @@ -464,7 +464,7 @@ DefineSelf(int /*fd */ ); #if XDMCP extern _X_EXPORT void -AugmentSelf(void */*from */ , int /*len */ ); +AugmentSelf(void *from, int len); extern _X_EXPORT void RegisterAuthorizations(void); diff --git a/include/pixmap.h b/include/pixmap.h index 46ec3f5a2..f3c2c60c0 100644 --- a/include/pixmap.h +++ b/include/pixmap.h @@ -93,13 +93,13 @@ typedef union _PixUnion { #define WindowDrawable(type) \ ((type == DRAWABLE_WINDOW) || (type == UNDRAWABLE_WINDOW)) -extern _X_EXPORT PixmapPtr GetScratchPixmapHeader(ScreenPtr /*pScreen */ , - int /*width */ , - int /*height */ , - int /*depth */ , - int /*bitsPerPixel */ , - int /*devKind */ , - void */*pPixData */ ); +extern _X_EXPORT PixmapPtr GetScratchPixmapHeader(ScreenPtr pScreen, + int width, + int height, + int depth, + int bitsPerPixel, + int devKind, + void *pPixData); extern _X_EXPORT void FreeScratchPixmapHeader(PixmapPtr /*pPixmap */ ); diff --git a/include/property.h b/include/property.h index 3b8ea8b2d..cae44719b 100644 --- a/include/property.h +++ b/include/property.h @@ -57,24 +57,24 @@ extern _X_EXPORT int dixLookupProperty(PropertyPtr * /*result */ , ClientPtr /*pClient */ , Mask /*access_mode */ ); -extern _X_EXPORT int dixChangeWindowProperty(ClientPtr /*pClient */ , - WindowPtr /*pWin */ , - Atom /*property */ , - Atom /*type */ , - int /*format */ , - int /*mode */ , - unsigned long /*len */ , - void */*value */ , - Bool /*sendevent */ ); +extern _X_EXPORT int dixChangeWindowProperty(ClientPtr pClient, + WindowPtr pWin, + Atom property, + Atom type, + int format, + int mode, + unsigned long len, + void *value, + Bool sendevent); -extern _X_EXPORT int ChangeWindowProperty(WindowPtr /*pWin */ , - Atom /*property */ , - Atom /*type */ , - int /*format */ , - int /*mode */ , - unsigned long /*len */ , - void */*value */ , - Bool /*sendevent */ ); +extern _X_EXPORT int ChangeWindowProperty(WindowPtr pWin, + Atom property, + Atom type, + int format, + int mode, + unsigned long len, + void *value, + Bool sendevent); extern _X_EXPORT int DeleteProperty(ClientPtr /*client */ , WindowPtr /*pWin */ , diff --git a/include/resource.h b/include/resource.h index db44aefad..fe56bb2a7 100644 --- a/include/resource.h +++ b/include/resource.h @@ -136,21 +136,21 @@ typedef struct { void *value; } ResourceStateInfoRec; -typedef int (*DeleteType) (void */*value */ , - XID /*id */ ); +typedef int (*DeleteType) (void *value, + XID id); -typedef void (*FindResType) (void */*value */ , - XID /*id */ , - void */*cdata */ ); +typedef void (*FindResType) (void *value, + XID id, + void *cdata); -typedef void (*FindAllRes) (void */*value */ , - XID /*id */ , - RESTYPE /*type */ , - void */*cdata */ ); +typedef void (*FindAllRes) (void *value, + XID id, + RESTYPE type, + void *cdata); -typedef Bool (*FindComplexResType) (void */*value */ , - XID /*id */ , - void */*cdata */ ); +typedef Bool (*FindComplexResType) (void *value, + XID id, + void *cdata); /* Structure for estimating resource memory usage. Memory usage * consists of space allocated for the resource itself and of @@ -166,16 +166,16 @@ typedef struct { unsigned long refCnt; } ResourceSizeRec, *ResourceSizePtr; -typedef void (*SizeType)(void */*value*/, - XID /*id*/, - ResourceSizePtr /*size*/); +typedef void (*SizeType)(void *value, + XID id, + ResourceSizePtr size); -extern _X_EXPORT RESTYPE CreateNewResourceType(DeleteType /*deleteFunc */ , - const char * /*name */ ); +extern _X_EXPORT RESTYPE CreateNewResourceType(DeleteType deleteFunc, + const char *name); -typedef void (*FindTypeSubResources)(void */* value */, - FindAllRes /* func */, - void */* cdata */); +typedef void (*FindTypeSubResources)(void *value, + FindAllRes func, + void *cdata); extern _X_EXPORT SizeType GetResourceTypeSizeFunc( RESTYPE /*type*/); @@ -200,9 +200,9 @@ extern _X_EXPORT XID FakeClientID(int /*client */ ); #ifdef __APPLE__ #define AddResource Darwin_X_AddResource #endif -extern _X_EXPORT Bool AddResource(XID /*id */ , - RESTYPE /*type */ , - void */*value */ ); +extern _X_EXPORT Bool AddResource(XID id, + RESTYPE type, + void *value); extern _X_EXPORT void FreeResource(XID /*id */ , RESTYPE /*skipDeleteFuncType */ ); @@ -211,27 +211,27 @@ extern _X_EXPORT void FreeResourceByType(XID /*id */ , RESTYPE /*type */ , Bool /*skipFree */ ); -extern _X_EXPORT Bool ChangeResourceValue(XID /*id */ , - RESTYPE /*rtype */ , - void */*value */ ); +extern _X_EXPORT Bool ChangeResourceValue(XID id, + RESTYPE rtype, + void *value); -extern _X_EXPORT void FindClientResourcesByType(ClientPtr /*client */ , - RESTYPE /*type */ , - FindResType /*func */ , - void */*cdata */ ); +extern _X_EXPORT void FindClientResourcesByType(ClientPtr client, + RESTYPE type, + FindResType func, + void *cdata); -extern _X_EXPORT void FindAllClientResources(ClientPtr /*client */ , - FindAllRes /*func */ , - void */*cdata */ ); +extern _X_EXPORT void FindAllClientResources(ClientPtr client, + FindAllRes func, + void *cdata); /** @brief Iterate through all subresources of a resource. @note The XID argument provided to the FindAllRes function may be 0 for subresources that don't have an XID */ -extern _X_EXPORT void FindSubResources(void */*resource*/, - RESTYPE /*type*/, - FindAllRes /*func*/, - void */*cdata*/); +extern _X_EXPORT void FindSubResources(void *resource, + RESTYPE type, + FindAllRes func, + void *cdata); extern _X_EXPORT void FreeClientNeverRetainResources(ClientPtr /*client */ ); diff --git a/include/scrnintstr.h b/include/scrnintstr.h index 6acdadd7a..531278126 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -259,23 +259,23 @@ typedef void (*SendGraphicsExposeProcPtr) (ClientPtr /*client */ , int /*major */ , int /*minor */ ); -typedef void (*ScreenBlockHandlerProcPtr) (ScreenPtr /*pScreen*/ , - void */*pTimeout */ , - void */*pReadmask */ ); +typedef void (*ScreenBlockHandlerProcPtr) (ScreenPtr pScreen, + void *pTimeout, + void *pReadmask); -typedef void (*ScreenWakeupHandlerProcPtr) (ScreenPtr /*pScreen*/ , - unsigned long /*result */ , - void */*pReadMask */ ); +typedef void (*ScreenWakeupHandlerProcPtr) (ScreenPtr pScreen, + unsigned long result, + void *pReadMask); typedef Bool (*CreateScreenResourcesProcPtr) (ScreenPtr /*pScreen */ ); -typedef Bool (*ModifyPixmapHeaderProcPtr) (PixmapPtr /*pPixmap */ , - int /*width */ , - int /*height */ , - int /*depth */ , - int /*bitsPerPixel */ , - int /*devKind */ , - void */*pPixData */ ); +typedef Bool (*ModifyPixmapHeaderProcPtr) (PixmapPtr pPixmap, + int width, + int height, + int depth, + int bitsPerPixel, + int devKind, + void *pPixData); typedef PixmapPtr (*GetWindowPixmapProcPtr) (WindowPtr /*pWin */ ); diff --git a/include/window.h b/include/window.h index b5a937eef..c123728f0 100644 --- a/include/window.h +++ b/include/window.h @@ -72,16 +72,16 @@ struct _Cursor; typedef struct _BackingStore *BackingStorePtr; typedef struct _Window *WindowPtr; -typedef int (*VisitWindowProcPtr) (WindowPtr /*pWin */ , - void */*data */ ); +typedef int (*VisitWindowProcPtr) (WindowPtr pWin, + void *data); -extern _X_EXPORT int TraverseTree(WindowPtr /*pWin */ , - VisitWindowProcPtr /*func */ , - void */*data */ ); +extern _X_EXPORT int TraverseTree(WindowPtr pWin, + VisitWindowProcPtr func, + void *data); -extern _X_EXPORT int WalkTree(ScreenPtr /*pScreen */ , - VisitWindowProcPtr /*func */ , - void */*data */ ); +extern _X_EXPORT int WalkTree(ScreenPtr pScreen, + VisitWindowProcPtr func, + void *data); extern _X_EXPORT Bool CreateRootWindow(ScreenPtr /*pScreen */ ); @@ -108,8 +108,8 @@ extern _X_EXPORT WindowPtr CreateWindow(Window /*wid */ , VisualID /*visual */ , int * /*error */ ); -extern _X_EXPORT int DeleteWindow(void */*pWin */ , - XID /*wid */ ); +extern _X_EXPORT int DeleteWindow(void *pWin, + XID wid); extern _X_EXPORT int DestroySubwindows(WindowPtr /*pWin */ , ClientPtr /*client */ ); diff --git a/include/xkbsrv.h b/include/xkbsrv.h index 229de2194..a4878fc9e 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -596,15 +596,15 @@ extern _X_EXPORT void XkbSendCompatMapNotify(DeviceIntPtr /* kbd */ , xkbCompatMapNotify * /* ev */ ); -extern _X_EXPORT void XkbHandleBell(BOOL /* force */ , - BOOL /* eventOnly */ , - DeviceIntPtr /* kbd */ , - CARD8 /* percent */ , - void */* ctrl */ , - CARD8 /* class */ , - Atom /* name */ , - WindowPtr /* pWin */ , - ClientPtr /* pClient */ +extern _X_EXPORT void XkbHandleBell(BOOL force, + BOOL eventOnly, + DeviceIntPtr kbd, + CARD8 percent, + void *ctrl, + CARD8 class, + Atom name, + WindowPtr pWin, + ClientPtr pClient ); extern _X_EXPORT void XkbSendAccessXNotify(DeviceIntPtr /* kbd */ , diff --git a/mi/mi.h b/mi/mi.h index 1209a16c4..483fa3ebe 100644 --- a/mi/mi.h +++ b/mi/mi.h @@ -265,22 +265,22 @@ extern _X_EXPORT void miPolyFillRect(DrawablePtr /*pDrawable */ , /* miglblt.c */ -extern _X_EXPORT void miPolyGlyphBlt(DrawablePtr /*pDrawable */ , - GCPtr /*pGC */ , - int /*x */ , - int /*y */ , - unsigned int /*nglyph */ , - CharInfoPtr * /*ppci */ , - void */*pglyphBase */ +extern _X_EXPORT void miPolyGlyphBlt(DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + void *pglyphBase ); -extern _X_EXPORT void miImageGlyphBlt(DrawablePtr /*pDrawable */ , - GCPtr /*pGC */ , - int /*x */ , - int /*y */ , - unsigned int /*nglyph */ , - CharInfoPtr * /*ppci */ , - void */*pglyphBase */ +extern _X_EXPORT void miImageGlyphBlt(DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + void *pglyphBase ); /* mipoly.c */ @@ -381,36 +381,36 @@ extern _X_EXPORT void miPushPixels(GCPtr /*pGC */ , /* miscrinit.c */ -extern _X_EXPORT Bool miModifyPixmapHeader(PixmapPtr /*pPixmap */ , - int /*width */ , - int /*height */ , - int /*depth */ , - int /*bitsPerPixel */ , - int /*devKind */ , - void */*pPixData */ +extern _X_EXPORT Bool miModifyPixmapHeader(PixmapPtr pPixmap, + int width, + int height, + int depth, + int bitsPerPixel, + int devKind, + void *pPixData ); extern _X_EXPORT Bool miCreateScreenResources(ScreenPtr /*pScreen */ ); -extern _X_EXPORT Bool miScreenDevPrivateInit(ScreenPtr /*pScreen */ , - int /*width */ , - void */*pbits */ +extern _X_EXPORT Bool miScreenDevPrivateInit(ScreenPtr pScreen, + int width, + void *pbits ); -extern _X_EXPORT Bool miScreenInit(ScreenPtr /*pScreen */ , - void */*pbits */ , - int /*xsize */ , - int /*ysize */ , - int /*dpix */ , - int /*dpiy */ , - int /*width */ , - int /*rootDepth */ , - int /*numDepths */ , - DepthPtr /*depths */ , - VisualID /*rootVisual */ , - int /*numVisuals */ , - VisualPtr /*visuals */ +extern _X_EXPORT Bool miScreenInit(ScreenPtr pScreen, + void *pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int rootDepth, + int numDepths, + DepthPtr depths, + VisualID rootVisual, + int numVisuals, + VisualPtr visuals ); /* mivaltree.c */ diff --git a/os/access.c b/os/access.c index e8c0781f2..9fcf99a73 100644 --- a/os/access.c +++ b/os/access.c @@ -1217,9 +1217,9 @@ AddHost(ClientPtr client, int family, unsigned length, /* of bytes in pAddr */ } Bool -ForEachHostInFamily(int family, Bool (*func) (unsigned char * /* addr */ , - short /* len */ , - void */* closure */ ), +ForEachHostInFamily(int family, Bool (*func) (unsigned char *addr, + short len, + void *closure), void *closure) { HOST *host; From c75fee79ace394f6f51aa6fdda1c0436eb8a2026 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 18 Apr 2014 13:54:11 -0700 Subject: [PATCH 33/40] Document how to correctly wrap screen procedures This adds a large comment to include/scrnintstr.h which should serve to document the correct way to wrap any screen procedure, with a particular focus on how to dynamically add/remove wrapping layers while the server is running. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- include/scrnintstr.h | 90 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/include/scrnintstr.h b/include/scrnintstr.h index 531278126..6955e77fd 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -358,6 +358,96 @@ typedef WindowPtr (*XYToWindowProcPtr)(ScreenPtr pScreen, typedef int (*NameWindowPixmapProcPtr)(WindowPtr, PixmapPtr, CARD32); +/* Wrapping Screen procedures + + There are a few modules in the X server which dynamically add and + remove themselves from various screen procedure call chains. + + For example, the BlockHandler is dynamically modified by: + + * xf86Rotate + * miSprite + * composite + * render (for animated cursors) + + Correctly manipulating this chain is complicated by the fact that + the chain is constructed through a sequence of screen private + structures, each holding the next screen->proc pointer. + + To add a module to a screen->proc chain is fairly simple; just save + the current screen->proc value in the module screen private + and store the module's function in the screen->proc location. + + Removing a screen proc is a bit trickier. It seems like all you + need to do is set the screen->proc pointer back to the value saved + in your screen private. However, if some other module has come + along and wrapped on top of you, then the right place to store the + previous screen->proc value is actually in the wrapping module's + screen private structure(!). Of course, you have no idea what + other module may have wrapped on top, nor could you poke inside + its screen private in any case. + + To make this work, we restrict the unwrapping process to happen + during the invocation of the screen proc itself, and then we + require the screen proc to take some care when manipulating the + screen proc functions pointers. + + The requirements are: + + 1) The screen proc must set the screen->proc pointer back to the + value saved in its screen private before calling outside its + module. + + 2a) If the screen proc wants to be remove itself from the chain, + it must not manipulate screen->proc pointer again before + returning. + + 2b) If the screen proc wants to remain in the chain, it must: + + 2b.1) Re-fetch the screen->proc pointer and store that in + its screen private. This ensures that any changes + to the chain will be preserved. + + 2b.2) Set screen->proc back to itself + + One key requirement here is that these steps must wrap not just + any invocation of the nested screen->proc value, but must nest + essentially any calls outside the current module. This ensures + that other modules can reliably manipulate screen->proc wrapping + using these same rules. + + For example, the animated cursor code in render has two macros, + Wrap and Unwrap. + + #define Unwrap(as,s,elt) ((s)->elt = (as)->elt) + + Unwrap takes the screen private (as), the screen (s) and the + member name (elt), and restores screen->proc to that saved in the + screen private. + + #define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) + + Wrap takes the screen private (as), the screen (s), the member + name (elt) and the wrapping function (func). It saves the + current screen->proc value in the screen private, and then sets the + screen->proc to the local wrapping function. + + Within each of these functions, there's a pretty simple pattern: + + Unwrap(as, pScreen, UnrealizeCursor); + + // Do local stuff, including possibly calling down through + // pScreen->UnrealizeCursor + + Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); + + The wrapping block handler is a bit different; it does the Unwrap, + the local operations and then only re-Wraps if the hook is still + required. Unwrap occurrs at the top of each function, just after + entry, and Wrap occurrs at the bottom of each function, just + before returning. + */ + typedef struct _Screen { int myNum; /* index of this instance in Screens[] */ ATOM id; From 08fc33042c858568e7244eb9ad25a8d0270754f0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 18 Apr 2014 13:55:50 -0700 Subject: [PATCH 34/40] hw/xfree86: Fix block handler wrapping in xf86Rotate xf86Rotate, it was delaying unwrapping the BlockHandler until after calling xf86RotateRedisplay. If there was a software cursor on the screen, the redisplay operation would cause cursor to be removed from the frame buffer and the misprite block handler to be inserted into the block handler chain with the misprite screen private saved block handler now set to xf86RotateBlockHandler. When xf86RotateRedisplay returned, xf86RotateBlockHandler would then set screen->BlockHandler to its saved value, call down and then reset screen->BlockHandler to xf86RotateBlockHandler. miSpriteBlockHandler would never be called after that, which meant that the software cursor will now disappear from the screen whenever rendering overlapped and would only reappear when the cursor was moved. To correct this, all that is needed is to move the restoration of screen->BlockHandler to the top of xf86RotateBlockHandler, before the call to xf86RotateRedisplay. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- hw/xfree86/modes/xf86Rotate.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index 0ddd8408e..99dcb43cb 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -234,8 +234,14 @@ xf86RotateBlockHandler(ScreenPtr pScreen, ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86RotateRedisplay(pScreen); + /* Unwrap before redisplay in case the software + * cursor layer wants to add its block handler to the + * chain + */ pScreen->BlockHandler = xf86_config->BlockHandler; + + xf86RotateRedisplay(pScreen); + (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask); /* cannot avoid re-wrapping until all wrapping is audited */ xf86_config->BlockHandler = pScreen->BlockHandler; From a1189fe322724ab1b524aaad5b700287777252bd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 18 Apr 2014 13:57:55 -0700 Subject: [PATCH 35/40] mi: Fix block handler wrapping in miSprite miSpriteBlockHandler was leaving the BlockHandler wrapped until just before calling any nested block handler. If any code executed before that added or removed block handlers, the wrapping chain would have been broken. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- mi/misprite.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mi/misprite.c b/mi/misprite.c index eea731a15..68a49be1e 100644 --- a/mi/misprite.c +++ b/mi/misprite.c @@ -520,6 +520,8 @@ miSpriteBlockHandler(ScreenPtr pScreen, void *pTimeout, miCursorInfoPtr pCursorInfo; Bool WorkToDo = FALSE; + SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler); + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); @@ -543,8 +545,6 @@ miSpriteBlockHandler(ScreenPtr pScreen, void *pTimeout, } } - SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler); - (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask); if (WorkToDo) From 79a2733005202af43821d8fd8e4c9fb77bf8f69e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 18 Apr 2014 14:11:17 -0700 Subject: [PATCH 36/40] hw/xfree86: Fix VGA arbiter screen proc wrapping Change the screen proc epilog code to re-fetch the current screen function in case a nested proc changes how things work. This isn't a problem with the current code as all of the wrapping layers that are set up at server init time (like the VGA arbiter) leave themselves in the screen proc chain forever. But, this makes the code conform with the expected norms. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- hw/xfree86/common/xf86VGAarbiterPriv.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/common/xf86VGAarbiterPriv.h b/hw/xfree86/common/xf86VGAarbiterPriv.h index ec21bc2f2..b832c9a5f 100644 --- a/hw/xfree86/common/xf86VGAarbiterPriv.h +++ b/hw/xfree86/common/xf86VGAarbiterPriv.h @@ -49,10 +49,14 @@ #define UNWRAP_SCREEN(x) pScreen->x = pScreenPriv->x -#define SCREEN_PROLOG(x) pScreen->x = ((VGAarbiterScreenPtr) \ - dixLookupPrivate(&(pScreen)->devPrivates, VGAarbiterScreenKey))->x +#define SCREEN_PRIV() ((VGAarbiterScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates, VGAarbiterScreenKey)) -#define SCREEN_EPILOG(x,y) pScreen->x = y; +#define SCREEN_PROLOG(x) (pScreen->x = SCREEN_PRIV()->x) + +#define SCREEN_EPILOG(x,y) do { \ + SCREEN_PRIV()->x = pScreen->x; \ + pScreen->x = y; \ + } while (0) #define WRAP_PICT(x,y) if (ps) {pScreenPriv->x = ps->x;\ ps->x = y;} From 3319e7041ff89bb01b16a1dbbac85e28b1976ae3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 18 Apr 2014 14:24:29 -0700 Subject: [PATCH 37/40] hw/xfree86: Let xf86Rotate leave the BlockHandler unwrapped when possible When no shadow frame buffer is needed, the rotate block handler doesn't need to be called any more. Remove it from the chain. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- hw/xfree86/modes/xf86Rotate.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index 99dcb43cb..1627e61dd 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -243,9 +243,13 @@ xf86RotateBlockHandler(ScreenPtr pScreen, xf86RotateRedisplay(pScreen); (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask); - /* cannot avoid re-wrapping until all wrapping is audited */ - xf86_config->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = xf86RotateBlockHandler; + + /* Re-wrap if we still need this hook */ + if (xf86_config->rotation_damage != NULL) { + xf86_config->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = xf86RotateBlockHandler; + } else + xf86_config->BlockHandler = NULL; } void From bfa5c73a36230f77fb211f185152212541c9d56d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 4 Jun 2014 22:00:45 -0700 Subject: [PATCH 38/40] ephyr: Free damage structure at server reset time The usual mechanism for freeing a damage structure when the pixmap is destroyed does not work for the screen pixmap as it isn't freed in the normal way. The existing driver cleanup function, scrfini, is called after the wrapped CloseScreen functions, including damageCloseScreen, are called and thus ephyr can't free the damage structure at that point. Deal with this by providing an early CloseScreen hook in KdCloseScreen which ephyr can use to free the damage structure before damage itself shuts down. Signed-off-by: Keith Packard Reviewed-by: Jamey Sharp --- hw/kdrive/ephyr/ephyr.c | 6 ++++++ hw/kdrive/ephyr/ephyr.h | 3 +++ hw/kdrive/ephyr/ephyrinit.c | 2 ++ hw/kdrive/src/kdrive.c | 4 ++++ hw/kdrive/src/kdrive.h | 1 + 5 files changed, 16 insertions(+) diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index def50d8d8..49a4d2ded 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -756,6 +756,12 @@ ephyrScreenFini(KdScreenInfo * screen) } } +void +ephyrCloseScreen(ScreenPtr pScreen) +{ + ephyrUnsetInternalDamage(pScreen); +} + /* * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug. * See https://bugs.freedesktop.org/show_bug.cgi?id=3030 diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index 34ce4601b..e69178082 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -130,6 +130,9 @@ void void ephyrScreenFini(KdScreenInfo * screen); +void +ephyrCloseScreen(ScreenPtr pScreen); + void ephyrCardFini(KdCardInfo * card); diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index fac84cd13..3f66e1c2f 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -430,4 +430,6 @@ KdCardFuncs ephyrFuncs = { ephyrGetColors, /* getColors */ ephyrPutColors, /* putColors */ + + ephyrCloseScreen, /* closeScreen */ }; diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index 9814fc66a..b5b91c0dd 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -621,8 +621,12 @@ KdCloseScreen(ScreenPtr pScreen) KdCardInfo *card = pScreenPriv->card; Bool ret; + if (card->cfuncs->closeScreen) + (*card->cfuncs->closeScreen)(pScreen); + pScreenPriv->closed = TRUE; pScreen->CloseScreen = pScreenPriv->CloseScreen; + if (pScreen->CloseScreen) ret = (*pScreen->CloseScreen) (pScreen); else diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index bec75cb6f..08b1681ce 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -130,6 +130,7 @@ typedef struct _KdCardFuncs { void (*getColors) (ScreenPtr, int, xColorItem *); void (*putColors) (ScreenPtr, int, xColorItem *); + void (*closeScreen) (ScreenPtr); /* close ScreenRec */ } KdCardFuncs; #define KD_MAX_PSEUDO_DEPTH 8 From 16fbad3c7a22d2fb33549bcd422de985a60982b8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 17 Jul 2014 16:17:53 -0700 Subject: [PATCH 39/40] Post 1.16 version bump to 1.16.99.1 And we're off towards 1.17; this version bump serves to keep development versions distinct from stable versions. Signed-off-by: Keith Packard --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 1c327fd59..4338dc551 100644 --- a/configure.ac +++ b/configure.ac @@ -26,9 +26,9 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.16.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2014-07-16" -RELEASE_NAME="Marionberry Pie" +AC_INIT([xorg-server], 1.16.99.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2014-07-17" +RELEASE_NAME="Baba Ghanouj" AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) From 55f5bfb578e934319d1308cbb56c900c5ac7cfa7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 16 Jul 2014 16:03:23 -0700 Subject: [PATCH 40/40] glamor: Fix temp picture coordinates in glamor_composite_clipped_region To understand this patch, let's start at the protocol interface where the relationship between the coordinate spaces is documented: static Bool _glamor_composite(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, INT16 x_source, INT16 y_source, INT16 x_mask, INT16 y_mask, INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height, Bool fallback) The coordinates are passed to this function directly off the wire and are all relative to their respective drawables. For Windows, this means that they are relative to the upper left corner of the window, in whatever pixmap that window is getting drawn to. _glamor_composite calls miComputeCompositeRegion to construct a clipped region to actually render to. In reality, miComputeCompositeRegion clips only to the destination these days; source clip region based clipping would have to respect the transform, which isn't really possible. The returned region is relative to the screen in which dest lives; offset by dest->drawable.x and dest->drawable.y. What is important to realize here is that, because of clipping, the composite region may not have the same position within the destination drawable as x_dest, y_dest. The protocol coordinates now exist solely to 'pin' the three objects together. extents->x1,y1 Screen origin of clipped operation width,height Extents of the clipped operation x_dest,y_dest Unclipped destination-relative operation coordinate x_source,y_source Unclipped source-relative operation coordinate x_mask,y_mask Unclipped mask-relative operation coordinate One thing we want to know is what the offset is from the original operation origin to the clipped origin Destination drawable relative coordinates of the clipped operation: x_dest_clipped = extents->x1 - dest->drawable.x y_dest_clipped = extents->y1 - dest->drawable.y Offset from the original operation origin: x_off_clipped = x_dest_clipped - x_dest y_off_clipped = y_dest_clipped - y_dest Source drawable relative coordinates of the clipped operation: x_source_clipped = x_source + x_off_clipped; y_source_clipped = y_source + y_off_clipped; Mask drawable relative coordinates of the clipped operation: x_mask_clipped = x_source + x_off_clipped; y_mask_clipped = y_source + y_off_clipped; This is where the original code fails -- it doesn't subtract the destination drawable location when computing the distance that the operation has been moved by clipping. Here's what it does when constructing a temporary source picture: temp_src = glamor_convert_gradient_picture(screen, source, extent->x1 + x_source - x_dest, extent->y1 + y_source - y_dest, width, height); ... x_temp_src = -extent->x1 + x_dest; y_temp_src = -extent->y1 + y_dest; glamor_convert_gradient_picture needs source drawable relative coordinates, but that is not what it's getting; it's getting screen-relative coordinates for the destination, adjusted by the distance between the provided source and destination operation coordinates. We want x_source_clipped and y_source_clipped: x_source_clipped = x_source + x_off_clipped = x_source + x_dest_clipped - x_dest = x_source + extents->x1 - dest->drawable.x - x_dest x_temp_src/y_temp_src are supposed to be the coordinates of the original operation translated to the temporary picture: x_temp_src = x_source - x_source_clipped; y_temp_src = y_source - y_source_clipped; Note that x_source_clipped/y_source_clipped will never be less than x_source/y_source because all we're doing is clipping. This means that x_temp_src/y_temp_src will always be non-positive; the original source coordinate can never be strictly *inside* the temporary image or we could have made the temporary image smaller. x_temp_src = x_source - x_source_clipped = x_source - (x_source + x_off_clipped) = -x_off_clipped = x_dest - x_dest_clipped = x_dest - (extents->x1 - dest->drawable.x) Again, this is off by the destination origin within the screen coordinate space. The code should look like: temp_src = glamor_convert_gradient_picture(screen, source, extent->x1 + x_source - x_dest - dest->pDrawable->x, extent->y1 + y_source - y_dest - dest->pDrawable->y, width, height); x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x; y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y; Signed-off-by: Keith Packard Reviewed-by: Markus Wick --- glamor/glamor_render.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 14ab738eb..e5d5d2cb1 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1450,8 +1450,8 @@ glamor_composite_clipped_region(CARD8 op, || source_pixmap->drawable.height != height)))) { temp_src = glamor_convert_gradient_picture(screen, source, - extent->x1 + x_source - x_dest, - extent->y1 + y_source - y_dest, + extent->x1 + x_source - x_dest - dest->pDrawable->x, + extent->y1 + y_source - y_dest - dest->pDrawable->y, width, height); if (!temp_src) { temp_src = source; @@ -1459,8 +1459,8 @@ glamor_composite_clipped_region(CARD8 op, } temp_src_priv = glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable)); - x_temp_src = -extent->x1 + x_dest; - y_temp_src = -extent->y1 + y_dest; + x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x; + y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y; } if (mask @@ -1474,8 +1474,8 @@ glamor_composite_clipped_region(CARD8 op, * to do reduce one convertion. */ temp_mask = glamor_convert_gradient_picture(screen, mask, - extent->x1 + x_mask - x_dest, - extent->y1 + y_mask - y_dest, + extent->x1 + x_mask - x_dest - dest->pDrawable->x, + extent->y1 + y_mask - y_dest - dest->pDrawable->y, width, height); if (!temp_mask) { temp_mask = mask; @@ -1483,8 +1483,8 @@ glamor_composite_clipped_region(CARD8 op, } temp_mask_priv = glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable)); - x_temp_mask = -extent->x1 + x_dest; - y_temp_mask = -extent->y1 + y_dest; + x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x; + y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y; } /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending.