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

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: 
1.1.1.2 ! root       25: /* $Header: gc.c,v 1.96 87/10/03 14:33:48 rws Exp $ */
1.1       root       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:                {
1.1.1.2 ! root      533:                    if (pgcDst->stipple == pgcSrc->stipple)
1.1       root      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.