Annotation of researchv9/X11/src/X.V11R1/server/ddx/mi/miexpose.c, revision 1.1.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.