diff --git a/SOURCES/tigervnc-region-handling.patch b/SOURCES/tigervnc-region-handling.patch
new file mode 100644
index 0000000..2c17d24
--- /dev/null
+++ b/SOURCES/tigervnc-region-handling.patch
@@ -0,0 +1,3365 @@
+diff --git a/BUILDING.txt b/BUILDING.txt
+index 9449810..99c8698 100644
+--- a/BUILDING.txt
++++ b/BUILDING.txt
+@@ -11,6 +11,8 @@ Build Requirements (All Systems)
+ 
+ -- zlib
+ 
++-- pixman
++
+ -- FLTK 1.3.3 or later
+ 
+ -- If building TLS support:
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 94ec2ef..dfdf197 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -134,6 +134,9 @@ endif()
+ # Check for zlib
+ find_package(ZLIB REQUIRED)
+ 
++# Check for pixman
++find_package(Pixman REQUIRED)
++
+ # Check for gettext
+ option(ENABLE_NLS "Enable translation of program messages" ON)
+ if(ENABLE_NLS)
+diff --git a/cmake/Modules/FindPixman.cmake b/cmake/Modules/FindPixman.cmake
+new file mode 100644
+index 0000000..7bfca77
+--- /dev/null
++++ b/cmake/Modules/FindPixman.cmake
+@@ -0,0 +1,40 @@
++# - Find Pixman
++# Find the Pixman libraries
++#
++#  This module defines the following variables:
++#     PIXMAN_FOUND        - true if PIXMAN_INCLUDE_DIR & PIXMAN_LIBRARY are found
++#     PIXMAN_LIBRARIES    - Set when PIXMAN_LIBRARY is found
++#     PIXMAN_INCLUDE_DIRS - Set when PIXMAN_INCLUDE_DIR is found
++#
++#     PIXMAN_INCLUDE_DIR  - where to find pixman.h, etc.
++#     PIXMAN_LIBRARY      - the Pixman library
++#
++
++#=============================================================================
++# Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
++#
++# Licensed under the Apache License, Version 2.0 (the "License");
++# you may not use this file except in compliance with the License.
++# You may obtain a copy of the License at
++#
++#     http://www.apache.org/licenses/LICENSE-2.0
++#
++# Unless required by applicable law or agreed to in writing, software
++# distributed under the License is distributed on an "AS IS" BASIS,
++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++# See the License for the specific language governing permissions and
++# limitations under the License.
++#=============================================================================
++
++find_path(PIXMAN_INCLUDE_DIR NAMES pixman.h PATH_SUFFIXES pixman-1)
++
++find_library(PIXMAN_LIBRARY NAMES pixman-1)
++
++find_package_handle_standard_args(pixman-1 DEFAULT_MSG PIXMAN_LIBRARY PIXMAN_INCLUDE_DIR)
++
++if(PIXMAN-1_FOUND)
++	set(PIXMAN_LIBRARIES ${PIXMAN_LIBRARY})
++	set(PIXMAN_INCLUDE_DIRS ${PIXMAN_INCLUDE_DIR})
++endif()
++
++mark_as_advanced(PIXMAN_INCLUDE_DIR PIXMAN_LIBRARY)
+diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake
+index 6db0e14..db30c5c 100644
+--- a/cmake/StaticBuild.cmake
++++ b/cmake/StaticBuild.cmake
+@@ -19,6 +19,7 @@ if(BUILD_STATIC)
+   set(BUILD_STATIC_GCC 1)
+ 
+   set(JPEG_LIBRARIES "-Wl,-Bstatic -ljpeg -Wl,-Bdynamic")
++  set(PIXMAN_LIBRARY "-Wl,-Bstatic -lpixman-1 -Wl,-Bdynamic")
+ 
+   if(WIN32)
+     set(ZLIB_LIBRARIES "-Wl,-Bstatic -lz -Wl,-Bdynamic")
+@@ -133,7 +134,7 @@ if(BUILD_STATIC_GCC)
+     # these things again
+     set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt")
+   else()
+-    set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lgcc -lgcc_eh -lc")
++    set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lm -lgcc -lgcc_eh -lc")
+   endif()
+   set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}")
+ endif()
+diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
+index e4489f6..6fd1e10 100644
+--- a/common/CMakeLists.txt
++++ b/common/CMakeLists.txt
+@@ -1,7 +1,6 @@
+ add_subdirectory(os)
+ add_subdirectory(rdr)
+ add_subdirectory(network)
+-add_subdirectory(Xregion)
+ add_subdirectory(rfb)
+ 
+ # For any convenience libraries that are linked into libvnc.so, we need to
+@@ -10,6 +9,6 @@ add_subdirectory(rfb)
+ # is passed (additionally, libvnc is not used on Windows.)
+ 
+ if(NOT WIN32)
+-  set_target_properties(os rdr network Xregion rfb
++  set_target_properties(os rdr network rfb
+     PROPERTIES COMPILE_FLAGS -fPIC)
+ endif()
+diff --git a/common/Xregion/CMakeLists.txt b/common/Xregion/CMakeLists.txt
+deleted file mode 100644
+index 40ca97e..0000000
+--- a/common/Xregion/CMakeLists.txt
++++ /dev/null
+@@ -1,6 +0,0 @@
+-add_library(Xregion STATIC
+-  Region.c)
+-
+-if(UNIX)
+-  libtool_create_control_file(Xregion)
+-endif()
+diff --git a/common/Xregion/Region.c b/common/Xregion/Region.c
+deleted file mode 100644
+index 1acf581..0000000
+--- a/common/Xregion/Region.c
++++ /dev/null
+@@ -1,1612 +0,0 @@
+-/************************************************************************
+-
+-Copyright 1987, 1988, 1998  The Open Group
+-
+-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.
+-
+-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
+-OPEN GROUP 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.
+-
+-Except as contained in this notice, the name of The Open Group shall not be
+-used in advertising or otherwise to promote the sale, use or other dealings
+-in this Software without prior written authorization from The Open Group.
+-
+-
+-Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
+-
+-                        All Rights Reserved
+-
+-Permission to use, copy, modify, and distribute this software and its
+-documentation for any purpose and without fee is hereby granted,
+-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 Digital not be
+-used in advertising or publicity pertaining to distribution of the
+-software without specific, written prior permission.
+-
+-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+-DIGITAL 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.
+-
+-************************************************************************/
+-/*
+- * The functions in this file implement the Region abstraction, similar to one
+- * used in the X11 sample server. A Region is simply an area, as the name
+- * implies, and is implemented as a "y-x-banded" array of rectangles. To
+- * explain: Each Region is made up of a certain number of rectangles sorted
+- * by y coordinate first, and then by x coordinate.
+- *
+- * Furthermore, the rectangles are banded such that every rectangle with a
+- * given upper-left y coordinate (y1) will have the same lower-right y
+- * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it
+- * will span the entire vertical distance of the band. This means that some
+- * areas that could be merged into a taller rectangle will be represented as
+- * several shorter rectangles to account for shorter rectangles to its left
+- * or right but within its "vertical scope".
+- *
+- * An added constraint on the rectangles is that they must cover as much
+- * horizontal area as possible. E.g. no two rectangles in a band are allowed
+- * to touch.
+- *
+- * Whenever possible, bands will be merged together to cover a greater vertical
+- * distance (and thus reduce the number of rectangles). Two bands can be merged
+- * only if the bottom of one touches the top of the other and they have
+- * rectangles in the same places (of the same width, of course). This maintains
+- * the y-x-banding that's so nice to have...
+- */
+-
+-#include <string.h>
+-
+-#include "Xlibint.h"
+-#include "Xutil.h"
+-#include "Xregion.h"
+-
+-#ifndef min
+-#define min(a,b)            (((a) < (b)) ? (a) : (b))
+-#endif
+-#ifndef max
+-#define max(a,b)            (((a) > (b)) ? (a) : (b))
+-#endif
+-
+-#ifdef DEBUG
+-#include <stdio.h>
+-#define assert(expr) {if (!(expr)) fprintf(stderr,\
+-"Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); }
+-#else
+-#define assert(expr)
+-#endif
+-
+-typedef int (*overlapProcp)(
+-        register Region     pReg,
+-        register BoxPtr     r1,
+-        BoxPtr              r1End,
+-        register BoxPtr     r2,
+-        BoxPtr              r2End,
+-        short               y1,
+-        short               y2);
+-
+-typedef int (*nonOverlapProcp)(
+-    register Region     pReg,
+-    register BoxPtr     r,
+-    BoxPtr              rEnd,
+-    register short      y1,
+-    register short      y2);
+-
+-static void miRegionOp(
+-    register Region 	newReg,	    	    	/* Place to store result */
+-    Region	  	reg1,	    	    	/* First region in operation */
+-    Region	  	reg2,	    	    	/* 2d region in operation */
+-    int    	  	(*overlapFunc)(
+-        register Region     pReg,
+-        register BoxPtr     r1,
+-        BoxPtr              r1End,
+-        register BoxPtr     r2,
+-        BoxPtr              r2End,
+-        short               y1,
+-        short               y2),                /* Function to call for over-
+-						 * lapping bands */
+-    int    	  	(*nonOverlap1Func)(
+-        register Region     pReg,
+-        register BoxPtr     r,
+-        BoxPtr              rEnd,
+-        register short      y1,
+-        register short      y2),                /* Function to call for non-
+-						 * overlapping bands in region
+-						 * 1 */
+-    int    	  	(*nonOverlap2Func)(
+-        register Region     pReg,
+-        register BoxPtr     r,
+-        BoxPtr              rEnd,
+-        register short      y1,
+-        register short      y2));               /* Function to call for non-
+-						 * overlapping bands in region
+-						 * 2 */
+-
+-
+-/*	Create a new empty region	*/
+-Region
+-XCreateRegion(void)
+-{
+-    Region temp;
+-
+-    if (! (temp = Xmalloc(sizeof( REGION ))))
+-	return (Region) NULL;
+-    if (! (temp->rects = Xmalloc(sizeof( BOX )))) {
+-	Xfree(temp);
+-	return (Region) NULL;
+-    }
+-    temp->numRects = 0;
+-    temp->extents.x1 = 0;
+-    temp->extents.y1 = 0;
+-    temp->extents.x2 = 0;
+-    temp->extents.y2 = 0;
+-    temp->size = 1;
+-    return( temp );
+-}
+-
+-int
+-XClipBox(
+-    Region r,
+-    XRectangle *rect)
+-{
+-    rect->x = r->extents.x1;
+-    rect->y = r->extents.y1;
+-    rect->width = r->extents.x2 - r->extents.x1;
+-    rect->height = r->extents.y2 - r->extents.y1;
+-    return 1;
+-}
+-
+-int
+-XUnionRectWithRegion(
+-    register XRectangle *rect,
+-    Region source, Region dest)
+-{
+-    REGION region;
+-
+-    if (!rect->width || !rect->height)
+-	return 0;
+-    region.rects = &region.extents;
+-    region.numRects = 1;
+-    region.extents.x1 = rect->x;
+-    region.extents.y1 = rect->y;
+-    region.extents.x2 = rect->x + rect->width;
+-    region.extents.y2 = rect->y + rect->height;
+-    region.size = 1;
+-
+-    return XUnionRegion(&region, source, dest);
+-}
+-
+-/*-
+- *-----------------------------------------------------------------------
+- * miSetExtents --
+- *	Reset the extents of a region to what they should be. Called by
+- *	miSubtract and miIntersect b/c they can't figure it out along the
+- *	way or do so easily, as miUnion can.
+- *
+- * Results:
+- *	None.
+- *
+- * Side Effects:
+- *	The region's 'extents' structure is overwritten.
+- *
+- *-----------------------------------------------------------------------
+- */
+-static void
+-miSetExtents (
+-    Region	  	pReg)
+-{
+-    register BoxPtr	pBox,
+-			pBoxEnd,
+-			pExtents;
+-
+-    if (pReg->numRects == 0)
+-    {
+-	pReg->extents.x1 = 0;
+-	pReg->extents.y1 = 0;
+-	pReg->extents.x2 = 0;
+-	pReg->extents.y2 = 0;
+-	return;
+-    }
+-
+-    pExtents = &pReg->extents;
+-    pBox = pReg->rects;
+-    pBoxEnd = &pBox[pReg->numRects - 1];
+-
+-    /*
+-     * Since pBox is the first rectangle in the region, it must have the
+-     * smallest y1 and since pBoxEnd is the last rectangle in the region,
+-     * it must have the largest y2, because of banding. Initialize x1 and
+-     * x2 from  pBox and pBoxEnd, resp., as good things to initialize them
+-     * to...
+-     */
+-    pExtents->x1 = pBox->x1;
+-    pExtents->y1 = pBox->y1;
+-    pExtents->x2 = pBoxEnd->x2;
+-    pExtents->y2 = pBoxEnd->y2;
+-
+-    assert(pExtents->y1 < pExtents->y2);
+-    while (pBox <= pBoxEnd)
+-    {
+-	if (pBox->x1 < pExtents->x1)
+-	{
+-	    pExtents->x1 = pBox->x1;
+-	}
+-	if (pBox->x2 > pExtents->x2)
+-	{
+-	    pExtents->x2 = pBox->x2;
+-	}
+-	pBox++;
+-    }
+-    assert(pExtents->x1 < pExtents->x2);
+-}
+-
+-#if 0
+-int
+-XSetRegion(
+-    Display *dpy,
+-    GC gc,
+-    register Region r)
+-{
+-    register int i;
+-    register XRectangle *xr, *pr;
+-    register BOX *pb;
+-    unsigned long total;
+-
+-    LockDisplay (dpy);
+-    total = r->numRects * sizeof (XRectangle);
+-    if ((xr = (XRectangle *) _XAllocTemp(dpy, total))) {
+-	for (pr = xr, pb = r->rects, i = r->numRects; --i >= 0; pr++, pb++) {
+-	    pr->x = pb->x1;
+-	    pr->y = pb->y1;
+-	    pr->width = pb->x2 - pb->x1;
+-	    pr->height = pb->y2 - pb->y1;
+-	}
+-    }
+-    if (xr || !r->numRects)
+-	_XSetClipRectangles(dpy, gc, 0, 0, xr, r->numRects, YXBanded);
+-    if (xr)
+-	_XFreeTemp(dpy, (char *)xr, total);
+-    UnlockDisplay(dpy);
+-    SyncHandle();
+-    return 1;
+-}
+-#endif
+-
+-int
+-XDestroyRegion(
+-    Region r)
+-{
+-    Xfree( (char *) r->rects );
+-    Xfree( (char *) r );
+-    return 1;
+-}
+-
+-
+-/* TranslateRegion(pRegion, x, y)
+-   translates in place
+-   added by raymond
+-*/
+-
+-int
+-XOffsetRegion(
+-    register Region pRegion,
+-    register int x,
+-    register int y)
+-{
+-    register int nbox;
+-    register BOX *pbox;
+-
+-    pbox = pRegion->rects;
+-    nbox = pRegion->numRects;
+-
+-    while(nbox--)
+-    {
+-	pbox->x1 += x;
+-	pbox->x2 += x;
+-	pbox->y1 += y;
+-	pbox->y2 += y;
+-	pbox++;
+-    }
+-    pRegion->extents.x1 += x;
+-    pRegion->extents.x2 += x;
+-    pRegion->extents.y1 += y;
+-    pRegion->extents.y2 += y;
+-    return 1;
+-}
+-
+-/*
+-   Utility procedure Compress:
+-   Replace r by the region r', where
+-     p in r' iff (Quantifer m <= dx) (p + m in r), and
+-     Quantifier is Exists if grow is TRUE, For all if grow is FALSE, and
+-     (x,y) + m = (x+m,y) if xdir is TRUE; (x,y+m) if xdir is FALSE.
+-
+-   Thus, if xdir is TRUE and grow is FALSE, r is replaced by the region
+-   of all points p such that p and the next dx points on the same
+-   horizontal scan line are all in r.  We do this using by noting
+-   that p is the head of a run of length 2^i + k iff p is the head
+-   of a run of length 2^i and p+2^i is the head of a run of length
+-   k. Thus, the loop invariant: s contains the region corresponding
+-   to the runs of length shift.  r contains the region corresponding
+-   to the runs of length 1 + dxo & (shift-1), where dxo is the original
+-   value of dx.  dx = dxo & ~(shift-1).  As parameters, s and t are
+-   scratch regions, so that we don't have to allocate them on every
+-   call.
+-*/
+-
+-#define ZOpRegion(a,b,c) if (grow) XUnionRegion(a,b,c); \
+-			 else XIntersectRegion(a,b,c)
+-#define ZShiftRegion(a,b) if (xdir) XOffsetRegion(a,b,0); \
+-			  else XOffsetRegion(a,0,b)
+-#define ZCopyRegion(a,b) XUnionRegion(a,a,b)
+-
+-static void
+-Compress(
+-    Region r, Region s, Region t,
+-    register unsigned dx,
+-    register int xdir, register int grow)
+-{
+-    register unsigned shift = 1;
+-
+-    ZCopyRegion(r, s);
+-    while (dx) {
+-        if (dx & shift) {
+-            ZShiftRegion(r, -(int)shift);
+-            ZOpRegion(r, s, r);
+-            dx -= shift;
+-            if (!dx) break;
+-        }
+-        ZCopyRegion(s, t);
+-        ZShiftRegion(s, -(int)shift);
+-        ZOpRegion(s, t, s);
+-        shift <<= 1;
+-    }
+-}
+-
+-#undef ZOpRegion
+-#undef ZShiftRegion
+-#undef ZCopyRegion
+-
+-int
+-XShrinkRegion(
+-    Region r,
+-    int dx, int dy)
+-{
+-    Region s, t;
+-    int grow;
+-
+-    if (!dx && !dy) return 0;
+-    if (! (s = XCreateRegion()) )
+-	return 0;
+-    if (! (t = XCreateRegion()) ) {
+-	XDestroyRegion(s);
+-	return 0;
+-    }
+-    if ((grow = (dx < 0))) dx = -dx;
+-    if (dx) Compress(r, s, t, (unsigned) 2*dx, TRUE, grow);
+-    if ((grow = (dy < 0))) dy = -dy;
+-    if (dy) Compress(r, s, t, (unsigned) 2*dy, FALSE, grow);
+-    XOffsetRegion(r, dx, dy);
+-    XDestroyRegion(s);
+-    XDestroyRegion(t);
+-    return 0;
+-}
+-
+-
+-/*======================================================================
+- *	    Region Intersection
+- *====================================================================*/
+-/*-
+- *-----------------------------------------------------------------------
+- * miIntersectO --
+- *	Handle an overlapping band for miIntersect.
+- *
+- * Results:
+- *	None.
+- *
+- * Side Effects:
+- *	Rectangles may be added to the region.
+- *
+- *-----------------------------------------------------------------------
+- */
+-/* static void*/
+-static int
+-miIntersectO (
+-    register Region	pReg,
+-    register BoxPtr	r1,
+-    BoxPtr  	  	r1End,
+-    register BoxPtr	r2,
+-    BoxPtr  	  	r2End,
+-    short    	  	y1,
+-    short    	  	y2)
+-{
+-    register short  	x1;
+-    register short  	x2;
+-    register BoxPtr	pNextRect;
+-
+-    pNextRect = &pReg->rects[pReg->numRects];
+-
+-    while ((r1 != r1End) && (r2 != r2End))
+-    {
+-	x1 = max(r1->x1,r2->x1);
+-	x2 = min(r1->x2,r2->x2);
+-
+-	/*
+-	 * If there's any overlap between the two rectangles, add that
+-	 * overlap to the new region.
+-	 * There's no need to check for subsumption because the only way
+-	 * such a need could arise is if some region has two rectangles
+-	 * right next to each other. Since that should never happen...
+-	 */
+-	if (x1 < x2)
+-	{
+-	    assert(y1<y2);
+-
+-	    MEMCHECK(pReg, pNextRect, pReg->rects);
+-	    pNextRect->x1 = x1;
+-	    pNextRect->y1 = y1;
+-	    pNextRect->x2 = x2;
+-	    pNextRect->y2 = y2;
+-	    pReg->numRects += 1;
+-	    pNextRect++;
+-	    assert(pReg->numRects <= pReg->size);
+-	}
+-
+-	/*
+-	 * Need to advance the pointers. Shift the one that extends
+-	 * to the right the least, since the other still has a chance to
+-	 * overlap with that region's next rectangle, if you see what I mean.
+-	 */
+-	if (r1->x2 < r2->x2)
+-	{
+-	    r1++;
+-	}
+-	else if (r2->x2 < r1->x2)
+-	{
+-	    r2++;
+-	}
+-	else
+-	{
+-	    r1++;
+-	    r2++;
+-	}
+-    }
+-    return 0;	/* lint */
+-}
+-
+-int
+-XIntersectRegion(
+-    Region 	  	reg1,
+-    Region	  	reg2,          /* source regions     */
+-    register Region 	newReg)               /* destination Region */
+-{
+-   /* check for trivial reject */
+-    if ( (!(reg1->numRects)) || (!(reg2->numRects))  ||
+-	(!EXTENTCHECK(&reg1->extents, &reg2->extents)))
+-        newReg->numRects = 0;
+-    else
+-	miRegionOp (newReg, reg1, reg2,
+-    		miIntersectO, NULL, NULL);
+-
+-    /*
+-     * Can't alter newReg's extents before we call miRegionOp because
+-     * it might be one of the source regions and miRegionOp depends
+-     * on the extents of those regions being the same. Besides, this
+-     * way there's no checking against rectangles that will be nuked
+-     * due to coalescing, so we have to examine fewer rectangles.
+-     */
+-    miSetExtents(newReg);
+-    return 1;
+-}
+-
+-static int
+-miRegionCopy(
+-    register Region dstrgn,
+-    register Region rgn)
+-
+-{
+-    if (dstrgn != rgn) /*  don't want to copy to itself */
+-    {
+-        if (dstrgn->size < rgn->numRects)
+-        {
+-            if (dstrgn->rects)
+-            {
+-		BOX *prevRects = dstrgn->rects;
+-
+-		dstrgn->rects = Xrealloc(dstrgn->rects,
+-					 rgn->numRects * (sizeof(BOX)));
+-		if (! dstrgn->rects) {
+-		    Xfree(prevRects);
+-		    dstrgn->size = 0;
+-		    return 0;
+-		}
+-            }
+-            dstrgn->size = rgn->numRects;
+-	}
+-        dstrgn->numRects = rgn->numRects;
+-        dstrgn->extents.x1 = rgn->extents.x1;
+-        dstrgn->extents.y1 = rgn->extents.y1;
+-        dstrgn->extents.x2 = rgn->extents.x2;
+-        dstrgn->extents.y2 = rgn->extents.y2;
+-
+-	memcpy((char *) dstrgn->rects, (char *) rgn->rects,
+-	       (int) (rgn->numRects * sizeof(BOX)));
+-    }
+-    return 1;
+-}
+-
+-/*======================================================================
+- *	    Generic Region Operator
+- *====================================================================*/
+-
+-/*-
+- *-----------------------------------------------------------------------
+- * miCoalesce --
+- *	Attempt to merge the boxes in the current band with those in the
+- *	previous one. Used only by miRegionOp.
+- *
+- * Results:
+- *	The new index for the previous band.
+- *
+- * Side Effects:
+- *	If coalescing takes place:
+- *	    - rectangles in the previous band will have their y2 fields
+- *	      altered.
+- *	    - pReg->numRects will be decreased.
+- *
+- *-----------------------------------------------------------------------
+- */
+-/* static int*/
+-static int
+-miCoalesce(
+-    register Region	pReg,	    	/* Region to coalesce */
+-    int	    	  	prevStart,  	/* Index of start of previous band */
+-    int	    	  	curStart)   	/* Index of start of current band */
+-{
+-    register BoxPtr	pPrevBox;   	/* Current box in previous band */
+-    register BoxPtr	pCurBox;    	/* Current box in current band */
+-    register BoxPtr	pRegEnd;    	/* End of region */
+-    int	    	  	curNumRects;	/* Number of rectangles in current
+-					 * band */
+-    int	    	  	prevNumRects;	/* Number of rectangles in previous
+-					 * band */
+-    int	    	  	bandY1;	    	/* Y1 coordinate for current band */
+-
+-    pRegEnd = &pReg->rects[pReg->numRects];
+-
+-    pPrevBox = &pReg->rects[prevStart];
+-    prevNumRects = curStart - prevStart;
+-
+-    /*
+-     * Figure out how many rectangles are in the current band. Have to do
+-     * this because multiple bands could have been added in miRegionOp
+-     * at the end when one region has been exhausted.
+-     */
+-    pCurBox = &pReg->rects[curStart];
+-    bandY1 = pCurBox->y1;
+-    for (curNumRects = 0;
+-	 (pCurBox != pRegEnd) && (pCurBox->y1 == bandY1);
+-	 curNumRects++)
+-    {
+-	pCurBox++;
+-    }
+-
+-    if (pCurBox != pRegEnd)
+-    {
+-	/*
+-	 * If more than one band was added, we have to find the start
+-	 * of the last band added so the next coalescing job can start
+-	 * at the right place... (given when multiple bands are added,
+-	 * this may be pointless -- see above).
+-	 */
+-	pRegEnd--;
+-	while (pRegEnd[-1].y1 == pRegEnd->y1)
+-	{
+-	    pRegEnd--;
+-	}
+-	curStart = pRegEnd - pReg->rects;
+-	pRegEnd = pReg->rects + pReg->numRects;
+-    }
+-
+-    if ((curNumRects == prevNumRects) && (curNumRects != 0)) {
+-	pCurBox -= curNumRects;
+-	/*
+-	 * The bands may only be coalesced if the bottom of the previous
+-	 * matches the top scanline of the current.
+-	 */
+-	if (pPrevBox->y2 == pCurBox->y1)
+-	{
+-	    /*
+-	     * Make sure the bands have boxes in the same places. This
+-	     * assumes that boxes have been added in such a way that they
+-	     * cover the most area possible. I.e. two boxes in a band must
+-	     * have some horizontal space between them.
+-	     */
+-	    do
+-	    {
+-		if ((pPrevBox->x1 != pCurBox->x1) ||
+-		    (pPrevBox->x2 != pCurBox->x2))
+-		{
+-		    /*
+-		     * The bands don't line up so they can't be coalesced.
+-		     */
+-		    return (curStart);
+-		}
+-		pPrevBox++;
+-		pCurBox++;
+-		prevNumRects -= 1;
+-	    } while (prevNumRects != 0);
+-
+-	    pReg->numRects -= curNumRects;
+-	    pCurBox -= curNumRects;
+-	    pPrevBox -= curNumRects;
+-
+-	    /*
+-	     * The bands may be merged, so set the bottom y of each box
+-	     * in the previous band to that of the corresponding box in
+-	     * the current band.
+-	     */
+-	    do
+-	    {
+-		pPrevBox->y2 = pCurBox->y2;
+-		pPrevBox++;
+-		pCurBox++;
+-		curNumRects -= 1;
+-	    } while (curNumRects != 0);
+-
+-	    /*
+-	     * If only one band was added to the region, we have to backup
+-	     * curStart to the start of the previous band.
+-	     *
+-	     * If more than one band was added to the region, copy the
+-	     * other bands down. The assumption here is that the other bands
+-	     * came from the same region as the current one and no further
+-	     * coalescing can be done on them since it's all been done
+-	     * already... curStart is already in the right place.
+-	     */
+-	    if (pCurBox == pRegEnd)
+-	    {
+-		curStart = prevStart;
+-	    }
+-	    else
+-	    {
+-		do
+-		{
+-		    *pPrevBox++ = *pCurBox++;
+-		} while (pCurBox != pRegEnd);
+-	    }
+-
+-	}
+-    }
+-    return (curStart);
+-}
+-
+-/*-
+- *-----------------------------------------------------------------------
+- * miRegionOp --
+- *	Apply an operation to two regions. Called by miUnion, miInverse,
+- *	miSubtract, miIntersect...
+- *
+- * Results:
+- *	None.
+- *
+- * Side Effects:
+- *	The new region is overwritten.
+- *
+- * Notes:
+- *	The idea behind this function is to view the two regions as sets.
+- *	Together they cover a rectangle of area that this function divides
+- *	into horizontal bands where points are covered only by one region
+- *	or by both. For the first case, the nonOverlapFunc is called with
+- *	each the band and the band's upper and lower extents. For the
+- *	second, the overlapFunc is called to process the entire band. It
+- *	is responsible for clipping the rectangles in the band, though
+- *	this function provides the boundaries.
+- *	At the end of each band, the new region is coalesced, if possible,
+- *	to reduce the number of rectangles in the region.
+- *
+- *-----------------------------------------------------------------------
+- */
+-/* static void*/
+-static void
+-miRegionOp(
+-    register Region 	newReg,	    	    	/* Place to store result */
+-    Region	  	reg1,	    	    	/* First region in operation */
+-    Region	  	reg2,	    	    	/* 2d region in operation */
+-    int    	  	(*overlapFunc)(
+-        register Region     pReg,
+-        register BoxPtr     r1,
+-        BoxPtr              r1End,
+-        register BoxPtr     r2,
+-        BoxPtr              r2End,
+-        short               y1,
+-        short               y2),                /* Function to call for over-
+-						 * lapping bands */
+-    int    	  	(*nonOverlap1Func)(
+-        register Region     pReg,
+-        register BoxPtr     r,
+-        BoxPtr              rEnd,
+-        register short      y1,
+-        register short      y2),                /* Function to call for non-
+-						 * overlapping bands in region
+-						 * 1 */
+-    int    	  	(*nonOverlap2Func)(
+-        register Region     pReg,
+-        register BoxPtr     r,
+-        BoxPtr              rEnd,
+-        register short      y1,
+-        register short      y2))                /* Function to call for non-
+-						 * overlapping bands in region
+-						 * 2 */
+-{
+-    register BoxPtr	r1; 	    	    	/* Pointer into first region */
+-    register BoxPtr	r2; 	    	    	/* Pointer into 2d region */
+-    BoxPtr  	  	r1End;	    	    	/* End of 1st region */
+-    BoxPtr  	  	r2End;	    	    	/* End of 2d region */
+-    register short  	ybot;	    	    	/* Bottom of intersection */
+-    register short  	ytop;	    	    	/* Top of intersection */
+-    BoxPtr  	  	oldRects;   	    	/* Old rects for newReg */
+-    int	    	  	prevBand;   	    	/* Index of start of
+-						 * previous band in newReg */
+-    int	    	  	curBand;    	    	/* Index of start of current
+-						 * band in newReg */
+-    register BoxPtr 	r1BandEnd;  	    	/* End of current band in r1 */
+-    register BoxPtr 	r2BandEnd;  	    	/* End of current band in r2 */
+-    short     	  	top;	    	    	/* Top of non-overlapping
+-						 * band */
+-    short     	  	bot;	    	    	/* Bottom of non-overlapping
+-						 * band */
+-
+-    /*
+-     * Initialization:
+-     *	set r1, r2, r1End and r2End appropriately, preserve the important
+-     * parts of the destination region until the end in case it's one of
+-     * the two source regions, then mark the "new" region empty, allocating
+-     * another array of rectangles for it to use.
+-     */
+-    r1 = reg1->rects;
+-    r2 = reg2->rects;
+-    r1End = r1 + reg1->numRects;
+-    r2End = r2 + reg2->numRects;
+-
+-    oldRects = newReg->rects;
+-
+-    EMPTY_REGION(newReg);
+-
+-    /*
+-     * Allocate a reasonable number of rectangles for the new region. The idea
+-     * is to allocate enough so the individual functions don't need to
+-     * reallocate and copy the array, which is time consuming, yet we don't
+-     * have to worry about using too much memory. I hope to be able to
+-     * nuke the Xrealloc() at the end of this function eventually.
+-     */
+-    newReg->size = max(reg1->numRects,reg2->numRects) * 2;
+-
+-    if (! (newReg->rects = Xmalloc (sizeof(BoxRec) * newReg->size))) {
+-	newReg->size = 0;
+-	return;
+-    }
+-
+-    /*
+-     * Initialize ybot and ytop.
+-     * In the upcoming loop, ybot and ytop serve different functions depending
+-     * on whether the band being handled is an overlapping or non-overlapping
+-     * band.
+-     * 	In the case of a non-overlapping band (only one of the regions
+-     * has points in the band), ybot is the bottom of the most recent
+-     * intersection and thus clips the top of the rectangles in that band.
+-     * ytop is the top of the next intersection between the two regions and
+-     * serves to clip the bottom of the rectangles in the current band.
+-     *	For an overlapping band (where the two regions intersect), ytop clips
+-     * the top of the rectangles of both regions and ybot clips the bottoms.
+-     */
+-    if (reg1->extents.y1 < reg2->extents.y1)
+-	ybot = reg1->extents.y1;
+-    else
+-	ybot = reg2->extents.y1;
+-
+-    /*
+-     * prevBand serves to mark the start of the previous band so rectangles
+-     * can be coalesced into larger rectangles. qv. miCoalesce, above.
+-     * In the beginning, there is no previous band, so prevBand == curBand
+-     * (curBand is set later on, of course, but the first band will always
+-     * start at index 0). prevBand and curBand must be indices because of
+-     * the possible expansion, and resultant moving, of the new region's
+-     * array of rectangles.
+-     */
+-    prevBand = 0;
+-
+-    do
+-    {
+-	curBand = newReg->numRects;
+-
+-	/*
+-	 * This algorithm proceeds one source-band (as opposed to a
+-	 * destination band, which is determined by where the two regions
+-	 * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
+-	 * rectangle after the last one in the current band for their
+-	 * respective regions.
+-	 */
+-	r1BandEnd = r1;
+-	while ((r1BandEnd != r1End) && (r1BandEnd->y1 == r1->y1))
+-	{
+-	    r1BandEnd++;
+-	}
+-
+-	r2BandEnd = r2;
+-	while ((r2BandEnd != r2End) && (r2BandEnd->y1 == r2->y1))
+-	{
+-	    r2BandEnd++;
+-	}
+-
+-	/*
+-	 * First handle the band that doesn't intersect, if any.
+-	 *
+-	 * Note that attention is restricted to one band in the
+-	 * non-intersecting region at once, so if a region has n
+-	 * bands between the current position and the next place it overlaps
+-	 * the other, this entire loop will be passed through n times.
+-	 */
+-	if (r1->y1 < r2->y1)
+-	{
+-	    top = max(r1->y1,ybot);
+-	    bot = min(r1->y2,r2->y1);
+-
+-	    if ((top != bot) && (nonOverlap1Func != NULL))
+-	    {
+-		(* nonOverlap1Func) (newReg, r1, r1BandEnd, top, bot);
+-	    }
+-
+-	    ytop = r2->y1;
+-	}
+-	else if (r2->y1 < r1->y1)
+-	{
+-	    top = max(r2->y1,ybot);
+-	    bot = min(r2->y2,r1->y1);
+-
+-	    if ((top != bot) && (nonOverlap2Func != NULL))
+-	    {
+-		(* nonOverlap2Func) (newReg, r2, r2BandEnd, top, bot);
+-	    }
+-
+-	    ytop = r1->y1;
+-	}
+-	else
+-	{
+-	    ytop = r1->y1;
+-	}
+-
+-	/*
+-	 * If any rectangles got added to the region, try and coalesce them
+-	 * with rectangles from the previous band. Note we could just do
+-	 * this test in miCoalesce, but some machines incur a not
+-	 * inconsiderable cost for function calls, so...
+-	 */
+-	if (newReg->numRects != curBand)
+-	{
+-	    prevBand = miCoalesce (newReg, prevBand, curBand);
+-	}
+-
+-	/*
+-	 * Now see if we've hit an intersecting band. The two bands only
+-	 * intersect if ybot > ytop
+-	 */
+-	ybot = min(r1->y2, r2->y2);
+-	curBand = newReg->numRects;
+-	if (ybot > ytop)
+-	{
+-	    (* overlapFunc) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
+-
+-	}
+-
+-	if (newReg->numRects != curBand)
+-	{
+-	    prevBand = miCoalesce (newReg, prevBand, curBand);
+-	}
+-
+-	/*
+-	 * If we've finished with a band (y2 == ybot) we skip forward
+-	 * in the region to the next band.
+-	 */
+-	if (r1->y2 == ybot)
+-	{
+-	    r1 = r1BandEnd;
+-	}
+-	if (r2->y2 == ybot)
+-	{
+-	    r2 = r2BandEnd;
+-	}
+-    } while ((r1 != r1End) && (r2 != r2End));
+-
+-    /*
+-     * Deal with whichever region still has rectangles left.
+-     */
+-    curBand = newReg->numRects;
+-    if (r1 != r1End)
+-    {
+-	if (nonOverlap1Func != NULL)
+-	{
+-	    do
+-	    {
+-		r1BandEnd = r1;
+-		while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1))
+-		{
+-		    r1BandEnd++;
+-		}
+-		(* nonOverlap1Func) (newReg, r1, r1BandEnd,
+-				     max(r1->y1,ybot), r1->y2);
+-		r1 = r1BandEnd;
+-	    } while (r1 != r1End);
+-	}
+-    }
+-    else if ((r2 != r2End) && (nonOverlap2Func != NULL))
+-    {
+-	do
+-	{
+-	    r2BandEnd = r2;
+-	    while ((r2BandEnd < r2End) && (r2BandEnd->y1 == r2->y1))
+-	    {
+-		 r2BandEnd++;
+-	    }
+-	    (* nonOverlap2Func) (newReg, r2, r2BandEnd,
+-				max(r2->y1,ybot), r2->y2);
+-	    r2 = r2BandEnd;
+-	} while (r2 != r2End);
+-    }
+-
+-    if (newReg->numRects != curBand)
+-    {
+-	(void) miCoalesce (newReg, prevBand, curBand);
+-    }
+-
+-    /*
+-     * A bit of cleanup. To keep regions from growing without bound,
+-     * we shrink the array of rectangles to match the new number of
+-     * rectangles in the region. This never goes to 0, however...
+-     *
+-     * Only do this stuff if the number of rectangles allocated is more than
+-     * twice the number of rectangles in the region (a simple optimization...).
+-     */
+-    if (newReg->numRects < (newReg->size >> 1))
+-    {
+-	if (REGION_NOT_EMPTY(newReg))
+-	{
+-	    BoxPtr prev_rects = newReg->rects;
+-	    newReg->rects = Xrealloc (newReg->rects,
+-				      sizeof(BoxRec) * newReg->numRects);
+-	    if (! newReg->rects)
+-		newReg->rects = prev_rects;
+-	    else
+-		newReg->size = newReg->numRects;
+-	}
+-	else
+-	{
+-	    /*
+-	     * No point in doing the extra work involved in an Xrealloc if
+-	     * the region is empty
+-	     */
+-	    newReg->size = 1;
+-	    Xfree(newReg->rects);
+-	    newReg->rects = Xmalloc(sizeof(BoxRec));
+-	}
+-    }
+-    Xfree (oldRects);
+-    return;
+-}
+-
+-
+-/*======================================================================
+- *	    Region Union
+- *====================================================================*/
+-
+-/*-
+- *-----------------------------------------------------------------------
+- * miUnionNonO --
+- *	Handle a non-overlapping band for the union operation. Just
+- *	Adds the rectangles into the region. Doesn't have to check for
+- *	subsumption or anything.
+- *
+- * Results:
+- *	None.
+- *
+- * Side Effects:
+- *	pReg->numRects is incremented and the final rectangles overwritten
+- *	with the rectangles we're passed.
+- *
+- *-----------------------------------------------------------------------
+- */
+-/* static void*/
+-static int
+-miUnionNonO (
+-    register Region	pReg,
+-    register BoxPtr	r,
+-    BoxPtr  	  	rEnd,
+-    register short  	y1,
+-    register short  	y2)
+-{
+-    register BoxPtr	pNextRect;
+-
+-    pNextRect = &pReg->rects[pReg->numRects];
+-
+-    assert(y1 < y2);
+-
+-    while (r != rEnd)
+-    {
+-	assert(r->x1 < r->x2);
+-	MEMCHECK(pReg, pNextRect, pReg->rects);
+-	pNextRect->x1 = r->x1;
+-	pNextRect->y1 = y1;
+-	pNextRect->x2 = r->x2;
+-	pNextRect->y2 = y2;
+-	pReg->numRects += 1;
+-	pNextRect++;
+-
+-	assert(pReg->numRects<=pReg->size);
+-	r++;
+-    }
+-    return 0;	/* lint */
+-}
+-
+-
+-/*-
+- *-----------------------------------------------------------------------
+- * miUnionO --
+- *	Handle an overlapping band for the union operation. Picks the
+- *	left-most rectangle each time and merges it into the region.
+- *
+- * Results:
+- *	None.
+- *
+- * Side Effects:
+- *	Rectangles are overwritten in pReg->rects and pReg->numRects will
+- *	be changed.
+- *
+- *-----------------------------------------------------------------------
+- */
+-
+-/* static void*/
+-static int
+-miUnionO (
+-    register Region	pReg,
+-    register BoxPtr	r1,
+-    BoxPtr  	  	r1End,
+-    register BoxPtr	r2,
+-    BoxPtr  	  	r2End,
+-    register short	y1,
+-    register short	y2)
+-{
+-    register BoxPtr	pNextRect;
+-
+-    pNextRect = &pReg->rects[pReg->numRects];
+-
+-#define MERGERECT(r) \
+-    if ((pReg->numRects != 0) &&  \
+-	(pNextRect[-1].y1 == y1) &&  \
+-	(pNextRect[-1].y2 == y2) &&  \
+-	(pNextRect[-1].x2 >= r->x1))  \
+-    {  \
+-	if (pNextRect[-1].x2 < r->x2)  \
+-	{  \
+-	    pNextRect[-1].x2 = r->x2;  \
+-	    assert(pNextRect[-1].x1<pNextRect[-1].x2); \
+-	}  \
+-    }  \
+-    else  \
+-    {  \
+-	MEMCHECK(pReg, pNextRect, pReg->rects);  \
+-	pNextRect->y1 = y1;  \
+-	pNextRect->y2 = y2;  \
+-	pNextRect->x1 = r->x1;  \
+-	pNextRect->x2 = r->x2;  \
+-	pReg->numRects += 1;  \
+-        pNextRect += 1;  \
+-    }  \
+-    assert(pReg->numRects<=pReg->size);\
+-    r++;
+-
+-    assert (y1<y2);
+-    while ((r1 != r1End) && (r2 != r2End))
+-    {
+-	if (r1->x1 < r2->x1)
+-	{
+-	    MERGERECT(r1);
+-	}
+-	else
+-	{
+-	    MERGERECT(r2);
+-	}
+-    }
+-
+-    if (r1 != r1End)
+-    {
+-	do
+-	{
+-	    MERGERECT(r1);
+-	} while (r1 != r1End);
+-    }
+-    else while (r2 != r2End)
+-    {
+-	MERGERECT(r2);
+-    }
+-    return 0;	/* lint */
+-}
+-
+-int
+-XUnionRegion(
+-    Region 	  reg1,
+-    Region	  reg2,             /* source regions     */
+-    Region 	  newReg)                  /* destination Region */
+-{
+-    /*  checks all the simple cases */
+-
+-    /*
+-     * Region 1 and 2 are the same or region 1 is empty
+-     */
+-    if ( (reg1 == reg2) || (!(reg1->numRects)) )
+-    {
+-        if (newReg != reg2)
+-            return miRegionCopy(newReg, reg2);
+-        return 1;
+-    }
+-
+-    /*
+-     * if nothing to union (region 2 empty)
+-     */
+-    if (!(reg2->numRects))
+-    {
+-        if (newReg != reg1)
+-            return miRegionCopy(newReg, reg1);
+-        return 1;
+-    }
+-
+-    /*
+-     * Region 1 completely subsumes region 2
+-     */
+-    if ((reg1->numRects == 1) &&
+-	(reg1->extents.x1 <= reg2->extents.x1) &&
+-	(reg1->extents.y1 <= reg2->extents.y1) &&
+-	(reg1->extents.x2 >= reg2->extents.x2) &&
+-	(reg1->extents.y2 >= reg2->extents.y2))
+-    {
+-        if (newReg != reg1)
+-            return miRegionCopy(newReg, reg1);
+-        return 1;
+-    }
+-
+-    /*
+-     * Region 2 completely subsumes region 1
+-     */
+-    if ((reg2->numRects == 1) &&
+-	(reg2->extents.x1 <= reg1->extents.x1) &&
+-	(reg2->extents.y1 <= reg1->extents.y1) &&
+-	(reg2->extents.x2 >= reg1->extents.x2) &&
+-	(reg2->extents.y2 >= reg1->extents.y2))
+-    {
+-        if (newReg != reg2)
+-            return miRegionCopy(newReg, reg2);
+-        return 1;
+-    }
+-
+-    miRegionOp (newReg, reg1, reg2, miUnionO,
+-    		miUnionNonO, miUnionNonO);
+-
+-    newReg->extents.x1 = min(reg1->extents.x1, reg2->extents.x1);
+-    newReg->extents.y1 = min(reg1->extents.y1, reg2->extents.y1);
+-    newReg->extents.x2 = max(reg1->extents.x2, reg2->extents.x2);
+-    newReg->extents.y2 = max(reg1->extents.y2, reg2->extents.y2);
+-
+-    return 1;
+-}
+-
+-
+-/*======================================================================
+- * 	    	  Region Subtraction
+- *====================================================================*/
+-
+-/*-
+- *-----------------------------------------------------------------------
+- * miSubtractNonO --
+- *	Deal with non-overlapping band for subtraction. Any parts from
+- *	region 2 we discard. Anything from region 1 we add to the region.
+- *
+- * Results:
+- *	None.
+- *
+- * Side Effects:
+- *	pReg may be affected.
+- *
+- *-----------------------------------------------------------------------
+- */
+-/* static void*/
+-static int
+-miSubtractNonO1 (
+-    register Region	pReg,
+-    register BoxPtr	r,
+-    BoxPtr  	  	rEnd,
+-    register short  	y1,
+-    register short   	y2)
+-{
+-    register BoxPtr	pNextRect;
+-
+-    pNextRect = &pReg->rects[pReg->numRects];
+-
+-    assert(y1<y2);
+-
+-    while (r != rEnd)
+-    {
+-	assert(r->x1<r->x2);
+-	MEMCHECK(pReg, pNextRect, pReg->rects);
+-	pNextRect->x1 = r->x1;
+-	pNextRect->y1 = y1;
+-	pNextRect->x2 = r->x2;
+-	pNextRect->y2 = y2;
+-	pReg->numRects += 1;
+-	pNextRect++;
+-
+-	assert(pReg->numRects <= pReg->size);
+-
+-	r++;
+-    }
+-    return 0;	/* lint */
+-}
+-
+-/*-
+- *-----------------------------------------------------------------------
+- * miSubtractO --
+- *	Overlapping band subtraction. x1 is the left-most point not yet
+- *	checked.
+- *
+- * Results:
+- *	None.
+- *
+- * Side Effects:
+- *	pReg may have rectangles added to it.
+- *
+- *-----------------------------------------------------------------------
+- */
+-/* static void*/
+-static int
+-miSubtractO (
+-    register Region	pReg,
+-    register BoxPtr	r1,
+-    BoxPtr  	  	r1End,
+-    register BoxPtr	r2,
+-    BoxPtr  	  	r2End,
+-    register short  	y1,
+-    register short  	y2)
+-{
+-    register BoxPtr	pNextRect;
+-    register int  	x1;
+-
+-    x1 = r1->x1;
+-
+-    assert(y1<y2);
+-    pNextRect = &pReg->rects[pReg->numRects];
+-
+-    while ((r1 != r1End) && (r2 != r2End))
+-    {
+-	if (r2->x2 <= x1)
+-	{
+-	    /*
+-	     * Subtrahend missed the boat: go to next subtrahend.
+-	     */
+-	    r2++;
+-	}
+-	else if (r2->x1 <= x1)
+-	{
+-	    /*
+-	     * Subtrahend preceds minuend: nuke left edge of minuend.
+-	     */
+-	    x1 = r2->x2;
+-	    if (x1 >= r1->x2)
+-	    {
+-		/*
+-		 * Minuend completely covered: advance to next minuend and
+-		 * reset left fence to edge of new minuend.
+-		 */
+-		r1++;
+-		if (r1 != r1End)
+-		    x1 = r1->x1;
+-	    }
+-	    else
+-	    {
+-		/*
+-		 * Subtrahend now used up since it doesn't extend beyond
+-		 * minuend
+-		 */
+-		r2++;
+-	    }
+-	}
+-	else if (r2->x1 < r1->x2)
+-	{
+-	    /*
+-	     * Left part of subtrahend covers part of minuend: add uncovered
+-	     * part of minuend to region and skip to next subtrahend.
+-	     */
+-	    assert(x1<r2->x1);
+-	    MEMCHECK(pReg, pNextRect, pReg->rects);
+-	    pNextRect->x1 = x1;
+-	    pNextRect->y1 = y1;
+-	    pNextRect->x2 = r2->x1;
+-	    pNextRect->y2 = y2;
+-	    pReg->numRects += 1;
+-	    pNextRect++;
+-
+-	    assert(pReg->numRects<=pReg->size);
+-
+-	    x1 = r2->x2;
+-	    if (x1 >= r1->x2)
+-	    {
+-		/*
+-		 * Minuend used up: advance to new...
+-		 */
+-		r1++;
+-		if (r1 != r1End)
+-		    x1 = r1->x1;
+-	    }
+-	    else
+-	    {
+-		/*
+-		 * Subtrahend used up
+-		 */
+-		r2++;
+-	    }
+-	}
+-	else
+-	{
+-	    /*
+-	     * Minuend used up: add any remaining piece before advancing.
+-	     */
+-	    if (r1->x2 > x1)
+-	    {
+-		MEMCHECK(pReg, pNextRect, pReg->rects);
+-		pNextRect->x1 = x1;
+-		pNextRect->y1 = y1;
+-		pNextRect->x2 = r1->x2;
+-		pNextRect->y2 = y2;
+-		pReg->numRects += 1;
+-		pNextRect++;
+-		assert(pReg->numRects<=pReg->size);
+-	    }
+-	    r1++;
+-	    if (r1 != r1End)
+-		x1 = r1->x1;
+-	}
+-    }
+-
+-    /*
+-     * Add remaining minuend rectangles to region.
+-     */
+-    while (r1 != r1End)
+-    {
+-	assert(x1<r1->x2);
+-	MEMCHECK(pReg, pNextRect, pReg->rects);
+-	pNextRect->x1 = x1;
+-	pNextRect->y1 = y1;
+-	pNextRect->x2 = r1->x2;
+-	pNextRect->y2 = y2;
+-	pReg->numRects += 1;
+-	pNextRect++;
+-
+-	assert(pReg->numRects<=pReg->size);
+-
+-	r1++;
+-	if (r1 != r1End)
+-	{
+-	    x1 = r1->x1;
+-	}
+-    }
+-    return 0;	/* lint */
+-}
+-
+-/*-
+- *-----------------------------------------------------------------------
+- * miSubtract --
+- *	Subtract regS from regM and leave the result in regD.
+- *	S stands for subtrahend, M for minuend and D for difference.
+- *
+- * Results:
+- *	TRUE.
+- *
+- * Side Effects:
+- *	regD is overwritten.
+- *
+- *-----------------------------------------------------------------------
+- */
+-
+-int
+-XSubtractRegion(
+-    Region 	  	regM,
+-    Region	  	regS,
+-    register Region	regD)
+-{
+-   /* check for trivial reject */
+-    if ( (!(regM->numRects)) || (!(regS->numRects))  ||
+-	(!EXTENTCHECK(&regM->extents, &regS->extents)) )
+-    {
+-	return miRegionCopy(regD, regM);
+-    }
+-
+-    miRegionOp (regD, regM, regS, miSubtractO,
+-    		miSubtractNonO1, NULL);
+-
+-    /*
+-     * Can't alter newReg's extents before we call miRegionOp because
+-     * it might be one of the source regions and miRegionOp depends
+-     * on the extents of those regions being the unaltered. Besides, this
+-     * way there's no checking against rectangles that will be nuked
+-     * due to coalescing, so we have to examine fewer rectangles.
+-     */
+-    miSetExtents (regD);
+-    return 1;
+-}
+-
+-int
+-XXorRegion(Region sra, Region srb, Region dr)
+-{
+-    Region tra, trb;
+-
+-    if (! (tra = XCreateRegion()) )
+-	return 0;
+-    if (! (trb = XCreateRegion()) ) {
+-	XDestroyRegion(tra);
+-	return 0;
+-    }
+-    (void) XSubtractRegion(sra,srb,tra);
+-    (void) XSubtractRegion(srb,sra,trb);
+-    (void) XUnionRegion(tra,trb,dr);
+-    XDestroyRegion(tra);
+-    XDestroyRegion(trb);
+-    return 0;
+-}
+-
+-/*
+- * Check to see if the region is empty.  Assumes a region is passed
+- * as a parameter
+- */
+-int
+-XEmptyRegion(
+-    Region r)
+-{
+-    if( r->numRects == 0 ) return TRUE;
+-    else  return FALSE;
+-}
+-
+-/*
+- *	Check to see if two regions are equal
+- */
+-int
+-XEqualRegion(Region r1, Region r2)
+-{
+-    int i;
+-
+-    if( r1->numRects != r2->numRects ) return FALSE;
+-    else if( r1->numRects == 0 ) return TRUE;
+-    else if ( r1->extents.x1 != r2->extents.x1 ) return FALSE;
+-    else if ( r1->extents.x2 != r2->extents.x2 ) return FALSE;
+-    else if ( r1->extents.y1 != r2->extents.y1 ) return FALSE;
+-    else if ( r1->extents.y2 != r2->extents.y2 ) return FALSE;
+-    else for( i=0; i < r1->numRects; i++ ) {
+-    	if ( r1->rects[i].x1 != r2->rects[i].x1 ) return FALSE;
+-    	else if ( r1->rects[i].x2 != r2->rects[i].x2 ) return FALSE;
+-    	else if ( r1->rects[i].y1 != r2->rects[i].y1 ) return FALSE;
+-    	else if ( r1->rects[i].y2 != r2->rects[i].y2 ) return FALSE;
+-    }
+-    return TRUE;
+-}
+-
+-int
+-XPointInRegion(
+-    Region pRegion,
+-    int x, int y)
+-{
+-    int i;
+-
+-    if (pRegion->numRects == 0)
+-        return FALSE;
+-    if (!INBOX(pRegion->extents, x, y))
+-        return FALSE;
+-    for (i=0; i<pRegion->numRects; i++)
+-    {
+-        if (INBOX (pRegion->rects[i], x, y))
+-	    return TRUE;
+-    }
+-    return FALSE;
+-}
+-
+-int
+-XRectInRegion(
+-    register Region	region,
+-    int rx, int ry,
+-    unsigned int rwidth, unsigned int rheight)
+-{
+-    register BoxPtr pbox;
+-    register BoxPtr pboxEnd;
+-    Box rect;
+-    register BoxPtr prect = &rect;
+-    int      partIn, partOut;
+-
+-    prect->x1 = rx;
+-    prect->y1 = ry;
+-    prect->x2 = rwidth + rx;
+-    prect->y2 = rheight + ry;
+-
+-    /* this is (just) a useful optimization */
+-    if ((region->numRects == 0) || !EXTENTCHECK(&region->extents, prect))
+-        return(RectangleOut);
+-
+-    partOut = FALSE;
+-    partIn = FALSE;
+-
+-    /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */
+-    for (pbox = region->rects, pboxEnd = pbox + region->numRects;
+-	 pbox < pboxEnd;
+-	 pbox++)
+-    {
+-
+-	if (pbox->y2 <= ry)
+-	   continue;	/* getting up to speed or skipping remainder of band */
+-
+-	if (pbox->y1 > ry)
+-	{
+-	   partOut = TRUE;	/* missed part of rectangle above */
+-	   if (partIn || (pbox->y1 >= prect->y2))
+-	      break;
+-	   ry = pbox->y1;	/* x guaranteed to be == prect->x1 */
+-	}
+-
+-	if (pbox->x2 <= rx)
+-	   continue;		/* not far enough over yet */
+-
+-	if (pbox->x1 > rx)
+-	{
+-	   partOut = TRUE;	/* missed part of rectangle to left */
+-	   if (partIn)
+-	      break;
+-	}
+-
+-	if (pbox->x1 < prect->x2)
+-	{
+-	    partIn = TRUE;	/* definitely overlap */
+-	    if (partOut)
+-	       break;
+-	}
+-
+-	if (pbox->x2 >= prect->x2)
+-	{
+-	   ry = pbox->y2;	/* finished with this band */
+-	   if (ry >= prect->y2)
+-	      break;
+-	   rx = prect->x1;	/* reset x out to left again */
+-	} else
+-	{
+-	    /*
+-	     * Because boxes in a band are maximal width, if the first box
+-	     * to overlap the rectangle doesn't completely cover it in that
+-	     * band, the rectangle must be partially out, since some of it
+-	     * will be uncovered in that band. partIn will have been set true
+-	     * by now...
+-	     */
+-	    break;
+-	}
+-
+-    }
+-
+-    return(partIn ? ((ry < prect->y2) ? RectanglePart : RectangleIn) :
+-		RectangleOut);
+-}
+diff --git a/common/Xregion/Xlib.h b/common/Xregion/Xlib.h
+deleted file mode 100644
+index ba6f281..0000000
+--- a/common/Xregion/Xlib.h
++++ /dev/null
+@@ -1,50 +0,0 @@
+-/*
+-
+-Copyright 1985, 1986, 1987, 1991, 1998  The Open Group
+-
+-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.
+-
+-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
+-OPEN GROUP 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.
+-
+-Except as contained in this notice, the name of The Open Group shall not be
+-used in advertising or otherwise to promote the sale, use or other dealings
+-in this Software without prior written authorization from The Open Group.
+-
+-*/
+-
+-
+-/*
+- *	Xlib.h - Header definition and support file for the C subroutine
+- *	interface library (Xlib) to the X Window System Protocol (V11).
+- *	Structures and symbols starting with "_" are private to the library.
+- */
+-#ifndef _X11_XLIB_H_
+-#define _X11_XLIB_H_
+-
+-#define NeedFunctionPrototypes 1
+-
+-#define Bool int
+-
+-typedef struct {
+-    short x, y;
+-} XPoint;
+-
+-typedef struct {
+-    short x, y;
+-    unsigned short width, height;
+-} XRectangle;
+-
+-
+-#endif /* _X11_XLIB_H_ */
+diff --git a/common/Xregion/Xlibint.h b/common/Xregion/Xlibint.h
+deleted file mode 100644
+index 9b9ae28..0000000
+--- a/common/Xregion/Xlibint.h
++++ /dev/null
+@@ -1,48 +0,0 @@
+-
+-/*
+-
+-Copyright 1984, 1985, 1987, 1989, 1998  The Open Group
+-
+-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.
+-
+-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 OPEN GROUP 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.
+-
+-Except as contained in this notice, the name of The Open Group shall
+-not be used in advertising or otherwise to promote the sale, use or
+-other dealings in this Software without prior written authorization
+-from The Open Group.
+-
+-*/
+-
+-#ifndef _X11_XLIBINT_H_
+-#define _X11_XLIBINT_H_ 1
+-
+-/*
+- *	Xlibint.h - Header definition and support file for the internal
+- *	support routines used by the C subroutine interface
+- *	library (Xlib) to the X Window System.
+- *
+- *	Warning, there be dragons here....
+- */
+-
+-#include <stdlib.h>
+-
+-#define Xfree(ptr) free((ptr))
+-#define Xmalloc(size) malloc((size))
+-#define Xrealloc(ptr, size) realloc((ptr), (size))
+-#define Xcalloc(nelem, elsize) calloc((nelem), (elsize))
+-
+-#endif /* _X11_XLIBINT_H_ */
+diff --git a/common/Xregion/Xregion.h b/common/Xregion/Xregion.h
+deleted file mode 100644
+index cf10f86..0000000
+--- a/common/Xregion/Xregion.h
++++ /dev/null
+@@ -1,190 +0,0 @@
+-/************************************************************************
+-
+-Copyright 1987, 1998  The Open Group
+-
+-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.
+-
+-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
+-OPEN GROUP 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.
+-
+-Except as contained in this notice, the name of The Open Group shall not be
+-used in advertising or otherwise to promote the sale, use or other dealings
+-in this Software without prior written authorization from The Open Group.
+-
+-
+-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+-
+-                        All Rights Reserved
+-
+-Permission to use, copy, modify, and distribute this software and its
+-documentation for any purpose and without fee is hereby granted,
+-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 Digital not be
+-used in advertising or publicity pertaining to distribution of the
+-software without specific, written prior permission.
+-
+-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+-DIGITAL 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.
+-
+-************************************************************************/
+-
+-#ifndef _X11_XREGION_H_
+-#define _X11_XREGION_H_
+-
+-typedef struct {
+-    short x1, x2, y1, y2;
+-} Box, BOX, BoxRec, *BoxPtr;
+-
+-typedef struct {
+-    short x, y, width, height;
+-}RECTANGLE, RectangleRec, *RectanglePtr;
+-
+-#define TRUE 1
+-#define FALSE 0
+-#define MAXSHORT 32767
+-#define MINSHORT -MAXSHORT
+-#ifndef MAX
+-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+-#endif
+-#ifndef MIN
+-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+-#endif
+-
+-
+-/*
+- *   clip region
+- */
+-
+-typedef struct _XRegion {
+-    long size;
+-    long numRects;
+-    BOX *rects;
+-    BOX extents;
+-} REGION;
+-
+-/* Xutil.h contains the declaration:
+- * typedef struct _XRegion *Region;
+- */
+-
+-/*  1 if two BOXs overlap.
+- *  0 if two BOXs do not overlap.
+- *  Remember, x2 and y2 are not in the region
+- */
+-#define EXTENTCHECK(r1, r2) \
+-	((r1)->x2 > (r2)->x1 && \
+-	 (r1)->x1 < (r2)->x2 && \
+-	 (r1)->y2 > (r2)->y1 && \
+-	 (r1)->y1 < (r2)->y2)
+-
+-/*
+- *  update region extents
+- */
+-#define EXTENTS(r,idRect){\
+-            if((r)->x1 < (idRect)->extents.x1)\
+-              (idRect)->extents.x1 = (r)->x1;\
+-            if((r)->y1 < (idRect)->extents.y1)\
+-              (idRect)->extents.y1 = (r)->y1;\
+-            if((r)->x2 > (idRect)->extents.x2)\
+-              (idRect)->extents.x2 = (r)->x2;\
+-            if((r)->y2 > (idRect)->extents.y2)\
+-              (idRect)->extents.y2 = (r)->y2;\
+-        }
+-
+-/*
+- *   Check to see if there is enough memory in the present region.
+- */
+-#define MEMCHECK(reg, rect, firstrect){\
+-        if ((reg)->numRects >= ((reg)->size - 1)){\
+-          BoxPtr tmpRect = Xrealloc ((firstrect), \
+-                                     (2 * (sizeof(BOX)) * ((reg)->size))); \
+-          if (tmpRect == NULL) \
+-            return(0);\
+-          (firstrect) = tmpRect; \
+-          (reg)->size *= 2;\
+-          (rect) = &(firstrect)[(reg)->numRects];\
+-         }\
+-       }
+-
+-/*  this routine checks to see if the previous rectangle is the same
+- *  or subsumes the new rectangle to add.
+- */
+-
+-#define CHECK_PREVIOUS(Reg, R, Rx1, Ry1, Rx2, Ry2)\
+-               (!(((Reg)->numRects > 0)&&\
+-                  ((R-1)->y1 == (Ry1)) &&\
+-                  ((R-1)->y2 == (Ry2)) &&\
+-                  ((R-1)->x1 <= (Rx1)) &&\
+-                  ((R-1)->x2 >= (Rx2))))
+-
+-/*  add a rectangle to the given Region */
+-#define ADDRECT(reg, r, rx1, ry1, rx2, ry2){\
+-    if (((rx1) < (rx2)) && ((ry1) < (ry2)) &&\
+-        CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\
+-              (r)->x1 = (rx1);\
+-              (r)->y1 = (ry1);\
+-              (r)->x2 = (rx2);\
+-              (r)->y2 = (ry2);\
+-              EXTENTS((r), (reg));\
+-              (reg)->numRects++;\
+-              (r)++;\
+-            }\
+-        }
+-
+-
+-
+-/*  add a rectangle to the given Region */
+-#define ADDRECTNOX(reg, r, rx1, ry1, rx2, ry2){\
+-            if ((rx1 < rx2) && (ry1 < ry2) &&\
+-                CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\
+-              (r)->x1 = (rx1);\
+-              (r)->y1 = (ry1);\
+-              (r)->x2 = (rx2);\
+-              (r)->y2 = (ry2);\
+-              (reg)->numRects++;\
+-              (r)++;\
+-            }\
+-        }
+-
+-#define EMPTY_REGION(pReg) pReg->numRects = 0
+-
+-#define REGION_NOT_EMPTY(pReg) pReg->numRects
+-
+-#define INBOX(r, x, y) \
+-      ( ( ((r).x2 >  x)) && \
+-        ( ((r).x1 <= x)) && \
+-        ( ((r).y2 >  y)) && \
+-        ( ((r).y1 <= y)) )
+-
+-/*
+- * number of points to buffer before sending them off
+- * to scanlines() :  Must be an even number
+- */
+-#define NUMPTSTOBUFFER 200
+-
+-/*
+- * used to allocate buffers for points and link
+- * the buffers together
+- */
+-typedef struct _POINTBLOCK {
+-    XPoint pts[NUMPTSTOBUFFER];
+-    struct _POINTBLOCK *next;
+-} POINTBLOCK;
+-
+-#endif /* _X11_XREGION_H_ */
+diff --git a/common/Xregion/Xutil.h b/common/Xregion/Xutil.h
+deleted file mode 100644
+index 4da56a5..0000000
+--- a/common/Xregion/Xutil.h
++++ /dev/null
+@@ -1,167 +0,0 @@
+-
+-/***********************************************************
+-
+-Copyright 1987, 1998  The Open Group
+-
+-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.
+-
+-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
+-OPEN GROUP 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.
+-
+-Except as contained in this notice, the name of The Open Group shall not be
+-used in advertising or otherwise to promote the sale, use or other dealings
+-in this Software without prior written authorization from The Open Group.
+-
+-
+-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+-
+-                        All Rights Reserved
+-
+-Permission to use, copy, modify, and distribute this software and its
+-documentation for any purpose and without fee is hereby granted,
+-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 Digital not be
+-used in advertising or publicity pertaining to distribution of the
+-software without specific, written prior permission.
+-
+-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+-DIGITAL 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.
+-
+-******************************************************************/
+-
+-#ifndef _X11_XUTIL_H_
+-#define _X11_XUTIL_H_
+-
+-/* You must include <X11/Xlib.h> before including this file */
+-#include "Xlib.h"
+-
+-/****** Avoid symbol clash with "real" libX11 ******/
+-#define XClipBox vncXClipBox
+-#define XCreateRegion vncXCreateRegion
+-#define XDestroyRegion vncXDestroyRegion
+-#define XEmptyRegion vncXEmptyRegion
+-#define XEqualRegion vncXEqualRegion
+-#define XIntersectRegion vncXIntersectRegion
+-#define XOffsetRegion vncXOffsetRegion
+-#define XPointInRegion vncXPointInRegion
+-#define XPolygonRegion vncXPolygonRegion
+-#define XRectInRegion vncXRectInRegion
+-#define XShrinkRegion vncXShrinkRegion
+-#define XSubtractRegion vncXSubtractRegion
+-#define XUnionRectWithRegion vncXUnionRectWithRegion
+-#define XUnionRegion vncXUnionRegion
+-#define XXorRegion vncXXorRegion
+-
+-/*
+- * opaque reference to Region data type
+- */
+-typedef struct _XRegion *Region;
+-
+-/* Return values from XRectInRegion() */
+-
+-#define RectangleOut 0
+-#define RectangleIn  1
+-#define RectanglePart 2
+-
+-extern int XClipBox(
+-    Region		/* r */,
+-    XRectangle*		/* rect_return */
+-);
+-
+-extern Region XCreateRegion(
+-    void
+-);
+-
+-extern int XDestroyRegion(
+-    Region		/* r */
+-);
+-
+-extern int XEmptyRegion(
+-    Region		/* r */
+-);
+-
+-extern int XEqualRegion(
+-    Region		/* r1 */,
+-    Region		/* r2 */
+-);
+-
+-extern int XIntersectRegion(
+-    Region		/* sra */,
+-    Region		/* srb */,
+-    Region		/* dr_return */
+-);
+-
+-extern int XOffsetRegion(
+-    Region		/* r */,
+-    int			/* dx */,
+-    int			/* dy */
+-);
+-
+-extern Bool XPointInRegion(
+-    Region		/* r */,
+-    int			/* x */,
+-    int			/* y */
+-);
+-
+-extern Region XPolygonRegion(
+-    XPoint*		/* points */,
+-    int			/* n */,
+-    int			/* fill_rule */
+-);
+-
+-extern int XRectInRegion(
+-    Region		/* r */,
+-    int			/* x */,
+-    int			/* y */,
+-    unsigned int	/* width */,
+-    unsigned int	/* height */
+-);
+-
+-extern int XShrinkRegion(
+-    Region		/* r */,
+-    int			/* dx */,
+-    int			/* dy */
+-);
+-
+-extern int XSubtractRegion(
+-    Region		/* sra */,
+-    Region		/* srb */,
+-    Region		/* dr_return */
+-);
+-
+-extern int XUnionRectWithRegion(
+-    XRectangle*		/* rectangle */,
+-    Region		/* src_region */,
+-    Region		/* dest_region_return */
+-);
+-
+-extern int XUnionRegion(
+-    Region		/* sra */,
+-    Region		/* srb */,
+-    Region		/* dr_return */
+-);
+-
+-extern int XXorRegion(
+-    Region		/* sra */,
+-    Region		/* srb */,
+-    Region		/* dr_return */
+-);
+-
+-#endif /* _X11_XUTIL_H_ */
+diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt
+index 5047e5e..ecfcb03 100644
+--- a/common/rfb/CMakeLists.txt
++++ b/common/rfb/CMakeLists.txt
+@@ -1,4 +1,4 @@
+-include_directories(${CMAKE_SOURCE_DIR}/common ${JPEG_INCLUDE_DIR})
++include_directories(${CMAKE_SOURCE_DIR}/common ${JPEG_INCLUDE_DIR} ${PIXMAN_INCLUDE_DIR})
+ 
+ set(RFB_SOURCES
+   Blacklist.cxx
+@@ -72,7 +72,7 @@ if(WIN32)
+   set(RFB_SOURCES ${RFB_SOURCES} WinPasswdValidator.cxx)
+ endif(WIN32)
+ 
+-set(RFB_LIBRARIES ${JPEG_LIBRARIES} os rdr Xregion)
++set(RFB_LIBRARIES ${JPEG_LIBRARIES} ${PIXMAN_LIBRARY} os rdr)
+ 
+ if(HAVE_PAM)
+   set(RFB_SOURCES ${RFB_SOURCES} UnixPasswordValidator.cxx
+diff --git a/common/rfb/ComparingUpdateTracker.cxx b/common/rfb/ComparingUpdateTracker.cxx
+index 237adc4..d565120 100644
+--- a/common/rfb/ComparingUpdateTracker.cxx
++++ b/common/rfb/ComparingUpdateTracker.cxx
+@@ -120,8 +120,6 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
+   rdr::U8* oldData = oldFb.getBufferRW(r, &oldStride);
+   int oldStrideBytes = oldStride * bytesPerPixel;
+ 
+-  std::vector<Rect> changedBlocks;
+-
+   for (int blockTop = r.tl.y; blockTop < r.br.y; blockTop += BLOCK_SIZE)
+   {
+     // Get a strip of the source buffer
+@@ -146,8 +144,8 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
+         if (memcmp(oldPtr, newPtr, blockWidthInBytes) != 0)
+         {
+           // A block has changed - copy the remainder to the oldFb
+-          changedBlocks.push_back(Rect(blockLeft, blockTop,
+-                                       blockRight, blockBottom));
++          newChanged->assign_union(Region(Rect(blockLeft, blockTop,
++                                               blockRight, blockBottom)));
+           for (int y2 = y; y2 < blockBottom; y2++)
+           {
+             memcpy(oldPtr, newPtr, blockWidthInBytes);
+@@ -169,12 +167,6 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
+   }
+ 
+   oldFb.commitBufferRW(r);
+-
+-  if (!changedBlocks.empty()) {
+-    Region temp;
+-    temp.setOrderedRects(changedBlocks);
+-    newChanged->assign_union(temp);
+-  }
+ }
+ 
+ void ComparingUpdateTracker::logStats()
+diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx
+index 0cd5206..6a153a8 100644
+--- a/common/rfb/EncodeManager.cxx
++++ b/common/rfb/EncodeManager.cxx
+@@ -273,7 +273,7 @@ void EncodeManager::writeUpdate(const UpdateInfo& ui, const PixelBuffer* pb,
+      * We start by searching for solid rects, which are then removed
+      * from the changed region.
+      */
+-    changed.copyFrom(ui.changed);
++    changed = ui.changed;
+ 
+     if (conn->cp.supportsLastRect)
+       writeSolidRects(&changed, pb);
+diff --git a/common/rfb/Region.cxx b/common/rfb/Region.cxx
+index 995f8c5..2b5d0cf 100644
+--- a/common/rfb/Region.cxx
++++ b/common/rfb/Region.cxx
+@@ -1,4 +1,5 @@
+ /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
++ * Copyright 2016-2020 Pierre Ossman for Cendio AB
+  * 
+  * This is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -16,190 +17,110 @@
+  * USA.
+  */
+ 
+-// Cross-platform Region class based on the X11 region implementation.  Note
+-// that for efficiency this code manipulates the Xlib region structure
+-// directly.  Apart from the layout of the structure, there is one other key
+-// assumption made: a Region returned from XCreateRegion must always have its
+-// rects member allocated so that there is space for at least one rectangle.
+-//
+-
+ #include <rfb/Region.h>
+-#include <assert.h>
+-#include <stdio.h>
+ 
+ extern "C" {
+-#include <Xregion/Xlibint.h>
+-#include <Xregion/Xutil.h>
+-#include <Xregion/Xregion.h>
+-}
+-
+-// A _RectRegion must never be passed as a return parameter to the Xlib region
+-// operations.  This is because for efficiency its "rects" member has not been
+-// allocated with Xmalloc.  It is however safe to pass it as an input
+-// parameter.
+-
+-class _RectRegion {
+-public:
+-  _RectRegion(const rfb::Rect& r) {
+-    region.rects = &region.extents;
+-    region.numRects = 1;
+-    region.extents.x1 = r.tl.x;
+-    region.extents.y1 = r.tl.y;
+-    region.extents.x2 = r.br.x;
+-    region.extents.y2 = r.br.y;
+-    region.size = 1;
+-    if (r.is_empty())
+-      region.numRects = 0;
+-  }
+-  REGION region;
+-};
+-
++#include <pixman.h>
++#include <stdio.h>
++}
+ 
+ rfb::Region::Region() {
+-  xrgn = XCreateRegion();
+-  assert(xrgn);
++  rgn = new struct pixman_region16;
++  pixman_region_init(rgn);
+ }
+ 
+ rfb::Region::Region(const Rect& r) {
+-  xrgn = XCreateRegion();
+-  assert(xrgn);
+-  reset(r);
++  rgn = new struct pixman_region16;
++  pixman_region_init_rect(rgn, r.tl.x, r.tl.y, r.width(), r.height());
+ }
+ 
+ rfb::Region::Region(const rfb::Region& r) {
+-  xrgn = XCreateRegion();
+-  assert(xrgn);
+-  XUnionRegion(xrgn, r.xrgn, xrgn);
++  rgn = new struct pixman_region16;
++  pixman_region_init(rgn);
++  pixman_region_copy(rgn, r.rgn);
+ }
+ 
+ rfb::Region::~Region() {
+-  XDestroyRegion(xrgn);
++  pixman_region_fini(rgn);
++  delete rgn;
+ }
+ 
+ rfb::Region& rfb::Region::operator=(const rfb::Region& r) {
+-  clear();
+-  XUnionRegion(xrgn, r.xrgn, xrgn);
++  pixman_region_copy(rgn, r.rgn);
+   return *this;
+ }
+ 
+ void rfb::Region::clear() {
+-  xrgn->numRects = 0;
+-  xrgn->extents.x1 = 0;
+-  xrgn->extents.y1 = 0;
+-  xrgn->extents.x2 = 0;
+-  xrgn->extents.y2 = 0;
++  // pixman_region_clear() isn't available on some older systems
++  pixman_region_fini(rgn);
++  pixman_region_init(rgn);
+ }
+ 
+ void rfb::Region::reset(const Rect& r) {
+-  if (r.is_empty()) {
+-    clear();
+-  } else {
+-    xrgn->numRects = 1;
+-    xrgn->rects[0].x1 = xrgn->extents.x1 = r.tl.x;
+-    xrgn->rects[0].y1 = xrgn->extents.y1 = r.tl.y;
+-    xrgn->rects[0].x2 = xrgn->extents.x2 = r.br.x;
+-    xrgn->rects[0].y2 = xrgn->extents.y2 = r.br.y;
+-  }
++  pixman_region_fini(rgn);
++  pixman_region_init_rect(rgn, r.tl.x, r.tl.y, r.width(), r.height());
+ }
+ 
+ void rfb::Region::translate(const Point& delta) {
+-  XOffsetRegion(xrgn, delta.x, delta.y);
+-}
+-
+-void rfb::Region::setOrderedRects(const std::vector<Rect>& rects) {
+-  clear();
+-  std::vector<Rect>::const_iterator i;
+-  for (i=rects.begin(); i != rects.end(); i++) {
+-    _RectRegion rr(*i);
+-    XUnionRegion(xrgn, &rr.region, xrgn);
+-  }
+-}
+-
+-void rfb::Region::setExtentsAndOrderedRects(const ShortRect* extents,
+-                                            int nRects, const ShortRect* rects)
+-{
+-  if (xrgn->size < nRects)
+-  {
+-    BOX* prevRects = xrgn->rects;
+-    xrgn->rects = (BOX*)Xrealloc((char*)xrgn->rects, nRects * sizeof(BOX));
+-    if (!xrgn->rects) {
+-      fprintf(stderr,"Xrealloc failed\n");
+-      Xfree(prevRects);
+-      return;
+-    }
+-    xrgn->size = nRects;
+-  }
+-
+-  xrgn->numRects = nRects;
+-  xrgn->extents.x1 = extents->x1;
+-  xrgn->extents.y1 = extents->y1;
+-  xrgn->extents.x2 = extents->x2;
+-  xrgn->extents.y2 = extents->y2;
+-  for (int i = 0; i < nRects; i++) {
+-    xrgn->rects[i].x1 = rects[i].x1;
+-    xrgn->rects[i].y1 = rects[i].y1;
+-    xrgn->rects[i].x2 = rects[i].x2;
+-    xrgn->rects[i].y2 = rects[i].y2;
+-  }
+-}
+-
+-void rfb::Region::copyFrom(const rfb::Region& r) {
+-  XUnionRegion(r.xrgn, r.xrgn, xrgn);
++  pixman_region_translate(rgn, delta.x, delta.y);
+ }
+ 
+ void rfb::Region::assign_intersect(const rfb::Region& r) {
+-  XIntersectRegion(xrgn, r.xrgn, xrgn);
++  pixman_region_intersect(rgn, rgn, r.rgn);
+ }
+ 
+ void rfb::Region::assign_union(const rfb::Region& r) {
+-  XUnionRegion(xrgn, r.xrgn, xrgn);
++  pixman_region_union(rgn, rgn, r.rgn);
+ }
+ 
+ void rfb::Region::assign_subtract(const rfb::Region& r) {
+-  XSubtractRegion(xrgn, r.xrgn, xrgn);
+++  pixman_region_subtract(rgn, rgn, r.rgn);
+ }
+ 
+ rfb::Region rfb::Region::intersect(const rfb::Region& r) const {
+   rfb::Region ret;
+-  XIntersectRegion(xrgn, r.xrgn, ret.xrgn);
++  pixman_region_intersect(ret.rgn, rgn, r.rgn);
+   return ret;
+ }
+ 
+ rfb::Region rfb::Region::union_(const rfb::Region& r) const {
+   rfb::Region ret;
+-  XUnionRegion(xrgn, r.xrgn, ret.xrgn);
++  pixman_region_union(ret.rgn, rgn, r.rgn);
+   return ret;
+ }
+ 
+ rfb::Region rfb::Region::subtract(const rfb::Region& r) const {
+   rfb::Region ret;
+-  XSubtractRegion(xrgn, r.xrgn, ret.xrgn);
++  pixman_region_subtract(ret.rgn, rgn, r.rgn);
+   return ret;
+ }
+ 
+ bool rfb::Region::equals(const rfb::Region& r) const {
+-  return XEqualRegion(xrgn, r.xrgn);
++  return pixman_region_equal(rgn, r.rgn);
+ }
+ 
+ int rfb::Region::numRects() const {
+-  return xrgn->numRects;
++  return pixman_region_n_rects(rgn);
+ }
+ 
+ bool rfb::Region::get_rects(std::vector<Rect>* rects,
+                             bool left2right, bool topdown, int maxArea) const
+ {
+-  int nRects = xrgn->numRects;
+-  int xInc = left2right ? 1 : -1;
+-  int yInc = topdown ? 1 : -1;
+-  int i = topdown ? 0 : nRects-1;
+-  rects->clear();
+-  rects->reserve(nRects);
++  int nRects;
++  const pixman_box16_t* boxes;
++  int xInc, yInc, i;
++
++  boxes = pixman_region_rectangles(rgn, &nRects);
++
++  xInc = left2right ? 1 : -1;
++  yInc = topdown ? 1 : -1;
++  i = topdown ? 0 : nRects-1;
+ 
+   while (nRects > 0) {
+     int firstInNextBand = i;
+     int nRectsInBand = 0;
+ 
+-    while (nRects > 0 && xrgn->rects[firstInNextBand].y1 == xrgn->rects[i].y1)
++    while (nRects > 0 && boxes[firstInNextBand].y1 == boxes[i].y1)
+     {
+       firstInNextBand += yInc;
+       nRects--;
+@@ -210,18 +131,10 @@ bool rfb::Region::get_rects(std::vector<Rect>* rects,
+       i = firstInNextBand - yInc;
+ 
+     while (nRectsInBand > 0) {
+-      int y = xrgn->rects[i].y1;
+-      int h = maxArea / (xrgn->rects[i].x2 - xrgn->rects[i].x1);
+-      if (!h) h = xrgn->rects[i].y2 - y;
+-      do {
+-        if (h > xrgn->rects[i].y2 - y)
+-          h = xrgn->rects[i].y2 - y;
+-        Rect r(xrgn->rects[i].x1, y, xrgn->rects[i].x2, y+h);
+-        rects->push_back(r);
+-        y += h;
+-      } while (y < xrgn->rects[i].y2);
+-      i += xInc;
+-      nRectsInBand--;
++       Rect r(boxes[i].x1, boxes[i].y1, boxes[i].x2, boxes[i].y2);
++       rects->push_back(r);
++       i += xInc;
++       nRectsInBand--;
+     }
+ 
+     i = firstInNextBand;
+@@ -231,22 +144,28 @@ bool rfb::Region::get_rects(std::vector<Rect>* rects,
+ }
+ 
+ rfb::Rect rfb::Region::get_bounding_rect() const {
+-  return Rect(xrgn->extents.x1, xrgn->extents.y1,
+-              xrgn->extents.x2, xrgn->extents.y2);
++  const pixman_box16_t* extents;
++  extents = pixman_region_extents(rgn);
++  return Rect(extents->x1, extents->y1, extents->x2, extents->y2);
+ }
+ 
+ 
+ void rfb::Region::debug_print(const char* prefix) const
+ {
++  Rect extents;
++  std::vector<Rect> rects;
++  std::vector<Rect>::const_iterator iter;
++
++  extents = get_bounding_rect();
++  get_rects(&rects);
++
+   fprintf(stderr,"%s num rects %3ld extents %3d,%3d %3dx%3d\n",
+-          prefix, xrgn->numRects, xrgn->extents.x1, xrgn->extents.y1,
+-          xrgn->extents.x2-xrgn->extents.x1,
+-          xrgn->extents.y2-xrgn->extents.y1);
++          prefix, (long)rects.size(), extents.tl.x, extents.tl.y,
++          extents.width(), extents.height());
+ 
+-  for (int i = 0; i < xrgn->numRects; i++) {
++  for (iter = rects.begin(); iter != rects.end(); ++iter) {
+     fprintf(stderr,"    rect %3d,%3d %3dx%3d\n",
+-            xrgn->rects[i].x1, xrgn->rects[i].y1,
+-            xrgn->rects[i].x2-xrgn->rects[i].x1,
+-            xrgn->rects[i].y2-xrgn->rects[i].y1);
++            iter->tl.x, iter->tl.y, iter->width(), iter->height());
++
+   }
+ }
+diff --git a/common/rfb/Region.h b/common/rfb/Region.h
+index 9337556..c12beed 100644
+--- a/common/rfb/Region.h
++++ b/common/rfb/Region.h
+@@ -1,4 +1,5 @@
+ /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
++ * Copyright 2016-2020 Pierre Ossman for Cendio AB
+  * 
+  * This is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -16,7 +17,7 @@
+  * USA.
+  */
+ 
+-// Cross-platform Region class based on the X11 region implementation
++// Region class wrapper around pixman's region operations
+ 
+ #ifndef __RFB_REGION_INCLUDED__
+ #define __RFB_REGION_INCLUDED__
+@@ -24,14 +25,10 @@
+ #include <rfb/Rect.h>
+ #include <vector>
+ 
+-struct _XRegion;
++struct pixman_region16;
+ 
+ namespace rfb {
+ 
+-  struct ShortRect {
+-    short x1, y1, x2, y2;
+-  };
+-
+   class Region {
+   public:
+     // Create an empty region
+@@ -49,10 +46,6 @@ namespace rfb {
+     void clear();
+     void reset(const Rect& r);
+     void translate(const rfb::Point& delta);
+-    void setOrderedRects(const std::vector<Rect>& rects);
+-    void setExtentsAndOrderedRects(const ShortRect* extents, int nRects,
+-                                   const ShortRect* rects);
+-    void copyFrom(const Region& r);
+ 
+     void assign_intersect(const Region& r);
+     void assign_union(const Region& r);
+@@ -76,7 +69,7 @@ namespace rfb {
+ 
+   protected:
+ 
+-    struct _XRegion* xrgn;
++    struct pixman_region16* rgn;
+   };
+ 
+ };
+diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
+index d2206f9..d1c7709 100644
+--- a/common/rfb/VNCSConnectionST.cxx
++++ b/common/rfb/VNCSConnectionST.cxx
+@@ -1028,7 +1028,7 @@ void VNCSConnectionST::writeDataUpdate()
+   if (!ui.copied.is_empty() && !damagedCursorRegion.is_empty()) {
+     Region bogusCopiedCursor;
+ 
+-    bogusCopiedCursor.copyFrom(damagedCursorRegion);
++    bogusCopiedCursor = damagedCursorRegion;
+     bogusCopiedCursor.translate(ui.copy_delta);
+     bogusCopiedCursor.assign_intersect(server->pb->getRect());
+     if (!ui.copied.intersect(bogusCopiedCursor).is_empty()) {
+diff --git a/unix/xserver/hw/vnc/Makefile.am b/unix/xserver/hw/vnc/Makefile.am
+index 0d6a4ac..9a26e45 100644
+--- a/unix/xserver/hw/vnc/Makefile.am
++++ b/unix/xserver/hw/vnc/Makefile.am
+@@ -5,8 +5,7 @@ RFB_LIB=$(LIB_DIR)/rfb/librfb.la
+ RDR_LIB=$(LIB_DIR)/rdr/librdr.la
+ OS_LIB=$(LIB_DIR)/os/libos.la
+ NETWORK_LIB=$(LIB_DIR)/network/libnetwork.la
+-XREGION_LIB=$(LIB_DIR)/Xregion/libXregion.la
+-COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(XREGION_LIB) $(OS_LIB)
++COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(OS_LIB)
+ 
+ noinst_LTLIBRARIES = libvnccommon.la
+ 
+diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc
+index 57bf6d8..b369ec3 100644
+--- a/unix/xserver/hw/vnc/vncExtInit.cc
++++ b/unix/xserver/hw/vnc/vncExtInit.cc
+@@ -149,11 +149,6 @@ void vncExtensionInit(void)
+     return;
+   }
+ 
+-  if (sizeof(ShortRect) != sizeof(struct UpdateRect)) {
+-    vlog.error("vncExtensionInit: Incompatible ShortRect size");
+-    return;
+-  }
+-
+   ret = vncAddExtension();
+   if (ret == -1)
+     return;
+@@ -358,25 +353,24 @@ void vncBell()
+   }
+ }
+ 
+-void vncAddChanged(int scrIdx, const struct UpdateRect *extents,
+-                   int nRects, const struct UpdateRect *rects)
++void vncAddChanged(int scrIdx, int nRects,
++                   const struct UpdateRect *rects)
+ {
+-  Region reg;
+-
+-  reg.setExtentsAndOrderedRects((const ShortRect*)extents,
+-                                nRects, (const ShortRect*)rects);
+-  desktop[scrIdx]->add_changed(reg);
++  for (int i = 0;i < nRects;i++) {
++    desktop[scrIdx]->add_changed(Region(Rect(rects[i].x1, rects[i].y1,
++                                             rects[i].x2, rects[i].y2)));
++  }
+ }
+ 
+-void vncAddCopied(int scrIdx, const struct UpdateRect *extents,
+-                  int nRects, const struct UpdateRect *rects,
++void vncAddCopied(int scrIdx, int nRects,
++                  const struct UpdateRect *rects,
+                   int dx, int dy)
+ {
+-  Region reg;
+-
+-  reg.setExtentsAndOrderedRects((const ShortRect*)extents,
+-                                nRects, (const ShortRect*)rects);
+-  desktop[scrIdx]->add_copied(reg, rfb::Point(dx, dy));
++  for (int i = 0;i < nRects;i++) {
++    desktop[scrIdx]->add_copied(Region(Rect(rects[i].x1, rects[i].y1,
++                                            rects[i].x2, rects[i].y2)),
++                                Point(dx, dy));
++  }
+ }
+ 
+ void vncSetCursor(int width, int height, int hotX, int hotY,
+diff --git a/unix/xserver/hw/vnc/vncExtInit.h b/unix/xserver/hw/vnc/vncExtInit.h
+index 9f8d9e7..0d7d691 100644
+--- a/unix/xserver/hw/vnc/vncExtInit.h
++++ b/unix/xserver/hw/vnc/vncExtInit.h
+@@ -76,10 +76,10 @@ struct UpdateRect {
+   short x1, y1, x2, y2;
+ };
+ 
+-void vncAddChanged(int scrIdx, const struct UpdateRect *extents,
+-                   int nRects, const struct UpdateRect *rects);
+-void vncAddCopied(int scrIdx, const struct UpdateRect *extents,
+-                  int nRects, const struct UpdateRect *rects,
++void vncAddChanged(int scrIdx, int nRects,
++                   const struct UpdateRect *rects);
++void vncAddCopied(int scrIdx, int nRects,
++                  const struct UpdateRect *rects,
+                   int dx, int dy);
+ 
+ void vncSetCursor(int width, int height, int hotX, int hotY,
+diff --git a/unix/xserver/hw/vnc/vncHooks.c b/unix/xserver/hw/vnc/vncHooks.c
+index 5b90f53..498ee3d 100644
+--- a/unix/xserver/hw/vnc/vncHooks.c
++++ b/unix/xserver/hw/vnc/vncHooks.c
+@@ -369,9 +369,8 @@ static inline void add_changed(ScreenPtr pScreen, RegionPtr reg)
+   if (vncHooksScreen->ignoreHooks)
+     return;
+   vncAddChanged(pScreen->myNum,
+-                (const struct UpdateRect*)REGION_EXTENTS(pScreen, reg),
+-                REGION_NUM_RECTS(reg),
+-                (const struct UpdateRect*)REGION_RECTS(reg));
++                RegionNumRects(reg),
++                (const struct UpdateRect*)RegionRects(reg));
+ }
+ 
+ static inline void add_copied(ScreenPtr pScreen, RegionPtr dst,
+@@ -381,9 +380,8 @@ static inline void add_copied(ScreenPtr pScreen, RegionPtr dst,
+   if (vncHooksScreen->ignoreHooks)
+     return;
+   vncAddCopied(pScreen->myNum,
+-               (const struct UpdateRect*)REGION_EXTENTS(pScreen, dst),
+-               REGION_NUM_RECTS(dst),
+-               (const struct UpdateRect*)REGION_RECTS(dst), dx, dy);
++               RegionNumRects(dst),
++               (const struct UpdateRect*)RegionRects(dst), dx, dy);
+ }
+ 
+ static inline Bool is_visible(DrawablePtr drawable)
+@@ -515,15 +513,15 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+ 
+   SCREEN_PROLOGUE(pWin->drawable.pScreen, CopyWindow);
+ 
+-  REGION_NULL(pScreen, &copied);
+-  REGION_COPY(pScreen, &copied, pOldRegion);
++  RegionNull(&copied);
++  RegionCopy(&copied, pOldRegion);
+ 
+   screen_box.x1 = 0;
+   screen_box.y1 = 0;
+   screen_box.x2 = pScreen->width;
+   screen_box.y2 = pScreen->height;
+ 
+-  REGION_INIT(pScreen, &screen_rgn, &screen_box, 1);
++  RegionInitBoxes(&screen_rgn, &screen_box, 1);
+ 
+   dx = pWin->drawable.x - ptOldOrg.x;
+   dy = pWin->drawable.y - ptOldOrg.y;
+@@ -532,18 +530,18 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+   // We also need to copy with changes to the Window's clipping region.
+   // Finally, make sure we don't get copies to or from regions outside
+   // the framebuffer.
+-  REGION_INTERSECT(pScreen, &copied, &copied, &screen_rgn);
+-  REGION_TRANSLATE(pScreen, &copied, dx, dy);
+-  REGION_INTERSECT(pScreen, &copied, &copied, &screen_rgn);
+-  REGION_INTERSECT(pScreen, &copied, &copied, &pWin->borderClip);
++  RegionIntersect(&copied, &copied, &screen_rgn);
++  RegionTranslate(&copied, dx, dy);
++  RegionIntersect(&copied, &copied, &screen_rgn);
++  RegionIntersect(&copied, &copied, &pWin->borderClip);
+ 
+   (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion);
+ 
+   if (REGION_NOTEMPTY(pScreen, &copied))
+     add_copied(pScreen, &copied, dx, dy);
+ 
+-  REGION_UNINIT(pScreen, &copied);
+-  REGION_UNINIT(pScreen, &screen_rgn);
++  RegionUninit(&copied);
++  RegionUninit(&screen_rgn);
+ 
+   SCREEN_EPILOGUE(CopyWindow);
+ }
+@@ -564,8 +562,8 @@ static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
+   box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width);
+   box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height);
+ 
+-  REGION_INIT(pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, &pWin->clipList);
+ 
+   (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
+ 
+@@ -573,7 +571,7 @@ static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
+     add_changed(pScreen, &reg);
+   }
+ 
+-  REGION_UNINIT(pScreen, &reg);
++  RegionUninit(&reg);
+ 
+   SCREEN_EPILOGUE(ClearToBackground);
+ }
+@@ -765,19 +763,19 @@ static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+     box.y1 = max(pDst->pDrawable->y + yDst, 0);
+     box.x2 = box.x1 + width;
+     box.y2 = box.y1 + height;
+-    REGION_INIT(pScreen, &changed, &box, 0);
++    RegionInitBoxes(&changed, &box, 1);
+ 
+     box.x1 = 0;
+     box.y1 = 0;
+     box.x2 = pScreen->width;
+     box.y2 = pScreen->height;
+-    REGION_INIT(pScreen, &fbreg, &box, 0);
++    RegionInitBoxes(&fbreg, &box, 1);
+ 
+-    REGION_INTERSECT(pScreen, &changed, &changed, &fbreg);
++    RegionIntersect(&changed, &changed, &fbreg);
+ 
+-    REGION_UNINIT(pScreen, &fbreg);
++    RegionUninit(&fbreg);
+   } else {
+-    REGION_NULL(pScreen, &changed);
++    RegionNull(&changed);
+   }
+ 
+ 
+@@ -787,7 +785,7 @@ static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+   if (REGION_NOTEMPTY(pScreen, &changed))
+     add_changed(pScreen, &changed);
+ 
+-  REGION_UNINIT(pScreen, &changed);
++  RegionUninit(&changed);
+ 
+   RENDER_EPILOGUE(Composite);
+ }
+@@ -855,20 +853,20 @@ static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+     RegionRec fbreg;
+ 
+     changed = GlyphsToRegion(pScreen, nlists, lists, glyphs);
+-    REGION_TRANSLATE(pScreen, changed,
++    RegionTranslate(changed,
+                      pDst->pDrawable->x, pDst->pDrawable->y);
+ 
+     fbbox.x1 = 0;
+     fbbox.y1 = 0;
+     fbbox.x2 = pScreen->width;
+     fbbox.y2 = pScreen->height;
+-    REGION_INIT(pScreen, &fbreg, &fbbox, 0);
++    RegionInitBoxes(&fbreg, &fbbox, 1);
+ 
+-    REGION_INTERSECT(pScreen, changed, changed, &fbreg);
++    RegionIntersect(changed, changed, &fbreg);
+ 
+-    REGION_UNINIT(pScreen, &fbreg);
++    RegionUninit(&fbreg);
+   } else {
+-    changed = REGION_CREATE(pScreen, NullBox, 0);
++    changed = RegionCreate(NullBox, 0);
+   }
+ 
+   (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs);
+@@ -876,7 +874,7 @@ static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+   if (REGION_NOTEMPTY(pScreen, changed))
+     add_changed(pScreen, changed);
+ 
+-  REGION_DESTROY(pScreen, changed);
++  RegionDestroy(changed);
+ 
+   RENDER_EPILOGUE(Glyphs);
+ }
+@@ -1067,17 +1065,17 @@ static void vncHooksFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
+ 
+   GC_OP_PROLOGUE(pGC, FillSpans);
+ 
+-  REGION_NULL(pGC->pScreen, &reg);
+-  REGION_COPY(pGC->pScreen, &reg, pGC->pCompositeClip);
++  RegionNull(&reg);
++  RegionCopy(&reg, pGC->pCompositeClip);
+ 
+   if (pDrawable->type == DRAWABLE_WINDOW)
+-    REGION_INTERSECT(pScreen, &reg, &reg, &((WindowPtr)pDrawable)->borderClip);
++    RegionIntersect(&reg, &reg, &((WindowPtr)pDrawable)->borderClip);
+ 
+   (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+   GC_OP_EPILOGUE(pGC);
+ }
+@@ -1093,17 +1091,17 @@ static void vncHooksSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ 
+   GC_OP_PROLOGUE(pGC, SetSpans);
+ 
+-  REGION_NULL(pGC->pScreen, &reg);
+-  REGION_COPY(pGC->pScreen, &reg, pGC->pCompositeClip);
++  RegionNull(&reg);
++  RegionCopy(&reg, pGC->pCompositeClip);
+ 
+   if (pDrawable->type == DRAWABLE_WINDOW)
+-    REGION_INTERSECT(pScreen, &reg, &reg, &((WindowPtr)pDrawable)->borderClip);
++    RegionIntersect(&reg, &reg, &((WindowPtr)pDrawable)->borderClip);
+ 
+   (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+   GC_OP_EPILOGUE(pGC);
+ }
+@@ -1124,15 +1122,15 @@ static void vncHooksPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+   box.x2 = box.x1 + w;
+   box.y2 = box.y1 + h;
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format,
+                          pBits);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+   GC_OP_EPILOGUE(pGC);
+ }
+@@ -1153,7 +1151,7 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+ 
+   // Apparently this happens now and then...
+   if ((w == 0) || (h == 0))
+-    REGION_NULL(pGC->pScreen, &dst);
++    RegionNull(&dst);
+   else {
+     BoxRec box;
+ 
+@@ -1162,10 +1160,10 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+     box.x2 = box.x1 + w;
+     box.y2 = box.y1 + h;
+ 
+-    REGION_INIT(pGC->pScreen, &dst, &box, 0);
++    RegionInitBoxes(&dst, &box, 1);
+   }
+ 
+-  REGION_INTERSECT(pGC->pScreen, &dst, &dst, pGC->pCompositeClip);
++  RegionIntersect(&dst, &dst, pGC->pCompositeClip);
+ 
+   // The source of the data has to be something that's on screen.
+   if (is_visible(pSrc)) {
+@@ -1176,24 +1174,24 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+     box.x2 = box.x1 + w;
+     box.y2 = box.y1 + h;
+ 
+-    REGION_INIT(pGC->pScreen, &src, &box, 0);
++    RegionInitBoxes(&src, &box, 1);
+ 
+     if ((pSrc->type == DRAWABLE_WINDOW) &&
+-        REGION_NOTEMPTY(pScreen, &((WindowPtr)pSrc)->clipList)) {
+-      REGION_INTERSECT(pScreen, &src, &src, &((WindowPtr)pSrc)->clipList);
++        RegionNotEmpty(&((WindowPtr)pSrc)->clipList)) {
++      RegionIntersect(&src, &src, &((WindowPtr)pSrc)->clipList);
+     }
+ 
+-    REGION_TRANSLATE(pScreen, &src,
++    RegionTranslate(&src,
+                      dstx + pDst->x - srcx - pSrc->x,
+                      dsty + pDst->y - srcy - pSrc->y);
+   } else {
+-    REGION_NULL(pGC->pScreen, &src);
++    RegionNull(&src);
+   }
+ 
+-  REGION_NULL(pGC->pScreen, &changed);
++  RegionNull(&changed);
+ 
+-  REGION_SUBTRACT(pScreen, &changed, &dst, &src);
+-  REGION_INTERSECT(pScreen, &dst, &dst, &src);
++  RegionSubtract(&changed, &dst, &src);
++  RegionIntersect(&dst, &dst, &src);
+ 
+   ret = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ 
+@@ -1205,9 +1203,9 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+   if (REGION_NOTEMPTY(pScreen, &changed))
+     add_changed(pGC->pScreen, &changed);
+ 
+-  REGION_UNINIT(pGC->pScreen, &dst);
+-  REGION_UNINIT(pGC->pScreen, &src);
+-  REGION_UNINIT(pGC->pScreen, &changed);
++  RegionUninit(&dst);
++  RegionUninit(&src);
++  RegionUninit(&changed);
+ 
+   GC_OP_EPILOGUE(pGC);
+ 
+@@ -1234,15 +1232,15 @@ static RegionPtr vncHooksCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
+   box.x2 = box.x1 + w;
+   box.y2 = box.y1 + h;
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   ret = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
+                                 dstx, dsty, plane);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+   GC_OP_EPILOGUE(pGC);
+ 
+@@ -1298,14 +1296,14 @@ static void vncHooksPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+   box.x2 = maxX + 1 + pDrawable->x;
+   box.y2 = maxY + 1 + pDrawable->y;
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1425,13 +1423,13 @@ static void vncHooksPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+   }
+ 
+   reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
+-  REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
++  RegionIntersect(reg, reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts);
+ 
+   add_changed(pGC->pScreen, reg);
+ 
+-  REGION_DESTROY(pGC->pScreen, reg);
++  RegionDestroy(reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1510,13 +1508,13 @@ static void vncHooksPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+   }
+ 
+   reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
+-  REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
++  RegionIntersect(reg, reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs);
+ 
+   add_changed(pGC->pScreen, reg);
+ 
+-  REGION_DESTROY(pGC->pScreen, reg);
++  RegionDestroy(reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1599,13 +1597,13 @@ static void vncHooksPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+   }
+ 
+   reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
+-  REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
++  RegionIntersect(reg, reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects);
+ 
+   add_changed(pGC->pScreen, reg);
+ 
+-  REGION_DESTROY(pGC->pScreen, reg);
++  RegionDestroy(reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1674,13 +1672,13 @@ static void vncHooksPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
+   }
+ 
+   reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
+-  REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
++  RegionIntersect(reg, reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs);
+ 
+   add_changed(pGC->pScreen, reg);
+ 
+-  REGION_DESTROY(pGC->pScreen, reg);
++  RegionDestroy(reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1737,14 +1735,14 @@ static void vncHooksFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
+   box.x2 = maxX + 1 + pDrawable->x;
+   box.y2 = maxY + 1 + pDrawable->y;
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1803,13 +1801,13 @@ static void vncHooksPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+   }
+ 
+   reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
+-  REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
++  RegionIntersect(reg, reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects);
+ 
+   add_changed(pGC->pScreen, reg);
+ 
+-  REGION_DESTROY(pGC->pScreen, reg);
++  RegionDestroy(reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1878,13 +1876,13 @@ static void vncHooksPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
+   }
+ 
+   reg = RECTS_TO_REGION(pGC->pScreen, nRegRects, regRects, CT_NONE);
+-  REGION_INTERSECT(pGC->pScreen, reg, reg, pGC->pCompositeClip);
++  RegionIntersect(reg, reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs);
+ 
+   add_changed(pGC->pScreen, reg);
+ 
+-  REGION_DESTROY(pGC->pScreen, reg);
++  RegionDestroy(reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1929,14 +1927,14 @@ static int vncHooksPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ 
+   GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1963,14 +1961,14 @@ static int vncHooksPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ 
+   GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -1996,14 +1994,14 @@ static void vncHooksImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ 
+   GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -2027,14 +2025,14 @@ static void vncHooksImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ 
+   GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -2059,14 +2057,14 @@ static void vncHooksImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x,
+ 
+   GetTextBoundingRect(pDrawable, pGC->font, x, y, nglyph, &box);
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -2091,14 +2089,14 @@ static void vncHooksPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x,
+ 
+   GetTextBoundingRect(pDrawable, pGC->font, x, y, nglyph, &box);
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+ out:
+   GC_OP_EPILOGUE(pGC);
+@@ -2121,14 +2119,14 @@ static void vncHooksPushPixels(GCPtr pGC, PixmapPtr pBitMap,
+   box.x2 = box.x1 + w;
+   box.y2 = box.y1 + h;
+ 
+-  REGION_INIT(pGC->pScreen, &reg, &box, 0);
+-  REGION_INTERSECT(pGC->pScreen, &reg, &reg, pGC->pCompositeClip);
++  RegionInitBoxes(&reg, &box, 1);
++  RegionIntersect(&reg, &reg, pGC->pCompositeClip);
+ 
+   (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
+ 
+   add_changed(pGC->pScreen, &reg);
+ 
+-  REGION_UNINIT(pGC->pScreen, &reg);
++  RegionUninit(&reg);
+ 
+   GC_OP_EPILOGUE(pGC);
+ }
+diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c
+index 93d8af4..dccea9c 100644
+--- a/unix/xserver/hw/vnc/xvnc.c
++++ b/unix/xserver/hw/vnc/xvnc.c
+@@ -1000,8 +1000,8 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
+ 	    {
+ 		RegionPtr	borderVisible;
+ 
+-		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+-		REGION_SUBTRACT(pScreen, borderVisible,
++		borderVisible = RegionCreate(NullBox, 1);
++		RegionSubtract(borderVisible,
+ 				&pWin->borderClip, &pWin->winSize);
+ 		pWin->valdata->before.borderVisible = borderVisible;
+ 	    }
+@@ -1010,7 +1010,7 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
+     }
+     
+     /*
+-     * Use REGION_BREAK to avoid optimizations in ValidateTree
++     * Use RegionBreak to avoid optimizations in ValidateTree
+      * that assume the root borderClip can't change well, normally
+      * it doesn't...)
+      */
+@@ -1020,18 +1020,18 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
+ 	box.y1 = 0;
+ 	box.x2 = pScreen->width;
+ 	box.y2 = pScreen->height;
+-	REGION_INIT (pScreen, &pWin->winSize, &box, 1);
+-	REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
++	RegionInit(&pWin->winSize, &box, 1);
++	RegionInit(&pWin->borderSize, &box, 1);
+ 	if (WasViewable)
+-	    REGION_RESET(pScreen, &pWin->borderClip, &box);
++	    RegionReset(&pWin->borderClip, &box);
+ 	pWin->drawable.width = pScreen->width;
+ 	pWin->drawable.height = pScreen->height;
+-        REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
++        RegionBreak(&pWin->clipList);
+     }
+     else
+     {
+-	REGION_EMPTY(pScreen, &pWin->borderClip);
+-	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
++	RegionEmpty(&pWin->borderClip);
++	RegionBreak(&pWin->clipList);
+     }
+     
+     ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
diff --git a/SPECS/tigervnc.spec b/SPECS/tigervnc.spec
index 34a3e48..fcc66f5 100644
--- a/SPECS/tigervnc.spec
+++ b/SPECS/tigervnc.spec
@@ -1,6 +1,6 @@
 Name:           tigervnc
 Version:        1.8.0
-Release:        21%{?dist}
+Release:        22%{?dist}
 Summary:        A TigerVNC remote display system
 
 Group:          User Interface/Desktops
@@ -65,6 +65,7 @@ Patch16:       tigervnc-fix-rendering-on-big-endian-systems.patch
 Patch17:       tigervnc-xvnc-update-manpage.patch
 Patch18:       tigervnc-release-pointer-grab-when-cursor-leaves-window.patch
 Patch19:       tigervnc-provide-correct-dimensions-for-xshm-setup.patch
+Patch20:       tigervnc-region-handling.patch
 
 # This is tigervnc-%{version}/unix/xserver116.patch rebased on the latest xorg
 Patch100:       tigervnc-xserver120.patch
@@ -227,6 +228,8 @@ popd
 
 %patch18 -p1 -b .release-pointer-grab-when-cursor-leaves-window
 
+%patch20 -p1 -b .region-handling
+
 # Security fixes
 %patch200 -p1 -b .CVE-2019-15691
 %patch201 -p1 -b .encapsulate-pixelbuffer-internal-details
@@ -409,6 +412,10 @@ fi
 %{_datadir}/icons/hicolor/*/apps/*
 
 %changelog
+* Thu Jul 09 2020 Jan Grulich <jgrulich@redhat.com> - 1.8.0-22
+- Region handling refresh
+  Resolves: bz#1753158
+
 * Wed Apr 22 2020 Jan Grulich <jgrulich@redhat.com> - 1.8.0-21
 - Add upstream patch needed because of previous security fixes
   Resolves: bz#1826822