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 +# +# 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 - -#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 -#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 = ®ion.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(®ion, 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(y1rects); - 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(®1->extents, ®2->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].x1rects); \ - 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 (y1x1 < 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(y1x1x2); - 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(y1rects[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(x1x1); - 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(x1x2); - 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(®M->extents, ®S->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; inumRects; 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 = ▭ - 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(®ion->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 - -#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 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 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 -#include -#include extern "C" { -#include -#include -#include -} - -// 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 = ®ion.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 +#include +} 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& rects) { - clear(); - std::vector::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* 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* 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* 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 rects; + std::vector::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 #include -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& 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, ®, &box, 0); - REGION_INTERSECT(pScreen, ®, ®, &pWin->clipList); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, &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, ®); } - REGION_UNINIT(pScreen, ®); + RegionUninit(®); 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, ®); - REGION_COPY(pGC->pScreen, ®, pGC->pCompositeClip); + RegionNull(®); + RegionCopy(®, pGC->pCompositeClip); if (pDrawable->type == DRAWABLE_WINDOW) - REGION_INTERSECT(pScreen, ®, ®, &((WindowPtr)pDrawable)->borderClip); + RegionIntersect(®, ®, &((WindowPtr)pDrawable)->borderClip); (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®); - REGION_COPY(pGC->pScreen, ®, pGC->pCompositeClip); + RegionNull(®); + RegionCopy(®, pGC->pCompositeClip); if (pDrawable->type == DRAWABLE_WINDOW) - REGION_INTERSECT(pScreen, ®, ®, &((WindowPtr)pDrawable)->borderClip); + RegionIntersect(®, ®, &((WindowPtr)pDrawable)->borderClip); (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); ret = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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, ®, &box, 0); - REGION_INTERSECT(pGC->pScreen, ®, ®, pGC->pCompositeClip); + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, pGC->pCompositeClip); (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y); add_changed(pGC->pScreen, ®); - REGION_UNINIT(pGC->pScreen, ®); + RegionUninit(®); 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);