GC.c revision 35c4bbdf
105b261ecSmrg/* 205b261ecSmrg 305b261ecSmrgCopyright 1993 by Davor Matic 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software 605b261ecSmrgand its documentation for any purpose is hereby granted without fee, 705b261ecSmrgprovided that the above copyright notice appear in all copies and that 805b261ecSmrgboth that copyright notice and this permission notice appear in 905b261ecSmrgsupporting documentation. Davor Matic makes no representations about 1005b261ecSmrgthe suitability of this software for any purpose. It is provided "as 1105b261ecSmrgis" without express or implied warranty. 1205b261ecSmrg 1305b261ecSmrg*/ 1405b261ecSmrg 1505b261ecSmrg#ifdef HAVE_XNEST_CONFIG_H 1605b261ecSmrg#include <xnest-config.h> 1705b261ecSmrg#endif 1805b261ecSmrg 1905b261ecSmrg#include <X11/X.h> 2005b261ecSmrg#include <X11/Xproto.h> 2105b261ecSmrg#include "gcstruct.h" 2205b261ecSmrg#include "windowstr.h" 2305b261ecSmrg#include "pixmapstr.h" 2405b261ecSmrg#include "scrnintstr.h" 2505b261ecSmrg#include <X11/fonts/fontstruct.h> 2605b261ecSmrg#include "mistruct.h" 2705b261ecSmrg#include "region.h" 2805b261ecSmrg 2905b261ecSmrg#include "Xnest.h" 3005b261ecSmrg 3105b261ecSmrg#include "Display.h" 3235c4bbdfSmrg#include "XNGC.h" 3305b261ecSmrg#include "GCOps.h" 3405b261ecSmrg#include "Drawable.h" 3505b261ecSmrg#include "XNFont.h" 3605b261ecSmrg#include "Color.h" 3705b261ecSmrg 386747b715SmrgDevPrivateKeyRec xnestGCPrivateKeyRec; 3905b261ecSmrg 4005b261ecSmrgstatic GCFuncs xnestFuncs = { 4135c4bbdfSmrg xnestValidateGC, 4235c4bbdfSmrg xnestChangeGC, 4335c4bbdfSmrg xnestCopyGC, 4435c4bbdfSmrg xnestDestroyGC, 4535c4bbdfSmrg xnestChangeClip, 4635c4bbdfSmrg xnestDestroyClip, 4735c4bbdfSmrg xnestCopyClip, 4805b261ecSmrg}; 4905b261ecSmrg 5005b261ecSmrgstatic GCOps xnestOps = { 5135c4bbdfSmrg xnestFillSpans, 5235c4bbdfSmrg xnestSetSpans, 5335c4bbdfSmrg xnestPutImage, 5435c4bbdfSmrg xnestCopyArea, 5535c4bbdfSmrg xnestCopyPlane, 5635c4bbdfSmrg xnestPolyPoint, 5735c4bbdfSmrg xnestPolylines, 5835c4bbdfSmrg xnestPolySegment, 5935c4bbdfSmrg xnestPolyRectangle, 6035c4bbdfSmrg xnestPolyArc, 6135c4bbdfSmrg xnestFillPolygon, 6235c4bbdfSmrg xnestPolyFillRect, 6335c4bbdfSmrg xnestPolyFillArc, 6435c4bbdfSmrg xnestPolyText8, 6535c4bbdfSmrg xnestPolyText16, 6635c4bbdfSmrg xnestImageText8, 6735c4bbdfSmrg xnestImageText16, 6835c4bbdfSmrg xnestImageGlyphBlt, 6935c4bbdfSmrg xnestPolyGlyphBlt, 7035c4bbdfSmrg xnestPushPixels 7105b261ecSmrg}; 7205b261ecSmrg 7305b261ecSmrgBool 7405b261ecSmrgxnestCreateGC(GCPtr pGC) 7505b261ecSmrg{ 7635c4bbdfSmrg pGC->funcs = &xnestFuncs; 7735c4bbdfSmrg pGC->ops = &xnestOps; 7835c4bbdfSmrg 7935c4bbdfSmrg pGC->miTranslate = 1; 8035c4bbdfSmrg 8135c4bbdfSmrg xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay, 8235c4bbdfSmrg xnestDefaultDrawables[pGC->depth], 8335c4bbdfSmrg 0L, NULL); 8435c4bbdfSmrg 8535c4bbdfSmrg return True; 8605b261ecSmrg} 8705b261ecSmrg 8805b261ecSmrgvoid 8905b261ecSmrgxnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 9005b261ecSmrg{ 9105b261ecSmrg} 9205b261ecSmrg 9305b261ecSmrgvoid 9405b261ecSmrgxnestChangeGC(GCPtr pGC, unsigned long mask) 9505b261ecSmrg{ 9635c4bbdfSmrg XGCValues values; 9735c4bbdfSmrg 9835c4bbdfSmrg if (mask & GCFunction) 9935c4bbdfSmrg values.function = pGC->alu; 10035c4bbdfSmrg 10135c4bbdfSmrg if (mask & GCPlaneMask) 10235c4bbdfSmrg values.plane_mask = pGC->planemask; 10335c4bbdfSmrg 10435c4bbdfSmrg if (mask & GCForeground) 10535c4bbdfSmrg values.foreground = xnestPixel(pGC->fgPixel); 10635c4bbdfSmrg 10735c4bbdfSmrg if (mask & GCBackground) 10835c4bbdfSmrg values.background = xnestPixel(pGC->bgPixel); 10935c4bbdfSmrg 11035c4bbdfSmrg if (mask & GCLineWidth) 11135c4bbdfSmrg values.line_width = pGC->lineWidth; 11235c4bbdfSmrg 11335c4bbdfSmrg if (mask & GCLineStyle) 11435c4bbdfSmrg values.line_style = pGC->lineStyle; 11535c4bbdfSmrg 11635c4bbdfSmrg if (mask & GCCapStyle) 11735c4bbdfSmrg values.cap_style = pGC->capStyle; 11835c4bbdfSmrg 11935c4bbdfSmrg if (mask & GCJoinStyle) 12035c4bbdfSmrg values.join_style = pGC->joinStyle; 12135c4bbdfSmrg 12235c4bbdfSmrg if (mask & GCFillStyle) 12335c4bbdfSmrg values.fill_style = pGC->fillStyle; 12435c4bbdfSmrg 12535c4bbdfSmrg if (mask & GCFillRule) 12635c4bbdfSmrg values.fill_rule = pGC->fillRule; 12735c4bbdfSmrg 12835c4bbdfSmrg if (mask & GCTile) { 12935c4bbdfSmrg if (pGC->tileIsPixel) 13035c4bbdfSmrg mask &= ~GCTile; 13135c4bbdfSmrg else 13235c4bbdfSmrg values.tile = xnestPixmap(pGC->tile.pixmap); 13335c4bbdfSmrg } 13435c4bbdfSmrg 13535c4bbdfSmrg if (mask & GCStipple) 13635c4bbdfSmrg values.stipple = xnestPixmap(pGC->stipple); 13735c4bbdfSmrg 13835c4bbdfSmrg if (mask & GCTileStipXOrigin) 13935c4bbdfSmrg values.ts_x_origin = pGC->patOrg.x; 14035c4bbdfSmrg 14135c4bbdfSmrg if (mask & GCTileStipYOrigin) 14235c4bbdfSmrg values.ts_y_origin = pGC->patOrg.y; 14335c4bbdfSmrg 14435c4bbdfSmrg if (mask & GCFont) 14535c4bbdfSmrg values.font = xnestFont(pGC->font); 14635c4bbdfSmrg 14735c4bbdfSmrg if (mask & GCSubwindowMode) 14835c4bbdfSmrg values.subwindow_mode = pGC->subWindowMode; 14935c4bbdfSmrg 15035c4bbdfSmrg if (mask & GCGraphicsExposures) 15135c4bbdfSmrg values.graphics_exposures = pGC->graphicsExposures; 15235c4bbdfSmrg 15335c4bbdfSmrg if (mask & GCClipXOrigin) 15435c4bbdfSmrg values.clip_x_origin = pGC->clipOrg.x; 15535c4bbdfSmrg 15635c4bbdfSmrg if (mask & GCClipYOrigin) 15735c4bbdfSmrg values.clip_y_origin = pGC->clipOrg.y; 15835c4bbdfSmrg 15935c4bbdfSmrg if (mask & GCClipMask) /* this is handled in change clip */ 16035c4bbdfSmrg mask &= ~GCClipMask; 16135c4bbdfSmrg 16235c4bbdfSmrg if (mask & GCDashOffset) 16335c4bbdfSmrg values.dash_offset = pGC->dashOffset; 16435c4bbdfSmrg 16535c4bbdfSmrg if (mask & GCDashList) { 16635c4bbdfSmrg mask &= ~GCDashList; 16735c4bbdfSmrg XSetDashes(xnestDisplay, xnestGC(pGC), 16835c4bbdfSmrg pGC->dashOffset, (char *) pGC->dash, pGC->numInDashList); 16935c4bbdfSmrg } 17035c4bbdfSmrg 17135c4bbdfSmrg if (mask & GCArcMode) 17235c4bbdfSmrg values.arc_mode = pGC->arcMode; 17335c4bbdfSmrg 17435c4bbdfSmrg if (mask) 17535c4bbdfSmrg XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values); 17605b261ecSmrg} 17705b261ecSmrg 17805b261ecSmrgvoid 17905b261ecSmrgxnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) 18005b261ecSmrg{ 18135c4bbdfSmrg XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst)); 18205b261ecSmrg} 18305b261ecSmrg 18405b261ecSmrgvoid 18505b261ecSmrgxnestDestroyGC(GCPtr pGC) 18605b261ecSmrg{ 18735c4bbdfSmrg XFreeGC(xnestDisplay, xnestGC(pGC)); 18805b261ecSmrg} 18905b261ecSmrg 19005b261ecSmrgvoid 19135c4bbdfSmrgxnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects) 19205b261ecSmrg{ 19335c4bbdfSmrg int i; 19435c4bbdfSmrg BoxPtr pBox; 19535c4bbdfSmrg XRectangle *pRects; 19605b261ecSmrg 19735c4bbdfSmrg xnestDestroyClip(pGC); 19805b261ecSmrg 19935c4bbdfSmrg switch (type) { 20005b261ecSmrg case CT_NONE: 20135c4bbdfSmrg XSetClipMask(xnestDisplay, xnestGC(pGC), None); 20235c4bbdfSmrg pValue = NULL; 20335c4bbdfSmrg break; 20435c4bbdfSmrg 20505b261ecSmrg case CT_REGION: 20635c4bbdfSmrg nRects = RegionNumRects((RegionPtr) pValue); 20735c4bbdfSmrg pRects = xallocarray(nRects, sizeof(*pRects)); 20835c4bbdfSmrg pBox = RegionRects((RegionPtr) pValue); 20935c4bbdfSmrg for (i = nRects; i-- > 0;) { 21035c4bbdfSmrg pRects[i].x = pBox[i].x1; 21135c4bbdfSmrg pRects[i].y = pBox[i].y1; 21235c4bbdfSmrg pRects[i].width = pBox[i].x2 - pBox[i].x1; 21335c4bbdfSmrg pRects[i].height = pBox[i].y2 - pBox[i].y1; 21435c4bbdfSmrg } 21535c4bbdfSmrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0, 21635c4bbdfSmrg pRects, nRects, Unsorted); 21735c4bbdfSmrg free((char *) pRects); 21835c4bbdfSmrg break; 21905b261ecSmrg 22005b261ecSmrg case CT_PIXMAP: 22135c4bbdfSmrg XSetClipMask(xnestDisplay, xnestGC(pGC), 22235c4bbdfSmrg xnestPixmap((PixmapPtr) pValue)); 22335c4bbdfSmrg /* 22435c4bbdfSmrg * Need to change into region, so subsequent uses are with 22535c4bbdfSmrg * current pixmap contents. 22635c4bbdfSmrg */ 22735c4bbdfSmrg pGC->clientClip = (*pGC->pScreen->BitmapToRegion) ((PixmapPtr) pValue); 22835c4bbdfSmrg (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) pValue); 22935c4bbdfSmrg pValue = pGC->clientClip; 23035c4bbdfSmrg break; 23105b261ecSmrg 23205b261ecSmrg case CT_UNSORTED: 23335c4bbdfSmrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 23435c4bbdfSmrg pGC->clipOrg.x, pGC->clipOrg.y, 23535c4bbdfSmrg (XRectangle *) pValue, nRects, Unsorted); 23635c4bbdfSmrg break; 23705b261ecSmrg 23805b261ecSmrg case CT_YSORTED: 23935c4bbdfSmrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 24035c4bbdfSmrg pGC->clipOrg.x, pGC->clipOrg.y, 24135c4bbdfSmrg (XRectangle *) pValue, nRects, YSorted); 24235c4bbdfSmrg break; 24305b261ecSmrg 24405b261ecSmrg case CT_YXSORTED: 24535c4bbdfSmrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 24635c4bbdfSmrg pGC->clipOrg.x, pGC->clipOrg.y, 24735c4bbdfSmrg (XRectangle *) pValue, nRects, YXSorted); 24835c4bbdfSmrg break; 24905b261ecSmrg 25005b261ecSmrg case CT_YXBANDED: 25135c4bbdfSmrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 25235c4bbdfSmrg pGC->clipOrg.x, pGC->clipOrg.y, 25335c4bbdfSmrg (XRectangle *) pValue, nRects, YXBanded); 25435c4bbdfSmrg break; 25505b261ecSmrg } 25605b261ecSmrg 25735c4bbdfSmrg switch (type) { 25805b261ecSmrg default: 25935c4bbdfSmrg break; 26005b261ecSmrg 26105b261ecSmrg case CT_UNSORTED: 26205b261ecSmrg case CT_YSORTED: 26305b261ecSmrg case CT_YXSORTED: 26405b261ecSmrg case CT_YXBANDED: 26535c4bbdfSmrg /* server clip representation is a region */ 26635c4bbdfSmrg pGC->clientClip = RegionFromRects(nRects, (xRectangle *) pValue, type); 26735c4bbdfSmrg free(pValue); 26835c4bbdfSmrg pValue = pGC->clientClip; 26935c4bbdfSmrg break; 27005b261ecSmrg } 27105b261ecSmrg 27235c4bbdfSmrg pGC->clientClip = pValue; 27305b261ecSmrg} 27405b261ecSmrg 27505b261ecSmrgvoid 27605b261ecSmrgxnestDestroyClip(GCPtr pGC) 27705b261ecSmrg{ 27835c4bbdfSmrg if (pGC->clientClip) { 27935c4bbdfSmrg RegionDestroy(pGC->clientClip); 28035c4bbdfSmrg XSetClipMask(xnestDisplay, xnestGC(pGC), None); 28135c4bbdfSmrg pGC->clientClip = NULL; 28205b261ecSmrg } 28305b261ecSmrg} 28405b261ecSmrg 28505b261ecSmrgvoid 28605b261ecSmrgxnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc) 28705b261ecSmrg{ 28835c4bbdfSmrg if (pGCSrc->clientClip) { 28935c4bbdfSmrg RegionPtr pRgn = RegionCreate(NULL, 1); 29035c4bbdfSmrg RegionCopy(pRgn, pGCSrc->clientClip); 29135c4bbdfSmrg xnestChangeClip(pGCDst, CT_REGION, pRgn, 0); 29235c4bbdfSmrg } else { 29335c4bbdfSmrg xnestDestroyClip(pGCDst); 29405b261ecSmrg } 29505b261ecSmrg} 296