home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / ppc / ppcCpArea.c < prev    next >
C/C++ Source or Header  |  1991-07-16  |  11KB  |  394 lines

  1. /*
  2.  * Copyright IBM Corporation 1987,1988,1989
  3.  *
  4.  * All Rights Reserved
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted,
  8.  * provided that the above copyright notice appear in all copies and that 
  9.  * both that copyright notice and this permission notice appear in
  10.  * supporting documentation, and that the name of IBM not be
  11.  * used in advertising or publicity pertaining to distribution of the
  12.  * software without specific, written prior permission.
  13.  *
  14.  * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  16.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  17.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  18.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  19.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  20.  * SOFTWARE.
  21.  *
  22. */
  23.  
  24. /* $Header: /andrew/X11/r3src/r3plus/server/ddx/ibm/ppc/RCS/ppcCpArea.c,v 9.4 89/05/07 15:30:29 paul Exp $ */
  25. /* $Source: /andrew/X11/r3src/r3plus/server/ddx/ibm/ppc/RCS/ppcCpArea.c,v $ */
  26.  
  27. #ifndef lint
  28. static char *rcsid = "$Header: /andrew/X11/r3src/r3plus/server/ddx/ibm/ppc/RCS/ppcCpArea.c,v 9.4 89/05/07 15:30:29 paul Exp $" ;
  29. #endif
  30.  
  31. /***********************************************************
  32. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  33. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  34.  
  35.                         All Rights Reserved
  36.  
  37. Permission to use, copy, modify, and distribute this software and its
  38. documentation for any purpose and without fee is hereby granted,
  39. provided that the above copyright notice appear in all copies and that
  40. both that copyright notice and this permission notice appear in
  41. supporting documentation, and that the names of Digital or MIT not be
  42. used in advertising or publicity pertaining to distribution of the
  43. software without specific, written prior permission.
  44.  
  45. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  46. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  47. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  48. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  49. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  50. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51. SOFTWARE.
  52.  
  53. ******************************************************************/
  54.  
  55. #include "X.h"
  56. #include "servermd.h"
  57. #include "misc.h"
  58. #include "regionstr.h"
  59. #include "gcstruct.h"
  60. #include "windowstr.h"
  61. #include "pixmapstr.h"
  62. #include "scrnintstr.h"
  63.  
  64. #include "mi.h"
  65.  
  66. #include "mfb.h"
  67.  
  68. #include "OScompiler.h"
  69.  
  70. #include "ppc.h"
  71. extern int mfbGCPrivateIndex;
  72.  
  73. static RegionPtr
  74. ppcCopyAreaFromPixmap( pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
  75.                width, height, dstx, dsty )
  76. register PixmapPtr pSrcDrawable ;
  77. register DrawablePtr pDstDrawable ;
  78. GC *pGC ;
  79. int srcx, srcy ;
  80. int width, height ;
  81. register int dstx, dsty ;
  82. {
  83.     register RegionPtr prgnDst ;
  84.     ScreenPtr pScreen ;
  85.     RegionPtr prgnExposed ;
  86.     int nbox ;
  87.     /* temporaries for shuffling rectangles */
  88.     xRectangle *origSource ;
  89.     DDXPointRec *origDest ;
  90.     ppcPrivGC * pPriv = (ppcPrivGC *) ( pGC->devPrivates[mfbGCPrivateIndex].ptr ) ;
  91.  
  92.     /* BY HERE, You know you are going Pixmap to window */
  93.     if ( pPriv->fExpose ) {
  94.         if ( !( origSource = (xRectangle *)
  95.             ALLOCATE_LOCAL( sizeof( xRectangle ) ) ) )
  96.             return NULL ;
  97.         origSource->x = srcx ;
  98.         origSource->y = srcy ;
  99.         origSource->width = width ;
  100.         origSource->height = height ;
  101.         if ( !( origDest = (DDXPointRec *)
  102.             ALLOCATE_LOCAL( sizeof( DDXPointRec ) ) ) ) {
  103.             DEALLOCATE_LOCAL( origSource ) ;
  104.             return NULL ;
  105.         }
  106.         origDest->x = dstx ;
  107.         origDest->y = dsty ;
  108.     }
  109.     else {
  110.         origSource = (xRectangle *) 0 ;
  111.         origDest = (DDXPointRec *) 0 ;
  112.     }
  113.  
  114.     /* clip the left and top edges of the source */
  115.     if ( srcx < 0 ) {
  116.         width += srcx ;
  117.         dstx += srcx ;
  118.         srcx = 0 ;
  119.     }
  120.     if ( srcy < 0 ) {
  121.         height += srcy ;
  122.         dsty += srcy ;
  123.         srcy = 0 ;
  124.     }
  125.  
  126.     dstx += pDstDrawable->x ;
  127.     dsty += pDstDrawable->y ;
  128.  
  129.     pScreen = pDstDrawable->pScreen ;
  130.     /* clip the source */
  131.     {
  132.         BoxRec dstBox ;
  133.  
  134.         dstBox.x1 = dstx ;
  135.         dstBox.x2 = dstx + MIN( width, pSrcDrawable->drawable.width - srcx ) ;
  136.         dstBox.y1 = dsty ;
  137.         dstBox.y2 = dsty + MIN( height, pSrcDrawable->drawable.height - srcy ) ;
  138.  
  139.         prgnDst = (* pScreen->RegionCreate)( &dstBox, 1 ) ;
  140.  
  141. if ( ! pPriv->pCompositeClip )
  142.     printf( "Fatal Error! no Composite Clip Region\n" ) ;
  143.  
  144.         /* clip the shape of to the destination composite clip */
  145.         (* pScreen->Intersect)( prgnDst, prgnDst,
  146.                     pPriv->pCompositeClip ) ;
  147.     }
  148.  
  149.     /* nbox != 0 destination region is visable */
  150.     if ( nbox = REGION_NUM_RECTS(prgnDst) ) {
  151.         {
  152.         register BoxPtr pbox = REGION_RECTS(prgnDst);
  153.         register unsigned char *data = pSrcDrawable->devPrivate.ptr ;
  154.         register int stride = pSrcDrawable->devKind ;
  155.         register void (*fnp)() =
  156.             ( (ppcScrnPriv *) ( pScreen->devPrivate ) )->imageFill ;
  157.         register int dx ;
  158.         register int dy ;
  159.  
  160.         dx = srcx - dstx ;
  161.         dy = srcy - dsty ;
  162.  
  163.         for ( ; nbox-- ; pbox++ )
  164.             (* fnp)( pbox->x1, pbox->y1,
  165.                  pbox->x2 - pbox->x1,
  166.                  pbox->y2 - pbox->y1,
  167.                  data + pbox->x1 + dx
  168.                   + ( ( pbox->y1 + dy ) * stride ),
  169.                  stride,
  170.                  pGC->alu, pGC->planemask ) ;
  171.  
  172.         }
  173.         if ( origSource ) {
  174.             prgnExposed = miHandleExposures(
  175.                     (DrawablePtr) pSrcDrawable,
  176.                     pDstDrawable, pGC,
  177.                         origSource->x, origSource->y,
  178.                         origSource->width, origSource->height,
  179.                         origDest->x, origDest->y ) ;
  180.             DEALLOCATE_LOCAL( origSource ) ;
  181.             DEALLOCATE_LOCAL( origDest ) ;
  182.         }
  183.         else
  184.             prgnExposed = (RegionPtr) 0 ;
  185.     }
  186.     else /* nbox == 0 no visable destination region */
  187.         prgnExposed = (RegionPtr) 0 ;
  188.  
  189.     (* pScreen->RegionDestroy)( prgnDst ) ;
  190.  
  191.     return prgnExposed ;
  192. }
  193.  
  194. RegionPtr
  195. ppcCopyArea( pSrcDrawable, pDstDrawable,
  196.          pGC, srcx, srcy, width, height, dstx, dsty )
  197. register DrawablePtr pSrcDrawable ;
  198. register DrawablePtr pDstDrawable ;
  199. GC *pGC ;
  200. int srcx, srcy ;
  201. int width, height ;
  202. int dstx, dsty ;
  203. {
  204.     register BoxPtr pbox ;
  205.     register int dx ;
  206.     register int dy ;
  207.     int nbox ;
  208.     ScreenPtr pScreen ;
  209.     RegionPtr prgnDst ;
  210.     RegionPtr prgnExposed ;
  211.     int alu ;
  212.     unsigned long int pm ;
  213.     /* temporaries for shuffling rectangles */
  214.     xRectangle *origSource ;
  215.     DDXPointRec *origDest ;
  216.     ppcPrivGC *pPriv ;
  217.  
  218.     if ( !( pm = pGC->planemask ) || ( ( alu = pGC->alu ) == GXnoop ) )
  219.         return NULL ;
  220.  
  221.     /*
  222.      * If the destination drawable is not a window then call the mi version.
  223.      */
  224.     if ( pDstDrawable->type != DRAWABLE_WINDOW )
  225.         return miCopyArea( pSrcDrawable, pDstDrawable, pGC,
  226.                    srcx, srcy, width, height, dstx, dsty ) ;
  227.  
  228.     /* BY HERE, You know you are going to a Window */
  229.     if ( !( (WindowPtr) pDstDrawable )->realized )
  230.         return NULL ;
  231.  
  232.     if ( pSrcDrawable->type != DRAWABLE_WINDOW )
  233.         return ppcCopyAreaFromPixmap( (PixmapPtr) pSrcDrawable,
  234.                           pDstDrawable,
  235.                           pGC, srcx, srcy, width,
  236.                           height, dstx, dsty ) ;
  237.  
  238.     pPriv = (ppcPrivGC *) ( pGC->devPrivates[mfbGCPrivateIndex].ptr ) ;
  239.     /* BY HERE, You know you are going from a Window to a Window */
  240.     if ( pPriv->fExpose ) {
  241.         if ( !( origSource = (xRectangle *)
  242.             ALLOCATE_LOCAL( sizeof( xRectangle ) ) ) )
  243.             return NULL ;
  244.         origSource->x = srcx ;
  245.         origSource->y = srcy ;
  246.         origSource->width = width ;
  247.         origSource->height = height ;
  248.         if ( !( origDest = (DDXPointRec *)
  249.             ALLOCATE_LOCAL( sizeof( DDXPointRec ) ) ) ) {
  250.             DEALLOCATE_LOCAL( origSource ) ;
  251.             return NULL ;
  252.         }
  253.         origDest->x = dstx ;
  254.         origDest->y = dsty ;
  255.     }
  256.     else {
  257.         origSource = (xRectangle *) 0 ;
  258.         origDest = (DDXPointRec *) 0 ;
  259.     }
  260.  
  261.     /* clip the left and top edges of the source */
  262.     if ( srcx < 0 ) {
  263.         width += srcx ;
  264.         srcx = pSrcDrawable->x ;
  265.     }
  266.     else
  267.         srcx += pSrcDrawable->x ;
  268.     if ( srcy < 0 ) {
  269.         height += srcy ;
  270.         srcy = pSrcDrawable->y ;
  271.     }
  272.     else
  273.         srcy += pSrcDrawable->y ;
  274.  
  275.     pScreen = pDstDrawable->pScreen ;
  276.     /* clip the source */
  277.     {
  278.         BoxRec srcBox ;
  279.  
  280.         srcBox.x1 = srcx ;
  281.         srcBox.y1 = srcy ;
  282.         srcBox.x2 = srcx + width ;
  283.         srcBox.y2 = srcy + height ;
  284.  
  285.         prgnDst = (* pScreen->RegionCreate)( &srcBox, 1 ) ;
  286.     }
  287.     if ( pGC->subWindowMode == IncludeInferiors ) {
  288.         register RegionPtr prgnSrcClip =
  289.             NotClippedByChildren( (WindowPtr) pSrcDrawable ) ;
  290.         (* pScreen->Intersect)( prgnDst, prgnDst, prgnSrcClip ) ;
  291.         (* pScreen->RegionDestroy)( prgnSrcClip ) ;
  292.     }
  293.     else
  294.         (* pScreen->Intersect)( prgnDst, prgnDst,
  295.                 &(((WindowPtr) pSrcDrawable)->clipList) ) ;
  296.  
  297.     dstx += pDstDrawable->x ;
  298.     dsty += pDstDrawable->y ;
  299.  
  300.     dx = srcx - dstx ;
  301.     dy = srcy - dsty ;
  302.  
  303.     /* clip the shape of the dst to the destination composite clip */
  304.     (* pScreen->TranslateRegion)( prgnDst, -dx, -dy ) ;
  305.     (* pScreen->Intersect)( prgnDst, prgnDst, pPriv->pCompositeClip ) ;
  306.  
  307.     /* nbox != 0 destination region is visable */
  308.     if ( nbox = REGION_NUM_RECTS(prgnDst) ) {
  309.         BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2 ;
  310.  
  311.         pbox = REGION_RECTS(prgnDst);
  312.  
  313.         pboxNew1 = 0 ;
  314.         pboxNew2 = 0 ;
  315.         if ( nbox > 1 ) {
  316.             if ( dy < 0 ) {
  317.                 /* walk source bottom to top */
  318.                 /* keep ordering in each band, */
  319.                 /* reverse order of bands */
  320.                 if ( !( pboxNew1 = (BoxPtr)
  321.                     ALLOCATE_LOCAL( nbox * sizeof (BoxRec) ) ) ) {
  322.                     (* pScreen->RegionDestroy)( prgnDst ) ;
  323.                     return NULL ;
  324.                 }
  325.                 for ( pboxBase = pboxNext = pbox + nbox - 1 ;
  326.                       pboxBase >= pbox ;
  327.                       pboxBase = pboxNext ) {
  328.                     while ( pboxNext >= pbox
  329.                          && pboxBase->y1 == pboxNext->y1 )
  330.                         pboxNext-- ;
  331.                     for ( pboxTmp = pboxNext + 1 ;
  332.                           pboxTmp <= pboxBase ;
  333.                           *pboxNew1++ = *pboxTmp++ )
  334.                         /*DO NOTHING*/ ;
  335.                 }
  336.                 pbox = ( pboxNew1 -= nbox ) ;
  337.             }
  338.             if ( dx < 0 ) {
  339.                 /* walk source right to left */
  340.                 /* reverse order of rects in each band */
  341.                 if ( !( pboxNew2 = (BoxPtr)
  342.                     ALLOCATE_LOCAL( sizeof (BoxRec) * nbox ) ) ) {
  343.                     (* pScreen->RegionDestroy)( prgnDst ) ;
  344.                     return NULL ;
  345.                 }
  346.                 for ( pboxBase = pboxNext = pbox ;
  347.                       pboxBase < pbox + nbox ;
  348.                       pboxBase = pboxNext ) {
  349.                     while ( pboxNext < pbox + nbox
  350.                          && pboxNext->y1 == pboxBase->y1 )
  351.                         pboxNext++ ;
  352.                     for ( pboxTmp = pboxNext ;
  353.                           pboxTmp != pboxBase ;
  354.                           *pboxNew2++ = *--pboxTmp )
  355.                         /*DO NOTHING*/ ;
  356.                 }
  357.                 pbox = ( pboxNew2 -= nbox ) ;
  358.             }
  359.         }
  360.         { /* Here is the "REAL" copy. All clipped and GO. */
  361.         register void (*fnp)() ;
  362.         fnp = ( (ppcScrnPriv *) ( pScreen->devPrivate ) )->blit ;
  363.         for ( ; nbox-- ; pbox++ )
  364.             (* fnp)( alu, pm, pm,
  365.                  pbox->x1 + dx, pbox->y1 + dy,
  366.                  pbox->x1, pbox->y1,
  367.                  pbox->x2 - pbox->x1, pbox->y2 - pbox->y1 ) ;
  368.         }
  369.         /* free up stuff */
  370.         if ( pboxNew1 )
  371.             DEALLOCATE_LOCAL( pboxNew1 ) ;
  372.         if ( pboxNew2 )
  373.             DEALLOCATE_LOCAL( pboxNew2 ) ;
  374.  
  375.         if ( origSource ) {
  376.             prgnExposed = miHandleExposures(
  377.                     pSrcDrawable, pDstDrawable, pGC,
  378.                         origSource->x, origSource->y,
  379.                         origSource->width, origSource->height,
  380.                         origDest->x, origDest->y ) ;
  381.             DEALLOCATE_LOCAL( origSource ) ;
  382.             DEALLOCATE_LOCAL( origDest ) ;
  383.         }
  384.         else
  385.             prgnExposed = (RegionPtr) 0 ;
  386.     }
  387.     else /* nbox == 0 no visable destination region */
  388.         prgnExposed = (RegionPtr) 0 ;
  389.  
  390.     (* pScreen->RegionDestroy)( prgnDst ) ;
  391.  
  392.     return prgnExposed ;
  393. }
  394.