/*
 * GDI region objects
 *
 * Copyright 1993, 1994 Alexandre Julliard
 *
static char Copyright[] = "Copyright  Alexandre Julliard, 1993, 1994";
*/
#include <stdlib.h>
#include <stdio.h>

#include "region.h"
#include "stddebug.h"
/* #define DEBUG_REGION */
#include "debug.h"

  /* GC used for region operations */
static GC regionGC = 0;

/***********************************************************************
 *           REGION_Init
 */
BOOL REGION_Init(void)
{
    Pixmap tmpPixmap;

      /* CreateGC needs a drawable */
    tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 );
    if (tmpPixmap)
    {
	regionGC = XCreateGC( display, tmpPixmap, 0, NULL );
	XFreePixmap( display, tmpPixmap );
	if (!regionGC) return FALSE;
	XSetForeground( display, regionGC, 1 );
	XSetGraphicsExposures( display, regionGC, False );
	return TRUE;
    }
    else return FALSE;
}


/***********************************************************************
 *           REGION_MakePixmap
 *
 * Make a pixmap of an X region.
 */
static BOOL REGION_MakePixmap( REGION *region )
{
    int width = region->box.right - region->box.left;
    int height = region->box.bottom - region->box.top;

    if (!region->xrgn) return TRUE;  /* Null region */
    region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
    if (!region->pixmap) return FALSE;
    XSetRegion( display, regionGC, region->xrgn );
    XSetClipOrigin( display, regionGC, -region->box.left, -region->box.top );
    XSetFunction( display, regionGC, GXset );
    XFillRectangle( display, region->pixmap, regionGC, 0, 0, width, height );
    XSetClipMask( display, regionGC, None );  /* Clear clip region */
    return TRUE;
}


/***********************************************************************
 *           REGION_SetRect
 *
 * Set the bounding box of the region and create the pixmap (or the X rgn).
 * The hrgn must be valid.
 */
static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect, BOOL createXrgn )
{
    int width, height;

      /* Fill region */

    REGION * region = &((RGNOBJ *)GDI_HEAP_ADDR( hrgn ))->region;
    width  = rect->right - rect->left;
    height = rect->bottom - rect->top;
    if ((width <= 0) || (height <= 0))
    {
	region->type       = NULLREGION;
	region->box.left   = 0;
	region->box.right  = 0;
	region->box.top    = 0;
	region->box.bottom = 0;
	region->pixmap     = 0;
	region->xrgn       = 0;
	return TRUE;
    }
    region->type   = SIMPLEREGION;
    region->box    = *rect;
    region->xrgn   = 0;
    region->pixmap = 0;

    if (createXrgn)  /* Create and set the X region */
    {
	XRectangle xrect = { region->box.left, region->box.top, width, height};
	if (!(region->xrgn = XCreateRegion())) return FALSE;
        XUnionRectWithRegion( &xrect, region->xrgn, region->xrgn );
    }
    else  /* Create the pixmap */
    {
	region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1);
	if (!region->pixmap) return FALSE;
	  /* Fill the pixmap */
	XSetFunction( display, regionGC, GXclear );
	XFillRectangle(display, region->pixmap, regionGC, 0, 0, width, height);
    }
    return TRUE;
}


/***********************************************************************
 *           REGION_DeleteObject
 */
BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj )
{
    if (obj->region.pixmap) XFreePixmap( display, obj->region.pixmap );
    if (obj->region.xrgn) XDestroyRegion( obj->region.xrgn );
    return GDI_FreeObject( hrgn );
}


/***********************************************************************
 *           OffsetRgn    (GDI.101)
 */
int OffsetRgn( HRGN hrgn, short x, short y )
{
    RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
    if (!obj) return ERROR;
    dprintf_region(stddeb, "OffsetRgn: %d %d,%d\n", hrgn, x, y );
    OffsetRect( &obj->region.box, x, y );
    if (obj->region.xrgn) XOffsetRegion( obj->region.xrgn, x, y );
    return obj->region.type;
}


/***********************************************************************
 *           GetRgnBox    (GDI.134)
 */
int GetRgnBox( HRGN hrgn, LPRECT rect )
{
    RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
    if (!obj) return ERROR;
    dprintf_region(stddeb, "GetRgnBox: %d\n", hrgn );
    *rect = obj->region.box;
    return obj->region.type;
}


/***********************************************************************
 *           CreateRectRgn    (GDI.64)
 */
HRGN CreateRectRgn( short left, short top, short right, short bottom )
{
    RECT rect = { left, top, right, bottom };    
    return CreateRectRgnIndirect( &rect );
}


/***********************************************************************
 *           CreateRectRgnIndirect    (GDI.65)
 */
HRGN CreateRectRgnIndirect( LPRECT rect )
{
    HRGN hrgn;

    dprintf_region(stddeb, "CreateRectRgnIndirect: %d,%d-%d,%d\n",
	    rect->left, rect->top, rect->right, rect->bottom );
    
      /* Create region */

    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
    if (!REGION_SetRect( hrgn, rect, TRUE ))
    {
	GDI_FreeObject( hrgn );
	return 0;
    }
    return hrgn;
}


/***********************************************************************
 *           CreateRoundRectRgn    (GDI.444)
 */
HRGN CreateRoundRectRgn( short left, short top, short right, short bottom,
			 short ellipse_width, short ellipse_height )
{
    RECT rect = { left, top, right, bottom };    
    RGNOBJ * rgnObj;
    HRGN hrgn;

    dprintf_region(stddeb, "CreateRoundRectRgn: %d,%d-%d,%d %dx%d\n",
	    left, top, right, bottom, ellipse_width, ellipse_height );
    
      /* Create region */

    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
    if (!REGION_SetRect( hrgn, &rect, FALSE ))
    {
	GDI_FreeObject( hrgn );
	return 0;
    }
    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );

      /* Fill pixmap */
    
    if (rgnObj->region.type != NULLREGION)
    {
	int width  = rgnObj->region.box.right - rgnObj->region.box.left;
	int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
	XSetFunction( display, regionGC, GXcopy );
	XFillRectangle( display, rgnObj->region.pixmap, regionGC,
		        0, ellipse_height / 2,
		        width, height - ellipse_height );
	XFillRectangle( display, rgnObj->region.pixmap, regionGC,
		        ellipse_width / 2, 0,
		        width - ellipse_width, height );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  0, 0,
		  ellipse_width, ellipse_height, 0, 360*64 );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  width - ellipse_width, 0,
		  ellipse_width, ellipse_height, 0, 360*64 );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  0, height - ellipse_height,
		  ellipse_width, ellipse_height, 0, 360*64 );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  width - ellipse_width, height - ellipse_height,
		  ellipse_width, ellipse_height, 0, 360*64 );
    }
    
    return hrgn;
}


/***********************************************************************
 *           SetRectRgn    (GDI.172)
 */
void SetRectRgn( HRGN hrgn, short left, short top, short right, short bottom )
{
    RECT rect = { left, top, right, bottom };    
    RGNOBJ * rgnObj;

    dprintf_region(stddeb, "SetRectRgn: %d %d,%d-%d,%d\n", 
		   hrgn, left, top, right, bottom );
    
      /* Free previous pixmap */

    if (!(rgnObj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return;
    if (rgnObj->region.pixmap) XFreePixmap( display, rgnObj->region.pixmap );
    if (rgnObj->region.xrgn) XDestroyRegion( rgnObj->region.xrgn );
    REGION_SetRect( hrgn, &rect, TRUE );
}


/***********************************************************************
 *           CreateEllipticRgn    (GDI.54)
 */
HRGN CreateEllipticRgn( short left, short top, short right, short bottom )
{
    RECT rect = { left, top, right, bottom };    
    return CreateEllipticRgnIndirect( &rect );
}


/***********************************************************************
 *           CreateEllipticRgnIndirect    (GDI.55)
 */
HRGN CreateEllipticRgnIndirect( LPRECT rect )
{
    RGNOBJ * rgnObj;
    HRGN hrgn;

    dprintf_region(stddeb, "CreateEllipticRgnIndirect: %d,%d-%d,%d\n",
	    rect->left, rect->top, rect->right, rect->bottom );
    
      /* Create region */

    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
    if (!REGION_SetRect( hrgn, rect, FALSE ))
    {
	GDI_FreeObject( hrgn );
	return 0;
    }
    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );

      /* Fill pixmap */
    
    if (rgnObj->region.type != NULLREGION)
    {
	int width  = rgnObj->region.box.right - rgnObj->region.box.left;
	int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
	XSetFunction( display, regionGC, GXcopy );
	XFillArc( display, rgnObj->region.pixmap, regionGC,
		  0, 0, width, height, 0, 360*64 );
    }
    
    return hrgn;
}


/***********************************************************************
 *           CreatePolygonRgn    (GDI.63)
 */
HRGN CreatePolygonRgn( POINT * points, short count, short mode )
{
    return CreatePolyPolygonRgn( points, &count, 1, mode );
}


/***********************************************************************
 *           CreatePolyPolygonRgn    (GDI.451)
 */
HRGN CreatePolyPolygonRgn( POINT * points, short * count,
			   short nbpolygons, short mode )
{
    RGNOBJ * rgnObj;
    HRGN hrgn;
    int i, j, maxPoints;
    XPoint *xpoints, *pt;
    XRectangle rect;
    Region xrgn;

    dprintf_region(stddeb, "CreatePolyPolygonRgn: %d polygons\n", nbpolygons );

      /* Allocate points array */

    if (!nbpolygons) return 0;
    for (i = maxPoints = 0; i < nbpolygons; i++)
	if (maxPoints < count[i]) maxPoints = count[i];
    if (!maxPoints) return 0;
    if (!(xpoints = (XPoint *) malloc( sizeof(XPoint) * maxPoints )))
	return 0;

      /* Allocate region */

    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC )))
    {
	free( xpoints );
	return 0;
    }
    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
    rgnObj->region.type   = SIMPLEREGION;
    rgnObj->region.xrgn   = 0;
    rgnObj->region.pixmap = 0;

      /* Create X region */

    for (i = 0; i < nbpolygons; i++, count++)
    {
	for (j = *count, pt = xpoints; j > 0; j--, points++, pt++)
	{
	    pt->x = points->x;
	    pt->y = points->y;
	}
	xrgn = XPolygonRegion( xpoints, *count,
			       (mode == WINDING) ? WindingRule : EvenOddRule );
	if (!xrgn)
        {
            if (rgnObj->region.xrgn) XDestroyRegion( rgnObj->region.xrgn );
            free( xpoints );
            GDI_FreeObject( hrgn );
            return 0;
        }
	if (i > 0)
	{
	    Region tmprgn = XCreateRegion();
	    if (mode == WINDING) XUnionRegion(xrgn,rgnObj->region.xrgn,tmprgn);
	    else XXorRegion( xrgn, rgnObj->region.xrgn, tmprgn );
	    XDestroyRegion( rgnObj->region.xrgn );
	    rgnObj->region.xrgn = tmprgn;
	}
	else rgnObj->region.xrgn = xrgn;
    }

    free( xpoints );
    XClipBox( rgnObj->region.xrgn, &rect );
    SetRect( &rgnObj->region.box, rect.x, rect.y,
	     rect.x + rect.width, rect.y + rect.height);
    return hrgn;
}


/***********************************************************************
 *           PtInRegion    (GDI.161)
 */
BOOL PtInRegion( HRGN hrgn, short x, short y )
{
    BOOL res;
    RGNOBJ * obj;
    POINT pt = { x, y };
    
    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
    if (!PtInRect( &obj->region.box, pt )) return FALSE;
    if (obj->region.xrgn)
    {
	return XPointInRegion( obj->region.xrgn, x, y );
    }
    else
    {
	XImage *image = XGetImage( display, obj->region.pixmap,
			    x - obj->region.box.left, y - obj->region.box.top,
			    1, 1, AllPlanes, ZPixmap );
	if (!image) return FALSE;
	res = (XGetPixel( image, 0, 0 ) != 0);
	XDestroyImage( image );
    }
    return res;
}


/***********************************************************************
 *           RectInRegion    (GDI.181)
 */
BOOL RectInRegion( HRGN hrgn, LPRECT rect )
{
    XImage * image;
    RGNOBJ * obj;
    RECT intersect;
    int x, y;
    
    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
    if (obj->region.xrgn)
    {
	return (XRectInRegion( obj->region.xrgn, rect->left, rect->top,
			       rect->right-rect->left,
			       rect->bottom-rect->top ) != RectangleOut);
    }
    else
    {
	if (!IntersectRect( &intersect, &obj->region.box, rect )) return FALSE;
    
	image = XGetImage( display, obj->region.pixmap,
			   intersect.left - obj->region.box.left,
			   intersect.top - obj->region.box.top,
			   intersect.right - intersect.left,
			   intersect.bottom - intersect.top,
			   AllPlanes, ZPixmap );
	if (!image) return FALSE;
	for (y = 0; y < image->height; y++)
	    for (x = 0; x < image->width; x++)
		if (XGetPixel( image, x, y ) != 0)
		{
		    XDestroyImage( image );
		    return TRUE;
		}
    
	XDestroyImage( image );
    }
    return FALSE;
}


/***********************************************************************
 *           EqualRgn    (GDI.72)
 */
BOOL EqualRgn( HRGN rgn1, HRGN rgn2 )
{
    RGNOBJ *obj1, *obj2;
    XImage *image1, *image2;
    Pixmap pixmap1, pixmap2;
    int width, height, x, y;

      /* Compare bounding boxes */

    if (!(obj1 = (RGNOBJ *) GDI_GetObjPtr( rgn1, REGION_MAGIC ))) return FALSE;
    if (!(obj2 = (RGNOBJ *) GDI_GetObjPtr( rgn2, REGION_MAGIC ))) return FALSE;
    if (obj1->region.type == NULLREGION)
	return (obj2->region.type == NULLREGION);
    else if (obj2->region.type == NULLREGION) return FALSE;
    if (!EqualRect( &obj1->region.box, &obj2->region.box )) return FALSE;
    if (obj1->region.xrgn && obj2->region.xrgn)
    {
	return XEqualRegion( obj1->region.xrgn, obj2->region.xrgn );
    }
    
      /* Get pixmap contents */

    if (!(pixmap1 = obj1->region.pixmap) &&
	!REGION_MakePixmap( &obj1->region )) return FALSE;
    if (!(pixmap2 = obj2->region.pixmap) &&
	!REGION_MakePixmap( &obj2->region )) return FALSE;
    width  = obj1->region.box.right - obj1->region.box.left;
    height = obj1->region.box.bottom - obj1->region.box.top;
    image1 = XGetImage( display, obj1->region.pixmap,
			0, 0, width, height, AllPlanes, ZPixmap );
    image2 = XGetImage( display, obj2->region.pixmap,
		        0, 0, width, height, AllPlanes, ZPixmap );
    if (!image1 || !image2)
    {
	if (image1) XDestroyImage( image1 );
	if (image2) XDestroyImage( image2 );
	return FALSE;
    }
    
      /* Compare pixmaps */
    for (y = 0; y < height; y++)
	for (x = 0; x < width; x++)
	    if (XGetPixel( image1, x, y ) != XGetPixel( image2, x, y))
	    {
		XDestroyImage( image1 );
		XDestroyImage( image2 );
		return FALSE;
	    }
    
    XDestroyImage( image1 );
    XDestroyImage( image2 );
    return TRUE;
}


/***********************************************************************
 *           REGION_CopyIntersection
 *
 * Copy to dest->pixmap the area of src->pixmap delimited by
 * the intersection of dest and src regions, using the current GC function.
 */
void REGION_CopyIntersection( REGION * dest, REGION * src )
{
    RECT inter;
    if (!IntersectRect( &inter, &dest->box, &src->box )) return;
    XCopyArea( display, src->pixmap, dest->pixmap, regionGC,
	       inter.left - src->box.left, inter.top - src->box.top,
	       inter.right - inter.left, inter.bottom - inter.top,
	       inter.left - dest->box.left, inter.top - dest->box.top );
}


/***********************************************************************
 *           REGION_CopyRegion
 *
 * Copy region src into dest.
 */
static int REGION_CopyRegion( RGNOBJ *src, RGNOBJ *dest )
{
    if (dest->region.pixmap) XFreePixmap( display, dest->region.pixmap );
    dest->region.type   = src->region.type;
    dest->region.box    = src->region.box;
    dest->region.pixmap = 0;
    if (src->region.xrgn)  /* Copy only the X region */
    {
        Region tmprgn = XCreateRegion();
        if (!dest->region.xrgn) dest->region.xrgn = XCreateRegion();
        XUnionRegion( tmprgn, src->region.xrgn, dest->region.xrgn );
        XDestroyRegion( tmprgn );
    }
    else  /* Copy the pixmap (if any) */
    {
        if (dest->region.xrgn)
        {
            XDestroyRegion( dest->region.xrgn );
            dest->region.xrgn = 0;
        }
        if (src->region.pixmap)
        {
            int width = src->region.box.right - src->region.box.left;
            int height = src->region.box.bottom - src->region.box.top;
            
            dest->region.pixmap = XCreatePixmap( display, rootWindow,
                                                 width, height, 1 );
            XSetFunction( display, regionGC, GXcopy );
            XCopyArea( display, src->region.pixmap, dest->region.pixmap,
                       regionGC, 0, 0, width, height, 0, 0 );
        }
    }
    return dest->region.type;
}


/***********************************************************************
 *           CombineRgn    (GDI.451)
 */
int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
{
    RGNOBJ *destObj, *src1Obj, *src2Obj;
    REGION * region;
    int width, height;
    BOOL res;
    
    dprintf_region(stddeb, "CombineRgn: %d %d %d %d\n", 
		   hDest, hSrc1, hSrc2, mode );
    
    if (!(destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC )))
	return ERROR;
    if (!(src1Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc1, REGION_MAGIC )))
	return ERROR;
    if (mode == RGN_COPY) return REGION_CopyRegion( src1Obj, destObj );

    if (!(src2Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc2, REGION_MAGIC )))
        return ERROR;
    region = &destObj->region;

      /* Some optimizations for null regions */

    if (src1Obj->region.type == NULLREGION)
    {
        switch(mode)
        {
        case RGN_AND:
        case RGN_DIFF:
            if (region->xrgn) XDestroyRegion( region->xrgn );
            if (region->pixmap) XFreePixmap( display, region->pixmap );
	    region->type = NULLREGION;
	    region->xrgn = 0;
	    return NULLREGION;
        case RGN_OR:
        case RGN_XOR:
            return REGION_CopyRegion( src2Obj, destObj );
	default:
	    return ERROR;
        }
    }
    else if (src2Obj->region.type == NULLREGION)
    {
        switch(mode)
        {
        case RGN_AND:
            if (region->xrgn) XDestroyRegion( region->xrgn );
            if (region->pixmap) XFreePixmap( display, region->pixmap );
	    region->type = NULLREGION;
	    region->xrgn = 0;
	    return NULLREGION;
        case RGN_OR:
        case RGN_XOR:
        case RGN_DIFF:
            return REGION_CopyRegion( src1Obj, destObj );
	default:
	    return ERROR;
        }
    }

    if (src1Obj->region.xrgn && src2Obj->region.xrgn)
    {
	/* Perform the operation with X regions */

	if (region->pixmap) XFreePixmap( display, region->pixmap );
	region->pixmap = 0;
	if (!region->xrgn) region->xrgn = XCreateRegion();
	switch(mode)
	{
	case RGN_AND:
	    XIntersectRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
			      region->xrgn );
	    break;
	case RGN_OR:
	    XUnionRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
			  region->xrgn );
	    break;
	case RGN_XOR:
	    XXorRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
			region->xrgn );
	    break;
	case RGN_DIFF:
	    XSubtractRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
			     region->xrgn );
	    break;
	default:
	    return ERROR;
	}
	if (XEmptyRegion(region->xrgn))
	{
            XDestroyRegion( region->xrgn );
	    region->type = NULLREGION;
	    region->xrgn = 0;
	    return NULLREGION;
	}
	else
	{
	    XRectangle rect;
	    XClipBox( region->xrgn, &rect );
	    region->type       = COMPLEXREGION;
	    region->box.left   = rect.x;
	    region->box.top    = rect.y;
	    region->box.right  = rect.x + rect.width;
	    region->box.bottom = rect.y + rect.height;
	    return COMPLEXREGION;
	}
    }
    else  /* Create pixmaps if needed */
    {
	if (!src1Obj->region.pixmap)
	    if (!REGION_MakePixmap( &src1Obj->region )) return ERROR;
	if (!src2Obj->region.pixmap)
	    if (!REGION_MakePixmap( &src2Obj->region )) return ERROR;
    }
    

    switch(mode)
    {
      case RGN_AND:
	res = IntersectRect( &region->box, &src1Obj->region.box,
			     &src2Obj->region.box );
	region->type = COMPLEXREGION;
	break;

      case RGN_OR:
      case RGN_XOR:
	res = UnionRect( &region->box, &src1Obj->region.box,
			 &src2Obj->region.box );
	region->type = COMPLEXREGION;
	break;

      case RGN_DIFF:
	res = SubtractRect( &region->box, &src1Obj->region.box,
			    &src2Obj->region.box );
	region->type = COMPLEXREGION;
	break;

      default:
	return ERROR;
    }

    if (region->pixmap) XFreePixmap( display, region->pixmap );
    if (region->xrgn) XDestroyRegion( region->xrgn );
    if (!res)
    {
	region->type   = NULLREGION;
	region->pixmap = 0;
	region->xrgn   = 0;
	return NULLREGION;
    }
    
    width  = region->box.right - region->box.left;
    height = region->box.bottom - region->box.top;
    if (!width || !height)
    {
	fprintf(stderr, "CombineRgn: width or height is 0. Please report this.\n" );
	fprintf(stderr, "src1=%d,%d-%d,%d  src2=%d,%d-%d,%d  dst=%d,%d-%d,%d  op=%d\n",
	        src1Obj->region.box.left, src1Obj->region.box.top,
	        src1Obj->region.box.right, src1Obj->region.box.bottom,
	        src2Obj->region.box.left, src2Obj->region.box.top,
	        src2Obj->region.box.right, src2Obj->region.box.bottom,
	        region->box.left, region->box.top,
	        region->box.right, region->box.bottom, mode );
	exit(1);
    }
    region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
    region->xrgn   = 0;

    switch(mode)
    {
      case RGN_AND:
	  XSetFunction( display, regionGC, GXcopy );
	  REGION_CopyIntersection( region, &src1Obj->region );
	  XSetFunction( display, regionGC, GXand );
	  REGION_CopyIntersection( region, &src2Obj->region );
	  break;

      case RGN_OR:
      case RGN_XOR:
	  XSetFunction( display, regionGC, GXclear );
	  XFillRectangle( display, region->pixmap, regionGC,
			  0, 0, width, height );
	  XSetFunction( display, regionGC, (mode == RGN_OR) ? GXor : GXxor);
	  REGION_CopyIntersection( region, &src1Obj->region );
	  REGION_CopyIntersection( region, &src2Obj->region );
	  break;
	  
      case RGN_DIFF:
	  XSetFunction( display, regionGC, GXclear );
	  XFillRectangle( display, region->pixmap, regionGC,
			  0, 0, width, height );
	  XSetFunction( display, regionGC, GXcopy );
	  REGION_CopyIntersection( region, &src1Obj->region );
	  XSetFunction( display, regionGC, GXandInverted );
	  REGION_CopyIntersection( region, &src2Obj->region );
	  break;
    }
    return region->type;
}
