xorg-server: Changes to 'debian-unstable'
debian/changelog | 2
debian/patches/series | 1
debian/patches/upstream-fixes-effd785aa8a97c9.diff | 2089 +++++++++++++++++++++
3 files changed, 2092 insertions(+)
New commits:
commit 8bd8393e944e5a07e2453f935fc56e3805d80d00
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Mon Jul 18 12:28:35 2016 +0300
upstream-fixes-effd785aa8a97c9.diff: Add fixes from 1.18-branch until effd785aa8a97c9.
diff --git a/debian/changelog b/debian/changelog
index 0d99e86..1224257 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,8 @@ xorg-server (2:1.18.3-2) UNRELEASED; urgency=medium
applied anyway since Dec'14.
* 06_use-intel-only-on-pre-gen4.diff: Use modesetting driver on intel
gen4 and newer.
+ * upstream-fixes-effd785aa8a97c9.diff: Add fixes from 1.18-branch
+ until effd785aa8a97c9.
-- Timo Aaltonen <tjaalton@debian.org> Thu, 12 May 2016 18:22:02 +0300
diff --git a/debian/patches/series b/debian/patches/series
index ef422b4..fe56207 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -6,3 +6,4 @@
05_Revert-Unload-submodules.diff
06_use-intel-only-on-pre-gen4.diff
os-treat-ssh-as-a-non-local-client.diff
+upstream-fixes-effd785aa8a97c9.diff
diff --git a/debian/patches/upstream-fixes-effd785aa8a97c9.diff b/debian/patches/upstream-fixes-effd785aa8a97c9.diff
new file mode 100644
index 0000000..ea25501
--- /dev/null
+++ b/debian/patches/upstream-fixes-effd785aa8a97c9.diff
@@ -0,0 +1,2089 @@
+diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
+index 9eb29bd..18f3ac7 100644
+--- a/Xext/panoramiXprocs.c
++++ b/Xext/panoramiXprocs.c
+@@ -106,7 +106,7 @@ PanoramiXCreateWindow(ClientPtr client)
+ if ((Mask) stuff->mask & CWColormap) {
+ cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
+ tmp = *((CARD32 *) &stuff[1] + cmap_offset);
+- if ((tmp != CopyFromParent) && (tmp != None)) {
++ if (tmp != CopyFromParent) {
+ result = dixLookupResourceByType((void **) &cmap, tmp,
+ XRT_COLORMAP, client,
+ DixReadAccess);
+@@ -210,7 +210,7 @@ PanoramiXChangeWindowAttributes(ClientPtr client)
+ if ((Mask) stuff->valueMask & CWColormap) {
+ cmap_offset = Ones((Mask) stuff->valueMask & (CWColormap - 1));
+ tmp = *((CARD32 *) &stuff[1] + cmap_offset);
+- if ((tmp != CopyFromParent) && (tmp != None)) {
++ if (tmp != CopyFromParent) {
+ result = dixLookupResourceByType((void **) &cmap, tmp,
+ XRT_COLORMAP, client,
+ DixReadAccess);
+diff --git a/Xext/saver.c b/Xext/saver.c
+index 0e20467..750b8b9 100644
+--- a/Xext/saver.c
++++ b/Xext/saver.c
+@@ -1143,7 +1143,7 @@ ProcScreenSaverSetAttributes(ClientPtr client)
+ if ((Mask) stuff->mask & CWColormap) {
+ cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
+ tmp = *((CARD32 *) &stuff[1] + cmap_offset);
+- if ((tmp != CopyFromParent) && (tmp != None)) {
++ if (tmp != CopyFromParent) {
+ status = dixLookupResourceByType((void **) &cmap, tmp,
+ XRT_COLORMAP, client,
+ DixReadAccess);
+diff --git a/Xi/exevents.c b/Xi/exevents.c
+index e728310..52b91e8 100644
+--- a/Xi/exevents.c
++++ b/Xi/exevents.c
+@@ -1379,6 +1379,9 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
+ if (!TouchResourceIsOwner(ti, listener->listener))
+ return !Success;
+
++ if (!ti->emulate_pointer)
++ return !Success;
++
+ nevents = TouchConvertToPointerEvent(ev, &motion, &button);
+ BUG_RETURN_VAL(nevents == 0, BadValue);
+
+diff --git a/configure.ac b/configure.ac
+index 77cf234..cfffcd8 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -555,17 +555,27 @@ AC_ARG_WITH(apple-application-name,AS_HELP_STRING([--with-apple-application-name
+ [ APPLE_APPLICATION_NAME="${withval}" ],
+ [ APPLE_APPLICATION_NAME="X11" ])
+ AC_SUBST([APPLE_APPLICATION_NAME])
+-AC_ARG_WITH(launchd-id-prefix, AS_HELP_STRING([--with-launchd-id-prefix=PATH], [Deprecated: Use --with-bundle-id-prefix.]),
+- [ BUNDLE_ID_PREFIX="${withval}" ],
+- [ BUNDLE_ID_PREFIX="org.x" ])
+-AC_ARG_WITH(bundle-id-prefix, AS_HELP_STRING([--with-bundle-id-prefix=PATH], [Prefix to use for bundle identifiers (default: org.x)]),
++AC_ARG_WITH(bundle-id-prefix, AS_HELP_STRING([--with-bundle-id-prefix=RDNS_PREFIX], [Prefix to use for bundle identifiers (default: org.x)]),
+ [ BUNDLE_ID_PREFIX="${withval}" ])
+ AC_SUBST([BUNDLE_ID_PREFIX])
+ AC_DEFINE_UNQUOTED(BUNDLE_ID_PREFIX, "$BUNDLE_ID_PREFIX", [Prefix to use for bundle identifiers])
++m4_define(DEFAULT_BUNDLE_VERSION, m4_esyscmd([echo ]AC_PACKAGE_VERSION[ | cut -f1-3 -d. | tr -d '\n']))
++AC_ARG_WITH(bundle-version, AS_HELP_STRING([--with-bundle-version=VERSION], [Version to use for X11.app's CFBundleVersion (default: ]DEFAULT_BUNDLE_VERSION[)]),
++ [ BUNDLE_VERSION="${withval}" ],
++ [ BUNDLE_VERSION="DEFAULT_BUNDLE_VERSION" ])
++AC_SUBST([BUNDLE_VERSION])
++AC_ARG_WITH(bundle-version-string, AS_HELP_STRING([--with-bundle-version-string=VERSION], [Version to use for X11.app's CFBundleShortVersionString (default: ]AC_PACKAGE_VERSION[)]),
++ [ BUNDLE_VERSION_STRING="${withval}" ],
++ [ BUNDLE_VERSION_STRING="${PACKAGE_VERSION}" ])
++AC_SUBST([BUNDLE_VERSION_STRING])
+ AC_ARG_ENABLE(sparkle,AS_HELP_STRING([--enable-sparkle], [Enable updating of X11.app using the Sparkle Framework (default: disabled)]),
+ [ XQUARTZ_SPARKLE="${enableval}" ],
+ [ XQUARTZ_SPARKLE="no" ])
+ AC_SUBST([XQUARTZ_SPARKLE])
++AC_ARG_WITH(sparkle-feed-url, AS_HELP_STRING([--with-sparkle-feed-url=URL], [URL for the Sparkle feed (default: https://www.xquartz.org/releases/sparkle/release.xml)]),
++ [ XQUARTZ_SPARKLE_FEED_URL="${withval}" ],
++ [ XQUARTZ_SPARKLE_FEED_URL="https://www.xquartz.org/releases/sparkle/release.xml" ])
++AC_SUBST([XQUARTZ_SPARKLE_FEED_URL])
+ AC_ARG_ENABLE(visibility, AS_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]),
+ [SYMBOL_VISIBILITY=$enableval],
+ [SYMBOL_VISIBILITY=auto])
+@@ -880,7 +890,7 @@ if test "x$CONFIG_UDEV" = xyes; then
+ fi
+ SAVE_LIBS=$LIBS
+ SAVE_CFLAGS=$CFLAGS
+- CFLAGS=$UDEV_CFLAGS
++ CFLAGS="$CFLAGS $UDEV_CFLAGS"
+ LIBS=$UDEV_LIBS
+ AC_CHECK_FUNCS([udev_monitor_filter_add_match_tag])
+ AC_CHECK_FUNCS([udev_enumerate_add_match_tag])
+@@ -1293,7 +1303,7 @@ fi
+
+ if test "x$DRI2" = xyes; then
+ save_CFLAGS=$CFLAGS
+- CFLAGS="$GL_CFLAGS $LIBDRM_CFLAGS"
++ CFLAGS="$CFLAGS $GL_CFLAGS $LIBDRM_CFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <GL/gl.h>
+ #include <GL/internal/dri_interface.h>
+ #ifndef __DRI_DRI2
+diff --git a/dix/devices.c b/dix/devices.c
+index 9b0c7d2..a532dcf 100644
+--- a/dix/devices.c
++++ b/dix/devices.c
+@@ -1682,8 +1682,7 @@ ProcSetModifierMapping(ClientPtr client)
+ stuff->numKeyPerModifier);
+ if (rc == MappingFailed || rc == -1)
+ return BadValue;
+- if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
+- rc != MappingBusy)
++ if (rc != MappingSuccess && rc != MappingFailed && rc != MappingBusy)
+ return rc;
+
+ rep.success = rc;
+diff --git a/dix/enterleave.c b/dix/enterleave.c
+index f0b1572..1b341f2 100644
+--- a/dix/enterleave.c
++++ b/dix/enterleave.c
+@@ -1446,19 +1446,25 @@ DeviceFocusEvents(DeviceIntPtr dev, WindowPtr from, WindowPtr to, int mode)
+
+ if ((to == NullWindow) || (to == PointerRootWin)) {
+ if ((from == NullWindow) || (from == PointerRootWin)) {
+- if (from == PointerRootWin)
++ if (from == PointerRootWin) {
++ DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyPointer,
++ sprite->win);
+ DeviceFocusOutEvents(dev, sprite->win,
+ GetCurrentRootWindow(dev), mode,
+ NotifyPointer);
++ }
+ /* Notify all the roots */
+ for (i = 0; i < nscreens; i++)
+ DeviceFocusEvent(dev, XI_FocusOut, mode, out,
+ screenInfo.screens[i]->root);
+ }
+ else {
+- if (IsParent(from, sprite->win))
++ if (IsParent(from, sprite->win)) {
++ DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyPointer,
++ sprite->win);
+ DeviceFocusOutEvents(dev, sprite->win, from, mode,
+ NotifyPointer);
++ }
+ DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from);
+ /* next call catches the root too, if the screen changed */
+ DeviceFocusOutEvents(dev, from, NullWindow, mode,
+@@ -1476,10 +1482,13 @@ DeviceFocusEvents(DeviceIntPtr dev, WindowPtr from, WindowPtr to, int mode)
+ }
+ else {
+ if ((from == NullWindow) || (from == PointerRootWin)) {
+- if (from == PointerRootWin)
++ if (from == PointerRootWin) {
++ DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyPointer,
++ sprite->win);
+ DeviceFocusOutEvents(dev, sprite->win,
+ GetCurrentRootWindow(dev), mode,
+ NotifyPointer);
++ }
+ for (i = 0; i < nscreens; i++)
+ DeviceFocusEvent(dev, XI_FocusOut, mode, out,
+ screenInfo.screens[i]->root);
+@@ -1506,9 +1515,12 @@ DeviceFocusEvents(DeviceIntPtr dev, WindowPtr from, WindowPtr to, int mode)
+ if ((IsParent(from, sprite->win)) &&
+ (sprite->win != from) &&
+ (!IsParent(to, sprite->win)) &&
+- (!IsParent(sprite->win, to)))
++ (!IsParent(sprite->win, to))) {
++ DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyPointer,
++ sprite->win);
+ DeviceFocusOutEvents(dev, sprite->win, from, mode,
+ NotifyPointer);
++ }
+ DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyInferior, from);
+ DeviceFocusInEvents(dev, from, to, mode, NotifyVirtual);
+ DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyAncestor, to);
+diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
+index e75300a..050c12a 100644
+--- a/dix/ptrveloc.c
++++ b/dix/ptrveloc.c
+@@ -134,13 +134,19 @@ InitPredictableAccelerationScheme(DeviceIntPtr dev,
+ scheme = *protoScheme;
+ vel = calloc(1, sizeof(DeviceVelocityRec));
+ schemeData = calloc(1, sizeof(PredictableAccelSchemeRec));
+- if (!vel || !schemeData)
++ if (!vel || !schemeData) {
++ free(vel);
++ free(schemeData);
+ return FALSE;
++ }
+ InitVelocityData(vel);
+ schemeData->vel = vel;
+ scheme.accelData = schemeData;
+- if (!InitializePredictableAccelerationProperties(dev, vel, schemeData))
++ if (!InitializePredictableAccelerationProperties(dev, vel, schemeData)) {
++ free(vel);
++ free(schemeData);
+ return FALSE;
++ }
+ /* all fine, assign scheme to device */
+ dev->valuator->accelScheme = scheme;
+ return TRUE;
+diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
+index cf21ea9..192a643 100644
+--- a/exa/exa_glyphs.c
++++ b/exa/exa_glyphs.c
+@@ -618,9 +618,9 @@ exaGlyphsToMask(PicturePtr pMask, ExaGlyphBufferPtr buffer)
+ }
+
+ static void
+-exaGlyphsToDst(PicturePtr pSrc, PicturePtr pDst, ExaGlyphBufferPtr buffer)
++exaGlyphsToDst(CARD8 op, PicturePtr pSrc, PicturePtr pDst, ExaGlyphBufferPtr buffer)
+ {
+- exaCompositeRects(PictOpOver, pSrc, buffer->mask, pDst, buffer->count,
++ exaCompositeRects(op, pSrc, buffer->mask, pDst, buffer->count,
+ buffer->rects);
+
+ buffer->count = 0;
+@@ -801,7 +801,7 @@ exaGlyphs(CARD8 op,
+ 0, 0, x - glyph->info.x,
+ y - glyph->info.y)
+ == ExaGlyphNeedFlush) {
+- exaGlyphsToDst(pSrc, pDst, &buffer);
++ exaGlyphsToDst(op, pSrc, pDst, &buffer);
+ exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
+ xSrc + (x - glyph->info.x) - first_xOff,
+ ySrc + (y - glyph->info.y) - first_yOff,
+@@ -821,7 +821,7 @@ exaGlyphs(CARD8 op,
+ if (maskFormat)
+ exaGlyphsToMask(pMask, &buffer);
+ else
+- exaGlyphsToDst(pSrc, pDst, &buffer);
++ exaGlyphsToDst(op, pSrc, pDst, &buffer);
+ }
+
+ if (maskFormat) {
+diff --git a/exa/exa_render.c b/exa/exa_render.c
+index fc3ddea..b24bec0 100644
+--- a/exa/exa_render.c
++++ b/exa/exa_render.c
+@@ -1141,7 +1141,8 @@ exaTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+
+ exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ for (; ntrap; ntrap--, traps++)
+- (*ps->RasterizeTrapezoid) (pPicture, traps, -bounds.x1, -bounds.y1);
++ if (xTrapezoidValid(traps))
++ (*ps->RasterizeTrapezoid) (pPicture, traps, -bounds.x1, -bounds.y1);
+ exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+
+ xRel = bounds.x1 + xSrc - xDst;
+diff --git a/glamor/glamor.c b/glamor/glamor.c
+index 9c6a0d1..0cb73c4 100644
+--- a/glamor/glamor.c
++++ b/glamor/glamor.c
+@@ -140,6 +140,42 @@ glamor_get_pixmap_texture(PixmapPtr pixmap)
+ return pixmap_priv->fbo->tex;
+ }
+
++void
++glamor_bind_texture(glamor_screen_private *glamor_priv, GLenum texture,
++ glamor_pixmap_fbo *fbo, Bool destination_red)
++{
++ glActiveTexture(texture);
++ glBindTexture(GL_TEXTURE_2D, fbo->tex);
++
++ /* If we're pulling data from a GL_RED texture, then whether we
++ * want to make it an A,0,0,0 result or a 0,0,0,R result depends
++ * on whether the destination is also a GL_RED texture.
++ *
++ * For GL_RED destinations, we need to leave the bits in the R
++ * channel. For all other destinations, we need to clear out the R
++ * channel so that it returns zero for R, G and B.
++ *
++ * Note that we're leaving the SWIZZLE_A value alone; for GL_RED
++ * destinations, that means we'll actually be returning R,0,0,R,
++ * but it doesn't matter as the bits in the alpha channel aren't
++ * going anywhere.
++ */
++
++ /* Is the operand a GL_RED fbo?
++ */
++
++ if (glamor_fbo_red_is_alpha(glamor_priv, fbo)) {
++
++ /* If destination is also GL_RED, then preserve the bits in
++ * the R channel */
++
++ if (destination_red)
++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
++ else
++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
++ }
++}
++
+ PixmapPtr
+ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+ unsigned int usage)
+@@ -816,3 +852,12 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
+ }
+ return -1;
+ }
++
++void
++glamor_finish(ScreenPtr screen)
++{
++ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
++
++ glamor_make_current(glamor_priv);
++ glFinish();
++}
+diff --git a/glamor/glamor.h b/glamor/glamor.h
+index 0aa6d56..250dc83 100644
+--- a/glamor/glamor.h
++++ b/glamor/glamor.h
+@@ -342,6 +342,7 @@ extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
+ extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
+ extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
+
++extern _X_EXPORT void glamor_finish(ScreenPtr screen);
+ #define HAS_GLAMOR_TEXT 1
+
+ #ifdef GLAMOR_FOR_XORG
+diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
+index f51ff6d..cc0aa6f 100644
+--- a/glamor/glamor_composite_glyphs.c
++++ b/glamor/glamor_composite_glyphs.c
+@@ -246,8 +246,7 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
+ glamor_put_vbo_space(drawable->pScreen);
+
+ glEnable(GL_SCISSOR_TEST);
+- glActiveTexture(GL_TEXTURE1);
+- glBindTexture(GL_TEXTURE_2D, atlas_fbo->tex);
++ glamor_bind_texture(glamor_priv, GL_TEXTURE1, atlas_fbo, FALSE);
+
+ for (;;) {
+ if (!glamor_use_program_render(prog, op, src, dst))
+@@ -558,7 +557,7 @@ glamor_free_glyph_atlas(struct glamor_glyph_atlas *atlas)
+ if (!atlas)
+ return;
+ if (atlas->atlas)
+- FreePicture(atlas->atlas, 0);
++ (*atlas->atlas->drawable.pScreen->DestroyPixmap)(atlas->atlas);
+ free (atlas);
+ }
+
+diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
+index 885a6c0..199e627 100644
+--- a/glamor/glamor_compositerects.c
++++ b/glamor/glamor_compositerects.c
+@@ -107,7 +107,6 @@ glamor_composite_rectangles(CARD8 op,
+ struct glamor_pixmap_private *priv;
+ pixman_region16_t region;
+ pixman_box16_t *boxes;
+- int dst_x, dst_y;
+ int num_boxes;
+ PicturePtr source = NULL;
+ Bool need_free_region = FALSE;
+@@ -225,17 +224,18 @@ glamor_composite_rectangles(CARD8 op,
+ RegionExtents(®ion)->x2, RegionExtents(®ion)->y2,
+ RegionNumRects(®ion));
+
+- glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
+- pixman_region_translate(®ion, dst_x, dst_y);
+-
+- DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
+- __FUNCTION__, dst_x, dst_y,
+- RegionExtents(®ion)->x1, RegionExtents(®ion)->y1,
+- RegionExtents(®ion)->x2, RegionExtents(®ion)->y2);
+-
+ boxes = pixman_region_rectangles(®ion, &num_boxes);
+ if (op == PictOpSrc || op == PictOpClear) {
+ CARD32 pixel;
++ int dst_x, dst_y;
++
++ glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
++ pixman_region_translate(®ion, dst_x, dst_y);
++
++ DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
++ __FUNCTION__, dst_x, dst_y,
++ RegionExtents(®ion)->x1, RegionExtents(®ion)->y1,
++ RegionExtents(®ion)->x2, RegionExtents(®ion)->y2);
+
+ if (op == PictOpClear)
+ pixel = 0;
+diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
+index 5fed89f..3501a0d 100644
+--- a/glamor/glamor_copy.c
++++ b/glamor/glamor_copy.c
+@@ -38,8 +38,8 @@ use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
+ struct copy_args *args = arg;
+ glamor_pixmap_fbo *src = args->src;
+
+- glActiveTexture(GL_TEXTURE0);
+- glBindTexture(GL_TEXTURE_2D, src->tex);
++ glamor_bind_texture(glamor_get_screen_private(dst->drawable.pScreen),
++ GL_TEXTURE0, src, TRUE);
+
+ glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
+ glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height);
+@@ -67,8 +67,8 @@ use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
+ struct copy_args *args = arg;
+ glamor_pixmap_fbo *src = args->src;
+
+- glActiveTexture(GL_TEXTURE0);
+- glBindTexture(GL_TEXTURE_2D, src->tex);
++ glamor_bind_texture(glamor_get_screen_private(dst->drawable.pScreen),
++ GL_TEXTURE0, src, TRUE);
+
+ glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
+ glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height);
+diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
+index a6a11c1..3c19dba 100644
+--- a/glamor/glamor_dash.c
++++ b/glamor/glamor_dash.c
+@@ -188,8 +188,7 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
+
+ /* Set the dash pattern as texture 1 */
+
+- glActiveTexture(GL_TEXTURE1);
+- glBindTexture(GL_TEXTURE_2D, dash_priv->fbo->tex);
++ glamor_bind_texture(glamor_priv, GL_TEXTURE1, dash_priv->fbo, FALSE);
+ glUniform1i(prog->dash_uniform, 1);
+ glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width);
+
+diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
+index 80a97f7..5aacbed 100644
+--- a/glamor/glamor_egl.c
++++ b/glamor/glamor_egl.c
+@@ -823,11 +823,6 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
+
+ glamor_egl->has_gem = glamor_egl_check_has_gem(fd);
+
+-#ifndef GLAMOR_GLES2
+- eglBindAPI(EGL_OPENGL_API);
+-#else
+- eglBindAPI(EGL_OPENGL_ES_API);
+-#endif
+ if (!eglInitialize
+ (glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n");
+@@ -835,6 +830,12 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
+ goto error;
+ }
+
++#ifndef GLAMOR_GLES2
++ eglBindAPI(EGL_OPENGL_API);
++#else
++ eglBindAPI(EGL_OPENGL_ES_API);
++#endif
++
+ version = eglQueryString(glamor_egl->display, EGL_VERSION);
+ xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
+
+diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
+index c6ba095..5bfffe5 100644
+--- a/glamor/glamor_fbo.c
++++ b/glamor/glamor_fbo.c
+@@ -340,10 +340,8 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+- if (format == glamor_priv->one_channel_format && format == GL_RED) {
+- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
++ if (format == glamor_priv->one_channel_format && format == GL_RED)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
+- }
+ glamor_priv->suppress_gl_out_of_memory_logging = true;
+ glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
+ format, GL_UNSIGNED_BYTE, NULL);
+diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
+index a70f10e..9d40397 100644
+--- a/glamor/glamor_priv.h
++++ b/glamor/glamor_priv.h
+@@ -593,6 +593,34 @@ void glamor_fini_pixmap_fbo(ScreenPtr screen);
+ Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
+ void glamor_fbo_expire(glamor_screen_private *glamor_priv);
+
++/* Return whether 'picture' is alpha-only */
++static inline Bool glamor_picture_is_alpha(PicturePtr picture)
++{
++ return picture->format == PICT_a1 || picture->format == PICT_a8;
++}
++
++/* Return whether 'fbo' is storing alpha bits in the red channel */
++static inline Bool
++glamor_fbo_red_is_alpha(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo)
++{
++ /* True when the format is GL_RED (that can only happen when our one channel format is GL_RED */
++ return fbo->format == GL_RED;
++}
++
++/* Return whether 'picture' is storing alpha bits in the red channel */
++static inline Bool
++glamor_picture_red_is_alpha(PicturePtr picture)
++{
++ /* True when the picture is alpha only and the screen is using GL_RED for alpha pictures */
++ return glamor_picture_is_alpha(picture) &&
++ glamor_get_screen_private(picture->pDrawable->pScreen)->one_channel_format == GL_RED;
++}
++
++void glamor_bind_texture(glamor_screen_private *glamor_priv,
++ GLenum texture,
++ glamor_pixmap_fbo *fbo,
++ Bool destination_red);
++
+ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv,
+ int w, int h, GLenum format,
+ int flag, int block_w, int block_h,
+diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
+index 0a94de6..dec116c 100644
+--- a/glamor/glamor_program.c
++++ b/glamor/glamor_program.c
+@@ -445,6 +445,7 @@ static struct blendinfo composite_op_info[] = {
+ static void
+ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst)
+ {
++ glamor_screen_private *glamor_priv = glamor_get_screen_private(dst->pDrawable->pScreen);
+ GLenum src_blend, dst_blend;
+ struct blendinfo *op_info;
+
+@@ -459,6 +460,9 @@ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst)
+ break;
+ }
+
++ if (glamor_priv->gl_flavor != GLAMOR_GL_ES2)
++ glDisable(GL_COLOR_LOGIC_OP);
++
+ if (op == PictOpSrc)
+ return;
+
+@@ -527,6 +531,7 @@ use_source_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *pro
+ glamor_set_blend(op, prog->alpha, dst);
+
+ return glamor_set_texture((PixmapPtr) src->pDrawable,
++ glamor_picture_red_is_alpha(dst),
+ 0, 0,
+ prog->fill_offset_uniform,
+ prog->fill_size_inv_uniform);
+@@ -545,7 +550,8 @@ use_source_1x1_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program
+ {
+ glamor_set_blend(op, prog->alpha, dst);
+
+- return glamor_set_texture_pixmap((PixmapPtr) src->pDrawable);
++ return glamor_set_texture_pixmap((PixmapPtr) src->pDrawable,
++ glamor_picture_red_is_alpha(dst));
+ }
+
+ static const glamor_facet glamor_source_1x1_picture = {
+diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
+index 73ac831..d70316d 100644
+--- a/glamor/glamor_render.c
++++ b/glamor/glamor_render.c
+@@ -105,7 +105,7 @@ glamor_create_composite_fs(struct shader_key *key)
+ /* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
+ * rel_sampler will recalculate the texture coords.*/
+ const char *rel_sampler =
+- " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n"
++ " vec4 rel_sampler_rgba(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n"
+ "{\n"
+ " if (repeat >= RepeatFix) {\n"
+ " tex = rel_tex_coord(tex, wh, repeat);\n"
+@@ -117,6 +117,19 @@ glamor_create_composite_fs(struct shader_key *key)
+ " }\n"
+ " }\n"
+ " return texture2D(tex_image, tex);\n"
++ "}\n"
++ " vec4 rel_sampler_rgbx(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n"
++ "{\n"
++ " if (repeat >= RepeatFix) {\n"
++ " tex = rel_tex_coord(tex, wh, repeat);\n"
++ " if (repeat == RepeatFix + RepeatNone) {\n"
++ " if (tex.x < 0.0 || tex.x >= 1.0 || \n"
++ " tex.y < 0.0 || tex.y >= 1.0)\n"
++ " return vec4(0.0, 0.0, 0.0, 0.0);\n"
++ " tex = (fract(tex) / wh.xy);\n"
++ " }\n"
++ " }\n"
++ " return vec4(texture2D(tex_image, tex).rgb, 1.0);\n"
+ "}\n";
+
+ const char *source_solid_fetch =
+@@ -131,8 +144,8 @@ glamor_create_composite_fs(struct shader_key *key)
+ "uniform vec4 source_wh;"
+ "vec4 get_source()\n"
+ "{\n"
+- " return rel_sampler(source_sampler, source_texture,\n"
+- " source_wh, source_repeat_mode);\n"
++ " return rel_sampler_rgba(source_sampler, source_texture,\n"
++ " source_wh, source_repeat_mode);\n"
+ "}\n";
+ const char *source_pixmap_fetch =
+ "varying vec2 source_texture;\n"
+@@ -140,9 +153,8 @@ glamor_create_composite_fs(struct shader_key *key)
+ "uniform vec4 source_wh;\n"
+ "vec4 get_source()\n"
+ "{\n"
+- " return vec4(rel_sampler(source_sampler, source_texture,\n"
+- " source_wh, source_repeat_mode).rgb,\n"
+- " 1.0);\n"
++ " return rel_sampler_rgbx(source_sampler, source_texture,\n"
++ " source_wh, source_repeat_mode);\n"
+ "}\n";
+ const char *mask_none =
+ "vec4 get_mask()\n"
+@@ -161,8 +173,8 @@ glamor_create_composite_fs(struct shader_key *key)
+ "uniform vec4 mask_wh;\n"
+ "vec4 get_mask()\n"
+ "{\n"
+- " return rel_sampler(mask_sampler, mask_texture,\n"
+- " mask_wh, mask_repeat_mode);\n"
++ " return rel_sampler_rgba(mask_sampler, mask_texture,\n"
++ " mask_wh, mask_repeat_mode);\n"
+ "}\n";
+ const char *mask_pixmap_fetch =
+ "varying vec2 mask_texture;\n"
+@@ -170,8 +182,8 @@ glamor_create_composite_fs(struct shader_key *key)
+ "uniform vec4 mask_wh;\n"
+ "vec4 get_mask()\n"
+ "{\n"
+- " return vec4(rel_sampler(mask_sampler, mask_texture,\n"
+- " mask_wh, mask_repeat_mode).rgb, 1.0);\n"
++ " return rel_sampler_rgbx(mask_sampler, mask_texture,\n"
++ " mask_wh, mask_repeat_mode);\n"
+ "}\n";
+
+ const char *dest_swizzle_default =
+@@ -500,15 +512,24 @@ static void
+ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
+ PicturePtr picture,
+ PixmapPtr pixmap,
+- GLuint wh_location, GLuint repeat_location)
++ GLuint wh_location, GLuint repeat_location,
++ glamor_pixmap_private *dest_priv)
+ {
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
++ glamor_pixmap_fbo *fbo = pixmap_priv->fbo;
+ float wh[4];
+ int repeat_type;
+
+ glamor_make_current(glamor_priv);
+- glActiveTexture(GL_TEXTURE0 + unit);
+- glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
++
++ /* The red channel swizzling doesn't depend on whether we're using
++ * 'fbo' as source or mask as we must have the same answer in case
++ * the same fbo is being used for both. That means the mask
++ * channel will sometimes get red bits in the R channel, and
++ * sometimes get zero bits in the R channel, which is harmless.
++ */
++ glamor_bind_texture(glamor_priv, GL_TEXTURE0 + unit, fbo,
++ glamor_fbo_red_is_alpha(glamor_priv, dest_priv->fbo));
+ repeat_type = picture->repeatType;
+ switch (picture->repeatType) {
+ case RepeatNone:
+@@ -557,8 +578,8 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
+ *
+ **/
+ if (glamor_pixmap_priv_is_large(pixmap_priv) ||
+- (glamor_priv->gl_flavor == GLAMOR_GL_ES2 && repeat_type == RepeatNone &&
+- picture->transform)) {
++ ((!PICT_FORMAT_A(picture->format) || glamor_priv->gl_flavor == GLAMOR_GL_ES2) &&
++ repeat_type == RepeatNone && picture->transform)) {
+ glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, pixmap_priv);
+ glUniform4fv(wh_location, 1, wh);
+
+@@ -1068,7 +1089,8 @@ glamor_composite_set_shader_blend(glamor_screen_private *glamor_priv,
+ glamor_set_composite_texture(glamor_priv, 0,
+ shader->source,
+ shader->source_pixmap, shader->source_wh,
+- shader->source_repeat_mode);
++ shader->source_repeat_mode,
++ dest_priv);
+ }
+
+ if (key->mask != SHADER_MASK_NONE) {
+@@ -1080,10 +1102,14 @@ glamor_composite_set_shader_blend(glamor_screen_private *glamor_priv,
+ glamor_set_composite_texture(glamor_priv, 1,
+ shader->mask,
+ shader->mask_pixmap, shader->mask_wh,
+- shader->mask_repeat_mode);
++ shader->mask_repeat_mode,
++ dest_priv);
+ }
+ }
+
++ if (glamor_priv->gl_flavor != GLAMOR_GL_ES2)
++ glDisable(GL_COLOR_LOGIC_OP);
++
+ if (op_info->source_blend == GL_ONE && op_info->dest_blend == GL_ZERO) {
+ glDisable(GL_BLEND);
+ }
+@@ -1144,12 +1170,12 @@ glamor_composite_with_shader(CARD8 op,
+ }
+ }
+
++ glamor_make_current(glamor_priv);
++
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, dest_pixmap, dest_pixmap_priv);
+ glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key, shader, &op_info);
+ glamor_set_alu(screen, GXcopy);
+
+- glamor_make_current(glamor_priv);
+-
+ glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
+ glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
+ key.mask != SHADER_MASK_SOLID);
+@@ -1392,6 +1418,36 @@ glamor_composite_clipped_region(CARD8 op,
+ DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
+ x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
+
++ /* Is the composite operation equivalent to a copy? */
++ if (!mask && !source->alphaMap && !dest->alphaMap
++ && source->pDrawable && !source->transform
++ && ((op == PictOpSrc
++ && (source->format == dest->format
++ || (PICT_FORMAT_COLOR(dest->format)
++ && PICT_FORMAT_COLOR(source->format)
++ && dest->format == PICT_FORMAT(PICT_FORMAT_BPP(source->format),
++ PICT_FORMAT_TYPE(source->format),
++ 0,
++ PICT_FORMAT_R(source->format),
++ PICT_FORMAT_G(source->format),
++ PICT_FORMAT_B(source->format)))))
++ || (op == PictOpOver
++ && source->format == dest->format
++ && !PICT_FORMAT_A(source->format)))
++ && x_source >= 0 && y_source >= 0
++ && (x_source + width) <= source->pDrawable->width
++ && (y_source + height) <= source->pDrawable->height) {
++ x_source += source->pDrawable->x;
++ y_source += source->pDrawable->y;
++ x_dest += dest->pDrawable->x;
++ y_dest += dest->pDrawable->y;
++ glamor_copy(source->pDrawable, dest->pDrawable, NULL,
++ box, nbox, x_source - x_dest,
++ y_source - y_dest, FALSE, FALSE, 0, NULL);
++ ok = TRUE;
++ goto out;
++ }
++
+ /* XXX is it possible source mask have non-zero drawable.x/y? */
+ if (source
+ && ((!source->pDrawable
+diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
+index 89a9c51..5217d04 100644
+--- a/glamor/glamor_spans.c
++++ b/glamor/glamor_spans.c
+@@ -294,8 +294,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
+ BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index);
+
+- glActiveTexture(GL_TEXTURE0);
+- glBindTexture(GL_TEXTURE_2D, fbo->tex);
++ glamor_bind_texture(glamor_priv, GL_TEXTURE0, fbo, TRUE);
+
+ s = src;
+ for (n = 0; n < numPoints; n++) {
+diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
+index ed81195..d788d06 100644
+--- a/glamor/glamor_transfer.c
++++ b/glamor/glamor_transfer.c
+@@ -83,8 +83,7 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ BoxPtr boxes = in_boxes;
+ int nbox = in_nbox;
+
+- glActiveTexture(GL_TEXTURE0);
+- glBindTexture(GL_TEXTURE_2D, fbo->tex);
++ glamor_bind_texture(glamor_priv, GL_TEXTURE0, fbo, TRUE);
+
+ while (nbox--) {
+
+diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
+index fc96fd6..eff500c 100644
+--- a/glamor/glamor_transform.c
++++ b/glamor/glamor_transform.c
+@@ -158,7 +158,7 @@ glamor_set_solid(PixmapPtr pixmap,
+ }
+
+ Bool
+-glamor_set_texture_pixmap(PixmapPtr texture)
++glamor_set_texture_pixmap(PixmapPtr texture, Bool destination_red)
+ {
+ glamor_pixmap_private *texture_priv;
+
+@@ -170,8 +170,9 @@ glamor_set_texture_pixmap(PixmapPtr texture)
+ if (glamor_pixmap_priv_is_large(texture_priv))
+ return FALSE;
+
+- glActiveTexture(GL_TEXTURE0);
+- glBindTexture(GL_TEXTURE_2D, texture_priv->fbo->tex);
++ glamor_bind_texture(glamor_get_screen_private(texture->drawable.pScreen),
++ GL_TEXTURE0,
++ texture_priv->fbo, destination_red);
+
+ /* we're not setting the sampler uniform here as we always use
+ * GL_TEXTURE0, and the default value for uniforms is zero. So,
+@@ -182,12 +183,13 @@ glamor_set_texture_pixmap(PixmapPtr texture)
+
+ Bool
+ glamor_set_texture(PixmapPtr texture,
++ Bool destination_red,
+ int off_x,
+ int off_y,
+ GLint offset_uniform,
+ GLint size_inv_uniform)
+ {
+- if (!glamor_set_texture_pixmap(texture))
++ if (!glamor_set_texture_pixmap(texture, destination_red))
+ return FALSE;
+
+ glUniform2f(offset_uniform, off_x, off_y);
+@@ -208,6 +210,7 @@ glamor_set_tiled(PixmapPtr pixmap,
+ return FALSE;
+
+ return glamor_set_texture(gc->tile.pixmap,
++ TRUE,
+ -gc->patOrg.x,
+ -gc->patOrg.y,
+ offset_uniform,
+@@ -289,6 +292,7 @@ glamor_set_stippled(PixmapPtr pixmap,
+ return FALSE;
+
+ return glamor_set_texture(stipple,
++ FALSE,
+ -gc->patOrg.x,
+ -gc->patOrg.y,
+ offset_uniform,
+diff --git a/glamor/glamor_transform.h b/glamor/glamor_transform.h
+index 5a520eb..70d2c16 100644
+--- a/glamor/glamor_transform.h
++++ b/glamor/glamor_transform.h
+@@ -48,10 +48,12 @@ glamor_set_color(PixmapPtr pixmap,
+ }
+
+ Bool
+-glamor_set_texture_pixmap(PixmapPtr texture);
++glamor_set_texture_pixmap(PixmapPtr texture,
++ Bool destination_red);
+
+ Bool
+ glamor_set_texture(PixmapPtr texture,
++ Bool destination_red,
+ int off_x,
+ int off_y,
+ GLint offset_uniform,
+diff --git a/glx/glxext.c b/glx/glxext.c
+index e41b881..c201fba 100644
+--- a/glx/glxext.c
++++ b/glx/glxext.c
+@@ -469,6 +469,12 @@ __glXForceCurrent(__GLXclientState * cl, GLXContextTag tag, int *error)
+
+ /* Make this context the current one for the GL. */
+ if (!cx->isDirect) {
++ /*
++ * If it is being forced, it means that this context was already made
++ * current. So it cannot just be made current again without decrementing
++ * refcount's
++ */
++ (*cx->loseCurrent) (cx);
+ lastGLContext = cx;
+ if (!(*cx->makeCurrent) (cx)) {
+ /* Bind failed, and set the error code. Bummer */
+diff --git a/hw/kdrive/linux/keyboard.c b/hw/kdrive/linux/keyboard.c
+index 9a6ee2d..5d31b7d 100644
+--- a/hw/kdrive/linux/keyboard.c
++++ b/hw/kdrive/linux/keyboard.c
+@@ -43,445 +43,6 @@
+
+ extern int LinuxConsoleFd;
+
+-static const KeySym linux_to_x[256] = {
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, XK_Escape,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
+- XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
+- XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
+- XK_comma, XK_minus, XK_period, XK_slash,
+- XK_0, XK_1, XK_2, XK_3,
+- XK_4, XK_5, XK_6, XK_7,
+- XK_8, XK_9, XK_colon, XK_semicolon,
+- XK_less, XK_equal, XK_greater, XK_question,
+- XK_at, XK_A, XK_B, XK_C,
+- XK_D, XK_E, XK_F, XK_G,
+- XK_H, XK_I, XK_J, XK_K,
+- XK_L, XK_M, XK_N, XK_O,
+- XK_P, XK_Q, XK_R, XK_S,
+- XK_T, XK_U, XK_V, XK_W,
+- XK_X, XK_Y, XK_Z, XK_bracketleft,
+- XK_backslash, XK_bracketright, XK_asciicircum, XK_underscore,
+- XK_grave, XK_a, XK_b, XK_c,
+- XK_d, XK_e, XK_f, XK_g,
+- XK_h, XK_i, XK_j, XK_k,
+- XK_l, XK_m, XK_n, XK_o,
+- XK_p, XK_q, XK_r, XK_s,
+- XK_t, XK_u, XK_v, XK_w,
+- XK_x, XK_y, XK_z, XK_braceleft,
+- XK_bar, XK_braceright, XK_asciitilde, XK_BackSpace,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+- XK_nobreakspace, XK_exclamdown, XK_cent, XK_sterling,
+- XK_currency, XK_yen, XK_brokenbar, XK_section,
+- XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft,
+- XK_notsign, XK_hyphen, XK_registered, XK_macron,
+- XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior,
+- XK_acute, XK_mu, XK_paragraph, XK_periodcentered,
+- XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright,
+- XK_onequarter, XK_onehalf, XK_threequarters, XK_questiondown,
+- XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde,
+- XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla,
+- XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis,
+- XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis,
+- XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute,
+- XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply,
+- XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex,
+- XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp,
+- XK_agrave, XK_aacute, XK_acircumflex, XK_atilde,
+- XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla,
+- XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis,
+- XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis,
+- XK_eth, XK_ntilde, XK_ograve, XK_oacute,
+- XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division,
+- XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex,
+- XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis
+-};
+-
+-/*
+- * Getting a keycode from scancode
+- *
+- * With XKB
+- * --------
+- *
+- * We have to enqueue keyboard events using standard X keycodes which correspond
+- * to AT scancode + 8; this means that we need to translate the Linux scancode
+- * provided by the kernel to an AT scancode -- this translation is not linear
+- * and requires that we use a LUT.
+- *
+- *
+- * Without XKB
+- * -----------
+- *
+- * We can use custom keycodes, which makes things simpler; we define our custom
+- * keycodes as Linux scancodes + KD_KEY_OFFSET
+-*/
+-
+-/*
+- This LUT translates AT scancodes into Linux ones -- the keymap we create
Reply to: