home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / ibm / pgc / pgcCpArea.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-16  |  6.8 KB  |  255 lines

  1. /*
  2.  * $XConsortium: pgcCpArea.c,v 1.2 91/07/16 13:12:10 jap Exp $
  3.  *
  4.  * Copyright IBM Corporation 1987,1988,1989,1990,1991
  5.  *
  6.  * All Rights Reserved
  7.  *
  8.  * License to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted,
  10.  * provided that the above copyright notice appear in all copies and that
  11.  * both that copyright notice and this permission notice appear in
  12.  * supporting documentation, and that the name of IBM not be
  13.  * used in advertising or publicity pertaining to distribution of the
  14.  * software without specific, written prior permission.
  15.  *
  16.  * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  17.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND 
  18.  * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL
  19.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  20.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  22.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  23.  * SOFTWARE.
  24.  *
  25. */
  26.  
  27. #include "X.h"
  28. #include "servermd.h"
  29. #include "misc.h"
  30. #include "regionstr.h"
  31. #include "gcstruct.h"
  32. #include "windowstr.h"
  33. #include "pixmapstr.h"
  34. #include "scrnintstr.h"
  35.  
  36. #include "ibmTrace.h"
  37. #include "mi.h"
  38.  
  39. #include "cfb.h"
  40. #include "pgc.h"
  41. extern pgcScreenRec pgcScreenInfo[] ;
  42.  
  43. extern int cfbGCPrivateIndex;
  44.  
  45. RegionPtr
  46. pgcCopyArea( pSrcDrawable, pDstDrawable,
  47.          pGC, srcx, srcy, width, height, dstx, dsty )
  48. register DrawablePtr pSrcDrawable ;
  49. register DrawablePtr pDstDrawable ;
  50. GC *pGC ;
  51. int srcx, srcy ;
  52. int width, height ;
  53. int dstx, dsty ;
  54. {
  55.     register BoxPtr pbox ;
  56.     register int dx ;
  57.     register int dy ;
  58.     int nbox ;
  59.     ScreenPtr pScreen ;
  60.     RegionPtr prgnDst ;
  61.     RegionPtr prgnExposed ;
  62.     int alu ;
  63.     unsigned long int pm ;
  64.     /* temporaries for shuffling rectangles */
  65.     xRectangle *origSource ;
  66.     DDXPointRec *origDest ;
  67.     cfbPrivGC *pPriv ;
  68.  
  69.         TRACE(("pgcCopyArea\n"));
  70.  
  71.     if ( !( pm = pGC->planemask ) || ( ( alu = pGC->alu ) == GXnoop ) )
  72.         return NULL ;
  73.  
  74.     /*
  75.      * If the destination drawable is not a window then call the mi version.
  76.      */
  77.  
  78.     if ( pDstDrawable->type != DRAWABLE_WINDOW )
  79.         return cfbCopyArea( pSrcDrawable, pDstDrawable, pGC,
  80.                    srcx, srcy, width, height, dstx, dsty ) ;
  81.  
  82.     /* BY HERE, You know you are going to a Window */
  83.     if ( !( (WindowPtr) pDstDrawable )->realized )
  84.         return NULL ;
  85.  
  86.     if ( pSrcDrawable->type != DRAWABLE_WINDOW )
  87.         return cfbCopyArea( (PixmapPtr) pSrcDrawable,
  88.                       pDstDrawable,
  89.                       pGC, srcx, srcy, width,
  90.                       height, dstx, dsty ) ;
  91.  
  92.     pPriv = (cfbPrivGC *) ( pGC->devPrivates[cfbGCPrivateIndex].ptr ) ;
  93.     /* BY HERE, You know you are going from a Window to a Window */
  94.     if ( pPriv->fExpose ) {
  95.         if ( !( origSource = (xRectangle *)
  96.             ALLOCATE_LOCAL( sizeof( xRectangle ) ) ) )
  97.             return NULL ;
  98.         origSource->x = srcx ;
  99.         origSource->y = srcy ;
  100.         origSource->width = width ;
  101.         origSource->height = height ;
  102.         if ( !( origDest = (DDXPointRec *)
  103.             ALLOCATE_LOCAL( sizeof( DDXPointRec ) ) ) ) {
  104.             DEALLOCATE_LOCAL( origSource ) ;
  105.             return NULL ;
  106.         }
  107.         origDest->x = dstx ;
  108.         origDest->y = dsty ;
  109.     }
  110.     else {
  111.         origSource = (xRectangle *) 0 ;
  112.         origDest = (DDXPointRec *) 0 ;
  113.     }
  114.  
  115.     /* clip the left and top edges of the source */
  116.     if ( srcx < 0 ) {
  117.         width += srcx ;
  118.         srcx = pSrcDrawable->x ;
  119.     }
  120.     else
  121.         srcx += pSrcDrawable->x ;
  122.     if ( srcy < 0 ) {
  123.         height += srcy ;
  124.         srcy = pSrcDrawable->y ;
  125.     }
  126.     else
  127.         srcy += pSrcDrawable->y ;
  128.  
  129.     pScreen = pDstDrawable->pScreen ;
  130.     /* clip the source */
  131.     {
  132.         BoxRec srcBox ;
  133.  
  134.         srcBox.x1 = srcx ;
  135.         srcBox.y1 = srcy ;
  136.         srcBox.x2 = srcx + width ;
  137.         srcBox.y2 = srcy + height ;
  138.  
  139.         prgnDst = (* pScreen->RegionCreate)( &srcBox, 1 ) ;
  140.     }
  141.     if ( pGC->subWindowMode == IncludeInferiors ) {
  142.         register RegionPtr prgnSrcClip =
  143.             NotClippedByChildren( (WindowPtr) pSrcDrawable ) ;
  144.         (* pScreen->Intersect)( prgnDst, prgnDst, prgnSrcClip ) ;
  145.         (* pScreen->RegionDestroy)( prgnSrcClip ) ;
  146.     }
  147.     else
  148.         (* pScreen->Intersect)( prgnDst, prgnDst,
  149.                 &(((WindowPtr) pSrcDrawable)->clipList) ) ;
  150.  
  151.     dstx += pDstDrawable->x ;
  152.     dsty += pDstDrawable->y ;
  153.  
  154.     dx = srcx - dstx ;
  155.     dy = srcy - dsty ;
  156.  
  157.     /* clip the shape of the dst to the destination composite clip */
  158.     (* pScreen->TranslateRegion)( prgnDst, -dx, -dy ) ;
  159.     (* pScreen->Intersect)( prgnDst, prgnDst, pPriv->pCompositeClip ) ;
  160.  
  161.     /* nbox != 0 destination region is visable */
  162.     if ( nbox = REGION_NUM_RECTS(prgnDst) ) {
  163.         BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2 ;
  164.  
  165.         pbox = REGION_RECTS(prgnDst);
  166.  
  167.         pboxNew1 = 0 ;
  168.         pboxNew2 = 0 ;
  169.         if ( nbox > 1 ) {
  170.             if ( dy < 0 ) {
  171.                 /* walk source bottom to top */
  172.                 /* keep ordering in each band, */
  173.                 /* reverse order of bands */
  174.                 if ( !( pboxNew1 = (BoxPtr)
  175.                     ALLOCATE_LOCAL( nbox * sizeof (BoxRec) ) ) ) {
  176.                     (* pScreen->RegionDestroy)( prgnDst ) ;
  177.                     return NULL ;
  178.                 }
  179.                 for ( pboxBase = pboxNext = pbox + nbox - 1 ;
  180.                       pboxBase >= pbox ;
  181.                       pboxBase = pboxNext ) {
  182.                     while ( pboxNext >= pbox
  183.                          && pboxBase->y1 == pboxNext->y1 )
  184.                         pboxNext-- ;
  185.                     for ( pboxTmp = pboxNext + 1 ;
  186.                           pboxTmp <= pboxBase ;
  187.                           *pboxNew1++ = *pboxTmp++ )
  188.                         /*DO NOTHING*/ ;
  189.                 }
  190.                 pbox = ( pboxNew1 -= nbox ) ;
  191.             }
  192.             if ( dx < 0 ) {
  193.                 /* walk source right to left */
  194.                 /* reverse order of rects in each band */
  195.                 if ( !( pboxNew2 = (BoxPtr)
  196.                     ALLOCATE_LOCAL( sizeof (BoxRec) * nbox ) ) ) {
  197.                     (* pScreen->RegionDestroy)( prgnDst ) ;
  198.                     return NULL ;
  199.                 }
  200.                 for ( pboxBase = pboxNext = pbox ;
  201.                       pboxBase < pbox + nbox ;
  202.                       pboxBase = pboxNext ) {
  203.                     while ( pboxNext < pbox + nbox
  204.                          && pboxNext->y1 == pboxBase->y1 )
  205.                         pboxNext++ ;
  206.                     for ( pboxTmp = pboxNext ;
  207.                           pboxTmp != pboxBase ;
  208.                           *pboxNew2++ = *--pboxTmp )
  209.                         /*DO NOTHING*/ ;
  210.                 }
  211.                 pbox = ( pboxNew2 -= nbox ) ;
  212.             }
  213.         }
  214.  
  215.         { /* Here is the "REAL" copy. All clipped and GO. */
  216.         void (*fnp)() ;
  217.         int   index ;
  218.         pgcScreenPtr    pPGCScreen ;
  219.  
  220.                 index = pScreen->myNum ;
  221.         pPGCScreen= &pgcScreenInfo[index];
  222.         fnp = pPGCScreen->blit ;
  223.  
  224.         for ( ; nbox-- ; pbox++ )
  225.            (* fnp)( alu, pScreen , pm,
  226.              pbox->x1 + dx, pbox->y1 + dy,
  227.              pbox->x1, pbox->y1,
  228.              pbox->x2 - pbox->x1, pbox->y2 - pbox->y1 ) ;
  229.         }
  230.         /* free up stuff */
  231.         if ( pboxNew1 )
  232.             DEALLOCATE_LOCAL( pboxNew1 ) ;
  233.         if ( pboxNew2 )
  234.             DEALLOCATE_LOCAL( pboxNew2 ) ;
  235.  
  236.         if ( origSource ) {
  237.             prgnExposed = miHandleExposures(
  238.                     pSrcDrawable, pDstDrawable, pGC,
  239.                         origSource->x, origSource->y,
  240.                         origSource->width, origSource->height,
  241.                         origDest->x, origDest->y ) ;
  242.             DEALLOCATE_LOCAL( origSource ) ;
  243.             DEALLOCATE_LOCAL( origDest ) ;
  244.         }
  245.         else
  246.             prgnExposed = (RegionPtr) 0 ;
  247.     }
  248.     else /* nbox == 0 no visable destination region */
  249.         prgnExposed = (RegionPtr) 0 ;
  250.  
  251.     (* pScreen->RegionDestroy)( prgnDst ) ;
  252.  
  253.     return prgnExposed ;
  254. }
  255.