309 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Id: s3gc.c,v 1.2 1999/11/02 06:16:29 keithp Exp $
 | |
|  *
 | |
|  * Copyright 1999 SuSE, Inc.
 | |
|  *
 | |
|  * 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, and that the name of SuSE not be used in advertising or
 | |
|  * publicity pertaining to distribution of the software without specific,
 | |
|  * written prior permission.  SuSE makes no representations about the
 | |
|  * suitability of this software for any purpose.  It is provided "as is"
 | |
|  * without express or implied warranty.
 | |
|  *
 | |
|  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 | |
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
 | |
|  * 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.
 | |
|  *
 | |
|  * Author:  Keith Packard, SuSE, Inc.
 | |
|  */
 | |
| /* $RCSId: xc/programs/Xserver/hw/kdrive/savage/s3gc.c,v 1.3 2000/01/21 01:12:02 dawes Exp $ */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include <config.h>
 | |
| #endif
 | |
| #include	"s3.h"
 | |
| #include	"s3draw.h"
 | |
| 
 | |
| #include	"Xmd.h"
 | |
| #include	"gcstruct.h"
 | |
| #include	"scrnintstr.h"
 | |
| #include	"pixmapstr.h"
 | |
| #include	"regionstr.h"
 | |
| #include	"mistruct.h"
 | |
| #include	"fontstruct.h"
 | |
| #include	"dixfontstr.h"
 | |
| #include	"migc.h"
 | |
| 
 | |
| /*
 | |
|  * Common op groups.  Common assumptions:
 | |
|  *
 | |
|  *  lineWidth	0
 | |
|  *  lineStyle	LineSolid
 | |
|  *  fillStyle	FillSolid
 | |
|  *  rop		GXcopy
 | |
|  *  font	<= 32 pixels wide
 | |
|  */
 | |
| 
 | |
| /* TE font */
 | |
| static const GCOps	s3TEOps = {
 | |
|     s3FillSpans,
 | |
|     KdCheckSetSpans,
 | |
|     KdCheckPutImage,
 | |
|     s3CopyArea,
 | |
|     s3CopyPlane,
 | |
|     KdCheckPolyPoint,
 | |
|     s3Polylines,
 | |
|     s3PolySegment,
 | |
|     KdCheckPolyRectangle,
 | |
|     KdCheckPolyArc,
 | |
|     s3FillPoly,
 | |
|     s3PolyFillRect,
 | |
|     s3PolyFillArcSolid,
 | |
|     miPolyText8,
 | |
|     miPolyText16,
 | |
|     miImageText8,
 | |
|     miImageText16,
 | |
|     s3ImageTEGlyphBlt,
 | |
|     s3PolyTEGlyphBlt,
 | |
|     s3PushPixels
 | |
| #ifdef NEED_LINEHELPER
 | |
|     ,NULL
 | |
| #endif
 | |
| };
 | |
| 
 | |
| /* Non TE font */
 | |
| static const GCOps	s3NonTEOps = {
 | |
|     s3FillSpans,
 | |
|     KdCheckSetSpans,
 | |
|     KdCheckPutImage,
 | |
|     s3CopyArea,
 | |
|     s3CopyPlane,
 | |
|     KdCheckPolyPoint,
 | |
|     s3Polylines,
 | |
|     s3PolySegment,
 | |
|     KdCheckPolyRectangle,
 | |
|     KdCheckPolyArc,
 | |
|     s3FillPoly,
 | |
|     s3PolyFillRect,
 | |
|     s3PolyFillArcSolid,
 | |
|     miPolyText8,
 | |
|     miPolyText16,
 | |
|     miImageText8,
 | |
|     miImageText16,
 | |
|     s3ImageGlyphBlt,
 | |
|     s3PolyGlyphBlt,
 | |
|     s3PushPixels
 | |
| #ifdef NEED_LINEHELPER
 | |
|     ,NULL
 | |
| #endif
 | |
| };
 | |
| 
 | |
| static GCOps *
 | |
| s3MatchCommon (DrawablePtr pDraw, GCPtr pGC, FbGCPrivPtr fbPriv)
 | |
| {
 | |
|     KdScreenPriv (pDraw->pScreen);
 | |
| 
 | |
|     if (!REGION_NOTEMPTY(pDraw->pScreen,fbGetCompositeClip(pGC)))
 | |
|     {
 | |
| 	DRAW_DEBUG ((DEBUG_CLIP, "Empty composite clip, clipping all ops"));
 | |
| 	return &kdNoopOps;
 | |
|     }
 | |
| 
 | |
|     if (pDraw->type != DRAWABLE_WINDOW)
 | |
| 	return (GCOps *) &kdAsyncPixmapGCOps;
 | |
|     
 | |
|     if (pGC->lineWidth != 0)
 | |
| 	return 0;
 | |
|     if (pGC->lineStyle != LineSolid)
 | |
| 	return 0;
 | |
|     if (pGC->fillStyle != FillSolid)
 | |
| 	return 0;
 | |
|     if (fbPriv->and != 0)
 | |
| 	return 0;
 | |
|     if (pGC->font)
 | |
|     {
 | |
| 	if (TERMINALFONT(pGC->font))
 | |
| 	    return (GCOps *) &s3TEOps;
 | |
| 	else
 | |
| 	    return (GCOps *) &s3NonTEOps;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| void
 | |
| s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
 | |
| {
 | |
|     int		new_type;	/* drawable type has changed */
 | |
|     int		new_origin;
 | |
|     
 | |
|     /* flags for changing the proc vector */
 | |
|     FbGCPrivPtr fbPriv;
 | |
|     s3PrivGCPtr	s3Priv;
 | |
|     int		oneRect;
 | |
|     GCOps	*newops;
 | |
|     
 | |
|     fbPriv = fbGetGCPrivate(pGC);
 | |
|     s3Priv = s3GetGCPrivate(pGC);
 | |
| 
 | |
|     new_type = FALSE;
 | |
|     new_origin = FALSE;
 | |
| 
 | |
|     /*
 | |
|      * If the type of drawable has changed, fix up accelerated functions
 | |
|      */
 | |
|     if (s3Priv->type != pDrawable->type)
 | |
|     {
 | |
| 	new_type = TRUE;
 | |
| 	s3Priv->type = pDrawable->type;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Check tile/stipple origin
 | |
|      */
 | |
|     if (pGC->lastWinOrg.x != pDrawable->x || pGC->lastWinOrg.y != pDrawable->y)
 | |
| 	new_origin = TRUE;
 | |
|     
 | |
|     /*
 | |
|      * Call down to FB to set clip list and rrop values
 | |
|      */
 | |
|     
 | |
|     fbValidateGC (pGC, changes, pDrawable);
 | |
|     
 | |
|     /*
 | |
|      * Check accelerated pattern if necessary
 | |
|      */
 | |
|     if (changes & (GCFillStyle|GCStipple|GCTile))
 | |
| 	s3CheckGCFill (pGC);
 | |
|     else if (s3Priv->pPattern && 
 | |
| 	     (new_origin || changes & (GCTileStipXOrigin|GCTileStipYOrigin)))
 | |
| 	s3MoveGCFill (pGC);
 | |
| 
 | |
|     /*
 | |
|      * Try to match common vector
 | |
|      */
 | |
|     
 | |
|     if (newops = s3MatchCommon (pDrawable, pGC, fbPriv))
 | |
|     {
 | |
| 	if (pGC->ops->devPrivate.val)
 | |
| 	    miDestroyGCOps (pGC->ops);
 | |
| 	pGC->ops = newops;
 | |
| 	return;
 | |
|     }
 | |
|     
 | |
|     /*
 | |
|      * No common vector matched, create private ops vector and
 | |
|      * fill it in
 | |
|      */
 | |
|     if (!pGC->ops->devPrivate.val)
 | |
|     {
 | |
| 	/*
 | |
| 	 * Switch from noop vector by first switching to fb
 | |
| 	 * vector and fixing it up
 | |
| 	 */
 | |
| 	if (pGC->ops == &kdNoopOps)
 | |
| 	{
 | |
| 	    pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
 | |
| 	    new_type = TRUE;
 | |
| 	}
 | |
|         pGC->ops = miCreateGCOps (pGC->ops);
 | |
|         pGC->ops->devPrivate.val = 1;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Fills
 | |
|      */
 | |
|     if (new_type || (changes & (GCFillStyle|GCTile|GCStipple)))
 | |
|     {
 | |
|         pGC->ops->FillSpans = KdCheckFillSpans;
 | |
| 	pGC->ops->PolyFillRect = KdCheckPolyFillRect;
 | |
| 	if (s3Priv->type == DRAWABLE_WINDOW &&
 | |
| 	    (pGC->fillStyle != FillTiled || s3Priv->pPattern))
 | |
| 	{
 | |
| 	    pGC->ops->FillSpans = s3FillSpans;
 | |
| 	    pGC->ops->PolyFillRect = s3PolyFillRect;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Blt
 | |
|      */
 | |
|     if (new_type)
 | |
|     {
 | |
| 	pGC->ops->CopyArea = s3CopyArea;
 | |
| 	pGC->ops->CopyPlane = s3CopyPlane;
 | |
| 	pGC->ops->PushPixels = s3PushPixels;
 | |
|     }
 | |
|     
 | |
|     /*
 | |
|      * Lines
 | |
|      */
 | |
|     if (new_type || (changes & (GCLineStyle|GCLineWidth|GCFillStyle)))
 | |
|     {
 | |
| 	pGC->ops->Polylines = KdCheckPolylines;
 | |
| 	pGC->ops->PolySegment = KdCheckPolySegment;
 | |
| 	if (pGC->lineStyle == LineSolid &&
 | |
| 	    pGC->lineWidth == 0 &&
 | |
| 	    pGC->fillStyle == FillSolid &&
 | |
| 	    s3Priv->type == DRAWABLE_WINDOW)
 | |
| 	{
 | |
| 	    pGC->ops->Polylines = s3Polylines;
 | |
| 	    pGC->ops->PolySegment = s3PolySegment;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Polygons
 | |
|      */
 | |
|     if (new_type || (changes & (GCFillStyle)))
 | |
|     {
 | |
| 	pGC->ops->FillPolygon = KdCheckFillPolygon;
 | |
| 	if (s3Priv->type == DRAWABLE_WINDOW &&
 | |
| 	    pGC->fillStyle == FillSolid)
 | |
| 	{
 | |
| 	    pGC->ops->FillPolygon = s3FillPoly;
 | |
| 	}
 | |
|     }
 | |
| 	
 | |
|     /*
 | |
|      * Filled arcs
 | |
|      */
 | |
|     if (new_type || (changes & GCFillStyle))
 | |
|     {
 | |
| 	pGC->ops->PolyFillArc = KdCheckPolyFillArc;
 | |
| 	if (s3Priv->type == DRAWABLE_WINDOW &&
 | |
| 	    pGC->fillStyle == FillSolid)
 | |
| 	{
 | |
| 	    pGC->ops->PolyFillArc = s3PolyFillArcSolid;
 | |
| 	}
 | |
|     }
 | |
|     
 | |
|     /*
 | |
|      * Text
 | |
|      */
 | |
|     if (new_type || (changes & (GCFont|GCFillStyle)))
 | |
|     {
 | |
| 	pGC->ops->PolyGlyphBlt = KdCheckPolyGlyphBlt;
 | |
| 	pGC->ops->ImageGlyphBlt = KdCheckImageGlyphBlt;
 | |
| 	if (s3Priv->type == DRAWABLE_WINDOW && pGC->font)
 | |
| 	{
 | |
| 	    if (pGC->fillStyle == FillSolid)
 | |
| 	    {
 | |
| 		if (TERMINALFONT(pGC->font))
 | |
| 		    pGC->ops->PolyGlyphBlt = s3PolyTEGlyphBlt;
 | |
| 		else
 | |
| 		    pGC->ops->PolyGlyphBlt = s3PolyGlyphBlt;
 | |
| 	    }
 | |
| 	    if (TERMINALFONT(pGC->font))
 | |
| 		pGC->ops->ImageGlyphBlt = s3ImageTEGlyphBlt;
 | |
| 	    else
 | |
| 		pGC->ops->ImageGlyphBlt = s3ImageGlyphBlt;
 | |
|         }
 | |
|     }    
 | |
| }
 |