Annotation of researchv9/X11/src/X.V11R1/server/ddx/mi/miexpose.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: miexpose.c,v 1.25 87/09/11 07:19:01 toddb Exp $ */
        !            26: 
        !            27: #include "X.h"
        !            28: #define NEED_EVENTS
        !            29: #include "Xproto.h"
        !            30: #include "Xprotostr.h"
        !            31: 
        !            32: #include "misc.h"
        !            33: #include "regionstr.h"
        !            34: #include "scrnintstr.h"
        !            35: #include "gcstruct.h"
        !            36: #include "windowstr.h"
        !            37: #include "pixmap.h"
        !            38: 
        !            39: #include "dixstruct.h"
        !            40: #include "mi.h"
        !            41: #include "Xmd.h"
        !            42: 
        !            43: extern WindowRec WindowTable[];
        !            44: 
        !            45: /*
        !            46:     machine-independent graphics exposure code.  any device that uses
        !            47: the region package can call this.
        !            48: */
        !            49: 
        !            50: 
        !            51: /* miHandleExposures 
        !            52:     generate exposures for areas that were copied from obscured or
        !            53: non-existent areas to non-obscured areas of the destination.
        !            54: 
        !            55: NOTE:
        !            56:     this code sends the exposure events, then paints the background.
        !            57: this will NOT work unless this routine is allowed to complete before
        !            58: the dispatcher looks at this client again.
        !            59: 
        !            60: NOTE:
        !            61:     this does not deal with backing store.
        !            62: */
        !            63: 
        !            64: void
        !            65: miHandleExposures(pSrcDrawable, pDstDrawable,
        !            66:                  pGC, srcx, srcy, width, height, dstx, dsty)
        !            67:     register DrawablePtr       pSrcDrawable;
        !            68:     register DrawablePtr       pDstDrawable;
        !            69:     GCPtr                      pGC;
        !            70:     int                        srcx, srcy;
        !            71:     int                        width, height;
        !            72:     int                        dstx, dsty;
        !            73: {
        !            74:     register ScreenPtr pscr = pGC->pScreen;
        !            75:     RegionPtr prgnSrcClip;     /* drawable-relative source clip */
        !            76:     RegionPtr prgnDstClip;     /* drawable-relative dest clip */
        !            77:     BoxRec srcBox;             /* unclipped source */
        !            78:     RegionPtr prgnSrc;         /* clipped source */
        !            79:     RegionPtr prgnExposed;     /* exposed region, calculated source-
        !            80:                                   relative, made dst relative to
        !            81:                                   intersect with visible parts of
        !            82:                                   dest and send events to client, 
        !            83:                                   and then screen relative to paint 
        !            84:                                   the window background
        !            85:                                */
        !            86: 
        !            87:     if (pSrcDrawable->type == DRAWABLE_WINDOW)
        !            88:     {
        !            89:        prgnSrcClip = (*pscr->RegionCreate)(NullBox, 1);
        !            90:        (*pscr->RegionCopy)(prgnSrcClip,
        !            91:                            ((WindowPtr)pSrcDrawable)->clipList);
        !            92:        (*pscr->TranslateRegion)(prgnSrcClip,
        !            93:                                 -((WindowPtr)pSrcDrawable)->absCorner.x,
        !            94:                                 -((WindowPtr)pSrcDrawable)->absCorner.y);
        !            95:     }
        !            96:     else
        !            97:     {
        !            98:        BoxRec  box;
        !            99: 
        !           100:        box.x1 = 0;
        !           101:        box.y1 = 0;
        !           102:        box.x2 = ((PixmapPtr)pSrcDrawable)->width;
        !           103:        box.y2 = ((PixmapPtr)pSrcDrawable)->height;
        !           104:        prgnSrcClip = (*pscr->RegionCreate)(&box, 1);
        !           105:     }
        !           106: 
        !           107:     if (pDstDrawable->type == DRAWABLE_WINDOW)
        !           108:     {
        !           109:        prgnDstClip = (*pscr->RegionCreate)(NullBox, 1);
        !           110:        (*pscr->RegionCopy)(prgnDstClip,
        !           111:                            ((WindowPtr)pDstDrawable)->clipList);
        !           112:        (*pscr->TranslateRegion)(prgnDstClip,
        !           113:                                 -((WindowPtr)pDstDrawable)->absCorner.x,
        !           114:                                 -((WindowPtr)pDstDrawable)->absCorner.y);
        !           115:     }
        !           116:     else
        !           117:     {
        !           118:        BoxRec  box;
        !           119: 
        !           120:        box.x1 = 0;
        !           121:        box.y1 = 0;
        !           122:        box.x2 = ((PixmapPtr)pDstDrawable)->width;
        !           123:        box.y2 = ((PixmapPtr)pDstDrawable)->height;
        !           124:        prgnDstClip = (*pscr->RegionCreate)(&box, 1);
        !           125:     }
        !           126: 
        !           127:     /* drawable-relative source region */
        !           128:     srcBox.x1 = srcx;
        !           129:     srcBox.y1 = srcy;
        !           130:     srcBox.x2 = srcx+width;
        !           131:     srcBox.y2 = srcy+height;
        !           132:     prgnSrc = (*pscr->RegionCreate)(&srcBox, 1);
        !           133: 
        !           134:     /* get the visible parts of the source box */
        !           135:     (*pscr->Intersect)(prgnSrc, prgnSrc, prgnSrcClip);
        !           136: 
        !           137:     /* now get the hidden parts */
        !           138:     prgnExposed = (*pscr->RegionCreate)(NullBox, 1);
        !           139:     (*pscr->Inverse)(prgnExposed, prgnSrc, &srcBox);
        !           140: 
        !           141:     /* move them over the destination */
        !           142:     (*pscr->TranslateRegion)(prgnExposed, dstx-srcx, dsty-srcy);
        !           143: 
        !           144:     /* intersect with visible areas of dest */
        !           145:     (*pscr->Intersect)(prgnExposed, prgnExposed, prgnDstClip);
        !           146: 
        !           147:     /* send them to the client */
        !           148:     if (pGC->graphicsExposures)
        !           149:     {
        !           150:         if (REGION_NOT_EMPTY(prgnExposed))
        !           151:         {
        !           152:             xEvent *pEvent;
        !           153:            register xEvent *pe;
        !           154:            register BoxPtr pBox = prgnExposed->rects;
        !           155:            register int i;
        !           156: 
        !           157:            if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(prgnExposed->numRects * 
        !           158:                                         sizeof(xEvent))))
        !           159:                return;
        !           160:            pe = pEvent;
        !           161: 
        !           162:            for (i=1; i<=prgnExposed->numRects; i++, pe++, pBox++)
        !           163:            {
        !           164:                pe->u.u.type = GraphicsExpose;
        !           165:                pe->u.graphicsExposure.drawable = 
        !           166:                                requestingClient->lastDrawableID;
        !           167:                pe->u.graphicsExposure.x = pBox->x1;
        !           168:                pe->u.graphicsExposure.y = pBox->y1;
        !           169:                pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
        !           170:                pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
        !           171:                pe->u.graphicsExposure.count = prgnExposed->numRects - i;
        !           172:                                        
        !           173:            }
        !           174:            TryClientEvents(requestingClient, pEvent, prgnExposed->numRects,
        !           175:                            0, NoEventMask, 0);
        !           176:            DEALLOCATE_LOCAL(pEvent);
        !           177:         }
        !           178:         else
        !           179:         {
        !           180:             xEvent event;
        !           181:            event.u.u.type = NoExpose;
        !           182:            event.u.noExposure.drawable = requestingClient->lastDrawableID;
        !           183:            TryClientEvents(requestingClient, &event, 1,
        !           184:                0, NoEventMask, 0);
        !           185:         }
        !           186:     }
        !           187: 
        !           188: 
        !           189:     if ((pDstDrawable->type == DRAWABLE_WINDOW) &&
        !           190:        (((WindowPtr)pDstDrawable)->backgroundTile != None))
        !           191:     {
        !           192:        WindowPtr pWin = (WindowPtr)pDstDrawable;
        !           193: 
        !           194:        /* make the exposed area screen-relative */
        !           195:        (*pscr->TranslateRegion)(prgnExposed, 
        !           196:                                 pWin->absCorner.x, pWin->absCorner.y);
        !           197: 
        !           198:        (*pWin->PaintWindowBackground)(pDstDrawable, prgnExposed, 
        !           199:                                       PW_BACKGROUND);
        !           200:     }
        !           201:     (*pscr->RegionDestroy)(prgnDstClip);
        !           202:     (*pscr->RegionDestroy)(prgnSrcClip);
        !           203:     (*pscr->RegionDestroy)(prgnSrc);
        !           204:     (*pscr->RegionDestroy)(prgnExposed);
        !           205: }
        !           206: 
        !           207: void
        !           208: miSendNoExpose(pGC)
        !           209:     GCPtr pGC;
        !           210: {
        !           211:     if (pGC->graphicsExposures)
        !           212:     {
        !           213:         xEvent event;
        !           214:        event.u.u.type = NoExpose;
        !           215:        event.u.noExposure.drawable = 
        !           216:                    requestingClient->lastDrawableID;
        !           217:         TryClientEvents(requestingClient, &event, 1,
        !           218:                0, NoEventMask, 0);
        !           219:     }
        !           220: }
        !           221: 
        !           222: 
        !           223: void 
        !           224: miWindowExposures(pWin)
        !           225:     WindowPtr pWin;
        !           226: {
        !           227:     register RegionPtr prgn;
        !           228: 
        !           229:     prgn = pWin->exposed;
        !           230:     if (prgn->numRects)
        !           231:     {
        !           232:        xEvent *pEvent;
        !           233:        register xEvent *pe;
        !           234:        register BoxPtr pBox;
        !           235:        register int i;
        !           236: 
        !           237:         (*pWin->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
        !           238:        (* pWin->drawable.pScreen->TranslateRegion)(prgn,
        !           239:                        -pWin->absCorner.x, -pWin->absCorner.y);
        !           240:        if (pWin->backingStore != NotUseful && pWin->backStorage)
        !           241:        {
        !           242:                /* modifies pWin->exposed */
        !           243:            (*pWin->backStorage->RestoreAreas)(pWin);
        !           244:        }
        !           245:        pBox = prgn->rects;
        !           246:         
        !           247:        if(!(pEvent = (xEvent *)
        !           248:            ALLOCATE_LOCAL(prgn->numRects * sizeof(xEvent))))
        !           249:            return;
        !           250:        pe = pEvent;
        !           251:         
        !           252:        for (i=1; i<=prgn->numRects; i++, pe++, pBox++)
        !           253:        {
        !           254:            pe->u.u.type = Expose;
        !           255:            pe->u.expose.window = pWin->wid;
        !           256:            pe->u.expose.x = pBox->x1;
        !           257:            pe->u.expose.y = pBox->y1;
        !           258:            pe->u.expose.width = pBox->x2 - pBox->x1;
        !           259:            pe->u.expose.height = pBox->y2 - pBox->y1;
        !           260:            pe->u.expose.count = (prgn->numRects - i);
        !           261:        }
        !           262:        DeliverEvents(pWin, pEvent, prgn->numRects, NullWindow);
        !           263:        prgn->numRects = 0;
        !           264:        DEALLOCATE_LOCAL(pEvent);
        !           265:     }
        !           266: }
        !           267: 
        !           268: 
        !           269: /*
        !           270:     this code is highly unlikely.  it is not haile selassie.
        !           271: 
        !           272:     there is some hair here.  we can't just use the window's
        !           273: clip region as it is, because if we are painting the border,
        !           274: the border is not in the client area and so we will be excluded
        !           275: when we validate the GC, and if we are painting a parent-relative
        !           276: background, the area we want to paint is in some other window.
        !           277: since we trust the code calling us to tell us to paint only areas
        !           278: that are really ours, we will temporarily give the window a
        !           279: clipList the size of the whole screen and an origin at (0,0).
        !           280: this more or less assumes that ddX code will do translation
        !           281: based on the window's absCorner, and that ValidateGC will
        !           282: look at clipList, and that no other fields from the
        !           283: window will be used.  it's not possible to just draw
        !           284: in the root because it may be a different depth.
        !           285: 
        !           286: to get the tile to align correctly we set the GC's tile origin to
        !           287: be the (x,y) of the window's upper left corner, after which we
        !           288: get the right bits when drawing into the root.
        !           289: 
        !           290: in order to call ChangeGC, we need to get an id for the pixmap, and
        !           291: enter it in the resource table.
        !           292: */
        !           293: void
        !           294: miPaintWindow(pWin, prgn, what)
        !           295: WindowPtr pWin;
        !           296: RegionPtr prgn;
        !           297: int what;
        !           298: {
        !           299:     int gcval[6];
        !           300:     int gcmask;
        !           301:     RegionPtr prgnWin;
        !           302:     DDXPointRec oldCorner;
        !           303:     BoxRec box;
        !           304:     GCPtr pGC;
        !           305:     int pid = 0;
        !           306:     register int i;
        !           307:     register BoxPtr pbox;
        !           308:     register ScreenPtr pScreen = pWin->drawable.pScreen;
        !           309:     register xRectangle *prect;
        !           310: 
        !           311:     gcval[0] = GXcopy;
        !           312:     gcval[3] = pWin->absCorner.x;
        !           313:     gcval[4] = pWin->absCorner.y;
        !           314:     gcval[5] = None;
        !           315:     gcmask = GCFunction | GCFillStyle |
        !           316:             GCTileStipXOrigin | GCTileStipYOrigin | GCClipMask;
        !           317:     if (what == PW_BACKGROUND)
        !           318:     {
        !           319:        if (pWin->backgroundTile == None)
        !           320:            return;
        !           321:        else if ((int)pWin->backgroundTile == ParentRelative)
        !           322:        {
        !           323:            (*pWin->parent->PaintWindowBorder)(pWin->parent, prgn, what);
        !           324:            return;
        !           325:        }
        !           326:        else if ((int)pWin->backgroundTile == USE_BACKGROUND_PIXEL)
        !           327:        {
        !           328:            gcval[1] = pWin->backgroundPixel;
        !           329:            gcval[2] = FillSolid;
        !           330:            gcmask |= GCForeground;
        !           331:        }
        !           332:        else
        !           333:        {
        !           334:            gcval[1] = FillTiled;
        !           335:            pid = FakeClientID(0);
        !           336:            AddResource(pid, RT_PIXMAP, pWin->backgroundTile,
        !           337:                        NoopDDA, RC_CORE);
        !           338:            gcval[2] = pid;
        !           339:            gcmask |= GCTile;
        !           340:        }
        !           341:     }
        !           342:     else
        !           343:     {
        !           344:        if (pWin->borderTile == None)
        !           345:            return;
        !           346:        else if ((int)pWin->borderTile == USE_BORDER_PIXEL)
        !           347:        {
        !           348:            gcval[1] = pWin->borderPixel;
        !           349:            gcval[2] = FillSolid;
        !           350:            gcmask |= GCForeground;
        !           351:        }
        !           352:        else
        !           353:        {
        !           354:            gcval[1] = FillTiled;
        !           355:            pid = FakeClientID(0);
        !           356:            AddResource(pid, RT_PIXMAP, pWin->borderTile,
        !           357:                        NoopDDA, RC_CORE);
        !           358:            gcval[2] = pid;
        !           359:            gcmask |= GCTile;
        !           360:        }
        !           361:     }
        !           362:     pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
        !           363:     DoChangeGC(pGC, gcmask, gcval, 0);
        !           364: 
        !           365:     box.x1 = 0;
        !           366:     box.y1 = 0;
        !           367:     box.x2 = pScreen->width;
        !           368:     box.y2 = pScreen->height;
        !           369:     
        !           370:     prgnWin = pWin->clipList;
        !           371:     oldCorner = pWin->absCorner;
        !           372:     pWin->absCorner.x = pWin->absCorner.y = 0;
        !           373:     pWin->clipList = (*pScreen->RegionCreate)(&box, 1);
        !           374:     pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
        !           375:     ValidateGC(pWin, pGC);
        !           376: 
        !           377:     prect = (xRectangle *)ALLOCATE_LOCAL(prgn->numRects * sizeof(xRectangle));
        !           378:     pbox = prgn->rects;
        !           379:     for (i= 0; i < prgn->numRects; i++, pbox++, prect++)
        !           380:     {
        !           381:        prect->x = pbox->x1;
        !           382:        prect->y = pbox->y1;
        !           383:        prect->width = pbox->x2 - pbox->x1;
        !           384:        prect->height = pbox->y2 - pbox->y1;
        !           385:     }
        !           386:     prect -= prgn->numRects;
        !           387:     (*pGC->PolyFillRect)(pWin, pGC, prgn->numRects, prect);
        !           388:     DEALLOCATE_LOCAL(prect);
        !           389: 
        !           390:     if (pid)
        !           391:        FreeResource(pid, RC_CORE);
        !           392:     (*pScreen->RegionDestroy)(pWin->clipList);
        !           393:     pWin->clipList = prgnWin;
        !           394:     pWin->absCorner = oldCorner;
        !           395:     pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
        !           396:     FreeScratchGC(pGC);
        !           397: }
        !           398: 

unix.superglobalmegacorp.com

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