home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / dec / qdss / qdcopy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-19  |  9.1 KB  |  263 lines

  1. /***********************************************************
  2. Copyright 1987, 1988 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. #include "X.h"
  26. #include "windowstr.h"
  27. #include "gcstruct.h"
  28. #include "mi.h"
  29.  
  30. #include "qd.h"
  31. #include "qdgc.h"
  32.  
  33. /* due to validation...                            *
  34.  *    if this is called, pDstDrawable is SURELY a DRAWABLE_WINDOW.    *
  35.  *    -unless, of course, it's a fake window, called from qdCopyArea
  36.  */
  37. RegionPtr
  38. qdCopyAreaWin(pSrcDrawable, pDstDrawable,
  39.           pGC, srcx, srcy, width, height, dstx, dsty)
  40.     register DrawablePtr pSrcDrawable;
  41.     register DrawablePtr pDstDrawable;
  42.     GCPtr    pGC;   /* composite clip region here is that of pDstDrawable */
  43.     int        srcx, srcy;
  44.     int        width, height;
  45.     int        dstx, dsty;
  46. {
  47.     if ((width == 0) || (height == 0)) return NULL;
  48.  
  49.     if (pSrcDrawable->type == DRAWABLE_WINDOW) {
  50.     WindowPtr    psrcwin;
  51.     int        abssrcx, abssrcy;    /* screen coordinates */
  52.     int     absdstx, absdsty;    /* screen coordinates */
  53.  
  54.     RegionRec    pcompclip[1];
  55.     psrcwin = (WindowPtr)pSrcDrawable;
  56.     abssrcx = QDWIN_X(psrcwin) + srcx;
  57.     abssrcy = QDWIN_Y(psrcwin) + srcy;
  58.     absdstx = pGC->lastWinOrg.x + dstx;
  59.     absdsty = pGC->lastWinOrg.y + dsty;
  60.  
  61.     /* set up pcompclip to be argument Box */
  62.     pcompclip->extents.x1 = abssrcx;
  63.     pcompclip->extents.x2 = abssrcx + width;
  64.     pcompclip->extents.y1 = abssrcy;
  65.     pcompclip->extents.y2 = abssrcy + height;
  66.     pcompclip->data = NULL;
  67.  
  68.     if ( pGC->subWindowMode == IncludeInferiors) /* used by qdCopyWindow */
  69.         miIntersect( pcompclip, pcompclip, QDWIN_WINSIZE(psrcwin));
  70.     else
  71.         miIntersect( pcompclip, pcompclip, QDWIN_CLIPLIST(psrcwin));
  72.     miTranslateRegion(pcompclip, absdstx-abssrcx, absdsty-abssrcy);
  73.  
  74.     miIntersect( pcompclip, pcompclip, QDGC_COMPOSITE_CLIP(pGC));
  75.     tlbltregion(pGC, pcompclip, absdstx-abssrcx, absdsty-abssrcy);
  76.     if (pcompclip->data && pcompclip->data->size) Xfree(pcompclip->data);
  77.     /*
  78.      * miHandleExposures wants window-relative coordinates
  79.      */
  80.     return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
  81.                  srcx, srcy, width, height, dstx, dsty, 0);
  82.     }
  83.     else if (pSrcDrawable->type == DRAWABLE_PIXMAP)
  84.     {
  85.     return (RegionPtr) tlspaca(pSrcDrawable, pDstDrawable,
  86.                 pGC, srcx, srcy, width, height, dstx, dsty);
  87.         
  88.     } else /* pSrcDrawable->type must be UNDRAWABLE_WINDOW */
  89.     return miCopyArea( pSrcDrawable, pDstDrawable,
  90.                 pGC, srcx, srcy, width, height, dstx, dsty);
  91. }
  92.  
  93. RegionPtr
  94. qdCopyArea( pSrcDrawable, pDstDrawable,
  95.                     pGC, srcx, srcy, width, height, dstx, dsty)
  96.     register DrawablePtr pSrcDrawable;
  97.     register DrawablePtr pDstDrawable;
  98.     GCPtr    pGC;   /* composite clip region here is that of pDstDrawable */
  99.     int        srcx, srcy;
  100.     int        width, height;
  101.     int        dstx, dsty;
  102. {
  103. /* We start with some magic to guard against both src and dst being
  104.  * pixmaps that fight for offscreen space.
  105.  */
  106.     if (pDstDrawable->type == DRAWABLE_PIXMAP) {
  107.     tlConfirmPixmap((QDPixPtr)pDstDrawable);
  108.     if (pSrcDrawable->type == DRAWABLE_PIXMAP)
  109.         tlConfirmPixmap((QDPixPtr)pSrcDrawable);
  110.     tlSinglePixmap((QDPixPtr)pDstDrawable);
  111.     }
  112.     if (pDstDrawable->type == DRAWABLE_PIXMAP
  113.     /* make sure dst is still off-screen */
  114.     && ((QDPixPtr)pDstDrawable)->planes
  115.     /* if src is Bitmap which is not offscreen, use mi */
  116.     && (pSrcDrawable->depth > 1 || ((QDPixPtr)pSrcDrawable)->planes)) {
  117.     RegionPtr region;
  118.  
  119.     SETUP_PIXMAP_AS_WINDOW(pDstDrawable, pGC);
  120.     CHECK_MOVED(pGC, pDstDrawable);
  121.     /*
  122.      * If src is Bitmap in plane different from dst, must use
  123.      * tlPlaneCopy. Otherwise, make fake window. (If src and
  124.      * dst are Bitmaps in the same plane, prefer qdCopyAreaWin, because
  125.      * it ultimately call tlbitblt, which correctly deals with
  126.      * overlapping src and dst.)
  127.      */
  128.     if (pSrcDrawable->depth == 1
  129.         && !(((QDPixPtr)pSrcDrawable)->planes
  130.            & ((QDPixPtr)pDstDrawable)->planes)) {
  131.         pGC->fgPixel = Allplanes;
  132.         pGC->bgPixel = 0;
  133.         tlPlaneBlt(pGC,
  134.                dstx + QDPIX_X((QDPixPtr)pDstDrawable),
  135.                dsty + QDPIX_Y((QDPixPtr)pDstDrawable),
  136.                width, height,
  137.                srcx + QDPIX_X((QDPixPtr)pSrcDrawable),
  138.                srcy + QDPIX_Y((QDPixPtr)pSrcDrawable),
  139.                ((QDPixPtr)pSrcDrawable)->planes);
  140.         region = NULL;
  141.     }
  142.         else
  143.         region = qdCopyAreaWin(pSrcDrawable, pDstDrawable,
  144.                    pGC, srcx, srcy, width, height, dstx, dsty);
  145.     CLEANUP_PIXMAP_AS_WINDOW(pGC);
  146.     return region;    
  147.     } else
  148.     return miCopyArea(pSrcDrawable, pDstDrawable,
  149.               pGC, srcx, srcy, width, height, dstx, dsty);
  150. }
  151.  
  152. /* Validation ensures that pDstDrawable is DRAWABLE_WINDOW. */
  153.  
  154. RegionPtr
  155. qdCopyPlane(pSrcDrawable, pDstDrawable,
  156.         pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
  157.     DrawablePtr     pSrcDrawable;
  158.     DrawablePtr        pDstDrawable;
  159.     GCPtr        pGC;
  160.     int         srcx, srcy;
  161.     int         width, height;
  162.     int         dstx, dsty;
  163.     unsigned long    bitPlane;
  164. {
  165.     int xOrg = dstx + pGC->lastWinOrg.x;
  166.     int yOrg = dsty + pGC->lastWinOrg.y;
  167.     unsigned long mask = 
  168.     pSrcDrawable->depth == 1 ? ((QDPixPtr)pSrcDrawable)->planes
  169.         : bitPlane;
  170.     if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
  171.     int w = QDPIX_WIDTH((PixmapPtr)pSrcDrawable) - srcx;
  172.     int h = QDPIX_HEIGHT((PixmapPtr)pSrcDrawable) - srcy;
  173.     if (w > width) w = width;
  174.     if (h > height) h = height;
  175.     if (QDPIX_Y((QDPixPtr)pSrcDrawable) != NOTOFFSCREEN)
  176.         tlPlaneBlt(pGC, xOrg, yOrg, w, h,
  177.                srcx + QDPIX_X((QDPixPtr)pSrcDrawable),
  178.                srcy + QDPIX_Y((QDPixPtr)pSrcDrawable),
  179.                mask);
  180.     else {
  181.         RegionPtr pcl = QDGC_COMPOSITE_CLIP(pGC);
  182.         register BoxPtr    rects = REGION_RECTS(pcl);
  183.         int saveMask = ((QDPixPtr)pSrcDrawable)->planes;
  184.         int ic;
  185.         ((QDPixPtr)pSrcDrawable)->planes = mask;
  186.         for (ic = REGION_NUM_RECTS(pcl); --ic >= 0; rects++) {
  187.         BoxRec    cb;
  188.         cb.x1 = max( rects->x1, xOrg);
  189.         cb.y1 = max( rects->y1, yOrg);
  190.         cb.x2 = min( rects->x2, xOrg+width);
  191.         cb.y2 = min( rects->y2, yOrg+height);
  192.         if (cb.x1 < cb.x2 && cb.y1 < cb.y2)
  193.             tlBitmapBichrome(pGC, pSrcDrawable,
  194.                      pGC->fgPixel, pGC->bgPixel,
  195.                      xOrg - srcx, yOrg - srcy, &cb);
  196.         }
  197.         ((QDPixPtr)pSrcDrawable)->planes = saveMask;
  198.     }
  199.     }
  200.     else if (pSrcDrawable->type == DRAWABLE_WINDOW) {
  201.     WindowPtr    psrcwin;
  202.     int        abssrcx, abssrcy;    /* screen coordinates */
  203.     int     absdstx, absdsty;    /* screen coordinates */
  204.     
  205.     RegionRec    pcompclip[1];
  206.     RegionPtr    pSaveClip = QDGC_COMPOSITE_CLIP(pGC);
  207.     psrcwin = (WindowPtr)pSrcDrawable;
  208.     abssrcx = QDWIN_X(psrcwin) + srcx;
  209.     abssrcy = QDWIN_Y(psrcwin) + srcy;
  210.     absdstx = pGC->lastWinOrg.x + dstx;
  211.     absdsty = pGC->lastWinOrg.y + dsty;
  212.  
  213.     /* set up pcompclip to be argument Box */
  214.     pcompclip->extents.x1 = abssrcx;
  215.     pcompclip->extents.x2 = abssrcx + width;
  216.     pcompclip->extents.y1 = abssrcy;
  217.     pcompclip->extents.y2 = abssrcy + height;
  218.     pcompclip->data = NULL;
  219.  
  220.     if ( pGC->subWindowMode == IncludeInferiors) /* used by qdCopyWindow */
  221.         miIntersect( pcompclip, pcompclip, QDWIN_WINSIZE(psrcwin));
  222.     else
  223.         miIntersect( pcompclip, pcompclip, QDWIN_CLIPLIST(psrcwin));
  224.     miTranslateRegion(pcompclip, absdstx-abssrcx, absdsty-abssrcy);
  225.     miIntersect( pcompclip, pcompclip, QDGC_COMPOSITE_CLIP(pGC));
  226.     QDGC_COMPOSITE_CLIP(pGC) = pcompclip;
  227.     tlPlaneBlt(pGC, xOrg, yOrg, width, height,
  228.            srcx + QDWIN_X((WindowPtr)pSrcDrawable),
  229.            srcy + QDWIN_Y((WindowPtr)pSrcDrawable),
  230.            mask);
  231.     QDGC_COMPOSITE_CLIP(pGC) = pSaveClip;
  232.     if (pcompclip->data && pcompclip->data->size) Xfree(pcompclip->data);
  233.     }
  234.     return miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
  235.                  width, height, dstx, dsty, bitPlane);
  236. }
  237.  
  238. RegionPtr
  239. qdCopyPlanePix(pSrcDrawable, pDstDrawable,
  240.         pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
  241.     DrawablePtr     pSrcDrawable;
  242.     DrawablePtr        pDstDrawable;
  243.     GCPtr        pGC;
  244.     int         srcx, srcy;
  245.     int         width, height;
  246.     int         dstx, dsty;
  247.     unsigned long    bitPlane;
  248. {
  249.     CHECK_MOVED(pGC, pDstDrawable);
  250.     if (QD_PIX_DATA((PixmapPtr)pDstDrawable) == NULL) {
  251.     RegionPtr region;
  252.     /* make dummy window and use that as the drawable */
  253.     SETUP_PIXMAP_AS_WINDOW(pDstDrawable, pGC);
  254.     region = qdCopyPlane(pSrcDrawable, pDstDrawable,
  255.         pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
  256.     CLEANUP_PIXMAP_AS_WINDOW(pGC);
  257.     return region;
  258.     }
  259.     else
  260.     return miCopyPlane(pSrcDrawable, pDstDrawable,
  261.                pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
  262. }
  263.