/*
 * Server-side region objects. Based on the X11 implementation.
 *
 * Copyright 1993, 1994, 1995, 2004 Alexandre Julliard
 * Modifications and additions: Copyright 1998 Huw Davies
 *					  1999 Alex Korobka
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Note:
 *  This is a simplified version of the code, without all the explanations.
 *  Check the equivalent GDI code to make sense of it.
 */

/************************************************************************

Copyright (c) 1987, 1988  X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
X CONSORTIUM 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 X Consortium 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 X Consortium.


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.

************************************************************************/

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "request.h"
#include "user.h"

struct region
{
    int size;
    int num_rects;
    rectangle_t *rects;
    rectangle_t extents;
};


#define RGN_DEFAULT_RECTS 2

#define EXTENTCHECK(r1, r2) \
    ((r1)->right > (r2)->left && \
    (r1)->left < (r2)->right && \
    (r1)->bottom > (r2)->top && \
    (r1)->top < (r2)->bottom)

typedef int (*overlap_func_t)( struct region *reg, const rectangle_t *r1, const rectangle_t *r1End,
                               const rectangle_t *r2, const rectangle_t *r2End, int top, int bottom );
typedef int (*non_overlap_func_t)( struct region *reg, const rectangle_t *r,
                                   const rectangle_t *rEnd, int top, int bottom );

static const rectangle_t empty_rect;  /* all-zero rectangle for empty regions */

/* add a rectangle to a region */
static inline rectangle_t *add_rect( struct region *reg )
{
    if (reg->num_rects >= reg->size - 1)
    {
        rectangle_t *new_rect = realloc( reg->rects, 2 * sizeof(rectangle_t) * reg->size );
        if (!new_rect)
        {
            set_error( STATUS_NO_MEMORY );
            return 0;
        }
        reg->rects = new_rect;
        reg->size *= 2;
    }
    return reg->rects + reg->num_rects++;
}

/* make sure all the rectangles are valid and that the region is properly y-x-banded */
static inline int validate_rectangles( const rectangle_t *rects, unsigned int nb_rects )
{
    const rectangle_t *ptr, *end;

    for (ptr = rects, end = rects + nb_rects; ptr < end; ptr++)
    {
        if (ptr->left >= ptr->right || ptr->top >= ptr->bottom) return 0;  /* empty rectangle */
        if (ptr == end - 1) break;
        if (ptr[0].top == ptr[1].top)  /* same band */
        {
            if (ptr[0].bottom != ptr[1].bottom) return 0;  /* not same y extent */
            if (ptr[0].right >= ptr[1].left) return 0;  /* not properly x ordered */
        }
        else  /* new band */
        {
            if (ptr[0].bottom > ptr[1].top) return 0;  /* not properly y ordered */
        }
    }
    return 1;
}

/* attempt to merge the rects in the current band with those in the */
/* previous one. Used only by region_op. */
static int coalesce_region( struct region *pReg, int prevStart, int curStart )
{
    int curNumRects;
    rectangle_t *pRegEnd = &pReg->rects[pReg->num_rects];
    rectangle_t *pPrevRect = &pReg->rects[prevStart];
    rectangle_t *pCurRect = &pReg->rects[curStart];
    int prevNumRects = curStart - prevStart;
    int bandtop = pCurRect->top;

    for (curNumRects = 0;
         (pCurRect != pRegEnd) && (pCurRect->top == bandtop);
         curNumRects++)
    {
        pCurRect++;
    }

    if (pCurRect != pRegEnd)
    {
        pRegEnd--;
        while (pRegEnd[-1].top == pRegEnd->top) pRegEnd--;
        curStart = pRegEnd - pReg->rects;
        pRegEnd = pReg->rects + pReg->num_rects;
    }

    if ((curNumRects == prevNumRects) && (curNumRects != 0))
    {
        pCurRect -= curNumRects;
        if (pPrevRect->bottom == pCurRect->top)
        {
            do
            {
                if ((pPrevRect->left != pCurRect->left) ||
                    (pPrevRect->right != pCurRect->right)) return curStart;
                pPrevRect++;
                pCurRect++;
                prevNumRects -= 1;
            } while (prevNumRects != 0);

            pReg->num_rects -= curNumRects;
            pCurRect -= curNumRects;
            pPrevRect -= curNumRects;

            do
            {
                pPrevRect->bottom = pCurRect->bottom;
                pPrevRect++;
                pCurRect++;
                curNumRects -= 1;
            } while (curNumRects != 0);

            if (pCurRect == pRegEnd) curStart = prevStart;
            else do { *pPrevRect++ = *pCurRect++; } while (pCurRect != pRegEnd);

        }
    }
    return curStart;
}

/* apply an operation to two regions */
/* check the GDI version of the code for explanations */
static int region_op( struct region *newReg, const struct region *reg1, const struct region *reg2,
                      overlap_func_t overlap_func,
                      non_overlap_func_t non_overlap1_func,
                      non_overlap_func_t non_overlap2_func )
{
    int ybot, ytop, top, bot, prevBand, curBand;
    const rectangle_t *r1BandEnd, *r2BandEnd;

    const rectangle_t *r1 = reg1->rects;
    const rectangle_t *r2 = reg2->rects;
    const rectangle_t *r1End = r1 + reg1->num_rects;
    const rectangle_t *r2End = r2 + reg2->num_rects;

    rectangle_t *new_rects, *old_rects = newReg->rects;
    int new_size, ret = 0;

    new_size = max( reg1->num_rects, reg2->num_rects ) * 2;
    if (!(new_rects = mem_alloc( new_size * sizeof(*newReg->rects) ))) return 0;

    newReg->size = new_size;
    newReg->rects = new_rects;
    newReg->num_rects = 0;

    if (reg1->extents.top < reg2->extents.top)
        ybot = reg1->extents.top;
    else
        ybot = reg2->extents.top;

    prevBand = 0;

    do
    {
        curBand = newReg->num_rects;

        r1BandEnd = r1;
        while ((r1BandEnd != r1End) && (r1BandEnd->top == r1->top)) r1BandEnd++;

        r2BandEnd = r2;
        while ((r2BandEnd != r2End) && (r2BandEnd->top == r2->top)) r2BandEnd++;

        if (r1->top < r2->top)
        {
            top = max(r1->top,ybot);
            bot = min(r1->bottom,r2->top);

            if ((top != bot) && non_overlap1_func)
            {
                if (!non_overlap1_func( newReg, r1, r1BandEnd, top, bot )) goto done;
            }

            ytop = r2->top;
        }
        else if (r2->top < r1->top)
        {
            top = max(r2->top,ybot);
            bot = min(r2->bottom,r1->top);

            if ((top != bot) && non_overlap2_func)
            {
                if (!non_overlap2_func( newReg, r2, r2BandEnd, top, bot )) goto done;
            }

            ytop = r1->top;
        }
        else
        {
            ytop = r1->top;
        }

        if (newReg->num_rects != curBand)
            prevBand = coalesce_region(newReg, prevBand, curBand);

        ybot = min(r1->bottom, r2->bottom);
        curBand = newReg->num_rects;
        if (ybot > ytop)
        {
            if (!overlap_func( newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot )) goto done;
        }

        if (newReg->num_rects != curBand)
            prevBand = coalesce_region(newReg, prevBand, curBand);

        if (r1->bottom == ybot) r1 = r1BandEnd;
        if (r2->bottom == ybot) r2 = r2BandEnd;
    } while ((r1 != r1End) && (r2 != r2End));

    curBand = newReg->num_rects;
    if (r1 != r1End)
    {
        if (non_overlap1_func)
        {
            do
            {
                r1BandEnd = r1;
                while ((r1BandEnd < r1End) && (r1BandEnd->top == r1->top)) r1BandEnd++;
                if (!non_overlap1_func( newReg, r1, r1BandEnd, max(r1->top,ybot), r1->bottom ))
                    goto done;
                r1 = r1BandEnd;
            } while (r1 != r1End);
        }
    }
    else if ((r2 != r2End) && non_overlap2_func)
    {
        do
        {
            r2BandEnd = r2;
            while ((r2BandEnd < r2End) && (r2BandEnd->top == r2->top)) r2BandEnd++;
            if (!non_overlap2_func( newReg, r2, r2BandEnd, max(r2->top,ybot), r2->bottom ))
                goto done;
            r2 = r2BandEnd;
        } while (r2 != r2End);
    }

    if (newReg->num_rects != curBand) coalesce_region(newReg, prevBand, curBand);

    if ((newReg->num_rects < (newReg->size / 2)) && (newReg->size > 2))
    {
        new_size = max( newReg->num_rects, RGN_DEFAULT_RECTS );
        if ((new_rects = realloc( newReg->rects, sizeof(*newReg->rects) * new_size )))
        {
            newReg->rects = new_rects;
            newReg->size = new_size;
        }
    }
    ret = 1;
done:
    free( old_rects );
    return ret;
}

/* recalculate the extents of a region */
static void set_region_extents( struct region *region )
{
    rectangle_t *pRect, *pRectEnd;

    if (region->num_rects == 0)
    {
        region->extents.left = 0;
        region->extents.top = 0;
        region->extents.right = 0;
        region->extents.bottom = 0;
        return;
    }

    pRect = region->rects;
    pRectEnd = &pRect[region->num_rects - 1];

    region->extents.left = pRect->left;
    region->extents.top = pRect->top;
    region->extents.right = pRectEnd->right;
    region->extents.bottom = pRectEnd->bottom;

    while (pRect <= pRectEnd)
    {
        if (pRect->left < region->extents.left) region->extents.left = pRect->left;
        if (pRect->right > region->extents.right) region->extents.right = pRect->right;
        pRect++;
    }
}

/* handle an overlapping band for intersect_region */
static int intersect_overlapping( struct region *pReg,
                                  const rectangle_t *r1, const rectangle_t *r1End,
                                  const rectangle_t *r2, const rectangle_t *r2End,
                                  int top, int bottom )

{
    int left, right;

    while ((r1 != r1End) && (r2 != r2End))
    {
        left = max(r1->left, r2->left);
        right = min(r1->right, r2->right);

        if (left < right)
        {
            rectangle_t *rect = add_rect( pReg );
            if (!rect) return 0;
            rect->left = left;
            rect->top = top;
            rect->right = right;
            rect->bottom = bottom;
        }

        if (r1->right < r2->right) r1++;
        else if (r2->right < r1->right) r2++;
        else
        {
            r1++;
            r2++;
        }
    }
    return 1;
}

/* handle a non-overlapping band for subtract_region */
static int subtract_non_overlapping( struct region *pReg, const rectangle_t *r,
                                  const rectangle_t *rEnd, int top, int bottom )
{
    while (r != rEnd)
    {
        rectangle_t *rect = add_rect( pReg );
        if (!rect) return 0;
        rect->left = r->left;
        rect->top = top;
        rect->right = r->right;
        rect->bottom = bottom;
        r++;
    }
    return 1;
}

/* handle an overlapping band for subtract_region */
static int subtract_overlapping( struct region *pReg,
                                 const rectangle_t *r1, const rectangle_t *r1End,
                                 const rectangle_t *r2, const rectangle_t *r2End,
                                 int top, int bottom )
{
    int left = r1->left;

    while ((r1 != r1End) && (r2 != r2End))
    {
        if (r2->right <= left) r2++;
        else if (r2->left <= left)
        {
            left = r2->right;
            if (left >= r1->right)
            {
                r1++;
                if (r1 != r1End)
                    left = r1->left;
            }
            else r2++;
        }
        else if (r2->left < r1->right)
        {
            rectangle_t *rect = add_rect( pReg );
            if (!rect) return 0;
            rect->left = left;
            rect->top = top;
            rect->right = r2->left;
            rect->bottom = bottom;
            left = r2->right;
            if (left >= r1->right)
            {
                r1++;
                if (r1 != r1End)
                    left = r1->left;
            }
            else r2++;
        }
        else
        {
            if (r1->right > left)
            {
                rectangle_t *rect = add_rect( pReg );
                if (!rect) return 0;
                rect->left = left;
                rect->top = top;
                rect->right = r1->right;
                rect->bottom = bottom;
            }
            r1++;
            left = r1->left;
        }
    }

    while (r1 != r1End)
    {
        rectangle_t *rect = add_rect( pReg );
        if (!rect) return 0;
        rect->left = left;
        rect->top = top;
        rect->right = r1->right;
        rect->bottom = bottom;
        r1++;
        if (r1 != r1End) left = r1->left;
    }
    return 1;
}

/* handle a non-overlapping band for union_region */
static int union_non_overlapping( struct region *pReg, const rectangle_t *r,
                                  const rectangle_t *rEnd, int top, int bottom )
{
    while (r != rEnd)
    {
        rectangle_t *rect = add_rect( pReg );
        if (!rect) return 0;
        rect->left = r->left;
        rect->top = top;
        rect->right = r->right;
        rect->bottom = bottom;
        r++;
    }
    return 1;
}

/* handle an overlapping band for union_region */
static int union_overlapping( struct region *pReg,
                              const rectangle_t *r1, const rectangle_t *r1End,
                              const rectangle_t *r2, const rectangle_t *r2End,
                              int top, int bottom )
{
#define MERGERECT(r) \
    if ((pReg->num_rects != 0) &&  \
        (pReg->rects[pReg->num_rects-1].top == top) &&  \
        (pReg->rects[pReg->num_rects-1].bottom == bottom) &&  \
        (pReg->rects[pReg->num_rects-1].right >= r->left))  \
    {  \
        if (pReg->rects[pReg->num_rects-1].right < r->right)  \
        {  \
            pReg->rects[pReg->num_rects-1].right = r->right;  \
        }  \
    }  \
    else  \
    {  \
        rectangle_t *rect = add_rect( pReg ); \
        if (!rect) return 0; \
        rect->top = top;  \
        rect->bottom = bottom;  \
        rect->left = r->left;  \
        rect->right = r->right;  \
    }  \
    r++;

    while ((r1 != r1End) && (r2 != r2End))
    {
        if (r1->left < r2->left)
        {
            MERGERECT(r1);
        }
        else
        {
            MERGERECT(r2);
        }
    }

    if (r1 != r1End)
    {
        do
        {
            MERGERECT(r1);
        } while (r1 != r1End);
    }
    else while (r2 != r2End)
    {
        MERGERECT(r2);
    }
    return 1;
#undef MERGERECT
}


/* create an empty region */
struct region *create_empty_region(void)
{
    struct region *region;

    if (!(region = mem_alloc( sizeof(*region) ))) return NULL;
    if (!(region->rects = mem_alloc( RGN_DEFAULT_RECTS * sizeof(*region->rects) )))
    {
        free( region );
        return NULL;
    }
    region->size = RGN_DEFAULT_RECTS;
    region->num_rects = 0;
    region->extents.left = 0;
    region->extents.top = 0;
    region->extents.right = 0;
    region->extents.bottom = 0;
    return region;
}

/* create a region from request data */
struct region *create_region_from_req_data( const void *data, size_t size )
{
    unsigned int alloc_rects;
    struct region *region;
    const rectangle_t *rects = data;
    int nb_rects = size / sizeof(rectangle_t);

    /* special case: empty region can be specified by a single all-zero rectangle */
    if (nb_rects == 1 && !memcmp( rects, &empty_rect, sizeof(empty_rect) )) nb_rects = 0;

    if (!validate_rectangles( rects, nb_rects ))
    {
        set_error( STATUS_INVALID_PARAMETER );
        return NULL;
    }

    if (!(region = mem_alloc( sizeof(*region) ))) return NULL;

    alloc_rects = max( nb_rects, RGN_DEFAULT_RECTS );
    if (!(region->rects = mem_alloc( alloc_rects * sizeof(*region->rects) )))
    {
        free( region );
        return NULL;
    }
    region->size = alloc_rects;
    region->num_rects = nb_rects;
    memcpy( region->rects, rects, nb_rects * sizeof(*rects) );
    set_region_extents( region );
    return region;
}

/* free a region */
void free_region( struct region *region )
{
    free( region->rects );
    free( region );
}

/* set region to a simple rectangle */
void set_region_rect( struct region *region, const rectangle_t *rect )
{
    if (rect->left < rect->right && rect->top < rect->bottom)
    {
        region->num_rects = 1;
        region->rects[0] = region->extents = *rect;
    }
    else
    {
        region->num_rects = 0;
        region->extents.left = 0;
        region->extents.top = 0;
        region->extents.right = 0;
        region->extents.bottom = 0;
    }
}

/* retrieve the region data for sending to the client */
rectangle_t *get_region_data( const struct region *region, size_t max_size, size_t *total_size )
{
    const rectangle_t *data = region->rects;

    if (!(*total_size = region->num_rects * sizeof(rectangle_t)))
    {
        /* return a single empty rect for empty regions */
        *total_size = sizeof(empty_rect);
        data = &empty_rect;
    }
    if (max_size >= *total_size) return memdup( data, *total_size );
    set_error( STATUS_BUFFER_OVERFLOW );
    return NULL;
}

/* retrieve the region data for sending to the client and free the region at the same time */
rectangle_t *get_region_data_and_free( struct region *region, size_t max_size, size_t *total_size )
{
    rectangle_t *ret = region->rects;

    if (!(*total_size = region->num_rects * sizeof(rectangle_t)))
    {
        /* return a single empty rect for empty regions */
        *total_size = sizeof(empty_rect);
        if (max_size >= sizeof(empty_rect))
        {
            ret = memdup( &empty_rect, sizeof(empty_rect) );
            free( region->rects );
        }
    }

    if (max_size < *total_size)
    {
        free( region->rects );
        set_error( STATUS_BUFFER_OVERFLOW );
        ret = NULL;
    }
    free( region );
    return ret;
}

/* check if a given region is empty */
int is_region_empty( const struct region *region )
{
    return region->num_rects == 0;
}


/* get the extents rect of a region */
void get_region_extents( const struct region *region, rectangle_t *rect )
{
    *rect = region->extents;
}

/* add an offset to a region */
void offset_region( struct region *region, int x, int y )
{
    rectangle_t *rect, *end;

    if (!region->num_rects) return;
    for (rect = region->rects, end = rect + region->num_rects; rect < end; rect++)
    {
        rect->left += x;
        rect->right += x;
        rect->top += y;
        rect->bottom += y;
    }
    region->extents.left += x;
    region->extents.right += x;
    region->extents.top += y;
    region->extents.bottom += y;
}

/* make a copy of a region; returns dst or NULL on error */
struct region *copy_region( struct region *dst, const struct region *src )
{
    if (dst == src) return dst;

    if (dst->size < src->num_rects)
    {
        rectangle_t *rect = realloc( dst->rects, src->num_rects * sizeof(*rect) );
        if (!rect)
        {
            set_error( STATUS_NO_MEMORY );
            return NULL;
        }
        dst->rects = rect;
        dst->size = src->num_rects;
    }
    dst->num_rects = src->num_rects;
    dst->extents = src->extents;
    memcpy( dst->rects, src->rects, src->num_rects * sizeof(*dst->rects) );
    return dst;
}

/* compute the intersection of two regions into dst, which can be one of the source regions */
struct region *intersect_region( struct region *dst, const struct region *src1,
                                 const struct region *src2 )
{
    if (!src1->num_rects || !src2->num_rects || !EXTENTCHECK(&src1->extents, &src2->extents))
    {
        dst->num_rects = 0;
        dst->extents.left = 0;
        dst->extents.top = 0;
        dst->extents.right = 0;
        dst->extents.bottom = 0;
        return dst;
    }
    if (!region_op( dst, src1, src2, intersect_overlapping, NULL, NULL )) return NULL;
    set_region_extents( dst );
    return dst;
}

/* compute the subtraction of two regions into dst, which can be one of the source regions */
struct region *subtract_region( struct region *dst, const struct region *src1,
                                const struct region *src2 )
{
    if (!src1->num_rects || !src2->num_rects || !EXTENTCHECK(&src1->extents, &src2->extents))
        return copy_region( dst, src1 );

    if (!region_op( dst, src1, src2, subtract_overlapping,
                    subtract_non_overlapping, NULL )) return NULL;
    set_region_extents( dst );
    return dst;
}

/* compute the union of two regions into dst, which can be one of the source regions */
struct region *union_region( struct region *dst, const struct region *src1,
                             const struct region *src2 )
{
    if (src1 == src2) return copy_region( dst, src1 );
    if (!src1->num_rects) return copy_region( dst, src2 );
    if (!src2->num_rects) return copy_region( dst, src1 );

    if ((src1->num_rects == 1) &&
        (src1->extents.left <= src2->extents.left) &&
        (src1->extents.top <= src2->extents.top) &&
        (src1->extents.right >= src2->extents.right) &&
        (src1->extents.bottom >= src2->extents.bottom))
        return copy_region( dst, src1 );

    if ((src2->num_rects == 1) &&
        (src2->extents.left <= src1->extents.left) &&
        (src2->extents.top <= src1->extents.top) &&
        (src2->extents.right >= src1->extents.right) &&
        (src2->extents.bottom >= src1->extents.bottom))
        return copy_region( dst, src2 );

    if (!region_op( dst, src1, src2, union_overlapping,
                    union_non_overlapping, union_non_overlapping )) return NULL;

    dst->extents.left = min(src1->extents.left, src2->extents.left);
    dst->extents.top = min(src1->extents.top, src2->extents.top);
    dst->extents.right = max(src1->extents.right, src2->extents.right);
    dst->extents.bottom = max(src1->extents.bottom, src2->extents.bottom);
    return dst;
}

/* compute the exclusive or of two regions into dst, which can be one of the source regions */
struct region *xor_region( struct region *dst, const struct region *src1,
                           const struct region *src2 )
{
    struct region *tmp = create_empty_region();

    if (!tmp) return NULL;

    if (!subtract_region( tmp, src1, src2 ) ||
        !subtract_region( dst, src2, src1 ) ||
        !union_region( dst, dst, tmp ))
        dst = NULL;

    free_region( tmp );
    return dst;
}

/* check if the given point is inside the region */
int point_in_region( struct region *region, int x, int y )
{
    const rectangle_t *ptr, *end;

    for (ptr = region->rects, end = region->rects + region->num_rects; ptr < end; ptr++)
    {
        if (ptr->top > y) return 0;
        if (ptr->bottom <= y) continue;
        /* now we are in the correct band */
        if (ptr->left > x) return 0;
        if (ptr->right <= x) continue;
        return 1;
    }
    return 0;
}

/* check if the given rectangle is (at least partially) inside the region */
int rect_in_region( struct region *region, const rectangle_t *rect )
{
    const rectangle_t *ptr, *end;

    for (ptr = region->rects, end = region->rects + region->num_rects; ptr < end; ptr++)
    {
        if (ptr->top >= rect->bottom) return 0;
        if (ptr->bottom <= rect->top) continue;
        if (ptr->left >= rect->right) continue;
        if (ptr->right <= rect->left) continue;
        return 1;
    }
    return 0;
}
