home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / apa16 / apa16GC.c < prev    next >
C/C++ Source or Header  |  1992-02-06  |  30KB  |  1,246 lines

  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.         Copyright IBM Corporation 1987,1988
  26.  
  27.                       All Rights Reserved
  28.  
  29. Permission to use, copy, modify, and distribute this software and its 
  30. documentation for any purpose and without fee is hereby granted, 
  31. provided that the above copyright notice appear in all copies and that
  32. both that copyright notice and this permission notice appear in 
  33. supporting documentation, and that the name of IBM not be
  34. used in advertising or publicity pertaining to distribution of the
  35. software without specific, written prior permission.  
  36.  
  37. IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  38. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  39. IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  41. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  42. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  43. SOFTWARE.
  44.  
  45. ******************************************************************/
  46. /***********************************************************
  47. Copyright 1989 by the Massachusetts Institute of Technology
  48.  
  49.                      All rights reserved.
  50.  
  51. Permission to use, copy, modify, and distribute this software and its
  52. documentation for any purpose and without fee is hereby granted,
  53. provided that the above copyright notice appear in all copies and that
  54. both that copyright notice and this permission notice appear in
  55. supporting documentation, and that the name of the Massachusetts
  56. Institute of Technology (M.I.T.) not be used in advertising or publicity
  57. pertaining to distribution of the software without specific, written
  58. prior permission.
  59.  
  60. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  61. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  62. M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  63. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  64. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  65. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  66. SOFTWARE.
  67.  
  68. ******************************************************************/
  69. /* $XConsortium: apa16GC.c,v 1.3 90/03/21 09:50:21 rws Exp $ */
  70. #include "X.h"
  71. #include "Xmd.h"
  72. #include "Xproto.h"
  73. #include "misc.h"
  74. #include "dixfontstr.h"
  75. #include "fontstruct.h"
  76. #include "gcstruct.h"
  77. #include "windowstr.h"
  78. #include "pixmapstr.h"
  79. #include "scrnintstr.h"
  80. #include "region.h"
  81.  
  82. #include "mfb.h"
  83. #include "mistruct.h"
  84.  
  85. #include "maskbits.h"
  86.  
  87. #include "ibmTrace.h"
  88. #include "apa16Hdwr.h"
  89. #include "apa16Decls.h"
  90. #include "apa16Font.h"
  91.  
  92. #ifndef NO_FUNCTION_PROTOTYPES
  93. extern void ppcPolyRectangle(DrawablePtr, GCPtr, int, xRectangle *);
  94. #else
  95. extern void ppcPolyRectangle();
  96. #endif
  97.  
  98. static void
  99.     apa16DestroyOps(),
  100.  
  101.     apa16ValidateGC(),
  102.     apa16ChangeGC(),
  103.     apa16CopyGC(),
  104.     apa16DestroyGC(),
  105.     apa16ChangeClip(),
  106.     apa16DestroyClip(),
  107.     apa16CopyClip();
  108.  
  109.  
  110.  
  111.  
  112. static GCFuncs    mfbFuncs = {
  113.     apa16ValidateGC,
  114.     apa16ChangeGC,
  115.     apa16CopyGC,
  116.     apa16DestroyGC,
  117.     apa16ChangeClip,
  118.     apa16DestroyClip,
  119.     apa16CopyClip,
  120. };
  121.  
  122. static GCOps    whiteTECopyOps = {
  123.     apa16SolidFS,
  124.     apa16SetSpans,
  125.     apa16PutImage,
  126.     apa16CopyArea,
  127.     apa16CopyPlane,
  128.     apa16PolyPoint,
  129.      apa16LineSS,
  130.     apa16PolySegment,
  131.     ppcPolyRectangle,
  132.     apa16ZeroPolyArcSS,
  133.     miFillPolygon,
  134.     mfbPolyFillRect,
  135.     apa16PolyFillArcSolid,
  136.     apa16PolyText8,
  137.     apa16PolyText16,
  138.     apa16ImageText8,
  139.     apa16ImageText16,
  140.     apa16ImageGlyphBlt,
  141.     apa16PolyGlyphBlt,
  142.     apa16SolidPP,
  143.     NULL,
  144. };
  145.  
  146. static GCOps    blackTECopyOps = {
  147.     apa16SolidFS,
  148.     apa16SetSpans,
  149.     apa16PutImage,
  150.     apa16CopyArea,
  151.     apa16CopyPlane,
  152.     apa16PolyPoint,
  153.     apa16LineSS,
  154.     apa16PolySegment,
  155.     ppcPolyRectangle,
  156.     apa16ZeroPolyArcSS,
  157.     miFillPolygon,
  158.     mfbPolyFillRect,
  159.     apa16PolyFillArcSolid,
  160.     apa16PolyText8,
  161.     apa16PolyText16,
  162.     apa16ImageText8,
  163.     apa16ImageText16,
  164.     apa16ImageGlyphBlt,
  165.     apa16PolyGlyphBlt,
  166.     apa16SolidPP,
  167.     NULL,
  168. };
  169.  
  170. static GCOps    invertWhiteTECopyOps = {
  171.     apa16SolidFS,
  172.     apa16SetSpans,
  173.     apa16PutImage,
  174.     apa16CopyArea,
  175.     apa16CopyPlane,
  176.     apa16PolyPoint,
  177.     apa16LineSS,
  178.     apa16PolySegment,
  179.     ppcPolyRectangle,
  180.     apa16ZeroPolyArcSS,
  181.     miFillPolygon,
  182.     mfbPolyFillRect,
  183.     apa16PolyFillArcSolid,
  184.     apa16PolyText8,
  185.     apa16PolyText16,
  186.     apa16ImageText8,
  187.     apa16ImageText16,
  188.     apa16ImageGlyphBlt,
  189.     apa16PolyGlyphBlt,
  190.     apa16SolidPP,
  191.     NULL,
  192. };
  193.  
  194. static GCOps    invertBlackTECopyOps = {
  195.     apa16SolidFS,
  196.     apa16SetSpans,
  197.     apa16PutImage,
  198.     apa16CopyArea,
  199.     apa16CopyPlane,
  200.     apa16PolyPoint,
  201.     apa16LineSS,
  202.     apa16PolySegment,
  203.     ppcPolyRectangle,
  204.     apa16ZeroPolyArcSS,
  205.     miFillPolygon,
  206.     mfbPolyFillRect,
  207.     apa16PolyFillArcSolid,
  208.     apa16PolyText8,
  209.     apa16PolyText16,
  210.     apa16ImageText8,
  211.     apa16ImageText16,
  212.     apa16ImageGlyphBlt,
  213.     apa16PolyGlyphBlt,
  214.     apa16SolidPP,
  215.     NULL,
  216. };
  217.  
  218. static GCOps    whiteCopyOps = {
  219.     apa16SolidFS,
  220.     apa16SetSpans,
  221.     apa16PutImage,
  222.     apa16CopyArea,
  223.     apa16CopyPlane,
  224.     apa16PolyPoint,
  225.     apa16LineSS,
  226.     apa16PolySegment,
  227.     ppcPolyRectangle,
  228.     apa16ZeroPolyArcSS,
  229.     miFillPolygon,
  230.     mfbPolyFillRect,
  231.     apa16PolyFillArcSolid,
  232.     apa16PolyText8,
  233.     apa16PolyText16,
  234.     apa16ImageText8,
  235.     apa16ImageText16,
  236.     apa16ImageGlyphBlt,
  237.     apa16PolyGlyphBlt,
  238.     apa16SolidPP,
  239.     NULL,
  240. };
  241.  
  242. static GCOps    blackCopyOps = {
  243.     apa16SolidFS,
  244.     apa16SetSpans,
  245.     apa16PutImage,
  246.     apa16CopyArea,
  247.     apa16CopyPlane,
  248.     apa16PolyPoint,
  249.     apa16LineSS,
  250.     apa16PolySegment,
  251.     ppcPolyRectangle,
  252.     apa16ZeroPolyArcSS,
  253.     miFillPolygon,
  254.     mfbPolyFillRect,
  255.     apa16PolyFillArcSolid,
  256.     apa16PolyText8,
  257.     apa16PolyText16,
  258.     apa16ImageText8,
  259.     apa16ImageText16,
  260.     apa16ImageGlyphBlt,
  261.     apa16PolyGlyphBlt,
  262.     apa16SolidPP,
  263.     NULL,
  264. };
  265.  
  266. static GCOps    invertWhiteCopyOps = {
  267.     apa16SolidFS,
  268.     apa16SetSpans,
  269.     apa16PutImage,
  270.     apa16CopyArea,
  271.     apa16CopyPlane,
  272.     apa16PolyPoint,
  273.     apa16LineSS,
  274.     apa16PolySegment,
  275.     ppcPolyRectangle,
  276.     apa16ZeroPolyArcSS,
  277.     miFillPolygon,
  278.     mfbPolyFillRect,
  279.     apa16PolyFillArcSolid,
  280.     apa16PolyText8,
  281.     apa16PolyText16,
  282.     apa16ImageText8,
  283.     apa16ImageText16,
  284.     apa16ImageGlyphBlt,
  285.     apa16PolyGlyphBlt,
  286.     apa16SolidPP,
  287.     NULL,
  288. };
  289.  
  290. static GCOps    invertBlackCopyOps = {
  291.     apa16SolidFS,
  292.     apa16SetSpans,
  293.     apa16PutImage,
  294.     apa16CopyArea,
  295.     apa16CopyPlane,
  296.     apa16PolyPoint,
  297.     apa16LineSS,
  298.     apa16PolySegment,
  299.     ppcPolyRectangle,
  300.     apa16ZeroPolyArcSS,
  301.     miFillPolygon,
  302.     mfbPolyFillRect,
  303.     apa16PolyFillArcSolid,
  304.     apa16PolyText8,
  305.     apa16PolyText16,
  306.     apa16ImageText8,
  307.     apa16ImageText16,
  308.     apa16ImageGlyphBlt,
  309.     apa16PolyGlyphBlt,
  310.     apa16SolidPP,
  311.     NULL,
  312.  
  313. };
  314.  
  315. struct commonOps {
  316.     int            fg, bg;
  317.     int            rrop;
  318.     int            terminalFont;
  319.     GCOps        *ops;
  320.     void        (*fillArea)();
  321. };
  322.  
  323. static struct commonOps mfbCommonOps[] = {
  324.     { 1, 0, RROP_WHITE, 1, &whiteTECopyOps, apa16SolidFillArea },
  325.     { 0, 1, RROP_BLACK, 1, &blackTECopyOps, apa16SolidFillArea },
  326.     { 1, 0, RROP_INVERT, 1, &invertWhiteTECopyOps, apa16SolidFillArea },
  327.     { 1, 0, RROP_INVERT, 1, &invertBlackTECopyOps, apa16SolidFillArea },
  328.     { 1, 0, RROP_WHITE, 0, &whiteCopyOps, apa16SolidFillArea },
  329.     { 0, 1, RROP_BLACK, 0, &blackCopyOps, apa16SolidFillArea },
  330.     { 1, 0, RROP_INVERT, 0, &invertWhiteCopyOps, apa16SolidFillArea },
  331.     { 0, 1, RROP_INVERT, 0, &invertBlackCopyOps, apa16SolidFillArea },
  332. };
  333.  
  334. #define numberCommonOps    (sizeof (mfbCommonOps) / sizeof (mfbCommonOps[0]))
  335.  
  336. static GCOps *
  337. matchCommon (pGC)
  338.     GCPtr   pGC;
  339. {
  340.     int    i;
  341.     struct commonOps    *cop;
  342.     mfbPrivGC        *priv;
  343.  
  344.     if (pGC->lineWidth != 0)
  345.     return 0;
  346.     if (pGC->lineStyle != LineSolid)
  347.     return 0;
  348.     if (pGC->fillStyle != FillSolid)
  349.     return 0;
  350.     if (!pGC->font ||
  351.         pGC->font->info.maxbounds.rightSideBearing -
  352.     pGC->font->info.maxbounds.leftSideBearing > 32)
  353.     return 0;
  354.     priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
  355.     for (i = 0; i < numberCommonOps; i++) {
  356.     cop = &mfbCommonOps[i];
  357.     if (pGC->fgPixel != cop->fg)
  358.         continue;
  359.     if (pGC->bgPixel != cop->bg)
  360.         continue;
  361.     if (priv->rop != cop->rrop)
  362.         continue;
  363.     if (cop->terminalFont && !pGC->font->info.terminalFont)
  364.         continue;
  365.     priv->FillArea = cop->fillArea;
  366.     return cop->ops;
  367.     }
  368.     return 0;
  369. }
  370.  
  371. Bool
  372. apa16CreateGC(pGC)
  373.     register GCPtr pGC;
  374. {
  375.     mfbPrivGC     *pPriv;
  376.  
  377.     TRACE(("apa16CreateGC( pGC= 0x%x)\n",pGC));
  378.  
  379.     pGC->clientClip = NULL;
  380.     pGC->clientClipType = CT_NONE;
  381.     
  382.     /* some of the output primitives aren't really necessary, since
  383.        they will be filled in validategc because of dix/creategc()
  384.        setting all the change bits.  others are necessary because although
  385.        they depend on being a monochrome frame buffer, they don't change 
  386.     */
  387.  
  388.     pGC->ops = &whiteCopyOps;
  389.     pGC->funcs = &mfbFuncs;
  390.  
  391.     /* mfb wants to translate before scan convesion */
  392.     pGC->miTranslate = 1;
  393.  
  394.     /* xxx -- warning: the next line is "special" */
  395.     pPriv = (mfbPrivGC *) (pGC->devPrivates[mfbGCPrivateIndex].ptr);
  396.     pPriv->rop = apa16ReduceRop(pGC->alu, pGC->fgPixel);
  397.     pPriv->fExpose = TRUE;
  398.     pPriv->pRotatedPixmap = NullPixmap;
  399.  
  400.     pPriv->freeCompClip = FALSE;
  401.     pPriv->FillArea = apa16SolidFillArea;
  402.     return TRUE;
  403. }
  404.  
  405. /*ARGSUSED*/
  406. static void
  407. apa16ChangeGC(pGC, mask)
  408.     GC        *pGC;
  409.     BITS32  mask;
  410. {
  411.     return;
  412. }
  413.  
  414. /*ARGSUSED*/
  415. static void
  416. apa16CopyGC (pGCSrc, changes, pGCDst)
  417.     GCPtr    pGCSrc;
  418.     Mask     changes;
  419.     GCPtr    pGCDst;
  420. {
  421.     return;
  422. }
  423.  
  424. static void
  425. apa16DestroyGC(pGC)
  426.     GC             *pGC;
  427. {
  428.     mfbPrivGC *pPriv;
  429.  
  430.     pPriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
  431.     if (pPriv->pRotatedPixmap)
  432.     mfbDestroyPixmap(pPriv->pRotatedPixmap);
  433.     if (pPriv->freeCompClip)
  434.     (*pGC->pScreen->RegionDestroy)(pPriv->pCompositeClip);
  435.     apa16DestroyOps (pGC->ops);
  436. }
  437.  
  438. /*
  439.  * create a private op array for a gc
  440.  */
  441.  
  442. static GCOps *
  443. apa16CreateOps (prototype)
  444.     GCOps    *prototype;
  445. {
  446.     GCOps    *ret;
  447.     extern Bool    Must_have_memory;
  448.  
  449.     ret = (GCOps *) xalloc (sizeof *ret);
  450.     if (!ret)
  451.     return 0;
  452.     *ret = *prototype;
  453.     ret->devPrivate.val = 1;
  454.     return ret;
  455. }
  456.  
  457. static void
  458. apa16DestroyOps (ops)
  459.     GCOps   *ops;
  460. {
  461.     if (ops->devPrivate.val)
  462.     xfree (ops);
  463. }
  464.  
  465. /* Clipping conventions
  466.     if the drawable is a window
  467.         CT_REGION ==> pCompositeClip really is the composite
  468.         CT_other ==> pCompositeClip is the window clip region
  469.     if the drawable is a pixmap
  470.         CT_REGION ==> pCompositeClip is the translated client region
  471.         clipped to the pixmap boundary
  472.         CT_other ==> pCompositeClip is the pixmap bounding box
  473. */
  474.  
  475. /*ARGSUSED*/
  476. static void
  477. apa16ValidateGC(pGC, changes, pDrawable)
  478.     register GCPtr     pGC;
  479.     Mask         changes;
  480.     DrawablePtr     pDrawable;
  481. {
  482.     register mfbPrivGCPtr    devPriv;
  483.     WindowPtr pWin;
  484.     int mask;            /* stateChanges */
  485.     int index;            /* used for stepping through bitfields */
  486.     int    xrot, yrot;        /* rotations for tile and stipple pattern */
  487.     int rrop;            /* reduced rasterop */
  488.                 /* flags for changing the proc vector 
  489.                    and updating things in devPriv
  490.                 */
  491.     int new_rotate, new_rrop,  new_line, new_text, new_fill;
  492.     DDXPointRec    oldOrg;        /* origin of thing GC was last used with */
  493.  
  494.     TRACE(("apa16ValidateGC(pGC=0x%x,changes=0x%x,pDrawable=0x%x)\n",
  495.                         pGC,changes,pDrawable));
  496.  
  497.  
  498.     oldOrg = pGC->lastWinOrg;
  499.  
  500.     pGC->lastWinOrg.x = pDrawable->x;
  501.     pGC->lastWinOrg.y = pDrawable->y;
  502.     if (pDrawable->type == DRAWABLE_WINDOW)
  503.     pWin = (WindowPtr)pDrawable;
  504.     else
  505.     pWin = (WindowPtr)NULL;
  506.  
  507.     /* we need to re-rotate the tile if the previous window/pixmap
  508.        origin (oldOrg) differs from the new window/pixmap origin
  509.        (pGC->lastWinOrg)
  510.     */
  511.     new_rotate = (oldOrg.x != pGC->lastWinOrg.x) ||
  512.          (oldOrg.y != pGC->lastWinOrg.y);
  513.  
  514.     /* XXX -- hewre is more of the index stuff! */
  515.     devPriv = ((mfbPrivGCPtr) (pGC->devPrivates[mfbGCPrivateIndex].ptr));
  516.  
  517.     /*
  518.     if the client clip is different or moved OR
  519.     the subwindowMode has changed OR
  520.     the window's clip has changed since the last validation
  521.     we need to recompute the composite clip
  522.     */
  523.     if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask)) ||
  524.     (changes & GCSubwindowMode) ||
  525.     (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
  526.        )
  527.     {
  528.     ScreenPtr pScreen = pGC->pScreen;
  529.  
  530.     if (pWin)
  531.     {
  532.         Bool freeTmpClip, freeCompClip;
  533.         RegionPtr pregWin;        /* clip for this window, without
  534.                        client clip */
  535.  
  536.         if (pGC->subWindowMode == IncludeInferiors)
  537.         {
  538.             pregWin = NotClippedByChildren(pWin);
  539.         freeTmpClip = TRUE;
  540.         }
  541.         else
  542.         {
  543.             pregWin = &pWin->clipList;
  544.         freeTmpClip = FALSE;
  545.         }
  546.         freeCompClip = devPriv->freeCompClip;
  547.  
  548.         /* if there is no client clip, we can get by with
  549.            just keeping the pointer we got, and remembering
  550.            whether or not should destroy (or maybe re-use)
  551.            it later.  this way, we avoid unnecessary copying
  552.            of regions.  (this wins especially if many clients clip
  553.            by children and have no client clip.)
  554.         */
  555.         if (pGC->clientClipType == CT_NONE)
  556.         {
  557.             if(freeCompClip) 
  558.             (*pScreen->RegionDestroy) (devPriv->pCompositeClip);
  559.             devPriv->pCompositeClip = pregWin;
  560.             devPriv->freeCompClip = freeTmpClip;
  561.         }
  562.         else
  563.         {
  564.         /* we need one 'real' region to put into the composite
  565.            clip.
  566.             if pregWin and the current composite clip 
  567.            are real, we can get rid of one.
  568.             if the current composite clip is real and
  569.            pregWin isn't, intersect the client clip and
  570.            pregWin into the existing composite clip.
  571.             if pregWin is real and the current composite
  572.            clip isn't, intersect pregWin with the client clip
  573.            and replace the composite clip with it.
  574.             if neither is real, create a new region and
  575.            do the intersection into it.
  576.         */
  577.  
  578.         (*pScreen->TranslateRegion)(pGC->clientClip,
  579.                         pDrawable->x + pGC->clipOrg.x,
  580.                         pDrawable->y + pGC->clipOrg.y);
  581.                           
  582.         if (freeCompClip)
  583.         {
  584.             (*pScreen->Intersect)(devPriv->pCompositeClip,
  585.                       pregWin, pGC->clientClip);
  586.             if (freeTmpClip)
  587.             (*pScreen->RegionDestroy)(pregWin);
  588.         }
  589.         else if (freeTmpClip)
  590.         {
  591.             (*pScreen->Intersect)(pregWin, pregWin, pGC->clientClip);
  592.             devPriv->pCompositeClip = pregWin;
  593.         }
  594.         else
  595.         {
  596.             devPriv->pCompositeClip = (*pScreen->RegionCreate)(NullBox,
  597.                                        0);
  598.             (*pScreen->Intersect)(devPriv->pCompositeClip,
  599.                       pregWin, pGC->clientClip);
  600.         }
  601.         devPriv->freeCompClip = TRUE;
  602.         (*pScreen->TranslateRegion)(pGC->clientClip,
  603.                         -(pDrawable->x + pGC->clipOrg.x),
  604.                         -(pDrawable->y + pGC->clipOrg.y));
  605.         }
  606.     } /* end of composite clip for a window */
  607.     else
  608.     {
  609.         BoxRec pixbounds;
  610.  
  611.         pixbounds.x1 = 0;
  612.         pixbounds.y1 = 0;
  613.         pixbounds.x2 = pDrawable->width;
  614.         pixbounds.y2 = pDrawable->height;
  615.  
  616.         if (devPriv->freeCompClip)
  617.             (*pScreen->RegionReset)(devPriv->pCompositeClip, &pixbounds);
  618.         else
  619.         {
  620.         devPriv->freeCompClip = TRUE;
  621.         devPriv->pCompositeClip = (*pScreen->RegionCreate)(&pixbounds,
  622.                                    1);
  623.         }
  624.  
  625.         if (pGC->clientClipType == CT_REGION)
  626.         {
  627.         (*pScreen->TranslateRegion)(devPriv->pCompositeClip,
  628.                         -pGC->clipOrg.x, -pGC->clipOrg.y);
  629.         (*pScreen->Intersect)(devPriv->pCompositeClip, 
  630.                       devPriv->pCompositeClip,
  631.                       pGC->clientClip);
  632.         (*pScreen->TranslateRegion)(devPriv->pCompositeClip,
  633.                         pGC->clipOrg.x, pGC->clipOrg.y);
  634.         }
  635.     } /* end of composite clip for pixmap */
  636.     }
  637.  
  638.     new_rrop = FALSE;
  639.     new_line = FALSE;
  640.     new_text = FALSE;
  641.     new_fill = FALSE;
  642.  
  643.     mask = changes;
  644.     mask &= ~(GCPlaneMask | GCCapStyle | GCFillRule |
  645.           GCSubwindowMode | GCGraphicsExposures | GCClipXOrigin |
  646.           GCClipYOrigin | GCClipMask | GCDashOffset | GCDashList |
  647.           GCArcMode);
  648.     while (mask)
  649.     {
  650.     index = lowbit (mask);
  651.     mask &= ~index;
  652.  
  653.     /* this switch acculmulates a list of which procedures
  654.        might have to change due to changes in the GC.  in
  655.        some cases (e.g. changing one 16 bit tile for another)
  656.        we might not really need a change, but the code is
  657.        being paranoid.
  658.        this sort of batching wins if, for example, the alu
  659.        and the font have been changed, or any other pair
  660.        of items that both change the same thing.
  661.     */
  662.     switch (index)
  663.     {
  664.       case GCFunction:
  665.       case GCForeground:
  666.         new_rrop = TRUE;
  667.         break;
  668.       case GCBackground:
  669.         new_rrop = TRUE;    /* for opaque stipples */
  670.         break;
  671.       case GCLineStyle:
  672.       case GCLineWidth:
  673.       case GCJoinStyle:
  674.         new_line = TRUE;
  675.         break;
  676.       case GCFillStyle:
  677.         new_fill = TRUE;
  678.         break;
  679.       case GCTile:
  680.         if(pGC->tileIsPixel)
  681.         break;
  682.         new_rotate = TRUE;
  683.         new_fill = TRUE;
  684.         break;
  685.  
  686.       case GCStipple:
  687.         if(pGC->stipple == (PixmapPtr)NULL)
  688.         break;
  689.         new_rotate = TRUE;
  690.         new_fill = TRUE;
  691.         break;
  692.  
  693.       case GCTileStipXOrigin:
  694.         new_rotate = TRUE;
  695.         break;
  696.  
  697.       case GCTileStipYOrigin:
  698.         new_rotate = TRUE;
  699.         break;
  700.  
  701.       case GCFont:
  702.         new_text = TRUE;
  703.         break;
  704.       default:
  705.         break;
  706.     }
  707.     }
  708.  
  709.     /* deal with the changes we've collected .
  710.        new_rrop must be done first because subsequent things
  711.        depend on it.
  712.     */
  713.  
  714.     if(new_rotate || new_fill)
  715.     {
  716.       extern unsigned int *apa16CurrentTileBits;
  717.       Bool new_pix = FALSE;
  718.  
  719.     /* figure out how much to rotate */
  720.     xrot = pGC->patOrg.x;
  721.     yrot = pGC->patOrg.y;
  722.     xrot += pDrawable->x;
  723.     yrot += pDrawable->y;
  724.  
  725.     switch (pGC->fillStyle)
  726.     {
  727.     case FillTiled:
  728.         /* copy current tile and stipple */
  729.         if (!pGC->tileIsPixel && (pGC->tile.pixmap->drawable.width <= 32) &&
  730.             !(pGC->tile.pixmap->drawable.width & (pGC->tile.pixmap->drawable.width - 1)))
  731.         {
  732.             mfbCopyRotatePixmap(pGC->tile.pixmap, 
  733.                     &devPriv->pRotatedPixmap, xrot, yrot);
  734.         new_pix = TRUE;
  735.         }
  736.         break;
  737.     case FillStippled:
  738.     case FillOpaqueStippled:
  739.         if (pGC->stipple && (pGC->stipple->drawable.width <= 32) &&
  740.             !(pGC->stipple->drawable.width & (pGC->stipple->drawable.width - 1)))
  741.         {
  742.             if (pGC->stipple == pGC->pScreen->PixmapPerDepth[0])
  743.             {
  744.             if (pGC->stipple->drawable.width != 32)
  745.             mfbPadPixmap(pGC->stipple);
  746.             if (devPriv->pRotatedPixmap)
  747.                 mfbDestroyPixmap(devPriv->pRotatedPixmap);
  748.             devPriv->pRotatedPixmap = pGC->stipple;
  749.             ++devPriv->pRotatedPixmap->refcnt;
  750.             }
  751.             else
  752.             {
  753.             mfbCopyRotatePixmap(pGC->stipple,
  754.                     &devPriv->pRotatedPixmap, xrot, yrot);
  755.             }
  756.         new_pix = TRUE;
  757.         }
  758.     }
  759. /* Destroy any previously rotate tile or stipple */
  760.       if (!new_pix && devPriv->pRotatedPixmap) 
  761.     {
  762.       mfbDestroyPixmap(devPriv->pRotatedPixmap);
  763.       devPriv->pRotatedPixmap = (PixmapPtr)NULL;
  764.     }
  765. /* For an apa16 - if we are destroying old rotate pixmap or have a new, 
  766.    clear the off screen cache 
  767.  */
  768.       apa16CurrentTileBits=    NULL;
  769.     }
  770.  
  771.     /*
  772.      * duck out here when the GC is unchanged
  773.      */
  774.  
  775.     if (!changes)
  776.     return;
  777.  
  778.     if (new_rrop || new_fill)
  779.     {
  780.     rrop = apa16ReduceRop(pGC->alu, pGC->fgPixel);
  781.     devPriv->rop = rrop;
  782.     new_fill = TRUE;
  783.     /* FillArea raster op is GC's for tile filling,
  784.        and the reduced rop for solid and stipple
  785.     */
  786.     if (pGC->fillStyle == FillTiled)
  787.         devPriv->ropFillArea = pGC->alu;
  788.     else
  789.         devPriv->ropFillArea = rrop;
  790.  
  791.     /* opaque stipples:
  792.        fg    bg    ropOpStip    fill style
  793.        1    0    alu        tile
  794.        0    1    inverseAlu    tile
  795.        1    1    rrop(fg, alu)    solid
  796.        0    0    rrop(fg, alu)    solid
  797.     Note that rrop(fg, alu) == mfbPrivGC.rop, so we don't really need to
  798.     compute it.
  799.     */
  800.         if (pGC->fillStyle == FillOpaqueStippled)
  801.         {
  802.         if (pGC->fgPixel != pGC->bgPixel)
  803.         {
  804.             if (pGC->fgPixel)
  805.             devPriv->ropOpStip = pGC->alu;
  806.             else
  807.             devPriv->ropOpStip = InverseAlu[pGC->alu];
  808.         }
  809.         else
  810.             devPriv->ropOpStip = rrop;
  811.         devPriv->ropFillArea = devPriv->ropOpStip;
  812.         }
  813.     }
  814.     else
  815.     rrop = devPriv->rop;
  816.  
  817.     if (new_text && pGC->font)
  818.       {
  819.     apa16FontPtr aFont = (apa16FontPtr)FontGetPrivate(pGC->font,apa16FontPrivateIndex);
  820.     if (aFont && aFont->afCache == 0)
  821.       apa16CacheFont(aFont);
  822.       }
  823.  
  824.  
  825.     if (new_line || new_fill || new_text)
  826.     {
  827.     GCOps    *newops;
  828.  
  829.     if (newops = matchCommon (pGC))
  830.      {
  831.         if (pGC->ops->devPrivate.val)
  832.         apa16DestroyOps (pGC->ops);
  833.         pGC->ops = newops;
  834.         new_line = new_fill = new_text = 0;
  835.     }
  836.      else
  837.      {
  838.         if (!pGC->ops->devPrivate.val)
  839.          {
  840.         pGC->ops = apa16CreateOps (pGC->ops);
  841.         pGC->ops->devPrivate.val = 1;
  842.         }
  843.     }
  844.     }
  845.  
  846.     if (new_line || new_fill)
  847.     {
  848.         if (pGC->lineWidth == 0)
  849.         {
  850.             if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid)
  851.                 && ((rrop == RROP_WHITE) || (rrop == RROP_BLACK)))
  852.                 pGC->ops->PolyArc = apa16ZeroPolyArcSS;
  853.             else
  854.                 pGC->ops->PolyArc = miZeroPolyArc;
  855.         }
  856.         else
  857.             pGC->ops->PolyArc = miPolyArc;
  858.     if (pGC->fillStyle == FillSolid && pGC->joinStyle == JoinMiter)
  859.       pGC->ops->PolyRectangle = ppcPolyRectangle;
  860.     else
  861.       pGC->ops->PolyRectangle = miPolyRectangle;
  862.     if (pGC->lineStyle == LineSolid)
  863.     {
  864.         if(pGC->lineWidth == 0)
  865.         {
  866.             if (pGC->fillStyle == FillSolid) {
  867.             pGC->ops->Polylines = apa16LineSS;
  868.             pGC->ops->PolySegment = apa16PolySegment;
  869.         } else {
  870.             pGC->ops->Polylines = miZeroLine;
  871.             pGC->ops->PolySegment = miPolySegment;
  872.         }
  873.         }
  874.         else
  875.         {
  876.         pGC->ops->Polylines = miWideLine;
  877.         pGC->ops->PolySegment = miPolySegment;
  878.         }
  879.     } else {
  880.         pGC->ops->PolySegment = miPolySegment;
  881.         if(pGC->lineWidth == 0) 
  882.             pGC->ops->Polylines = apa16DashLine;
  883.         else
  884.             pGC->ops->Polylines = miWideDash;
  885.     }
  886.     }
  887.  
  888.     if (new_text || new_fill)
  889.     {
  890.     pGC->ops->ImageGlyphBlt = apa16ImageGlyphBlt;
  891.  
  892.     if (pGC->fillStyle == FillSolid ||
  893.         (pGC->fillStyle == FillOpaqueStippled &&
  894.          pGC->fgPixel == pGC->bgPixel))
  895.     {
  896.         pGC->ops->PolyGlyphBlt    = apa16PolyGlyphBlt;
  897.         pGC->ops->PolyText8        = apa16PolyText8;
  898.         pGC->ops->PolyText16    = apa16PolyText16;
  899.         pGC->ops->ImageText8    = apa16ImageText8;
  900.         pGC->ops->ImageText16    = apa16ImageText16;
  901.     }
  902.     else
  903.     {
  904.         pGC->ops->PolyGlyphBlt    = miPolyGlyphBlt;
  905.         pGC->ops->PolyText8        = miPolyText8;
  906.         pGC->ops->PolyText16    = miPolyText16;
  907.         pGC->ops->ImageText8    = apa16ImageText8;
  908.         pGC->ops->ImageText16    = apa16ImageText16;
  909.     }
  910.     }
  911.  
  912.     if (new_fill)
  913.     {
  914.     /* install a suitable fillspans */
  915.     pGC->ops->PushPixels = apa16PushPixels;
  916.     if ((pGC->fillStyle == FillSolid) ||
  917.         ((pGC->fillStyle == FillOpaqueStippled) &&
  918.          (pGC->fgPixel == pGC->bgPixel)))
  919.     {
  920.         pGC->ops->PushPixels = apa16SolidPP;
  921.         switch(devPriv->rop)
  922.         {
  923.           case RROP_WHITE:
  924.           case RROP_BLACK:
  925.           case RROP_INVERT:
  926.         pGC->ops->FillSpans = apa16SolidFS;
  927.         break;
  928.           case RROP_NOP:
  929.         pGC->ops->FillSpans = NoopDDA;
  930.         break;
  931.         }
  932.     }
  933.     /* beyond this point, opaqueStippled ==> fg != bg */
  934.     else if (((pGC->fillStyle == FillTiled) ||
  935.          (pGC->fillStyle == FillOpaqueStippled)) &&
  936.          !devPriv->pRotatedPixmap)
  937.     {
  938.         pGC->ops->FillSpans = apa16UnnaturalTileFS;
  939.     }
  940.     else if ((pGC->fillStyle == FillStippled) && !devPriv->pRotatedPixmap)
  941.     {
  942.         pGC->ops->FillSpans = apa16UnnaturalStippleFS;
  943.     }
  944.     else if (pGC->fillStyle == FillStippled)
  945.     {
  946.         switch(devPriv->rop)
  947.         {
  948.           case RROP_WHITE:
  949.         pGC->ops->FillSpans = mfbWhiteStippleFS;
  950.         break;
  951.           case RROP_INVERT:
  952.         pGC->ops->FillSpans = mfbInvertStippleFS;
  953.         break;
  954.           case RROP_BLACK:
  955.         pGC->ops->FillSpans = mfbBlackStippleFS;
  956.         break;
  957.           case RROP_NOP:
  958.         pGC->ops->FillSpans = NoopDDA;
  959.         break;
  960.         }
  961.     }
  962.     else /* overload tiles to do parti-colored opaque stipples */
  963.     {
  964.         pGC->ops->FillSpans = apa16TileFS;
  965.     }
  966.         if (pGC->fillStyle == FillSolid)
  967.             pGC->ops->PolyFillArc = apa16PolyFillArcSolid;
  968.         else
  969.             pGC->ops->PolyFillArc = miPolyFillArc;
  970.     /* the rectangle code doesn't deal with opaque stipples that
  971.        are two colors -- we can fool it for fg==bg, though
  972.      */
  973.     if ((((pGC->fillStyle == FillTiled) ||
  974.         (pGC->fillStyle == FillStippled)) && 
  975.          !devPriv->pRotatedPixmap) ||
  976.         ((pGC->fillStyle == FillOpaqueStippled) &&
  977.          (pGC->fgPixel != pGC->bgPixel))
  978.        )
  979.     {
  980.         pGC->ops->PolyFillRect = miPolyFillRect;
  981.     }
  982.     else /* deal with solids and natural stipples and tiles */
  983.     {
  984.         pGC->ops->PolyFillRect = mfbPolyFillRect;
  985.  
  986.         if ((pGC->fillStyle == FillSolid) ||
  987.         ((pGC->fillStyle == FillOpaqueStippled) &&
  988.          (pGC->fgPixel == pGC->bgPixel)))
  989.         {
  990.         switch(devPriv->rop)
  991.         {
  992.           case RROP_WHITE:
  993.           case RROP_BLACK:
  994.           case RROP_INVERT:
  995.             devPriv->FillArea = apa16SolidFillArea;
  996.             break;
  997.           case RROP_NOP:
  998.             devPriv->FillArea = NoopDDA;
  999.             break;
  1000.         }
  1001.         }
  1002.         else if (pGC->fillStyle == FillStippled)
  1003.         {
  1004.         switch(devPriv->rop)
  1005.         {
  1006.           case RROP_WHITE:
  1007.           case RROP_BLACK:
  1008.           case RROP_INVERT:
  1009.             devPriv->FillArea = apa16StippleFillArea;
  1010.             break;
  1011.           case RROP_NOP:
  1012.             devPriv->FillArea = NoopDDA;
  1013.             break;
  1014.         }
  1015.         }
  1016.         else /* deal with tiles */
  1017.         {
  1018.         devPriv->FillArea = apa16TileArea32;
  1019.         }
  1020.     } /* end of natural rectangles */
  1021.     } /* end of new_fill */
  1022. }
  1023.  
  1024. /* table to map alu(src, dst) to alu(~src, dst) 
  1025. int InverseAlu[16] = {
  1026.     GXclear,
  1027.     GXandInverted,
  1028.     GXnor,
  1029.     GXcopyInverted,
  1030.     GXand,
  1031.     GXnoop,
  1032.     GXequiv,
  1033.     GXorInverted,
  1034.     GXandReverse,
  1035.     GXxor,
  1036.     GXinvert,
  1037.     GXnand,
  1038.     GXcopy,
  1039.     GXor,
  1040.     GXorReverse,
  1041.     GXset
  1042. };
  1043. */
  1044. int
  1045. apa16ReduceRop(alu, src)
  1046.     register unsigned char alu;
  1047.     register Pixel src;
  1048. {
  1049.     int rop;
  1050.     if (src == 0)    /* src is black */
  1051.     {
  1052.     switch(alu)
  1053.     {
  1054.       case GXclear:
  1055.         rop = RROP_BLACK;
  1056.         break;
  1057.  
  1058.       case GXand:
  1059.         rop = RROP_BLACK;
  1060.         break;
  1061.       case GXandReverse:
  1062.         rop = RROP_BLACK;
  1063.         break;
  1064.       case GXcopy:
  1065.         rop = RROP_BLACK;
  1066.         break;
  1067.       case GXandInverted:
  1068.         rop = RROP_NOP;
  1069.         break;
  1070.       case GXnoop:
  1071.         rop = RROP_NOP;
  1072.         break;
  1073.       case GXxor:
  1074.         rop = RROP_NOP;
  1075.         break;
  1076.       case GXor:
  1077.         rop = RROP_NOP;
  1078.         break;
  1079.       case GXnor:
  1080.         rop = RROP_INVERT;
  1081.         break;
  1082.       case GXequiv:
  1083.         rop = RROP_INVERT;
  1084.         break;
  1085.       case GXinvert:
  1086.         rop = RROP_INVERT;
  1087.         break;
  1088.       case GXorReverse:
  1089.         rop = RROP_INVERT;
  1090.         break;
  1091.       case GXcopyInverted:
  1092.         rop = RROP_WHITE;
  1093.         break;
  1094.       case GXorInverted:
  1095.         rop = RROP_WHITE;
  1096.         break;
  1097.       case GXnand:
  1098.         rop = RROP_WHITE;
  1099.         break;
  1100.       case GXset:
  1101.         rop = RROP_WHITE;
  1102.         break;
  1103.     }
  1104.     }
  1105.     else /* src is white */
  1106.     {
  1107.     switch(alu)
  1108.     {
  1109.       case GXclear:
  1110.         rop = RROP_BLACK;
  1111.         break;
  1112.       case GXand:
  1113.         rop = RROP_NOP;
  1114.         break;
  1115.       case GXandReverse:
  1116.         rop = RROP_INVERT;
  1117.         break;
  1118.       case GXcopy:
  1119.         rop = RROP_WHITE;
  1120.         break;
  1121.       case GXandInverted:
  1122.         rop = RROP_BLACK;
  1123.         break;
  1124.       case GXnoop:
  1125.         rop = RROP_NOP;
  1126.         break;
  1127.       case GXxor:
  1128.         rop = RROP_INVERT;
  1129.         break;
  1130.       case GXor:
  1131.         rop = RROP_WHITE;
  1132.         break;
  1133.       case GXnor:
  1134.         rop = RROP_BLACK;
  1135.         break;
  1136.       case GXequiv:
  1137.         rop = RROP_NOP;
  1138.         break;
  1139.       case GXinvert:
  1140.         rop = RROP_INVERT;
  1141.         break;
  1142.       case GXorReverse:
  1143.         rop = RROP_WHITE;
  1144.         break;
  1145.       case GXcopyInverted:
  1146.         rop = RROP_BLACK;
  1147.         break;
  1148.       case GXorInverted:
  1149.         rop = RROP_NOP;
  1150.         break;
  1151.       case GXnand:
  1152.         rop = RROP_INVERT;
  1153.         break;
  1154.       case GXset:
  1155.         rop = RROP_WHITE;
  1156.         break;
  1157.     }
  1158.     }
  1159.     return rop;
  1160. }
  1161.  
  1162. static void
  1163. apa16DestroyClip(pGC)
  1164.     GCPtr    pGC;
  1165. {
  1166.     if(pGC->clientClipType == CT_NONE)
  1167.     return;
  1168.     else if (pGC->clientClipType == CT_PIXMAP)
  1169.     {
  1170.     mfbDestroyPixmap((PixmapPtr)(pGC->clientClip));
  1171.     }
  1172.     else
  1173.     {
  1174.     /* we know we'll never have a list of rectangles, since
  1175.        ChangeClip immediately turns them into a region 
  1176.     */
  1177.         (*pGC->pScreen->RegionDestroy)(pGC->clientClip);
  1178.     }
  1179.     pGC->clientClip = NULL;
  1180.     pGC->clientClipType = CT_NONE;
  1181. }
  1182.  
  1183. static void
  1184. apa16ChangeClip(pGC, type, pvalue, nrects)
  1185.     GCPtr        pGC;
  1186.     unsigned int    type;
  1187.     pointer        pvalue;
  1188.     int            nrects;
  1189. {
  1190.     apa16DestroyClip(pGC);
  1191.     if(type == CT_PIXMAP)
  1192.     {
  1193.     /* convert the pixmap to a region */
  1194.     pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pvalue);
  1195.     /* you wouldn't do this if you were leaving the pixmap in
  1196.        rather than converting it.
  1197.     */
  1198.     (*pGC->pScreen->DestroyPixmap)(pvalue);
  1199.     }
  1200.     else if (type == CT_REGION)
  1201.     {
  1202.     /* stuff the region in the GC */
  1203.     pGC->clientClip = pvalue;
  1204.     }
  1205.     else if (type != CT_NONE)
  1206.     {
  1207.     pGC->clientClip = (pointer) (*pGC->pScreen->RectsToRegion)(nrects,
  1208.                             (xRectangle *)pvalue,
  1209.                             type);
  1210.     /* Check for invalid request from client */
  1211.     if (((RegionPtr)pGC->clientClip)->extents.x1 >
  1212.         ((RegionPtr)pGC->clientClip)->extents.x2)
  1213.       {
  1214.         (*pGC->pScreen->RegionDestroy)(pGC->clientClip);
  1215.         pGC->clientClip = 0;
  1216.       }
  1217.     xfree(pvalue);
  1218.     }
  1219.     pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION :
  1220.         CT_NONE;
  1221.     pGC->stateChanges |= GCClipMask;
  1222. }
  1223.  
  1224. static void
  1225. apa16CopyClip (pgcDst, pgcSrc)
  1226.     GCPtr pgcDst, pgcSrc;
  1227. {
  1228.     RegionPtr prgnNew;
  1229.  
  1230.     switch(pgcSrc->clientClipType)
  1231.     {
  1232.       case CT_PIXMAP:
  1233.     ((PixmapPtr) pgcSrc->clientClip)->refcnt++;
  1234.     /* Fall through !! */
  1235.       case CT_NONE:
  1236.     apa16ChangeClip(pgcDst, pgcSrc->clientClipType, pgcSrc->clientClip, 0);
  1237.     break;
  1238.       case CT_REGION:
  1239.     prgnNew = (*pgcSrc->pScreen->RegionCreate)(NULL, 1);
  1240.     (*pgcSrc->pScreen->RegionCopy)(prgnNew,
  1241.                        (RegionPtr)(pgcSrc->clientClip));
  1242.     apa16ChangeClip(pgcDst, CT_REGION, (pointer)prgnNew, 0);
  1243.     break;
  1244.     }
  1245. }
  1246.