Annotation of researchv9/X11/src/X.V11R1/server/dix/gc.c, revision 1.1

1.1     ! root        1: /***********************************************************
        !             2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
        !             3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
        !             4: 
        !             5:                         All Rights Reserved
        !             6: 
        !             7: Permission to use, copy, modify, and distribute this software and its 
        !             8: documentation for any purpose and without fee is hereby granted, 
        !             9: provided that the above copyright notice appear in all copies and that
        !            10: both that copyright notice and this permission notice appear in 
        !            11: supporting documentation, and that the names of Digital or MIT not be
        !            12: used in advertising or publicity pertaining to distribution of the
        !            13: software without specific, written prior permission.  
        !            14: 
        !            15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            21: SOFTWARE.
        !            22: 
        !            23: ******************************************************************/
        !            24: 
        !            25: /* $Header: gc.c,v 1.95 87/09/03 15:52:13 toddb Exp $ */
        !            26: 
        !            27: #include "X.h"
        !            28: #include "Xmd.h"
        !            29: #include "Xproto.h"
        !            30: #include "misc.h"
        !            31: #include "resource.h"
        !            32: #include "gcstruct.h"
        !            33: #include "pixmapstr.h"
        !            34: #include "dixfontstr.h"
        !            35: #include "scrnintstr.h"
        !            36: #include "region.h"
        !            37: 
        !            38: #include "dix.h"
        !            39: 
        !            40: extern int NotImplemented();
        !            41: 
        !            42: /* written by drewry august 1986 */
        !            43: 
        !            44: void
        !            45: ValidateGC(pDraw, pGC)
        !            46:     DrawablePtr        pDraw;
        !            47:     GC         *pGC;
        !            48: {
        !            49:     GCInterestPtr      pQ, pQInit;
        !            50: 
        !            51:     pQ = pGC->pNextGCInterest;
        !            52:     pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
        !            53:     if (pGC->serialNumber != pDraw->serialNumber)
        !            54:         pGC->stateChanges |= GC_CALL_VALIDATE_BIT;
        !            55:     do
        !            56:     {
        !            57:        if (pQ->ValInterestMask & pGC->stateChanges)
        !            58:            (* pQ->ValidateGC) (pGC, pQ, pGC->stateChanges, pDraw);
        !            59:        pQ = pQ->pNextGCInterest;
        !            60:     }
        !            61:     while(pQ != pQInit);
        !            62:     pGC->stateChanges = 0;
        !            63:     pGC->serialNumber = pDraw->serialNumber;
        !            64: }
        !            65: 
        !            66: 
        !            67: 
        !            68: /* Publically defined entry to ChangeGC.  Just calls DoChangeGC and tells
        !            69:  * it that all of the entries are constants or IDs */
        !            70: ChangeGC(pGC, mask, pval)
        !            71:     register GC        *pGC;
        !            72:     register BITS32    mask;
        !            73:     CARD32             *pval;
        !            74: {
        !            75:     return (DoChangeGC(pGC, mask, pval, 0));
        !            76: }
        !            77: /* DoChangeGC(pGC, mask, pval, fPointer)
        !            78:    mask is a set of bits indicating which values to change.
        !            79:    pval contains an appropriate value for each mask.
        !            80:    fPointer is true if the values for tiles, stipples, fonts or clipmasks
        !            81:    are pointers instead of IDs.  
        !            82:    if there is an error, the value is marked as changed 
        !            83:    anyway, which is probably wrong, but infrequent.
        !            84: 
        !            85: NOTE:
        !            86:        all values sent over the protocol for ChangeGC requests are
        !            87: 32 bits long
        !            88: */
        !            89: 
        !            90: int
        !            91: DoChangeGC(pGC, mask, pval, fPointer)
        !            92:     register GC        *pGC;
        !            93:     register BITS32    mask;
        !            94:     CARD32             *pval;
        !            95:     int                        fPointer;
        !            96: {
        !            97:     register int       index;
        !            98:     register int       error = 0;
        !            99:     PixmapPtr          pPixmap;
        !           100:     BITS32             maskQ;
        !           101:     GCInterestPtr      pQ, pQInit;
        !           102: 
        !           103:     pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
        !           104: 
        !           105:     maskQ = mask;      /* save these for when we walk the GCque */
        !           106:     while (mask && !error) 
        !           107:     {
        !           108:        index = ffs(mask) - 1;
        !           109:        mask &= ~(index = (1 << index));
        !           110:        pGC->stateChanges |= index;
        !           111:        switch (index)
        !           112:        {
        !           113:            case GCFunction:
        !           114:                if (((CARD8)*pval >= GXclear) && ((CARD8)*pval <= GXset))
        !           115:                    pGC->alu = (CARD8)*pval;
        !           116:                else
        !           117:                    error = BadValue;
        !           118:                pval++;
        !           119:                break;
        !           120:            case GCPlaneMask:
        !           121:                pGC->planemask = *pval++;
        !           122:                break;
        !           123:            case GCForeground:
        !           124:                pGC->fgPixel = *pval++;
        !           125:                break;
        !           126:            case GCBackground:
        !           127:                pGC->bgPixel = *pval++;
        !           128:                break;
        !           129:            case GCLineWidth:           /* ??? line width is a CARD16 */
        !           130:                pGC->lineWidth = (CARD16)*pval;
        !           131:                 pval++;
        !           132:                break;
        !           133:            case GCLineStyle:
        !           134:                if (((CARD8)*pval >= LineSolid) 
        !           135:                    && ((CARD8)*pval <= LineDoubleDash))
        !           136:                    pGC->lineStyle = (CARD8)*pval;
        !           137:                else
        !           138:                    error = BadValue;
        !           139:                pval++;
        !           140:                break;
        !           141:            case GCCapStyle:
        !           142:                if (((CARD8)*pval >= CapNotLast) 
        !           143:                    && ((CARD8)*pval <= CapProjecting))
        !           144:                    pGC->capStyle = (CARD8)*pval;
        !           145:                else
        !           146:                    error = BadValue;
        !           147:                pval++;
        !           148:                break;
        !           149:            case GCJoinStyle:
        !           150:                if (((CARD8)*pval >= JoinMiter) && ((CARD8)*pval <= JoinBevel))
        !           151:                    pGC->joinStyle = (CARD8)*pval;
        !           152:                else
        !           153:                    error = BadValue;
        !           154:                pval++;
        !           155:                break;
        !           156:            case GCFillStyle:
        !           157:                if (((CARD8)*pval >= FillSolid) 
        !           158:                    && ((CARD8)*pval <= FillOpaqueStippled))
        !           159:                    pGC->fillStyle = (CARD8)*pval;
        !           160:                else
        !           161:                    error = BadValue;
        !           162:                pval++;
        !           163:                break;
        !           164:            case GCFillRule:
        !           165:                if (((CARD8)*pval >= EvenOddRule) && 
        !           166:                    ((CARD8)*pval <= WindingRule))
        !           167:                    pGC->fillRule = (CARD8)*pval;
        !           168:                else
        !           169:                    error = BadValue;
        !           170:                pval++;
        !           171:                break;
        !           172:            case GCTile:
        !           173:                if(fPointer)
        !           174:                    pPixmap = (PixmapPtr) *pval;
        !           175:                else
        !           176:                    pPixmap = (PixmapPtr)LookupID((CARD32)*pval, 
        !           177:                                              RT_PIXMAP, RC_CORE);
        !           178:                pval++;
        !           179:                if (pPixmap)
        !           180:                {
        !           181:                    if ((pPixmap->drawable.depth != pGC->depth) ||
        !           182:                        (pPixmap->drawable.pScreen != pGC->pScreen))
        !           183:                    {
        !           184:                        error = BadMatch;
        !           185:                    }
        !           186:                    else
        !           187:                    {
        !           188:                        (* pGC->pScreen->DestroyPixmap)(pGC->tile);
        !           189:                        pGC->tile = pPixmap;
        !           190:                        pPixmap->refcnt++;
        !           191:                    }
        !           192:                }
        !           193:                else
        !           194:                    error = BadPixmap;
        !           195:                break;
        !           196:            case GCStipple:
        !           197:                if(fPointer)
        !           198:                    pPixmap = (PixmapPtr) *pval;
        !           199:                else
        !           200:                    pPixmap = (PixmapPtr)LookupID((CARD32)*pval, 
        !           201:                                              RT_PIXMAP, RC_CORE);
        !           202:                pval++;
        !           203:                if (pPixmap)
        !           204:                {
        !           205:                    if ((pPixmap->drawable.depth != 1) ||
        !           206:                        (pPixmap->drawable.pScreen != pGC->pScreen))
        !           207:                    {
        !           208:                        error = BadMatch;
        !           209:                    }
        !           210:                    else
        !           211:                    {
        !           212:                        (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
        !           213:                        pGC->stipple = pPixmap;
        !           214:                        pPixmap->refcnt++;
        !           215:                    }
        !           216:                }
        !           217:                else
        !           218:                    error = BadPixmap;
        !           219:                break;
        !           220:            case GCTileStipXOrigin:
        !           221:                pGC->patOrg.x = (INT16)*pval;
        !           222:                 pval++;
        !           223:                break;
        !           224:            case GCTileStipYOrigin:
        !           225:                pGC->patOrg.y = (INT16)*pval;
        !           226:                pval++;
        !           227:                break;
        !           228:            case GCFont:
        !           229:               {
        !           230:                CARD32 fid;
        !           231:                FontPtr pFont;
        !           232: 
        !           233: 
        !           234:                if(fPointer)
        !           235:                    pFont = (FontPtr) *pval++;
        !           236:                else
        !           237:                {
        !           238:                    fid = * pval++;
        !           239:                    pFont = (FontPtr)LookupID(fid, RT_FONT, RC_CORE);
        !           240:                }
        !           241: 
        !           242:                if (pFont)
        !           243:                {
        !           244:                    if (pGC->font)
        !           245:                        CloseFont( pGC->font);
        !           246:                    pGC->font = pFont;
        !           247:                    pGC->font->refcnt++;
        !           248:                 }
        !           249:                else
        !           250:                    error = BadFont;
        !           251:                break;
        !           252:              }
        !           253:            case GCSubwindowMode:
        !           254:                if ((*pval == ClipByChildren) ||
        !           255:                    (*pval == IncludeInferiors))
        !           256:                    pGC->subWindowMode = (CARD8)(*pval);
        !           257:                else
        !           258:                    error = BadValue;
        !           259:                pval++;
        !           260:                break;
        !           261:            case GCGraphicsExposures:
        !           262:                if ((Bool)*pval == xFalse)
        !           263:                    pGC->graphicsExposures = FALSE;
        !           264:                else if ((Bool)*pval == xTrue)
        !           265:                    pGC->graphicsExposures = TRUE;
        !           266:                else
        !           267:                    error = BadValue;
        !           268:                pval++;
        !           269:                break;
        !           270:            case GCClipXOrigin:
        !           271:                pGC->clipOrg.x = (INT16)(*pval);
        !           272:                pval++;
        !           273:                break;
        !           274:            case GCClipYOrigin:
        !           275:                pGC->clipOrg.y = (INT16)(*pval);
        !           276:                pval++;
        !           277:                break;
        !           278:            case GCClipMask:
        !           279:              {
        !           280:                Pixmap pid;
        !           281:                int     clipType;
        !           282: 
        !           283:                pid = (Pixmap) *pval;
        !           284:                if (pid == None)
        !           285:                {
        !           286:                    clipType = CT_NONE;
        !           287:                }
        !           288:                else
        !           289:                {
        !           290:                    if(fPointer)
        !           291:                        pPixmap = (PixmapPtr) pval;
        !           292:                    else
        !           293:                        pPixmap = (PixmapPtr)LookupID(pid, RT_PIXMAP, RC_CORE);
        !           294:                    if (pPixmap)
        !           295:                    {
        !           296:                        clipType = CT_PIXMAP;
        !           297:                        pPixmap->refcnt++;
        !           298:                    }
        !           299:                    else
        !           300:                        error = BadPixmap;
        !           301:                }
        !           302:                pval++;
        !           303:                if(error == Success)
        !           304:                {
        !           305:                    (*pGC->ChangeClip)(pGC, clipType, pPixmap, 0);
        !           306:                }
        !           307:                break;
        !           308:              }
        !           309:            case GCDashOffset:
        !           310:                pGC->dashOffset = (CARD16)*pval;
        !           311:                pval++;
        !           312:                break;
        !           313:            case GCDashList:
        !           314:                Xfree(pGC->dash);
        !           315:                pGC->numInDashList = 2;
        !           316:                pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char));
        !           317:                pGC->dash[0] = (CARD8)(*pval);
        !           318:                pGC->dash[1] = (CARD8)(*pval++);
        !           319:                break;
        !           320:            case GCArcMode:
        !           321:                if (((CARD8)*pval >= ArcChord) 
        !           322:                    && ((CARD8)*pval <= ArcPieSlice))
        !           323:                    pGC->arcMode = (CARD8)*pval;
        !           324:                else
        !           325:                    error = BadValue;
        !           326:                pval++;
        !           327:                break;
        !           328:            default:
        !           329:                break;
        !           330:        }
        !           331:     }
        !           332:     pQ = pGC->pNextGCInterest;
        !           333:     pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
        !           334:     do
        !           335:     {
        !           336:        /* I assume that if you've set a change interest mask, you've set a
        !           337:         * changeGC function */
        !           338:        if(pQ->ChangeInterestMask & maskQ)
        !           339:            (*pQ->ChangeGC)(pGC, pQ, maskQ);
        !           340:        pQ = pQ->pNextGCInterest;
        !           341:     }
        !           342:     while(pQ != pQInit);
        !           343:     return error;
        !           344: }
        !           345: 
        !           346: /* CreateGC(pDrawable, mask, pval, pStatus)
        !           347:    creates a default GC for the given drawable, using mask to fill
        !           348:    in any non-default values.
        !           349:    Returns a pointer to the new GC on success, NULL otherwise.
        !           350:    returns status of non-default fields in pStatus
        !           351: BUG:
        !           352:    should check for failure to create default tile and stipple
        !           353:    should be able to set the tile before the call the (pScreen->ChangeGC)
        !           354:        as it is, we must call ChangeGC twice.
        !           355: 
        !           356: */
        !           357: 
        !           358: GC *
        !           359: CreateGC(pDrawable, mask, pval, pStatus)
        !           360:     DrawablePtr        pDrawable;
        !           361:     BITS32     mask;
        !           362:     long       *pval;
        !           363:     BITS32     *pStatus;
        !           364: {
        !           365:     register GC *pGC;
        !           366:     extern FontPtr defaultFont;
        !           367:     CARD32     tmpval[3];
        !           368:     PixmapPtr  pTile;
        !           369:     GCPtr pgcScratch;  /* for drawing into default tile and stipple */
        !           370:     xRectangle rect;
        !           371: #ifdef DEBUG
        !           372:     void       (**j)();
        !           373: #endif /* DEBUG */
        !           374: 
        !           375:     pGC = (GC *)Xalloc(sizeof(GC));
        !           376:     if (!pGC)
        !           377:        return (GC *)NULL;
        !           378: 
        !           379: #ifdef DEBUG
        !           380:     for(j = &pGC->FillSpans;
        !           381:         j < &pGC->PushPixels;
        !           382:         j++ )
        !           383:         *j = (void (*) ())NotImplemented;
        !           384: #endif /* DEBUG */
        !           385: 
        !           386:     pGC->pScreen = pDrawable->pScreen;
        !           387:     pGC->depth = pDrawable->depth;
        !           388:     pGC->alu = GXcopy; /* dst <- src */
        !           389:     pGC->planemask = ~0;
        !           390:     pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
        !           391: 
        !           392:     pGC->fgPixel = 0;
        !           393:     pGC->bgPixel = 1;
        !           394:     pGC->lineWidth = 0;
        !           395:     pGC->lineStyle = LineSolid;
        !           396:     pGC->capStyle = CapButt;
        !           397:     pGC->joinStyle = JoinMiter;
        !           398:     pGC->fillStyle = FillSolid;
        !           399:     pGC->fillRule = EvenOddRule;
        !           400:     pGC->arcMode = ArcPieSlice;
        !           401:     pGC->font = defaultFont;
        !           402:     if ( pGC->font)  /* necessary, because open of default font could fail */
        !           403:        pGC->font->refcnt++;
        !           404:     pGC->tile = NullPixmap;
        !           405: 
        !           406:     /* use the default stipple */
        !           407:     pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
        !           408:     pGC->stipple->refcnt++;
        !           409:     pGC->patOrg.x = 0;
        !           410:     pGC->patOrg.y = 0;
        !           411:     pGC->subWindowMode = ClipByChildren;
        !           412:     pGC->graphicsExposures = TRUE;
        !           413:     pGC->clipOrg.x = 0;
        !           414:     pGC->clipOrg.y = 0;
        !           415:     pGC->clientClipType = CT_NONE;
        !           416:     pGC->clientClip = (pointer)NULL;
        !           417:     pGC->numInDashList = 2;
        !           418:     pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char));
        !           419:     pGC->dash[0] = 4;
        !           420:     pGC->dash[1] = 4;
        !           421:     pGC->dashOffset = 0;
        !           422: 
        !           423:     pGC->stateChanges = (1 << GCLastBit+1) - 1;
        !           424:     (*pGC->pScreen->CreateGC)(pGC);
        !           425:     if(mask)
        !           426:         *pStatus = ChangeGC(pGC, mask, pval);
        !           427:     else
        !           428:        *pStatus = Success;
        !           429: 
        !           430:     /* if the client hasn't provided a tile, build one and fill it with
        !           431:        the foreground pixel
        !           432:     */
        !           433:     if (!pGC->tile)
        !           434:     {
        !           435:        int w, h;
        !           436: 
        !           437:        w = 16;
        !           438:        h = 16;
        !           439:        (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h);
        !           440:        pTile = (PixmapPtr)
        !           441:                (*pGC->pScreen->CreatePixmap)(pDrawable->pScreen,
        !           442:                                              w, h, pGC->depth);
        !           443:        tmpval[0] = GXcopy;
        !           444:        tmpval[1] = pGC->fgPixel;
        !           445:        tmpval[2] = FillSolid;
        !           446:        pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
        !           447:        ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle, 
        !           448:                 tmpval);
        !           449:        ValidateGC(pTile, pgcScratch);
        !           450:        rect.x = 0;
        !           451:        rect.y = 0;
        !           452:        rect.width = w;
        !           453:        rect.height = h;
        !           454:        (*pgcScratch->PolyFillRect)(pTile, pgcScratch,
        !           455:                                         1, &rect);
        !           456:        /* Always remember to free the scratch graphics context after use. */
        !           457:        FreeScratchGC(pgcScratch);
        !           458: 
        !           459:        /*
        !           460:         * Unfortunately, we must call ChangeGC a second time to get
        !           461:         * the tile installed.  This would be nice to do before the first
        !           462:         * call to ChangeGC, but we don't know the value of the
        !           463:         * foreground pixel until afterwards.
        !           464:         */
        !           465:        DoChangeGC(pGC, GCTile, (CARD32 *)&pTile, TRUE);
        !           466:     }
        !           467:     return (pGC);
        !           468: }
        !           469: 
        !           470: 
        !           471: void
        !           472: CopyGC(pgcSrc, pgcDst, mask)
        !           473:     register GC                *pgcSrc;
        !           474:     register GC                *pgcDst;
        !           475:     register int       mask;
        !           476: {
        !           477:     register int       index;
        !           478:     int                        maskQ;
        !           479:     GCInterestPtr      pQ, pQInit;
        !           480:     int i;
        !           481: 
        !           482:     pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
        !           483:     pgcDst->stateChanges |= mask;
        !           484:     maskQ = mask;
        !           485:     while (mask)
        !           486:     {
        !           487:        index = ffs(mask) - 1;
        !           488:        mask &= ~(index = (1 << index));
        !           489:        switch (index)
        !           490:        {
        !           491:            case GCFunction:
        !           492:                pgcDst->alu = pgcSrc->alu;
        !           493:                break;
        !           494:            case GCPlaneMask:
        !           495:                pgcDst->planemask = pgcSrc->planemask;
        !           496:                break;
        !           497:            case GCForeground:
        !           498:                pgcDst->fgPixel = pgcSrc->fgPixel;
        !           499:                break;
        !           500:            case GCBackground:
        !           501:                pgcDst->bgPixel = pgcSrc->bgPixel;
        !           502:                break;
        !           503:            case GCLineWidth:
        !           504:                pgcDst->lineWidth = pgcSrc->lineWidth;
        !           505:                break;
        !           506:            case GCLineStyle:
        !           507:                pgcDst->lineStyle = pgcSrc->lineStyle;
        !           508:                break;
        !           509:            case GCCapStyle:
        !           510:                pgcDst->capStyle = pgcSrc->capStyle;
        !           511:                break;
        !           512:            case GCJoinStyle:
        !           513:                pgcDst->joinStyle = pgcSrc->joinStyle;
        !           514:                break;
        !           515:            case GCFillStyle:
        !           516:                pgcDst->fillStyle = pgcSrc->fillStyle;
        !           517:                break;
        !           518:            case GCFillRule:
        !           519:                pgcDst->fillRule = pgcSrc->fillRule;
        !           520:                break;
        !           521:            case GCTile:
        !           522:                {
        !           523:                    if (pgcDst->tile == pgcSrc->tile)
        !           524:                        break;
        !           525:                    (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile);
        !           526:                    pgcDst->tile = pgcSrc->tile;
        !           527:                    if (IS_VALID_PIXMAP(pgcDst->tile))
        !           528:                       pgcDst->tile->refcnt ++;
        !           529:                    break;
        !           530:                }
        !           531:            case GCStipple:
        !           532:                {
        !           533:                    if (pgcDst->stipple = pgcSrc->stipple)
        !           534:                        break;
        !           535:                    (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
        !           536:                    pgcDst->stipple = pgcSrc->stipple;
        !           537:                    if (IS_VALID_PIXMAP(pgcDst->stipple))
        !           538:                        pgcDst->stipple->refcnt ++;
        !           539:                    break;
        !           540:                }
        !           541:            case GCTileStipXOrigin:
        !           542:                pgcDst->patOrg.x = pgcSrc->patOrg.x;
        !           543:                break;
        !           544:            case GCTileStipYOrigin:
        !           545:                pgcDst->patOrg.y = pgcSrc->patOrg.y;
        !           546:                break;
        !           547:            case GCFont:
        !           548:                if (pgcDst->font == pgcSrc->font)
        !           549:                    break;
        !           550:                if (pgcDst->font)
        !           551:                    CloseFont(pgcDst->font);
        !           552:                if ((pgcDst->font = pgcSrc->font) != NullFont)
        !           553:                    (pgcDst->font)->refcnt++;
        !           554:                break;
        !           555:            case GCSubwindowMode:
        !           556:                pgcDst->subWindowMode = pgcSrc->subWindowMode;
        !           557:                break;
        !           558:            case GCGraphicsExposures:
        !           559:                pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
        !           560:                break;
        !           561:            case GCClipXOrigin:
        !           562:                pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
        !           563:                break;
        !           564:            case GCClipYOrigin:
        !           565:                pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
        !           566:                break;
        !           567:            case GCClipMask:
        !           568:                (* pgcDst->CopyClip)(pgcDst, pgcSrc);
        !           569:                break;
        !           570:            case GCDashOffset:
        !           571:                pgcDst->dashOffset = pgcSrc->dashOffset;
        !           572:                break;
        !           573:            case GCDashList:
        !           574:                Xfree(pgcDst->dash);
        !           575:                pgcDst->dash = (unsigned char *)
        !           576:                                Xalloc(2 * sizeof(unsigned char));
        !           577:                pgcDst->numInDashList = pgcSrc->numInDashList;
        !           578:                for (i=0; i<pgcSrc->numInDashList; i++)
        !           579:                    pgcDst->dash[i] = pgcSrc->dash[i];
        !           580:                break;
        !           581:            case GCArcMode:
        !           582:                pgcDst->arcMode = pgcSrc->arcMode;
        !           583:                break;
        !           584:            default:
        !           585:                break;
        !           586:        }
        !           587:     }
        !           588:     pQ = pgcSrc->pNextGCInterest;
        !           589:     pQInit = (GCInterestPtr) &pgcSrc->pNextGCInterest;
        !           590:     do
        !           591:     {
        !           592:        if(pQ->CopyGCSource)
        !           593:            (*pQ->CopyGCSource)(pgcSrc, pQ, maskQ, pgcDst);
        !           594:        pQ = pQ->pNextGCInterest;
        !           595:     }
        !           596:     while(pQ != pQInit);
        !           597:     pQ = pgcDst->pNextGCInterest;
        !           598:     pQInit = (GCInterestPtr) &pgcDst->pNextGCInterest;
        !           599:     do
        !           600:     {
        !           601:        if(pQ->CopyGCDest)
        !           602:            (*pQ->CopyGCDest)(pgcDst, pQ, maskQ, pgcSrc);
        !           603:        pQ = pQ->pNextGCInterest;
        !           604:     }
        !           605:     while(pQ != pQInit);
        !           606: }
        !           607: 
        !           608: /*****************
        !           609:  * FreeGC 
        !           610:  *   does the diX part of freeing the characteristics in the GC 
        !           611:  ***************/
        !           612: 
        !           613: void
        !           614: FreeGC(pGC, gid)
        !           615:     GC *pGC;
        !           616:     int gid;
        !           617: {
        !           618:     GCInterestPtr      pQ, pQInit, pQnext;
        !           619: 
        !           620:     CloseFont(pGC->font);
        !           621:     (* pGC->DestroyClip)(pGC);
        !           622: 
        !           623:     (* pGC->pScreen->DestroyPixmap)(pGC->tile);
        !           624:     (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
        !           625: 
        !           626:     pQ = pGC->pNextGCInterest;
        !           627:     pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
        !           628:     do
        !           629:     {
        !           630:         pQnext = pQ->pNextGCInterest;
        !           631:        if(pQ->DestroyGC)
        !           632:            (*pQ->DestroyGC) (pGC, pQ);
        !           633:        pQ = pQnext;
        !           634:     }
        !           635:     while(pQ != pQInit);
        !           636:     Xfree(pGC->dash);
        !           637:     Xfree(pGC);
        !           638: }
        !           639: 
        !           640: void
        !           641: SetGCMask(pGC, selectMask, newDataMask)
        !           642:     GCPtr pGC;
        !           643:     Mask selectMask;
        !           644:     Mask newDataMask;
        !           645: {
        !           646:     pGC->stateChanges = (~selectMask & pGC->stateChanges) |
        !           647:                        (selectMask & newDataMask);
        !           648:     if (selectMask & newDataMask)
        !           649:         pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;        
        !           650: }
        !           651: 
        !           652: 
        !           653: 
        !           654: /* CreateScratchGC(pScreen, depth)
        !           655:     like CreateGC, but doesn't do the default tile or stipple,
        !           656: since we can't create them without already having a GC.  any code
        !           657: using the tile or stipple has to set them explicitly anyway,
        !           658: since the state of the scratch gc is unknown.  This is OK
        !           659: because ChangeGC() has to be able to deal with NULL tiles and
        !           660: stipples anyway (in case the CreateGC() call has provided a 
        !           661: value for them -- we can't set the default tile until the
        !           662: client-supplied attributes are installed, since the fgPixel
        !           663: is what fills the default tile.  (maybe this comment should
        !           664: go with CreateGC() or ChangeGC().)
        !           665: */
        !           666: 
        !           667: GC *
        !           668: CreateScratchGC(pScreen, depth)
        !           669:     ScreenPtr pScreen;
        !           670:     int depth;
        !           671: {
        !           672:     register GC *pGC;
        !           673:     extern FontPtr defaultFont;
        !           674: #ifdef DEBUG
        !           675:     void       (**j)();
        !           676: #endif /* DEBUG */
        !           677: 
        !           678:     pGC = (GC *)Xalloc(sizeof(GC));
        !           679:     if (!pGC)
        !           680:        return (GC *)NULL;
        !           681: 
        !           682: #ifdef DEBUG
        !           683:     for(j = &pGC->FillSpans;
        !           684:         j < &pGC->PushPixels;
        !           685:         j++ )
        !           686:         *j = (void (*) ())NotImplemented;
        !           687: #endif /* DEBUG */
        !           688: 
        !           689:     pGC->pScreen = pScreen;
        !           690:     pGC->depth = depth;
        !           691:     pGC->alu = GXcopy; /* dst <- src */
        !           692:     pGC->planemask = ~0;
        !           693:     pGC->serialNumber = 0;
        !           694: 
        !           695:     pGC->fgPixel = 0;
        !           696:     pGC->bgPixel = 1;
        !           697:     pGC->lineWidth = 0;
        !           698:     pGC->lineStyle = LineSolid;
        !           699:     pGC->capStyle = CapButt;
        !           700:     pGC->joinStyle = JoinMiter;
        !           701:     pGC->fillStyle = FillSolid;
        !           702:     pGC->fillRule = EvenOddRule;
        !           703:     pGC->arcMode = ArcPieSlice;
        !           704:     pGC->font = defaultFont;
        !           705:     if ( pGC->font)  /* necessary, because open of default font could fail */
        !           706:        pGC->font->refcnt++;
        !           707:     pGC->tile = NullPixmap;
        !           708:     pGC->stipple = NullPixmap;
        !           709:     pGC->patOrg.x = 0;
        !           710:     pGC->patOrg.y = 0;
        !           711:     pGC->subWindowMode = ClipByChildren;
        !           712:     pGC->graphicsExposures = TRUE;
        !           713:     pGC->clipOrg.x = 0;
        !           714:     pGC->clipOrg.y = 0;
        !           715:     pGC->clientClipType = CT_NONE;
        !           716:     pGC->numInDashList = 2;
        !           717:     pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char));
        !           718:     pGC->dash[0] = 4;
        !           719:     pGC->dash[1] = 4;
        !           720:     pGC->dashOffset = 0;
        !           721: 
        !           722:     pGC->stateChanges = (1 << GCLastBit+1) - 1;
        !           723:     (*pScreen->CreateGC)(pGC);
        !           724:     return pGC;
        !           725: }
        !           726: 
        !           727: 
        !           728: FreeGCperDepth(screenNum)
        !           729:     int screenNum;
        !           730: {
        !           731:     register int i;
        !           732:     register ScreenPtr pScreen;
        !           733:     GCPtr *ppGC;
        !           734: 
        !           735:     pScreen = &screenInfo.screen[screenNum];
        !           736:     ppGC = (GCPtr *) pScreen->GCperDepth;
        !           737: 
        !           738:     /* do depth 1 seperately because it's not included in list */
        !           739:     FreeGC(ppGC[0], 0);
        !           740: 
        !           741:     for (i = 0; i < pScreen-> numDepths; i++)
        !           742:     {
        !           743:        FreeGC(ppGC[i+1], 0);
        !           744:     }
        !           745: }
        !           746: 
        !           747: 
        !           748: CreateGCperDepthArray(screenNum)
        !           749:     int screenNum;
        !           750: {
        !           751:     register int i;
        !           752:     register ScreenPtr pScreen;
        !           753:     DepthPtr pDepth;
        !           754: 
        !           755:     pScreen = &screenInfo.screen[screenNum];
        !           756:     pScreen->rgf = 0;
        !           757:     /* do depth 1 seperately because it's not included in list */
        !           758:     pScreen->GCperDepth[0] = CreateScratchGC(pScreen, 1);
        !           759:     (pScreen->GCperDepth[0])->graphicsExposures = FALSE;
        !           760: 
        !           761:     pDepth = pScreen->allowedDepths;
        !           762:     for (i=0; i<pScreen->numDepths; i++, pDepth++)
        !           763:     {
        !           764:        pScreen->GCperDepth[i+1] = CreateScratchGC(pScreen,
        !           765:                                                   pDepth->depth);
        !           766:        (pScreen->GCperDepth[i+1])->graphicsExposures = FALSE;
        !           767:     }
        !           768: }
        !           769: 
        !           770: CreateDefaultStipple(screenNum)
        !           771:     int screenNum;
        !           772: {
        !           773:     register ScreenPtr pScreen;
        !           774:     int tmpval[3];
        !           775:     xRectangle rect;
        !           776:     int w, h;
        !           777:     GCPtr pgcScratch;
        !           778: 
        !           779:     pScreen = &screenInfo.screen[screenNum];
        !           780: 
        !           781:     w = 16;
        !           782:     h = 16;
        !           783:     (* pScreen->QueryBestSize)(StippleShape, &w, &h);
        !           784:     pScreen->PixmapPerDepth[0] = 
        !           785:                (*pScreen->CreatePixmap)(pScreen, w, h, 1);
        !           786: 
        !           787:     /* fill stipple with 1 */
        !           788:     tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
        !           789:     pgcScratch = GetScratchGC(1, pScreen);
        !           790:     ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval);
        !           791:     ValidateGC(pScreen->PixmapPerDepth[0], pgcScratch);
        !           792:     rect.x = 0;
        !           793:     rect.y = 0;
        !           794:     rect.width = w;
        !           795:     rect.height = h;
        !           796:     (*pgcScratch->PolyFillRect)(pScreen->PixmapPerDepth[0], 
        !           797:                                pgcScratch, 1, &rect);
        !           798:     FreeScratchGC(pgcScratch);
        !           799: }
        !           800: 
        !           801: FreeDefaultStipple(screenNum)
        !           802:     int screenNum;
        !           803: {
        !           804:     ScreenPtr pScreen = &screenInfo.screen[screenNum];
        !           805:     (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
        !           806: }
        !           807: 
        !           808: 
        !           809: SetDashes(pGC, offset, ndash, pdash)
        !           810: register GCPtr pGC;
        !           811: int offset;
        !           812: register int ndash;
        !           813: register unsigned char *pdash;
        !           814: {
        !           815:     register int i;
        !           816:     register unsigned char *p;
        !           817:     GCInterestPtr      pQ, pQInit;
        !           818:     int maskQ = 0;
        !           819: 
        !           820:     i = ndash;
        !           821:     p = pdash;
        !           822:     while (i--)
        !           823:     {
        !           824:        if (!*p++)
        !           825:        {
        !           826:            /* dash segment must be > 0 */
        !           827:            return BadValue;
        !           828:        }
        !           829:     }
        !           830: 
        !           831:     if (offset != pGC->dashOffset)
        !           832:     {
        !           833:        pGC->dashOffset = offset;
        !           834:        pGC->stateChanges |= GCDashOffset;
        !           835:        maskQ |= GCDashOffset;
        !           836:     }
        !           837: 
        !           838:     p = (unsigned char *)Xalloc(ndash * sizeof(unsigned char));
        !           839:     if (!p)
        !           840:     {
        !           841:        return BadAlloc;
        !           842:     }
        !           843:     Xfree(pGC->dash);
        !           844:     pGC->dash = p;
        !           845:     pGC->numInDashList = ndash;
        !           846:     while(ndash--)
        !           847:        *p++ = *pdash++;
        !           848:     pGC->stateChanges |= GCDashList;
        !           849:     maskQ |= GCDashList;
        !           850: 
        !           851:     pQ = pGC->pNextGCInterest;
        !           852:     pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
        !           853:     do
        !           854:     {
        !           855:        if(pQ->ChangeInterestMask & maskQ)
        !           856:            (*pQ->ChangeGC)(pGC, pQ, maskQ);
        !           857:        pQ = pQ->pNextGCInterest;
        !           858:     }
        !           859:     while(pQ != pQInit);
        !           860:     return Success;
        !           861: }
        !           862: 
        !           863: 
        !           864: int
        !           865: SetClipRects(pGC, nrects, prects, ordering)
        !           866:     GCPtr              pGC;
        !           867:     int                        nrects;
        !           868:     xRectangle         *prects;
        !           869:     int                        ordering;
        !           870: {
        !           871:     register xRectangle        *prectP, *prectN;
        !           872:     register int       i;
        !           873:     int                        newct, size;
        !           874:     xRectangle                 *prectsNew;
        !           875:     GCInterestPtr      pQ, pQInit;
        !           876: 
        !           877:     switch(ordering)
        !           878:     {
        !           879:       case Unsorted:
        !           880:          newct = CT_UNSORTED;
        !           881:          break;
        !           882:       case YSorted:
        !           883:          if(i > 0)
        !           884:          {
        !           885:              prectP = prects;
        !           886:              prectN = prects + 1;
        !           887:              for(i = 1; i < nrects; i++, prectN++, prectP++)
        !           888:                  if(prectN->y < prectP->y)
        !           889:                      return(BadMatch);
        !           890:          }
        !           891:          newct = CT_YSORTED;
        !           892:          break;
        !           893:       case YXSorted:
        !           894:          if(i > 0)
        !           895:          {
        !           896:              for(i = 1; i < nrects; i++, prectN++, prectP++)
        !           897:                  if((prectN->y < prectP->y) ||
        !           898:                      ( (prectN->y == prectP->y) &&
        !           899:                        (prectN->x < prectP->x) ) )
        !           900:                      return(BadMatch);
        !           901:          }
        !           902:          newct = CT_YXSORTED;
        !           903:          break;
        !           904:       case YXBanded:
        !           905:          if(i > 0)
        !           906:          {
        !           907:              for(i = 1; i < nrects; i++, prectN++, prectP++)
        !           908:                  if((prectN->y < prectP->y) ||
        !           909:                      ( (prectN->y == prectP->y) &&
        !           910:                        (  (prectN->x < prectP->x)   ||
        !           911:                           (prectN->height != prectP->height) ) ) )
        !           912:                      return(BadMatch);
        !           913:          }
        !           914:          newct = CT_YXBANDED;
        !           915:          break;
        !           916:     }
        !           917: 
        !           918:     size = nrects * sizeof(xRectangle);
        !           919:     prectsNew = (xRectangle *) Xalloc(size);
        !           920:     bcopy(prects, prectsNew, size);
        !           921:     (*pGC->ChangeClip)(pGC, newct, prectsNew, nrects);
        !           922:     pQ = pGC->pNextGCInterest;
        !           923:     pQInit = (GCInterestPtr) &pGC->pNextGCInterest;
        !           924:     do
        !           925:     {
        !           926:        if(pQ->ChangeInterestMask & GCClipMask)
        !           927:            (*pQ->ChangeGC)(pGC, pQ, GCClipMask);
        !           928:        pQ = pQ->pNextGCInterest;
        !           929:     }
        !           930:     while(pQ != pQInit);
        !           931:     return Success;
        !           932: 
        !           933: }
        !           934: 
        !           935: 
        !           936: /*
        !           937:    sets reasonable defaults 
        !           938:    if we can get a pre-allocated one, use it and mark it as used.
        !           939:    if we can't, create one out of whole cloth (The Velveteen GC -- if
        !           940:    you use it often enough it will become real.)
        !           941: */
        !           942: GCPtr
        !           943: GetScratchGC(depth, pScreen)
        !           944:     register int depth;
        !           945:     register ScreenPtr pScreen;
        !           946: {
        !           947:     register int i;
        !           948:     register GCPtr pGC = (GCPtr)NULL;;
        !           949: 
        !           950:     for (i=0; i<=pScreen->numDepths; i++)
        !           951:         if ( pScreen->GCperDepth[i]->depth == depth &&
        !           952:             !(pScreen->rgf & 1 << (i+1))
        !           953:           )
        !           954:        {
        !           955:            pScreen->rgf |= 1 << (i+1);
        !           956:             pGC = (pScreen->GCperDepth[i]);
        !           957: 
        !           958:            pGC->alu = GXcopy;
        !           959:            pGC->planemask = ~0;
        !           960:            pGC->serialNumber = 0;
        !           961:            pGC->fgPixel = 0;
        !           962:            pGC->bgPixel = 1;
        !           963:            pGC->lineWidth = 0;
        !           964:            pGC->lineStyle = LineSolid;
        !           965:            pGC->capStyle = CapButt;
        !           966:            pGC->joinStyle = JoinMiter;
        !           967:            pGC->fillStyle = FillSolid;
        !           968:            pGC->fillRule = EvenOddRule;
        !           969:            pGC->arcMode = ArcChord;
        !           970:            pGC->patOrg.x = 0;
        !           971:            pGC->patOrg.y = 0;
        !           972:            pGC->subWindowMode = ClipByChildren;
        !           973:            pGC->graphicsExposures = FALSE;
        !           974:            pGC->clipOrg.x = 0;
        !           975:            pGC->clipOrg.y = 0;
        !           976:            /* can't change clip type, because we might drop storage */
        !           977:            pGC->stateChanges = (1 << GCLastBit+1) - 1;
        !           978:            return pGC;
        !           979:        }
        !           980:     /* if we make it this far, need to roll our own */
        !           981:     pGC =  CreateScratchGC(pScreen, depth);
        !           982:     pGC->graphicsExposures = FALSE;
        !           983:     return pGC;
        !           984: }
        !           985: 
        !           986: /*
        !           987:    if the gc to free is in the table of pre-existing ones,
        !           988: mark it as available.
        !           989:    if not, free it for real
        !           990: */
        !           991: void
        !           992: FreeScratchGC(pGC)
        !           993:     register GCPtr pGC;
        !           994: {
        !           995:     register ScreenPtr pScreen = pGC->pScreen;
        !           996:     register int i;
        !           997: 
        !           998:     for (i=0; i<=pScreen->numDepths; i++)
        !           999:     {
        !          1000:         if ( pScreen->GCperDepth[i] == pGC)
        !          1001:        {
        !          1002:            pScreen->rgf &= ~(1<<i+1);
        !          1003:            return;
        !          1004:        }
        !          1005:     }
        !          1006:     FreeGC(pGC, 0);
        !          1007: }
        !          1008: 
        !          1009: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.